From dd9c4e35bf62592bb93aafd88e7b266a15c12c0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 08:46:50 -0400 Subject: [PATCH 001/162] Update dependency @octokit/plugin-retry to v5.0.1 (#16835) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 07913ff11e..4c89acf357 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "@babel/preset-typescript": "7.21.5", "@koa/cors": "4.0.0", "@octokit/auth-oauth-device": "4.0.4", - "@octokit/plugin-retry": "5.0.0", + "@octokit/plugin-retry": "5.0.1", "@octokit/rest": "19.0.11", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", diff --git a/yarn.lock b/yarn.lock index b7e8cd082f..9007ca29e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3349,15 +3349,15 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-retry@npm:5.0.0": - version: 5.0.0 - resolution: "@octokit/plugin-retry@npm:5.0.0" +"@octokit/plugin-retry@npm:5.0.1": + version: 5.0.1 + resolution: "@octokit/plugin-retry@npm:5.0.1" dependencies: "@octokit/types": ^9.0.0 bottleneck: ^2.15.3 peerDependencies: "@octokit/core": ">=3" - checksum: 3ffea3da379f724f476ba053de3b43c6509684c33cd7a5015b936ea77324cf5801259e20867ab5dccee07af6c23000ccb13c924ce4eef1f4d28e69e4c9056beb + checksum: 56a67dacca4a55e1baa3ff1b37f13bc14f36c72d3c5a281ccc3a19f31c7774fc20955db2ec55cb5122e4c634b300fcaf86b7a22d54a6e84eba584affc933f180 languageName: node linkType: hard @@ -9669,7 +9669,7 @@ __metadata: "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 "@octokit/auth-oauth-device": 4.0.4 - "@octokit/plugin-retry": 5.0.0 + "@octokit/plugin-retry": 5.0.1 "@octokit/rest": 19.0.11 "@open-wc/dev-server-hmr": 0.1.4 "@polymer/app-layout": 3.1.0 From 549e4e7fb344147ab1313ec5a1257ef3aecfc22c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 08:48:34 -0400 Subject: [PATCH 002/162] Update typescript-eslint monorepo to v5.59.9 (#16832) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +-- yarn.lock | 100 +++++++++++++++++++++++++-------------------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 4c89acf357..746f5b8f9b 100644 --- a/package.json +++ b/package.json @@ -180,8 +180,8 @@ "@types/sortablejs": "1.15.1", "@types/tar": "6.1.5", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "5.59.8", - "@typescript-eslint/parser": "5.59.8", + "@typescript-eslint/eslint-plugin": "5.59.9", + "@typescript-eslint/parser": "5.59.9", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.2", diff --git a/yarn.lock b/yarn.lock index 9007ca29e8..f2ae6c0313 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4658,14 +4658,14 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/eslint-plugin@npm:5.59.8" +"@typescript-eslint/eslint-plugin@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/eslint-plugin@npm:5.59.9" dependencies: "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.59.8 - "@typescript-eslint/type-utils": 5.59.8 - "@typescript-eslint/utils": 5.59.8 + "@typescript-eslint/scope-manager": 5.59.9 + "@typescript-eslint/type-utils": 5.59.9 + "@typescript-eslint/utils": 5.59.9 debug: ^4.3.4 grapheme-splitter: ^1.0.4 ignore: ^5.2.0 @@ -4678,43 +4678,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 3e05cd06149ec3741c3c2fb638e2d19a55687b4614a5c8820433db82997687650297e51c17828d320162ccf4241798cf5712c405561e7605cb17e984a6967f7b + checksum: bd2428e307085d7fa6699913b6e61d65eb450bbcd26f884390cbf16722b80e1d80dc289c72774be1cdffd022744894204c3242f40ba3ffdfa05d3f210c4130bb languageName: node linkType: hard -"@typescript-eslint/parser@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/parser@npm:5.59.8" +"@typescript-eslint/parser@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/parser@npm:5.59.9" dependencies: - "@typescript-eslint/scope-manager": 5.59.8 - "@typescript-eslint/types": 5.59.8 - "@typescript-eslint/typescript-estree": 5.59.8 + "@typescript-eslint/scope-manager": 5.59.9 + "@typescript-eslint/types": 5.59.9 + "@typescript-eslint/typescript-estree": 5.59.9 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: bac9f09d8552086ceb882a7b87ce4d98dfaa41579249216c75d97e3fc07af33cddc4cbbd07a127a5823c826a258882643aaf658bec19cb2a434002b55c5f0d12 + checksum: 69b07d0a5bc6e1d24d23916c057ea9f2f53a0e7fb6dabadff92987c299640edee2c013fb93269322c7124e87b5c515529001397eae33006dfb40e1dcdf1902d7 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/scope-manager@npm:5.59.8" +"@typescript-eslint/scope-manager@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/scope-manager@npm:5.59.9" dependencies: - "@typescript-eslint/types": 5.59.8 - "@typescript-eslint/visitor-keys": 5.59.8 - checksum: e1e810ee991cfeb433330b04ee949bb6784abe4dbdb7d9480aa7a7536671b4fec914b7803edf662516c8ecb1b31dcff126797f9923270a529c26e2b00b0ea96f + "@typescript-eslint/types": 5.59.9 + "@typescript-eslint/visitor-keys": 5.59.9 + checksum: 362c22662d844440a7e14223d8cc0722f77ff21ad8f78deb0ee3b3f21de01b8846bf25fbbf527544677e83d8ff48008b3f7d40b39ddec55994ea4a1863e9ec0a languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/type-utils@npm:5.59.8" +"@typescript-eslint/type-utils@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/type-utils@npm:5.59.9" dependencies: - "@typescript-eslint/typescript-estree": 5.59.8 - "@typescript-eslint/utils": 5.59.8 + "@typescript-eslint/typescript-estree": 5.59.9 + "@typescript-eslint/utils": 5.59.9 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -4722,23 +4722,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: d9fde31397da0f0e62a5568f64bad99d06bcd324b7e3aac7fd997a3d045a0fe4c084b2e85d440e0a39645acd2269ad6593f196399c2c0f880d293417fec894e3 + checksum: 6bc2619c5024c152b181eff1f44c9b5e7d0fc75ce9403f03b39d59fc1e13191b2fbaf6730f26a1caae22922ac47489f39c2cebccdd713588f6963169ed2a7958 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/types@npm:5.59.8" - checksum: 559473d5601c849eb0da1874a2ac67c753480beed484ad6f6cda62fa6023273f2c3005c7f2864d9c2afb7c6356412d0d304b57db10c53597207f18a7f6cd4f18 +"@typescript-eslint/types@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/types@npm:5.59.9" + checksum: 283f8fee1ee590eeccc2e0fcd3526c856c4b1e2841af2cdcd09eeac842a42cfb32f6bc8b40385380f3dbc3ee29da30f1819115eedf9e16f69ff5a160aeddd8fa languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/typescript-estree@npm:5.59.8" +"@typescript-eslint/typescript-estree@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/typescript-estree@npm:5.59.9" dependencies: - "@typescript-eslint/types": 5.59.8 - "@typescript-eslint/visitor-keys": 5.59.8 + "@typescript-eslint/types": 5.59.9 + "@typescript-eslint/visitor-keys": 5.59.9 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -4747,35 +4747,35 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: d93371cc866f573a6a1ddc0eb10d498a8e59f36763a99ce21da0737fff2b4c942eef1587216aad273f8d896ebc0b19003677cba63a27d2646aa2c087638963eb + checksum: c0c9b81f20a2a4337f07bc3ccdc9c1dabd765f59096255ed9a149e91e5c9517b25c2b6655f8f073807cfc13500c7451fbd9bb62e5e572c07cc07945ab042db89 languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/utils@npm:5.59.8" +"@typescript-eslint/utils@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/utils@npm:5.59.9" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.59.8 - "@typescript-eslint/types": 5.59.8 - "@typescript-eslint/typescript-estree": 5.59.8 + "@typescript-eslint/scope-manager": 5.59.9 + "@typescript-eslint/types": 5.59.9 + "@typescript-eslint/typescript-estree": 5.59.9 eslint-scope: ^5.1.1 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: cbaa057485c7f52c45d0dfb4f5a8e9273abccb1c52dcb4426a79f9e71d2c1062cf2525bad6d4aca5ec42db3fe723d749843bcade5a323bde7fbe4b5d5b5d5c3b + checksum: 22ec5962886de7dcf65f99c37aad9fb189a3bef6b2b07c81887fb82a0e8bf137246da58e64fb02141352285708440be13acd7f6db1ca19e96f86724813ac4646 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.59.8": - version: 5.59.8 - resolution: "@typescript-eslint/visitor-keys@npm:5.59.8" +"@typescript-eslint/visitor-keys@npm:5.59.9": + version: 5.59.9 + resolution: "@typescript-eslint/visitor-keys@npm:5.59.9" dependencies: - "@typescript-eslint/types": 5.59.8 + "@typescript-eslint/types": 5.59.9 eslint-visitor-keys: ^3.3.0 - checksum: 6bfa7918dbb0e08d8a7404aeeef7bcd1a85736dc8d01614d267c0c5ec10f94d2746b50a945bf5c82c54fda67926e8deaeba8565c919da17f725fc11209ef8987 + checksum: 2909ce761f7fe546592cd3c43e33263d8a5fa619375fd2fdffbc72ffc33e40d6feacafb28c79f36c638fcc2225048e7cc08c61cbac6ca63723dc68610d80e3e6 languageName: node linkType: hard @@ -9705,8 +9705,8 @@ __metadata: "@types/sortablejs": 1.15.1 "@types/tar": 6.1.5 "@types/webspeechapi": 0.0.29 - "@typescript-eslint/eslint-plugin": 5.59.8 - "@typescript-eslint/parser": 5.59.8 + "@typescript-eslint/eslint-plugin": 5.59.9 + "@typescript-eslint/parser": 5.59.9 "@vaadin/combo-box": 24.0.8 "@vaadin/vaadin-themable-mixin": 24.0.8 "@vibrant/color": 3.2.1-alpha.1 From 36de0e5c8c50e38d300b82463d3af3c010ab12c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 08:55:19 -0400 Subject: [PATCH 003/162] Update CodeMirror (#16820) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 ++-- yarn.lock | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 746f5b8f9b..a11175d706 100644 --- a/package.json +++ b/package.json @@ -31,9 +31,9 @@ "@codemirror/commands": "6.2.4", "@codemirror/language": "6.7.0", "@codemirror/legacy-modes": "6.3.2", - "@codemirror/search": "6.4.0", + "@codemirror/search": "6.5.0", "@codemirror/state": "6.2.1", - "@codemirror/view": "6.12.0", + "@codemirror/view": "6.13.0", "@egjs/hammerjs": "2.0.17", "@formatjs/intl-datetimeformat": "6.8.0", "@formatjs/intl-displaynames": "6.3.2", diff --git a/yarn.lock b/yarn.lock index f2ae6c0313..a38efec2bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1507,14 +1507,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/search@npm:6.4.0": - version: 6.4.0 - resolution: "@codemirror/search@npm:6.4.0" +"@codemirror/search@npm:6.5.0": + version: 6.5.0 + resolution: "@codemirror/search@npm:6.5.0" dependencies: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 crelt: ^1.0.5 - checksum: 441e04fc896ac984f224e3adb20bc8a6c63d929778335c70d2cb1e3843674c7998db93e2ab1cd05e8276cb3819766cd23951eec748fdf8e66e3611bd9a55aab5 + checksum: 2e9f2344b7dbd4bad79058c105d8cbd02b2bf94c27495310f0e3b6e999010aa080dceea47ef46e35439cc9e131b47c46f7d2eda700ef491b5f2f34bbc8e145ab languageName: node linkType: hard @@ -1525,14 +1525,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:6.12.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.6.0": - version: 6.12.0 - resolution: "@codemirror/view@npm:6.12.0" +"@codemirror/view@npm:6.13.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.6.0": + version: 6.13.0 + resolution: "@codemirror/view@npm:6.13.0" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: 512cbc9c05ac2cfa738cdf7aac711847b44e24ff5869f31839a9fcc11da6a512448fa9bc980535d55b897de80d49e744336a2724ca1fe3dae8bfcb31e339fe64 + checksum: 3c4713eba5cf54afd9cf92f42295f7a9b42f4041ad9c17fc3dbbeebeb94f95fe3b2bd5377265ceed71a070d5b2472bae2fbb5013254c7e85fe5e1e3b5c807d79 languageName: node linkType: hard @@ -9618,9 +9618,9 @@ __metadata: "@codemirror/commands": 6.2.4 "@codemirror/language": 6.7.0 "@codemirror/legacy-modes": 6.3.2 - "@codemirror/search": 6.4.0 + "@codemirror/search": 6.5.0 "@codemirror/state": 6.2.1 - "@codemirror/view": 6.12.0 + "@codemirror/view": 6.13.0 "@egjs/hammerjs": 2.0.17 "@formatjs/intl-datetimeformat": 6.8.0 "@formatjs/intl-displaynames": 6.3.2 From e1f73dac0241563615565e21b0db6e9402dc8179 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 13:02:14 +0000 Subject: [PATCH 004/162] Update dependency hls.js to v1.4.5 (#16842) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a11175d706..d88323e2e5 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "deep-freeze": "0.0.1", "fuse.js": "6.6.2", "google-timezones-json": "1.1.0", - "hls.js": "1.4.4", + "hls.js": "1.4.5", "home-assistant-js-websocket": "8.0.1", "idb-keyval": "6.2.1", "intl-messageformat": "10.3.5", diff --git a/yarn.lock b/yarn.lock index a38efec2bf..17384fc446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9596,10 +9596,10 @@ __metadata: languageName: node linkType: hard -"hls.js@npm:1.4.4": - version: 1.4.4 - resolution: "hls.js@npm:1.4.4" - checksum: 57b1a3607d240ddfa5a145b5075af22e2f27d55fae9330af2520f762651cf0d8811234e01b7b38e04c9e40f371a6350821c013c79ecb5ee5c3fff260f4fca996 +"hls.js@npm:1.4.5": + version: 1.4.5 + resolution: "hls.js@npm:1.4.5" + checksum: 7d01e17e5a434e3d6c8579b8d8340bfb4d7affb2f4015c02894466f0ce2719dc4c7e6f8953fb5a38642795e838d06c58d71ced579948e712d58e434001b69320 languageName: node linkType: hard @@ -9753,7 +9753,7 @@ __metadata: gulp-merge-json: 2.1.2 gulp-rename: 2.0.0 gulp-zopfli-green: 6.0.1 - hls.js: 1.4.4 + hls.js: 1.4.5 home-assistant-js-websocket: 8.0.1 html-minifier-terser: 7.2.0 husky: 8.0.3 From e4eaa52d53962bc86ed27fa25f6c5564f452f094 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 09:04:55 -0400 Subject: [PATCH 005/162] Update dependency webpack-cli to v5.1.3 (#16809) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 40 ++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index d88323e2e5..7c45339ae2 100644 --- a/package.json +++ b/package.json @@ -239,7 +239,7 @@ "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", "webpack": "5.84.1", - "webpack-cli": "5.1.1", + "webpack-cli": "5.1.3", "webpack-dev-server": "4.15.0", "webpack-manifest-plugin": "5.0.0", "webpackbar": "5.0.2", diff --git a/yarn.lock b/yarn.lock index 17384fc446..2156d3dc5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5326,36 +5326,36 @@ __metadata: languageName: node linkType: hard -"@webpack-cli/configtest@npm:^2.1.0": - version: 2.1.0 - resolution: "@webpack-cli/configtest@npm:2.1.0" +"@webpack-cli/configtest@npm:^2.1.1": + version: 2.1.1 + resolution: "@webpack-cli/configtest@npm:2.1.1" peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x - checksum: b875fccd8be9a936924e24986725823347703e3eb72ea884e74669ca20f007704e859855a6a05940d5d3805ce2fc08b183a0f1658d5395b5454b3f5f88293081 + checksum: 9f9f9145c2d05471fc83d426db1df85cf49f329836b0c4b9f46b6948bed4b013464c00622b136d2a0a26993ce2306976682592245b08ee717500b1db45009a72 languageName: node linkType: hard -"@webpack-cli/info@npm:^2.0.1": - version: 2.0.1 - resolution: "@webpack-cli/info@npm:2.0.1" +"@webpack-cli/info@npm:^2.0.2": + version: 2.0.2 + resolution: "@webpack-cli/info@npm:2.0.2" peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x - checksum: b8fba49fee10d297c2affb0b064c9a81e9038d75517c6728fb85f9fb254cae634e5d33e696dac5171e6944ae329d85fddac72f781c7d833f7e9dfe43151ce60d + checksum: 8f9a178afca5c82e113aed1efa552d64ee5ae4fdff63fe747c096a981ec74f18a5d07bd6e89bbe6715c3e57d96eea024a410e58977169489fe1df044c10dd94e languageName: node linkType: hard -"@webpack-cli/serve@npm:^2.0.4": - version: 2.0.4 - resolution: "@webpack-cli/serve@npm:2.0.4" +"@webpack-cli/serve@npm:^2.0.5": + version: 2.0.5 + resolution: "@webpack-cli/serve@npm:2.0.5" peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x peerDependenciesMeta: webpack-dev-server: optional: true - checksum: 561ea2e6eb551415f0b1675393a8480e1201293fe37eae334cbb1fdc466986668cca76ca1ca327ada9b498eae27cbecef0793e3bb5677288f1a5216cad414efe + checksum: 75f0e54681796d567a71ac3e2781d2901a8d8cf1cdfc82f261034dddac59a8343e8c3bc5e32b4bb9d6766759ba49fb29a5cd86ef1701d79c506fe886bb63ac75 languageName: node linkType: hard @@ -9811,7 +9811,7 @@ __metadata: vue: 2.7.14 vue2-daterange-picker: 0.6.8 webpack: 5.84.1 - webpack-cli: 5.1.1 + webpack-cli: 5.1.3 webpack-dev-server: 4.15.0 webpack-manifest-plugin: 5.0.0 webpackbar: 5.0.2 @@ -16103,14 +16103,14 @@ __metadata: languageName: node linkType: hard -"webpack-cli@npm:5.1.1": - version: 5.1.1 - resolution: "webpack-cli@npm:5.1.1" +"webpack-cli@npm:5.1.3": + version: 5.1.3 + resolution: "webpack-cli@npm:5.1.3" dependencies: "@discoveryjs/json-ext": ^0.5.0 - "@webpack-cli/configtest": ^2.1.0 - "@webpack-cli/info": ^2.0.1 - "@webpack-cli/serve": ^2.0.4 + "@webpack-cli/configtest": ^2.1.1 + "@webpack-cli/info": ^2.0.2 + "@webpack-cli/serve": ^2.0.5 colorette: ^2.0.14 commander: ^10.0.1 cross-spawn: ^7.0.3 @@ -16131,7 +16131,7 @@ __metadata: optional: true bin: webpack-cli: bin/cli.js - checksum: 7738e6a84a0098886e1e0c0fd0dab44b7dedfbb0580afbb5ef734c5109dcaee80140bebb5d9f4b40f425029563bb09bcbda8b08d904fa14e60ff632e6dcc8a17 + checksum: 5bb8326bf8bdbc4118cb5dd17332429434a5ab6cde88d79c3d95abf23571c8213ce5e3ff2ca4e1e7145e6f16a4e78740f5d60f999b2e11a0ee37bb339d4da3e4 languageName: node linkType: hard From 2b6cf55638b4e0a572da0e3c1f9557e37b8882f0 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 9 Jun 2023 16:38:01 +0200 Subject: [PATCH 006/162] Add paste to else automation action (#16840) --- .../config/automation/action/types/ha-automation-action-if.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/config/automation/action/types/ha-automation-action-if.ts b/src/panels/config/automation/action/types/ha-automation-action-if.ts index 5ead09f792..c49b9ef287 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-if.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-if.ts @@ -77,6 +77,7 @@ export class HaIfAction extends LitElement implements ActionElement { .reOrderMode=${this.reOrderMode} .disabled=${this.disabled} @value-changed=${this._elseChanged} + .clipboard=${this.clipboard} .hass=${this.hass} > ` From 15132783d4c4e0c9f924c70fecf6eb313432db61 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:49:59 -0400 Subject: [PATCH 007/162] Update formatjs monorepo (#16843) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 16 ++--- yarn.lock | 168 +++++++++++++++++++++++++-------------------------- 2 files changed, 92 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index 7c45339ae2..1666e82f66 100644 --- a/package.json +++ b/package.json @@ -35,13 +35,13 @@ "@codemirror/state": "6.2.1", "@codemirror/view": "6.13.0", "@egjs/hammerjs": "2.0.17", - "@formatjs/intl-datetimeformat": "6.8.0", - "@formatjs/intl-displaynames": "6.3.2", - "@formatjs/intl-getcanonicallocales": "2.2.0", - "@formatjs/intl-locale": "3.3.0", - "@formatjs/intl-numberformat": "8.5.0", - "@formatjs/intl-pluralrules": "5.2.2", - "@formatjs/intl-relativetimeformat": "11.2.2", + "@formatjs/intl-datetimeformat": "6.9.0", + "@formatjs/intl-displaynames": "6.4.0", + "@formatjs/intl-getcanonicallocales": "2.2.1", + "@formatjs/intl-locale": "3.3.1", + "@formatjs/intl-numberformat": "8.6.0", + "@formatjs/intl-pluralrules": "5.2.3", + "@formatjs/intl-relativetimeformat": "11.2.3", "@fullcalendar/core": "6.1.8", "@fullcalendar/daygrid": "6.1.8", "@fullcalendar/interaction": "6.1.8", @@ -114,7 +114,7 @@ "hls.js": "1.4.5", "home-assistant-js-websocket": "8.0.1", "idb-keyval": "6.2.1", - "intl-messageformat": "10.3.5", + "intl-messageformat": "10.4.0", "js-yaml": "4.1.0", "leaflet": "1.9.4", "leaflet-draw": "1.0.4", diff --git a/yarn.lock b/yarn.lock index 2156d3dc5c..54d5777c25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1594,137 +1594,137 @@ __metadata: languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:1.15.0": - version: 1.15.0 - resolution: "@formatjs/ecma402-abstract@npm:1.15.0" +"@formatjs/ecma402-abstract@npm:1.16.0": + version: 1.16.0 + resolution: "@formatjs/ecma402-abstract@npm:1.16.0" dependencies: - "@formatjs/intl-localematcher": 0.2.32 + "@formatjs/intl-localematcher": 0.3.0 tslib: ^2.4.0 - checksum: c9feca174f9490026ef75b2de363d17fcac57848fb73bc8001a5c6c733db33a6674cdd506d69414067bd4ad670587f721d1e446b134e38e998b5f44b0c1412d3 + checksum: a3d6016d51b9f9a876e4ad66010ef80b07f54b9bb50f6135267d41203219d38e9b934fc575e65e3556eb89d92640452e03927f50f030906be8919a319d906bd2 languageName: node linkType: hard -"@formatjs/fast-memoize@npm:2.0.1": - version: 2.0.1 - resolution: "@formatjs/fast-memoize@npm:2.0.1" +"@formatjs/fast-memoize@npm:2.1.0": + version: 2.1.0 + resolution: "@formatjs/fast-memoize@npm:2.1.0" dependencies: tslib: ^2.4.0 - checksum: e434cdc53354666459c47556c403f0ed3391ebab0e851a64e5622d8d81e3b684a74a09c4bf5189885c66e743004601f64e2e2c8c70adf6b00071d4afea20f69d + checksum: 778da54abaaa77013205c7f0dceb654ca2d9b76d0d1380b4d4bd08d57a870f62d434f29b2cda4dbf892d47b045e7d2bc90f1273ebd968844dea2a2e8b3315e69 languageName: node linkType: hard -"@formatjs/icu-messageformat-parser@npm:2.4.0": - version: 2.4.0 - resolution: "@formatjs/icu-messageformat-parser@npm:2.4.0" +"@formatjs/icu-messageformat-parser@npm:2.5.0": + version: 2.5.0 + resolution: "@formatjs/icu-messageformat-parser@npm:2.5.0" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/icu-skeleton-parser": 1.4.0 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/icu-skeleton-parser": 1.5.0 tslib: ^2.4.0 - checksum: 9bf9537b30e6f542a2f3d6763c6baf10010d3fc8e82a7a5a3899b1eaa38f3338ba9f59959fff5837bbd9154e44cf23e0f5503a969e80cce1fa57c2bb6c17ac22 + checksum: 11c524cc2c15c1f15b54e81fca506ccfc77f3b3adabdb457053aacfbd28789c88054e378439cf23accf69baeefbe8e35d9bb5a6253235a1bc4724dd4956bfba3 languageName: node linkType: hard -"@formatjs/icu-skeleton-parser@npm:1.4.0": - version: 1.4.0 - resolution: "@formatjs/icu-skeleton-parser@npm:1.4.0" +"@formatjs/icu-skeleton-parser@npm:1.5.0": + version: 1.5.0 + resolution: "@formatjs/icu-skeleton-parser@npm:1.5.0" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 + "@formatjs/ecma402-abstract": 1.16.0 tslib: ^2.4.0 - checksum: 00f016b4d9b446c395ec88d979baeaef97ed2006848b888ea0a6a44e08b875b7f16a2e4b54297161ecf7d8be64736ac4168c140ab42006b0b13274a955c0f26a + checksum: 0da173c1fb3d28c8eb4c3fd4eadec9d0b6476d639abb5c371b0a156aa79bbe6d1e0d6fc6fff09b254da7523049baa1032a61a0cad647a3e2e005f7e55317ef39 languageName: node linkType: hard -"@formatjs/intl-datetimeformat@npm:6.8.0": - version: 6.8.0 - resolution: "@formatjs/intl-datetimeformat@npm:6.8.0" +"@formatjs/intl-datetimeformat@npm:6.9.0": + version: 6.9.0 + resolution: "@formatjs/intl-datetimeformat@npm:6.9.0" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/intl-localematcher": 0.2.32 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-localematcher": 0.3.0 tslib: ^2.4.0 - checksum: 1ad7fb6d5a9eb8ae70758f5402c8e4dbdba6ff4282ca08e76cf3f7ed622b5d691343956cc9439dc8c5b4755f232714eb0c8ae25679fe550b36896fb873b00161 + checksum: 3abfab4d8e02e84442b2231e4bd1961e5eaaccbeee895333293babca685f96aac5082005443be3bb7a1343a80bc6b65fe6713ed1bb794d265a04ef570f0fdb09 languageName: node linkType: hard -"@formatjs/intl-displaynames@npm:6.3.2": - version: 6.3.2 - resolution: "@formatjs/intl-displaynames@npm:6.3.2" +"@formatjs/intl-displaynames@npm:6.4.0": + version: 6.4.0 + resolution: "@formatjs/intl-displaynames@npm:6.4.0" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/intl-localematcher": 0.2.32 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-localematcher": 0.3.0 tslib: ^2.4.0 - checksum: fa736c6c6bd40782a630ee9dc1bb36be2bffddfa66adcca554417f6ce5f9d4bf84422c1b47b308278f74b52b12f7e0f8fce064678b96299a7f9d9f1bb4f69b98 + checksum: 66d787bdd398da6a14a2f2ae0b74e9f98f6832a0745f5fa8e986d76d3cb21933bdafc503fd6ec4cb94de38f5324867774f60895e6e2ebbabf1db6702f56b50d4 languageName: node linkType: hard -"@formatjs/intl-enumerator@npm:1.3.0": - version: 1.3.0 - resolution: "@formatjs/intl-enumerator@npm:1.3.0" +"@formatjs/intl-enumerator@npm:1.3.1": + version: 1.3.1 + resolution: "@formatjs/intl-enumerator@npm:1.3.1" dependencies: tslib: ^2.4.0 - checksum: 99160b87e7b986528241e4eb4cb06f5523747ad3858e4d1ce0b4c787798cf3414f466a73e4420a8e94e5afc52de4f3e790a8ed91cb79790078f2359df7c4a12a + checksum: 48acfd7f3368eee9a64017c0e9dedc588178aa94606c51a03a00f2d1a4954fd31457f98835f11e0b725f0e9272a438b98df03ad7dff85b33483f810b33aafd01 languageName: node linkType: hard -"@formatjs/intl-getcanonicallocales@npm:2.2.0": - version: 2.2.0 - resolution: "@formatjs/intl-getcanonicallocales@npm:2.2.0" +"@formatjs/intl-getcanonicallocales@npm:2.2.1": + version: 2.2.1 + resolution: "@formatjs/intl-getcanonicallocales@npm:2.2.1" dependencies: tslib: ^2.4.0 - checksum: 71942361942a987703669bd7ce472ab68aa514e532bd019abb9fbb0636fbb2840447b90cf702ae800ccad428b32b3f2861140b172653b62549d417fc2d2d598e + checksum: 9842f21308ee7cc46bf5a7f54c3ae66ebcaf107226ea43c11571eab0d8b36fdfa81521bf3210a4f385e2ca3302d9a61378e375946a930687278432bc482c9f8e languageName: node linkType: hard -"@formatjs/intl-locale@npm:3.3.0": - version: 3.3.0 - resolution: "@formatjs/intl-locale@npm:3.3.0" +"@formatjs/intl-locale@npm:3.3.1": + version: 3.3.1 + resolution: "@formatjs/intl-locale@npm:3.3.1" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/intl-enumerator": 1.3.0 - "@formatjs/intl-getcanonicallocales": 2.2.0 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-enumerator": 1.3.1 + "@formatjs/intl-getcanonicallocales": 2.2.1 tslib: ^2.4.0 - checksum: 4932b2543291e1854c557045feaf20a6c339963ca2810bc1b08db3b1eb98534c058b96b7b2513d9f0ea92ad72bc14dc77c742fe2c79fd569782ec14617218685 + checksum: 6f4b1f7c55ea6108f3dacd9167e15c57a853dec69bdfeadfdc1a2c50167e7f90c8962c9b03b10efa1e0ae5dabeb0c7499c86545592ba0ca88e690ac13665f185 languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.2.32": - version: 0.2.32 - resolution: "@formatjs/intl-localematcher@npm:0.2.32" +"@formatjs/intl-localematcher@npm:0.3.0": + version: 0.3.0 + resolution: "@formatjs/intl-localematcher@npm:0.3.0" dependencies: tslib: ^2.4.0 - checksum: 477e18aabaf2e6e90fc12952a3cb6c0ebb40ad99414d6b9d2501c6348fbad58cacb433ec6630955cfd1491ea7630f32a9dc280bb27d0fb8a784251404a54140a + checksum: 26fbe20a3187842ea9fd417429dd53af941ad896c783fcc15df25e92c3fe9b9895f9909de9f9731ef75b81e7fb396d3d10d35656e3f5ff3588488521d600ec3a languageName: node linkType: hard -"@formatjs/intl-numberformat@npm:8.5.0": - version: 8.5.0 - resolution: "@formatjs/intl-numberformat@npm:8.5.0" +"@formatjs/intl-numberformat@npm:8.6.0": + version: 8.6.0 + resolution: "@formatjs/intl-numberformat@npm:8.6.0" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/intl-localematcher": 0.2.32 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-localematcher": 0.3.0 tslib: ^2.4.0 - checksum: 60a9b4f3740ac1d85e932a4585455142a4c152a70a0a2028ab37ddcfd18c3d753b9609ea6984a0d487ad303995485a50cfd6b7ca1db963b5434ca63d62ad0b60 + checksum: d15a7ef5cc18262f2a02956b4bfe3376f1f6fc2f696a222e5653809bb05060bda9ed45836f47a332fd608ea08e6f52cadd76e75ec6f9723bb6139db23d203399 languageName: node linkType: hard -"@formatjs/intl-pluralrules@npm:5.2.2": - version: 5.2.2 - resolution: "@formatjs/intl-pluralrules@npm:5.2.2" +"@formatjs/intl-pluralrules@npm:5.2.3": + version: 5.2.3 + resolution: "@formatjs/intl-pluralrules@npm:5.2.3" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/intl-localematcher": 0.2.32 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-localematcher": 0.3.0 tslib: ^2.4.0 - checksum: 4fa72cdad265f19511d4728a15d40e6877d49f1e28ad7053eb566e696597a37e1111be8412b5927dffe792ed35c8fe5c7f3181ccb06b6f149cd75209cb14b967 + checksum: aae18c138f5402712df43831a2f4a0c261734fa88c7bf165c2375d0a355d996e4475afc046d255cf2441ebdc096cc47b391c621ae4eacd5a8af318d72b1dc341 languageName: node linkType: hard -"@formatjs/intl-relativetimeformat@npm:11.2.2": - version: 11.2.2 - resolution: "@formatjs/intl-relativetimeformat@npm:11.2.2" +"@formatjs/intl-relativetimeformat@npm:11.2.3": + version: 11.2.3 + resolution: "@formatjs/intl-relativetimeformat@npm:11.2.3" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/intl-localematcher": 0.2.32 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-localematcher": 0.3.0 tslib: ^2.4.0 - checksum: 6c9376140bb58193e1c2788a2559af24c150c39fe16249199719ee63474fdb113a2974252514e61120d9ad6daa5d174b442c30af85c3740f1e90f3c822448d8d + checksum: b3b60ba5a03538be66ff73aa9621a7aaa4ee911dc0052c737295ec06301a0bf34ecfd2c9872951e7a6507152ba858aa9fdb6499a28a6f3c020ed1b9aabe4b9fa languageName: node linkType: hard @@ -9622,13 +9622,13 @@ __metadata: "@codemirror/state": 6.2.1 "@codemirror/view": 6.13.0 "@egjs/hammerjs": 2.0.17 - "@formatjs/intl-datetimeformat": 6.8.0 - "@formatjs/intl-displaynames": 6.3.2 - "@formatjs/intl-getcanonicallocales": 2.2.0 - "@formatjs/intl-locale": 3.3.0 - "@formatjs/intl-numberformat": 8.5.0 - "@formatjs/intl-pluralrules": 5.2.2 - "@formatjs/intl-relativetimeformat": 11.2.2 + "@formatjs/intl-datetimeformat": 6.9.0 + "@formatjs/intl-displaynames": 6.4.0 + "@formatjs/intl-getcanonicallocales": 2.2.1 + "@formatjs/intl-locale": 3.3.1 + "@formatjs/intl-numberformat": 8.6.0 + "@formatjs/intl-pluralrules": 5.2.3 + "@formatjs/intl-relativetimeformat": 11.2.3 "@fullcalendar/core": 6.1.8 "@fullcalendar/daygrid": 6.1.8 "@fullcalendar/interaction": 6.1.8 @@ -9759,7 +9759,7 @@ __metadata: husky: 8.0.3 idb-keyval: 6.2.1 instant-mocha: 1.5.1 - intl-messageformat: 10.3.5 + intl-messageformat: 10.4.0 js-yaml: 4.1.0 jszip: 3.10.1 leaflet: 1.9.4 @@ -10239,15 +10239,15 @@ __metadata: languageName: node linkType: hard -"intl-messageformat@npm:10.3.5": - version: 10.3.5 - resolution: "intl-messageformat@npm:10.3.5" +"intl-messageformat@npm:10.4.0": + version: 10.4.0 + resolution: "intl-messageformat@npm:10.4.0" dependencies: - "@formatjs/ecma402-abstract": 1.15.0 - "@formatjs/fast-memoize": 2.0.1 - "@formatjs/icu-messageformat-parser": 2.4.0 + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/fast-memoize": 2.1.0 + "@formatjs/icu-messageformat-parser": 2.5.0 tslib: ^2.4.0 - checksum: a52526a02ee54fda870e5a83900ba089332c5a820bec033ffd5c422e68e90269e36e2aa144dc3728a43b5df506d8a5e261e162227410463d5d8a03864f39170e + checksum: 763b6da80a69242d1a52cb13c9435dd40908a2ae0a7407bef260aa537e0e96cfa5394e7d01fa90dc45c3c2d159ac874d2ae58bbaa2da483effb44e914e87a185 languageName: node linkType: hard From c77905bd22b45b3fb386e370bde738a059846635 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 20:45:14 -0400 Subject: [PATCH 008/162] Update dependency glob to v10.2.7 (#16851) --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1666e82f66..52e5a95a3e 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "esprima": "4.0.1", "fancy-log": "2.0.0", "fs-extra": "11.1.1", - "glob": "10.2.6", + "glob": "10.2.7", "gulp": "4.0.2", "gulp-flatmap": "1.0.2", "gulp-json-transform": "0.4.8", diff --git a/yarn.lock b/yarn.lock index 54d5777c25..b2532c6546 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9174,9 +9174,9 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.2.6": - version: 10.2.6 - resolution: "glob@npm:10.2.6" +"glob@npm:10.2.7": + version: 10.2.7 + resolution: "glob@npm:10.2.7" dependencies: foreground-child: ^3.1.0 jackspeak: ^2.0.3 @@ -9185,7 +9185,7 @@ __metadata: path-scurry: ^1.7.0 bin: glob: dist/cjs/src/bin.js - checksum: 94c5964bfa9df95207a69a3bd9b07b99ea7b5ba1f36dd73a8914378cee9436a205b9b5bdff58872abc238684ea7f4b4936e932155b8885250818bcc8d5321ddf + checksum: 555205a74607d6f8d9874ba888924b305b5ea1abfaa2e9ccb11ac713d040aac7edbf7d8702a2f4a1cd81b2d7666412170ce7ef061d33cddde189dae8c1a1a054 languageName: node linkType: hard @@ -9745,7 +9745,7 @@ __metadata: fancy-log: 2.0.0 fs-extra: 11.1.1 fuse.js: 6.6.2 - glob: 10.2.6 + glob: 10.2.7 google-timezones-json: 1.1.0 gulp: 4.0.2 gulp-flatmap: 1.0.2 From 273992c8e9c3062c6e49481b6d7d688a07067232 Mon Sep 17 00:00:00 2001 From: Matthias Alphart Date: Sat, 10 Jun 2023 16:39:43 +0200 Subject: [PATCH 009/162] Consolidate dependency updates in release-drafter (#16856) --- .github/release-drafter.yml | 5 +++++ .github/workflows/release-drafter.yaml | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index a4dce4c2b4..0d507d1104 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -1,3 +1,8 @@ +categories: + - title: 'Dependency updates' + collapse-after: 3 + labels: + - 'dependencies' template: | ## What's Changed diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 00954a2615..71a80c804f 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -5,8 +5,17 @@ on: branches: - dev +permissions: + contents: read + jobs: update_release_draft: + permissions: + # write permission for contents is required to create a github release + contents: write + # write permission for pull-requests is required for autolabeler + # otherwise, read permission is required at least + pull-requests: read runs-on: ubuntu-latest steps: - uses: release-drafter/release-drafter@v5 From eaffed9ff86562f46393e12e21f5226428a7ce41 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 13:27:10 -0400 Subject: [PATCH 010/162] Update dependency @octokit/plugin-retry to v5.0.2 (#16861) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 52e5a95a3e..42398f72b6 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "@babel/preset-typescript": "7.21.5", "@koa/cors": "4.0.0", "@octokit/auth-oauth-device": "4.0.4", - "@octokit/plugin-retry": "5.0.1", + "@octokit/plugin-retry": "5.0.2", "@octokit/rest": "19.0.11", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", diff --git a/yarn.lock b/yarn.lock index b2532c6546..d2782cc82f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3349,15 +3349,15 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-retry@npm:5.0.1": - version: 5.0.1 - resolution: "@octokit/plugin-retry@npm:5.0.1" +"@octokit/plugin-retry@npm:5.0.2": + version: 5.0.2 + resolution: "@octokit/plugin-retry@npm:5.0.2" dependencies: "@octokit/types": ^9.0.0 bottleneck: ^2.15.3 peerDependencies: "@octokit/core": ">=3" - checksum: 56a67dacca4a55e1baa3ff1b37f13bc14f36c72d3c5a281ccc3a19f31c7774fc20955db2ec55cb5122e4c634b300fcaf86b7a22d54a6e84eba584affc933f180 + checksum: b86f92a55e10dfc2012029d7b00bc8bf7cd7c6a4ea3d6484a6d6ec3c0e441298cda00975eee22b7d9b9e73741d12b0a5c4790e42a805e0222743bc9693a5d5a8 languageName: node linkType: hard @@ -9669,7 +9669,7 @@ __metadata: "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 "@octokit/auth-oauth-device": 4.0.4 - "@octokit/plugin-retry": 5.0.1 + "@octokit/plugin-retry": 5.0.2 "@octokit/rest": 19.0.11 "@open-wc/dev-server-hmr": 0.1.4 "@polymer/app-layout": 3.1.0 From 17a2560d94d52e53c84f794c060c86109182a53d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 13:28:12 -0400 Subject: [PATCH 011/162] Update dependency webpack-cli to v5.1.4 (#16862) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 42398f72b6..7e576faac5 100644 --- a/package.json +++ b/package.json @@ -239,7 +239,7 @@ "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", "webpack": "5.84.1", - "webpack-cli": "5.1.3", + "webpack-cli": "5.1.4", "webpack-dev-server": "4.15.0", "webpack-manifest-plugin": "5.0.0", "webpackbar": "5.0.2", diff --git a/yarn.lock b/yarn.lock index d2782cc82f..9ac5e885eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9811,7 +9811,7 @@ __metadata: vue: 2.7.14 vue2-daterange-picker: 0.6.8 webpack: 5.84.1 - webpack-cli: 5.1.3 + webpack-cli: 5.1.4 webpack-dev-server: 4.15.0 webpack-manifest-plugin: 5.0.0 webpackbar: 5.0.2 @@ -16103,9 +16103,9 @@ __metadata: languageName: node linkType: hard -"webpack-cli@npm:5.1.3": - version: 5.1.3 - resolution: "webpack-cli@npm:5.1.3" +"webpack-cli@npm:5.1.4": + version: 5.1.4 + resolution: "webpack-cli@npm:5.1.4" dependencies: "@discoveryjs/json-ext": ^0.5.0 "@webpack-cli/configtest": ^2.1.1 @@ -16131,7 +16131,7 @@ __metadata: optional: true bin: webpack-cli: bin/cli.js - checksum: 5bb8326bf8bdbc4118cb5dd17332429434a5ab6cde88d79c3d95abf23571c8213ce5e3ff2ca4e1e7145e6f16a4e78740f5d60f999b2e11a0ee37bb339d4da3e4 + checksum: 3a4ad0d0342a6815c850ee4633cc2a8a5dae04f918e7847f180bf24ab400803cf8a8943707ffbed03eb20fe6ce647f996f60a2aade87b0b4a9954da3da172ce0 languageName: node linkType: hard From 983bba357a421bf09b950bcdacfc37f416123839 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 11 Jun 2023 17:42:06 -0400 Subject: [PATCH 012/162] Update babel monorepo to v7.22.5 (#16872) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 12 +- yarn.lock | 1251 +++++++++++++++++++++++++------------------------- 2 files changed, 629 insertions(+), 634 deletions(-) diff --git a/package.json b/package.json index 7e576faac5..2bad0faf13 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "license": "Apache-2.0", "type": "module", "dependencies": { - "@babel/runtime": "7.22.3", + "@babel/runtime": "7.22.5", "@braintree/sanitize-url": "6.0.2", "@codemirror/autocomplete": "6.7.1", "@codemirror/commands": "6.2.4", @@ -149,11 +149,11 @@ "xss": "1.0.14" }, "devDependencies": { - "@babel/core": "7.22.1", - "@babel/plugin-proposal-decorators": "7.22.3", - "@babel/plugin-transform-runtime": "7.22.4", - "@babel/preset-env": "7.22.4", - "@babel/preset-typescript": "7.21.5", + "@babel/core": "7.22.5", + "@babel/plugin-proposal-decorators": "7.22.5", + "@babel/plugin-transform-runtime": "7.22.5", + "@babel/preset-env": "7.22.5", + "@babel/preset-typescript": "7.22.5", "@koa/cors": "4.0.0", "@octokit/auth-oauth-device": "4.0.4", "@octokit/plugin-retry": "5.0.2", diff --git a/yarn.lock b/yarn.lock index 9ac5e885eb..64b7250dcc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,119 +38,119 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.11, @babel/code-frame@npm:^7.21.4": - version: 7.21.4 - resolution: "@babel/code-frame@npm:7.21.4" +"@babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.11, @babel/code-frame@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/code-frame@npm:7.22.5" dependencies: - "@babel/highlight": ^7.18.6 - checksum: e5390e6ec1ac58dcef01d4f18eaf1fd2f1325528661ff6d4a5de8979588b9f5a8e852a54a91b923846f7a5c681b217f0a45c2524eb9560553160cd963b7d592c + "@babel/highlight": ^7.22.5 + checksum: cfe804f518f53faaf9a1d3e0f9f74127ab9a004912c3a16fda07fb6a633393ecb9918a053cb71804204c1b7ec3d49e1699604715e2cfb0c9f7bc4933d324ebb6 languageName: node linkType: hard -"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.22.0, @babel/compat-data@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/compat-data@npm:7.22.3" - checksum: eb001646f41459f42ccb0d39ee8bb3c3c495bc297234817044c0002689c625e3159a6678c53fd31bd98cf21f31472b73506f350fc6906e3bdfa49cb706e2af8d +"@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/compat-data@npm:7.22.5" + checksum: eb1a47ebf79ae268b4a16903e977be52629339806e248455eb9973897c503a04b701f36a9de64e19750d6e081d0561e77a514c8dc470babbeba59ae94298ed18 languageName: node linkType: hard -"@babel/core@npm:7.22.1, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3": - version: 7.22.1 - resolution: "@babel/core@npm:7.22.1" +"@babel/core@npm:7.22.5, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3": + version: 7.22.5 + resolution: "@babel/core@npm:7.22.5" dependencies: "@ampproject/remapping": ^2.2.0 - "@babel/code-frame": ^7.21.4 - "@babel/generator": ^7.22.0 - "@babel/helper-compilation-targets": ^7.22.1 - "@babel/helper-module-transforms": ^7.22.1 - "@babel/helpers": ^7.22.0 - "@babel/parser": ^7.22.0 - "@babel/template": ^7.21.9 - "@babel/traverse": ^7.22.1 - "@babel/types": ^7.22.0 + "@babel/code-frame": ^7.22.5 + "@babel/generator": ^7.22.5 + "@babel/helper-compilation-targets": ^7.22.5 + "@babel/helper-module-transforms": ^7.22.5 + "@babel/helpers": ^7.22.5 + "@babel/parser": ^7.22.5 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.2 json5: ^2.2.2 semver: ^6.3.0 - checksum: bbe45e791f223a7e692d2ea6597a73f48050abd24b119c85c48ac6504c30ce63343a2ea3f79b5847bf4b409ddd8a68b6cdc4f0272ded1d2ef6f6b1e9663432f0 + checksum: 173ae426958c90c7bbd7de622c6f13fcab8aef0fac3f138e2d47bc466d1cd1f86f71ca82ae0acb9032fd8794abed8efb56fea55c031396337eaec0d673b69d56 languageName: node linkType: hard -"@babel/generator@npm:^7.22.0": - version: 7.22.3 - resolution: "@babel/generator@npm:7.22.3" +"@babel/generator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/generator@npm:7.22.5" dependencies: - "@babel/types": ^7.22.3 + "@babel/types": ^7.22.5 "@jridgewell/gen-mapping": ^0.3.2 "@jridgewell/trace-mapping": ^0.3.17 jsesc: ^2.5.1 - checksum: ccb6426ca5b5a38f0d47a3ac9628e223d2aaaa489cbf90ffab41468795c22afe86855f68a58667f0f2673949f1810d4d5a57b826c17984eab3e28fdb34a909e6 + checksum: efa64da70ca88fe69f05520cf5feed6eba6d30a85d32237671488cc355fdc379fe2c3246382a861d49574c4c2f82a317584f8811e95eb024e365faff3232b49d languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-annotate-as-pure@npm:7.18.6" +"@babel/helper-annotate-as-pure@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" dependencies: - "@babel/types": ^7.18.6 - checksum: 88ccd15ced475ef2243fdd3b2916a29ea54c5db3cd0cfabf9d1d29ff6e63b7f7cd1c27264137d7a40ac2e978b9b9a542c332e78f40eb72abe737a7400788fc1b + "@babel/types": ^7.22.5 + checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.18.6": - version: 7.21.5 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.21.5" +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.5" dependencies: - "@babel/types": ^7.21.5 - checksum: 9a033d3d7a6409256272ea6fc03731511af9f936ee0b161ace05d171d7bd5adf455dc85f80437d92277462f6bd2af9af1f2d1967edc21ca4d5966ac0a09cf61d + "@babel/types": ^7.22.5 + checksum: d753acac62399fc6dd354cf1b9441bde0c331c2fe792a4c14904c5e5eafc3cac79478f6aa038e8a51c1148b0af6710a2e619855e4b5d54497ac972eaffed5884 languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.18.9, @babel/helper-compilation-targets@npm:^7.20.7, @babel/helper-compilation-targets@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/helper-compilation-targets@npm:7.22.1" +"@babel/helper-compilation-targets@npm:^7.17.7, @babel/helper-compilation-targets@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-compilation-targets@npm:7.22.5" dependencies: - "@babel/compat-data": ^7.22.0 - "@babel/helper-validator-option": ^7.21.0 + "@babel/compat-data": ^7.22.5 + "@babel/helper-validator-option": ^7.22.5 browserslist: ^4.21.3 lru-cache: ^5.1.1 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: a686a01bd3288cf95ca26faa27958d34c04e2501c4b0858c3a6558776dec20317b5635f33d64c5a635b6fbdfe462a85c30d4bfa0ae7e7ffe3467e4d06442d7c8 + checksum: a479460615acffa0f4fd0a29b740eafb53a93694265207d23a6038ccd18d183a382cacca515e77b7c9b042c3ba80b0aca0da5f1f62215140e81660d2cf721b68 languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/helper-create-class-features-plugin@npm:7.22.1" +"@babel/helper-create-class-features-plugin@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-create-class-features-plugin@npm:7.22.5" dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 - "@babel/helper-environment-visitor": ^7.22.1 - "@babel/helper-function-name": ^7.21.0 - "@babel/helper-member-expression-to-functions": ^7.22.0 - "@babel/helper-optimise-call-expression": ^7.18.6 - "@babel/helper-replace-supers": ^7.22.1 - "@babel/helper-skip-transparent-expression-wrappers": ^7.20.0 - "@babel/helper-split-export-declaration": ^7.18.6 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.22.5 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-replace-supers": ^7.22.5 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: a132d940c345effc55f4d018db4d113be56528cc5f9bdc12d14da311d27febdde9c606c62e81d17c7ab06b44fb7995d6116ed2aceee75ffa6c5e4e2da3c106ba + checksum: f1e91deae06dbee6dd956c0346bca600adfbc7955427795d9d8825f0439a3c3290c789ba2b4a02a1cdf6c1a1bd163dfa16d3d5e96b02a8efb639d2a774e88ed9 languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.1" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.5" dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 + "@babel/helper-annotate-as-pure": ^7.22.5 regexpu-core: ^5.3.1 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 52d875762110d5dac41ce21fa30a2aaa47c119ca58add190a5123b7a843da096854c0b6358c327b8e0dc2f2219a47eace69332d8a26f165f529ec402a4e6f974 + checksum: 94932145beeb1f91856be25fea8de30b4b81b63fbc7c5a207ed97a5ddc34cd1e9b04041ed28bd24ec09cdcfbb62e8d66f820e4fe864672afe0aa2f357c784e11 languageName: node linkType: hard @@ -170,251 +170,246 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.18.9, @babel/helper-environment-visitor@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/helper-environment-visitor@npm:7.22.1" - checksum: a6b4bb5505453bff95518d361ac1de393f0029aeb8b690c70540f4317934c53c43cc4afcda8c752ffa8c272e63ed6b929a56eca28e4978424177b24238b21bf9 +"@babel/helper-environment-visitor@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-environment-visitor@npm:7.22.5" + checksum: 248532077d732a34cd0844eb7b078ff917c3a8ec81a7f133593f71a860a582f05b60f818dc5049c2212e5baa12289c27889a4b81d56ef409b4863db49646c4b1 languageName: node linkType: hard -"@babel/helper-function-name@npm:^7.18.9, @babel/helper-function-name@npm:^7.19.0, @babel/helper-function-name@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/helper-function-name@npm:7.21.0" +"@babel/helper-function-name@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-function-name@npm:7.22.5" dependencies: - "@babel/template": ^7.20.7 - "@babel/types": ^7.21.0 - checksum: d63e63c3e0e3e8b3138fa47b0cd321148a300ef12b8ee951196994dcd2a492cc708aeda94c2c53759a5c9177fffaac0fd8778791286746f72a000976968daf4e + "@babel/template": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: 6b1f6ce1b1f4e513bf2c8385a557ea0dd7fa37971b9002ad19268ca4384bbe90c09681fe4c076013f33deabc63a53b341ed91e792de741b4b35e01c00238177a languageName: node linkType: hard -"@babel/helper-hoist-variables@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-hoist-variables@npm:7.18.6" +"@babel/helper-hoist-variables@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-hoist-variables@npm:7.22.5" dependencies: - "@babel/types": ^7.18.6 - checksum: fd9c35bb435fda802bf9ff7b6f2df06308a21277c6dec2120a35b09f9de68f68a33972e2c15505c1a1a04b36ec64c9ace97d4a9e26d6097b76b4396b7c5fa20f + "@babel/types": ^7.22.5 + checksum: 394ca191b4ac908a76e7c50ab52102669efe3a1c277033e49467913c7ed6f7c64d7eacbeabf3bed39ea1f41731e22993f763b1edce0f74ff8563fd1f380d92cc languageName: node linkType: hard -"@babel/helper-member-expression-to-functions@npm:^7.22.0": - version: 7.22.3 - resolution: "@babel/helper-member-expression-to-functions@npm:7.22.3" +"@babel/helper-member-expression-to-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-member-expression-to-functions@npm:7.22.5" dependencies: - "@babel/types": ^7.22.3 - checksum: c31b7c8096e722ab7717a1e2343b26afa469172aeb1a8643e9387a14bb50d77dd032fafedf282fcde37b90dcadd2e770c0dfea745a3b1de893d607f2ccba7c0f + "@babel/types": ^7.22.5 + checksum: 4bd5791529c280c00743e8bdc669ef0d4cd1620d6e3d35e0d42b862f8262bc2364973e5968007f960780344c539a4b9cf92ab41f5b4f94560a9620f536de2a39 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.18.6, @babel/helper-module-imports@npm:^7.21.4": - version: 7.21.4 - resolution: "@babel/helper-module-imports@npm:7.21.4" +"@babel/helper-module-imports@npm:^7.10.4, @babel/helper-module-imports@npm:^7.18.6, @babel/helper-module-imports@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-module-imports@npm:7.22.5" dependencies: - "@babel/types": ^7.21.4 - checksum: bd330a2edaafeb281fbcd9357652f8d2666502567c0aad71db926e8499c773c9ea9c10dfaae30122452940326d90c8caff5c649ed8e1bf15b23f858758d3abc6 + "@babel/types": ^7.22.5 + checksum: 9ac2b0404fa38b80bdf2653fbeaf8e8a43ccb41bd505f9741d820ed95d3c4e037c62a1bcdcb6c9527d7798d2e595924c4d025daed73283badc180ada2c9c49ad languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.18.6, @babel/helper-module-transforms@npm:^7.20.11, @babel/helper-module-transforms@npm:^7.21.5, @babel/helper-module-transforms@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/helper-module-transforms@npm:7.22.1" +"@babel/helper-module-transforms@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-module-transforms@npm:7.22.5" dependencies: - "@babel/helper-environment-visitor": ^7.22.1 - "@babel/helper-module-imports": ^7.21.4 - "@babel/helper-simple-access": ^7.21.5 - "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/helper-validator-identifier": ^7.19.1 - "@babel/template": ^7.21.9 - "@babel/traverse": ^7.22.1 - "@babel/types": ^7.22.0 - checksum: dfa084211a93c9f0174ab07385fdbf7831bbf5c1ff3d4f984effc489f48670825ad8b817b9e9d2ec6492fde37ed6518c15944e9dd7a60b43a3d9874c9250f5f8 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-module-imports": ^7.22.5 + "@babel/helper-simple-access": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.5 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: 8985dc0d971fd17c467e8b84fe0f50f3dd8610e33b6c86e5b3ca8e8859f9448bcc5c84e08a2a14285ef388351c0484797081c8f05a03770bf44fc27bf4900e68 languageName: node linkType: hard -"@babel/helper-optimise-call-expression@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-optimise-call-expression@npm:7.18.6" +"@babel/helper-optimise-call-expression@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" dependencies: - "@babel/types": ^7.18.6 - checksum: e518fe8418571405e21644cfb39cf694f30b6c47b10b006609a92469ae8b8775cbff56f0b19732343e2ea910641091c5a2dc73b56ceba04e116a33b0f8bd2fbd + "@babel/types": ^7.22.5 + checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.18.9, @babel/helper-plugin-utils@npm:^7.19.0, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.21.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": - version: 7.21.5 - resolution: "@babel/helper-plugin-utils@npm:7.21.5" - checksum: 6f086e9a84a50ea7df0d5639c8f9f68505af510ea3258b3c8ac8b175efdfb7f664436cb48996f71791a1350ba68f47ad3424131e8e718c5e2ad45564484cbb36 +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": + version: 7.22.5 + resolution: "@babel/helper-plugin-utils@npm:7.22.5" + checksum: c0fc7227076b6041acd2f0e818145d2e8c41968cc52fb5ca70eed48e21b8fe6dd88a0a91cbddf4951e33647336eb5ae184747ca706817ca3bef5e9e905151ff5 languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/helper-remap-async-to-generator@npm:7.18.9" +"@babel/helper-remap-async-to-generator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-remap-async-to-generator@npm:7.22.5" dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-wrap-function": ^7.18.9 - "@babel/types": ^7.18.9 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-wrap-function": ^7.22.5 + "@babel/types": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: 4be6076192308671b046245899b703ba090dbe7ad03e0bea897bb2944ae5b88e5e85853c9d1f83f643474b54c578d8ac0800b80341a86e8538264a725fbbefec + checksum: 1e51dcff1c22e97ea3d22034b77788048eb6d8c6860325bd7a1046b7a7135730cefd93b5c96fd9839d76031095d5ffb6f0cd6ee90a5d69a4c7de980d7f4623d9 languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.18.6, @babel/helper-replace-supers@npm:^7.20.7, @babel/helper-replace-supers@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/helper-replace-supers@npm:7.22.1" +"@babel/helper-replace-supers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-replace-supers@npm:7.22.5" dependencies: - "@babel/helper-environment-visitor": ^7.22.1 - "@babel/helper-member-expression-to-functions": ^7.22.0 - "@babel/helper-optimise-call-expression": ^7.18.6 - "@babel/template": ^7.21.9 - "@babel/traverse": ^7.22.1 - "@babel/types": ^7.22.0 - checksum: 4179090f7010cf9456d17ec354df10f4f647d9b57f6e0b021519d504afca977f67ca39ffe04b47369ea671a744309d0d58f436cb4c18aef000f1df3c0e1162ba + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-member-expression-to-functions": ^7.22.5 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: af29deff6c6dc3fa2d1a517390716aa3f4d329855e8689f1d5c3cb07c1b898e614a5e175f1826bb58e9ff1480e6552885a71a9a0ba5161787aaafa2c79b216cc languageName: node linkType: hard -"@babel/helper-simple-access@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/helper-simple-access@npm:7.21.5" +"@babel/helper-simple-access@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-simple-access@npm:7.22.5" dependencies: - "@babel/types": ^7.21.5 - checksum: ad212beaa24be3864c8c95bee02f840222457ccf5419991e2d3e3e39b0f75b77e7e857e0bf4ed428b1cd97acefc87f3831bdb0b9696d5ad0557421f398334fc3 + "@babel/types": ^7.22.5 + checksum: fe9686714caf7d70aedb46c3cce090f8b915b206e09225f1e4dbc416786c2fdbbee40b38b23c268b7ccef749dd2db35f255338fb4f2444429874d900dede5ad2 languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0": - version: 7.20.0 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.20.0" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" dependencies: - "@babel/types": ^7.20.0 - checksum: 34da8c832d1c8a546e45d5c1d59755459ffe43629436707079989599b91e8c19e50e73af7a4bd09c95402d389266731b0d9c5f69e372d8ebd3a709c05c80d7dd + "@babel/types": ^7.22.5 + checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/helper-split-export-declaration@npm:7.18.6" +"@babel/helper-split-export-declaration@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-split-export-declaration@npm:7.22.5" dependencies: - "@babel/types": ^7.18.6 - checksum: c6d3dede53878f6be1d869e03e9ffbbb36f4897c7cc1527dc96c56d127d834ffe4520a6f7e467f5b6f3c2843ea0e81a7819d66ae02f707f6ac057f3d57943a2b + "@babel/types": ^7.22.5 + checksum: d10e05a02f49c1f7c578cea63d2ac55356501bbf58856d97ac9bfde4957faee21ae97c7f566aa309e38a256eef58b58e5b670a7f568b362c00e93dfffe072650 languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/helper-string-parser@npm:7.21.5" - checksum: 36c0ded452f3858e67634b81960d4bde1d1cd2a56b82f4ba2926e97864816021c885f111a7cf81de88a0ed025f49d84a393256700e9acbca2d99462d648705d8 +"@babel/helper-string-parser@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-string-parser@npm:7.22.5" + checksum: 836851ca5ec813077bbb303acc992d75a360267aa3b5de7134d220411c852a6f17de7c0d0b8c8dcc0f567f67874c00f4528672b2a4f1bc978a3ada64c8c78467 languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.18.6, @babel/helper-validator-identifier@npm:^7.19.1": - version: 7.19.1 - resolution: "@babel/helper-validator-identifier@npm:7.19.1" - checksum: 0eca5e86a729162af569b46c6c41a63e18b43dbe09fda1d2a3c8924f7d617116af39cac5e4cd5d431bb760b4dca3c0970e0c444789b1db42bcf1fa41fbad0a3a +"@babel/helper-validator-identifier@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-validator-identifier@npm:7.22.5" + checksum: 7f0f30113474a28298c12161763b49de5018732290ca4de13cdaefd4fd0d635a6fe3f6686c37a02905fb1e64f21a5ee2b55140cf7b070e729f1bd66866506aea languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/helper-validator-option@npm:7.21.0" - checksum: 8ece4c78ffa5461fd8ab6b6e57cc51afad59df08192ed5d84b475af4a7193fc1cb794b59e3e7be64f3cdc4df7ac78bf3dbb20c129d7757ae078e6279ff8c2f07 +"@babel/helper-validator-option@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-validator-option@npm:7.22.5" + checksum: bbeca8a85ee86990215c0424997438b388b8d642d69b9f86c375a174d3cdeb270efafd1ff128bc7a1d370923d13b6e45829ba8581c027620e83e3a80c5c414b3 languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.18.9": - version: 7.20.5 - resolution: "@babel/helper-wrap-function@npm:7.20.5" +"@babel/helper-wrap-function@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-wrap-function@npm:7.22.5" dependencies: - "@babel/helper-function-name": ^7.19.0 - "@babel/template": ^7.18.10 - "@babel/traverse": ^7.20.5 - "@babel/types": ^7.20.5 - checksum: 11a6fc28334368a193a9cb3ad16f29cd7603bab958433efc82ebe59fa6556c227faa24f07ce43983f7a85df826f71d441638442c4315e90a554fe0a70ca5005b + "@babel/helper-function-name": ^7.22.5 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: a4ba2d7577ad3ce92fadaa341ffce3b0e4b389808099b07c80847f9be0852f4b42344612bc1b3d1b796ffb75be56d5957c5c56a1734f6aee5ccbb7cd9ab12691 languageName: node linkType: hard -"@babel/helpers@npm:^7.22.0": - version: 7.22.3 - resolution: "@babel/helpers@npm:7.22.3" +"@babel/helpers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helpers@npm:7.22.5" dependencies: - "@babel/template": ^7.21.9 - "@babel/traverse": ^7.22.1 - "@babel/types": ^7.22.3 - checksum: 385289ee8b87cf9af448bbb9fcf747f6e67600db5f7f64eb4ad97761ee387819bf2212b6a757008286c6bfacf4f3fc0b6de88686f2e517a70fb59996bdfbd1e9 + "@babel/template": ^7.22.5 + "@babel/traverse": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: a96e785029dff72f171190943df895ab0f76e17bf3881efd630bc5fae91215042d1c2e9ed730e8e4adf4da6f28b24bd1f54ed93b90ffbca34c197351872a084e languageName: node linkType: hard -"@babel/highlight@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/highlight@npm:7.18.6" +"@babel/highlight@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/highlight@npm:7.22.5" dependencies: - "@babel/helper-validator-identifier": ^7.18.6 + "@babel/helper-validator-identifier": ^7.22.5 chalk: ^2.0.0 js-tokens: ^4.0.0 - checksum: 92d8ee61549de5ff5120e945e774728e5ccd57fd3b2ed6eace020ec744823d4a98e242be1453d21764a30a14769ecd62170fba28539b211799bbaf232bbb2789 + checksum: f61ae6de6ee0ea8d9b5bcf2a532faec5ab0a1dc0f7c640e5047fc61630a0edb88b18d8c92eb06566d30da7a27db841aca11820ecd3ebe9ce514c9350fbed39c4 languageName: node linkType: hard -"@babel/parser@npm:^7.18.4, @babel/parser@npm:^7.21.9, @babel/parser@npm:^7.22.0": - version: 7.22.3 - resolution: "@babel/parser@npm:7.22.3" +"@babel/parser@npm:^7.18.4, @babel/parser@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/parser@npm:7.22.5" bin: parser: ./bin/babel-parser.js - checksum: 016f2960212fd86817e15d90b9b3450d2b51af189b1c17a20ade5735d9ec69e76e29def317e09188ecd5fa6eab4f9ab72d88b8b829c1b2994400a6a2c2dc1958 + checksum: 470ebba516417ce8683b36e2eddd56dcfecb32c54b9bb507e28eb76b30d1c3e618fd0cfeee1f64d8357c2254514e1a19e32885cfb4e73149f4ae875436a6d59c languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.18.6" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: 845bd280c55a6a91d232cfa54eaf9708ec71e594676fe705794f494bb8b711d833b752b59d1a5c154695225880c23dbc9cab0e53af16fd57807976cd3ff41b8d + checksum: 1e353a060fb2cd8f1256d28cd768f16fb02513f905b9b6d656fb0242c96c341a196fa188b27c2701506a6e27515359fbcc1a5ca7fa8b9b530cf88fbd137baefc languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.22.3" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.20.0 - "@babel/plugin-transform-optional-chaining": ^7.22.3 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/plugin-transform-optional-chaining": ^7.22.5 peerDependencies: "@babel/core": ^7.13.0 - checksum: d786e4d89c0674cab4fb65e804920782b2ff8319a3e6c561c81b0265451f4ac9f8ce1f9699303398636352b5177730e31c219a086b72980bf39f98faadeab3c1 + checksum: 16e7a5f3bf2f2ac0ca032a70bf0ebd7e886d84dbb712b55c0643c04c495f0f221fbcbca14b5f8f8027fa6c87a3dafae0934022ad2b409384af6c5c356495b7bd languageName: node linkType: hard -"@babel/plugin-proposal-decorators@npm:7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-proposal-decorators@npm:7.22.3" +"@babel/plugin-proposal-decorators@npm:7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-proposal-decorators@npm:7.22.5" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-replace-supers": ^7.22.1 - "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/plugin-syntax-decorators": ^7.22.3 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-replace-supers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 + "@babel/plugin-syntax-decorators": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e68d9311924095d6e35a8ed52dfaa06ec8a24bbfa2ca2a241a9ef31a543b014eaf32e6434b737cf87368ffc3051d80091d8640554f99f34211caaa7e90985ea9 + checksum: b3807b92b6ffcaba7519a9b2bb59e4b5530873234cd170ff5727414939334fbcae17bbe523df846a103e2fc8ed2d2890d0d9408f073cfc1e90c28ab565c358e5 languageName: node linkType: hard -"@babel/plugin-proposal-private-property-in-object@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0" - dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 - "@babel/helper-create-class-features-plugin": ^7.21.0 - "@babel/helper-plugin-utils": ^7.20.2 - "@babel/plugin-syntax-private-property-in-object": ^7.14.5 +"@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": + version: 7.21.0-placeholder-for-preset-env.2 + resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: add881a6a836635c41d2710551fdf777e2c07c0b691bf2baacc5d658dd64107479df1038680d6e67c468bfc6f36fb8920025d6bac2a1df0a81b867537d40ae78 + checksum: d97745d098b835d55033ff3a7fb2b895b9c5295b08a5759e4f20df325aa385a3e0bc9bd5ad8f2ec554a44d4e6525acfc257b8c5848a1345cb40f26a30e277e91 languageName: node linkType: hard @@ -463,14 +458,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-decorators@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-syntax-decorators@npm:7.22.3" +"@babel/plugin-syntax-decorators@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-decorators@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1886778ae5284202329e60f5be3322307dc77d0764a75e23f8fc222bc05409f4153035eb817cabd40265cc1c20eb201ca539c8cd2e883b312024dbb6480cdd95 + checksum: 643c75a3b603320c499a0542ca97b5cced81e99de02ae9cbfca1a1ec6d938467546a65023b13df742e1b2f94ffe352ddfe908d14b9303fae7514ed9325886a97 languageName: node linkType: hard @@ -496,25 +491,25 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-assertions@npm:^7.12.1, @babel/plugin-syntax-import-assertions@npm:^7.20.0": - version: 7.20.0 - resolution: "@babel/plugin-syntax-import-assertions@npm:7.20.0" +"@babel/plugin-syntax-import-assertions@npm:^7.12.1, @babel/plugin-syntax-import-assertions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.19.0 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6a86220e0aae40164cd3ffaf80e7c076a1be02a8f3480455dddbae05fda8140f429290027604df7a11b3f3f124866e8a6d69dbfa1dda61ee7377b920ad144d5b + checksum: 2b8b5572db04a7bef1e6cd20debf447e4eef7cb012616f5eceb8fa3e23ce469b8f76ee74fd6d1e158ba17a8f58b0aec579d092fb67c5a30e83ccfbc5754916c1 languageName: node linkType: hard -"@babel/plugin-syntax-import-attributes@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-syntax-import-attributes@npm:7.22.3" +"@babel/plugin-syntax-import-attributes@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 48cf66ba1b6772134f4e638c42ff51a0e8037cea540733642146e031641641e8a03e4f43e6be613e2313d174f95d9b3a1f14f41db0a9fa78a8330282b5aad03c + checksum: 197b3c5ea2a9649347f033342cb222ab47f4645633695205c0250c6bf2af29e643753b8bb24a2db39948bef08e7c540babfd365591eb57fc110cb30b425ffc47 languageName: node linkType: hard @@ -540,14 +535,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.21.4": - version: 7.21.4 - resolution: "@babel/plugin-syntax-jsx@npm:7.21.4" +"@babel/plugin-syntax-jsx@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-jsx@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: bb7309402a1d4e155f32aa0cf216e1fa8324d6c4cfd248b03280028a015a10e46b6efd6565f515f8913918a3602b39255999c06046f7d4b8a5106be2165d724a + checksum: 8829d30c2617ab31393d99cec2978e41f014f4ac6f01a1cecf4c4dd8320c3ec12fdc3ce121126b2d8d32f6887e99ca1a0bad53dedb1e6ad165640b92b24980ce languageName: node linkType: hard @@ -639,14 +634,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.20.0": - version: 7.21.4 - resolution: "@babel/plugin-syntax-typescript@npm:7.21.4" +"@babel/plugin-syntax-typescript@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a59ce2477b7ae8c8945dc37dda292fef9ce46a6507b3d76b03ce7f3a6c9451a6567438b20a78ebcb3955d04095fd1ccd767075a863f79fcc30aa34dcfa441fe0 + checksum: 8ab7718fbb026d64da93681a57797d60326097fd7cb930380c8bffd9eb101689e90142c760a14b51e8e69c88a73ba3da956cb4520a3b0c65743aee5c71ef360a languageName: node linkType: hard @@ -662,634 +657,634 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.21.5" +"@babel/plugin-transform-arrow-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c7c281cdf37c33a584102d9fd1793e85c96d4d320cdfb7c43f1ce581323d057f13b53203994fcc7ee1f8dc1ff013498f258893aa855a06c6f830fcc4c33d6e44 + checksum: 35abb6c57062802c7ce8bd96b2ef2883e3124370c688bbd67609f7d2453802fb73944df8808f893b6c67de978eb2bcf87bbfe325e46d6f39b5fcb09ece11d01a languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.22.3" +"@babel/plugin-transform-async-generator-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.22.5" dependencies: - "@babel/helper-environment-visitor": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-remap-async-to-generator": ^7.18.9 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-remap-async-to-generator": ^7.22.5 "@babel/plugin-syntax-async-generators": ^7.8.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0ea339f9e484df0b72eb962dca81f5e6291d674eb4de7af2cde2a7e2ff728fbc4fdad662f2e77bf5bdbd2b628e111b9a7c71c3165684147ca1bf1f891fc30a4b + checksum: 32890b69ec5627eb46ee8e084bddc6b98d85b66cae5e015f3a23924611a759789d2ff836406605f5293b5c2bad306b20cb1f5b7a46ed549b07bfec634bcd31f9 languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.20.7": - version: 7.20.7 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.20.7" +"@babel/plugin-transform-async-to-generator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.22.5" dependencies: - "@babel/helper-module-imports": ^7.18.6 - "@babel/helper-plugin-utils": ^7.20.2 - "@babel/helper-remap-async-to-generator": ^7.18.9 + "@babel/helper-module-imports": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-remap-async-to-generator": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: fe9ee8a5471b4317c1b9ea92410ace8126b52a600d7cfbfe1920dcac6fb0fad647d2e08beb4fd03c630eb54430e6c72db11e283e3eddc49615c68abd39430904 + checksum: b95f23f99dcb379a9f0a1c2a3bbea3f8dc0e1b16dc1ac8b484fe378370169290a7a63d520959a9ba1232837cf74a80e23f6facbe14fd42a3cda6d3c2d7168e62 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.18.6" +"@babel/plugin-transform-block-scoped-functions@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0a0df61f94601e3666bf39f2cc26f5f7b22a94450fb93081edbed967bd752ce3f81d1227fefd3799f5ee2722171b5e28db61379234d1bb85b6ec689589f99d7e + checksum: 416b1341858e8ca4e524dee66044735956ced5f478b2c3b9bc11ec2285b0c25d7dbb96d79887169eb938084c95d0a89338c8b2fe70d473bd9dc92e5d9db1732c languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/plugin-transform-block-scoping@npm:7.21.0" +"@babel/plugin-transform-block-scoping@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-block-scoping@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 15aacaadbecf96b53a750db1be4990b0d89c7f5bc3e1794b63b49fb219638c1fd25d452d15566d7e5ddf5b5f4e1a0a0055c35c1c7aee323c7b114bf49f66f4b0 + checksum: 26987002cfe6e24544e60fa35f07052b6557f590c1a1cc5cf35d6dc341d7fea163c1222a2d70d5d2692f0b9860d942fd3ba979848b2995d4debffa387b9b19ae languageName: node linkType: hard -"@babel/plugin-transform-class-properties@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-class-properties@npm:7.22.3" +"@babel/plugin-transform-class-properties@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-class-properties@npm:7.22.5" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4037397badb5d537d87c092da99a0278f735e66dc667a31495aa2dd5fcf1315bfe8981773d2ce502ff8048c68ab32a7c3019df714945520443e28380fa5e7f74 + checksum: b830152dfc2ff2f647f0abe76e6251babdfbef54d18c4b2c73a6bf76b1a00050a5d998dac80dc901a48514e95604324943a9dd39317073fe0928b559e0e0c579 languageName: node linkType: hard -"@babel/plugin-transform-class-static-block@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-class-static-block@npm:7.22.3" +"@babel/plugin-transform-class-static-block@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-class-static-block@npm:7.22.5" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-class-static-block": ^7.14.5 peerDependencies: "@babel/core": ^7.12.0 - checksum: f407a3354ee0720803cd3366d7d081643d37201892243deed1aa76eb9330c11bf4e548441fa6a77637262a1b61890c1aacea176ad828650b8eb3f5b4d2da9c97 + checksum: bc48b92dbaf625a14f2bf62382384eef01e0515802426841636ae9146e27395d068c7a8a45e9e15699491b0a01d990f38f179cbc9dc89274a393f85648772f12 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.21.0": - version: 7.21.0 - resolution: "@babel/plugin-transform-classes@npm:7.21.0" +"@babel/plugin-transform-classes@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-classes@npm:7.22.5" dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 - "@babel/helper-compilation-targets": ^7.20.7 - "@babel/helper-environment-visitor": ^7.18.9 - "@babel/helper-function-name": ^7.21.0 - "@babel/helper-optimise-call-expression": ^7.18.6 - "@babel/helper-plugin-utils": ^7.20.2 - "@babel/helper-replace-supers": ^7.20.7 - "@babel/helper-split-export-declaration": ^7.18.6 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-compilation-targets": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-replace-supers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 globals: ^11.1.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 088ae152074bd0e90f64659169255bfe50393e637ec8765cb2a518848b11b0299e66b91003728fd0a41563a6fdc6b8d548ece698a314fd5447f5489c22e466b7 + checksum: 124b1b79180524cc9d08155cecde92c7f2ab0db02cbe0f8befa187ef3c7320909ce1a6d6daf5ce73e8330f9b40cf9991f424c6e572b8dddc1f14e2758fa80d20 languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/plugin-transform-computed-properties@npm:7.21.5" +"@babel/plugin-transform-computed-properties@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-computed-properties@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/template": ^7.20.7 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/template": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e819780ab30fc40d7802ffb75b397eff63ca4942a1873058f81c80f660189b78e158fa03fd3270775f0477c4c33cee3d8d40270e64404bbf24aa6cdccb197e7b + checksum: c2a77a0f94ec71efbc569109ec14ea2aa925b333289272ced8b33c6108bdbb02caf01830ffc7e49486b62dec51911924d13f3a76f1149f40daace1898009e131 languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.21.3": - version: 7.21.3 - resolution: "@babel/plugin-transform-destructuring@npm:7.21.3" +"@babel/plugin-transform-destructuring@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-destructuring@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 43ebbe0bfa20287e34427be7c2200ce096c20913775ea75268fb47fe0e55f9510800587e6052c42fe6dffa0daaad95dd465c3e312fd1ef9785648384c45417ac + checksum: 76f6ea2aee1fcfa1c3791eb7a5b89703c6472650b993e8666fff0f1d6e9d737a84134edf89f63c92297f3e75064c1263219463b02dd9bc7434b6e5b9935e3f20 languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.18.6, @babel/plugin-transform-dotall-regex@npm:^7.4.4": - version: 7.18.6 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.18.6" +"@babel/plugin-transform-dotall-regex@npm:^7.22.5, @babel/plugin-transform-dotall-regex@npm:^7.4.4": + version: 7.22.5 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.22.5" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.18.6 - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: cbe5d7063eb8f8cca24cd4827bc97f5641166509e58781a5f8aa47fb3d2d786ce4506a30fca2e01f61f18792783a5cb5d96bf5434c3dd1ad0de8c9cc625a53da + checksum: 409b658d11e3082c8f69e9cdef2d96e4d6d11256f005772425fb230cc48fd05945edbfbcb709dab293a1a2f01f9c8a5bb7b4131e632b23264039d9f95864b453 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.18.9" +"@babel/plugin-transform-duplicate-keys@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.9 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 220bf4a9fec5c4d4a7b1de38810350260e8ea08481bf78332a464a21256a95f0df8cd56025f346238f09b04f8e86d4158fafc9f4af57abaef31637e3b58bd4fe + checksum: bb1280fbabaab6fab2ede585df34900712698210a3bd413f4df5bae6d8c24be36b496c92722ae676a7a67d060a4624f4d6c23b923485f906bfba8773c69f55b4 languageName: node linkType: hard -"@babel/plugin-transform-dynamic-import@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/plugin-transform-dynamic-import@npm:7.22.1" +"@babel/plugin-transform-dynamic-import@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-dynamic-import": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e322a08f01cedddcd7c70aa6a74342e900df39ab13dbaa2c8175af660b1786dd26b582546fc37e16bec47181931963e173ff53ffd7c41d5f54687da5f8d457bb + checksum: 186a6d59f36eb3c5824739fc9c22ed0f4ca68e001662aa3a302634346a8b785cb9579b23b0c158f4570604d697d19598ca09b58c60a7fa2894da1163c4eb1907 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.18.6" +"@babel/plugin-transform-exponentiation-operator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.22.5" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": ^7.18.6 - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-builder-binary-assignment-operator-visitor": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7f70222f6829c82a36005508d34ddbe6fd0974ae190683a8670dd6ff08669aaf51fef2209d7403f9bd543cb2d12b18458016c99a6ed0332ccedb3ea127b01229 + checksum: f2d660c1b1d51ad5fec1cd5ad426a52187204068c4158f8c4aa977b31535c61b66898d532603eef21c15756827be8277f724c869b888d560f26d7fe848bb5eae languageName: node linkType: hard -"@babel/plugin-transform-export-namespace-from@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-export-namespace-from@npm:7.22.3" +"@babel/plugin-transform-export-namespace-from@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-export-namespace-from": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7bb031ea6e05e8090ac18dc03c62527be29f541e9ec0c93031d77d4540c736b43384a2f2a9aef1f72b7867989f1ce2aaefb325dbc7cc49c59f55aed87a96d488 + checksum: 3d197b788758044983c96b9c49bed4b456055f35a388521a405968db0f6e2ffb6fd59110e3931f4dcc5e126ae9e5e00e154a0afb47a7ea359d8d0dea79f480d7 languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/plugin-transform-for-of@npm:7.21.5" +"@babel/plugin-transform-for-of@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-for-of@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b6666b24e8ca1ffbf7452a0042149724e295965aad55070dc9ee992451d69d855fc9db832c1c5fb4d3dc532f4a18a2974d5f8524f5c2250dda888d05f6f3cadb + checksum: d7b8d4db010bce7273674caa95c4e6abd909362866ce297e86a2ecaa9ae636e05d525415811db9b3c942155df7f3651d19b91dd6c41f142f7308a97c7cb06023 languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/plugin-transform-function-name@npm:7.18.9" +"@babel/plugin-transform-function-name@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-function-name@npm:7.22.5" dependencies: - "@babel/helper-compilation-targets": ^7.18.9 - "@babel/helper-function-name": ^7.18.9 - "@babel/helper-plugin-utils": ^7.18.9 + "@babel/helper-compilation-targets": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 62dd9c6cdc9714704efe15545e782ee52d74dc73916bf954b4d3bee088fb0ec9e3c8f52e751252433656c09f744b27b757fc06ed99bcde28e8a21600a1d8e597 + checksum: cff3b876357999cb8ae30e439c3ec6b0491a53b0aa6f722920a4675a6dd5b53af97a833051df4b34791fe5b3dd326ccf769d5c8e45b322aa50ee11a660b17845 languageName: node linkType: hard -"@babel/plugin-transform-json-strings@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-json-strings@npm:7.22.3" +"@babel/plugin-transform-json-strings@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-json-strings@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-json-strings": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2b09a549bdd80020b390dbc91aaf0be624e42fff64026a38abad1ec6c7714551edad8a84edb555288778aa9e3bb20e9df535587466b30347b63532fb1f404731 + checksum: 4e00b902487a670b6c8948f33f9108133fd745cf9d1478aca515fb460b9b2f12e137988ebc1663630fb82070a870aed8b0c1aa4d007a841c18004619798f255c languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/plugin-transform-literals@npm:7.18.9" +"@babel/plugin-transform-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-literals@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.9 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3458dd2f1a47ac51d9d607aa18f3d321cbfa8560a985199185bed5a906bb0c61ba85575d386460bac9aed43fdd98940041fae5a67dff286f6f967707cff489f8 + checksum: ec37cc2ffb32667af935ab32fe28f00920ec8a1eb999aa6dc6602f2bebd8ba205a558aeedcdccdebf334381d5c57106c61f52332045730393e73410892a9735b languageName: node linkType: hard -"@babel/plugin-transform-logical-assignment-operators@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.22.3" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b2452c6804aa440bd3fc662ee4f477c3acfa4a7f768ac66a6084a9e0774ac52cfff7cc6ea72495cc4e0728d2d7f98b65555927484dc96e9564adf1bcc5aa956e + checksum: 18748e953c08f64885f18c224eac58df10a13eac4d845d16b5d9b6276907da7ca2530dfebe6ed41cdc5f8a75d9db3e36d8eb54ddce7cd0364af1cab09b435302 languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.18.6" +"@babel/plugin-transform-member-expression-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 35a3d04f6693bc6b298c05453d85ee6e41cc806538acb6928427e0e97ae06059f97d2f07d21495fcf5f70d3c13a242e2ecbd09d5c1fcb1b1a73ff528dcb0b695 + checksum: ec4b0e07915ddd4fda0142fd104ee61015c208608a84cfa13643a95d18760b1dc1ceb6c6e0548898b8c49e5959a994e46367260176dbabc4467f729b21868504 languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.20.11": - version: 7.20.11 - resolution: "@babel/plugin-transform-modules-amd@npm:7.20.11" +"@babel/plugin-transform-modules-amd@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-modules-amd@npm:7.22.5" dependencies: - "@babel/helper-module-transforms": ^7.20.11 - "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-module-transforms": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 23665c1c20c8f11c89382b588fb9651c0756d130737a7625baeaadbd3b973bc5bfba1303bedffa8fb99db1e6d848afb01016e1df2b69b18303e946890c790001 + checksum: 7da4c4ebbbcf7d182abb59b2046b22d86eee340caf8a22a39ef6a727da2d8acfec1f714fcdcd5054110b280e4934f735e80a6848d192b6834c5d4459a014f04d languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.21.5" +"@babel/plugin-transform-modules-commonjs@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.22.5" dependencies: - "@babel/helper-module-transforms": ^7.21.5 - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-simple-access": ^7.21.5 + "@babel/helper-module-transforms": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-simple-access": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d9ff7a21baaa60c08a0c86c5e468bb4b2bd85caf51ba78712d8f45e9afa2498d50d6cdf349696e08aa820cafed65f19b70e5938613db9ebb095f7aba1127f282 + checksum: 2067aca8f6454d54ffcce69b02c457cfa61428e11372f6a1d99ff4fcfbb55c396ed2ca6ca886bf06c852e38c1a205b8095921b2364fd0243f3e66bc1dda61caa languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.22.3" +"@babel/plugin-transform-modules-systemjs@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.22.5" dependencies: - "@babel/helper-hoist-variables": ^7.18.6 - "@babel/helper-module-transforms": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-validator-identifier": ^7.19.1 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-module-transforms": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a12a063dad61cccf50686d3f394f9f3f6c06261160c897a4b3423309aa7c40d37bd88126cf8535701f3490b99ac93b34c947f664465d63a74477ba66ab1d82e9 + checksum: 04f4178589543396b3c24330a67a59c5e69af5e96119c9adda730c0f20122deaff54671ebbc72ad2df6495a5db8a758bd96942de95fba7ad427de9c80b1b38c8 languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-modules-umd@npm:7.18.6" +"@babel/plugin-transform-modules-umd@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-modules-umd@npm:7.22.5" dependencies: - "@babel/helper-module-transforms": ^7.18.6 - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-module-transforms": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c3b6796c6f4579f1ba5ab0cdcc73910c1e9c8e1e773c507c8bb4da33072b3ae5df73c6d68f9126dab6e99c24ea8571e1563f8710d7c421fac1cde1e434c20153 + checksum: 46622834c54c551b231963b867adbc80854881b3e516ff29984a8da989bd81665bd70e8cba6710345248e97166689310f544aee1a5773e262845a8f1b3e5b8b4 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.3" +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: baf3d8d785ab36df2d7396b8a255e1209eecf83ad5334121fbb9e966a95353fe2100dd3683436f4c74b3c848ec0b34817491c4d14b074e3e539e2040076173d8 + checksum: 3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-new-target@npm:7.22.3" +"@babel/plugin-transform-new-target@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-new-target@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a28043575aae52127b7287711cf0b244a28279464d979858408ca6197169b6f7e6341e5b4554a894d409245fcd696c9bf38d5f1f1c64f84a82f479bf35659920 + checksum: 6b72112773487a881a1d6ffa680afde08bad699252020e86122180ee7a88854d5da3f15d9bca3331cf2e025df045604494a8208a2e63b486266b07c14e2ffbf3 languageName: node linkType: hard -"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.22.3" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 404c3c7eb8b99f226ce40147d350ad3df55b38ffe39856356f7cfbbb1626ce060bc1daff0663c090d53160d39fdb26ea67ca291d47211ff7746a8a0c3bbc1639 + checksum: e6a059169d257fc61322d0708edae423072449b7c33de396261e68dee582aec5396789a1c22bce84e5bd88a169623c2e750b513fc222930979e6accd52a44bf2 languageName: node linkType: hard -"@babel/plugin-transform-numeric-separator@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-numeric-separator@npm:7.22.3" +"@babel/plugin-transform-numeric-separator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-numeric-separator": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2cbcf21d040cb9ab6ded383586620f3a84e8619fecdc222d8b3d462c706b1e8ceae2dddf530d9177291c155c80dd67100142e76a11f1e230aeda6d90273a2890 + checksum: 9e7837d4eae04f211ebaa034fe5003d2927b6bf6d5b9dc09f2b1183c01482cdde5a75b8bd5c7ff195c2abc7b923339eb0b2a9d27cb78359d38248a3b2c2367c4 languageName: node linkType: hard -"@babel/plugin-transform-object-rest-spread@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-object-rest-spread@npm:7.22.3" +"@babel/plugin-transform-object-rest-spread@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.22.5" dependencies: - "@babel/compat-data": ^7.22.3 - "@babel/helper-compilation-targets": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/compat-data": ^7.22.5 + "@babel/helper-compilation-targets": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-object-rest-spread": ^7.8.3 - "@babel/plugin-transform-parameters": ^7.22.3 + "@babel/plugin-transform-parameters": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 43f4cb8eb60e76bb506cab86a6c9a98b2f4f986296a20a01f93c6a7bf3835621a22e3e85eaca094c86b03580f93e583391f4c0da0af0c9408ff1a2b35f2e96ca + checksum: 3b5e091f0dc67108f2e41ed5a97e15bbe4381a19d9a7eea80b71c7de1d8169fd28784e1e41a3d2ad12709ab212e58fc481282a5bb65d591fae7b443048de3330 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-object-super@npm:7.18.6" +"@babel/plugin-transform-object-super@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-object-super@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 - "@babel/helper-replace-supers": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-replace-supers": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0fcb04e15deea96ae047c21cb403607d49f06b23b4589055993365ebd7a7d7541334f06bf9642e90075e66efce6ebaf1eb0ef066fbbab802d21d714f1aac3aef + checksum: b71887877d74cb64dbccb5c0324fa67e31171e6a5311991f626650e44a4083e5436a1eaa89da78c0474fb095d4ec322d63ee778b202d33aa2e4194e1ed8e62d7 languageName: node linkType: hard -"@babel/plugin-transform-optional-catch-binding@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.22.3" +"@babel/plugin-transform-optional-catch-binding@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e766bd2ac74fcd2226c8816500c788268a1fa5200498a288f10854253addb36871cd7b415e20736819e7fcb996a0e33312bc1ce6db9b540ec9dd7b946cb37dda + checksum: b0e8b4233ff06b5c9d285257f49c5bd441f883189b24282e6200f9ebdf5db29aeeebbffae57fbbcd5df9f4387b3e66e5d322aaae5652a78e89685ddbae46bbd1 languageName: node linkType: hard -"@babel/plugin-transform-optional-chaining@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-optional-chaining@npm:7.22.3" +"@babel/plugin-transform-optional-chaining@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.20.0 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 "@babel/plugin-syntax-optional-chaining": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9b50a28b59250ecabeae928b8237c596e6f81f5fcdacd03a99a3777bbfea2447773936f4b5091e63b2d46e707429d9bdf22fcd0fb4b05a702bf08f554bea3ae2 + checksum: 57b9c05fb22ae881b8a334b184fc6ee966661ed5d1eb4eed8c2fb9a12e68150d90b229efcb1aa777e246999830844fee06d7365f8bb4bb262fdcd23876ff3ea2 languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-parameters@npm:7.22.3" +"@babel/plugin-transform-parameters@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-parameters@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 68a30f630f5d99be7675fab23d009205302f33f1eac015418d5344983fe8f97f4eae0130f6e4f3c21b8dd8971d516346fba90b01ba3c2c15f23b47c6f4b7161a + checksum: b44f89cf97daf23903776ba27c2ab13b439d80d8c8a95be5c476ab65023b1e0c0e94c28d3745f3b60a58edc4e590fa0cd4287a0293e51401ca7d29a2ddb13b8e languageName: node linkType: hard -"@babel/plugin-transform-private-methods@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-private-methods@npm:7.22.3" +"@babel/plugin-transform-private-methods@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-private-methods@npm:7.22.5" dependencies: - "@babel/helper-create-class-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 048501cfdf86c3de5750dc0728cf73d65f1ec4ad932e16e55b238ac0b5b805882c1fbbdb63077d95ce8beadae840cee11b767cc6918264517245e7f04baf9f63 + checksum: 321479b4fcb6d3b3ef622ab22fd24001e43d46e680e8e41324c033d5810c84646e470f81b44cbcbef5c22e99030784f7cac92f1829974da7a47a60a7139082c3 languageName: node linkType: hard -"@babel/plugin-transform-private-property-in-object@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-private-property-in-object@npm:7.22.3" +"@babel/plugin-transform-private-property-in-object@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.22.5" dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 - "@babel/helper-create-class-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 "@babel/plugin-syntax-private-property-in-object": ^7.14.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ea3c347687672119305ba2f2ef7ca66905c1713c6652bb01deacc057178bedcf07c46b6b75e1fe8688ffed8fcabe312a735eeb0fef21dd9ab61a61db23ef6ba5 + checksum: 9ac019fb2772f3af6278a7f4b8b14b0663accb3fd123d87142ceb2fbc57fd1afa07c945d1329029b026b9ee122096ef71a3f34f257a9e04cf4245b87298c38b4 languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-property-literals@npm:7.18.6" +"@babel/plugin-transform-property-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-property-literals@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1c16e64de554703f4b547541de2edda6c01346dd3031d4d29e881aa7733785cd26d53611a4ccf5353f4d3e69097bb0111c0a93ace9e683edd94fea28c4484144 + checksum: 796176a3176106f77fcb8cd04eb34a8475ce82d6d03a88db089531b8f0453a2fb8b0c6ec9a52c27948bc0ea478becec449893741fc546dfc3930ab927e3f9f2e languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/plugin-transform-regenerator@npm:7.21.5" +"@babel/plugin-transform-regenerator@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-regenerator@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 regenerator-transform: ^0.15.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5291f6871276f57a6004f16d50ae9ad57f22a6aa2a183b8c84de8126f1066c6c9f9bbeadb282b5207fa9e7b0f57e40a8421d46cb5c60caf7e2848e98224d5639 + checksum: f7c5ca5151321963df777cc02725d10d1ccc3b3b8323da0423aecd9ac6144cbdd2274af5281a5580db2fc2f8b234e318517b5d76b85669118906533a559f2b6a languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-reserved-words@npm:7.18.6" +"@babel/plugin-transform-reserved-words@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-reserved-words@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0738cdc30abdae07c8ec4b233b30c31f68b3ff0eaa40eddb45ae607c066127f5fa99ddad3c0177d8e2832e3a7d3ad115775c62b431ebd6189c40a951b867a80c + checksum: 3ffd7dbc425fe8132bfec118b9817572799cab1473113a635d25ab606c1f5a2341a636c04cf6b22df3813320365ed5a965b5eeb3192320a10e4cc2c137bd8bfc languageName: node linkType: hard -"@babel/plugin-transform-runtime@npm:7.22.4": - version: 7.22.4 - resolution: "@babel/plugin-transform-runtime@npm:7.22.4" +"@babel/plugin-transform-runtime@npm:7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-runtime@npm:7.22.5" dependencies: - "@babel/helper-module-imports": ^7.21.4 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-module-imports": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 babel-plugin-polyfill-corejs2: ^0.4.3 babel-plugin-polyfill-corejs3: ^0.8.1 babel-plugin-polyfill-regenerator: ^0.5.0 semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e51400ffeccfc8875c6d136510aa6145e44d825ee7fb52da462401388b4303a6a274ca94fad4aa46b06870c6fdc6141dafa51f681423160d924a21212daa8792 + checksum: 52cf177045b5f61a6cfc36b45aa7629586dc00a28371a09ef03e877a627f520efd51817ad8cceabaaa25f266e069859b36a5ac5018afeaa7f37aafa9325df4d8 languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.18.6" +"@babel/plugin-transform-shorthand-properties@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b8e4e8acc2700d1e0d7d5dbfd4fdfb935651913de6be36e6afb7e739d8f9ca539a5150075a0f9b79c88be25ddf45abb912fe7abf525f0b80f5b9d9860de685d7 + checksum: a5ac902c56ea8effa99f681340ee61bac21094588f7aef0bc01dff98246651702e677552fa6d10e548c4ac22a3ffad047dd2f8c8f0540b68316c2c203e56818b languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.20.7": - version: 7.20.7 - resolution: "@babel/plugin-transform-spread@npm:7.20.7" +"@babel/plugin-transform-spread@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-spread@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.20.2 - "@babel/helper-skip-transparent-expression-wrappers": ^7.20.0 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8ea698a12da15718aac7489d4cde10beb8a3eea1f66167d11ab1e625033641e8b328157fd1a0b55dd6531933a160c01fc2e2e61132a385cece05f26429fd0cc2 + checksum: 5587f0deb60b3dfc9b274e269031cc45ec75facccf1933ea2ea71ced9fd3ce98ed91bb36d6cd26817c14474b90ed998c5078415f0eab531caf301496ce24c95c languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.18.6" +"@babel/plugin-transform-sticky-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 68ea18884ae9723443ffa975eb736c8c0d751265859cd3955691253f7fee37d7a0f7efea96c8a062876af49a257a18ea0ed5fea0d95a7b3611ce40f7ee23aee3 + checksum: 63b2c575e3e7f96c32d52ed45ee098fb7d354b35c2223b8c8e76840b32cc529ee0c0ceb5742fd082e56e91e3d82842a367ce177e82b05039af3d602c9627a729 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/plugin-transform-template-literals@npm:7.18.9" +"@babel/plugin-transform-template-literals@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-template-literals@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.9 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3d2fcd79b7c345917f69b92a85bdc3ddd68ce2c87dc70c7d61a8373546ccd1f5cb8adc8540b49dfba08e1b82bb7b3bbe23a19efdb2b9c994db2db42906ca9fb2 + checksum: 27e9bb030654cb425381c69754be4abe6a7c75b45cd7f962cd8d604b841b2f0fb7b024f2efc1c25cc53f5b16d79d5e8cfc47cacbdaa983895b3aeefa3e7e24ff languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.18.9": - version: 7.18.9 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.18.9" +"@babel/plugin-transform-typeof-symbol@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.18.9 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e754e0d8b8a028c52e10c148088606e3f7a9942c57bd648fc0438e5b4868db73c386a5ed47ab6d6f0594aae29ee5ffc2ffc0f7ebee7fae560a066d6dea811cd4 + checksum: 82a53a63ffc3010b689ca9a54e5f53b2718b9f4b4a9818f36f9b7dba234f38a01876680553d2716a645a61920b5e6e4aaf8d4a0064add379b27ca0b403049512 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.21.3": - version: 7.21.3 - resolution: "@babel/plugin-transform-typescript@npm:7.21.3" +"@babel/plugin-transform-typescript@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-typescript@npm:7.22.5" dependencies: - "@babel/helper-annotate-as-pure": ^7.18.6 - "@babel/helper-create-class-features-plugin": ^7.21.0 - "@babel/helper-plugin-utils": ^7.20.2 - "@babel/plugin-syntax-typescript": ^7.20.0 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/plugin-syntax-typescript": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c16fd577bf43f633deb76fca2a8527d8ae25968c8efdf327c1955472c3e0257e62992473d1ad7f9ee95379ce2404699af405ea03346055adadd3478ad0ecd117 + checksum: d12f1ca1ef1f2a54432eb044d2999705d1205ebe211c2a7f05b12e8eb2d2a461fd7657b5486b2f2f1efe7c0c0dc8e80725b767073d40fe4ae059a7af057b05e4 languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.21.5": - version: 7.21.5 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.21.5" +"@babel/plugin-transform-unicode-escapes@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6504d642d0449a275191b624bd94d3e434ae154e610bf2f0e3c109068b287d2474f68e1da64b47f21d193cd67b27ee4643877d530187670565cac46e29fd257d + checksum: da5e85ab3bb33a75cbf6181bfd236b208dc934702fd304db127232f17b4e0f42c6d3f238de8589470b4190906967eea8ca27adf3ae9d8ee4de2a2eae906ed186 languageName: node linkType: hard -"@babel/plugin-transform-unicode-property-regex@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.22.3" +"@babel/plugin-transform-unicode-property-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.22.5" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 666592f5f5496e7dc267fb32e5c0d1ca620a5a1b7dcfec4fec517a625d2413213f795d3905aea05f45639285578ef13351cedfc5b699aaa482841866089863f6 + checksum: 2495e5f663cb388e3d888b4ba3df419ac436a5012144ac170b622ddfc221f9ea9bdba839fa2bc0185cb776b578030666406452ec7791cbf0e7a3d4c88ae9574c languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.18.6": - version: 7.18.6 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.18.6" +"@babel/plugin-transform-unicode-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.22.5" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.18.6 - "@babel/helper-plugin-utils": ^7.18.6 + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d9e18d57536a2d317fb0b7c04f8f55347f3cfacb75e636b4c6fa2080ab13a3542771b5120e726b598b815891fc606d1472ac02b749c69fd527b03847f22dc25e + checksum: 6b5d1404c8c623b0ec9bd436c00d885a17d6a34f3f2597996343ddb9d94f6379705b21582dfd4cec2c47fd34068872e74ab6b9580116c0566b3f9447e2a7fa06 languageName: node linkType: hard -"@babel/plugin-transform-unicode-sets-regex@npm:^7.22.3": - version: 7.22.3 - resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.22.3" +"@babel/plugin-transform-unicode-sets-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.22.5" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: 992f6ae2764b1ee3bea9d948132daed22f042517cd6109a8fd2c52c03e7b930fac5a9e6e28130b0ed5a6f1cbf809c9735985352de0484b4c95fb0f6dd88614a2 + checksum: c042070f980b139547f8b0179efbc049ac5930abec7fc26ed7a41d89a048d8ab17d362200e204b6f71c3c20d6991a0e74415e1a412a49adc8131c2a40c04822e languageName: node linkType: hard -"@babel/preset-env@npm:7.22.4, @babel/preset-env@npm:^7.11.0": - version: 7.22.4 - resolution: "@babel/preset-env@npm:7.22.4" +"@babel/preset-env@npm:7.22.5, @babel/preset-env@npm:^7.11.0": + version: 7.22.5 + resolution: "@babel/preset-env@npm:7.22.5" dependencies: - "@babel/compat-data": ^7.22.3 - "@babel/helper-compilation-targets": ^7.22.1 - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-validator-option": ^7.21.0 - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.18.6 - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.22.3 - "@babel/plugin-proposal-private-property-in-object": ^7.21.0 + "@babel/compat-data": ^7.22.5 + "@babel/helper-compilation-targets": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-validator-option": ^7.22.5 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.22.5 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.22.5 + "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 "@babel/plugin-syntax-async-generators": ^7.8.4 "@babel/plugin-syntax-class-properties": ^7.12.13 "@babel/plugin-syntax-class-static-block": ^7.14.5 "@babel/plugin-syntax-dynamic-import": ^7.8.3 "@babel/plugin-syntax-export-namespace-from": ^7.8.3 - "@babel/plugin-syntax-import-assertions": ^7.20.0 - "@babel/plugin-syntax-import-attributes": ^7.22.3 + "@babel/plugin-syntax-import-assertions": ^7.22.5 + "@babel/plugin-syntax-import-attributes": ^7.22.5 "@babel/plugin-syntax-import-meta": ^7.10.4 "@babel/plugin-syntax-json-strings": ^7.8.3 "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 @@ -1301,56 +1296,56 @@ __metadata: "@babel/plugin-syntax-private-property-in-object": ^7.14.5 "@babel/plugin-syntax-top-level-await": ^7.14.5 "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 - "@babel/plugin-transform-arrow-functions": ^7.21.5 - "@babel/plugin-transform-async-generator-functions": ^7.22.3 - "@babel/plugin-transform-async-to-generator": ^7.20.7 - "@babel/plugin-transform-block-scoped-functions": ^7.18.6 - "@babel/plugin-transform-block-scoping": ^7.21.0 - "@babel/plugin-transform-class-properties": ^7.22.3 - "@babel/plugin-transform-class-static-block": ^7.22.3 - "@babel/plugin-transform-classes": ^7.21.0 - "@babel/plugin-transform-computed-properties": ^7.21.5 - "@babel/plugin-transform-destructuring": ^7.21.3 - "@babel/plugin-transform-dotall-regex": ^7.18.6 - "@babel/plugin-transform-duplicate-keys": ^7.18.9 - "@babel/plugin-transform-dynamic-import": ^7.22.1 - "@babel/plugin-transform-exponentiation-operator": ^7.18.6 - "@babel/plugin-transform-export-namespace-from": ^7.22.3 - "@babel/plugin-transform-for-of": ^7.21.5 - "@babel/plugin-transform-function-name": ^7.18.9 - "@babel/plugin-transform-json-strings": ^7.22.3 - "@babel/plugin-transform-literals": ^7.18.9 - "@babel/plugin-transform-logical-assignment-operators": ^7.22.3 - "@babel/plugin-transform-member-expression-literals": ^7.18.6 - "@babel/plugin-transform-modules-amd": ^7.20.11 - "@babel/plugin-transform-modules-commonjs": ^7.21.5 - "@babel/plugin-transform-modules-systemjs": ^7.22.3 - "@babel/plugin-transform-modules-umd": ^7.18.6 - "@babel/plugin-transform-named-capturing-groups-regex": ^7.22.3 - "@babel/plugin-transform-new-target": ^7.22.3 - "@babel/plugin-transform-nullish-coalescing-operator": ^7.22.3 - "@babel/plugin-transform-numeric-separator": ^7.22.3 - "@babel/plugin-transform-object-rest-spread": ^7.22.3 - "@babel/plugin-transform-object-super": ^7.18.6 - "@babel/plugin-transform-optional-catch-binding": ^7.22.3 - "@babel/plugin-transform-optional-chaining": ^7.22.3 - "@babel/plugin-transform-parameters": ^7.22.3 - "@babel/plugin-transform-private-methods": ^7.22.3 - "@babel/plugin-transform-private-property-in-object": ^7.22.3 - "@babel/plugin-transform-property-literals": ^7.18.6 - "@babel/plugin-transform-regenerator": ^7.21.5 - "@babel/plugin-transform-reserved-words": ^7.18.6 - "@babel/plugin-transform-shorthand-properties": ^7.18.6 - "@babel/plugin-transform-spread": ^7.20.7 - "@babel/plugin-transform-sticky-regex": ^7.18.6 - "@babel/plugin-transform-template-literals": ^7.18.9 - "@babel/plugin-transform-typeof-symbol": ^7.18.9 - "@babel/plugin-transform-unicode-escapes": ^7.21.5 - "@babel/plugin-transform-unicode-property-regex": ^7.22.3 - "@babel/plugin-transform-unicode-regex": ^7.18.6 - "@babel/plugin-transform-unicode-sets-regex": ^7.22.3 + "@babel/plugin-transform-arrow-functions": ^7.22.5 + "@babel/plugin-transform-async-generator-functions": ^7.22.5 + "@babel/plugin-transform-async-to-generator": ^7.22.5 + "@babel/plugin-transform-block-scoped-functions": ^7.22.5 + "@babel/plugin-transform-block-scoping": ^7.22.5 + "@babel/plugin-transform-class-properties": ^7.22.5 + "@babel/plugin-transform-class-static-block": ^7.22.5 + "@babel/plugin-transform-classes": ^7.22.5 + "@babel/plugin-transform-computed-properties": ^7.22.5 + "@babel/plugin-transform-destructuring": ^7.22.5 + "@babel/plugin-transform-dotall-regex": ^7.22.5 + "@babel/plugin-transform-duplicate-keys": ^7.22.5 + "@babel/plugin-transform-dynamic-import": ^7.22.5 + "@babel/plugin-transform-exponentiation-operator": ^7.22.5 + "@babel/plugin-transform-export-namespace-from": ^7.22.5 + "@babel/plugin-transform-for-of": ^7.22.5 + "@babel/plugin-transform-function-name": ^7.22.5 + "@babel/plugin-transform-json-strings": ^7.22.5 + "@babel/plugin-transform-literals": ^7.22.5 + "@babel/plugin-transform-logical-assignment-operators": ^7.22.5 + "@babel/plugin-transform-member-expression-literals": ^7.22.5 + "@babel/plugin-transform-modules-amd": ^7.22.5 + "@babel/plugin-transform-modules-commonjs": ^7.22.5 + "@babel/plugin-transform-modules-systemjs": ^7.22.5 + "@babel/plugin-transform-modules-umd": ^7.22.5 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.22.5 + "@babel/plugin-transform-new-target": ^7.22.5 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.22.5 + "@babel/plugin-transform-numeric-separator": ^7.22.5 + "@babel/plugin-transform-object-rest-spread": ^7.22.5 + "@babel/plugin-transform-object-super": ^7.22.5 + "@babel/plugin-transform-optional-catch-binding": ^7.22.5 + "@babel/plugin-transform-optional-chaining": ^7.22.5 + "@babel/plugin-transform-parameters": ^7.22.5 + "@babel/plugin-transform-private-methods": ^7.22.5 + "@babel/plugin-transform-private-property-in-object": ^7.22.5 + "@babel/plugin-transform-property-literals": ^7.22.5 + "@babel/plugin-transform-regenerator": ^7.22.5 + "@babel/plugin-transform-reserved-words": ^7.22.5 + "@babel/plugin-transform-shorthand-properties": ^7.22.5 + "@babel/plugin-transform-spread": ^7.22.5 + "@babel/plugin-transform-sticky-regex": ^7.22.5 + "@babel/plugin-transform-template-literals": ^7.22.5 + "@babel/plugin-transform-typeof-symbol": ^7.22.5 + "@babel/plugin-transform-unicode-escapes": ^7.22.5 + "@babel/plugin-transform-unicode-property-regex": ^7.22.5 + "@babel/plugin-transform-unicode-regex": ^7.22.5 + "@babel/plugin-transform-unicode-sets-regex": ^7.22.5 "@babel/preset-modules": ^0.1.5 - "@babel/types": ^7.22.4 + "@babel/types": ^7.22.5 babel-plugin-polyfill-corejs2: ^0.4.3 babel-plugin-polyfill-corejs3: ^0.8.1 babel-plugin-polyfill-regenerator: ^0.5.0 @@ -1358,7 +1353,7 @@ __metadata: semver: ^6.3.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 68ae8b712e7548cb0aa593019bf22ed473bd83887c621c1f820ef0af99958d48b687c01b8aee16035cbc70edae1edc703b892e6efed14b95c8435343a2cb2bda + checksum: 6d9d09010ababef2ab48c8830770b2a8f45d6cce51db0924a98b0d95a5b1248a99ee07ee61cb5446d8b05b562db99a8af30b3ed194546419fb9b2889b8fd1ed3 languageName: node linkType: hard @@ -1377,18 +1372,18 @@ __metadata: languageName: node linkType: hard -"@babel/preset-typescript@npm:7.21.5": - version: 7.21.5 - resolution: "@babel/preset-typescript@npm:7.21.5" +"@babel/preset-typescript@npm:7.22.5": + version: 7.22.5 + resolution: "@babel/preset-typescript@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.21.5 - "@babel/helper-validator-option": ^7.21.0 - "@babel/plugin-syntax-jsx": ^7.21.4 - "@babel/plugin-transform-modules-commonjs": ^7.21.5 - "@babel/plugin-transform-typescript": ^7.21.3 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/helper-validator-option": ^7.22.5 + "@babel/plugin-syntax-jsx": ^7.22.5 + "@babel/plugin-transform-modules-commonjs": ^7.22.5 + "@babel/plugin-transform-typescript": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e7b35c435139eec1d6bd9f57e8f3eb79bfc2da2c57a34ad9e9ea848ba4ecd72791cf4102df456604ab07c7f4518525b0764754b6dd5898036608b351e0792448 + checksum: 7be1670cb4404797d3a473bd72d66eb2b3e0f2f8a672a5e40bdb0812cc66085ec84bcd7b896709764cabf042fdc6b7f2d4755ac7cce10515eb596ff61dab5154 languageName: node linkType: hard @@ -1399,52 +1394,52 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.22.3, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4": - version: 7.22.3 - resolution: "@babel/runtime@npm:7.22.3" +"@babel/runtime@npm:7.22.5, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4": + version: 7.22.5 + resolution: "@babel/runtime@npm:7.22.5" dependencies: regenerator-runtime: ^0.13.11 - checksum: 8fc50785ca4cba749fed90bffca7e6fd52d4709755654e95b8d2a945fc034b56fb8c2e8a0183fea7c4abb86bf5fa77678c0ea35163b6920649833d180c34c234 + checksum: 12a50b7de2531beef38840d17af50c55a094253697600cee255311222390c68eed704829308d4fd305e1b3dfbce113272e428e9d9d45b1730e0fede997eaceb1 languageName: node linkType: hard -"@babel/template@npm:^7.18.10, @babel/template@npm:^7.20.7, @babel/template@npm:^7.21.9": - version: 7.21.9 - resolution: "@babel/template@npm:7.21.9" +"@babel/template@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/template@npm:7.22.5" dependencies: - "@babel/code-frame": ^7.21.4 - "@babel/parser": ^7.21.9 - "@babel/types": ^7.21.5 - checksum: 6ec2c60d4d53b2a9230ab82c399ba6525df87e9a4e01e4b111e071cbad283b1362e7c99a1bc50027073f44f2de36a495a89c27112c4e7efe7ef9c8d9c84de2ec + "@babel/code-frame": ^7.22.5 + "@babel/parser": ^7.22.5 + "@babel/types": ^7.22.5 + checksum: c5746410164039aca61829cdb42e9a55410f43cace6f51ca443313f3d0bdfa9a5a330d0b0df73dc17ef885c72104234ae05efede37c1cc8a72dc9f93425977a3 languageName: node linkType: hard -"@babel/traverse@npm:^7.20.5, @babel/traverse@npm:^7.22.1": - version: 7.22.1 - resolution: "@babel/traverse@npm:7.22.1" +"@babel/traverse@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/traverse@npm:7.22.5" dependencies: - "@babel/code-frame": ^7.21.4 - "@babel/generator": ^7.22.0 - "@babel/helper-environment-visitor": ^7.22.1 - "@babel/helper-function-name": ^7.21.0 - "@babel/helper-hoist-variables": ^7.18.6 - "@babel/helper-split-export-declaration": ^7.18.6 - "@babel/parser": ^7.22.0 - "@babel/types": ^7.22.0 + "@babel/code-frame": ^7.22.5 + "@babel/generator": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.5 + "@babel/helper-function-name": ^7.22.5 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.5 + "@babel/parser": ^7.22.5 + "@babel/types": ^7.22.5 debug: ^4.1.0 globals: ^11.1.0 - checksum: 5761837f9ce9b6ec2fe851ce76c6048d4fc11fc5be13218b7492849e42497ea957dafd2b84ab673aaabf31ac26ddc79c298d2a0fcff79ebdfc5c204cb35071a1 + checksum: 560931422dc1761f2df723778dcb4e51ce0d02e560cf2caa49822921578f49189a5a7d053b78a32dca33e59be886a6b2200a6e24d4ae9b5086ca0ba803815694 languageName: node linkType: hard -"@babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.5, @babel/types@npm:^7.21.0, @babel/types@npm:^7.21.4, @babel/types@npm:^7.21.5, @babel/types@npm:^7.22.0, @babel/types@npm:^7.22.3, @babel/types@npm:^7.22.4, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.22.4 - resolution: "@babel/types@npm:7.22.4" +"@babel/types@npm:^7.22.5, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.22.5 + resolution: "@babel/types@npm:7.22.5" dependencies: - "@babel/helper-string-parser": ^7.21.5 - "@babel/helper-validator-identifier": ^7.19.1 + "@babel/helper-string-parser": ^7.22.5 + "@babel/helper-validator-identifier": ^7.22.5 to-fast-properties: ^2.0.0 - checksum: ffe36bb4f4a99ad13c426a98c3b508d70736036cae4e471d9c862e3a579847ed4f480686af0fce2633f6f7c0f0d3bf02da73da36e7edd3fde0b2061951dcba9a + checksum: c13a9c1dc7d2d1a241a2f8363540cb9af1d66e978e8984b400a20c4f38ba38ca29f06e26a0f2d49a70bad9e57615dac09c35accfddf1bb90d23cd3e0a0bab892 languageName: node linkType: hard @@ -9607,12 +9602,12 @@ __metadata: version: 0.0.0-use.local resolution: "home-assistant-frontend@workspace:." dependencies: - "@babel/core": 7.22.1 - "@babel/plugin-proposal-decorators": 7.22.3 - "@babel/plugin-transform-runtime": 7.22.4 - "@babel/preset-env": 7.22.4 - "@babel/preset-typescript": 7.21.5 - "@babel/runtime": 7.22.3 + "@babel/core": 7.22.5 + "@babel/plugin-proposal-decorators": 7.22.5 + "@babel/plugin-transform-runtime": 7.22.5 + "@babel/preset-env": 7.22.5 + "@babel/preset-typescript": 7.22.5 + "@babel/runtime": 7.22.5 "@braintree/sanitize-url": 6.0.2 "@codemirror/autocomplete": 6.7.1 "@codemirror/commands": 6.2.4 From 655b630fa52c63788de03fa5c0d66addd8da2eae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jun 2023 11:46:54 +0200 Subject: [PATCH 013/162] Bump actions/checkout from 3.5.2 to 3.5.3 (#16876) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cast_deployment.yaml | 4 ++-- .github/workflows/ci.yaml | 8 ++++---- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/demo_deployment.yaml | 4 ++-- .github/workflows/design_deployment.yaml | 2 +- .github/workflows/design_preview.yaml | 2 +- .github/workflows/nightly.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/translations.yaml | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/cast_deployment.yaml b/.github/workflows/cast_deployment.yaml index 85a076bf00..120658dd0c 100644 --- a/.github/workflows/cast_deployment.yaml +++ b/.github/workflows/cast_deployment.yaml @@ -21,7 +21,7 @@ jobs: url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 with: ref: dev @@ -57,7 +57,7 @@ jobs: url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 with: ref: master diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e73c4f7a1e..16656927e6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Setup Node uses: actions/setup-node@v3.6.0 with: @@ -47,7 +47,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Setup Node uses: actions/setup-node@v3.6.0 with: @@ -65,7 +65,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Setup Node uses: actions/setup-node@v3.6.0 with: @@ -83,7 +83,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Setup Node uses: actions/setup-node@v3.6.0 with: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b71752c7f7..fda71956ed 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 with: # We must fetch at least the immediate parents so that if this is # a pull request then we can checkout the head. diff --git a/.github/workflows/demo_deployment.yaml b/.github/workflows/demo_deployment.yaml index cddec2a128..77c4b98f5c 100644 --- a/.github/workflows/demo_deployment.yaml +++ b/.github/workflows/demo_deployment.yaml @@ -22,7 +22,7 @@ jobs: url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 with: ref: dev @@ -58,7 +58,7 @@ jobs: url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 with: ref: master diff --git a/.github/workflows/design_deployment.yaml b/.github/workflows/design_deployment.yaml index 62478e741a..8b5aec8a39 100644 --- a/.github/workflows/design_deployment.yaml +++ b/.github/workflows/design_deployment.yaml @@ -16,7 +16,7 @@ jobs: url: ${{ steps.deploy.outputs.NETLIFY_LIVE_URL || steps.deploy.outputs.NETLIFY_URL }} steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Setup Node uses: actions/setup-node@v3.6.0 diff --git a/.github/workflows/design_preview.yaml b/.github/workflows/design_preview.yaml index 59f487a4b6..a257f9ec98 100644 --- a/.github/workflows/design_preview.yaml +++ b/.github/workflows/design_preview.yaml @@ -21,7 +21,7 @@ jobs: if: github.repository == 'home-assistant/frontend' && contains(github.event.pull_request.labels.*.name, 'needs design preview') steps: - name: Check out files from GitHub - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Setup Node uses: actions/setup-node@v3.6.0 diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index aeb820a8d4..0b22247453 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -20,7 +20,7 @@ jobs: contents: write steps: - name: Checkout the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Set up Python ${{ env.PYTHON_VERSION }} uses: actions/setup-python@v4 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0766eb857f..7d943eda97 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -23,7 +23,7 @@ jobs: contents: write # Required to upload release assets steps: - name: Checkout the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Verify version uses: home-assistant/actions/helpers/verify-version@master diff --git a/.github/workflows/translations.yaml b/.github/workflows/translations.yaml index 38bcdc8071..8e503deb83 100644 --- a/.github/workflows/translations.yaml +++ b/.github/workflows/translations.yaml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Upload Translations run: | From e3faa618bfa5761e34cfc4de80f351683813bc00 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 12 Jun 2023 13:49:39 +0200 Subject: [PATCH 014/162] Use esm module for hls.js (#16878) --- src/components/ha-hls-player.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ha-hls-player.ts b/src/components/ha-hls-player.ts index 3943abb615..cf3ed5a526 100644 --- a/src/components/ha-hls-player.ts +++ b/src/components/ha-hls-player.ts @@ -109,7 +109,8 @@ class HaHLSPlayer extends LitElement { private async _startHls(): Promise { const masterPlaylistPromise = fetch(this.url); - const Hls: typeof HlsType = (await import("hls.js/dist/hls.light")).default; + const Hls: typeof HlsType = (await import("hls.js/dist/hls.light.mjs")) + .default; if (!this.isConnected) { return; From f7722a270f2abe810e3b09c32a24244952f621e0 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 13 Jun 2023 11:55:52 +0200 Subject: [PATCH 015/162] Add safe zone to reach min and max temperature easily with temperature (#16880) Add safe zone to reach min and max temperature easily with temperature picker --- src/components/ha-temp-color-picker.ts | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/components/ha-temp-color-picker.ts b/src/components/ha-temp-color-picker.ts index c3e19707c6..16422f55bd 100644 --- a/src/components/ha-temp-color-picker.ts +++ b/src/components/ha-temp-color-picker.ts @@ -7,6 +7,8 @@ import { rgb2hex } from "../common/color/convert-color"; import { temperature2rgb } from "../common/color/convert-light-color"; import { fireEvent } from "../common/dom/fire_event"; +const SAFE_ZONE_FACTOR = 0.9; + declare global { interface HASSDomEvents { "cursor-moved": { value?: any }; @@ -50,9 +52,12 @@ function drawColorWheel( for (let y = -radius; y < radius; y += 1) { const x = radius * Math.sqrt(1 - (y / radius) ** 2); - const fraction = (y / radius + 1) / 2; + const fraction = (y / (radius * SAFE_ZONE_FACTOR) + 1) / 2; - const temperature = min + fraction * (max - min); + const temperature = Math.max( + Math.min(min + fraction * (max - min), max), + min + ); const color = rgb2hex(temperature2rgb(temperature)); @@ -202,14 +207,23 @@ class HaTempColorPicker extends LitElement { } private _getCoordsFromValue = (temperature: number): [number, number] => { + if (this.value === this.min) { + return [0, -1]; + } + if (this.value === this.max) { + return [0, 1]; + } const fraction = (temperature - this.min) / (this.max - this.min); - const y = 2 * fraction - 1; + const y = (2 * fraction - 1) * SAFE_ZONE_FACTOR; return [0, y]; }; private _getValueFromCoord = (_x: number, y: number): number => { - const fraction = (y + 1) / 2; - const temperature = this.min + fraction * (this.max - this.min); + const fraction = (y / SAFE_ZONE_FACTOR + 1) / 2; + const temperature = Math.max( + Math.min(this.min + fraction * (this.max - this.min), this.max), + this.min + ); return Math.round(temperature); }; From 780de42e4bdeb4e84000271d452f515b7b799c5b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 13 Jun 2023 12:12:13 +0200 Subject: [PATCH 016/162] Allow to show times in the UI in the timezone of the server (#16799) --- gallery/src/pages/date-time/date.ts | 59 ++++++--- gallery/src/pages/misc/entity-state.ts | 1 + .../components/supervisor-backup-content.ts | 10 +- src/common/datetime/absolute_time.ts | 8 +- src/common/datetime/calc_date.ts | 25 ++++ src/common/datetime/format_date.ts | 119 ++++++++++++------ src/common/datetime/format_date_time.ts | 47 ++++--- src/common/datetime/format_time.ts | 39 ++++-- .../entity/compute_attribute_display.ts | 8 +- src/common/entity/compute_state_display.ts | 30 +++-- src/common/translations/day_names.ts | 10 +- src/common/translations/month_names.ts | 10 +- src/components/chart/chart-date-adapter.ts | 84 ++++++++++--- .../chart/state-history-chart-line.ts | 1 + .../chart/state-history-chart-timeline.ts | 13 +- src/components/chart/statistics-chart.ts | 1 + .../entity/ha-entity-state-picker.ts | 2 + src/components/entity/ha-state-label-badge.ts | 1 + src/components/ha-absolute-time.ts | 6 +- src/components/ha-attributes.ts | 1 + src/components/ha-climate-state.ts | 3 + src/components/ha-date-input.ts | 10 +- src/components/ha-date-range-picker.ts | 94 ++++++++++++-- src/components/trace/ha-trace-path-details.ts | 3 +- src/components/trace/hat-trace-timeline.ts | 6 +- src/data/automation_i18n.ts | 45 ++++--- src/data/context.ts | 3 +- src/data/energy.ts | 46 +++++-- src/data/history.ts | 8 +- src/data/logbook.ts | 1 + src/data/timer.ts | 2 + src/data/translation.ts | 6 + .../components/fan/ha-more-info-fan-speed.ts | 1 + .../components/ha-more-info-state-header.ts | 1 + .../more-info/controls/more-info-climate.ts | 4 + .../more-info/controls/more-info-cover.ts | 1 + .../more-info/controls/more-info-fan.ts | 3 + .../controls/more-info-humidifier.ts | 1 + .../more-info/controls/more-info-light.ts | 2 + .../controls/more-info-media_player.ts | 2 + .../more-info/controls/more-info-remote.ts | 1 + .../more-info/controls/more-info-sun.ts | 3 +- .../more-info/controls/more-info-vacuum.ts | 4 + .../more-info/controls/more-info-weather.ts | 6 +- .../configurator-notification-item.ts | 1 + .../persistent-notification-item.ts | 2 +- src/fake_data/provide_hass.ts | 2 + .../calendar/dialog-calendar-event-detail.ts | 21 ++-- src/panels/calendar/recurrence.ts | 8 +- .../config/automation/ha-automation-picker.ts | 12 +- .../config/automation/ha-automation-trace.ts | 3 +- .../config/cloud/account/cloud-account.ts | 3 +- .../dialog-cloud-certificate.ts | 3 +- .../mqtt/mqtt-messages.ts | 3 +- .../config/hardware/ha-config-hardware.ts | 1 + .../config/helpers/forms/ha-schedule-form.ts | 10 +- .../integrations/dialog-add-integration.ts | 3 +- .../mqtt/mqtt-subscribe-card.ts | 2 +- .../config/logs/dialog-system-log-detail.ts | 12 +- src/panels/config/logs/system-log-card.ts | 12 +- src/panels/config/logs/util.ts | 11 +- .../config/repairs/dialog-repairs-issue.ts | 3 +- .../repairs/dialog-system-information.ts | 12 +- src/panels/config/scene/ha-scene-dashboard.ts | 6 +- src/panels/config/script/ha-script-picker.ts | 8 +- src/panels/config/script/ha-script-trace.ts | 3 +- .../debug/assist-pipeline-debug.ts | 3 +- .../event/event-subscribe-card.ts | 3 +- .../dialog-statistics-adjust-sum.ts | 12 +- src/panels/history/ha-panel-history.ts | 38 +----- src/panels/logbook/ha-logbook-renderer.ts | 9 +- src/panels/logbook/ha-panel-logbook.ts | 32 ----- .../cards/energy/hui-energy-compare-card.ts | 17 ++- .../cards/energy/hui-energy-gas-graph-card.ts | 14 ++- .../energy/hui-energy-solar-graph-card.ts | 14 ++- .../energy/hui-energy-usage-graph-card.ts | 14 ++- .../energy/hui-energy-water-graph-card.ts | 14 ++- src/panels/lovelace/cards/hui-button-card.ts | 12 +- src/panels/lovelace/cards/hui-entity-card.ts | 2 + src/panels/lovelace/cards/hui-glance-card.ts | 1 + .../lovelace/cards/hui-humidifier-card.ts | 1 + src/panels/lovelace/cards/hui-light-card.ts | 1 + src/panels/lovelace/cards/hui-map-card.ts | 14 ++- .../lovelace/cards/hui-picture-entity-card.ts | 1 + .../lovelace/cards/hui-picture-glance-card.ts | 2 + .../lovelace/cards/hui-thermostat-card.ts | 3 + src/panels/lovelace/cards/hui-tile-card.ts | 1 + .../cards/hui-weather-forecast-card.ts | 12 +- .../components/hui-energy-period-selector.ts | 57 ++++++--- .../components/hui-timestamp-display.ts | 11 +- .../elements/hui-state-label-element.ts | 1 + .../entity-rows/hui-group-entity-row.ts | 1 + .../entity-rows/hui-humidifier-entity-row.ts | 1 + .../hui-input-number-entity-row.ts | 1 + .../hui-media-player-entity-row.ts | 1 + .../entity-rows/hui-number-entity-row.ts | 1 + .../entity-rows/hui-select-entity-row.ts | 1 + .../entity-rows/hui-sensor-entity-row.ts | 1 + .../entity-rows/hui-simple-entity-row.ts | 1 + .../entity-rows/hui-toggle-entity-row.ts | 1 + .../entity-rows/hui-weather-entity-row.ts | 1 + .../special-rows/hui-attribute-row.ts | 1 + .../hui-fan-speed-tile-feature.ts | 1 + src/panels/profile/ha-panel-profile.ts | 5 + src/panels/profile/ha-pick-date-format-row.ts | 12 +- src/panels/profile/ha-pick-time-format-row.ts | 12 +- src/panels/profile/ha-pick-time-zone-row.ts | 76 +++++++++++ src/state-summary/state-card-display.ts | 3 +- src/state-summary/state-card-input_number.ts | 1 + src/state-summary/state-card-select.ts | 1 + src/state/connection-mixin.ts | 2 + src/state/translations-mixin.ts | 23 ++++ src/translations/en.json | 9 ++ src/util/common-translation.ts | 7 +- test/common/datetime/format_date.ts | 21 ++-- test/common/datetime/format_date_time.ts | 79 +++++++----- test/common/datetime/format_time.ts | 116 ++++++++++------- test/common/datetime/relative_time.ts | 3 + test/common/entity/compute_state_display.ts | 66 +++++++--- test/common/string/format_number.ts | 2 + 120 files changed, 1169 insertions(+), 442 deletions(-) create mode 100644 src/common/datetime/calc_date.ts create mode 100644 src/panels/profile/ha-pick-time-zone-row.ts diff --git a/gallery/src/pages/date-time/date.ts b/gallery/src/pages/date-time/date.ts index c344f6f7cc..90776e89b1 100644 --- a/gallery/src/pages/date-time/date.ts +++ b/gallery/src/pages/date-time/date.ts @@ -10,7 +10,9 @@ import { TimeFormat, DateFormat, FirstWeekday, + TimeZone, } from "../../../../src/data/translation"; +import "@material/mwc-list/mwc-list"; @customElement("demo-date-time-date") export class DemoDateTimeDate extends LitElement { @@ -22,6 +24,7 @@ export class DemoDateTimeDate extends LitElement { number_format: NumberFormat.language, time_format: TimeFormat.language, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.language, }; const date = new Date(); @@ -41,32 +44,48 @@ export class DemoDateTimeDate extends LitElement {
${value.nativeName}
- ${formatDateNumeric(date, { - ...defaultLocale, - language: key, - date_format: DateFormat.language, - })} + ${formatDateNumeric( + date, + { + ...defaultLocale, + language: key, + date_format: DateFormat.language, + }, + this.hass.config + )}
- ${formatDateNumeric(date, { - ...defaultLocale, - language: key, - date_format: DateFormat.DMY, - })} + ${formatDateNumeric( + date, + { + ...defaultLocale, + language: key, + date_format: DateFormat.DMY, + }, + this.hass.config + )}
- ${formatDateNumeric(date, { - ...defaultLocale, - language: key, - date_format: DateFormat.MDY, - })} + ${formatDateNumeric( + date, + { + ...defaultLocale, + language: key, + date_format: DateFormat.MDY, + }, + this.hass.config + )}
- ${formatDateNumeric(date, { - ...defaultLocale, - language: key, - date_format: DateFormat.YMD, - })} + ${formatDateNumeric( + date, + { + ...defaultLocale, + language: key, + date_format: DateFormat.YMD, + }, + this.hass.config + )}
` diff --git a/gallery/src/pages/misc/entity-state.ts b/gallery/src/pages/misc/entity-state.ts index 01beaa0507..aa0905d9b2 100644 --- a/gallery/src/pages/misc/entity-state.ts +++ b/gallery/src/pages/misc/entity-state.ts @@ -354,6 +354,7 @@ export class DemoEntityState extends LitElement { hass.localize, entry.stateObj, hass.locale, + hass.config, hass.entities )}`, }, diff --git a/hassio/src/components/supervisor-backup-content.ts b/hassio/src/components/supervisor-backup-content.ts index 3480cf9aba..ded21bf63a 100644 --- a/hassio/src/components/supervisor-backup-content.ts +++ b/hassio/src/components/supervisor-backup-content.ts @@ -143,7 +143,11 @@ export class SupervisorBackupContent extends LitElement { : this._localize("partial_backup")} (${Math.ceil(this.backup.size * 10) / 10 + " MB"})
${this.hass - ? formatDateTime(new Date(this.backup.date), this.hass.locale) + ? formatDateTime( + new Date(this.backup.date), + this.hass.locale, + this.hass.config + ) : this.backup.date} ` : html` { const _to = to ?? new Date(); if (isSameDay(from, _to)) { - return formatTime(from, locale); + return formatTime(from, locale, config); } if (isSameYear(from, _to)) { - return formatShortDateTime(from, locale); + return formatShortDateTime(from, locale, config); } - return formatShortDateTimeWithYear(from, locale); + return formatShortDateTimeWithYear(from, locale, config); }; diff --git a/src/common/datetime/calc_date.ts b/src/common/datetime/calc_date.ts new file mode 100644 index 0000000000..5a4da09a29 --- /dev/null +++ b/src/common/datetime/calc_date.ts @@ -0,0 +1,25 @@ +import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz"; +import { HassConfig } from "home-assistant-js-websocket"; +import { FrontendLocaleData, TimeZone } from "../../data/translation"; + +const calcZonedDate = ( + date: Date, + tz: string, + fn: (date: Date, options?: any) => Date, + options? +) => { + const inputZoned = utcToZonedTime(date, tz); + const fnZoned = fn(inputZoned, options); + return zonedTimeToUtc(fnZoned, tz); +}; + +export const calcDate = ( + date: Date, + fn: (date: Date, options?: any) => Date, + locale: FrontendLocaleData, + config: HassConfig, + options? +) => + locale.time_zone === TimeZone.server + ? calcZonedDate(date, config.time_zone, fn, options) + : fn(date, options); diff --git a/src/common/datetime/format_date.ts b/src/common/datetime/format_date.ts index cb6893a625..ffb48bc64e 100644 --- a/src/common/datetime/format_date.ts +++ b/src/common/datetime/format_date.ts @@ -1,3 +1,4 @@ +import { HassConfig } from "home-assistant-js-websocket"; import memoizeOne from "memoize-one"; import { FrontendLocaleData, DateFormat } from "../../data/translation"; import "../../resources/intl-polyfill"; @@ -5,37 +6,44 @@ import "../../resources/intl-polyfill"; // Tuesday, August 10 export const formatDateWeekdayDay = ( dateObj: Date, - locale: FrontendLocaleData -) => formatDateWeekdayDayMem(locale).format(dateObj); + locale: FrontendLocaleData, + config: HassConfig +) => formatDateWeekdayDayMem(locale, config.time_zone).format(dateObj); const formatDateWeekdayDayMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { weekday: "long", month: "long", day: "numeric", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); // August 10, 2021 -export const formatDate = (dateObj: Date, locale: FrontendLocaleData) => - formatDateMem(locale).format(dateObj); +export const formatDate = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateMem(locale, config.time_zone).format(dateObj); const formatDateMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { year: "numeric", month: "long", day: "numeric", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); // 10/08/2021 export const formatDateNumeric = ( dateObj: Date, - locale: FrontendLocaleData + locale: FrontendLocaleData, + config: HassConfig ) => { - const formatter = formatDateNumericMem(locale); + const formatter = formatDateNumericMem(locale, config.time_zone); if ( locale.date_format === DateFormat.language || @@ -67,83 +75,120 @@ export const formatDateNumeric = ( return formats[locale.date_format]; }; -const formatDateNumericMem = memoizeOne((locale: FrontendLocaleData) => { - const localeString = - locale.date_format === DateFormat.system ? undefined : locale.language; +const formatDateNumericMem = memoizeOne( + (locale: FrontendLocaleData, serverTimeZone: string) => { + const localeString = + locale.date_format === DateFormat.system ? undefined : locale.language; + + if ( + locale.date_format === DateFormat.language || + locale.date_format === DateFormat.system + ) { + return new Intl.DateTimeFormat(localeString, { + year: "numeric", + month: "numeric", + day: "numeric", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }); + } - if ( - locale.date_format === DateFormat.language || - locale.date_format === DateFormat.system - ) { return new Intl.DateTimeFormat(localeString, { year: "numeric", month: "numeric", day: "numeric", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }); } - - return new Intl.DateTimeFormat(localeString, { - year: "numeric", - month: "numeric", - day: "numeric", - }); -}); +); // Aug 10 -export const formatDateShort = (dateObj: Date, locale: FrontendLocaleData) => - formatDateShortMem(locale).format(dateObj); +export const formatDateShort = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateShortMem(locale, config.time_zone).format(dateObj); const formatDateShortMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { day: "numeric", month: "short", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); // August 2021 export const formatDateMonthYear = ( dateObj: Date, - locale: FrontendLocaleData -) => formatDateMonthYearMem(locale).format(dateObj); + locale: FrontendLocaleData, + config: HassConfig +) => formatDateMonthYearMem(locale, config.time_zone).format(dateObj); const formatDateMonthYearMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { month: "long", year: "numeric", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); // August -export const formatDateMonth = (dateObj: Date, locale: FrontendLocaleData) => - formatDateMonthMem(locale).format(dateObj); +export const formatDateMonth = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateMonthMem(locale, config.time_zone).format(dateObj); const formatDateMonthMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { month: "long", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); // 2021 -export const formatDateYear = (dateObj: Date, locale: FrontendLocaleData) => - formatDateYearMem(locale).format(dateObj); +export const formatDateYear = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateYearMem(locale, config.time_zone).format(dateObj); const formatDateYearMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { year: "numeric", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); // Monday -export const formatDateWeekday = (dateObj: Date, locale: FrontendLocaleData) => - formatDateWeekdayMem(locale).format(dateObj); +export const formatDateWeekday = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateWeekdayMem(locale, config.time_zone).format(dateObj); const formatDateWeekdayMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat(locale.language, { weekday: "long", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) +); + +// Mon +export const formatDateWeekdayShort = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateWeekdayShortMem(locale, config.time_zone).format(dateObj); + +const formatDateWeekdayShortMem = memoizeOne( + (locale: FrontendLocaleData, serverTimeZone: string) => + new Intl.DateTimeFormat(locale.language, { + weekday: "short", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); diff --git a/src/common/datetime/format_date_time.ts b/src/common/datetime/format_date_time.ts index 7c38d1fd18..d9b7a3a862 100644 --- a/src/common/datetime/format_date_time.ts +++ b/src/common/datetime/format_date_time.ts @@ -1,16 +1,20 @@ +import { HassConfig } from "home-assistant-js-websocket"; import memoizeOne from "memoize-one"; import { FrontendLocaleData } from "../../data/translation"; import "../../resources/intl-polyfill"; -import { useAmPm } from "./use_am_pm"; import { formatDateNumeric } from "./format_date"; import { formatTime } from "./format_time"; +import { useAmPm } from "./use_am_pm"; // August 9, 2021, 8:23 AM -export const formatDateTime = (dateObj: Date, locale: FrontendLocaleData) => - formatDateTimeMem(locale).format(dateObj); +export const formatDateTime = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatDateTimeMem(locale, config.time_zone).format(dateObj); const formatDateTimeMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -22,6 +26,7 @@ const formatDateTimeMem = memoizeOne( hour: useAmPm(locale) ? "numeric" : "2-digit", minute: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); @@ -29,11 +34,12 @@ const formatDateTimeMem = memoizeOne( // Aug 9, 2021, 8:23 AM export const formatShortDateTimeWithYear = ( dateObj: Date, - locale: FrontendLocaleData -) => formatShortDateTimeWithYearMem(locale).format(dateObj); + locale: FrontendLocaleData, + config: HassConfig +) => formatShortDateTimeWithYearMem(locale, config.time_zone).format(dateObj); const formatShortDateTimeWithYearMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -45,6 +51,7 @@ const formatShortDateTimeWithYearMem = memoizeOne( hour: useAmPm(locale) ? "numeric" : "2-digit", minute: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); @@ -52,11 +59,12 @@ const formatShortDateTimeWithYearMem = memoizeOne( // Aug 9, 8:23 AM export const formatShortDateTime = ( dateObj: Date, - locale: FrontendLocaleData -) => formatShortDateTimeMem(locale).format(dateObj); + locale: FrontendLocaleData, + config: HassConfig +) => formatShortDateTimeMem(locale, config.time_zone).format(dateObj); const formatShortDateTimeMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -67,6 +75,7 @@ const formatShortDateTimeMem = memoizeOne( hour: useAmPm(locale) ? "numeric" : "2-digit", minute: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); @@ -74,11 +83,12 @@ const formatShortDateTimeMem = memoizeOne( // August 9, 2021, 8:23:15 AM export const formatDateTimeWithSeconds = ( dateObj: Date, - locale: FrontendLocaleData -) => formatDateTimeWithSecondsMem(locale).format(dateObj); + locale: FrontendLocaleData, + config: HassConfig +) => formatDateTimeWithSecondsMem(locale, config.time_zone).format(dateObj); const formatDateTimeWithSecondsMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -91,6 +101,7 @@ const formatDateTimeWithSecondsMem = memoizeOne( minute: "2-digit", second: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); @@ -98,5 +109,11 @@ const formatDateTimeWithSecondsMem = memoizeOne( // 9/8/2021, 8:23 AM export const formatDateTimeNumeric = ( dateObj: Date, - locale: FrontendLocaleData -) => `${formatDateNumeric(dateObj, locale)}, ${formatTime(dateObj, locale)}`; + locale: FrontendLocaleData, + config: HassConfig +) => + `${formatDateNumeric(dateObj, locale, config)}, ${formatTime( + dateObj, + locale, + config + )}`; diff --git a/src/common/datetime/format_time.ts b/src/common/datetime/format_time.ts index ec4459fe2c..41827b4f8d 100644 --- a/src/common/datetime/format_time.ts +++ b/src/common/datetime/format_time.ts @@ -1,14 +1,18 @@ +import { HassConfig } from "home-assistant-js-websocket"; import memoizeOne from "memoize-one"; import { FrontendLocaleData } from "../../data/translation"; import "../../resources/intl-polyfill"; import { useAmPm } from "./use_am_pm"; // 9:15 PM || 21:15 -export const formatTime = (dateObj: Date, locale: FrontendLocaleData) => - formatTimeMem(locale).format(dateObj); +export const formatTime = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatTimeMem(locale, config.time_zone).format(dateObj); const formatTimeMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -17,6 +21,7 @@ const formatTimeMem = memoizeOne( hour: "numeric", minute: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); @@ -24,11 +29,12 @@ const formatTimeMem = memoizeOne( // 9:15:24 PM || 21:15:24 export const formatTimeWithSeconds = ( dateObj: Date, - locale: FrontendLocaleData -) => formatTimeWithSecondsMem(locale).format(dateObj); + locale: FrontendLocaleData, + config: HassConfig +) => formatTimeWithSecondsMem(locale, config.time_zone).format(dateObj); const formatTimeWithSecondsMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -38,16 +44,20 @@ const formatTimeWithSecondsMem = memoizeOne( minute: "2-digit", second: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); // Tuesday 7:00 PM || Tuesday 19:00 -export const formatTimeWeekday = (dateObj: Date, locale: FrontendLocaleData) => - formatTimeWeekdayMem(locale).format(dateObj); +export const formatTimeWeekday = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatTimeWeekdayMem(locale, config.time_zone).format(dateObj); const formatTimeWeekdayMem = memoizeOne( - (locale: FrontendLocaleData) => + (locale: FrontendLocaleData, serverTimeZone: string) => new Intl.DateTimeFormat( locale.language === "en" && !useAmPm(locale) ? "en-u-hc-h23" @@ -57,20 +67,25 @@ const formatTimeWeekdayMem = memoizeOne( hour: useAmPm(locale) ? "numeric" : "2-digit", minute: "2-digit", hour12: useAmPm(locale), + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, } ) ); // 21:15 -export const formatTime24h = (dateObj: Date) => - formatTime24hMem().format(dateObj); +export const formatTime24h = ( + dateObj: Date, + locale: FrontendLocaleData, + config: HassConfig +) => formatTime24hMem(locale, config.time_zone).format(dateObj); const formatTime24hMem = memoizeOne( - () => + (locale: FrontendLocaleData, serverTimeZone: string) => // en-GB to fix Chrome 24:59 to 0:59 https://stackoverflow.com/a/60898146 new Intl.DateTimeFormat("en-GB", { hour: "numeric", minute: "2-digit", hour12: false, + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, }) ); diff --git a/src/common/entity/compute_attribute_display.ts b/src/common/entity/compute_attribute_display.ts index 5fdfabe7a8..1d5d8af8a4 100644 --- a/src/common/entity/compute_attribute_display.ts +++ b/src/common/entity/compute_attribute_display.ts @@ -1,4 +1,4 @@ -import { HassEntity } from "home-assistant-js-websocket"; +import { HassConfig, HassEntity } from "home-assistant-js-websocket"; import { html, TemplateResult } from "lit"; import { until } from "lit/directives/until"; import { EntityRegistryDisplayEntry } from "../../data/entity_registry"; @@ -20,6 +20,7 @@ export const computeAttributeValueDisplay = ( localize: LocalizeFunc, stateObj: HassEntity, locale: FrontendLocaleData, + config: HassConfig, entities: HomeAssistant["entities"], attribute: string, value?: any @@ -59,14 +60,14 @@ export const computeAttributeValueDisplay = ( if (isTimestamp(attributeValue)) { const date = new Date(attributeValue); if (checkValidDate(date)) { - return formatDateTimeWithSeconds(date, locale); + return formatDateTimeWithSeconds(date, locale, config); } } // Value was not a timestamp, so only do date formatting const date = new Date(attributeValue); if (checkValidDate(date)) { - return formatDate(date, locale); + return formatDate(date, locale, config); } } } @@ -92,6 +93,7 @@ export const computeAttributeValueDisplay = ( localize, stateObj, locale, + config, entities, attribute, item diff --git a/src/common/entity/compute_state_display.ts b/src/common/entity/compute_state_display.ts index a35b8cf780..34db8700d1 100644 --- a/src/common/entity/compute_state_display.ts +++ b/src/common/entity/compute_state_display.ts @@ -1,7 +1,7 @@ -import { HassEntity } from "home-assistant-js-websocket"; +import { HassConfig, HassEntity } from "home-assistant-js-websocket"; import { UNAVAILABLE, UNKNOWN } from "../../data/entity"; import { EntityRegistryDisplayEntry } from "../../data/entity_registry"; -import { FrontendLocaleData } from "../../data/translation"; +import { FrontendLocaleData, TimeZone } from "../../data/translation"; import { updateIsInstallingFromAttributes, UPDATE_SUPPORT_PROGRESS, @@ -28,12 +28,14 @@ export const computeStateDisplaySingleEntity = ( localize: LocalizeFunc, stateObj: HassEntity, locale: FrontendLocaleData, + config: HassConfig, entity: EntityRegistryDisplayEntry | undefined, state?: string ): string => computeStateDisplayFromEntityAttributes( localize, locale, + config, entity, stateObj.entity_id, stateObj.attributes, @@ -44,6 +46,7 @@ export const computeStateDisplay = ( localize: LocalizeFunc, stateObj: HassEntity, locale: FrontendLocaleData, + config: HassConfig, entities: HomeAssistant["entities"], state?: string ): string => { @@ -54,6 +57,7 @@ export const computeStateDisplay = ( return computeStateDisplayFromEntityAttributes( localize, locale, + config, entity, stateObj.entity_id, stateObj.attributes, @@ -64,6 +68,7 @@ export const computeStateDisplay = ( export const computeStateDisplayFromEntityAttributes = ( localize: LocalizeFunc, locale: FrontendLocaleData, + config: HassConfig, entity: EntityRegistryDisplayEntry | undefined, entityId: string, attributes: any, @@ -119,29 +124,40 @@ export const computeStateDisplayFromEntityAttributes = ( if (domain === "datetime") { const time = new Date(state); - return formatDateTime(time, locale); + return formatDateTime(time, locale, config); } if (["date", "input_datetime", "time"].includes(domain)) { // If trying to display an explicit state, need to parse the explicit state to `Date` then format. // Attributes aren't available, we have to use `state`. + + // These are timezone agnostic, so we should NOT use the system timezone here. try { const components = state.split(" "); if (components.length === 2) { // Date and time. - return formatDateTime(new Date(components.join("T")), locale); + return formatDateTime( + new Date(components.join("T")), + { ...locale, time_zone: TimeZone.local }, + config + ); } if (components.length === 1) { if (state.includes("-")) { // Date only. - return formatDate(new Date(`${state}T00:00`), locale); + return formatDate( + new Date(`${state}T00:00`), + { ...locale, time_zone: TimeZone.local }, + config + ); } if (state.includes(":")) { // Time only. const now = new Date(); return formatTime( new Date(`${now.toISOString().split("T")[0]}T${state}`), - locale + { ...locale, time_zone: TimeZone.local }, + config ); } } @@ -179,7 +195,7 @@ export const computeStateDisplayFromEntityAttributes = ( (domain === "sensor" && attributes.device_class === "timestamp") ) { try { - return formatDateTime(new Date(state), locale); + return formatDateTime(new Date(state), locale, config); } catch (_err) { return state; } diff --git a/src/common/translations/day_names.ts b/src/common/translations/day_names.ts index 34b18fdb4a..885cd84029 100644 --- a/src/common/translations/day_names.ts +++ b/src/common/translations/day_names.ts @@ -1,10 +1,12 @@ import { addDays, startOfWeek } from "date-fns"; +import { HassConfig } from "home-assistant-js-websocket"; import memoizeOne from "memoize-one"; import { FrontendLocaleData } from "../../data/translation"; import { formatDateWeekday } from "../datetime/format_date"; -export const dayNames = memoizeOne((locale: FrontendLocaleData): string[] => - Array.from({ length: 7 }, (_, d) => - formatDateWeekday(addDays(startOfWeek(new Date()), d), locale) - ) +export const dayNames = memoizeOne( + (locale: FrontendLocaleData, config: HassConfig): string[] => + Array.from({ length: 7 }, (_, d) => + formatDateWeekday(addDays(startOfWeek(new Date()), d), locale, config) + ) ); diff --git a/src/common/translations/month_names.ts b/src/common/translations/month_names.ts index 2e456b1855..4df4236d28 100644 --- a/src/common/translations/month_names.ts +++ b/src/common/translations/month_names.ts @@ -1,10 +1,12 @@ import { addMonths, startOfYear } from "date-fns"; +import { HassConfig } from "home-assistant-js-websocket"; import memoizeOne from "memoize-one"; import { FrontendLocaleData } from "../../data/translation"; import { formatDateMonth } from "../datetime/format_date"; -export const monthNames = memoizeOne((locale: FrontendLocaleData): string[] => - Array.from({ length: 12 }, (_, m) => - formatDateMonth(addMonths(startOfYear(new Date()), m), locale) - ) +export const monthNames = memoizeOne( + (locale: FrontendLocaleData, config: HassConfig): string[] => + Array.from({ length: 12 }, (_, m) => + formatDateMonth(addMonths(startOfYear(new Date()), m), locale, config) + ) ); diff --git a/src/components/chart/chart-date-adapter.ts b/src/components/chart/chart-date-adapter.ts index 462ee52dc1..f348823a29 100644 --- a/src/components/chart/chart-date-adapter.ts +++ b/src/components/chart/chart-date-adapter.ts @@ -80,33 +80,89 @@ _adapters._date.override({ format: function (time, fmt: keyof typeof FORMATS) { switch (fmt) { case "datetime": - return formatDateTime(new Date(time), this.options.locale); + return formatDateTime( + new Date(time), + this.options.locale, + this.options.config + ); case "datetimeseconds": - return formatDateTimeWithSeconds(new Date(time), this.options.locale); + return formatDateTimeWithSeconds( + new Date(time), + this.options.locale, + this.options.config + ); case "millisecond": - return formatTimeWithSeconds(new Date(time), this.options.locale); + return formatTimeWithSeconds( + new Date(time), + this.options.locale, + this.options.config + ); case "second": - return formatTimeWithSeconds(new Date(time), this.options.locale); + return formatTimeWithSeconds( + new Date(time), + this.options.locale, + this.options.config + ); case "minute": - return formatTime(new Date(time), this.options.locale); + return formatTime( + new Date(time), + this.options.locale, + this.options.config + ); case "hour": - return formatTime(new Date(time), this.options.locale); + return formatTime( + new Date(time), + this.options.locale, + this.options.config + ); case "weekday": - return formatDateWeekdayDay(new Date(time), this.options.locale); + return formatDateWeekdayDay( + new Date(time), + this.options.locale, + this.options.config + ); case "date": - return formatDate(new Date(time), this.options.locale); + return formatDate( + new Date(time), + this.options.locale, + this.options.config + ); case "day": - return formatDateShort(new Date(time), this.options.locale); + return formatDateShort( + new Date(time), + this.options.locale, + this.options.config + ); case "week": - return formatDate(new Date(time), this.options.locale); + return formatDate( + new Date(time), + this.options.locale, + this.options.config + ); case "month": - return formatDateMonth(new Date(time), this.options.locale); + return formatDateMonth( + new Date(time), + this.options.locale, + this.options.config + ); case "monthyear": - return formatDateMonthYear(new Date(time), this.options.locale); + return formatDateMonthYear( + new Date(time), + this.options.locale, + this.options.config + ); case "quarter": - return formatDate(new Date(time), this.options.locale); + return formatDate( + new Date(time), + this.options.locale, + this.options.config + ); case "year": - return formatDateYear(new Date(time), this.options.locale); + return formatDateYear( + new Date(time), + this.options.locale, + this.options.config + ); default: return ""; } diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index 3ce2235320..50f164c094 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -71,6 +71,7 @@ class StateHistoryChartLine extends LitElement { adapters: { date: { locale: this.hass.locale, + config: this.hass.config, }, }, suggestedMax: this.endTime, diff --git a/src/components/chart/state-history-chart-timeline.ts b/src/components/chart/state-history-chart-timeline.ts index 2d9b93b413..b1686aa2ab 100644 --- a/src/components/chart/state-history-chart-timeline.ts +++ b/src/components/chart/state-history-chart-timeline.ts @@ -98,6 +98,7 @@ export class StateHistoryChartTimeline extends LitElement { adapters: { date: { locale: this.hass.locale, + config: this.hass.config, }, }, suggestedMin: this.startTime, @@ -181,8 +182,16 @@ export class StateHistoryChartTimeline extends LitElement { return [ d.label || "", - formatDateTimeWithSeconds(d.start, this.hass.locale), - formatDateTimeWithSeconds(d.end, this.hass.locale), + formatDateTimeWithSeconds( + d.start, + this.hass.locale, + this.hass.config + ), + formatDateTimeWithSeconds( + d.end, + this.hass.locale, + this.hass.config + ), formattedDuration, ]; }, diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index 014e658417..d9f30d9d67 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -146,6 +146,7 @@ class StatisticsChart extends LitElement { adapters: { date: { locale: this.hass.locale, + config: this.hass.config, }, }, ticks: { diff --git a/src/components/entity/ha-entity-state-picker.ts b/src/components/entity/ha-entity-state-picker.ts index 7b92f63aa2..688b38e6db 100644 --- a/src/components/entity/ha-entity-state-picker.ts +++ b/src/components/entity/ha-entity-state-picker.ts @@ -62,6 +62,7 @@ class HaEntityStatePicker extends LitElement { this.hass.localize, state, this.hass.locale, + this.hass.config, this.hass.entities, key ) @@ -69,6 +70,7 @@ class HaEntityStatePicker extends LitElement { this.hass.localize, state, this.hass.locale, + this.hass.config, this.hass.entities, this.attribute, key diff --git a/src/components/entity/ha-state-label-badge.ts b/src/components/entity/ha-state-label-badge.ts index b5d60d9bb1..519dbfc107 100644 --- a/src/components/entity/ha-state-label-badge.ts +++ b/src/components/entity/ha-state-label-badge.ts @@ -192,6 +192,7 @@ export class HaStateLabelBadge extends LitElement { this.hass!.localize, entityState, this.hass!.locale, + this.hass!.config, this.hass!.entities ); } diff --git a/src/components/ha-absolute-time.ts b/src/components/ha-absolute-time.ts index f782b32317..528c658514 100644 --- a/src/components/ha-absolute-time.ts +++ b/src/components/ha-absolute-time.ts @@ -64,7 +64,11 @@ class HaAbsoluteTime extends ReactiveElement { if (!this.datetime) { this.innerHTML = this.hass.localize("ui.components.absolute_time.never"); } else { - this.innerHTML = absoluteTime(new Date(this.datetime), this.hass.locale); + this.innerHTML = absoluteTime( + new Date(this.datetime), + this.hass.locale, + this.hass.config + ); } } } diff --git a/src/components/ha-attributes.ts b/src/components/ha-attributes.ts index c1092cb96f..dce1fd4c07 100644 --- a/src/components/ha-attributes.ts +++ b/src/components/ha-attributes.ts @@ -62,6 +62,7 @@ class HaAttributes extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, attribute )} diff --git a/src/components/ha-climate-state.ts b/src/components/ha-climate-state.ts index 7c8be97a6e..7a1617e4ee 100644 --- a/src/components/ha-climate-state.ts +++ b/src/components/ha-climate-state.ts @@ -28,6 +28,7 @@ class HaClimateState extends LitElement { this.hass.localize, this.stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "preset_mode" )}` @@ -136,6 +137,7 @@ class HaClimateState extends LitElement { this.hass.localize, this.stateObj, this.hass.locale, + this.hass.config, this.hass.entities ); @@ -144,6 +146,7 @@ class HaClimateState extends LitElement { this.hass.localize, this.stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "hvac_action" )} (${stateString})` diff --git a/src/components/ha-date-input.ts b/src/components/ha-date-input.ts index 2b1cc6fe22..d3b5a0607e 100644 --- a/src/components/ha-date-input.ts +++ b/src/components/ha-date-input.ts @@ -1,9 +1,11 @@ import { mdiCalendar } from "@mdi/js"; +import { HassConfig } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; -import { formatDateNumeric } from "../common/datetime/format_date"; import { firstWeekdayIndex } from "../common/datetime/first_weekday"; +import { formatDateNumeric } from "../common/datetime/format_date"; import { fireEvent } from "../common/dom/fire_event"; +import { TimeZone } from "../data/translation"; import { HomeAssistant } from "../types"; import "./ha-svg-icon"; import "./ha-textfield"; @@ -59,7 +61,11 @@ export class HaDateInput extends LitElement { .value=${this.value ? formatDateNumeric( new Date(`${this.value.split("T")[0]}T00:00:00`), - this.locale + { + ...this.locale, + time_zone: TimeZone.local, + }, + {} as HassConfig ) : ""} .required=${this.required} diff --git a/src/components/ha-date-range-picker.ts b/src/components/ha-date-range-picker.ts index 5c870215a7..557d139ae3 100644 --- a/src/components/ha-date-range-picker.ts +++ b/src/components/ha-date-range-picker.ts @@ -3,6 +3,13 @@ import "@material/mwc-list/mwc-list"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiCalendar } from "@mdi/js"; +import { + addDays, + endOfDay, + endOfWeek, + startOfDay, + startOfWeek, +} from "date-fns"; import { css, CSSResultGroup, @@ -12,10 +19,11 @@ import { TemplateResult, } from "lit"; import { customElement, property } from "lit/decorators"; -import { formatDateTime } from "../common/datetime/format_date_time"; -import { formatDate } from "../common/datetime/format_date"; -import { useAmPm } from "../common/datetime/use_am_pm"; +import { calcDate } from "../common/datetime/calc_date"; import { firstWeekdayIndex } from "../common/datetime/first_weekday"; +import { formatDate } from "../common/datetime/format_date"; +import { formatDateTime } from "../common/datetime/format_date_time"; +import { useAmPm } from "../common/datetime/use_am_pm"; import { computeRTLDirection } from "../common/util/compute_rtl"; import { HomeAssistant } from "../types"; import "./date-range-picker"; @@ -34,7 +42,7 @@ export class HaDateRangePicker extends LitElement { @property() public endDate!: Date; - @property() public ranges?: DateRangePickerRanges; + @property() public ranges?: DateRangePickerRanges | false; @property() public autoApply = false; @@ -46,6 +54,70 @@ export class HaDateRangePicker extends LitElement { @property({ type: String }) private _rtlDirection = "ltr"; + protected willUpdate() { + if (!this.hasUpdated && this.ranges === undefined) { + const today = new Date(); + const weekStartsOn = firstWeekdayIndex(this.hass.locale); + const weekStart = calcDate( + today, + startOfWeek, + this.hass.locale, + this.hass.config, + { + weekStartsOn, + } + ); + const weekEnd = calcDate( + today, + endOfWeek, + this.hass.locale, + this.hass.config, + { + weekStartsOn, + } + ); + + this.ranges = { + [this.hass.localize("ui.components.date-range-picker.ranges.today")]: [ + calcDate(today, startOfDay, this.hass.locale, this.hass.config, { + weekStartsOn, + }), + calcDate(today, endOfDay, this.hass.locale, this.hass.config, { + weekStartsOn, + }), + ], + [this.hass.localize( + "ui.components.date-range-picker.ranges.yesterday" + )]: [ + calcDate( + addDays(today, -1), + startOfDay, + this.hass.locale, + this.hass.config, + { + weekStartsOn, + } + ), + calcDate( + addDays(today, -1), + endOfDay, + this.hass.locale, + this.hass.config, + { + weekStartsOn, + } + ), + ], + [this.hass.localize( + "ui.components.date-range-picker.ranges.this_week" + )]: [weekStart, weekEnd], + [this.hass.localize( + "ui.components.date-range-picker.ranges.last_week" + )]: [addDays(weekStart, -7), addDays(weekEnd, -7)], + }; + } + } + protected updated(changedProps: PropertyValues) { if (changedProps.has("hass")) { const oldHass = changedProps.get("hass") as HomeAssistant | undefined; @@ -65,15 +137,19 @@ export class HaDateRangePicker extends LitElement { twentyfour-hours=${this._hour24format} start-date=${this.startDate} end-date=${this.endDate} - ?ranges=${this.ranges !== undefined} + ?ranges=${this.ranges !== false} first-day=${firstWeekdayIndex(this.hass.locale)} >
${result ? html`Result: diff --git a/src/components/trace/hat-trace-timeline.ts b/src/components/trace/hat-trace-timeline.ts index 7bd01cd431..2396c65879 100644 --- a/src/components/trace/hat-trace-timeline.ts +++ b/src/components/trace/hat-trace-timeline.ts @@ -335,7 +335,8 @@ class ActionRenderer { } at ${formatDateTimeWithSeconds( new Date(triggerStep.timestamp), - this.hass.locale + this.hass.locale, + this.hass.config )}`, mdiCircle ); @@ -632,7 +633,8 @@ export class HaAutomationTracer extends LitElement { const renderFinishedAt = () => formatDateTimeWithSeconds( new Date(this.trace!.timestamp.finish!), - this.hass.locale + this.hass.locale, + this.hass.config ); const renderRuntime = () => `(runtime: ${( diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index d989b8617f..ab4c0056ea 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -1,26 +1,27 @@ +import { HassConfig } from "home-assistant-js-websocket"; +import { ensureArray } from "../common/array/ensure-array"; import { formatDuration } from "../common/datetime/format_duration"; import { formatTime, formatTimeWithSeconds, } from "../common/datetime/format_time"; -import { FrontendLocaleData } from "./translation"; import secondsToDuration from "../common/datetime/seconds_to_duration"; -import { ensureArray } from "../common/array/ensure-array"; +import { + computeAttributeNameDisplay, + computeAttributeValueDisplay, +} from "../common/entity/compute_attribute_display"; +import { computeStateDisplay } from "../common/entity/compute_state_display"; import { computeStateName } from "../common/entity/compute_state_name"; import type { HomeAssistant } from "../types"; -import { Condition, Trigger, ForDict } from "./automation"; +import { Condition, ForDict, Trigger } from "./automation"; import { DeviceCondition, DeviceTrigger, localizeDeviceAutomationCondition, localizeDeviceAutomationTrigger, } from "./device_automation"; -import { - computeAttributeNameDisplay, - computeAttributeValueDisplay, -} from "../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { EntityRegistryEntry } from "./entity_registry"; +import { FrontendLocaleData } from "./translation"; const describeDuration = (forTime: number | string | ForDict) => { let duration: string | null; @@ -34,7 +35,11 @@ const describeDuration = (forTime: number | string | ForDict) => { return duration; }; -const localizeTimeString = (time: string, locale: FrontendLocaleData) => { +const localizeTimeString = ( + time: string, + locale: FrontendLocaleData, + config: HassConfig +) => { const chunks = time.split(":"); if (chunks.length < 2 || chunks.length > 3) { return time; @@ -42,9 +47,9 @@ const localizeTimeString = (time: string, locale: FrontendLocaleData) => { try { const dt = new Date("1970-01-01T" + time); if (chunks.length === 2 || Number(chunks[2]) === 0) { - return formatTime(dt, locale); + return formatTime(dt, locale, config); } - return formatTimeWithSeconds(dt, locale); + return formatTimeWithSeconds(dt, locale, config); } catch { return time; } @@ -209,6 +214,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, trigger.attribute, state @@ -217,6 +223,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, state ) @@ -232,6 +239,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, trigger.attribute, trigger.from @@ -240,6 +248,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, trigger.from.toString() ).toString() @@ -263,6 +272,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, trigger.attribute, state @@ -271,6 +281,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, state ).toString() @@ -286,6 +297,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, trigger.attribute, trigger.to @@ -294,6 +306,7 @@ export const describeTrigger = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, trigger.to.toString() ).toString() @@ -353,7 +366,7 @@ export const describeTrigger = ( ? at : at.includes(".") ? `entity ${hass.states[at] ? computeStateName(hass.states[at]) : at}` - : localizeTimeString(at, hass.locale) + : localizeTimeString(at, hass.locale, hass.config) ); const last = result.splice(-1, 1)[0]; @@ -738,6 +751,7 @@ export const describeCondition = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, condition.attribute, state @@ -746,6 +760,7 @@ export const describeCondition = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, state ) @@ -758,6 +773,7 @@ export const describeCondition = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, condition.attribute, condition.state @@ -766,6 +782,7 @@ export const describeCondition = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities, condition.state.toString() ).toString() @@ -830,7 +847,7 @@ export const describeCondition = ( ? computeStateName(hass.states[condition.before]) : condition.before }` - : localizeTimeString(condition.before, hass.locale); + : localizeTimeString(condition.before, hass.locale, hass.config); const after = typeof condition.after !== "string" @@ -841,7 +858,7 @@ export const describeCondition = ( ? computeStateName(hass.states[condition.after]) : condition.after }` - : localizeTimeString(condition.after, hass.locale); + : localizeTimeString(condition.after, hass.locale, hass.config); let result = "Confirm the "; if (after || before) { diff --git a/src/data/context.ts b/src/data/context.ts index f62e666ebe..7fbff9fd06 100644 --- a/src/data/context.ts +++ b/src/data/context.ts @@ -1,4 +1,5 @@ import { createContext } from "@lit-labs/context"; +import { HassConfig } from "home-assistant-js-websocket"; import { HomeAssistant } from "../types"; import { EntityRegistryEntry } from "./entity_registry"; @@ -11,7 +12,7 @@ export const areasContext = createContext("areas"); export const localizeContext = createContext("localize"); export const localeContext = createContext("locale"); -export const configContext = createContext("config"); +export const configContext = createContext("config"); export const themesContext = createContext("themes"); export const selectedThemeContext = createContext("selectedTheme"); diff --git a/src/data/energy.ts b/src/data/energy.ts index 151089d929..1e1fbd3c5e 100644 --- a/src/data/energy.ts +++ b/src/data/energy.ts @@ -4,12 +4,12 @@ import { addMilliseconds, addMonths, differenceInDays, - endOfToday, - endOfYesterday, - startOfToday, - startOfYesterday, + endOfDay, + startOfDay, } from "date-fns/esm"; import { Collection, getCollection } from "home-assistant-js-websocket"; +import { calcDate } from "../common/datetime/calc_date"; +import { formatTime24h } from "../common/datetime/format_time"; import { groupBy } from "../common/util/group-by"; import { HomeAssistant } from "../types"; import { ConfigEntry, getConfigEntries } from "./config_entries"; @@ -626,18 +626,40 @@ export const getEnergyDataCollection = ( collection._active = 0; collection.prefs = options.prefs; const now = new Date(); + const hour = formatTime24h(now, hass.locale, hass.config).split(":")[0]; // Set start to start of today if we have data for today, otherwise yesterday - collection.start = now.getHours() > 0 ? startOfToday() : startOfYesterday(); - collection.end = now.getHours() > 0 ? endOfToday() : endOfYesterday(); + collection.start = calcDate( + hour === "0" ? addDays(now, -1) : now, + startOfDay, + hass.locale, + hass.config + ); + collection.end = calcDate( + hour === "0" ? addDays(now, -1) : now, + endOfDay, + hass.locale, + hass.config + ); const scheduleUpdatePeriod = () => { collection._updatePeriodTimeout = window.setTimeout( () => { - collection.start = startOfToday(); - collection.end = endOfToday(); + collection.start = calcDate( + new Date(), + startOfDay, + hass.locale, + hass.config + ); + collection.end = calcDate( + new Date(), + endOfDay, + hass.locale, + hass.config + ); scheduleUpdatePeriod(); }, - addHours(endOfToday(), 1).getTime() - Date.now() // Switch to next day an hour after the day changed + addHours(calcDate(now, endOfDay, hass.locale, hass.config), 1).getTime() - + Date.now() // Switch to next day an hour after the day changed ); }; scheduleUpdatePeriod(); @@ -649,8 +671,10 @@ export const getEnergyDataCollection = ( collection.start = newStart; collection.end = newEnd; if ( - collection.start.getTime() === startOfToday().getTime() && - collection.end?.getTime() === endOfToday().getTime() && + collection.start.getTime() === + calcDate(new Date(), startOfDay, hass.locale, hass.config).getTime() && + collection.end?.getTime() === + calcDate(new Date(), endOfDay, hass.locale, hass.config).getTime() && !collection._updatePeriodTimeout ) { scheduleUpdatePeriod(); diff --git a/src/data/history.ts b/src/data/history.ts index dcc37a45a3..8202f44167 100644 --- a/src/data/history.ts +++ b/src/data/history.ts @@ -1,4 +1,5 @@ import { + HassConfig, HassEntities, HassEntity, HassEntityAttributeBase, @@ -269,7 +270,8 @@ const equalState = (obj1: LineChartState, obj2: LineChartState) => const processTimelineEntity = ( localize: LocalizeFunc, - language: FrontendLocaleData, + locale: FrontendLocaleData, + config: HassConfig, entities: HomeAssistant["entities"], entityId: string, states: EntityHistoryState[], @@ -290,7 +292,8 @@ const processTimelineEntity = ( data.push({ state_localize: computeStateDisplayFromEntityAttributes( localize, - language, + locale, + config, entities[entityId], entityId, { @@ -441,6 +444,7 @@ export const computeHistory = ( processTimelineEntity( localize, hass.locale, + hass.config, hass.entities, entityId, stateInfo, diff --git a/src/data/logbook.ts b/src/data/logbook.ts index c191ed8535..a30b9cde02 100644 --- a/src/data/logbook.ts +++ b/src/data/logbook.ts @@ -439,6 +439,7 @@ export const localizeStateMessage = ( localize, stateObj, hass.locale, + hass.config, hass.entities, state ) diff --git a/src/data/timer.ts b/src/data/timer.ts index a06a865bf3..5401175d41 100644 --- a/src/data/timer.ts +++ b/src/data/timer.ts @@ -94,6 +94,7 @@ export const computeDisplayTimer = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities ); } @@ -105,6 +106,7 @@ export const computeDisplayTimer = ( hass.localize, stateObj, hass.locale, + hass.config, hass.entities )})`; } diff --git a/src/data/translation.ts b/src/data/translation.ts index fb6fdaeeb9..b64e557b6b 100644 --- a/src/data/translation.ts +++ b/src/data/translation.ts @@ -17,6 +17,11 @@ export enum TimeFormat { twenty_four = "24", } +export enum TimeZone { + local = "local", + server = "server", +} + export enum DateFormat { language = "language", system = "system", @@ -42,6 +47,7 @@ export interface FrontendLocaleData { time_format: TimeFormat; date_format: DateFormat; first_weekday: FirstWeekday; + time_zone: TimeZone; } declare global { diff --git a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts index d40e88816e..72333bd2a2 100644 --- a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts +++ b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts @@ -72,6 +72,7 @@ export class HaMoreInfoFanSpeed extends LitElement { this.hass.localize, this.stateObj, this.hass.locale, + this.hass.config, this.hass.entities, speed ); diff --git a/src/dialogs/more-info/components/ha-more-info-state-header.ts b/src/dialogs/more-info/components/ha-more-info-state-header.ts index 1e7430cb23..150058e89b 100644 --- a/src/dialogs/more-info/components/ha-more-info-state-header.ts +++ b/src/dialogs/more-info/components/ha-more-info-state-header.ts @@ -39,6 +39,7 @@ export class HaMoreInfoStateHeader extends LitElement { this.hass!.localize, stateObj, this.hass!.locale, + this.hass!.config, this.hass!.entities ); diff --git a/src/dialogs/more-info/controls/more-info-climate.ts b/src/dialogs/more-info/controls/more-info-climate.ts index 52a4b0aa14..9294e06855 100644 --- a/src/dialogs/more-info/controls/more-info-climate.ts +++ b/src/dialogs/more-info/controls/more-info-climate.ts @@ -203,6 +203,7 @@ class MoreInfoClimate extends LitElement { hass.localize, stateObj, hass.locale, + this.hass.config, hass.entities, mode )} @@ -236,6 +237,7 @@ class MoreInfoClimate extends LitElement { hass.localize, stateObj, hass.locale, + hass.config, hass.entities, "preset_mode", mode @@ -270,6 +272,7 @@ class MoreInfoClimate extends LitElement { hass.localize, stateObj, hass.locale, + this.hass.config, hass.entities, "fan_mode", mode @@ -304,6 +307,7 @@ class MoreInfoClimate extends LitElement { hass.localize, stateObj, hass.locale, + this.hass.config, hass.entities, "swing_mode", mode diff --git a/src/dialogs/more-info/controls/more-info-cover.ts b/src/dialogs/more-info/controls/more-info-cover.ts index b4fe8114ba..7fd9d9a8ac 100644 --- a/src/dialogs/more-info/controls/more-info-cover.ts +++ b/src/dialogs/more-info/controls/more-info-cover.ts @@ -83,6 +83,7 @@ class MoreInfoCover extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, forcedState ); diff --git a/src/dialogs/more-info/controls/more-info-fan.ts b/src/dialogs/more-info/controls/more-info-fan.ts index af32733d77..588397c5ce 100644 --- a/src/dialogs/more-info/controls/more-info-fan.ts +++ b/src/dialogs/more-info/controls/more-info-fan.ts @@ -119,6 +119,7 @@ class MoreInfoFan extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, forcedState ); @@ -281,6 +282,7 @@ class MoreInfoFan extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, "preset_mode", this._presetMode @@ -307,6 +309,7 @@ class MoreInfoFan extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, "preset_mode", mode diff --git a/src/dialogs/more-info/controls/more-info-humidifier.ts b/src/dialogs/more-info/controls/more-info-humidifier.ts index 1e6d270d9d..527c82461f 100644 --- a/src/dialogs/more-info/controls/more-info-humidifier.ts +++ b/src/dialogs/more-info/controls/more-info-humidifier.ts @@ -83,6 +83,7 @@ class MoreInfoHumidifier extends LitElement { hass.localize, stateObj, hass.locale, + this.hass.config, hass.entities, "mode", mode diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts index f40b41977b..45597b228d 100644 --- a/src/dialogs/more-info/controls/more-info-light.ts +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -240,6 +240,7 @@ class MoreInfoLight extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, "effect", this._effect @@ -261,6 +262,7 @@ class MoreInfoLight extends LitElement { this.hass.localize, this.stateObj!, this.hass.locale, + this.hass.config, this.hass.entities, "effect", effect diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts index c6b4d34840..b02fc75e9d 100644 --- a/src/dialogs/more-info/controls/more-info-media_player.ts +++ b/src/dialogs/more-info/controls/more-info-media_player.ts @@ -163,6 +163,7 @@ class MoreInfoMediaPlayer extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "source", source @@ -196,6 +197,7 @@ class MoreInfoMediaPlayer extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "sound_mode", mode diff --git a/src/dialogs/more-info/controls/more-info-remote.ts b/src/dialogs/more-info/controls/more-info-remote.ts index 4d486fb5d4..9080897c13 100644 --- a/src/dialogs/more-info/controls/more-info-remote.ts +++ b/src/dialogs/more-info/controls/more-info-remote.ts @@ -44,6 +44,7 @@ class MoreInfoRemote extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "activity", activity diff --git a/src/dialogs/more-info/controls/more-info-sun.ts b/src/dialogs/more-info/controls/more-info-sun.ts index 537fb95f78..28f5727e43 100644 --- a/src/dialogs/more-info/controls/more-info-sun.ts +++ b/src/dialogs/more-info/controls/more-info-sun.ts @@ -44,7 +44,8 @@ class MoreInfoSun extends LitElement {
${formatTime( item === "ris" ? risingDate : settingDate, - this.hass.locale + this.hass.locale, + this.hass.config )}
diff --git a/src/dialogs/more-info/controls/more-info-vacuum.ts b/src/dialogs/more-info/controls/more-info-vacuum.ts index 652a3eb785..dfa940e31f 100644 --- a/src/dialogs/more-info/controls/more-info-vacuum.ts +++ b/src/dialogs/more-info/controls/more-info-vacuum.ts @@ -119,6 +119,7 @@ class MoreInfoVacuum extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "status" ) || @@ -126,6 +127,7 @@ class MoreInfoVacuum extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )} @@ -201,6 +203,7 @@ class MoreInfoVacuum extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "fan_speed", mode @@ -218,6 +221,7 @@ class MoreInfoVacuum extends LitElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "fan_speed" )} diff --git a/src/dialogs/more-info/controls/more-info-weather.ts b/src/dialogs/more-info/controls/more-info-weather.ts index 0b4a80ad93..628886339d 100644 --- a/src/dialogs/more-info/controls/more-info-weather.ts +++ b/src/dialogs/more-info/controls/more-info-weather.ts @@ -164,7 +164,8 @@ class MoreInfoWeather extends LitElement {
${formatTimeWeekday( new Date(item.datetime), - this.hass.locale + this.hass.locale, + this.hass.config )}
` @@ -172,7 +173,8 @@ class MoreInfoWeather extends LitElement {
${formatDateWeekdayDay( new Date(item.datetime), - this.hass.locale + this.hass.locale, + this.hass.config )}
`} diff --git a/src/dialogs/notifications/configurator-notification-item.ts b/src/dialogs/notifications/configurator-notification-item.ts index 47c7be0750..96174e02a1 100644 --- a/src/dialogs/notifications/configurator-notification-item.ts +++ b/src/dialogs/notifications/configurator-notification-item.ts @@ -38,6 +38,7 @@ export class HuiConfiguratorNotificationItem extends LitElement { this.hass.localize, this.notification, this.hass.locale, + this.hass.config, this.hass.entities )} diff --git a/src/dialogs/notifications/persistent-notification-item.ts b/src/dialogs/notifications/persistent-notification-item.ts index 310a6b93b9..40ce7e6b2f 100644 --- a/src/dialogs/notifications/persistent-notification-item.ts +++ b/src/dialogs/notifications/persistent-notification-item.ts @@ -82,7 +82,7 @@ export class HuiPersistentNotificationItem extends LitElement { } const d = new Date(notification.created_at!); - return formatDateTime(d, hass.locale); + return formatDateTime(d, hass.locale, hass.config); } } diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts index 6116fbc015..3da61ed4fe 100644 --- a/src/fake_data/provide_hass.ts +++ b/src/fake_data/provide_hass.ts @@ -11,6 +11,7 @@ import { NumberFormat, DateFormat, TimeFormat, + TimeZone, } from "../data/translation"; import { translationMetadata } from "../resources/translations-metadata"; import { HomeAssistant } from "../types"; @@ -230,6 +231,7 @@ export const provideHass = ( number_format: NumberFormat.language, time_format: TimeFormat.language, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.language, }, resources: null as any, diff --git a/src/panels/calendar/dialog-calendar-event-detail.ts b/src/panels/calendar/dialog-calendar-event-detail.ts index aba011143a..6172e79b4c 100644 --- a/src/panels/calendar/dialog-calendar-event-detail.ts +++ b/src/panels/calendar/dialog-calendar-event-detail.ts @@ -154,23 +154,28 @@ class DialogCalendarEventDetail extends LitElement { if (isSameDay(start, end)) { if (isDate(this._data.dtstart)) { // Single date string only - return formatDate(start, this.hass.locale); + return formatDate(start, this.hass.locale, this.hass.config); } // Single day with a start/end time range - return `${formatDate(start, this.hass.locale)} ${formatTime( + return `${formatDate( start, - this.hass.locale - )} - ${formatTime(end, this.hass.locale)}`; + this.hass.locale, + this.hass.config + )} ${formatTime( + start, + this.hass.locale, + this.hass.config + )} - ${formatTime(end, this.hass.locale, this.hass.config)}`; } // An event across multiple dates, optionally with a time range return `${ isDate(this._data.dtstart) - ? formatDate(start, this.hass.locale) - : formatDateTime(start, this.hass.locale) + ? formatDate(start, this.hass.locale, this.hass.config) + : formatDateTime(start, this.hass.locale, this.hass.config) } - ${ isDate(this._data.dtend) - ? formatDate(end, this.hass.locale) - : formatDateTime(end, this.hass.locale) + ? formatDate(end, this.hass.locale, this.hass.config) + : formatDateTime(end, this.hass.locale, this.hass.config) }`; } diff --git a/src/panels/calendar/recurrence.ts b/src/panels/calendar/recurrence.ts index ddc1d45729..1a502c9678 100644 --- a/src/panels/calendar/recurrence.ts +++ b/src/panels/calendar/recurrence.ts @@ -247,8 +247,8 @@ export function renderRRuleAsText(hass: HomeAssistant, value: string) { return ""; }, { - dayNames: dayNames(hass.locale), - monthNames: monthNames(hass.locale), + dayNames: dayNames(hass.locale, hass.config), + monthNames: monthNames(hass.locale, hass.config), tokens: {}, }, // Format the date @@ -263,9 +263,9 @@ export function renderRRuleAsText(hass: HomeAssistant, value: string) { // need to convert it back to something Date can work with. The already localized // months names are a must in the RRule.Language structure (an empty string[] would // mean we get undefined months input in this method here). - date.setMonth(monthNames(hass.locale).indexOf(month)); + date.setMonth(monthNames(hass.locale, hass.config).indexOf(month)); date.setDate(day); - return formatDate(date, hass.locale); + return formatDate(date, hass.locale, hass.config); } ) ); diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index cb89fd8af5..cdf33e2b50 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -128,7 +128,11 @@ class HaAutomationPicker extends LitElement { ${this.hass.localize("ui.card.automation.last_triggered")}: ${automation.attributes.last_triggered ? dayDifference > 3 - ? formatShortDateTime(date, this.hass.locale) + ? formatShortDateTime( + date, + this.hass.locale, + this.hass.config + ) : relativeTime(date, this.hass.locale) : this.hass.localize("ui.components.relative_time.never")} @@ -149,7 +153,11 @@ class HaAutomationPicker extends LitElement { return html` ${last_triggered ? dayDifference > 3 - ? formatShortDateTime(date, this.hass.locale) + ? formatShortDateTime( + date, + this.hass.locale, + this.hass.config + ) : relativeTime(date, this.hass.locale) : this.hass.localize("ui.components.relative_time.never")} `; diff --git a/src/panels/config/automation/ha-automation-trace.ts b/src/panels/config/automation/ha-automation-trace.ts index bfebbadb0b..fbf52c6974 100644 --- a/src/panels/config/automation/ha-automation-trace.ts +++ b/src/panels/config/automation/ha-automation-trace.ts @@ -192,7 +192,8 @@ export class HaAutomationTrace extends LitElement { html`` )} diff --git a/src/panels/config/cloud/account/cloud-account.ts b/src/panels/config/cloud/account/cloud-account.ts index 2be0ccffbd..2f0f3e791d 100644 --- a/src/panels/config/cloud/account/cloud-account.ts +++ b/src/panels/config/cloud/account/cloud-account.ts @@ -79,7 +79,8 @@ export class CloudAccount extends SubscribeMixin(LitElement) { new Date( this._subscription.plan_renewal_date * 1000 ), - this.hass.locale + this.hass.locale, + this.hass.config ) : "" ) diff --git a/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts b/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts index d999a162af..0e170e539b 100644 --- a/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts +++ b/src/panels/config/cloud/dialog-cloud-certificate/dialog-cloud-certificate.ts @@ -49,7 +49,8 @@ class DialogCloudCertificate extends LitElement { )} ${formatDateTime( new Date(certificateInfo.expire_date), - this.hass!.locale + this.hass!.locale, + this.hass!.config )}
(${this.hass!.localize( "ui.panel.config.cloud.dialog_certificate.will_be_auto_renewed" diff --git a/src/panels/config/devices/device-detail/integration-elements/mqtt/mqtt-messages.ts b/src/panels/config/devices/device-detail/integration-elements/mqtt/mqtt-messages.ts index 90bfb086c0..2d3b5acd1f 100644 --- a/src/panels/config/devices/device-detail/integration-elements/mqtt/mqtt-messages.ts +++ b/src/panels/config/devices/device-detail/integration-elements/mqtt/mqtt-messages.ts @@ -55,7 +55,8 @@ class MQTTMessages extends LitElement { ${this.direction} ${formatTimeWithSeconds( new Date(message.time), - this.hass.locale + this.hass.locale, + this.hass.config )} ${this._renderSingleMessage(message)} diff --git a/src/panels/config/hardware/ha-config-hardware.ts b/src/panels/config/hardware/ha-config-hardware.ts index ee910d622e..a6498ab9bb 100644 --- a/src/panels/config/hardware/ha-config-hardware.ts +++ b/src/panels/config/hardware/ha-config-hardware.ts @@ -170,6 +170,7 @@ class HaConfigHardware extends SubscribeMixin(LitElement) { adapters: { date: { locale: this.hass.locale, + config: this.hass.config, }, }, gridLines: { diff --git a/src/panels/config/helpers/forms/ha-schedule-form.ts b/src/panels/config/helpers/forms/ha-schedule-form.ts index 1568452504..e3116d5b21 100644 --- a/src/panels/config/helpers/forms/ha-schedule-form.ts +++ b/src/panels/config/helpers/forms/ha-schedule-form.ts @@ -286,9 +286,9 @@ class HaScheduleForm extends LitElement { const value = [...this[`_${day}`]]; const newValue = { ...this._item }; - const endFormatted = formatTime24h(end); + const endFormatted = formatTime24h(end, this.hass.locale, this.hass.config); value.push({ - from: formatTime24h(start), + from: formatTime24h(start, this.hass.locale, this.hass.config), to: !isSameDay(start, end) || endFormatted === "0:00" ? "24:00" @@ -313,7 +313,7 @@ class HaScheduleForm extends LitElement { const value = this[`_${day}`][parseInt(index)]; const newValue = { ...this._item }; - const endFormatted = formatTime24h(end); + const endFormatted = formatTime24h(end, this.hass.locale, this.hass.config); newValue[day][index] = { from: value.from, to: @@ -338,9 +338,9 @@ class HaScheduleForm extends LitElement { const newDay = weekdays[start.getDay()]; const newValue = { ...this._item }; - const endFormatted = formatTime24h(end); + const endFormatted = formatTime24h(end, this.hass.locale, this.hass.config); const event = { - from: formatTime24h(start), + from: formatTime24h(start, this.hass.locale, this.hass.config), to: !isSameDay(start, end) || endFormatted === "0:00" ? "24:00" diff --git a/src/panels/config/integrations/dialog-add-integration.ts b/src/panels/config/integrations/dialog-add-integration.ts index 1798614a68..02935336c0 100644 --- a/src/panels/config/integrations/dialog-add-integration.ts +++ b/src/panels/config/integrations/dialog-add-integration.ts @@ -1,6 +1,7 @@ import "@material/mwc-button"; import "@material/mwc-list/mwc-list"; import Fuse from "fuse.js"; +import { HassConfig } from "home-assistant-js-websocket"; import { css, html, @@ -158,7 +159,7 @@ class AddIntegrationDialog extends LitElement { ( i: Brands, h: Integrations, - components: HomeAssistant["config"]["components"], + components: HassConfig["components"], localize: LocalizeFunc, filter?: string ): IntegrationListItem[] => { diff --git a/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts b/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts index ebc0e1a123..bb04eb4f78 100644 --- a/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts +++ b/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts @@ -105,7 +105,7 @@ class MqttSubscribeCard extends LitElement { "topic", msg.message.topic, "time", - formatTime(msg.time, this.hass!.locale) + formatTime(msg.time, this.hass!.locale, this.hass!.config) )}
${msg.payload}
diff --git a/src/panels/config/logs/dialog-system-log-detail.ts b/src/panels/config/logs/dialog-system-log-detail.ts index 49891035ef..4856efdb98 100644 --- a/src/panels/config/logs/dialog-system-log-detail.ts +++ b/src/panels/config/logs/dialog-system-log-detail.ts @@ -145,12 +145,20 @@ class DialogSystemLogDetail extends LitElement { ${item.count > 0 ? html` First occurred: - ${formatSystemLogTime(item.first_occurred, this.hass!.locale)} + ${formatSystemLogTime( + item.first_occurred, + this.hass!.locale, + this.hass!.config + )} (${item.count} occurrences)
` : ""} Last logged: - ${formatSystemLogTime(item.timestamp, this.hass!.locale)} + ${formatSystemLogTime( + item.timestamp, + this.hass!.locale, + this.hass!.config + )}

${item.message.length > 1 ? html` diff --git a/src/panels/config/logs/system-log-card.ts b/src/panels/config/logs/system-log-card.ts index beec07abaf..e05da8a75d 100644 --- a/src/panels/config/logs/system-log-card.ts +++ b/src/panels/config/logs/system-log-card.ts @@ -38,14 +38,22 @@ export class SystemLogCard extends LitElement { } private _timestamp(item: LoggedError): string { - return formatSystemLogTime(item.timestamp, this.hass!.locale); + return formatSystemLogTime( + item.timestamp, + this.hass.locale, + this.hass.config + ); } private _multipleMessages(item: LoggedError): string { return this.hass.localize( "ui.panel.config.logs.multiple_messages", "time", - formatSystemLogTime(item.first_occurred, this.hass!.locale), + formatSystemLogTime( + item.first_occurred, + this.hass.locale, + this.hass.config + ), "counter", item.count ); diff --git a/src/panels/config/logs/util.ts b/src/panels/config/logs/util.ts index 3eb92fcd96..4cf0d7f704 100644 --- a/src/panels/config/logs/util.ts +++ b/src/panels/config/logs/util.ts @@ -1,13 +1,18 @@ +import { HassConfig } from "home-assistant-js-websocket"; import { formatDateTimeWithSeconds } from "../../../common/datetime/format_date_time"; import { formatTimeWithSeconds } from "../../../common/datetime/format_time"; import { FrontendLocaleData } from "../../../data/translation"; -export const formatSystemLogTime = (date, locale: FrontendLocaleData) => { +export const formatSystemLogTime = ( + date, + locale: FrontendLocaleData, + config: HassConfig +) => { const today = new Date().setHours(0, 0, 0, 0); const dateTime = new Date(date * 1000); const dateTimeDay = new Date(date * 1000).setHours(0, 0, 0, 0); return dateTimeDay < today - ? formatDateTimeWithSeconds(dateTime, locale) - : formatTimeWithSeconds(dateTime, locale); + ? formatDateTimeWithSeconds(dateTime, locale, config) + : formatTimeWithSeconds(dateTime, locale, config); }; diff --git a/src/panels/config/repairs/dialog-repairs-issue.ts b/src/panels/config/repairs/dialog-repairs-issue.ts index 3aae980d29..4e628ccbd0 100644 --- a/src/panels/config/repairs/dialog-repairs-issue.ts +++ b/src/panels/config/repairs/dialog-repairs-issue.ts @@ -100,7 +100,8 @@ class DialogRepairsIssue extends LitElement { ${this._issue.created ? formatDateNumeric( new Date(this._issue.created), - this.hass.locale + this.hass.locale, + this.hass.config ) : ""}
diff --git a/src/panels/config/repairs/dialog-system-information.ts b/src/panels/config/repairs/dialog-system-information.ts index ce2bfefd5a..bc3b1e0181 100644 --- a/src/panels/config/repairs/dialog-system-information.ts +++ b/src/panels/config/repairs/dialog-system-information.ts @@ -349,7 +349,11 @@ class DialogSystemInformation extends LitElement { `} `; } else if (info.type === "date") { - value = formatDateTime(new Date(info.value), this.hass.locale); + value = formatDateTime( + new Date(info.value), + this.hass.locale, + this.hass.config + ); } } else { value = domainInfo.info[key]; @@ -425,7 +429,11 @@ class DialogSystemInformation extends LitElement { } else if (info.type === "failed") { value = `failed to load: ${info.error}`; } else if (info.type === "date") { - value = formatDateTime(new Date(info.value), this.hass.locale); + value = formatDateTime( + new Date(info.value), + this.hass.locale, + this.hass.config + ); } } else { value = domainInfo.info[key]; diff --git a/src/panels/config/scene/ha-scene-dashboard.ts b/src/panels/config/scene/ha-scene-dashboard.ts index 11762b419b..df9f6be040 100644 --- a/src/panels/config/scene/ha-scene-dashboard.ts +++ b/src/panels/config/scene/ha-scene-dashboard.ts @@ -118,7 +118,11 @@ class HaSceneDashboard extends LitElement { return html` ${last_activated && !isUnavailableState(last_activated) ? dayDifference > 3 - ? formatShortDateTime(date, this.hass.locale) + ? formatShortDateTime( + date, + this.hass.locale, + this.hass.config + ) : relativeTime(date, this.hass.locale) : this.hass.localize("ui.components.relative_time.never")} `; diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index f5d80a60be..61ac52dc3f 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -118,7 +118,11 @@ class HaScriptPicker extends LitElement { ${this.hass.localize("ui.card.automation.last_triggered")}: ${script.attributes.last_triggered ? dayDifference > 3 - ? formatShortDateTime(date, this.hass.locale) + ? formatShortDateTime( + date, + this.hass.locale, + this.hass.config + ) : relativeTime(date, this.hass.locale) : this.hass.localize("ui.components.relative_time.never")} @@ -139,7 +143,7 @@ class HaScriptPicker extends LitElement { return html` ${last_triggered ? dayDifference > 3 - ? formatShortDateTime(date, this.hass.locale) + ? formatShortDateTime(date, this.hass.locale, this.hass.config) : relativeTime(date, this.hass.locale) : this.hass.localize("ui.components.relative_time.never")} `; diff --git a/src/panels/config/script/ha-script-trace.ts b/src/panels/config/script/ha-script-trace.ts index 54bb1542d2..dd410b745a 100644 --- a/src/panels/config/script/ha-script-trace.ts +++ b/src/panels/config/script/ha-script-trace.ts @@ -191,7 +191,8 @@ export class HaScriptTrace extends LitElement { html`` )} diff --git a/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts b/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts index 638fad5c3c..e75f3a230f 100644 --- a/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts +++ b/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts @@ -64,7 +64,8 @@ export class AssistPipelineDebug extends LitElement { html`` )} diff --git a/src/panels/developer-tools/event/event-subscribe-card.ts b/src/panels/developer-tools/event/event-subscribe-card.ts index 0b0ce881b6..d1d7afc0aa 100644 --- a/src/panels/developer-tools/event/event-subscribe-card.ts +++ b/src/panels/developer-tools/event/event-subscribe-card.ts @@ -80,7 +80,8 @@ class EventSubscribeCard extends LitElement { )} ${formatTime( new Date(event.event.time_fired), - this.hass!.locale + this.hass!.locale, + this.hass!.config )}: ${growth} ${unit} - ${formatDateTime(new Date(stat.start), this.hass.locale)} + ${formatDateTime( + new Date(stat.start), + this.hass.locale, + this.hass.config + )} @@ -213,7 +217,8 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement { ${formatDateTime( new Date(this._chosenStat!.start), - this.hass.locale + this.hass.locale, + this.hass.config )} @@ -223,7 +228,8 @@ export class DialogStatisticsFixUnsupportedUnitMetadata extends LitElement { ${formatDateTime( new Date(this._chosenStat!.end), - this.hass.locale + this.hass.locale, + this.hass.config )} diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts index 08b8f0d90c..b88861d44c 100644 --- a/src/panels/history/ha-panel-history.ts +++ b/src/panels/history/ha-panel-history.ts @@ -1,14 +1,5 @@ import { mdiFilterRemove, mdiRefresh } from "@mdi/js"; -import { - addDays, - differenceInHours, - endOfToday, - endOfWeek, - endOfYesterday, - startOfToday, - startOfWeek, - startOfYesterday, -} from "date-fns/esm"; +import { differenceInHours } from "date-fns/esm"; import { HassServiceTarget, UnsubscribeFunc, @@ -16,7 +7,6 @@ import { import { css, html, LitElement, PropertyValues } from "lit"; import { property, query, state } from "lit/decorators"; import { ensureArray } from "../../common/array/ensure-array"; -import { firstWeekdayIndex } from "../../common/datetime/first_weekday"; import { LocalStorage } from "../../common/decorators/local-storage"; import { navigate } from "../../common/navigate"; import { constructUrlCurrentPath } from "../../common/url/construct-url"; @@ -31,10 +21,11 @@ import "../../components/chart/state-history-charts"; import type { StateHistoryCharts } from "../../components/chart/state-history-charts"; import "../../components/ha-circular-progress"; import "../../components/ha-date-range-picker"; -import type { DateRangePickerRanges } from "../../components/ha-date-range-picker"; import "../../components/ha-icon-button"; +import "../../components/ha-icon-button-arrow-prev"; import "../../components/ha-menu-button"; import "../../components/ha-target-picker"; +import "../../components/ha-top-app-bar-fixed"; import { AreaDeviceLookup, AreaEntityLookup, @@ -55,8 +46,6 @@ import { import { SubscribeMixin } from "../../mixins/subscribe-mixin"; import { haStyle } from "../../resources/styles"; import { HomeAssistant } from "../../types"; -import "../../components/ha-top-app-bar-fixed"; -import "../../components/ha-icon-button-arrow-prev"; class HaPanelHistory extends SubscribeMixin(LitElement) { @property({ attribute: false }) hass!: HomeAssistant; @@ -76,8 +65,6 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { @state() private _stateHistory?: HistoryResult; - @state() private _ranges?: DateRangePickerRanges; - @state() private _deviceEntityLookup?: DeviceEntityLookup; @state() private _areaEntityLookup?: AreaEntityLookup; @@ -178,7 +165,6 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { ?disabled=${this._isLoading} .startDate=${this._startDate} .endDate=${this._endDate} - .ranges=${this._ranges} @change=${this._dateRangeChanged} > - ${formatDate(new Date(item.when * 1000), this.hass.locale)} + ${formatDate( + new Date(item.when * 1000), + this.hass.locale, + this.hass.config + )} ` : nothing} @@ -229,7 +233,8 @@ class HaLogbookRenderer extends LitElement { ${formatTimeWithSeconds( new Date(item.when * 1000), - this.hass.locale + this.hass.locale, + this.hass.config )} - diff --git a/src/panels/logbook/ha-panel-logbook.ts b/src/panels/logbook/ha-panel-logbook.ts index aba47b77d4..9a93813793 100644 --- a/src/panels/logbook/ha-panel-logbook.ts +++ b/src/panels/logbook/ha-panel-logbook.ts @@ -1,16 +1,6 @@ import { mdiRefresh } from "@mdi/js"; -import { - addDays, - endOfToday, - endOfWeek, - endOfYesterday, - startOfToday, - startOfWeek, - startOfYesterday, -} from "date-fns/esm"; import { css, html, LitElement, PropertyValues } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { firstWeekdayIndex } from "../../common/datetime/first_weekday"; import { navigate } from "../../common/navigate"; import { constructUrlCurrentPath } from "../../common/url/construct-url"; import { @@ -20,7 +10,6 @@ import { } from "../../common/url/search-params"; import "../../components/entity/ha-entity-picker"; import "../../components/ha-date-range-picker"; -import type { DateRangePickerRanges } from "../../components/ha-date-range-picker"; import "../../components/ha-icon-button"; import "../../components/ha-icon-button-arrow-prev"; import "../../components/ha-menu-button"; @@ -40,8 +29,6 @@ export class HaPanelLogbook extends LitElement { @state() _entityIds?: string[]; - @state() private _ranges?: DateRangePickerRanges; - @state() private _showBack?: boolean; @@ -91,7 +78,6 @@ export class HaPanelLogbook extends LitElement { .hass=${this.hass} .startDate=${this._time.range[0]} .endDate=${this._time.range[1]} - .ranges=${this._ranges} @change=${this._dateRangeChanged} > @@ -123,24 +109,6 @@ export class HaPanelLogbook extends LitElement { return; } - const today = new Date(); - const weekStartsOn = firstWeekdayIndex(this.hass.locale); - const weekStart = startOfWeek(today, { weekStartsOn }); - const weekEnd = endOfWeek(today, { weekStartsOn }); - - this._ranges = { - [this.hass.localize("ui.components.date-range-picker.ranges.today")]: [ - startOfToday(), - endOfToday(), - ], - [this.hass.localize("ui.components.date-range-picker.ranges.yesterday")]: - [startOfYesterday(), endOfYesterday()], - [this.hass.localize("ui.components.date-range-picker.ranges.this_week")]: - [weekStart, weekEnd], - [this.hass.localize("ui.components.date-range-picker.ranges.last_week")]: - [addDays(weekStart, -7), addDays(weekEnd, -7)], - }; - this._applyURLParams(); } diff --git a/src/panels/lovelace/cards/energy/hui-energy-compare-card.ts b/src/panels/lovelace/cards/energy/hui-energy-compare-card.ts index 552680e2e9..4c545668fe 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-compare-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-compare-card.ts @@ -60,18 +60,27 @@ export class HuiEnergyCompareCard ${this.hass.localize("ui.panel.energy.compare.info", { start: html`${formatDate(this._start!, this.hass.locale)}${dayDifference > 0 + >${formatDate( + this._start!, + this.hass.locale, + this.hass.config + )}${dayDifference > 0 ? ` - - ${formatDate(this._end || endOfDay(new Date()), this.hass.locale)}` + ${formatDate( + this._end || endOfDay(new Date()), + this.hass.locale, + this.hass.config + )}` : ""}`, end: html`${formatDate( this._startCompare, - this.hass.locale + this.hass.locale, + this.hass.config )}${dayDifference > 0 ? ` - - ${formatDate(this._endCompare, this.hass.locale)}` + ${formatDate(this._endCompare, this.hass.locale, this.hass.config)}` : ""}`, })} diff --git a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts index 8fa32d49b1..432dada500 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts @@ -12,7 +12,7 @@ import { isToday, startOfToday, } from "date-fns"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { HassConfig, UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -112,6 +112,7 @@ export class HuiEnergyGasGraphCard this._start, this._end, this.hass.locale, + this.hass.config, this._unit, this._compareStart, this._compareEnd @@ -137,6 +138,7 @@ export class HuiEnergyGasGraphCard start: Date, end: Date, locale: FrontendLocaleData, + config: HassConfig, unit?: string, compareStart?: Date, compareEnd?: Date @@ -167,7 +169,8 @@ export class HuiEnergyGasGraphCard suggestedMax: end.getTime(), adapters: { date: { - locale: locale, + locale, + config, }, }, ticks: { @@ -221,10 +224,11 @@ export class HuiEnergyGasGraphCard } const date = new Date(datasets[0].parsed.x); return `${ - compare ? `${formatDateShort(date, locale)}: ` : "" - }${formatTime(date, locale)} – ${formatTime( + compare ? `${formatDateShort(date, locale, config)}: ` : "" + }${formatTime(date, locale, config)} – ${formatTime( addHours(date, 1), - locale + locale, + config )}`; }, label: (context) => diff --git a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts index 6c693b4b46..49290b5647 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts @@ -12,7 +12,7 @@ import { isToday, startOfToday, } from "date-fns/esm"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { HassConfig, UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -111,6 +111,7 @@ export class HuiEnergySolarGraphCard this._start, this._end, this.hass.locale, + this.hass.config, this._compareStart, this._compareEnd )} @@ -135,6 +136,7 @@ export class HuiEnergySolarGraphCard start: Date, end: Date, locale: FrontendLocaleData, + config: HassConfig, compareStart?: Date, compareEnd?: Date ): ChartOptions => { @@ -164,7 +166,8 @@ export class HuiEnergySolarGraphCard suggestedMax: end.getTime(), adapters: { date: { - locale: locale, + locale, + config, }, }, ticks: { @@ -217,10 +220,11 @@ export class HuiEnergySolarGraphCard } const date = new Date(datasets[0].parsed.x); return `${ - compare ? `${formatDateShort(date, locale)}: ` : "" - }${formatTime(date, locale)} – ${formatTime( + compare ? `${formatDateShort(date, locale, config)}: ` : "" + }${formatTime(date, locale, config)} – ${formatTime( addHours(date, 1), - locale + locale, + config )}`; }, label: (context) => diff --git a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts index 693f5deb83..5b97bd290d 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts @@ -12,7 +12,7 @@ import { isToday, startOfToday, } from "date-fns/esm"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { HassConfig, UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -105,6 +105,7 @@ export class HuiEnergyUsageGraphCard this._start, this._end, this.hass.locale, + this.hass.config, this._compareStart, this._compareEnd )} @@ -129,6 +130,7 @@ export class HuiEnergyUsageGraphCard start: Date, end: Date, locale: FrontendLocaleData, + config: HassConfig, compareStart?: Date, compareEnd?: Date ): ChartOptions => { @@ -158,7 +160,8 @@ export class HuiEnergyUsageGraphCard suggestedMax: end.getTime(), adapters: { date: { - locale: locale, + locale, + config, }, }, ticks: { @@ -213,10 +216,11 @@ export class HuiEnergyUsageGraphCard } const date = new Date(datasets[0].parsed.x); return `${ - compare ? `${formatDateShort(date, locale)}: ` : "" - }${formatTime(date, locale)} – ${formatTime( + compare ? `${formatDateShort(date, locale, config)}: ` : "" + }${formatTime(date, locale, config)} – ${formatTime( addHours(date, 1), - locale + locale, + config )}`; }, label: (context) => diff --git a/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts index 709921d45c..84f21089c2 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts @@ -12,7 +12,7 @@ import { isToday, startOfToday, } from "date-fns"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { HassConfig, UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -112,6 +112,7 @@ export class HuiEnergyWaterGraphCard this._start, this._end, this.hass.locale, + this.hass.config, this._unit, this._compareStart, this._compareEnd @@ -137,6 +138,7 @@ export class HuiEnergyWaterGraphCard start: Date, end: Date, locale: FrontendLocaleData, + config: HassConfig, unit?: string, compareStart?: Date, compareEnd?: Date @@ -167,7 +169,8 @@ export class HuiEnergyWaterGraphCard suggestedMax: end.getTime(), adapters: { date: { - locale: locale, + locale, + config, }, }, ticks: { @@ -221,10 +224,11 @@ export class HuiEnergyWaterGraphCard } const date = new Date(datasets[0].parsed.x); return `${ - compare ? `${formatDateShort(date, locale)}: ` : "" - }${formatTime(date, locale)} – ${formatTime( + compare ? `${formatDateShort(date, locale, config)}: ` : "" + }${formatTime(date, locale, config)} – ${formatTime( addHours(date, 1), - locale + locale, + config )}`; }, label: (context) => diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index 6f00fc3dfa..1e9167e5a4 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -2,7 +2,11 @@ import { consume } from "@lit-labs/context"; import "@material/mwc-ripple"; import type { Ripple } from "@material/mwc-ripple"; import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; -import { HassEntities, HassEntity } from "home-assistant-js-websocket"; +import { + HassConfig, + HassEntities, + HassEntity, +} from "home-assistant-js-websocket"; import { CSSResultGroup, LitElement, @@ -27,6 +31,7 @@ import { iconColorCSS } from "../../../common/style/icon_color_css"; import "../../../components/ha-card"; import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { + configContext, entitiesContext, localeContext, localizeContext, @@ -103,6 +108,10 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { @consume({ context: localeContext, subscribe: true }) _locale!: FrontendLocaleData; + @state() + @consume({ context: configContext, subscribe: true }) + _hassConfig!: HassConfig; + @consume({ context: entitiesContext, subscribe: true }) @transform({ transformer: function (this: HuiButtonCard, value) { @@ -223,6 +232,7 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { this._localize, stateObj, this._locale, + this._hassConfig, this._entity )} ` diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index 4d948cd0d7..548dbd80ec 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -163,6 +163,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, this._config.attribute! ) @@ -180,6 +181,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )}${showUnit diff --git a/src/panels/lovelace/cards/hui-glance-card.ts b/src/panels/lovelace/cards/hui-glance-card.ts index f22ac84267..1e42db66c7 100644 --- a/src/panels/lovelace/cards/hui-glance-card.ts +++ b/src/panels/lovelace/cards/hui-glance-card.ts @@ -337,6 +337,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard { this.hass!.localize, stateObj, this.hass!.locale, + this.hass!.config, this.hass!.entities )} diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index a99331e67e..9e24121a29 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -140,6 +140,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "mode" )} diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index e41aef6afe..9c2041c7ba 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -161,6 +161,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )} diff --git a/src/panels/lovelace/cards/hui-map-card.ts b/src/panels/lovelace/cards/hui-map-card.ts index d84694d048..ec9dfa6138 100644 --- a/src/panels/lovelace/cards/hui-map-card.ts +++ b/src/panels/lovelace/cards/hui-map-card.ts @@ -374,11 +374,19 @@ class HuiMapCard extends LitElement implements LovelaceCard { if ((config.hours_to_show! ?? DEFAULT_HOURS_TO_SHOW) > 144) { // if showing > 6 days in the history trail, show the full // date and time - p.tooltip = formatDateTime(t, this.hass.locale); + p.tooltip = formatDateTime(t, this.hass.locale, this.hass.config); } else if (isToday(t)) { - p.tooltip = formatTimeWithSeconds(t, this.hass.locale); + p.tooltip = formatTimeWithSeconds( + t, + this.hass.locale, + this.hass.config + ); } else { - p.tooltip = formatTimeWeekday(t, this.hass.locale); + p.tooltip = formatTimeWeekday( + t, + this.hass.locale, + this.hass.config + ); } points.push(p); } diff --git a/src/panels/lovelace/cards/hui-picture-entity-card.ts b/src/panels/lovelace/cards/hui-picture-entity-card.ts index 665aad7f32..1d6c51fcd7 100644 --- a/src/panels/lovelace/cards/hui-picture-entity-card.ts +++ b/src/panels/lovelace/cards/hui-picture-entity-card.ts @@ -123,6 +123,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard { this.hass!.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities ); diff --git a/src/panels/lovelace/cards/hui-picture-glance-card.ts b/src/panels/lovelace/cards/hui-picture-glance-card.ts index 298a745026..b307d0f1d0 100644 --- a/src/panels/lovelace/cards/hui-picture-glance-card.ts +++ b/src/panels/lovelace/cards/hui-picture-glance-card.ts @@ -257,6 +257,7 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard { this.hass!.localize, stateObj, this.hass!.locale, + this.hass!.config, this.hass!.entities )}`} > @@ -280,6 +281,7 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard { this.hass!.localize, stateObj, this.hass!.locale, + this.hass!.config, this.hass!.entities )} diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index b186cf8e59..0438374c7a 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -235,6 +235,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "hvac_action" ) @@ -242,6 +243,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities ) } @@ -254,6 +256,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "preset_mode" )} diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 5f2b43b83a..0afb105c2f 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -228,6 +228,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { this.hass!.localize, stateObj, this.hass!.locale, + this.hass!.config, this.hass!.entities ); diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index 066d14fa02..85f29fc0a4 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -39,6 +39,7 @@ import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfil import { createEntityNotFoundWarning } from "../components/hui-warning"; import type { LovelaceCard, LovelaceCardEditor } from "../types"; import type { WeatherForecastCardConfig } from "./types"; +import { formatDateWeekdayShort } from "../../../common/datetime/format_date"; const DAY_IN_MILLISECONDS = 86400000; @@ -222,6 +223,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )} @@ -319,13 +321,15 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { ? html` ${formatTime( new Date(item.datetime), - this.hass!.locale + this.hass!.locale, + this.hass!.config )} ` : html` - ${new Date(item.datetime).toLocaleDateString( - this.hass!.language, - { weekday: "short" } + ${formatDateWeekdayShort( + new Date(item.datetime), + this.hass!.locale, + this.hass!.config )} `} diff --git a/src/panels/lovelace/components/hui-energy-period-selector.ts b/src/panels/lovelace/components/hui-energy-period-selector.ts index c4054e7e7c..9cd6666cd3 100644 --- a/src/panels/lovelace/components/hui-energy-period-selector.ts +++ b/src/panels/lovelace/components/hui-energy-period-selector.ts @@ -21,6 +21,7 @@ import { import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { calcDate } from "../../../common/datetime/calc_date"; import { firstWeekdayIndex } from "../../../common/datetime/first_weekday"; import { formatDate, @@ -105,17 +106,27 @@ export class HuiEnergyPeriodSelector extends SubscribeMixin(LitElement) {
${this._period === "day" - ? formatDate(this._startDate, this.hass.locale) + ? formatDate(this._startDate, this.hass.locale, this.hass.config) : this._period === "month" - ? formatDateMonthYear(this._startDate, this.hass.locale) + ? formatDateMonthYear( + this._startDate, + this.hass.locale, + this.hass.config + ) : this._period === "year" - ? formatDateYear(this._startDate, this.hass.locale) + ? formatDateYear( + this._startDate, + this.hass.locale, + this.hass.config + ) : `${formatDateShort( this._startDate, - this.hass.locale + this.hass.locale, + this.hass.config )} – ${formatDateShort( this._endDate || new Date(), - this.hass.locale + this.hass.locale, + this.hass.config )}`} string; + [key: string]: ( + ts: Date, + lang: FrontendLocaleData, + config: HassConfig + ) => string; } = { date: formatDate, datetime: formatDateTime, @@ -63,7 +68,9 @@ class HuiTimestampDisplay extends LitElement { return html` ${this._relative} `; } if (format in FORMATS) { - return html` ${FORMATS[format](this.ts, this.hass.locale)} `; + return html` + ${FORMATS[format](this.ts, this.hass.locale, this.hass.config)} + `; } return html`${this.hass.localize( "ui.panel.lovelace.components.timestamp-display.invalid_format" diff --git a/src/panels/lovelace/elements/hui-state-label-element.ts b/src/panels/lovelace/elements/hui-state-label-element.ts index 4d52fb81f4..d7f3ce9872 100644 --- a/src/panels/lovelace/elements/hui-state-label-element.ts +++ b/src/panels/lovelace/elements/hui-state-label-element.ts @@ -87,6 +87,7 @@ class HuiStateLabelElement extends LitElement implements LovelaceElement { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities ) : stateObj.attributes[this._config.attribute]}${this._config.suffix} diff --git a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts index 9dad7f8e6d..146943251e 100644 --- a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts @@ -70,6 +70,7 @@ class HuiGroupEntityRow extends LitElement implements LovelaceRow { this.hass!.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )}
diff --git a/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts b/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts index f2666cfe99..4aa7738253 100644 --- a/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts @@ -54,6 +54,7 @@ class HuiHumidifierEntityRow extends LitElement implements LovelaceRow { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, "mode" )})` diff --git a/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts index ab81ff7eb1..6488d33843 100644 --- a/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts @@ -100,6 +100,7 @@ class HuiInputNumberEntityRow extends LitElement implements LovelaceRow { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, stateObj.state )} diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index 2dc020a493..f2f481ad46 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -193,6 +193,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )} > diff --git a/src/panels/lovelace/entity-rows/hui-number-entity-row.ts b/src/panels/lovelace/entity-rows/hui-number-entity-row.ts index 0046379e3f..bd55652798 100644 --- a/src/panels/lovelace/entity-rows/hui-number-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-number-entity-row.ts @@ -104,6 +104,7 @@ class HuiNumberEntityRow extends LitElement implements LovelaceRow { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, stateObj.state )} diff --git a/src/panels/lovelace/entity-rows/hui-select-entity-row.ts b/src/panels/lovelace/entity-rows/hui-select-entity-row.ts index c263519425..2d7d3c51e1 100644 --- a/src/panels/lovelace/entity-rows/hui-select-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-select-entity-row.ts @@ -82,6 +82,7 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow { this.hass!.localize, stateObj, this.hass!.locale, + this.hass!.config, this.hass!.entities, option )} diff --git a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts index ce291b44cc..0d536ca9f9 100644 --- a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts @@ -83,6 +83,7 @@ class HuiSensorEntityRow extends LitElement implements LovelaceRow { this.hass!.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )}
diff --git a/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts b/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts index 98e1b44a43..23b4cb8720 100644 --- a/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts @@ -53,6 +53,7 @@ class HuiSimpleEntityRow extends LitElement implements LovelaceRow { this.hass!.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities )} diff --git a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts index 7ea096e9ad..611fd2bdd5 100644 --- a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts @@ -65,6 +65,7 @@ class HuiToggleEntityRow extends LitElement implements LovelaceRow { this.hass!.localize, stateObj, this.hass!.locale, + this.hass.config, this.hass!.entities )} diff --git a/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts b/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts index 088869be37..f8badf7b10 100644 --- a/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-weather-entity-row.ts @@ -148,6 +148,7 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities ) : html` diff --git a/src/panels/lovelace/special-rows/hui-attribute-row.ts b/src/panels/lovelace/special-rows/hui-attribute-row.ts index b0e95de02f..b8db4ebf56 100644 --- a/src/panels/lovelace/special-rows/hui-attribute-row.ts +++ b/src/panels/lovelace/special-rows/hui-attribute-row.ts @@ -75,6 +75,7 @@ class HuiAttributeRow extends LitElement implements LovelaceRow { this.hass.localize, stateObj, this.hass.locale, + this.hass.config, this.hass.entities, this._config.attribute, attribute diff --git a/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts b/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts index fb0f23bf29..da69431ad0 100644 --- a/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts @@ -59,6 +59,7 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature { this.hass!.localize, this.stateObj!, this.hass!.locale, + this.hass!.config, this.hass!.entities, speed ); diff --git a/src/panels/profile/ha-panel-profile.ts b/src/panels/profile/ha-panel-profile.ts index 628c44ef38..47bccf93ea 100644 --- a/src/panels/profile/ha-panel-profile.ts +++ b/src/panels/profile/ha-panel-profile.ts @@ -28,6 +28,7 @@ import "./ha-pick-number-format-row"; import "./ha-pick-theme-row"; import "./ha-pick-time-format-row"; import "./ha-pick-date-format-row"; +import "./ha-pick-time-zone-row"; import "./ha-push-notifications-row"; import "./ha-refresh-tokens-card"; import "./ha-set-suspend-row"; @@ -101,6 +102,10 @@ class HaPanelProfile extends LitElement { .narrow=${this.narrow} .hass=${this.hass} > + ${Object.values(DateFormat).map((format) => { - const formattedDate = formatDateNumeric(date, { - ...this.hass.locale, - date_format: format, - }); + const formattedDate = formatDateNumeric( + date, + { + ...this.hass.locale, + date_format: format, + }, + this.hass.config + ); const value = this.hass.localize( `ui.panel.profile.date_format.formats.${format}` ); diff --git a/src/panels/profile/ha-pick-time-format-row.ts b/src/panels/profile/ha-pick-time-format-row.ts index e890e10474..b9d24d597f 100644 --- a/src/panels/profile/ha-pick-time-format-row.ts +++ b/src/panels/profile/ha-pick-time-format-row.ts @@ -35,10 +35,14 @@ class TimeFormatRow extends LitElement { naturalMenuWidth > ${Object.values(TimeFormat).map((format) => { - const formattedTime = formatTime(date, { - ...this.hass.locale, - time_format: format, - }); + const formattedTime = formatTime( + date, + { + ...this.hass.locale, + time_format: format, + }, + this.hass.config + ); const value = this.hass.localize( `ui.panel.profile.time_format.formats.${format}` ); diff --git a/src/panels/profile/ha-pick-time-zone-row.ts b/src/panels/profile/ha-pick-time-zone-row.ts new file mode 100644 index 0000000000..c1bd070406 --- /dev/null +++ b/src/panels/profile/ha-pick-time-zone-row.ts @@ -0,0 +1,76 @@ +import "@material/mwc-list/mwc-list-item"; +import { html, LitElement, TemplateResult } from "lit"; +import { customElement, property } from "lit/decorators"; +import { formatDateTimeNumeric } from "../../common/datetime/format_date_time"; +import { fireEvent } from "../../common/dom/fire_event"; +import "../../components/ha-card"; +import "../../components/ha-select"; +import "../../components/ha-settings-row"; +import { TimeZone } from "../../data/translation"; +import { HomeAssistant } from "../../types"; + +@customElement("ha-pick-time-zone-row") +class TimeZoneRow extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public narrow!: boolean; + + protected render(): TemplateResult { + const date = new Date(); + return html` + + + ${this.hass.localize("ui.panel.profile.time_zone.header")} + + + ${this.hass.localize("ui.panel.profile.time_zone.description")} + + + ${Object.values(TimeZone).map((format) => { + const formattedTime = formatDateTimeNumeric( + date, + { + ...this.hass.locale, + time_zone: format, + }, + this.hass.config + ); + return html` + ${this.hass.localize( + `ui.panel.profile.time_zone.options.${format}`, + { + timezone: (format === "server" + ? this.hass.config.time_zone + : Intl.DateTimeFormat?.().resolvedOptions?.().timeZone || + "" + ).replace("_", " "), + } + )} + ${formattedTime} + `; + })} + + + `; + } + + private async _handleFormatSelection(ev) { + fireEvent(this, "hass-time-zone-select", ev.target.value); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-pick-time-zone-row": TimeZoneRow; + } +} diff --git a/src/state-summary/state-card-display.ts b/src/state-summary/state-card-display.ts index 9214ecc1fb..a168d05711 100755 --- a/src/state-summary/state-card-display.ts +++ b/src/state-summary/state-card-display.ts @@ -42,7 +42,7 @@ export class StateCardDisplay extends LitElement { this.stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP && !isUnavailableState(this.stateObj.state) - ? html` diff --git a/src/state-summary/state-card-input_number.ts b/src/state-summary/state-card-input_number.ts index d455a5a862..6cd218fb03 100644 --- a/src/state-summary/state-card-input_number.ts +++ b/src/state-summary/state-card-input_number.ts @@ -72,6 +72,7 @@ class StateCardInputNumber extends LitElement { this.hass.localize, this.stateObj, this.hass.locale, + this.hass.config, this.hass.entities, this.stateObj.state )} diff --git a/src/state-summary/state-card-select.ts b/src/state-summary/state-card-select.ts index 78c749c48e..354136c67e 100644 --- a/src/state-summary/state-card-select.ts +++ b/src/state-summary/state-card-select.ts @@ -36,6 +36,7 @@ class StateCardSelect extends LitElement { this.hass.localize, this.stateObj, this.hass.locale, + this.hass.config, this.hass.entities, option )} diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index b02e26d837..c2c81cc87f 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -23,6 +23,7 @@ import { NumberFormat, DateFormat, TimeFormat, + TimeZone, } from "../data/translation"; import { subscribePanels } from "../data/ws-panels"; import { translationMetadata } from "../resources/translations-metadata"; @@ -63,6 +64,7 @@ export const connectionMixin = >( number_format: NumberFormat.language, time_format: TimeFormat.language, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.language, }, resources: null as any, diff --git a/src/state/translations-mixin.ts b/src/state/translations-mixin.ts index 149c478925..66b86a140a 100644 --- a/src/state/translations-mixin.ts +++ b/src/state/translations-mixin.ts @@ -15,6 +15,7 @@ import { TimeFormat, DateFormat, TranslationCategory, + TimeZone, } from "../data/translation"; import { translationMetadata } from "../resources/translations-metadata"; import { Constructor, HomeAssistant } from "../types"; @@ -41,6 +42,9 @@ declare global { "hass-date-format-select": { date_format: DateFormat; }; + "hass-time-zone-select": { + time_zone: TimeZone; + }; "hass-first-weekday-select": { first_weekday: FirstWeekday; }; @@ -89,6 +93,9 @@ export default >(superClass: T) => this.addEventListener("hass-date-format-select", (e) => { this._selectDateFormat((e as CustomEvent).detail, true); }); + this.addEventListener("hass-time-zone-select", (e) => { + this._selectTimeZone((e as CustomEvent).detail, true); + }); this.addEventListener("hass-first-weekday-select", (e) => { this._selectFirstWeekday((e as CustomEvent).detail, true); }); @@ -137,6 +144,13 @@ export default >(superClass: T) => // We just got date_format from backend, no need to save back this._selectDateFormat(locale.date_format, false); } + if ( + locale?.time_zone && + this.hass!.locale.time_zone !== locale.time_zone + ) { + // We just got time_zone from backend, no need to save back + this._selectTimeZone(locale.time_zone, false); + } if ( locale?.first_weekday && this.hass!.locale.first_weekday !== locale.first_weekday @@ -203,6 +217,15 @@ export default >(superClass: T) => } } + private _selectTimeZone(time_zone: TimeZone, saveToBackend: boolean) { + this._updateHass({ + locale: { ...this.hass!.locale, time_zone }, + }); + if (saveToBackend) { + saveTranslationPreferences(this.hass!, this.hass!.locale); + } + } + private _selectFirstWeekday( first_weekday: FirstWeekday, saveToBackend: boolean diff --git a/src/translations/en.json b/src/translations/en.json index a9f9608190..f03055696a 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4928,6 +4928,15 @@ "24": "24 hours" } }, + "time_zone": { + "header": "Time Zone", + "dropdown_label": "Time zone", + "description": "Choose the time zone to use for displaying times.", + "options": { + "local": "Use your local time zone ({timezone})", + "server": "Use server time zone ({timezone})" + } + }, "date_format": { "header": "Date Format", "dropdown_label": "Date format", diff --git a/src/util/common-translation.ts b/src/util/common-translation.ts index be14097dd8..041d1fa537 100644 --- a/src/util/common-translation.ts +++ b/src/util/common-translation.ts @@ -77,6 +77,7 @@ export async function getUserLocale( const number_format = result?.number_format; const time_format = result?.time_format; const date_format = result?.date_format; + const time_zone = result?.time_zone; const first_weekday = result?.first_weekday; if (language) { const availableLanguage = findAvailableLanguage(language); @@ -85,7 +86,8 @@ export async function getUserLocale( language: availableLanguage, number_format, time_format, - date_format: date_format, + date_format, + time_zone, first_weekday, }; } @@ -93,7 +95,8 @@ export async function getUserLocale( return { number_format, time_format, - date_format: date_format, + date_format, + time_zone, first_weekday, }; } diff --git a/test/common/datetime/format_date.ts b/test/common/datetime/format_date.ts index 9d6841ea7d..d399b58e25 100644 --- a/test/common/datetime/format_date.ts +++ b/test/common/datetime/format_date.ts @@ -6,20 +6,27 @@ import { TimeFormat, FirstWeekday, DateFormat, + TimeZone, } from "../../../src/data/translation"; +import { demoConfig } from "../../../src/fake_data/demo_config"; describe("formatDate", () => { const dateObj = new Date(2017, 10, 18, 11, 12, 13, 1400); it("Formats English dates", () => { assert.strictEqual( - formatDate(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.language, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatDate( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "November 18, 2017" ); }); diff --git a/test/common/datetime/format_date_time.ts b/test/common/datetime/format_date_time.ts index 5632d60615..2f7988e5d3 100644 --- a/test/common/datetime/format_date_time.ts +++ b/test/common/datetime/format_date_time.ts @@ -9,30 +9,42 @@ import { TimeFormat, FirstWeekday, DateFormat, + TimeZone, } from "../../../src/data/translation"; +import { demoConfig } from "../../../src/fake_data/demo_config"; describe("formatDateTime", () => { const dateObj = new Date(2017, 10, 18, 23, 12, 13, 400); it("Formats English date times", () => { assert.strictEqual( - formatDateTime(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.am_pm, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatDateTime( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.am_pm, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "November 18, 2017 at 11:12 PM" ); assert.strictEqual( - formatDateTime(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.twenty_four, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatDateTime( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.twenty_four, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "November 18, 2017 at 23:12" ); }); @@ -43,23 +55,34 @@ describe("formatDateTimeWithSeconds", () => { it("Formats English date times with seconds", () => { assert.strictEqual( - formatDateTimeWithSeconds(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.am_pm, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatDateTimeWithSeconds( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.am_pm, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "November 18, 2017 at 11:12:13 PM" ); assert.strictEqual( - formatDateTimeWithSeconds(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.twenty_four, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatDateTimeWithSeconds( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.twenty_four, + date_format: DateFormat.language, + time_zone: TimeZone.local, + + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "November 18, 2017 at 23:12:13" ); }); diff --git a/test/common/datetime/format_time.ts b/test/common/datetime/format_time.ts index 3c7e7899c7..3dbbcfd0a8 100644 --- a/test/common/datetime/format_time.ts +++ b/test/common/datetime/format_time.ts @@ -10,30 +10,42 @@ import { TimeFormat, FirstWeekday, DateFormat, + TimeZone, } from "../../../src/data/translation"; +import { demoConfig } from "../../../src/fake_data/demo_config"; describe("formatTime", () => { const dateObj = new Date(2017, 10, 18, 23, 12, 13, 1400); it("Formats English times", () => { assert.strictEqual( - formatTime(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.am_pm, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatTime( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.am_pm, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "11:12 PM" ); assert.strictEqual( - formatTime(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.twenty_four, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatTime( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.twenty_four, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "23:12" ); }); @@ -44,23 +56,33 @@ describe("formatTimeWithSeconds", () => { it("Formats English times with seconds", () => { assert.strictEqual( - formatTimeWithSeconds(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.am_pm, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatTimeWithSeconds( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.am_pm, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "11:12:13 PM" ); assert.strictEqual( - formatTimeWithSeconds(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.twenty_four, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatTimeWithSeconds( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.twenty_four, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "23:12:13" ); }); @@ -71,23 +93,33 @@ describe("formatTimeWeekday", () => { it("Formats English times", () => { assert.strictEqual( - formatTimeWeekday(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.am_pm, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatTimeWeekday( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.am_pm, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "Saturday 11:12 PM" ); assert.strictEqual( - formatTimeWeekday(dateObj, { - language: "en", - number_format: NumberFormat.language, - time_format: TimeFormat.twenty_four, - date_format: DateFormat.language, - first_weekday: FirstWeekday.language, - }), + formatTimeWeekday( + dateObj, + { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.twenty_four, + date_format: DateFormat.language, + time_zone: TimeZone.local, + first_weekday: FirstWeekday.language, + }, + demoConfig + ), "Saturday 23:12" ); }); diff --git a/test/common/datetime/relative_time.ts b/test/common/datetime/relative_time.ts index ebdf39185b..a99ed08765 100644 --- a/test/common/datetime/relative_time.ts +++ b/test/common/datetime/relative_time.ts @@ -6,6 +6,7 @@ import { TimeFormat, FirstWeekday, DateFormat, + TimeZone, } from "../../../src/data/translation"; describe("relativeTime", () => { @@ -14,6 +15,7 @@ describe("relativeTime", () => { number_format: NumberFormat.language, time_format: TimeFormat.language, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.language, }; @@ -22,6 +24,7 @@ describe("relativeTime", () => { number_format: NumberFormat.language, time_format: TimeFormat.language, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.monday, }; diff --git a/test/common/entity/compute_state_display.ts b/test/common/entity/compute_state_display.ts index f09df55c5d..2cfc130a56 100644 --- a/test/common/entity/compute_state_display.ts +++ b/test/common/entity/compute_state_display.ts @@ -7,7 +7,9 @@ import { TimeFormat, FirstWeekday, DateFormat, + TimeZone, } from "../../../src/data/translation"; +import { demoConfig } from "../../../src/fake_data/demo_config"; let localeData: FrontendLocaleData; @@ -22,6 +24,7 @@ describe("computeStateDisplay", () => { number_format: NumberFormat.comma_decimal, time_format: TimeFormat.am_pm, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.language, }; }); @@ -33,7 +36,7 @@ describe("computeStateDisplay", () => { attributes: {}, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "component.binary_sensor.entity_component._.state.off" ); }); @@ -47,7 +50,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "component.binary_sensor.state.moisture.off" ); }); @@ -67,7 +70,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(altLocalize, stateObj, localeData, {}), + computeStateDisplay(altLocalize, stateObj, localeData, demoConfig, {}), "component.binary_sensor.state.invalid_device_class.off" ); }); @@ -81,7 +84,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "123 m" ); }); @@ -95,7 +98,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "1,234.5 m" ); }); @@ -109,7 +112,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "1,234.5" ); }); @@ -129,7 +132,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(altLocalize, stateObj, localeData, {}), + computeStateDisplay(altLocalize, stateObj, localeData, demoConfig, {}), "state.default.unknown" ); }); @@ -149,7 +152,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(altLocalize, stateObj, localeData, {}), + computeStateDisplay(altLocalize, stateObj, localeData, demoConfig, {}), "state.default.unavailable" ); }); @@ -169,7 +172,7 @@ describe("computeStateDisplay", () => { attributes: {}, }; assert.strictEqual( - computeStateDisplay(altLocalize, stateObj, localeData, {}), + computeStateDisplay(altLocalize, stateObj, localeData, demoConfig, {}), "component.sensor.entity_component._.state.custom_state" ); }); @@ -191,14 +194,14 @@ describe("computeStateDisplay", () => { }; it("Uses am/pm time format", () => { assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "November 18, 2017 at 11:12 PM" ); }); it("Uses 24h time format", () => { localeData.time_format = TimeFormat.twenty_four; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "November 18, 2017 at 23:12" ); }); @@ -220,7 +223,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "November 18, 2017" ); }); @@ -243,14 +246,14 @@ describe("computeStateDisplay", () => { it("Uses am/pm time format", () => { localeData.time_format = TimeFormat.am_pm; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "11:12 PM" ); }); it("Uses 24h time format", () => { localeData.time_format = TimeFormat.twenty_four; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}), + computeStateDisplay(localize, stateObj, localeData, demoConfig, {}), "23:12" ); }); @@ -277,6 +280,7 @@ describe("computeStateDisplay", () => { localize, stateObj, localeData, + demoConfig, {}, "2021-07-04 15:40:03" ), @@ -290,6 +294,7 @@ describe("computeStateDisplay", () => { localize, stateObj, localeData, + demoConfig, {}, "2021-07-04 15:40:03" ), @@ -314,7 +319,14 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}, "2021-07-04"), + computeStateDisplay( + localize, + stateObj, + localeData, + demoConfig, + {}, + "2021-07-04" + ), "July 4, 2021" ); }); @@ -337,14 +349,28 @@ describe("computeStateDisplay", () => { it("Uses am/pm time format", () => { localeData.time_format = TimeFormat.am_pm; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}, "17:05:07"), + computeStateDisplay( + localize, + stateObj, + localeData, + demoConfig, + {}, + "17:05:07" + ), "5:05 PM" ); }); it("Uses 24h time format", () => { localeData.time_format = TimeFormat.twenty_four; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, {}, "17:05:07"), + computeStateDisplay( + localize, + stateObj, + localeData, + demoConfig, + {}, + "17:05:07" + ), "17:05" ); }); @@ -363,7 +389,7 @@ describe("computeStateDisplay", () => { attributes: {}, }; assert.strictEqual( - computeStateDisplay(altLocalize, stateObj, localeData, {}), + computeStateDisplay(altLocalize, stateObj, localeData, demoConfig, {}), "state.default.unavailable" ); }); @@ -378,7 +404,7 @@ describe("computeStateDisplay", () => { attributes: {}, }; assert.strictEqual( - computeStateDisplay(altLocalize, stateObj, localeData, {}), + computeStateDisplay(altLocalize, stateObj, localeData, demoConfig, {}), "My Custom State" ); }); @@ -396,7 +422,7 @@ describe("computeStateDisplay", () => { }, }; assert.strictEqual( - computeStateDisplay(localize, stateObj, localeData, entities), + computeStateDisplay(localize, stateObj, localeData, demoConfig, entities), "component.custom_integration.entity.sensor.custom_translation.state.custom_state" ); }); diff --git a/test/common/string/format_number.ts b/test/common/string/format_number.ts index 986ab9a01b..2004b06234 100644 --- a/test/common/string/format_number.ts +++ b/test/common/string/format_number.ts @@ -12,6 +12,7 @@ import { TimeFormat, FirstWeekday, DateFormat, + TimeZone, } from "../../../src/data/translation"; describe("formatNumber", () => { @@ -21,6 +22,7 @@ describe("formatNumber", () => { number_format: NumberFormat.language, time_format: TimeFormat.language, date_format: DateFormat.language, + time_zone: TimeZone.local, first_weekday: FirstWeekday.language, }; From 49fa7ec4eded9fcac12ac99971ff52db679ffd24 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 13 Jun 2023 12:20:02 +0200 Subject: [PATCH 017/162] Clear more info content when switching entity (#16846) --- src/dialogs/more-info/more-info-content.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dialogs/more-info/more-info-content.ts b/src/dialogs/more-info/more-info-content.ts index ead8379b1e..3783851c91 100644 --- a/src/dialogs/more-info/more-info-content.ts +++ b/src/dialogs/more-info/more-info-content.ts @@ -55,6 +55,9 @@ class MoreInfoContent extends ReactiveElement { } if (!moreInfoType) { + if (this.lastChild) { + this.removeChild(this.lastChild); + } return; } From 5fc4e7a95dd4d0935828fe85a2f72514be8fbb08 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 13 Jun 2023 15:22:23 +0200 Subject: [PATCH 018/162] Introduce Intl.ListFormat (#16857) Co-authored-by: Steve Repsher Co-authored-by: Bram Kragten --- build-scripts/gulp/locale-data.js | 1 + package.json | 1 + src/data/automation_i18n.ts | 113 ++++++++++++-------------- src/resources/intl-polyfill-legacy.ts | 2 + src/resources/intl-polyfill.ts | 4 + src/resources/locale-data-polyfill.ts | 11 +++ tsconfig.json | 11 +-- yarn.lock | 12 +++ 8 files changed, 86 insertions(+), 69 deletions(-) diff --git a/build-scripts/gulp/locale-data.js b/build-scripts/gulp/locale-data.js index 5def7818fe..f902256877 100755 --- a/build-scripts/gulp/locale-data.js +++ b/build-scripts/gulp/locale-data.js @@ -17,6 +17,7 @@ const modules = { "intl-datetimeformat": "DateTimeFormat", "intl-numberformat": "NumberFormat", "intl-displaynames": "DisplayNames", + "intl-listformat": "ListFormat", }; gulp.task("create-locale-data", (done) => { diff --git a/package.json b/package.json index 2bad0faf13..d00dbbc956 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "@formatjs/intl-datetimeformat": "6.9.0", "@formatjs/intl-displaynames": "6.4.0", "@formatjs/intl-getcanonicallocales": "2.2.1", + "@formatjs/intl-listformat": "7.3.0", "@formatjs/intl-locale": "3.3.1", "@formatjs/intl-numberformat": "8.6.0", "@formatjs/intl-pluralrules": "5.2.3", diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index ab4c0056ea..89ea2257c4 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -21,6 +21,7 @@ import { localizeDeviceAutomationTrigger, } from "./device_automation"; import { EntityRegistryEntry } from "./entity_registry"; +import "../resources/intl-polyfill"; import { FrontendLocaleData } from "./translation"; const describeDuration = (forTime: number | string | ForDict) => { @@ -82,6 +83,11 @@ export const describeTrigger = ( return trigger.alias; } + const disjunctionFormatter = new Intl.ListFormat("en", { + style: "long", + type: "disjunction", + }); + // Event Trigger if (trigger.platform === "event" && trigger.event_type) { let eventTypes = ""; @@ -489,51 +495,43 @@ export const describeTrigger = ( // Zone Trigger if (trigger.platform === "zone" && trigger.entity_id && trigger.zone) { - let entities = ""; - let zones = ""; - let zonesPlural = false; + const entities: string[] = []; + const zones: string[] = []; const states = hass.states; if (Array.isArray(trigger.entity_id)) { - for (const [index, entity] of trigger.entity_id.entries()) { + for (const [entity] of trigger.entity_id.entries()) { if (states[entity]) { - entities += `${index > 0 ? "," : ""} ${ - trigger.entity_id.length > 1 && - index === trigger.entity_id.length - 1 - ? "or" - : "" - } ${computeStateName(states[entity]) || entity}`; + entities.push(`${computeStateName(states[entity]) || entity}`); } } } else { - entities = states[trigger.entity_id] - ? computeStateName(states[trigger.entity_id]) - : trigger.entity_id; + entities.push( + states[trigger.entity_id] + ? computeStateName(states[trigger.entity_id]) + : trigger.entity_id + ); } if (Array.isArray(trigger.zone)) { - if (trigger.zone.length > 1) { - zonesPlural = true; - } - - for (const [index, zone] of trigger.zone.entries()) { + for (const [zone] of trigger.zone.entries()) { if (states[zone]) { - zones += `${index > 0 ? "," : ""} ${ - trigger.zone.length > 1 && index === trigger.zone.length - 1 - ? "or" - : "" - } ${computeStateName(states[zone]) || zone}`; + zones.push(`${computeStateName(states[zone]) || zone}`); } } } else { - zones = states[trigger.zone] - ? computeStateName(states[trigger.zone]) - : trigger.zone; + zones.push( + states[trigger.zone] + ? computeStateName(states[trigger.zone]) + : trigger.zone + ); } - return `When ${entities} ${trigger.event}s ${zones} ${ - zonesPlural ? "zones" : "zone" + const entitiesString = disjunctionFormatter.format(entities); + const zonesString = disjunctionFormatter.format(zones); + return `When ${entitiesString} ${trigger.event}s ${zonesString} ${ + zones.length > 1 ? "zones" : "zone" }`; } @@ -636,6 +634,11 @@ export const describeCondition = ( return condition.alias; } + const disjunctionFormatter = new Intl.ListFormat("en", { + style: "long", + type: "disjunction", + }); + if (!condition.condition) { const shorthands: Array<"and" | "or" | "not"> = ["and", "or", "not"]; for (const key of shorthands) { @@ -938,56 +941,44 @@ export const describeCondition = ( // Zone condition if (condition.condition === "zone" && condition.entity_id && condition.zone) { - let entities = ""; - let entitiesPlural = false; - let zones = ""; - let zonesPlural = false; + const entities: string[] = []; + const zones: string[] = []; const states = hass.states; if (Array.isArray(condition.entity_id)) { - if (condition.entity_id.length > 1) { - entitiesPlural = true; - } - for (const [index, entity] of condition.entity_id.entries()) { + for (const [entity] of condition.entity_id.entries()) { if (states[entity]) { - entities += `${index > 0 ? "," : ""} ${ - condition.entity_id.length > 1 && - index === condition.entity_id.length - 1 - ? "or" - : "" - } ${computeStateName(states[entity]) || entity}`; + entities.push(`${computeStateName(states[entity]) || entity}`); } } } else { - entities = states[condition.entity_id] - ? computeStateName(states[condition.entity_id]) - : condition.entity_id; + entities.push( + states[condition.entity_id] + ? computeStateName(states[condition.entity_id]) + : condition.entity_id + ); } if (Array.isArray(condition.zone)) { - if (condition.zone.length > 1) { - zonesPlural = true; - } - - for (const [index, zone] of condition.zone.entries()) { + for (const [zone] of condition.zone.entries()) { if (states[zone]) { - zones += `${index > 0 ? "," : ""} ${ - condition.zone.length > 1 && index === condition.zone.length - 1 - ? "or" - : "" - } ${computeStateName(states[zone]) || zone}`; + zones.push(`${computeStateName(states[zone]) || zone}`); } } } else { - zones = states[condition.zone] - ? computeStateName(states[condition.zone]) - : condition.zone; + zones.push( + states[condition.zone] + ? computeStateName(states[condition.zone]) + : condition.zone + ); } - return `Confirm ${entities} ${entitiesPlural ? "are" : "is"} in ${zones} ${ - zonesPlural ? "zones" : "zone" - }`; + const entitiesString = disjunctionFormatter.format(entities); + const zonesString = disjunctionFormatter.format(zones); + return `Confirm ${entitiesString} ${ + entities.length > 1 ? "are" : "is" + } in ${zonesString} ${zones.length > 1 ? "zones" : "zone"}`; } if (condition.condition === "device") { diff --git a/src/resources/intl-polyfill-legacy.ts b/src/resources/intl-polyfill-legacy.ts index c3072b0e90..01a057d75a 100644 --- a/src/resources/intl-polyfill-legacy.ts +++ b/src/resources/intl-polyfill-legacy.ts @@ -15,3 +15,5 @@ import "@formatjs/intl-datetimeformat/locale-data/en"; import "@formatjs/intl-datetimeformat/add-all-tz"; import "@formatjs/intl-displaynames/polyfill"; import "@formatjs/intl-displaynames/locale-data/en"; +import "@formatjs/intl-listformat/polyfill"; +import "@formatjs/intl-listformat/locale-data/en"; diff --git a/src/resources/intl-polyfill.ts b/src/resources/intl-polyfill.ts index 8b09aea77a..b98fc722b8 100644 --- a/src/resources/intl-polyfill.ts +++ b/src/resources/intl-polyfill.ts @@ -3,6 +3,7 @@ import { shouldPolyfill as shouldPolyfillDisplayName } from "@formatjs/intl-disp import { shouldPolyfill as shouldPolyfillLocale } from "@formatjs/intl-locale/should-polyfill"; import { shouldPolyfill as shouldPolyfillPluralRules } from "@formatjs/intl-pluralrules/should-polyfill"; import { shouldPolyfill as shouldPolyfillRelativeTime } from "@formatjs/intl-relativetimeformat/should-polyfill"; +import { shouldPolyfill as shouldPolyfillListFormat } from "@formatjs/intl-listformat/should-polyfill"; import { getLocalLanguage } from "../util/common-translation"; import { polyfillLocaleData } from "./locale-data-polyfill"; @@ -29,6 +30,9 @@ const polyfillIntl = async () => { if (shouldPolyfillDisplayName(locale)) { polyfills.push(import("@formatjs/intl-displaynames/polyfill-force")); } + if (shouldPolyfillListFormat(locale)) { + polyfills.push(import("@formatjs/intl-listformat/polyfill-force")); + } if (polyfills.length === 0) { return; } diff --git a/src/resources/locale-data-polyfill.ts b/src/resources/locale-data-polyfill.ts index 2b8b424af0..e408947a65 100644 --- a/src/resources/locale-data-polyfill.ts +++ b/src/resources/locale-data-polyfill.ts @@ -53,6 +53,17 @@ export const polyfillLocaleData = async (language: string) => { // @ts-ignore Intl.DisplayNames.__addLocaleData(await result.json()); } + if ( + Intl.ListFormat && + // @ts-ignore + typeof Intl.ListFormat.__addLocaleData === "function" + ) { + const result = await fetch( + `${__STATIC_PATH__}locale-data/intl-listformat/${language}.json` + ); + // @ts-ignore + Intl.ListFormat.__addLocaleData(await result.json()); + } } catch (e) { // Ignore } diff --git a/tsconfig.json b/tsconfig.json index 13af372a4c..a5bac525d4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,8 @@ { "compilerOptions": { // Language Options - "target": "ES2017", - "lib": [ - "ES2017", - "DOM", - "DOM.Iterable", - "WebWorker" - ], + "target": "ES2021", + "lib": ["ES2021", "DOM", "DOM.Iterable", "WebWorker"], "experimentalDecorators": true, // Modules "module": "ESNext", @@ -43,4 +38,4 @@ } ] } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 64b7250dcc..6520047cb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1669,6 +1669,17 @@ __metadata: languageName: node linkType: hard +"@formatjs/intl-listformat@npm:7.3.0": + version: 7.3.0 + resolution: "@formatjs/intl-listformat@npm:7.3.0" + dependencies: + "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/intl-localematcher": 0.3.0 + tslib: ^2.4.0 + checksum: 6638e6a3cad750ac5199cf293c549c4048f0de240762dd98c61cece645091f19262ef64c1fb2f7a44b5bb3e5c168a8f53e9aa604b4867290981c30baf8635c0d + languageName: node + linkType: hard + "@formatjs/intl-locale@npm:3.3.1": version: 3.3.1 resolution: "@formatjs/intl-locale@npm:3.3.1" @@ -9620,6 +9631,7 @@ __metadata: "@formatjs/intl-datetimeformat": 6.9.0 "@formatjs/intl-displaynames": 6.4.0 "@formatjs/intl-getcanonicallocales": 2.2.1 + "@formatjs/intl-listformat": 7.3.0 "@formatjs/intl-locale": 3.3.1 "@formatjs/intl-numberformat": 8.6.0 "@formatjs/intl-pluralrules": 5.2.3 From c821f4296e203efafd19f71b22d57e17c7c712cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:23:14 -0400 Subject: [PATCH 019/162] Update dependency @octokit/auth-oauth-device to v4.0.5 (#16891) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index d00dbbc956..1f3d65bb2a 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "@babel/preset-env": "7.22.5", "@babel/preset-typescript": "7.22.5", "@koa/cors": "4.0.0", - "@octokit/auth-oauth-device": "4.0.4", + "@octokit/auth-oauth-device": "4.0.5", "@octokit/plugin-retry": "5.0.2", "@octokit/rest": "19.0.11", "@open-wc/dev-server-hmr": "0.1.4", diff --git a/yarn.lock b/yarn.lock index 6520047cb8..ba5464b599 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3237,15 +3237,15 @@ __metadata: languageName: node linkType: hard -"@octokit/auth-oauth-device@npm:4.0.4": - version: 4.0.4 - resolution: "@octokit/auth-oauth-device@npm:4.0.4" +"@octokit/auth-oauth-device@npm:4.0.5": + version: 4.0.5 + resolution: "@octokit/auth-oauth-device@npm:4.0.5" dependencies: "@octokit/oauth-methods": ^2.0.0 "@octokit/request": ^6.0.0 "@octokit/types": ^9.0.0 universal-user-agent: ^6.0.0 - checksum: 245e1fd77684d131793a52a45133ad2514dbb14e5bb6af99eeaccff58662b567327196a721e296ef5734c0988e85a7536ef22bbf04613b302eba595995c5c751 + checksum: 361824ba13c56beb05016b48b7d492f7439650abbb9e687c9f3e82ef4830790e1aae3d78c6e95dc317278146442c59821d87bf0b9b3c6d53f87117fe32b380d0 languageName: node linkType: hard @@ -9675,7 +9675,7 @@ __metadata: "@material/web": =1.0.0-pre.9 "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 - "@octokit/auth-oauth-device": 4.0.4 + "@octokit/auth-oauth-device": 4.0.5 "@octokit/plugin-retry": 5.0.2 "@octokit/rest": 19.0.11 "@open-wc/dev-server-hmr": 0.1.4 From f8ea7e0ef253d6e78001ec6a259e38a7ebbf03a3 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 13 Jun 2023 15:24:36 +0200 Subject: [PATCH 020/162] Make actions available as event (#16839) --- src/panels/lovelace/cards/hui-button-card.ts | 21 ++++++++------ src/panels/lovelace/common/handle-action.ts | 16 ++++++----- src/state/action-mixin.ts | 30 ++++++++++++++++++++ src/state/hass-element.ts | 2 ++ 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 src/state/action-mixin.ts diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index 1e9167e5a4..b98607fcc2 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -8,12 +8,12 @@ import { HassEntity, } from "home-assistant-js-websocket"; import { - CSSResultGroup, - LitElement, - PropertyValues, css, + CSSResultGroup, html, + LitElement, nothing, + PropertyValues, } from "lit"; import { customElement, eventOptions, queryAsync, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; @@ -21,6 +21,7 @@ import { styleMap } from "lit/directives/style-map"; import { DOMAINS_TOGGLE } from "../../../common/const"; import { transform } from "../../../common/decorators/transform"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; +import { fireEvent } from "../../../common/dom/fire_event"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDisplaySingleEntity } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; @@ -28,6 +29,7 @@ import { computeStateName } from "../../../common/entity/compute_state_name"; import { stateColorCss } from "../../../common/entity/state_color"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; import { iconColorCSS } from "../../../common/style/icon_color_css"; +import { LocalizeFunc } from "../../../common/translations/localize"; import "../../../components/ha-card"; import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { @@ -38,20 +40,18 @@ import { statesContext, themesContext, } from "../../../data/context"; +import { EntityRegistryDisplayEntry } from "../../../data/entity_registry"; import { LightEntity } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; +import { FrontendLocaleData } from "../../../data/translation"; +import { Themes } from "../../../data/ws-themes"; import { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { findEntities } from "../common/find-entities"; -import { handleAction } from "../common/handle-action"; import { hasAction } from "../common/has-action"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { ButtonCardConfig } from "./types"; -import { LocalizeFunc } from "../../../common/translations/localize"; -import { FrontendLocaleData } from "../../../data/translation"; -import { Themes } from "../../../data/ws-themes"; -import { EntityRegistryDisplayEntry } from "../../../data/entity_registry"; @customElement("hui-button-card") export class HuiButtonCard extends LitElement implements LovelaceCard { @@ -364,7 +364,10 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { } private _handleAction(ev: ActionHandlerEvent) { - handleAction(this, this.hass!, this._config!, ev.detail.action!); + fireEvent(this, "hass-action", { + config: this._config!, + action: ev.detail.action, + }); } } diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index ddbbc838f3..7ea895d723 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -14,16 +14,18 @@ declare global { } } +export type ActionConfigParams = { + entity?: string; + camera_image?: string; + hold_action?: ActionConfig; + tap_action?: ActionConfig; + double_tap_action?: ActionConfig; +}; + export const handleAction = async ( node: HTMLElement, hass: HomeAssistant, - config: { - entity?: string; - camera_image?: string; - hold_action?: ActionConfig; - tap_action?: ActionConfig; - double_tap_action?: ActionConfig; - }, + config: ActionConfigParams, action: string ): Promise => { let actionConfig: ActionConfig | undefined; diff --git a/src/state/action-mixin.ts b/src/state/action-mixin.ts new file mode 100644 index 0000000000..5a583bfc62 --- /dev/null +++ b/src/state/action-mixin.ts @@ -0,0 +1,30 @@ +import type { PropertyValues } from "lit"; +import type { HASSDomEvent } from "../common/dom/fire_event"; +import { + ActionConfigParams, + handleAction, +} from "../panels/lovelace/common/handle-action"; +import type { Constructor } from "../types"; +import type { HassBaseEl } from "./hass-base-mixin"; + +declare global { + // for fire event + interface HASSDomEvents { + "hass-action": { config: ActionConfigParams; action: string }; + } +} + +export default >(superClass: T) => + class extends superClass { + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this.addEventListener("hass-action", (ev) => this._handleAction(ev)); + } + + private async _handleAction( + ev: HASSDomEvent<{ config: ActionConfigParams; action: string }> + ) { + if (!this.hass) return; + handleAction(this, this.hass, ev.detail.config, ev.detail.action); + } + }; diff --git a/src/state/hass-element.ts b/src/state/hass-element.ts index e6e5b9f67a..e017d5c3ef 100644 --- a/src/state/hass-element.ts +++ b/src/state/hass-element.ts @@ -8,6 +8,7 @@ import { HassBaseEl } from "./hass-base-mixin"; import { loggingMixin } from "./logging-mixin"; import { contextMixin } from "./context-mixin"; import MoreInfoMixin from "./more-info-mixin"; +import ActionMixin from "./action-mixin"; import NotificationMixin from "./notification-mixin"; import { panelTitleMixin } from "./panel-title-mixin"; import SidebarMixin from "./sidebar-mixin"; @@ -23,6 +24,7 @@ export class HassElement extends ext(HassBaseEl, [ ThemesMixin, TranslationsMixin, MoreInfoMixin, + ActionMixin, SidebarMixin, DisconnectToastMixin, connectionMixin, From 9875cb2723c2afca7e1d66b26ee2e3195b10c95a Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 13 Jun 2023 17:21:01 +0200 Subject: [PATCH 021/162] Only catch event inside color wheel (#16890) --- src/components/ha-hs-color-picker.ts | 4 +++- src/components/ha-temp-color-picker.ts | 11 ++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/ha-hs-color-picker.ts b/src/components/ha-hs-color-picker.ts index ad739818df..1533e2b6c4 100644 --- a/src/components/ha-hs-color-picker.ts +++ b/src/components/ha-hs-color-picker.ts @@ -373,17 +373,19 @@ class HaHsColorPicker extends LitElement { return css` :host { display: block; + outline: none; } .container { position: relative; width: 100%; height: 100%; - cursor: pointer; display: flex; } canvas { width: 100%; height: 100%; + border-radius: 50%; + cursor: pointer; } svg { position: absolute; diff --git a/src/components/ha-temp-color-picker.ts b/src/components/ha-temp-color-picker.ts index 16422f55bd..9070a46e28 100644 --- a/src/components/ha-temp-color-picker.ts +++ b/src/components/ha-temp-color-picker.ts @@ -381,21 +381,22 @@ class HaTempColorPicker extends LitElement { :host { display: block; outline: none; - border-radius: 9999px; - } - :host(:focus-visible) { - box-shadow: 0 0 0 2px rgb(255, 160, 0); } .container { position: relative; width: 100%; height: 100%; - cursor: pointer; display: flex; } canvas { width: 100%; height: 100%; + border-radius: 50%; + transition: box-shadow 180ms ease-in-out; + cursor: pointer; + } + :host(:focus-visible) canvas { + box-shadow: 0 0 0 2px rgb(255, 160, 0); } svg { position: absolute; From 6e3cf0975b49a3853052385e69b15e5a617af293 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 13 Jun 2023 08:22:45 -0700 Subject: [PATCH 022/162] Fix mqtt debug info dialog too big (#16893) --- .../mqtt/dialog-mqtt-device-debug-info.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/panels/config/devices/device-detail/integration-elements/mqtt/dialog-mqtt-device-debug-info.ts b/src/panels/config/devices/device-detail/integration-elements/mqtt/dialog-mqtt-device-debug-info.ts index 933ed8769c..d3d15a4a28 100644 --- a/src/panels/config/devices/device-detail/integration-elements/mqtt/dialog-mqtt-device-debug-info.ts +++ b/src/panels/config/devices/device-detail/integration-elements/mqtt/dialog-mqtt-device-debug-info.ts @@ -250,8 +250,18 @@ class DialogMQTTDeviceDebugInfo extends LitElement { haStyleDialog, css` ha-dialog { - --mdc-dialog-max-width: 95%; - --mdc-dialog-min-width: 640px; + --mdc-dialog-max-width: 95vw; + --mdc-dialog-min-width: min(640px, 95vw); + } + @media all and (max-width: 450px), all and (max-height: 500px) { + ha-dialog { + --mdc-dialog-min-width: calc( + 100vw - env(safe-area-inset-right) - env(safe-area-inset-left) + ); + --mdc-dialog-max-width: calc( + 100vw - env(safe-area-inset-right) - env(safe-area-inset-left) + ); + } } ha-switch { margin: 16px; From 197638b28291fb5811d8661b8a4a4a2c45f15eff Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 13 Jun 2023 17:27:21 +0200 Subject: [PATCH 023/162] Fix date demo in gallery (#16894) --- gallery/src/pages/date-time/date.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/gallery/src/pages/date-time/date.ts b/gallery/src/pages/date-time/date.ts index 90776e89b1..1ddc60ea7f 100644 --- a/gallery/src/pages/date-time/date.ts +++ b/gallery/src/pages/date-time/date.ts @@ -1,23 +1,21 @@ -import { html, css, LitElement } from "lit"; -import { customElement, property } from "lit/decorators"; -import "../../../../src/components/ha-card"; -import { HomeAssistant } from "../../../../src/types"; -import { translationMetadata } from "../../../../src/resources/translations-metadata"; +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 { + DateFormat, + FirstWeekday, FrontendLocaleData, NumberFormat, TimeFormat, - DateFormat, - FirstWeekday, TimeZone, } from "../../../../src/data/translation"; -import "@material/mwc-list/mwc-list"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; @customElement("demo-date-time-date") export class DemoDateTimeDate extends LitElement { - @property({ attribute: false }) hass!: HomeAssistant; - protected render() { const defaultLocale: FrontendLocaleData = { language: "en", @@ -51,7 +49,7 @@ export class DemoDateTimeDate extends LitElement { language: key, date_format: DateFormat.language, }, - this.hass.config + demoConfig )}
@@ -62,7 +60,7 @@ export class DemoDateTimeDate extends LitElement { language: key, date_format: DateFormat.DMY, }, - this.hass.config + demoConfig )}
@@ -73,7 +71,7 @@ export class DemoDateTimeDate extends LitElement { language: key, date_format: DateFormat.MDY, }, - this.hass.config + demoConfig )}
@@ -84,7 +82,7 @@ export class DemoDateTimeDate extends LitElement { language: key, date_format: DateFormat.YMD, }, - this.hass.config + demoConfig )}
From fa1a6affa752a596059e4bd25497f3be7db02ba0 Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Tue, 13 Jun 2023 12:12:44 -0400 Subject: [PATCH 024/162] Use ES modules and dynamic import for Webpack latest builds (#16849) --- .browserslistrc | 6 ++++ build-scripts/bundle.cjs | 1 + build-scripts/webpack.cjs | 12 +++++-- ...filter_worker.ts => sort-filter-worker.ts} | 0 src/components/data-table/sort-filter.ts | 33 ++++++++++--------- ...{markdown_worker.ts => markdown-worker.ts} | 0 src/resources/render-markdown.ts | 10 ++++-- test/webpack.config.js | 7 +++- 8 files changed, 47 insertions(+), 22 deletions(-) rename src/components/data-table/{sort_filter_worker.ts => sort-filter-worker.ts} (100%) rename src/resources/{markdown_worker.ts => markdown-worker.ts} (100%) diff --git a/.browserslistrc b/.browserslistrc index 86481f8e08..516fec9cec 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -10,6 +10,12 @@ supports es6-module-dynamic-import not Safari < 13 not iOS < 13 +# Exclude KaiOS, QQ, and UC browsers due to lack of sufficient feature support data +# Babel ignores these automatically, but we need here for Webpack to output ESM with dynamic imports +not KaiOS > 0 +not QQAndroid > 0 +not UCAndroid > 0 + # Exclude unsupported browsers not dead diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index a6d14f18c8..f840f21762 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -77,6 +77,7 @@ module.exports.htmlMinifierOptions = { module.exports.terserOptions = ({ latestBuild, isTestBuild }) => ({ safari10: !latestBuild, ecma: latestBuild ? 2015 : 5, + module: latestBuild, format: { comments: false }, sourceMap: !isTestBuild, }); diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs index 58cc184ca8..0ff76cc832 100644 --- a/build-scripts/webpack.cjs +++ b/build-scripts/webpack.cjs @@ -41,7 +41,7 @@ const createWebpackConfig = ({ return { name, mode: isProdBuild ? "production" : "development", - target: ["web", latestBuild ? "es2017" : "es5"], + target: `browserslist:${latestBuild ? "modern" : "legacy"}`, // For tests/CI, source maps are skipped to gain build speed // For production, generate source maps for accurate stack traces without source code // For development, generate "cheap" versions that can map to original line numbers @@ -84,6 +84,13 @@ const createWebpackConfig = ({ ], moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", + splitChunks: { + // Disable splitting for web workers with ESM output + // Imports of external chunks are broken + chunks: latestBuild + ? (chunk) => !chunk.canBeInitial() && !/^.+-worker$/.test(chunk.name) + : undefined, + }, }, plugins: [ !isStatsBuild && new WebpackBar({ fancy: !isProdBuild }), @@ -163,6 +170,7 @@ const createWebpackConfig = ({ }, }, output: { + module: latestBuild, filename: ({ chunk }) => !isProdBuild || isStatsBuild || dontHash.has(chunk.name) ? "[name].js" @@ -196,7 +204,7 @@ const createWebpackConfig = ({ : undefined, }, experiments: { - topLevelAwait: true, + outputModule: true, }, }; }; diff --git a/src/components/data-table/sort_filter_worker.ts b/src/components/data-table/sort-filter-worker.ts similarity index 100% rename from src/components/data-table/sort_filter_worker.ts rename to src/components/data-table/sort-filter-worker.ts diff --git a/src/components/data-table/sort-filter.ts b/src/components/data-table/sort-filter.ts index 67d7679397..e0eacf3305 100644 --- a/src/components/data-table/sort-filter.ts +++ b/src/components/data-table/sort-filter.ts @@ -1,5 +1,5 @@ import { Remote, wrap } from "comlink"; -import type { Api } from "./sort_filter_worker"; +import type { Api } from "./sort-filter-worker"; type FilterDataType = Api["filterData"]; type FilterDataParamTypes = Parameters; @@ -9,27 +9,28 @@ type SortDataParamTypes = Parameters; let worker: Remote | undefined; +const getWorker = () => { + if (!worker) { + worker = wrap( + new Worker( + /* webpackChunkName: "sort-filter-worker" */ + new URL("./sort-filter-worker", import.meta.url) + ) + ); + } + return worker; +}; + export const filterData = ( data: FilterDataParamTypes[0], columns: FilterDataParamTypes[1], filter: FilterDataParamTypes[2] -): Promise> => { - if (!worker) { - worker = wrap(new Worker(new URL("./sort_filter_worker", import.meta.url))); - } - - return worker.filterData(data, columns, filter); -}; - +): Promise> => + getWorker().filterData(data, columns, filter); export const sortData = ( data: SortDataParamTypes[0], columns: SortDataParamTypes[1], direction: SortDataParamTypes[2], sortColumn: SortDataParamTypes[3] -): Promise> => { - if (!worker) { - worker = wrap(new Worker(new URL("./sort_filter_worker", import.meta.url))); - } - - return worker.sortData(data, columns, direction, sortColumn); -}; +): Promise> => + getWorker().sortData(data, columns, direction, sortColumn); diff --git a/src/resources/markdown_worker.ts b/src/resources/markdown-worker.ts similarity index 100% rename from src/resources/markdown_worker.ts rename to src/resources/markdown-worker.ts diff --git a/src/resources/render-markdown.ts b/src/resources/render-markdown.ts index fb9b8cf438..85c584c939 100644 --- a/src/resources/render-markdown.ts +++ b/src/resources/render-markdown.ts @@ -1,5 +1,5 @@ import { Remote, wrap } from "comlink"; -import type { Api } from "./markdown_worker"; +import type { Api } from "./markdown-worker"; type RenderMarkdownType = Api["renderMarkdown"]; type RenderMarkdownParamTypes = Parameters; @@ -12,8 +12,12 @@ export const renderMarkdown = async ( hassOptions?: RenderMarkdownParamTypes[2] ): Promise> => { if (!worker) { - worker = wrap(new Worker(new URL("./markdown_worker", import.meta.url))); + worker = wrap( + new Worker( + /* webpackChunkName: "markdown-worker" */ + new URL("./markdown-worker", import.meta.url) + ) + ); } - return worker.renderMarkdown(content, markedOptions, hassOptions); }; diff --git a/test/webpack.config.js b/test/webpack.config.js index 20e1e163e3..ad593b58aa 100644 --- a/test/webpack.config.js +++ b/test/webpack.config.js @@ -1,8 +1,13 @@ import webpack from "../build-scripts/webpack.cjs"; -export default webpack.createAppConfig({ +const config = webpack.createAppConfig({ isProdBuild: false, latestBuild: true, isStatsBuild: false, isTestBuild: true, }); + +// instant-mocha forces a CJS library, so cannot output ESM +config.output.module = false; + +export default config; From 3bea2cf7f9114032d7cce89c1c0238c6d593adb5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 15:28:58 -0400 Subject: [PATCH 025/162] Update dependency @rollup/plugin-commonjs to v25.0.1 (#16892) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1f3d65bb2a..970b5df434 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "@octokit/rest": "19.0.11", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", - "@rollup/plugin-commonjs": "25.0.0", + "@rollup/plugin-commonjs": "25.0.1", "@rollup/plugin-json": "6.0.0", "@rollup/plugin-node-resolve": "15.1.0", "@rollup/plugin-replace": "5.0.2", diff --git a/yarn.lock b/yarn.lock index ba5464b599..5905a667c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3871,9 +3871,9 @@ __metadata: languageName: node linkType: hard -"@rollup/plugin-commonjs@npm:25.0.0": - version: 25.0.0 - resolution: "@rollup/plugin-commonjs@npm:25.0.0" +"@rollup/plugin-commonjs@npm:25.0.1": + version: 25.0.1 + resolution: "@rollup/plugin-commonjs@npm:25.0.1" dependencies: "@rollup/pluginutils": ^5.0.1 commondir: ^1.0.1 @@ -3886,7 +3886,7 @@ __metadata: peerDependenciesMeta: rollup: optional: true - checksum: f014f98f161ba4573e5101cf262c152bdcd8cfebf9cf4872f8bb657d20e20d8e2dc51af5339fe10772d19007e63044bd79881af0db4fe9babe9e96d0c0eeb328 + checksum: 886340bac6ba8c20bb16e3b7fa4d0357019708043697153e7b18cecb7e1fdbe7ec6f26974079f32091c6168c67300960f023ad3d167d2d0d9a9e3bd713cd22a4 languageName: node linkType: hard @@ -9691,7 +9691,7 @@ __metadata: "@polymer/paper-toast": 3.0.1 "@polymer/polymer": 3.5.1 "@rollup/plugin-babel": 6.0.3 - "@rollup/plugin-commonjs": 25.0.0 + "@rollup/plugin-commonjs": 25.0.1 "@rollup/plugin-json": 6.0.0 "@rollup/plugin-node-resolve": 15.1.0 "@rollup/plugin-replace": 5.0.2 From c1c18affbc7005fed67f55d5e4054bcaec1789b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 16:09:57 -0400 Subject: [PATCH 026/162] Update dependency webpack to v5.86.0 (#16749) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 970b5df434..83deeb1ef0 100644 --- a/package.json +++ b/package.json @@ -239,7 +239,7 @@ "typescript": "4.9.5", "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", - "webpack": "5.84.1", + "webpack": "5.86.0", "webpack-cli": "5.1.4", "webpack-dev-server": "4.15.0", "webpack-manifest-plugin": "5.0.0", diff --git a/yarn.lock b/yarn.lock index 5905a667c7..cb4c5ad45b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9817,7 +9817,7 @@ __metadata: vis-network: 9.1.6 vue: 2.7.14 vue2-daterange-picker: 0.6.8 - webpack: 5.84.1 + webpack: 5.86.0 webpack-cli: 5.1.4 webpack-dev-server: 4.15.0 webpack-manifest-plugin: 5.0.0 @@ -16243,9 +16243,9 @@ __metadata: languageName: node linkType: hard -"webpack@npm:5.84.1": - version: 5.84.1 - resolution: "webpack@npm:5.84.1" +"webpack@npm:5.86.0": + version: 5.86.0 + resolution: "webpack@npm:5.86.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -16276,7 +16276,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 646b645df5badf2dac2ddd0193c9e9a177d51283d18f918eead36a0cdf7b750c4111d9ac11d9825c1334cbd0a6fb8f82628fbfb90d0066f927265dd11b47b192 + checksum: 682b1aa8328bb9d52ae66a1d0a1078af88f9e3b3b3a9c9e1ce203e669581a8e61d522420ef253130eacd510d24d7275b840c1311d50bd048d6fd7c1af186ce55 languageName: node linkType: hard From b891c5399471b2ed48468ebb04401b77dcf4c6ac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:26:26 -0400 Subject: [PATCH 027/162] Update dependency webpack-dev-server to v4.15.1 (#16900) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 83deeb1ef0..f122c729d6 100644 --- a/package.json +++ b/package.json @@ -241,7 +241,7 @@ "vinyl-source-stream": "2.0.0", "webpack": "5.86.0", "webpack-cli": "5.1.4", - "webpack-dev-server": "4.15.0", + "webpack-dev-server": "4.15.1", "webpack-manifest-plugin": "5.0.0", "webpackbar": "5.0.2", "workbox-build": "7.0.0" diff --git a/yarn.lock b/yarn.lock index cb4c5ad45b..48aa606539 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4655,12 +4655,12 @@ __metadata: languageName: node linkType: hard -"@types/ws@npm:^8.5.1": - version: 8.5.4 - resolution: "@types/ws@npm:8.5.4" +"@types/ws@npm:^8.5.5": + version: 8.5.5 + resolution: "@types/ws@npm:8.5.5" dependencies: "@types/node": "*" - checksum: fefbad20d211929bb996285c4e6f699b12192548afedbe4930ab4384f8a94577c9cd421acaad163cacd36b88649509970a05a0b8f20615b30c501ed5269038d1 + checksum: d00bf8070e6938e3ccf933010921c6ce78ac3606696ce37a393b27a9a603f7bd93ea64f3c5fa295a2f743575ba9c9a9fdb904af0f5fe2229bf2adf0630386e4a languageName: node linkType: hard @@ -9819,7 +9819,7 @@ __metadata: vue2-daterange-picker: 0.6.8 webpack: 5.86.0 webpack-cli: 5.1.4 - webpack-dev-server: 4.15.0 + webpack-dev-server: 4.15.1 webpack-manifest-plugin: 5.0.0 webpackbar: 5.0.2 weekstart: 2.0.0 @@ -16157,9 +16157,9 @@ __metadata: languageName: node linkType: hard -"webpack-dev-server@npm:4.15.0": - version: 4.15.0 - resolution: "webpack-dev-server@npm:4.15.0" +"webpack-dev-server@npm:4.15.1": + version: 4.15.1 + resolution: "webpack-dev-server@npm:4.15.1" dependencies: "@types/bonjour": ^3.5.9 "@types/connect-history-api-fallback": ^1.3.5 @@ -16167,7 +16167,7 @@ __metadata: "@types/serve-index": ^1.9.1 "@types/serve-static": ^1.13.10 "@types/sockjs": ^0.3.33 - "@types/ws": ^8.5.1 + "@types/ws": ^8.5.5 ansi-html-community: ^0.0.8 bonjour-service: ^1.0.11 chokidar: ^3.5.3 @@ -16200,7 +16200,7 @@ __metadata: optional: true bin: webpack-dev-server: bin/webpack-dev-server.js - checksum: 6fe375089b061be2e4ed6d6a8b20743734d304cd0c34757271c6685f97642b028f253c627f899b629c97c067c294484f906e394fd1c104ee795237b8725f2701 + checksum: cd0063b068d2b938fd76c412d555374186ac2fa84bbae098265212ed50a5c15d6f03aa12a5a310c544a242943eb58c0bfde4c296d5c36765c182f53799e1bc71 languageName: node linkType: hard From 73317a48ee433880593427056ad7a2c8629d15f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 13 Jun 2023 17:27:30 -0400 Subject: [PATCH 028/162] Update dependency rollup-plugin-visualizer to v5.9.2 (#16899) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f122c729d6..85daa244a1 100644 --- a/package.json +++ b/package.json @@ -228,7 +228,7 @@ "rollup": "2.79.1", "rollup-plugin-string": "3.0.0", "rollup-plugin-terser": "7.0.2", - "rollup-plugin-visualizer": "5.9.0", + "rollup-plugin-visualizer": "5.9.2", "serve-handler": "6.1.5", "sinon": "15.1.0", "source-map-url": "0.4.1", diff --git a/yarn.lock b/yarn.lock index 48aa606539..cbe46a34e3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9795,7 +9795,7 @@ __metadata: rollup: 2.79.1 rollup-plugin-string: 3.0.0 rollup-plugin-terser: 7.0.2 - rollup-plugin-visualizer: 5.9.0 + rollup-plugin-visualizer: 5.9.2 rrule: 2.7.2 serve-handler: 6.1.5 sinon: 15.1.0 @@ -13940,9 +13940,9 @@ __metadata: languageName: node linkType: hard -"rollup-plugin-visualizer@npm:5.9.0": - version: 5.9.0 - resolution: "rollup-plugin-visualizer@npm:5.9.0" +"rollup-plugin-visualizer@npm:5.9.2": + version: 5.9.2 + resolution: "rollup-plugin-visualizer@npm:5.9.2" dependencies: open: ^8.4.0 picomatch: ^2.3.1 @@ -13955,7 +13955,7 @@ __metadata: optional: true bin: rollup-plugin-visualizer: dist/bin/cli.js - checksum: 362d4fac0295c14bd205dbc85c20c31f4b6c47604868da21d9565ed47e0333759f08b9fe0acb82f78221f5173ea01e4eb70d47351eb6012216afe71b5492ed5f + checksum: ab2adf322e3b20bffc94a8dc804f46be8840a9fcbab4f872dcc2dec205cdd7752e4d2d90cfcf00783bfb5209c5a8bb4e591984e8b61bca41fd048fb7deb0ed4e languageName: node linkType: hard From 2076a083d3f1f8548ded2e28df48df2b23b59ed6 Mon Sep 17 00:00:00 2001 From: JakobDNS <58788765+JakobDNS@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:18:02 +0200 Subject: [PATCH 029/162] en.json: Fix typo "recieved" -> "received" (#16903) --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index f03055696a..58056b3e1c 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1687,7 +1687,7 @@ "energy_stat": "Energy returned to the grid", "cost_para": "Do you get money back when you return energy to the grid?", "no_cost": "I do not get money back", - "cost_stat": "Use an entity tracking the total recieved money", + "cost_stat": "Use an entity tracking the total received money", "cost_stat_input": "Entity with the total compensation", "cost_entity": "Use an entity with current rate", "cost_entity_input": "Entity with the current rate", From 7182abfec5b4e3620ce81df4295dc3af925dc05d Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 14 Jun 2023 08:45:57 -0700 Subject: [PATCH 030/162] Fix history chart when final sensor state is unavailable (#16852) --- src/components/chart/state-history-chart-line.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index 50f164c094..1e34d204fb 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -376,6 +376,9 @@ class StateHistoryChartLine extends LitElement { lastNullDate = date; } }); + if (lastNullDate !== null) { + pushData(lastNullDate, [null]); + } } // Add an entry for final values From 3a64f64894bd9799ef95103b8cefc4f815bd414b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 18:08:19 +0200 Subject: [PATCH 031/162] Update dependency @material/web to v1.0.0-pre.10 (#16841) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 85daa244a1..0874b27500 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "@material/mwc-top-app-bar": "0.27.0", "@material/mwc-top-app-bar-fixed": "0.27.0", "@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0", - "@material/web": "=1.0.0-pre.9", + "@material/web": "=1.0.0-pre.10", "@mdi/js": "7.2.96", "@mdi/svg": "7.2.96", "@polymer/app-layout": "3.1.0", diff --git a/yarn.lock b/yarn.lock index cbe46a34e3..420d735932 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3148,14 +3148,14 @@ __metadata: languageName: node linkType: hard -"@material/web@npm:=1.0.0-pre.9": - version: 1.0.0-pre.9 - resolution: "@material/web@npm:1.0.0-pre.9" +"@material/web@npm:=1.0.0-pre.10": + version: 1.0.0-pre.10 + resolution: "@material/web@npm:1.0.0-pre.10" dependencies: lit: ^2.7.4 safevalues: ^0.4.3 tslib: ^2.4.0 - checksum: c4c6a5328448ee55a6f68260bbadecda2cabd031bf81502934fff95422e63b6903f9737e35ae3cd7e87f6f146a13dc3f492e92fc4e3cef3caee8d0fd4e177a7a + checksum: 977ef988279c96b93f7e20761595b71cd8a07cb0b59969e374fcc003293e9353b948cc9f0dbf43b407e49ab4b11fdc566d3daa693d5a26482e48e0351be20ecb languageName: node linkType: hard @@ -9672,7 +9672,7 @@ __metadata: "@material/mwc-top-app-bar": 0.27.0 "@material/mwc-top-app-bar-fixed": 0.27.0 "@material/top-app-bar": =14.0.0-canary.53b3cad2f.0 - "@material/web": =1.0.0-pre.9 + "@material/web": =1.0.0-pre.10 "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 "@octokit/auth-oauth-device": 4.0.5 From d0641d64bdca350ef6d25b0f25993572727c7a50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Jun 2023 16:03:53 -0400 Subject: [PATCH 032/162] Update dependency eslint-plugin-lit-a11y to v3 (#16910) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0874b27500..32f7ab0cea 100644 --- a/package.json +++ b/package.json @@ -197,7 +197,7 @@ "eslint-plugin-disable": "2.0.3", "eslint-plugin-import": "2.27.5", "eslint-plugin-lit": "1.8.3", - "eslint-plugin-lit-a11y": "2.4.1", + "eslint-plugin-lit-a11y": "3.0.0", "eslint-plugin-unused-imports": "2.0.0", "eslint-plugin-wc": "1.5.0", "esprima": "4.0.1", diff --git a/yarn.lock b/yarn.lock index 420d735932..4be37e0fe3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8068,9 +8068,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-lit-a11y@npm:2.4.1": - version: 2.4.1 - resolution: "eslint-plugin-lit-a11y@npm:2.4.1" +"eslint-plugin-lit-a11y@npm:3.0.0": + version: 3.0.0 + resolution: "eslint-plugin-lit-a11y@npm:3.0.0" dependencies: aria-query: ^5.1.3 axe-core: ^4.3.3 @@ -8085,7 +8085,7 @@ __metadata: requireindex: ~1.2.0 peerDependencies: eslint: ">= 5" - checksum: 1e3caf3dbe16545bbdde096dea1c6ac47b1c366ac7014ccda392c6a62faecaf8c066b5a2f22e7f39c2618a4f14b91158bffbcb48c7f305ce92769f0e9e9bb257 + checksum: c7836aa88714a2fc0388216d44b8a1251edadc6a540cdc054cb4951b56eaa5a017cb51cc37ed8f33e79e8e139cb0c9208ee488af100f76e31c381b66488fc783 languageName: node linkType: hard @@ -9745,7 +9745,7 @@ __metadata: eslint-plugin-disable: 2.0.3 eslint-plugin-import: 2.27.5 eslint-plugin-lit: 1.8.3 - eslint-plugin-lit-a11y: 2.4.1 + eslint-plugin-lit-a11y: 3.0.0 eslint-plugin-unused-imports: 2.0.0 eslint-plugin-wc: 1.5.0 esprima: 4.0.1 From 3be601a3b967758539e37aab9ad5481abfcdfd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 15 Jun 2023 16:08:32 +0200 Subject: [PATCH 033/162] Add location to backups table (#16813) --- hassio/src/backups/hassio-backups.ts | 9 +++++++++ src/data/hassio/backup.ts | 1 + src/translations/en.json | 2 ++ 3 files changed, 12 insertions(+) diff --git a/hassio/src/backups/hassio-backups.ts b/hassio/src/backups/hassio-backups.ts index 382f8ec669..7dc5c94972 100644 --- a/hassio/src/backups/hassio-backups.ts +++ b/hassio/src/backups/hassio-backups.ts @@ -136,6 +136,15 @@ export class HassioBackups extends LitElement { sortable: true, template: (entry: number) => Math.ceil(entry * 10) / 10 + " MB", }, + location: { + title: this.supervisor.localize("backup.location"), + width: "15%", + hidden: narrow, + filterable: true, + sortable: true, + template: (entry: string | null) => + entry || this.supervisor.localize("backup.data_disk"), + }, date: { title: this.supervisor.localize("backup.created"), width: "15%", diff --git a/src/data/hassio/backup.ts b/src/data/hassio/backup.ts index c01b9440da..b29b45590c 100644 --- a/src/data/hassio/backup.ts +++ b/src/data/hassio/backup.ts @@ -23,6 +23,7 @@ export interface HassioBackup { size: number; type: "full" | "partial"; protected: boolean; + location: string | null; content: BackupContent; } diff --git a/src/translations/en.json b/src/translations/en.json index 58056b3e1c..2b46e38cca 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5824,6 +5824,8 @@ "download_backup": "Download backup", "create_backup": "Create backup", "create": "Create", + "location": "Location", + "data_disk": "Data disk", "created": "Created", "name": "Backup name", "type": "Backup type", From 12b7b903bc226d8d3d7a11c603fd894a8a4a44c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 05:40:10 +0000 Subject: [PATCH 034/162] Update dependency core-js to v3.31.0 (#16913) * Update dependency core-js to v3.31.0 * Update babel setting --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Steve Repsher --- build-scripts/bundle.cjs | 2 +- package.json | 2 +- yarn.lock | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index f840f21762..622527f194 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -98,7 +98,7 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ "@babel/preset-env", { useBuiltIns: latestBuild ? false : "entry", - corejs: latestBuild ? false : { version: "3.30", proposals: true }, + corejs: latestBuild ? false : { version: "3.31", proposals: true }, bugfixes: true, }, ], diff --git a/package.json b/package.json index 32f7ab0cea..f36cc92f72 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "app-datepicker": "5.1.1", "chart.js": "3.3.2", "comlink": "4.4.1", - "core-js": "3.30.2", + "core-js": "3.31.0", "cropperjs": "1.5.13", "date-fns": "2.30.0", "date-fns-tz": "2.0.0", diff --git a/yarn.lock b/yarn.lock index 4be37e0fe3..f4ede5ea72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7112,10 +7112,10 @@ __metadata: languageName: node linkType: hard -"core-js@npm:3.30.2": - version: 3.30.2 - resolution: "core-js@npm:3.30.2" - checksum: 73d47e2b9d9f502800973982d08e995bbf04832e20b04e04be31dd7607247158271315e9328788a2408190e291c7ffbefad141167b1e57dea9f983e1e723541e +"core-js@npm:3.31.0": + version: 3.31.0 + resolution: "core-js@npm:3.31.0" + checksum: f7cf9b3010f7ca99c026d95b61743baca1a85512742ed2b67e8f65a72ac4f4fe0b90b00057783e886bdd39d3a295f42f845d33e7cba3973ed263df978343ab79 languageName: node linkType: hard @@ -9730,7 +9730,7 @@ __metadata: chai: 4.3.7 chart.js: 3.3.2 comlink: 4.4.1 - core-js: 3.30.2 + core-js: 3.31.0 cropperjs: 1.5.13 date-fns: 2.30.0 date-fns-tz: 2.0.0 From 3b32825e2abb32ad70ddc6a2821af114ecef40be Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 05:47:46 +0000 Subject: [PATCH 035/162] Update dependency @octokit/plugin-retry to v5.0.3 (#16938) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index f36cc92f72..e98f6b265f 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "@babel/preset-typescript": "7.22.5", "@koa/cors": "4.0.0", "@octokit/auth-oauth-device": "4.0.5", - "@octokit/plugin-retry": "5.0.2", + "@octokit/plugin-retry": "5.0.3", "@octokit/rest": "19.0.11", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", diff --git a/yarn.lock b/yarn.lock index f4ede5ea72..44d0758ab0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3322,6 +3322,13 @@ __metadata: languageName: node linkType: hard +"@octokit/openapi-types@npm:^18.0.0": + version: 18.0.0 + resolution: "@octokit/openapi-types@npm:18.0.0" + checksum: d487d6c6c1965e583eee417d567e4fe3357a98953fc49bce1a88487e7908e9b5dbb3e98f60dfa340e23b1792725fbc006295aea071c5667a813b9c098185b56f + languageName: node + linkType: hard + "@octokit/plugin-paginate-rest@npm:^6.1.2": version: 6.1.2 resolution: "@octokit/plugin-paginate-rest@npm:6.1.2" @@ -3355,15 +3362,16 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-retry@npm:5.0.2": - version: 5.0.2 - resolution: "@octokit/plugin-retry@npm:5.0.2" +"@octokit/plugin-retry@npm:5.0.3": + version: 5.0.3 + resolution: "@octokit/plugin-retry@npm:5.0.3" dependencies: + "@octokit/request-error": ^4.0.1 "@octokit/types": ^9.0.0 bottleneck: ^2.15.3 peerDependencies: "@octokit/core": ">=3" - checksum: b86f92a55e10dfc2012029d7b00bc8bf7cd7c6a4ea3d6484a6d6ec3c0e441298cda00975eee22b7d9b9e73741d12b0a5c4790e42a805e0222743bc9693a5d5a8 + checksum: f98b90333e26a214f057557ee5b13a926e0472a47d103345c504f99e6c3d8564a8fa54bf2871eda8ef47a8f9c1dba84fb68e749ab7a1a749c0a86a3ae74bdfa7 languageName: node linkType: hard @@ -3378,6 +3386,17 @@ __metadata: languageName: node linkType: hard +"@octokit/request-error@npm:^4.0.1": + version: 4.0.2 + resolution: "@octokit/request-error@npm:4.0.2" + dependencies: + "@octokit/types": ^10.0.0 + deprecation: ^2.0.0 + once: ^1.4.0 + checksum: 9510078f718be08cf74e7b04b45f67aa545a388787192ff1cd3ca0d066499963d641bf1fea76ef47d2657a55f0cf3e612e46bbf4f33a96436415d30a2e3bb00a + languageName: node + linkType: hard + "@octokit/request@npm:^6.0.0, @octokit/request@npm:^6.2.3": version: 6.2.5 resolution: "@octokit/request@npm:6.2.5" @@ -3411,6 +3430,15 @@ __metadata: languageName: node linkType: hard +"@octokit/types@npm:^10.0.0": + version: 10.0.0 + resolution: "@octokit/types@npm:10.0.0" + dependencies: + "@octokit/openapi-types": ^18.0.0 + checksum: 8aafba2ff0cd2435fb70c291bf75ed071c0fa8a865cf6169648732068a35dec7b85a345851f18920ec5f3e94ee0e954988485caac0da09ec3f6781cc44fe153a + languageName: node + linkType: hard + "@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.2.3": version: 9.2.3 resolution: "@octokit/types@npm:9.2.3" @@ -9676,7 +9704,7 @@ __metadata: "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 "@octokit/auth-oauth-device": 4.0.5 - "@octokit/plugin-retry": 5.0.2 + "@octokit/plugin-retry": 5.0.3 "@octokit/rest": 19.0.11 "@open-wc/dev-server-hmr": 0.1.4 "@polymer/app-layout": 3.1.0 From a409f494a22c8d98e595eed6b349d436e90417df Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 05:55:36 +0000 Subject: [PATCH 036/162] Update dependency @types/leaflet-draw to v1.0.7 (#16939) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e98f6b265f..621a759e7b 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,7 @@ "@types/html-minifier-terser": "7.0.0", "@types/js-yaml": "4.0.5", "@types/leaflet": "1.9.3", - "@types/leaflet-draw": "1.0.6", + "@types/leaflet-draw": "1.0.7", "@types/marked": "4.3.1", "@types/mocha": "10.0.1", "@types/qrcode": "1.5.0", diff --git a/yarn.lock b/yarn.lock index 44d0758ab0..6fda483dcf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4423,12 +4423,12 @@ __metadata: languageName: node linkType: hard -"@types/leaflet-draw@npm:1.0.6": - version: 1.0.6 - resolution: "@types/leaflet-draw@npm:1.0.6" +"@types/leaflet-draw@npm:1.0.7": + version: 1.0.7 + resolution: "@types/leaflet-draw@npm:1.0.7" dependencies: "@types/leaflet": "*" - checksum: 6520de61f26f4f845fea3faa43077515d2eac58274e98d61b26ca0885d9002fdeb131375e85f4e503daa6b4ec27f0837a1ecddacbba78aea4764084a424bf93e + checksum: 8b2ab83fea3ae95cd8ce652eeb00386f14a3be5d94df96f5f5cb46054e228fbac179751b4e3d35347bcde7fa01dccbe1255601f44a0ec41f16bd1e51b3d8d5a2 languageName: node linkType: hard @@ -9732,7 +9732,7 @@ __metadata: "@types/html-minifier-terser": 7.0.0 "@types/js-yaml": 4.0.5 "@types/leaflet": 1.9.3 - "@types/leaflet-draw": 1.0.6 + "@types/leaflet-draw": 1.0.7 "@types/marked": 4.3.1 "@types/mocha": 10.0.1 "@types/qrcode": 1.5.0 From b8da7121865a3beb8423144ae56fb4ff1df3aa76 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 11:13:30 -0400 Subject: [PATCH 037/162] Update typescript-eslint monorepo to v5.59.11 (#16941) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +-- yarn.lock | 100 +++++++++++++++++++++++++-------------------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 621a759e7b..b8458ded98 100644 --- a/package.json +++ b/package.json @@ -181,8 +181,8 @@ "@types/sortablejs": "1.15.1", "@types/tar": "6.1.5", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "5.59.9", - "@typescript-eslint/parser": "5.59.9", + "@typescript-eslint/eslint-plugin": "5.59.11", + "@typescript-eslint/parser": "5.59.11", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.2", diff --git a/yarn.lock b/yarn.lock index 6fda483dcf..163d382fbc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4692,14 +4692,14 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/eslint-plugin@npm:5.59.9" +"@typescript-eslint/eslint-plugin@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/eslint-plugin@npm:5.59.11" dependencies: "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.59.9 - "@typescript-eslint/type-utils": 5.59.9 - "@typescript-eslint/utils": 5.59.9 + "@typescript-eslint/scope-manager": 5.59.11 + "@typescript-eslint/type-utils": 5.59.11 + "@typescript-eslint/utils": 5.59.11 debug: ^4.3.4 grapheme-splitter: ^1.0.4 ignore: ^5.2.0 @@ -4712,43 +4712,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: bd2428e307085d7fa6699913b6e61d65eb450bbcd26f884390cbf16722b80e1d80dc289c72774be1cdffd022744894204c3242f40ba3ffdfa05d3f210c4130bb + checksum: ff03eaa65a9fa4415cc1a14c2d4382289b9483f11dd3e0746233c2148d941cdbef421c1693304502f42307c72e049d4c3f3b58d30ce5d2ae452f31906e394e62 languageName: node linkType: hard -"@typescript-eslint/parser@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/parser@npm:5.59.9" +"@typescript-eslint/parser@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/parser@npm:5.59.11" dependencies: - "@typescript-eslint/scope-manager": 5.59.9 - "@typescript-eslint/types": 5.59.9 - "@typescript-eslint/typescript-estree": 5.59.9 + "@typescript-eslint/scope-manager": 5.59.11 + "@typescript-eslint/types": 5.59.11 + "@typescript-eslint/typescript-estree": 5.59.11 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 69b07d0a5bc6e1d24d23916c057ea9f2f53a0e7fb6dabadff92987c299640edee2c013fb93269322c7124e87b5c515529001397eae33006dfb40e1dcdf1902d7 + checksum: 75eb6e60577690e3c9dd66fde83c9b4e9e5fd818fe9673e532052d5ba8fa21a5f7a69aad19be99e6ef5825e9f52036262b25e918e51f96e1dc26e862448d2d3a languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/scope-manager@npm:5.59.9" +"@typescript-eslint/scope-manager@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/scope-manager@npm:5.59.11" dependencies: - "@typescript-eslint/types": 5.59.9 - "@typescript-eslint/visitor-keys": 5.59.9 - checksum: 362c22662d844440a7e14223d8cc0722f77ff21ad8f78deb0ee3b3f21de01b8846bf25fbbf527544677e83d8ff48008b3f7d40b39ddec55994ea4a1863e9ec0a + "@typescript-eslint/types": 5.59.11 + "@typescript-eslint/visitor-keys": 5.59.11 + checksum: f5c4e6d26da0a983b8f0c016f3ae63b3462442fe9c04d7510ca397461e13f6c48332b09b584258a7f336399fa7cd866f3ab55eaad89c5096a411c0d05d296475 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/type-utils@npm:5.59.9" +"@typescript-eslint/type-utils@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/type-utils@npm:5.59.11" dependencies: - "@typescript-eslint/typescript-estree": 5.59.9 - "@typescript-eslint/utils": 5.59.9 + "@typescript-eslint/typescript-estree": 5.59.11 + "@typescript-eslint/utils": 5.59.11 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -4756,23 +4756,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 6bc2619c5024c152b181eff1f44c9b5e7d0fc75ce9403f03b39d59fc1e13191b2fbaf6730f26a1caae22922ac47489f39c2cebccdd713588f6963169ed2a7958 + checksum: 3570ba21af35e7e0a916b606c1af311c00d20fe354a5837e0e937191b5e99ceb0076a5ba2924eaa028d4614e03981b20cfdd83a2be780c39e02be3b3bd365b63 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/types@npm:5.59.9" - checksum: 283f8fee1ee590eeccc2e0fcd3526c856c4b1e2841af2cdcd09eeac842a42cfb32f6bc8b40385380f3dbc3ee29da30f1819115eedf9e16f69ff5a160aeddd8fa +"@typescript-eslint/types@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/types@npm:5.59.11" + checksum: 4bb667571a7254f8c2b0dc3e37100e7290f9be14978722cc31c7204dfababd8a346bed4125e70dcafd15d07be386fb55bb9738bd86662ac10b98a6c964716396 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/typescript-estree@npm:5.59.9" +"@typescript-eslint/typescript-estree@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/typescript-estree@npm:5.59.11" dependencies: - "@typescript-eslint/types": 5.59.9 - "@typescript-eslint/visitor-keys": 5.59.9 + "@typescript-eslint/types": 5.59.11 + "@typescript-eslint/visitor-keys": 5.59.11 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -4781,35 +4781,35 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: c0c9b81f20a2a4337f07bc3ccdc9c1dabd765f59096255ed9a149e91e5c9517b25c2b6655f8f073807cfc13500c7451fbd9bb62e5e572c07cc07945ab042db89 + checksum: 516a828884e6939000aac17a27208088055670b0fd9bd22d137a7b2d359a8db9ce9cd09eedffed6f498f968be90ce3c2695a91d46abbd4049f87fd3b7bb986b5 languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/utils@npm:5.59.9" +"@typescript-eslint/utils@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/utils@npm:5.59.11" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.59.9 - "@typescript-eslint/types": 5.59.9 - "@typescript-eslint/typescript-estree": 5.59.9 + "@typescript-eslint/scope-manager": 5.59.11 + "@typescript-eslint/types": 5.59.11 + "@typescript-eslint/typescript-estree": 5.59.11 eslint-scope: ^5.1.1 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: 22ec5962886de7dcf65f99c37aad9fb189a3bef6b2b07c81887fb82a0e8bf137246da58e64fb02141352285708440be13acd7f6db1ca19e96f86724813ac4646 + checksum: a61f3e761dbdc5d0bdb6c78bca7b2e628f7a1920192286d002219cc3acb516757613c2ec2a4adc416858ba1751ecbe2784457d6ebcec6bbb109cfc2ca210572b languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.59.9": - version: 5.59.9 - resolution: "@typescript-eslint/visitor-keys@npm:5.59.9" +"@typescript-eslint/visitor-keys@npm:5.59.11": + version: 5.59.11 + resolution: "@typescript-eslint/visitor-keys@npm:5.59.11" dependencies: - "@typescript-eslint/types": 5.59.9 + "@typescript-eslint/types": 5.59.11 eslint-visitor-keys: ^3.3.0 - checksum: 2909ce761f7fe546592cd3c43e33263d8a5fa619375fd2fdffbc72ffc33e40d6feacafb28c79f36c638fcc2225048e7cc08c61cbac6ca63723dc68610d80e3e6 + checksum: 4894ec4b2b8da773b1f44398c836fcacb7f5a0c81f9404ecd193920e88d618091a7328659e0aa24697edda10479534db30bec7c8b0ba9fa0fce43f78222d5619 languageName: node linkType: hard @@ -9740,8 +9740,8 @@ __metadata: "@types/sortablejs": 1.15.1 "@types/tar": 6.1.5 "@types/webspeechapi": 0.0.29 - "@typescript-eslint/eslint-plugin": 5.59.9 - "@typescript-eslint/parser": 5.59.9 + "@typescript-eslint/eslint-plugin": 5.59.11 + "@typescript-eslint/parser": 5.59.11 "@vaadin/combo-box": 24.0.8 "@vaadin/vaadin-themable-mixin": 24.0.8 "@vibrant/color": 3.2.1-alpha.1 From 67e8357bb99ae30338d89a094830c3171e55f82d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 11:15:05 -0400 Subject: [PATCH 038/162] Update dependency sinon to v15.1.2 (#16940) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index b8458ded98..d5cbe1b644 100644 --- a/package.json +++ b/package.json @@ -230,7 +230,7 @@ "rollup-plugin-terser": "7.0.2", "rollup-plugin-visualizer": "5.9.2", "serve-handler": "6.1.5", - "sinon": "15.1.0", + "sinon": "15.1.2", "source-map-url": "0.4.1", "systemjs": "6.14.1", "tar": "6.1.15", diff --git a/yarn.lock b/yarn.lock index 163d382fbc..557fb0ebf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4057,7 +4057,7 @@ __metadata: languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^10.0.2, @sinonjs/fake-timers@npm:^10.2.0": +"@sinonjs/fake-timers@npm:^10.0.2, @sinonjs/fake-timers@npm:^10.1.0": version: 10.2.0 resolution: "@sinonjs/fake-timers@npm:10.2.0" dependencies: @@ -9826,7 +9826,7 @@ __metadata: rollup-plugin-visualizer: 5.9.2 rrule: 2.7.2 serve-handler: 6.1.5 - sinon: 15.1.0 + sinon: 15.1.2 sortablejs: 1.15.0 source-map-url: 0.4.1 superstruct: 1.0.3 @@ -14366,17 +14366,17 @@ __metadata: languageName: node linkType: hard -"sinon@npm:15.1.0": - version: 15.1.0 - resolution: "sinon@npm:15.1.0" +"sinon@npm:15.1.2": + version: 15.1.2 + resolution: "sinon@npm:15.1.2" dependencies: "@sinonjs/commons": ^3.0.0 - "@sinonjs/fake-timers": ^10.2.0 + "@sinonjs/fake-timers": ^10.1.0 "@sinonjs/samsam": ^8.0.0 diff: ^5.1.0 nise: ^5.1.4 supports-color: ^7.2.0 - checksum: 3f0eab3e293c6206cca4a31f3c2836be86889f16bf6f54e2429550c1d07d0e7e9327cdbe6b7b69662c152a63e9f2661334c266932ba8f3206190009d58cb4f06 + checksum: 4484235fe4e84cc142cb8810a3a80f5b016178d739c1e2cc0b5eb1f0e05e05dd2dffaf53878826ac40743791acabb7265297affced727b0480c8bfe9abead8e8 languageName: node linkType: hard From 49f59d71629b3c5e3ed9426144e16f25b1fd9406 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 11:17:37 -0400 Subject: [PATCH 039/162] Update CodeMirror (#16942) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 6 +++--- yarn.lock | 30 +++++++++++++++--------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index d5cbe1b644..852b4e97d4 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,13 @@ "dependencies": { "@babel/runtime": "7.22.5", "@braintree/sanitize-url": "6.0.2", - "@codemirror/autocomplete": "6.7.1", + "@codemirror/autocomplete": "6.8.0", "@codemirror/commands": "6.2.4", - "@codemirror/language": "6.7.0", + "@codemirror/language": "6.8.0", "@codemirror/legacy-modes": "6.3.2", "@codemirror/search": "6.5.0", "@codemirror/state": "6.2.1", - "@codemirror/view": "6.13.0", + "@codemirror/view": "6.13.2", "@egjs/hammerjs": "2.0.17", "@formatjs/intl-datetimeformat": "6.9.0", "@formatjs/intl-displaynames": "6.4.0", diff --git a/yarn.lock b/yarn.lock index 557fb0ebf1..6171785b1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1450,9 +1450,9 @@ __metadata: languageName: node linkType: hard -"@codemirror/autocomplete@npm:6.7.1": - version: 6.7.1 - resolution: "@codemirror/autocomplete@npm:6.7.1" +"@codemirror/autocomplete@npm:6.8.0": + version: 6.8.0 + resolution: "@codemirror/autocomplete@npm:6.8.0" dependencies: "@codemirror/language": ^6.0.0 "@codemirror/state": ^6.0.0 @@ -1463,7 +1463,7 @@ __metadata: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.0.0 - checksum: 5f1331cceb6a7b0bd4dc9bad6025d16d1c415bfc2fba29b452f9f5501abd34b75a240e3a20fb9fed92a82a666e54562c32cfe220892713bfbd5a5a16fa004cd8 + checksum: b251a21065a954be7a4a9cf6fd1dce6027bd79ac7006728c0fde364b50c75ee4079bd53acf9890fdfdca78453c863f0c010010c26010cd9acdede3480273ad23 languageName: node linkType: hard @@ -1479,9 +1479,9 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:6.7.0, @codemirror/language@npm:^6.0.0": - version: 6.7.0 - resolution: "@codemirror/language@npm:6.7.0" +"@codemirror/language@npm:6.8.0, @codemirror/language@npm:^6.0.0": + version: 6.8.0 + resolution: "@codemirror/language@npm:6.8.0" dependencies: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 @@ -1489,7 +1489,7 @@ __metadata: "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 673905e9eb80f039a5e6c59a8aeca217e124a9a03734848043192aeff9e5b3a82f150559f7bd637ee197c4b2171eb5b04e757d717922128ea4fecca1ac6ecac4 + checksum: 64408d996641931fa4c6b892e17ee1fdaee0f63d3d84c019a6ea7b1e6d1c774f92357b95c2ebaed60545062b795b72d0a058c03578b2bf4023c87726e97b5d2f languageName: node linkType: hard @@ -1520,14 +1520,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:6.13.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.6.0": - version: 6.13.0 - resolution: "@codemirror/view@npm:6.13.0" +"@codemirror/view@npm:6.13.2, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.6.0": + version: 6.13.2 + resolution: "@codemirror/view@npm:6.13.2" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: 3c4713eba5cf54afd9cf92f42295f7a9b42f4041ad9c17fc3dbbeebeb94f95fe3b2bd5377265ceed71a070d5b2472bae2fbb5013254c7e85fe5e1e3b5c807d79 + checksum: db0d638fbbe2f9a832674f06512ca55cdb7576a265c01ab8a7b6715d2a50ddf53200f597637b146adebe1df51255fe5bd2d2c74cf1fa539b0434764c0550d3a5 languageName: node linkType: hard @@ -9648,13 +9648,13 @@ __metadata: "@babel/preset-typescript": 7.22.5 "@babel/runtime": 7.22.5 "@braintree/sanitize-url": 6.0.2 - "@codemirror/autocomplete": 6.7.1 + "@codemirror/autocomplete": 6.8.0 "@codemirror/commands": 6.2.4 - "@codemirror/language": 6.7.0 + "@codemirror/language": 6.8.0 "@codemirror/legacy-modes": 6.3.2 "@codemirror/search": 6.5.0 "@codemirror/state": 6.2.1 - "@codemirror/view": 6.13.0 + "@codemirror/view": 6.13.2 "@egjs/hammerjs": 2.0.17 "@formatjs/intl-datetimeformat": 6.9.0 "@formatjs/intl-displaynames": 6.4.0 From 356935fefc2ae7ffc92a0e7c72950fd425c388e1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 15:28:29 +0000 Subject: [PATCH 040/162] Update formatjs monorepo (#16945) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 16 ++--- yarn.lock | 170 +++++++++++++++++++++++++-------------------------- 2 files changed, 93 insertions(+), 93 deletions(-) diff --git a/package.json b/package.json index 852b4e97d4..74e8378655 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,14 @@ "@codemirror/state": "6.2.1", "@codemirror/view": "6.13.2", "@egjs/hammerjs": "2.0.17", - "@formatjs/intl-datetimeformat": "6.9.0", - "@formatjs/intl-displaynames": "6.4.0", + "@formatjs/intl-datetimeformat": "6.10.0", + "@formatjs/intl-displaynames": "6.5.0", "@formatjs/intl-getcanonicallocales": "2.2.1", - "@formatjs/intl-listformat": "7.3.0", - "@formatjs/intl-locale": "3.3.1", - "@formatjs/intl-numberformat": "8.6.0", - "@formatjs/intl-pluralrules": "5.2.3", - "@formatjs/intl-relativetimeformat": "11.2.3", + "@formatjs/intl-listformat": "7.4.0", + "@formatjs/intl-locale": "3.3.2", + "@formatjs/intl-numberformat": "8.7.0", + "@formatjs/intl-pluralrules": "5.2.4", + "@formatjs/intl-relativetimeformat": "11.2.4", "@fullcalendar/core": "6.1.8", "@fullcalendar/daygrid": "6.1.8", "@fullcalendar/interaction": "6.1.8", @@ -115,7 +115,7 @@ "hls.js": "1.4.5", "home-assistant-js-websocket": "8.0.1", "idb-keyval": "6.2.1", - "intl-messageformat": "10.4.0", + "intl-messageformat": "10.5.0", "js-yaml": "4.1.0", "leaflet": "1.9.4", "leaflet-draw": "1.0.4", diff --git a/yarn.lock b/yarn.lock index 6171785b1e..ff99f0482b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1589,74 +1589,74 @@ __metadata: languageName: node linkType: hard -"@formatjs/ecma402-abstract@npm:1.16.0": - version: 1.16.0 - resolution: "@formatjs/ecma402-abstract@npm:1.16.0" +"@formatjs/ecma402-abstract@npm:1.17.0": + version: 1.17.0 + resolution: "@formatjs/ecma402-abstract@npm:1.17.0" dependencies: - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: a3d6016d51b9f9a876e4ad66010ef80b07f54b9bb50f6135267d41203219d38e9b934fc575e65e3556eb89d92640452e03927f50f030906be8919a319d906bd2 + checksum: cc45d238e541076cb27b9cf02d8b97f789d1744b60218da6d31793204850c159e85f5b2557de3905a365eefd52a1c2e7f1febb9e1f009bad23d5eca17b3de6c8 languageName: node linkType: hard -"@formatjs/fast-memoize@npm:2.1.0": - version: 2.1.0 - resolution: "@formatjs/fast-memoize@npm:2.1.0" +"@formatjs/fast-memoize@npm:2.2.0": + version: 2.2.0 + resolution: "@formatjs/fast-memoize@npm:2.2.0" dependencies: tslib: ^2.4.0 - checksum: 778da54abaaa77013205c7f0dceb654ca2d9b76d0d1380b4d4bd08d57a870f62d434f29b2cda4dbf892d47b045e7d2bc90f1273ebd968844dea2a2e8b3315e69 + checksum: 8697fe72a7ece252d600a7d08105f2a2f758e2dd96f54ac0a4c508b1205a559fc08835635e1f8e5ca9dcc3ee61ce1fca4a0e7047b402f29fc96051e293a280ff languageName: node linkType: hard -"@formatjs/icu-messageformat-parser@npm:2.5.0": - version: 2.5.0 - resolution: "@formatjs/icu-messageformat-parser@npm:2.5.0" +"@formatjs/icu-messageformat-parser@npm:2.6.0": + version: 2.6.0 + resolution: "@formatjs/icu-messageformat-parser@npm:2.6.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/icu-skeleton-parser": 1.5.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/icu-skeleton-parser": 1.6.0 tslib: ^2.4.0 - checksum: 11c524cc2c15c1f15b54e81fca506ccfc77f3b3adabdb457053aacfbd28789c88054e378439cf23accf69baeefbe8e35d9bb5a6253235a1bc4724dd4956bfba3 + checksum: 67e76416a381663f62cb7ceaa699b3dc4505b9bfd8dda31950b8fa159e9abc1aae85d2ffa08760448083f113bdabca1653796e988b7a12eef891260726e56ed7 languageName: node linkType: hard -"@formatjs/icu-skeleton-parser@npm:1.5.0": - version: 1.5.0 - resolution: "@formatjs/icu-skeleton-parser@npm:1.5.0" +"@formatjs/icu-skeleton-parser@npm:1.6.0": + version: 1.6.0 + resolution: "@formatjs/icu-skeleton-parser@npm:1.6.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 + "@formatjs/ecma402-abstract": 1.17.0 tslib: ^2.4.0 - checksum: 0da173c1fb3d28c8eb4c3fd4eadec9d0b6476d639abb5c371b0a156aa79bbe6d1e0d6fc6fff09b254da7523049baa1032a61a0cad647a3e2e005f7e55317ef39 + checksum: e0a2e251358fb62cc45ad4783f57ed63db361334634557d5dcf3992b98c2c5409146d890b465321f91d2255eda5d8fdbfc9962e9f2e3fa7b10a738abfbe8ebc0 languageName: node linkType: hard -"@formatjs/intl-datetimeformat@npm:6.9.0": - version: 6.9.0 - resolution: "@formatjs/intl-datetimeformat@npm:6.9.0" +"@formatjs/intl-datetimeformat@npm:6.10.0": + version: 6.10.0 + resolution: "@formatjs/intl-datetimeformat@npm:6.10.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: 3abfab4d8e02e84442b2231e4bd1961e5eaaccbeee895333293babca685f96aac5082005443be3bb7a1343a80bc6b65fe6713ed1bb794d265a04ef570f0fdb09 + checksum: a0f915dd0d179dfeb0dfa585c7e939ef4b51a90cf04b9522d14de8acc9fb18e7af30898cc215c134955f31aa244d1f59ca677b9769fa9ee539148f6f52ceaa1d languageName: node linkType: hard -"@formatjs/intl-displaynames@npm:6.4.0": - version: 6.4.0 - resolution: "@formatjs/intl-displaynames@npm:6.4.0" +"@formatjs/intl-displaynames@npm:6.5.0": + version: 6.5.0 + resolution: "@formatjs/intl-displaynames@npm:6.5.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: 66d787bdd398da6a14a2f2ae0b74e9f98f6832a0745f5fa8e986d76d3cb21933bdafc503fd6ec4cb94de38f5324867774f60895e6e2ebbabf1db6702f56b50d4 + checksum: d071f8459796240575e9911052b7116a6e2e43687607b0a5d1ac8ceddbaa85324af78694226c37c8172c0f3e7d6b793f506c5758b6bc50b2110516902b532e12 languageName: node linkType: hard -"@formatjs/intl-enumerator@npm:1.3.1": - version: 1.3.1 - resolution: "@formatjs/intl-enumerator@npm:1.3.1" +"@formatjs/intl-enumerator@npm:1.3.2": + version: 1.3.2 + resolution: "@formatjs/intl-enumerator@npm:1.3.2" dependencies: tslib: ^2.4.0 - checksum: 48acfd7f3368eee9a64017c0e9dedc588178aa94606c51a03a00f2d1a4954fd31457f98835f11e0b725f0e9272a438b98df03ad7dff85b33483f810b33aafd01 + checksum: 37435354fcab9f69390402b1bcc917e83d0e35869cd5a06b584ca84ef62b179a4b94b9ee94febb59ab503a9d1587babcdcbebc2d4ece146fbc02bef41f722314 languageName: node linkType: hard @@ -1669,68 +1669,68 @@ __metadata: languageName: node linkType: hard -"@formatjs/intl-listformat@npm:7.3.0": - version: 7.3.0 - resolution: "@formatjs/intl-listformat@npm:7.3.0" +"@formatjs/intl-listformat@npm:7.4.0": + version: 7.4.0 + resolution: "@formatjs/intl-listformat@npm:7.4.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: 6638e6a3cad750ac5199cf293c549c4048f0de240762dd98c61cece645091f19262ef64c1fb2f7a44b5bb3e5c168a8f53e9aa604b4867290981c30baf8635c0d + checksum: a2deed31cce57f249e470f54675286c36edc2f5ec1d63a2f36e6315a0154ca06404fa5c00aaefc2c52af57d3d471b17c217e885cc9565e5f54c36509af37fe12 languageName: node linkType: hard -"@formatjs/intl-locale@npm:3.3.1": - version: 3.3.1 - resolution: "@formatjs/intl-locale@npm:3.3.1" +"@formatjs/intl-locale@npm:3.3.2": + version: 3.3.2 + resolution: "@formatjs/intl-locale@npm:3.3.2" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-enumerator": 1.3.1 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-enumerator": 1.3.2 "@formatjs/intl-getcanonicallocales": 2.2.1 tslib: ^2.4.0 - checksum: 6f4b1f7c55ea6108f3dacd9167e15c57a853dec69bdfeadfdc1a2c50167e7f90c8962c9b03b10efa1e0ae5dabeb0c7499c86545592ba0ca88e690ac13665f185 + checksum: 41d2ab272ba759671cfa1720b2c43f8e261694f68d114ff976f2b9749ac3afad2181aa1b16799740082aa05bedd6f23b0ab67c65f48bfa0097b42582789e9a4d languageName: node linkType: hard -"@formatjs/intl-localematcher@npm:0.3.0": - version: 0.3.0 - resolution: "@formatjs/intl-localematcher@npm:0.3.0" +"@formatjs/intl-localematcher@npm:0.4.0": + version: 0.4.0 + resolution: "@formatjs/intl-localematcher@npm:0.4.0" dependencies: tslib: ^2.4.0 - checksum: 26fbe20a3187842ea9fd417429dd53af941ad896c783fcc15df25e92c3fe9b9895f9909de9f9731ef75b81e7fb396d3d10d35656e3f5ff3588488521d600ec3a + checksum: c65108e9a81c3733d2b6240ceedc846d0ae59c3606041cb5cc71c13453cdabe295b0dc8559dc4a8acaafdc45876807bd5e9ef37a3ec1cb864e78db655d434b66 languageName: node linkType: hard -"@formatjs/intl-numberformat@npm:8.6.0": - version: 8.6.0 - resolution: "@formatjs/intl-numberformat@npm:8.6.0" +"@formatjs/intl-numberformat@npm:8.7.0": + version: 8.7.0 + resolution: "@formatjs/intl-numberformat@npm:8.7.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: d15a7ef5cc18262f2a02956b4bfe3376f1f6fc2f696a222e5653809bb05060bda9ed45836f47a332fd608ea08e6f52cadd76e75ec6f9723bb6139db23d203399 + checksum: 987bd3e6a48e6efa054d9f526b3cba01675a6c96ffc6d652f6053f3dd1cbae5e56ac784718d135a2e2cd6c7afab4f89c0a592a28e2ff93134baeddc1fa1aff30 languageName: node linkType: hard -"@formatjs/intl-pluralrules@npm:5.2.3": - version: 5.2.3 - resolution: "@formatjs/intl-pluralrules@npm:5.2.3" +"@formatjs/intl-pluralrules@npm:5.2.4": + version: 5.2.4 + resolution: "@formatjs/intl-pluralrules@npm:5.2.4" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: aae18c138f5402712df43831a2f4a0c261734fa88c7bf165c2375d0a355d996e4475afc046d255cf2441ebdc096cc47b391c621ae4eacd5a8af318d72b1dc341 + checksum: a55445724a65c7c82896792babb2522a03774f3dd370bda2c8a76103528f71e101be84636ae4b161f68fc68afb63f1e61a3bf7489c07ffa722c8213199113814 languageName: node linkType: hard -"@formatjs/intl-relativetimeformat@npm:11.2.3": - version: 11.2.3 - resolution: "@formatjs/intl-relativetimeformat@npm:11.2.3" +"@formatjs/intl-relativetimeformat@npm:11.2.4": + version: 11.2.4 + resolution: "@formatjs/intl-relativetimeformat@npm:11.2.4" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/intl-localematcher": 0.3.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/intl-localematcher": 0.4.0 tslib: ^2.4.0 - checksum: b3b60ba5a03538be66ff73aa9621a7aaa4ee911dc0052c737295ec06301a0bf34ecfd2c9872951e7a6507152ba858aa9fdb6499a28a6f3c020ed1b9aabe4b9fa + checksum: 8a99abd4fa7a4dec6d46140940709d83c094f4dce5e331f0556e72d75f375f6758d3fcfaee9e78cd313dcded17fd6788814a4a0bee542e83ec74cef71d35e2bf languageName: node linkType: hard @@ -9656,14 +9656,14 @@ __metadata: "@codemirror/state": 6.2.1 "@codemirror/view": 6.13.2 "@egjs/hammerjs": 2.0.17 - "@formatjs/intl-datetimeformat": 6.9.0 - "@formatjs/intl-displaynames": 6.4.0 + "@formatjs/intl-datetimeformat": 6.10.0 + "@formatjs/intl-displaynames": 6.5.0 "@formatjs/intl-getcanonicallocales": 2.2.1 - "@formatjs/intl-listformat": 7.3.0 - "@formatjs/intl-locale": 3.3.1 - "@formatjs/intl-numberformat": 8.6.0 - "@formatjs/intl-pluralrules": 5.2.3 - "@formatjs/intl-relativetimeformat": 11.2.3 + "@formatjs/intl-listformat": 7.4.0 + "@formatjs/intl-locale": 3.3.2 + "@formatjs/intl-numberformat": 8.7.0 + "@formatjs/intl-pluralrules": 5.2.4 + "@formatjs/intl-relativetimeformat": 11.2.4 "@fullcalendar/core": 6.1.8 "@fullcalendar/daygrid": 6.1.8 "@fullcalendar/interaction": 6.1.8 @@ -9794,7 +9794,7 @@ __metadata: husky: 8.0.3 idb-keyval: 6.2.1 instant-mocha: 1.5.1 - intl-messageformat: 10.4.0 + intl-messageformat: 10.5.0 js-yaml: 4.1.0 jszip: 3.10.1 leaflet: 1.9.4 @@ -10274,15 +10274,15 @@ __metadata: languageName: node linkType: hard -"intl-messageformat@npm:10.4.0": - version: 10.4.0 - resolution: "intl-messageformat@npm:10.4.0" +"intl-messageformat@npm:10.5.0": + version: 10.5.0 + resolution: "intl-messageformat@npm:10.5.0" dependencies: - "@formatjs/ecma402-abstract": 1.16.0 - "@formatjs/fast-memoize": 2.1.0 - "@formatjs/icu-messageformat-parser": 2.5.0 + "@formatjs/ecma402-abstract": 1.17.0 + "@formatjs/fast-memoize": 2.2.0 + "@formatjs/icu-messageformat-parser": 2.6.0 tslib: ^2.4.0 - checksum: 763b6da80a69242d1a52cb13c9435dd40908a2ae0a7407bef260aa537e0e96cfa5394e7d01fa90dc45c3c2d159ac874d2ae58bbaa2da483effb44e914e87a185 + checksum: 164c49028b8bf2685f57f8f018d9a2c1d827e94b1c300ebf9df50b6aef25adedb3bf511b3cf603364d67257634b57926935066b2f3715ccb6c2af683cc0815a6 languageName: node linkType: hard From bcceef30bb33ae2bd6f68de938cd6c9b450b39fb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 12:46:30 -0400 Subject: [PATCH 041/162] Update dependency @octokit/auth-oauth-device to v5 (#16947) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 74e8378655..f76945ef96 100644 --- a/package.json +++ b/package.json @@ -156,7 +156,7 @@ "@babel/preset-env": "7.22.5", "@babel/preset-typescript": "7.22.5", "@koa/cors": "4.0.0", - "@octokit/auth-oauth-device": "4.0.5", + "@octokit/auth-oauth-device": "5.0.0", "@octokit/plugin-retry": "5.0.3", "@octokit/rest": "19.0.11", "@open-wc/dev-server-hmr": "0.1.4", diff --git a/yarn.lock b/yarn.lock index ff99f0482b..90c2c21078 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3237,15 +3237,15 @@ __metadata: languageName: node linkType: hard -"@octokit/auth-oauth-device@npm:4.0.5": - version: 4.0.5 - resolution: "@octokit/auth-oauth-device@npm:4.0.5" +"@octokit/auth-oauth-device@npm:5.0.0": + version: 5.0.0 + resolution: "@octokit/auth-oauth-device@npm:5.0.0" dependencies: "@octokit/oauth-methods": ^2.0.0 "@octokit/request": ^6.0.0 "@octokit/types": ^9.0.0 universal-user-agent: ^6.0.0 - checksum: 361824ba13c56beb05016b48b7d492f7439650abbb9e687c9f3e82ef4830790e1aae3d78c6e95dc317278146442c59821d87bf0b9b3c6d53f87117fe32b380d0 + checksum: 7089bf13bc01629e501af88dc01c18b29b70dba87e26bd4eb2b7faf6baefe3ba9e4ed92f77d5b7a8a56afbbdb1a01b4b264c140c10c4ca6fbd28a7976fcfdc6e languageName: node linkType: hard @@ -9703,7 +9703,7 @@ __metadata: "@material/web": =1.0.0-pre.10 "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 - "@octokit/auth-oauth-device": 4.0.5 + "@octokit/auth-oauth-device": 5.0.0 "@octokit/plugin-retry": 5.0.3 "@octokit/rest": 19.0.11 "@open-wc/dev-server-hmr": 0.1.4 From d4f4ee1e5913bd783d1b70821abe3a63ddc54c65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 16:53:36 +0000 Subject: [PATCH 042/162] Update dependency tinykeys to v2 (#16873) * Update dependency tinykeys to v2 * Switch to named import --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Steve Repsher --- package.json | 2 +- src/state/quick-bar-mixin.ts | 2 +- yarn.lock | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index f76945ef96..f9fb14b6d9 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "rrule": "2.7.2", "sortablejs": "1.15.0", "superstruct": "1.0.3", - "tinykeys": "1.4.0", + "tinykeys": "2.0.0", "tsparticles-engine": "2.9.3", "tsparticles-preset-links": "2.9.3", "unfetch": "5.0.0", diff --git a/src/state/quick-bar-mixin.ts b/src/state/quick-bar-mixin.ts index 04659ac940..0ccaf9f091 100644 --- a/src/state/quick-bar-mixin.ts +++ b/src/state/quick-bar-mixin.ts @@ -1,5 +1,5 @@ import type { PropertyValues } from "lit"; -import tinykeys from "tinykeys"; +import { tinykeys } from "tinykeys"; import { isComponentLoaded } from "../common/config/is_component_loaded"; import { mainWindow } from "../common/dom/get_main_window"; import { diff --git a/yarn.lock b/yarn.lock index 90c2c21078..dfb6164030 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9833,7 +9833,7 @@ __metadata: systemjs: 6.14.1 tar: 6.1.15 terser-webpack-plugin: 5.3.9 - tinykeys: 1.4.0 + tinykeys: 2.0.0 ts-lit-plugin: 1.2.1 tsparticles-engine: 2.9.3 tsparticles-preset-links: 2.9.3 @@ -15217,10 +15217,10 @@ __metadata: languageName: node linkType: hard -"tinykeys@npm:1.4.0": - version: 1.4.0 - resolution: "tinykeys@npm:1.4.0" - checksum: 1a285204116f1150d761a5c34bac9340e9c66a2b1a619311c3e0581168bc086a0ba9ae844774b82cb3393a121def5738c1f33f426135052d5acbf7863e9268d2 +"tinykeys@npm:2.0.0": + version: 2.0.0 + resolution: "tinykeys@npm:2.0.0" + checksum: 2f81ce9660b27e3ea664c5afc3af89860254989bb194834b530f5ccad389fef2ddbdac8e6b4de8628c0f8e5b50957032d11a27232fc6666472212513c279a9c1 languageName: node linkType: hard From afdeb3625890ed86a0598c7bf04bac0512b535fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 14:56:35 -0400 Subject: [PATCH 043/162] Update vaadinWebComponents monorepo to v24.1.0 (#16844) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 164 ++++++++++++++++++++++++++++----------------------- 2 files changed, 92 insertions(+), 76 deletions(-) diff --git a/package.json b/package.json index f9fb14b6d9..4887816443 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,8 @@ "@polymer/paper-toast": "3.0.1", "@polymer/polymer": "3.5.1", "@thomasloven/round-slider": "0.6.0", - "@vaadin/combo-box": "24.0.8", - "@vaadin/vaadin-themable-mixin": "24.0.8", + "@vaadin/combo-box": "24.1.0", + "@vaadin/vaadin-themable-mixin": "24.1.0", "@vibrant/color": "3.2.1-alpha.1", "@vibrant/core": "3.2.1-alpha.1", "@vibrant/quantizer-mmcq": "3.2.1-alpha.1", diff --git a/yarn.lock b/yarn.lock index dfb6164030..6e34f8320e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4813,110 +4813,126 @@ __metadata: languageName: node linkType: hard -"@vaadin/combo-box@npm:24.0.8": - version: 24.0.8 - resolution: "@vaadin/combo-box@npm:24.0.8" +"@vaadin/a11y-base@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/a11y-base@npm:24.1.0" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.0.8 - "@vaadin/field-base": ~24.0.8 - "@vaadin/input-container": ~24.0.8 - "@vaadin/item": ~24.0.8 - "@vaadin/lit-renderer": ~24.0.8 - "@vaadin/overlay": ~24.0.8 - "@vaadin/vaadin-lumo-styles": ~24.0.8 - "@vaadin/vaadin-material-styles": ~24.0.8 - "@vaadin/vaadin-themable-mixin": ~24.0.8 - checksum: 14bea4c273a96393e8cd3338f0aee6da417026d5712adc82e4dc7f2964e9ccb3b338f950788bc22ec7e7805ababb98f624d44415d969788c0ea896cdc7480084 + "@vaadin/component-base": ~24.1.0 + lit: ^2.0.0 + checksum: f019f2c04473c60c3714ec3da65a129833e1fab4e2eefb4f88d4caa81eb45da756dce2cec8b222bd259d0b87bc67439a4aa88f636b90e6f704c037197bdc1492 languageName: node linkType: hard -"@vaadin/component-base@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/component-base@npm:24.0.8" +"@vaadin/combo-box@npm:24.1.0": + version: 24.1.0 + resolution: "@vaadin/combo-box@npm:24.1.0" + dependencies: + "@open-wc/dedupe-mixin": ^1.3.0 + "@polymer/polymer": ^3.0.0 + "@vaadin/a11y-base": ~24.1.0 + "@vaadin/component-base": ~24.1.0 + "@vaadin/field-base": ~24.1.0 + "@vaadin/input-container": ~24.1.0 + "@vaadin/item": ~24.1.0 + "@vaadin/lit-renderer": ~24.1.0 + "@vaadin/overlay": ~24.1.0 + "@vaadin/vaadin-lumo-styles": ~24.1.0 + "@vaadin/vaadin-material-styles": ~24.1.0 + "@vaadin/vaadin-themable-mixin": ~24.1.0 + checksum: cbdbfba535a16faa84a897d61565e91d1b2ec0dad87c1644e287c180fed13fcf3e2b0c436fb85ad7f394a4bb7aceb596b9070e3e171afe8167f2158908e71ea5 + languageName: node + linkType: hard + +"@vaadin/component-base@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/component-base@npm:24.1.0" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 "@vaadin/vaadin-development-mode-detector": ^2.0.0 "@vaadin/vaadin-usage-statistics": ^2.1.0 lit: ^2.0.0 - checksum: 6406ee2f2bdca164a15480f870611caa91f4b5cfd083de2b838ddf2e6438415d1fce236edebfc8509057ee64f1f1c59712af49e2b41d938a6fa6bc6593b0b00e + checksum: 1df8786d8ef1b3a2a104101c8877464d6fca3ea70fa851b2f99bcf32bb83780ced05f524b6225e95f901edb8ec9379fe625ac18154367a3a684846004277badc languageName: node linkType: hard -"@vaadin/field-base@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/field-base@npm:24.0.8" +"@vaadin/field-base@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/field-base@npm:24.1.0" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.0.8 + "@vaadin/a11y-base": ~24.1.0 + "@vaadin/component-base": ~24.1.0 lit: ^2.0.0 - checksum: 7603960e86e705ead7bddaa24252cf733b43b8f08a4b0d4f7c7941f01a2c45fc6a8a50d98ccc49a50a5e1e40b7bbd6327db6762a6fa449a3b31c2934d46f64b0 + checksum: 5e37ede91e05dd8eb9fa43749b89670904abfc30e522eebb4ec2225318cf72774dd4e94e49deb1b55daea719818803d90968c4d0f4b87132d24289345e728abd languageName: node linkType: hard -"@vaadin/icon@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/icon@npm:24.0.8" +"@vaadin/icon@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/icon@npm:24.1.0" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.0.8 - "@vaadin/vaadin-lumo-styles": ~24.0.8 - "@vaadin/vaadin-themable-mixin": ~24.0.8 + "@vaadin/component-base": ~24.1.0 + "@vaadin/vaadin-lumo-styles": ~24.1.0 + "@vaadin/vaadin-themable-mixin": ~24.1.0 lit: ^2.0.0 - checksum: bfec0d0048649817dd40f5aec2ad3c94d51557161c5af5f04aebadf56d6546b34a5b29013008207e71deaa4ccf9aad0b5a82beb00541f246cb0707396b72e327 + checksum: 60ee5e3056d175b032c1ad41b3b208b2289c2ef043e4f073e86f691ed135ea98a8780fe0624c9347858f5f0f44a0cc58c345d51eb3795fac47cdafd6cc1a8c59 languageName: node linkType: hard -"@vaadin/input-container@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/input-container@npm:24.0.8" +"@vaadin/input-container@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/input-container@npm:24.1.0" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.0.8 - "@vaadin/vaadin-lumo-styles": ~24.0.8 - "@vaadin/vaadin-material-styles": ~24.0.8 - "@vaadin/vaadin-themable-mixin": ~24.0.8 - checksum: d323b2e5b74c72107a9cb6f833bd20b09b2f419d2fbac45136acd535e50ac78d216779ed56aaf510fc73d28677e850d2ed2588f44189289687625cb51a0617d2 + "@vaadin/component-base": ~24.1.0 + "@vaadin/vaadin-lumo-styles": ~24.1.0 + "@vaadin/vaadin-material-styles": ~24.1.0 + "@vaadin/vaadin-themable-mixin": ~24.1.0 + checksum: d222ec0df6c3e169341d8e1c4bc5b15da6f4324bb962537929b864df389f24474195c0088b1d06d88aaecc18f63938c5f5fa614d8fcda233c8ea5222fc31f183 languageName: node linkType: hard -"@vaadin/item@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/item@npm:24.0.8" +"@vaadin/item@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/item@npm:24.1.0" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.0.8 - "@vaadin/vaadin-lumo-styles": ~24.0.8 - "@vaadin/vaadin-material-styles": ~24.0.8 - "@vaadin/vaadin-themable-mixin": ~24.0.8 - checksum: 7d2ebcd7b9a04dd093c22fdf4e5fe8e37f96c5bafd480f4cd69471d12d675d8fd966f3cea2b82f3fb7bd3f77a1d1f05cc07d7799345df0885ad3cea63d579c20 + "@vaadin/a11y-base": ~24.1.0 + "@vaadin/component-base": ~24.1.0 + "@vaadin/vaadin-lumo-styles": ~24.1.0 + "@vaadin/vaadin-material-styles": ~24.1.0 + "@vaadin/vaadin-themable-mixin": ~24.1.0 + checksum: 643f47f7e4ae74cffa3e891789c0689063d73552d81aa84dad66d3f415e624e734f13ae0b0123710984fa8390ea2df1f468d9415d7d914150695821045e09ea0 languageName: node linkType: hard -"@vaadin/lit-renderer@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/lit-renderer@npm:24.0.8" +"@vaadin/lit-renderer@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/lit-renderer@npm:24.1.0" dependencies: lit: ^2.0.0 - checksum: d624c779e2b4682923322cb952255490b5f58f392bfd24121fffc347f8cb89be9e90de760c24e846bc98e0f9bb76b658ed99a5446dfaa8f81e61270f8adcf06f + checksum: 9f0940e0245f608dc613cb33ffdb4f88c275597f7b25fac04892d29ddfc752801fde118fca47bd8445a9d51bca203c339216186ca9b4941b0b6f07a52cc4fc9a languageName: node linkType: hard -"@vaadin/overlay@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/overlay@npm:24.0.8" +"@vaadin/overlay@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/overlay@npm:24.1.0" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.0.8 - "@vaadin/vaadin-lumo-styles": ~24.0.8 - "@vaadin/vaadin-material-styles": ~24.0.8 - "@vaadin/vaadin-themable-mixin": ~24.0.8 - checksum: f274cfd0cd2bd0f2a75b0f4f494e1d82e0947d7faaa8cb791801c0b2aa90020113ece50fa9736dc59015436ea07c053261efa096ca39ed458c072a7fb98b8110 + "@vaadin/a11y-base": ~24.1.0 + "@vaadin/component-base": ~24.1.0 + "@vaadin/vaadin-lumo-styles": ~24.1.0 + "@vaadin/vaadin-material-styles": ~24.1.0 + "@vaadin/vaadin-themable-mixin": ~24.1.0 + checksum: 8362db034347e8186c4397de55fd51b69e645f621614298b68fa383e4957a6ea8290b0770b3d686217ce937a7a18d33ea0ea6844d3da4d3aa3a61d7498210b80 languageName: node linkType: hard @@ -4927,34 +4943,34 @@ __metadata: languageName: node linkType: hard -"@vaadin/vaadin-lumo-styles@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/vaadin-lumo-styles@npm:24.0.8" +"@vaadin/vaadin-lumo-styles@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/vaadin-lumo-styles@npm:24.1.0" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/icon": ~24.0.8 - "@vaadin/vaadin-themable-mixin": ~24.0.8 - checksum: 351516cf34d95d3800f82d067ef8c539d67a8cde4c0becbc5bc2467f805999c3ba66d9ba3e493aff3708cde3684be937ed766828af7ad956c9ec48f6209650f7 + "@vaadin/icon": ~24.1.0 + "@vaadin/vaadin-themable-mixin": ~24.1.0 + checksum: 68c55fadb2468048b3fe2ae14c8e5fdb90cb35a171c1a2dc7e33b369d8f79565b6e1c5a93a26dbc5e24b3f7b7e5634b87459fd5528e58bf045cc6c5717840703 languageName: node linkType: hard -"@vaadin/vaadin-material-styles@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/vaadin-material-styles@npm:24.0.8" +"@vaadin/vaadin-material-styles@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/vaadin-material-styles@npm:24.1.0" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/vaadin-themable-mixin": ~24.0.8 - checksum: 667719adb4efbf9544025a2c59887a359321190e15c5cd902f17c53b7138a23720ddbf0986b2315884163c92e61c1847419844b604651efb0118bc985af47645 + "@vaadin/vaadin-themable-mixin": ~24.1.0 + checksum: 205e67f5a99dda6cdf1410a0786408d42b8ea48c18c26b3a89d9524fd651b89993db12f3ccfff6635d7981a557416aa8656696d42e6f58fe593d6845b88334ac languageName: node linkType: hard -"@vaadin/vaadin-themable-mixin@npm:24.0.8, @vaadin/vaadin-themable-mixin@npm:~24.0.8": - version: 24.0.8 - resolution: "@vaadin/vaadin-themable-mixin@npm:24.0.8" +"@vaadin/vaadin-themable-mixin@npm:24.1.0, @vaadin/vaadin-themable-mixin@npm:~24.1.0": + version: 24.1.0 + resolution: "@vaadin/vaadin-themable-mixin@npm:24.1.0" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 lit: ^2.0.0 - checksum: 5ffcacd49f2f42e01fee55033375ebcf46e93abcb2c7df02b460b635dfb3d7bef5629e7fdafb0813027a4239d6e11ff1ddca31f9281abf5a5f08db8c5418807d + checksum: 0abe57312bdda606b52ce93843e82628310e419cbfe4c8bd564c574f7883c8979861b1eb34982bab4a488a82a467dd80cd482e018154ce343310b2918146808d languageName: node linkType: hard @@ -9742,8 +9758,8 @@ __metadata: "@types/webspeechapi": 0.0.29 "@typescript-eslint/eslint-plugin": 5.59.11 "@typescript-eslint/parser": 5.59.11 - "@vaadin/combo-box": 24.0.8 - "@vaadin/vaadin-themable-mixin": 24.0.8 + "@vaadin/combo-box": 24.1.0 + "@vaadin/vaadin-themable-mixin": 24.1.0 "@vibrant/color": 3.2.1-alpha.1 "@vibrant/core": 3.2.1-alpha.1 "@vibrant/quantizer-mmcq": 3.2.1-alpha.1 From 2a4356ce868c51017653331def6777ffc48ce677 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 20:33:36 -0400 Subject: [PATCH 044/162] Update dependency tinykeys to v2.1.0 (#16951) --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 4887816443..ae712fa839 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "rrule": "2.7.2", "sortablejs": "1.15.0", "superstruct": "1.0.3", - "tinykeys": "2.0.0", + "tinykeys": "2.1.0", "tsparticles-engine": "2.9.3", "tsparticles-preset-links": "2.9.3", "unfetch": "5.0.0", diff --git a/yarn.lock b/yarn.lock index 6e34f8320e..7877b99df7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9849,7 +9849,7 @@ __metadata: systemjs: 6.14.1 tar: 6.1.15 terser-webpack-plugin: 5.3.9 - tinykeys: 2.0.0 + tinykeys: 2.1.0 ts-lit-plugin: 1.2.1 tsparticles-engine: 2.9.3 tsparticles-preset-links: 2.9.3 @@ -15233,10 +15233,10 @@ __metadata: languageName: node linkType: hard -"tinykeys@npm:2.0.0": - version: 2.0.0 - resolution: "tinykeys@npm:2.0.0" - checksum: 2f81ce9660b27e3ea664c5afc3af89860254989bb194834b530f5ccad389fef2ddbdac8e6b4de8628c0f8e5b50957032d11a27232fc6666472212513c279a9c1 +"tinykeys@npm:2.1.0": + version: 2.1.0 + resolution: "tinykeys@npm:2.1.0" + checksum: 49e8f7cf09c29372758f434d072429ed5a93cd3148d218af9938ccbbac4e15a2697c93a34dcfe7138a11e569a2145b35709947e5d2b74e48a8e17c575b8beb7f languageName: node linkType: hard From 79c010eb7b87a1975cbb16a4f712fca79bb26d97 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 20:34:43 -0400 Subject: [PATCH 045/162] Update dependency webpack to v5.87.0 (#16949) --- package.json | 2 +- yarn.lock | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index ae712fa839..b8c9fbd898 100644 --- a/package.json +++ b/package.json @@ -239,7 +239,7 @@ "typescript": "4.9.5", "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", - "webpack": "5.86.0", + "webpack": "5.87.0", "webpack-cli": "5.1.4", "webpack-dev-server": "4.15.1", "webpack-manifest-plugin": "5.0.0", diff --git a/yarn.lock b/yarn.lock index 7877b99df7..630919a181 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7766,13 +7766,13 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.14.1": - version: 5.14.1 - resolution: "enhanced-resolve@npm:5.14.1" +"enhanced-resolve@npm:^5.15.0": + version: 5.15.0 + resolution: "enhanced-resolve@npm:5.15.0" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: ad2a31928b6649eed40d364838449587f731baa63863e83d2629bebaa8be1eabac18b90f89c1784bc805b0818363e99b22547159edd485d7e5ccf18cdc640642 + checksum: fbd8cdc9263be71cc737aa8a7d6c57b43d6aa38f6cc75dde6fcd3598a130cc465f979d2f4d01bb3bf475acb43817749c79f8eef9be048683602ca91ab52e4f11 languageName: node linkType: hard @@ -9861,7 +9861,7 @@ __metadata: vis-network: 9.1.6 vue: 2.7.14 vue2-daterange-picker: 0.6.8 - webpack: 5.86.0 + webpack: 5.87.0 webpack-cli: 5.1.4 webpack-dev-server: 4.15.1 webpack-manifest-plugin: 5.0.0 @@ -14117,14 +14117,14 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.1.1, schema-utils@npm:^3.1.2": - version: 3.1.2 - resolution: "schema-utils@npm:3.1.2" +"schema-utils@npm:^3.1.1, schema-utils@npm:^3.2.0": + version: 3.3.0 + resolution: "schema-utils@npm:3.3.0" dependencies: "@types/json-schema": ^7.0.8 ajv: ^6.12.5 ajv-keywords: ^3.5.2 - checksum: 39683edfe3beff018cdb1ae4fa296fc55cea13a080aa2b4d9351895cd64b22ba4d87e2e548c2a2ac1bc76e60980670adb0f413a58104479f1a0c12e5663cb8ca + checksum: ea56971926fac2487f0757da939a871388891bc87c6a82220d125d587b388f1704788f3706e7f63a7b70e49fc2db974c41343528caea60444afd5ce0fe4b85c0 languageName: node linkType: hard @@ -16287,9 +16287,9 @@ __metadata: languageName: node linkType: hard -"webpack@npm:5.86.0": - version: 5.86.0 - resolution: "webpack@npm:5.86.0" +"webpack@npm:5.87.0": + version: 5.87.0 + resolution: "webpack@npm:5.87.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -16300,7 +16300,7 @@ __metadata: acorn-import-assertions: ^1.9.0 browserslist: ^4.14.5 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^5.14.1 + enhanced-resolve: ^5.15.0 es-module-lexer: ^1.2.1 eslint-scope: 5.1.1 events: ^3.2.0 @@ -16310,7 +16310,7 @@ __metadata: loader-runner: ^4.2.0 mime-types: ^2.1.27 neo-async: ^2.6.2 - schema-utils: ^3.1.2 + schema-utils: ^3.2.0 tapable: ^2.1.1 terser-webpack-plugin: ^5.3.7 watchpack: ^2.4.0 @@ -16320,7 +16320,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: 682b1aa8328bb9d52ae66a1d0a1078af88f9e3b3b3a9c9e1ce203e669581a8e61d522420ef253130eacd510d24d7275b840c1311d50bd048d6fd7c1af186ce55 + checksum: b7d0e390f9d30627e303d54b17cb87b62f49ecffe2d35481f830679904993bae208e23748ffe0e6091b6dd4810562b2f2e88bb0f23b96515d74fb1e3c2898210 languageName: node linkType: hard From 2b51228665b7247d4b4ea6d3ff0c2919fd30c2a6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 17 Jun 2023 19:41:41 -0500 Subject: [PATCH 046/162] Fix notifications subscription leak when in narrow mode (#16953) Fix persistent notifications subscription leak on mobile/narrow --- src/components/ha-menu-button.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/ha-menu-button.ts b/src/components/ha-menu-button.ts index b51dd78800..3bb80a0e04 100644 --- a/src/components/ha-menu-button.ts +++ b/src/components/ha-menu-button.ts @@ -74,11 +74,16 @@ class HaMenuButton extends LitElement { } const oldHass = changedProps.get("hass") as HomeAssistant | undefined; - const oldNarrow = - changedProps.get("narrow") || - (oldHass && oldHass.dockedSidebar === "always_hidden"); - const newNarrow = - this.narrow || this.hass.dockedSidebar === "always_hidden"; + + let oldNarrow: boolean | undefined; + let newNarrow: boolean | undefined; + if (changedProps.has("narrow")) { + oldNarrow = changedProps.get("narrow"); + newNarrow = this.narrow; + } else if (oldHass) { + oldNarrow = oldHass.dockedSidebar === "always_hidden"; + newNarrow = this.hass.dockedSidebar === "always_hidden"; + } if (oldNarrow === newNarrow) { return; @@ -98,6 +103,9 @@ class HaMenuButton extends LitElement { } private _subscribeNotifications() { + if (this._unsubNotifications) { + throw new Error("Already subscribed"); + } this._unsubNotifications = subscribeNotifications( this.hass.connection, (notifications) => { From cac341a938887f144453f2ff9f8cefbc35f6cbb4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 18 Jun 2023 23:31:13 -0400 Subject: [PATCH 047/162] Update dependency hls.js to v1.4.6 (#16960) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index b8c9fbd898..e70d2f55ee 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "deep-freeze": "0.0.1", "fuse.js": "6.6.2", "google-timezones-json": "1.1.0", - "hls.js": "1.4.5", + "hls.js": "1.4.6", "home-assistant-js-websocket": "8.0.1", "idb-keyval": "6.2.1", "intl-messageformat": "10.5.0", diff --git a/yarn.lock b/yarn.lock index 630919a181..14667d96b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9646,10 +9646,10 @@ __metadata: languageName: node linkType: hard -"hls.js@npm:1.4.5": - version: 1.4.5 - resolution: "hls.js@npm:1.4.5" - checksum: 7d01e17e5a434e3d6c8579b8d8340bfb4d7affb2f4015c02894466f0ce2719dc4c7e6f8953fb5a38642795e838d06c58d71ced579948e712d58e434001b69320 +"hls.js@npm:1.4.6": + version: 1.4.6 + resolution: "hls.js@npm:1.4.6" + checksum: 7a44107c92e52859bfd5a37b6ea647cfea20848466286c1280b2cf956cfaccf8131fa54867cd8edfb60042a238025fb8788263fd9dfb9d1798ddbdc08f5aab50 languageName: node linkType: hard @@ -9804,7 +9804,7 @@ __metadata: gulp-merge-json: 2.1.2 gulp-rename: 2.0.0 gulp-zopfli-green: 6.0.1 - hls.js: 1.4.5 + hls.js: 1.4.6 home-assistant-js-websocket: 8.0.1 html-minifier-terser: 7.2.0 husky: 8.0.3 From 827d89628d2f06447179c0390477892f82bfbbfd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 18 Jun 2023 23:52:23 -0400 Subject: [PATCH 048/162] Update dependency tsparticles-engine to v2.10.1 (#16790) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e70d2f55ee..3fe080c2cd 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "sortablejs": "1.15.0", "superstruct": "1.0.3", "tinykeys": "2.1.0", - "tsparticles-engine": "2.9.3", + "tsparticles-engine": "2.10.1", "tsparticles-preset-links": "2.9.3", "unfetch": "5.0.0", "vis-data": "7.1.6", diff --git a/yarn.lock b/yarn.lock index 14667d96b1..61d01b77fe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9851,7 +9851,7 @@ __metadata: terser-webpack-plugin: 5.3.9 tinykeys: 2.1.0 ts-lit-plugin: 1.2.1 - tsparticles-engine: 2.9.3 + tsparticles-engine: 2.10.1 tsparticles-preset-links: 2.9.3 typescript: 4.9.5 unfetch: 5.0.0 @@ -15397,10 +15397,10 @@ __metadata: languageName: node linkType: hard -"tsparticles-engine@npm:2.9.3, tsparticles-engine@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-engine@npm:2.9.3" - checksum: 767b6c1568f9428706e62bd15fe91f290fd1a86e9641f00d848006165e829d414e954b95833a4360f2b0a9a2699fa6d340bb007cce22412b48b7692d4a6489f5 +"tsparticles-engine@npm:2.10.1, tsparticles-engine@npm:^2.9.3": + version: 2.10.1 + resolution: "tsparticles-engine@npm:2.10.1" + checksum: 5662c453b1e4c37c608435393a8c5ae03bd9b301dc488a3909bdddf321f38c486b6076d61641add3e2d8764c6e8eb28021e1b424da3240b6efa723c6e8bcbc43 languageName: node linkType: hard From 8e9b5ea66b2fbaac060e13944a6c3bf24d1f7730 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 05:10:21 +0000 Subject: [PATCH 049/162] Update dependency tsparticles-preset-links to v2.10.1 (#16802) * Update dependency tsparticles-preset-links to v2.10.1 * Group future tsparticles updates --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Steve Repsher --- package.json | 2 +- renovate.json | 10 ++++-- yarn.lock | 98 +++++++++++++++++++++++++-------------------------- 3 files changed, 58 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 3fe080c2cd..43c1f40927 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "superstruct": "1.0.3", "tinykeys": "2.1.0", "tsparticles-engine": "2.10.1", - "tsparticles-preset-links": "2.9.3", + "tsparticles-preset-links": "2.10.1", "unfetch": "5.0.0", "vis-data": "7.1.6", "vis-network": "9.1.6", diff --git a/renovate.json b/renovate.json index 895cfc3667..291e6a4a26 100644 --- a/renovate.json +++ b/renovate.json @@ -19,14 +19,20 @@ }, "packageRules": [ { - "description": ["MDC packages are pinned to the same version as MWC"], + "description": "MDC packages are pinned to the same version as MWC", "extends": ["monorepo:material-components-web"], "enabled": false }, { - "description": ["Vue is only used by date range which is only v2"], + "description": "Vue is only used by date range which is only v2", "matchPackageNames": ["vue"], "allowedVersions": "< 3" + }, + { + "description": "Group tsparticles engine and presets", + "groupName": "tsparticles", + "matchPackageNames": ["tsparticles-engine"], + "matchPackagePrefixes": ["tsparticles-preset-"] } ] } diff --git a/yarn.lock b/yarn.lock index 61d01b77fe..666b70044f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9852,7 +9852,7 @@ __metadata: tinykeys: 2.1.0 ts-lit-plugin: 1.2.1 tsparticles-engine: 2.10.1 - tsparticles-preset-links: 2.9.3 + tsparticles-preset-links: 2.10.1 typescript: 4.9.5 unfetch: 5.0.0 vinyl-buffer: 1.0.1 @@ -15397,89 +15397,89 @@ __metadata: languageName: node linkType: hard -"tsparticles-engine@npm:2.10.1, tsparticles-engine@npm:^2.9.3": +"tsparticles-engine@npm:2.10.1, tsparticles-engine@npm:^2.10.1": version: 2.10.1 resolution: "tsparticles-engine@npm:2.10.1" checksum: 5662c453b1e4c37c608435393a8c5ae03bd9b301dc488a3909bdddf321f38c486b6076d61641add3e2d8764c6e8eb28021e1b424da3240b6efa723c6e8bcbc43 languageName: node linkType: hard -"tsparticles-interaction-particles-links@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-interaction-particles-links@npm:2.9.3" +"tsparticles-interaction-particles-links@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-interaction-particles-links@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: be551275a6fd4bb543b4a5eb5105df8f53aed799527e9e032ab282f383367a90b002e8d134432bd8828ef0c06ddd4c826a1bcc158335bf81e83c39b042358322 + tsparticles-engine: ^2.10.1 + checksum: 994fcac1cfcae34409095437db7684cc9f74b4e084995da310ea7f1a63c0a97030cac8fde47a7a54b5e8644e26a3b72fb5e6d229e10758eb1e6fcf52800b8e83 languageName: node linkType: hard -"tsparticles-move-base@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-move-base@npm:2.9.3" +"tsparticles-move-base@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-move-base@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: 06b579ce3873daa8f706261c28c0fb5b9b60bf9682da6eb0ca4488e60b06e08d122b9e20613a65db2e7b4c535728dc54a24fcc8942fa79935fd5d4315de44e11 + tsparticles-engine: ^2.10.1 + checksum: 26fb88e7622dfbede4d0177d01645917b01611bf8be32508588e7d8d6e28fcaf58daf900095a7947382d59fe9fcd420563cc6fc6a50c67c9c7ea7236c601d9b7 languageName: node linkType: hard -"tsparticles-preset-links@npm:2.9.3": - version: 2.9.3 - resolution: "tsparticles-preset-links@npm:2.9.3" +"tsparticles-preset-links@npm:2.10.1": + version: 2.10.1 + resolution: "tsparticles-preset-links@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - tsparticles-interaction-particles-links: ^2.9.3 - tsparticles-move-base: ^2.9.3 - tsparticles-shape-circle: ^2.9.3 - tsparticles-updater-color: ^2.9.3 - tsparticles-updater-opacity: ^2.9.3 - tsparticles-updater-out-modes: ^2.9.3 - tsparticles-updater-size: ^2.9.3 - checksum: fc867d5a7efc0d596a1cfe06159f8e872ff806eafd37a3b07d94537d0432c4839dab3b9c10797341a8526ca395c0e5cd4e91b551c3f4b55da298d2d6b5a938ce + tsparticles-engine: ^2.10.1 + tsparticles-interaction-particles-links: ^2.10.1 + tsparticles-move-base: ^2.10.1 + tsparticles-shape-circle: ^2.10.1 + tsparticles-updater-color: ^2.10.1 + tsparticles-updater-opacity: ^2.10.1 + tsparticles-updater-out-modes: ^2.10.1 + tsparticles-updater-size: ^2.10.1 + checksum: 0678ad77ae9022f3ceac6b462ad4e049e2a0f5559b035690698609df081d7d6307fb93c38d07f3fe6e0f517635bd6a4831b705b7ba6fc33f79a22d4a3ddf65fe languageName: node linkType: hard -"tsparticles-shape-circle@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-shape-circle@npm:2.9.3" +"tsparticles-shape-circle@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-shape-circle@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: f770e6edd10e1935402ef19b1f5c051758c3a1f1722b64dae4f215f178bb83211abe8abde26bc87c220db1969457bc7729a77f5e3fcd00e44e7103bc10a13336 + tsparticles-engine: ^2.10.1 + checksum: 49c2a865745c6217b08006c11f134e64792e1d62abbc1dc6f2484165b6b13b6bd7205cd10171418697680e513bd3c8d128c7d9877c61540722250bb8e1693f02 languageName: node linkType: hard -"tsparticles-updater-color@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-updater-color@npm:2.9.3" +"tsparticles-updater-color@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-updater-color@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: e602b4754c6bb11ec2475939131e4fff815b07dc0431f4df34b9fdd82567fd299f5648f61e323258126856a3b71f87e77e5cf97e3100fb3929204e53a726c01f + tsparticles-engine: ^2.10.1 + checksum: 6858b429fd59f244251584346d47748216774a9012a6ffb9a614f87ca83b957a6da2b0dffb1c9e5238c84c043c29a23eb828568baf4ddde76c73707a1a0652ba languageName: node linkType: hard -"tsparticles-updater-opacity@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-updater-opacity@npm:2.9.3" +"tsparticles-updater-opacity@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-updater-opacity@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: 4bc735e014219615256469fc05330140e7d5d43e85a91c8400045c812108f73b3549f7d50b92b985cf12264e81bb5cf0e2093e4ba16adcb0c420bb9e71dc801e + tsparticles-engine: ^2.10.1 + checksum: f5a418dfe922db99cd6ee75a7accb901eebb4e4f34ef411be46a1d88c8893816b4f8487f7b100a0a1cda749fdecf1d052efaae994a8639a464b6d6829ec9ee8b languageName: node linkType: hard -"tsparticles-updater-out-modes@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-updater-out-modes@npm:2.9.3" +"tsparticles-updater-out-modes@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-updater-out-modes@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: 2c695211254b39831987a465b35711899f7e13fc7512aac83b4019a948c22eab15c71ad61627cca34ea6b18b7370f88d5b5d07f743dab8d3ec3eb0b99b4ff684 + tsparticles-engine: ^2.10.1 + checksum: 0f78d2aae5fa03f1af32dbe9eab326d6ef59b4e63226a84a5f8ce91efb1beecd13e0465068de9c9cd70ba830c212552fbe3b01fd21c674368ba39071af335e9b languageName: node linkType: hard -"tsparticles-updater-size@npm:^2.9.3": - version: 2.9.3 - resolution: "tsparticles-updater-size@npm:2.9.3" +"tsparticles-updater-size@npm:^2.10.1": + version: 2.10.1 + resolution: "tsparticles-updater-size@npm:2.10.1" dependencies: - tsparticles-engine: ^2.9.3 - checksum: 13e0231a7469cd83ff74a20766980c8bce4480fc0e91841103431acf7df051e58ead2391f58947d03307bc20c6d3a0065c9a675f7c2f603b82fceffccc4e7c77 + tsparticles-engine: ^2.10.1 + checksum: c77ce515aa765f4e069d232ca7407105d86c432042593fffdd6ae33948f84a654cba7e41c0aef00c2327ed3b5715ab07e057153b93afe5c7a2a5917eee786e85 languageName: node linkType: hard From 195b1eef02380a56013d37f6810de7c648b4d34d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 05:26:18 +0000 Subject: [PATCH 050/162] Lock file maintenance (#16961) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 640 +++++++++++++++++++++--------------------------------- 1 file changed, 244 insertions(+), 396 deletions(-) diff --git a/yarn.lock b/yarn.lock index 666b70044f..0f0d787f5f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1781,13 +1781,6 @@ __metadata: languageName: node linkType: hard -"@gar/promisify@npm:^1.1.3": - version: 1.1.3 - resolution: "@gar/promisify@npm:1.1.3" - checksum: 4059f790e2d07bf3c3ff3e0fec0daa8144fe35c1f6e0111c9921bd32106adaa97a4ab096ad7dab1e28ee6a9060083c4d1a4ada42a7f5f3f7a96b8812e2b757c1 - languageName: node - linkType: hard - "@gfx/zopfli@npm:^1.0.15": version: 1.0.15 resolution: "@gfx/zopfli@npm:1.0.15" @@ -1994,7 +1987,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/source-map@npm:^0.3.2": +"@jridgewell/source-map@npm:^0.3.3": version: 0.3.3 resolution: "@jridgewell/source-map@npm:0.3.3" dependencies: @@ -2045,9 +2038,9 @@ __metadata: linkType: hard "@lezer/common@npm:^1.0.0": - version: 1.0.2 - resolution: "@lezer/common@npm:1.0.2" - checksum: bbcc58e07be02652bf0700d2856042ec089d5be0b95893d628b3e18192ade864fac83b61b19653e10b9f1472261a178b12318d934e9004edd5483a577c0db56b + version: 1.0.3 + resolution: "@lezer/common@npm:1.0.3" + checksum: cc90dc2f0aeaebeb3fe886cbd27f8b1e8bee817d8c2efff178604807debd68c5db820fd23afb830962780063d21891afbdf564420221faca2822e77bc6327184 languageName: node linkType: hard @@ -2061,11 +2054,11 @@ __metadata: linkType: hard "@lezer/lr@npm:^1.0.0": - version: 1.3.4 - resolution: "@lezer/lr@npm:1.3.4" + version: 1.3.6 + resolution: "@lezer/lr@npm:1.3.6" dependencies: "@lezer/common": ^1.0.0 - checksum: 58bc25a9ba891dc6ca713fc8768706935e65d6e54d79a8ddb40c742cc799e87eddf4f49a6d6566a649c4726a9ab79a4200d36c9351608285a9bee6cdf3b33341 + checksum: b2bbcfecc01bd9c801f3ee636ceda333adbbea1f274017cec6f315a23346e7a035a984f325d4f1cd14b157d74d28badda6f794514c29a0b078f7fb3357cdfc32 languageName: node linkType: hard @@ -2106,11 +2099,11 @@ __metadata: linkType: hard "@lit/reactive-element@npm:^1.3.0, @lit/reactive-element@npm:^1.5.0, @lit/reactive-element@npm:^1.6.0": - version: 1.6.1 - resolution: "@lit/reactive-element@npm:1.6.1" + version: 1.6.2 + resolution: "@lit/reactive-element@npm:1.6.2" dependencies: "@lit-labs/ssr-dom-shim": ^1.0.0 - checksum: fab0bcfdade9c26af2ad5115fb564bcf8ba0732a3a8be86c157851c2771e3fdc65ab38f2cd60fa121946058bf6e487461fd217f87b01f96e88ee7a95d5d866ba + checksum: 011a3ef0933fda86ec726d29ebc14e829e2f1ba23eca8ed8ed4d5c6f2a102c55cc6986000c5f4c8c3d0c549bc671f5d84d00ce91adc5bbd95970eec3662c0a92 languageName: node linkType: hard @@ -3217,23 +3210,12 @@ __metadata: languageName: node linkType: hard -"@npmcli/fs@npm:^2.1.0": - version: 2.1.2 - resolution: "@npmcli/fs@npm:2.1.2" +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" dependencies: - "@gar/promisify": ^1.1.3 semver: ^7.3.5 - checksum: 405074965e72d4c9d728931b64d2d38e6ea12066d4fad651ac253d175e413c06fe4350970c783db0d749181da8fe49c42d3880bd1cbc12cd68e3a7964d820225 - languageName: node - linkType: hard - -"@npmcli/move-file@npm:^2.0.0": - version: 2.0.1 - resolution: "@npmcli/move-file@npm:2.0.1" - dependencies: - mkdirp: ^1.0.4 - rimraf: ^3.0.2 - checksum: 52dc02259d98da517fae4cb3a0a3850227bdae4939dda1980b788a7670636ca2b4a01b58df03dd5f65c1e3cb70c50fa8ce5762b582b3f499ec30ee5ce1fd9380 + checksum: a50a6818de5fc557d0b0e6f50ec780a7a02ab8ad07e5ac8b16bf519e0ad60a144ac64f97d05c443c3367235d337182e1d012bbac0eb8dbae8dc7b40b193efd0e languageName: node linkType: hard @@ -3250,17 +3232,15 @@ __metadata: linkType: hard "@octokit/auth-token@npm:^3.0.0": - version: 3.0.3 - resolution: "@octokit/auth-token@npm:3.0.3" - dependencies: - "@octokit/types": ^9.0.0 - checksum: 9b3f569cec1b7e0aa88ab6da68aed4b49b6652261bd957257541fabaf6a4d4ed99f908153cc3dd2fe15b8b0ccaff8caaafaa50bb1a4de3925b0954a47cca1900 + version: 3.0.4 + resolution: "@octokit/auth-token@npm:3.0.4" + checksum: 42f533a873d4192e6df406b3176141c1f95287423ebdc4cf23a38bb77ee00ccbc0e60e3fbd5874234fc2ed2e67bbc6035e3b0561dacc1d078adb5c4ced3579e3 languageName: node linkType: hard "@octokit/core@npm:^4.2.1": - version: 4.2.1 - resolution: "@octokit/core@npm:4.2.1" + version: 4.2.4 + resolution: "@octokit/core@npm:4.2.4" dependencies: "@octokit/auth-token": ^3.0.0 "@octokit/graphql": ^5.0.0 @@ -3269,29 +3249,29 @@ __metadata: "@octokit/types": ^9.0.0 before-after-hook: ^2.2.0 universal-user-agent: ^6.0.0 - checksum: f82d52e937e12da1c7c163341c845b8e27e7fa75678f5e5954e6fa017a94f1833d6e5c4e43f0be796fbfea9dc5e1137087f655dbd5acb3d57879e1b28568e0a9 + checksum: ac8ab47440a31b0228a034aacac6994b64d6b073ad5b688b4c5157fc5ee0d1af1c926e6087bf17fd7244ee9c5998839da89065a90819bde4a97cb77d4edf58a6 languageName: node linkType: hard "@octokit/endpoint@npm:^7.0.0": - version: 7.0.5 - resolution: "@octokit/endpoint@npm:7.0.5" + version: 7.0.6 + resolution: "@octokit/endpoint@npm:7.0.6" dependencies: "@octokit/types": ^9.0.0 is-plain-object: ^5.0.0 universal-user-agent: ^6.0.0 - checksum: 81c9e9eabf50e48940cceff7c4d7fbc9327190296507cfe8a199ea00cd492caf8f18a841caf4e3619828924b481996eb16091826db6b5a649bee44c8718ecaa9 + checksum: 7caebf30ceec50eb7f253341ed419df355232f03d4638a95c178ee96620400db7e4a5e15d89773fe14db19b8653d4ab4cc81b2e93ca0c760b4e0f7eb7ad80301 languageName: node linkType: hard "@octokit/graphql@npm:^5.0.0": - version: 5.0.5 - resolution: "@octokit/graphql@npm:5.0.5" + version: 5.0.6 + resolution: "@octokit/graphql@npm:5.0.6" dependencies: "@octokit/request": ^6.0.0 "@octokit/types": ^9.0.0 universal-user-agent: ^6.0.0 - checksum: eb2d1a6305a3d1f55ff0ce92fb88b677f0bb789757152d58a79ef61171fb65ecf6fe18d6c27e236c0cee6a0c2600c2cb8370f5ac7184f8e9361c085aa4555bb1 + checksum: 7be545d348ef31dcab0a2478dd64d5746419a2f82f61459c774602bcf8a9b577989c18001f50b03f5f61a3d9e34203bdc021a4e4d75ff2d981e8c9c09cf8a65c languageName: node linkType: hard @@ -3303,22 +3283,15 @@ __metadata: linkType: hard "@octokit/oauth-methods@npm:^2.0.0": - version: 2.0.5 - resolution: "@octokit/oauth-methods@npm:2.0.5" + version: 2.0.6 + resolution: "@octokit/oauth-methods@npm:2.0.6" dependencies: "@octokit/oauth-authorization-url": ^5.0.0 "@octokit/request": ^6.2.3 "@octokit/request-error": ^3.0.3 "@octokit/types": ^9.0.0 btoa-lite: ^1.0.0 - checksum: dda36fdc85f1b9a4322e47d88b13183f86fd7e03e66e787ced7be41ea4a1a64f610e2d1a75f82c7ec7ff5c4a76e07a696c2e7232bf944f04fe64aac5c26bd484 - languageName: node - linkType: hard - -"@octokit/openapi-types@npm:^17.2.0": - version: 17.2.0 - resolution: "@octokit/openapi-types@npm:17.2.0" - checksum: 29995e34f98d9d64ba234d64a7ae9486c66d2bb6ac0d30d9a42decdbb4b03b13e811769b1e1505a1748ff20c22d35724985e6c128cd11a3f14f8322201520093 + checksum: 151b933d79d6fbf36fdfae8cdc868a3d43316352eaccf46cb8c420cfd238658275e41996d2d377177553bc0c637c3aefe8ca99c1ab7fd62054654b6119b7b1cc languageName: node linkType: hard @@ -3351,14 +3324,13 @@ __metadata: linkType: hard "@octokit/plugin-rest-endpoint-methods@npm:^7.1.2": - version: 7.1.2 - resolution: "@octokit/plugin-rest-endpoint-methods@npm:7.1.2" + version: 7.2.3 + resolution: "@octokit/plugin-rest-endpoint-methods@npm:7.2.3" dependencies: - "@octokit/types": ^9.2.3 - deprecation: ^2.3.1 + "@octokit/types": ^10.0.0 peerDependencies: "@octokit/core": ">=3" - checksum: 159d29bf28d7aecbe39f08c25cf376d39b6c90ce17e50a55eafb44f3e4b9e1053a300c1edd72f308ae386146a17cbad46c410c1cfd000b048adf9c21d6922a1a + checksum: 21dfb98514dbe900c29cddb13b335bbce43d613800c6b17eba3c1fd31d17e69c1960f3067f7bf864bb38fdd5043391f4a23edee42729d8c7fbabd00569a80336 languageName: node linkType: hard @@ -3398,8 +3370,8 @@ __metadata: linkType: hard "@octokit/request@npm:^6.0.0, @octokit/request@npm:^6.2.3": - version: 6.2.5 - resolution: "@octokit/request@npm:6.2.5" + version: 6.2.8 + resolution: "@octokit/request@npm:6.2.8" dependencies: "@octokit/endpoint": ^7.0.0 "@octokit/request-error": ^3.0.0 @@ -3407,7 +3379,7 @@ __metadata: is-plain-object: ^5.0.0 node-fetch: ^2.6.7 universal-user-agent: ^6.0.0 - checksum: 856451ea8cc6b1dd0f6e350a141e65c318b5e3a25b8dea373d3afd115f9a3077535a0330f5d90e9db81dc3234dba1dd64edd31e68f639553baa10b4d02b99498 + checksum: 3747106f50d7c462131ff995b13defdd78024b7becc40283f4ac9ea0af2391ff33a0bb476a05aa710346fe766d20254979079a1d6f626112015ba271fe38f3e2 languageName: node linkType: hard @@ -3440,18 +3412,18 @@ __metadata: linkType: hard "@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.2.3": - version: 9.2.3 - resolution: "@octokit/types@npm:9.2.3" + version: 9.3.2 + resolution: "@octokit/types@npm:9.3.2" dependencies: - "@octokit/openapi-types": ^17.2.0 - checksum: 6806413089f20a8302237ef85aa2e83bace7499e95fdc3db2d304f9e6dc6e87fb6766452f92e08ddf475046b69753e11beabaeff6733c38bdaf3e21dfd7d3341 + "@octokit/openapi-types": ^18.0.0 + checksum: f55d096aaed3e04b8308d4422104fb888f355988056ba7b7ef0a4c397b8a3e54290d7827b06774dbe0c9ce55280b00db486286954f9c265aa6b03091026d9da8 languageName: node linkType: hard "@open-wc/dedupe-mixin@npm:^1.3.0": - version: 1.3.1 - resolution: "@open-wc/dedupe-mixin@npm:1.3.1" - checksum: f0771906242cfd506531f3de65d44dbb069b0b61388612f91ad16b91838d216347d71144e4718dfaf9890a33ab0c7b625b0e6d979e09a288f81acb09f239f55d + version: 1.4.0 + resolution: "@open-wc/dedupe-mixin@npm:1.4.0" + checksum: 25ae5d1c76ffecec74cb38948ee093e8b9fcfdde274ad176e288070370c4fe8182880d50e42b0403ac5449f12a9ebfa508df42772b15910c19177a0a63f47010 languageName: node linkType: hard @@ -4058,11 +4030,11 @@ __metadata: linkType: hard "@sinonjs/fake-timers@npm:^10.0.2, @sinonjs/fake-timers@npm:^10.1.0": - version: 10.2.0 - resolution: "@sinonjs/fake-timers@npm:10.2.0" + version: 10.1.0 + resolution: "@sinonjs/fake-timers@npm:10.1.0" dependencies: "@sinonjs/commons": ^3.0.0 - checksum: 586c76e1dd90d03b0c4e754f2011325b38ac6055878c81c52434c900f36d9d245438c96ef69e08e28d9fbecf2335fb347b67850962d8b6e539dd7359d8c62802 + checksum: f8f7e23a136e32ba0128493207e4223f453e033471257a971acb43840927e738a0838004b1e4fa046279609762a2dd8d700606616e9264dc3891c4f8d45889a2 languageName: node linkType: hard @@ -4156,12 +4128,12 @@ __metadata: linkType: hard "@types/chrome@npm:*": - version: 0.0.236 - resolution: "@types/chrome@npm:0.0.236" + version: 0.0.237 + resolution: "@types/chrome@npm:0.0.237" dependencies: "@types/filesystem": "*" "@types/har-format": "*" - checksum: 64cc6f8ac5c23f5dc6a3e1137721dda52e6401b1e1a8f9d16bfca7236bd5a118be6746324fd9e33630d98863370137ff0749b9949ededb9f46accb187f333896 + checksum: 9dfb0070065ca4667ef2fa9ec45af2f604b9ba98b6429d38607c6bfcc8dc2178e83eea4eeedbe88a8299dfe9dda029c9341e454c4eff7b715b90e9d5fc7b990d languageName: node linkType: hard @@ -4237,12 +4209,12 @@ __metadata: linkType: hard "@types/eslint@npm:*": - version: 8.37.0 - resolution: "@types/eslint@npm:8.37.0" + version: 8.40.2 + resolution: "@types/eslint@npm:8.40.2" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: 06d3b3fba12004294591b5c7a52e3cec439472195da54e096076b1f2ddfbb8a445973b9681046dd530a6ac31eca502f635abc1e3ce37d03513089358e6f822ee + checksum: a4780e45e677e3af21c44a900846996cb6d9ae8f71d51940942a047163ae93a05444392c005f491ed46aa169f3b25f8be125ab42c5d8bdb571154bf62a7c828a languageName: node linkType: hard @@ -4334,9 +4306,9 @@ __metadata: linkType: hard "@types/har-format@npm:*": - version: 1.2.10 - resolution: "@types/har-format@npm:1.2.10" - checksum: 14c0118d809e77a0bac9deec0a87159c28beab21105cfce3aa291b51e28d4c07142851c4e6b93b7ecb4ea237fe07d39ba98a42bb2de2f5891144733411ac76b7 + version: 1.2.11 + resolution: "@types/har-format@npm:1.2.11" + checksum: f36add1ac253c99b594231783cc9ca75b6226df60ba2924351dcad4d0fcd0d7e62188c530a981b4dad8c2a9fcf10ea312f8c75ebc7ddbfae7e1a979635b04780 languageName: node linkType: hard @@ -4378,9 +4350,9 @@ __metadata: linkType: hard "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": - version: 7.0.11 - resolution: "@types/json-schema@npm:7.0.11" - checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d + version: 7.0.12 + resolution: "@types/json-schema@npm:7.0.12" + checksum: 00239e97234eeb5ceefb0c1875d98ade6e922bfec39dd365ec6bd360b5c2f825e612ac4f6e5f1d13601b8b30f378f15e6faa805a3a732f4a1bbe61915163d293 languageName: node linkType: hard @@ -4451,9 +4423,9 @@ __metadata: linkType: hard "@types/lodash@npm:*": - version: 4.14.194 - resolution: "@types/lodash@npm:4.14.194" - checksum: 113f34831c461469d91feca2dde737f88487732898b4d25e9eb23b087bb193985f864d1e1e0f3b777edc5022e460443588b6000a3b2348c966f72d17eedc35ea + version: 4.14.195 + resolution: "@types/lodash@npm:4.14.195" + checksum: 39b75ca635b3fa943d17d3d3aabc750babe4c8212485a4df166fe0516e39288e14b0c60afc6e21913cc0e5a84734633c71e617e2bd14eaa1cf51b8d7799c432e languageName: node linkType: hard @@ -4493,9 +4465,9 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 20.2.1 - resolution: "@types/node@npm:20.2.1" - checksum: ed774afa6e9b4ad7868ed0182a8ca40ad0dd54815a70d3051b23fa850f3bca6bea4d0cb55e1fc769666786ac2cc4c1b37aeade313cb4c4634133f18ebcded496 + version: 20.3.1 + resolution: "@types/node@npm:20.3.1" + checksum: 63a393ab6d947be17320817b35d7277ef03728e231558166ed07ee30b09fd7c08861be4d746f10fdc63ca7912e8cd023939d4eab887ff6580ff704ff24ed810c languageName: node linkType: hard @@ -5458,12 +5430,12 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.5.0, acorn@npm:^8.7.1, acorn@npm:^8.8.0": - version: 8.8.2 - resolution: "acorn@npm:8.8.2" +"acorn@npm:^8.5.0, acorn@npm:^8.7.1, acorn@npm:^8.8.0, acorn@npm:^8.8.2": + version: 8.9.0 + resolution: "acorn@npm:8.9.0" bin: acorn: bin/acorn - checksum: f790b99a1bf63ef160c967e23c46feea7787e531292bb827126334612c234ed489a0dc2c7ba33156416f0ffa8d25bf2b0fdb7f35c2ba60eb3e960572bece4001 + checksum: 25dfb94952386ecfb847e61934de04a4e7c2dc21c2e700fc4e2ef27ce78cb717700c4c4f279cd630bb4774948633c3859fc16063ec8573bda4568e0a312e6744 languageName: node linkType: hard @@ -5766,11 +5738,11 @@ __metadata: linkType: hard "aria-query@npm:^5.1.3": - version: 5.1.3 - resolution: "aria-query@npm:5.1.3" + version: 5.2.1 + resolution: "aria-query@npm:5.2.1" dependencies: - deep-equal: ^2.0.5 - checksum: 929ff95f02857b650fb4cbcd2f41072eee2f46159a6605ea03bf63aa572e35ffdff43d69e815ddc462e16e07de8faba3978afc2813650b4448ee18c9895d982b + dequal: ^2.0.3 + checksum: fdb7a337d97acf4dae831e4c2c786233aca5ccb779a02c10fe65a65af9849f6e9868073593313ab52b7b0d9817e05cfb22a5cd43ecf22a8e7f2abea2268bdac9 languageName: node linkType: hard @@ -6073,9 +6045,9 @@ __metadata: linkType: hard "axe-core@npm:^4.3.3": - version: 4.7.1 - resolution: "axe-core@npm:4.7.1" - checksum: ff6fb92d6cadb749977af72b7d28009dec2b1842d4fdc4114a295ce973a39d0ac477e541be360eb9482a8d63f55840196813d7d892c0bd8437f52d9f7349c788 + version: 4.7.2 + resolution: "axe-core@npm:4.7.2" + checksum: 5d86fa0f45213b0e54cbb5d713ce885c4a8fe3a72b92dd915a47aa396d6fd149c4a87fec53aa978511f6d941402256cfeb26f2db35129e370f25a453c688655a languageName: node linkType: hard @@ -6362,16 +6334,16 @@ __metadata: linkType: hard "browserslist@npm:^4.14.5, browserslist@npm:^4.21.3, browserslist@npm:^4.21.5": - version: 4.21.5 - resolution: "browserslist@npm:4.21.5" + version: 4.21.9 + resolution: "browserslist@npm:4.21.9" dependencies: - caniuse-lite: ^1.0.30001449 - electron-to-chromium: ^1.4.284 - node-releases: ^2.0.8 - update-browserslist-db: ^1.0.10 + caniuse-lite: ^1.0.30001503 + electron-to-chromium: ^1.4.431 + node-releases: ^2.0.12 + update-browserslist-db: ^1.0.11 bin: browserslist: cli.js - checksum: 9755986b22e73a6a1497fd8797aedd88e04270be33ce66ed5d85a1c8a798292a65e222b0f251bafa1c2522261e237d73b08b58689d4920a607e5a53d56dc4706 + checksum: 80d3820584e211484ad1b1a5cfdeca1dd00442f47be87e117e1dda34b628c87e18b81ae7986fa5977b3e6a03154f6d13cd763baa6b8bf5dd9dd19f4926603698 languageName: node linkType: hard @@ -6443,29 +6415,23 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^16.1.0": - version: 16.1.3 - resolution: "cacache@npm:16.1.3" +"cacache@npm:^17.0.0": + version: 17.1.3 + resolution: "cacache@npm:17.1.3" dependencies: - "@npmcli/fs": ^2.1.0 - "@npmcli/move-file": ^2.0.0 - chownr: ^2.0.0 - fs-minipass: ^2.1.0 - glob: ^8.0.1 - infer-owner: ^1.0.4 + "@npmcli/fs": ^3.1.0 + fs-minipass: ^3.0.0 + glob: ^10.2.2 lru-cache: ^7.7.1 - minipass: ^3.1.6 + minipass: ^5.0.0 minipass-collect: ^1.0.2 minipass-flush: ^1.0.5 minipass-pipeline: ^1.2.4 - mkdirp: ^1.0.4 p-map: ^4.0.0 - promise-inflight: ^1.0.1 - rimraf: ^3.0.2 - ssri: ^9.0.0 + ssri: ^10.0.0 tar: ^6.1.11 - unique-filename: ^2.0.0 - checksum: d91409e6e57d7d9a3a25e5dcc589c84e75b178ae8ea7de05cbf6b783f77a5fae938f6e8fda6f5257ed70000be27a681e1e44829251bfffe4c10216002f8f14e6 + unique-filename: ^3.0.0 + checksum: 385756781e1e21af089160d89d7462b7ed9883c978e848c7075b90b73cb823680e66092d61513050164588387d2ca87dd6d910e28d64bc13a9ac82cd8580c796 languageName: node linkType: hard @@ -6551,10 +6517,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001449": - version: 1.0.30001488 - resolution: "caniuse-lite@npm:1.0.30001488" - checksum: ef0caf2914f9fca700b75d22921f500241f4e988ded9985e62737136031787052185d8136a65a3a6d6d12b559cf75ab99f5488931f8bd060f1b7810a2c1ee1d1 +"caniuse-lite@npm:^1.0.30001503": + version: 1.0.30001504 + resolution: "caniuse-lite@npm:1.0.30001504" + checksum: 0256f8ef2f5d6d1559198967d7325952e6451e79ff1b92d3d6ba1ec43efedf49fcd3fbb0735ebed0bfd96c6c6a49730e169535e273c60795d23ef25bd37e3e3d languageName: node linkType: hard @@ -7148,11 +7114,11 @@ __metadata: linkType: hard "core-js-compat@npm:^3.30.1, core-js-compat@npm:^3.30.2": - version: 3.30.2 - resolution: "core-js-compat@npm:3.30.2" + version: 3.31.0 + resolution: "core-js-compat@npm:3.31.0" dependencies: browserslist: ^4.21.5 - checksum: 4c81d635559eebc2f81db60f5095a235f580a2f90698113c4124c72761393592b139e30974cce6095a9a6aad6bb3cd467b24b20c32e77ed24ca74eb5944d0638 + checksum: 5c76ac5e4ab39480391f93a5aef14a2cfa188cda7bd6a7b8532de1f8bc5d89099a5025b2640d2ef70a2928614792363dcbcf8bd254aa7b2e11b85aeed7ac460f languageName: node linkType: hard @@ -7318,32 +7284,6 @@ __metadata: languageName: node linkType: hard -"deep-equal@npm:^2.0.5": - version: 2.2.1 - resolution: "deep-equal@npm:2.2.1" - dependencies: - array-buffer-byte-length: ^1.0.0 - call-bind: ^1.0.2 - es-get-iterator: ^1.1.3 - get-intrinsic: ^1.2.0 - is-arguments: ^1.1.1 - is-array-buffer: ^3.0.2 - is-date-object: ^1.0.5 - is-regex: ^1.1.4 - is-shared-array-buffer: ^1.0.2 - isarray: ^2.0.5 - object-is: ^1.1.5 - object-keys: ^1.1.1 - object.assign: ^4.1.4 - regexp.prototype.flags: ^1.5.0 - side-channel: ^1.0.4 - which-boxed-primitive: ^1.0.2 - which-collection: ^1.0.1 - which-typed-array: ^1.1.9 - checksum: 561f0e001a07b2f1b80ff914d0b3d76964bbfc102f34c2128bc8039c0050e63b1a504a8911910e011d8cd1cd4b600a9686c049e327f4ef94420008efc42d25f4 - languageName: node - linkType: hard - "deep-equal@npm:~1.0.1": version: 1.0.1 resolution: "deep-equal@npm:1.0.1" @@ -7517,13 +7457,20 @@ __metadata: languageName: node linkType: hard -"deprecation@npm:^2.0.0, deprecation@npm:^2.3.1": +"deprecation@npm:^2.0.0": version: 2.3.1 resolution: "deprecation@npm:2.3.1" checksum: f56a05e182c2c195071385455956b0c4106fe14e36245b00c689ceef8e8ab639235176a96977ba7c74afb173317fac2e0ec6ec7a1c6d1e6eaa401c586c714132 languageName: node linkType: hard +"dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 + languageName: node + linkType: hard + "destroy@npm:1.2.0, destroy@npm:^1.0.4": version: 1.2.0 resolution: "destroy@npm:1.2.0" @@ -7695,10 +7642,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.284": - version: 1.4.402 - resolution: "electron-to-chromium@npm:1.4.402" - checksum: d2e6473921df875169d58e6317bcb64f1d88127fbd841799218720458e1e6d30e5a3abaac97d20c5bf02c3c2246f3cc701d6503713e3f14ff656a87068489d1e +"electron-to-chromium@npm:^1.4.431": + version: 1.4.433 + resolution: "electron-to-chromium@npm:1.4.433" + checksum: 106e3bc2fb4ee5eddd4b141363900d5cd731c7579aa6bebd02509c52d6b598a1684aba1b75791e838dfa54dec0a40ddd17ea01199041ea46310aafb206395e43 languageName: node linkType: hard @@ -7857,27 +7804,10 @@ __metadata: languageName: node linkType: hard -"es-get-iterator@npm:^1.1.3": - version: 1.1.3 - resolution: "es-get-iterator@npm:1.1.3" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.3 - has-symbols: ^1.0.3 - is-arguments: ^1.1.1 - is-map: ^2.0.2 - is-set: ^2.0.2 - is-string: ^1.0.7 - isarray: ^2.0.5 - stop-iteration-iterator: ^1.0.0 - checksum: 8fa118da42667a01a7c7529f8a8cca514feeff243feec1ce0bb73baaa3514560bd09d2b3438873cf8a5aaec5d52da248131de153b28e2638a061b6e4df13267d - languageName: node - linkType: hard - "es-module-lexer@npm:^1.0.0, es-module-lexer@npm:^1.2.1": - version: 1.2.1 - resolution: "es-module-lexer@npm:1.2.1" - checksum: c4145b853e1491eaa5d591e4580926d242978c38071ad3d09165c3b6d50314cc0ae3bf6e1dec81a9e53768b9299df2063d2e4a67d7742a5029ddeae6c4fc26f0 + version: 1.3.0 + resolution: "es-module-lexer@npm:1.3.0" + checksum: 48fd9f504a9d2a894126f75c8b7ccc6273a289983e9b67255f165bfd9ae765d50100218251e94e702ca567826905ea2f7b3b4a0c4d74d3ce99cce3a2a606a238 languageName: node linkType: hard @@ -8430,6 +8360,13 @@ __metadata: languageName: node linkType: hard +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 3d21519a4f8207c99f7457287291316306255a328770d320b401114ec8481986e4e467e854cb9914dd965e0a1ca810a23ccb559c642c88f4c7f55c55778a9b48 + languageName: node + linkType: hard + "express@npm:^4.17.3": version: 4.18.2 resolution: "express@npm:4.18.2" @@ -8939,7 +8876,7 @@ __metadata: languageName: node linkType: hard -"fs-minipass@npm:^2.0.0, fs-minipass@npm:^2.1.0": +"fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" dependencies: @@ -8948,6 +8885,15 @@ __metadata: languageName: node linkType: hard +"fs-minipass@npm:^3.0.0": + version: 3.0.2 + resolution: "fs-minipass@npm:3.0.2" + dependencies: + minipass: ^5.0.0 + checksum: e9cc0e1f2d01c6f6f62f567aee59530aba65c6c7b2ae88c5027bc34c711ebcfcfaefd0caf254afa6adfe7d1fba16bc2537508a6235196bac7276747d078aef0a + languageName: node + linkType: hard + "fs-mkdirp-stream@npm:^1.0.0": version: 1.0.0 resolution: "fs-mkdirp-stream@npm:1.0.0" @@ -8958,10 +8904,10 @@ __metadata: languageName: node linkType: hard -"fs-monkey@npm:^1.0.3": - version: 1.0.3 - resolution: "fs-monkey@npm:1.0.3" - checksum: cf50804833f9b88a476911ae911fe50f61a98d986df52f890bd97e7262796d023698cb2309fa9b74fdd8974f04315b648748a0a8ee059e7d5257b293bfc409c0 +"fs-monkey@npm:^1.0.4": + version: 1.0.4 + resolution: "fs-monkey@npm:1.0.4" + checksum: 8b254c982905c0b7e028eab22b410dc35a5c0019c1c860456f5f54ae6a61666e1cb8c6b700d6c88cc873694c00953c935847b9959cc4dcf274aacb8673c1e8bf languageName: node linkType: hard @@ -9224,7 +9170,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.2.7": +"glob@npm:10.2.7, glob@npm:^10.2.2": version: 10.2.7 resolution: "glob@npm:10.2.7" dependencies: @@ -9267,7 +9213,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.1, glob@npm:^8.0.3": +"glob@npm:^8.0.3": version: 8.1.0 resolution: "glob@npm:8.1.0" dependencies: @@ -9354,15 +9300,15 @@ __metadata: linkType: hard "globby@npm:^13.1.2": - version: 13.1.4 - resolution: "globby@npm:13.1.4" + version: 13.2.0 + resolution: "globby@npm:13.2.0" dependencies: dir-glob: ^3.0.1 fast-glob: ^3.2.11 ignore: ^5.2.0 merge2: ^1.4.1 slash: ^4.0.0 - checksum: e8bc13879972082d590cd1b0e27080d90d2e12fff7eeb2cee9329c29115ace14cc5b9f899e3d6beb136ba826307a727016658919a6f383e1511d698acee81741 + checksum: 0a3dd786571788adef1c894f22112834cff5bbe061ae6e0a01c5118c39d44b3f1937ef1dae3f8b9bc24756eba84a0923e565b1ad9a4ec52831d7e2a04c035e75 languageName: node linkType: hard @@ -9914,9 +9860,9 @@ __metadata: linkType: hard "html-entities@npm:^2.3.2": - version: 2.3.3 - resolution: "html-entities@npm:2.3.3" - checksum: 92521501da8aa5f66fee27f0f022d6e9ceae62667dae93aa6a2f636afa71ad530b7fb24a18d4d6c124c9885970cac5f8a52dbf1731741161002816ae43f98196 + version: 2.3.6 + resolution: "html-entities@npm:2.3.6" + checksum: 559a88dc3a2059b1e8882940dcaf996ea9d8151b9a780409ff223a79dc1d42ee8bb19b3365064f241f2e2543b0f90612d63f9b8e36d14c4c7fbb73540a8f41cb languageName: node linkType: hard @@ -9964,7 +9910,7 @@ __metadata: languageName: node linkType: hard -"http-cache-semantics@npm:^4.1.0": +"http-cache-semantics@npm:^4.1.1": version: 4.1.1 resolution: "http-cache-semantics@npm:4.1.1" checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236 @@ -10210,13 +10156,6 @@ __metadata: languageName: node linkType: hard -"infer-owner@npm:^1.0.4": - version: 1.0.4 - resolution: "infer-owner@npm:1.0.4" - checksum: 181e732764e4a0611576466b4b87dac338972b839920b2a8cde43642e4ed6bd54dc1fb0b40874728f2a2df9a1b097b8ff83b56d5f8f8e3927f837fdcb47d8a89 - languageName: node - linkType: hard - "inflight@npm:^1.0.4": version: 1.0.6 resolution: "inflight@npm:1.0.6" @@ -10265,7 +10204,7 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5": +"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.5": version: 1.0.5 resolution: "internal-slot@npm:1.0.5" dependencies: @@ -10331,9 +10270,9 @@ __metadata: linkType: hard "ipaddr.js@npm:^2.0.1": - version: 2.0.1 - resolution: "ipaddr.js@npm:2.0.1" - checksum: dd194a394a843d470f88d17191b0948f383ed1c8e320813f850c336a0fcb5e9215d97ec26ca35ab4fbbd31392c8b3467f3e8344628029ed3710b2ff6b5d1034e + version: 2.1.0 + resolution: "ipaddr.js@npm:2.1.0" + checksum: 807a054f2bd720c4d97ee479d6c9e865c233bea21f139fb8dabd5a35c4226d2621c42e07b4ad94ff3f82add926a607d8d9d37c625ad0319f0e08f9f2bd1968e2 languageName: node linkType: hard @@ -10365,16 +10304,6 @@ __metadata: languageName: node linkType: hard -"is-arguments@npm:^1.1.1": - version: 1.1.1 - resolution: "is-arguments@npm:1.1.1" - dependencies: - call-bind: ^1.0.2 - has-tostringtag: ^1.0.0 - checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 - languageName: node - linkType: hard - "is-array-buffer@npm:^3.0.1, is-array-buffer@npm:^3.0.2": version: 3.0.2 resolution: "is-array-buffer@npm:3.0.2" @@ -10480,7 +10409,7 @@ __metadata: languageName: node linkType: hard -"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": +"is-date-object@npm:^1.0.1": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" dependencies: @@ -10627,13 +10556,6 @@ __metadata: languageName: node linkType: hard -"is-map@npm:^2.0.1, is-map@npm:^2.0.2": - version: 2.0.2 - resolution: "is-map@npm:2.0.2" - checksum: ace3d0ecd667bbdefdb1852de601268f67f2db725624b1958f279316e13fecb8fa7df91fd60f690d7417b4ec180712f5a7ee967008e27c65cfd475cc84337728 - languageName: node - linkType: hard - "is-module@npm:^1.0.0": version: 1.0.0 resolution: "is-module@npm:1.0.0" @@ -10787,13 +10709,6 @@ __metadata: languageName: node linkType: hard -"is-set@npm:^2.0.1, is-set@npm:^2.0.2": - version: 2.0.2 - resolution: "is-set@npm:2.0.2" - checksum: b64343faf45e9387b97a6fd32be632ee7b269bd8183701f3b3f5b71a7cf00d04450ed8669d0bd08753e08b968beda96fca73a10fd0ff56a32603f64deba55a57 - languageName: node - linkType: hard - "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -10887,13 +10802,6 @@ __metadata: languageName: node linkType: hard -"is-weakmap@npm:^2.0.1": - version: 2.0.1 - resolution: "is-weakmap@npm:2.0.1" - checksum: 1222bb7e90c32bdb949226e66d26cb7bce12e1e28e3e1b40bfa6b390ba3e08192a8664a703dff2a00a84825f4e022f9cd58c4599ff9981ab72b1d69479f4f7f6 - languageName: node - linkType: hard - "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -10903,16 +10811,6 @@ __metadata: languageName: node linkType: hard -"is-weakset@npm:^2.0.1": - version: 2.0.2 - resolution: "is-weakset@npm:2.0.2" - dependencies: - call-bind: ^1.0.2 - get-intrinsic: ^1.1.1 - checksum: 5d8698d1fa599a0635d7ca85be9c26d547b317ed8fd83fc75f03efbe75d50001b5eececb1e9971de85fcde84f69ae6f8346bc92d20d55d46201d328e4c74a367 - languageName: node - linkType: hard - "is-windows@npm:^1.0.1, is-windows@npm:^1.0.2": version: 1.0.2 resolution: "is-windows@npm:1.0.2" @@ -10943,13 +10841,6 @@ __metadata: languageName: node linkType: hard -"isarray@npm:^2.0.5": - version: 2.0.5 - resolution: "isarray@npm:2.0.5" - checksum: bd5bbe4104438c4196ba58a54650116007fa0262eccef13a4c55b2e09a5b36b59f1e75b9fcc49883dd9d4953892e6fc007eef9e9155648ceea036e184b0f930a - languageName: node - linkType: hard - "isbinaryfile@npm:^5.0.0": version: 5.0.0 resolution: "isbinaryfile@npm:5.0.0" @@ -10981,21 +10872,21 @@ __metadata: linkType: hard "jackspeak@npm:^2.0.3": - version: 2.2.0 - resolution: "jackspeak@npm:2.2.0" + version: 2.2.1 + resolution: "jackspeak@npm:2.2.1" dependencies: "@isaacs/cliui": ^8.0.2 "@pkgjs/parseargs": ^0.11.0 dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: d8cd5be4f0e89cef04add5b0b068162a086bdb1ca68113ed729e99489b7865ca3edcc6430d6fd20c430e15382929ef5f3c7ec36e6aa7c17be23cac116f92dcff + checksum: e29291c0d0f280a063fa18fbd1e891ab8c2d7519fd34052c0ebde38538a15c603140d60c2c7f432375ff7ee4c5f1c10daa8b2ae19a97c3d4affe308c8360c1df languageName: node linkType: hard "jake@npm:^10.8.5": - version: 10.8.6 - resolution: "jake@npm:10.8.6" + version: 10.8.7 + resolution: "jake@npm:10.8.7" dependencies: async: ^3.2.3 chalk: ^4.0.2 @@ -11003,7 +10894,7 @@ __metadata: minimatch: ^3.1.2 bin: jake: bin/cli.js - checksum: eebebd3ca62a01ced630afc116f429d727d34bebe58a9424c0d5a0618ad6c1db893163fb4fbcdff01f34d34d6d63c0dd2448de598270bcd27d9440630de4aeea + checksum: a23fd2273fb13f0d0d845502d02c791fd55ef5c6a2d207df72f72d8e1eac6d2b8ffa6caf660bc8006b3242e0daaa88a3ecc600194d72b5c6016ad56e9cd43553 languageName: node linkType: hard @@ -11745,9 +11636,9 @@ __metadata: linkType: hard "lru-cache@npm:^9.1.1": - version: 9.1.1 - resolution: "lru-cache@npm:9.1.1" - checksum: 4d703bb9b66216bbee55ead82a9682820a2b6acbdfca491b235390b1ef1056000a032d56dfb373fdf9ad4492f1fa9d04cc9a05a77f25bd7ce6901d21ad9b68b7 + version: 9.1.2 + resolution: "lru-cache@npm:9.1.2" + checksum: d3415634be3908909081fc4c56371a8d562d9081eba70543d86871b978702fffd0e9e362b83921b27a29ae2b37b90f55675aad770a54ac83bb3e4de5049d4b15 languageName: node linkType: hard @@ -11787,27 +11678,26 @@ __metadata: languageName: node linkType: hard -"make-fetch-happen@npm:^10.0.3": - version: 10.2.1 - resolution: "make-fetch-happen@npm:10.2.1" +"make-fetch-happen@npm:^11.0.3": + version: 11.1.1 + resolution: "make-fetch-happen@npm:11.1.1" dependencies: agentkeepalive: ^4.2.1 - cacache: ^16.1.0 - http-cache-semantics: ^4.1.0 + cacache: ^17.0.0 + http-cache-semantics: ^4.1.1 http-proxy-agent: ^5.0.0 https-proxy-agent: ^5.0.0 is-lambda: ^1.0.1 lru-cache: ^7.7.1 - minipass: ^3.1.6 - minipass-collect: ^1.0.2 - minipass-fetch: ^2.0.3 + minipass: ^5.0.0 + minipass-fetch: ^3.0.0 minipass-flush: ^1.0.5 minipass-pipeline: ^1.2.4 negotiator: ^0.6.3 promise-retry: ^2.0.1 socks-proxy-agent: ^7.0.0 - ssri: ^9.0.0 - checksum: 2332eb9a8ec96f1ffeeea56ccefabcb4193693597b132cd110734d50f2928842e22b84cfa1508e921b8385cdfd06dda9ad68645fed62b50fff629a580f5fb72c + ssri: ^10.0.0 + checksum: 7268bf274a0f6dcf0343829489a4506603ff34bd0649c12058753900b0eb29191dce5dba12680719a5d0a983d3e57810f594a12f3c18494e93a1fbc6348a4540 languageName: node linkType: hard @@ -11872,11 +11762,11 @@ __metadata: linkType: hard "memfs@npm:^3.4.3, memfs@npm:^3.5.0": - version: 3.5.1 - resolution: "memfs@npm:3.5.1" + version: 3.5.3 + resolution: "memfs@npm:3.5.3" dependencies: - fs-monkey: ^1.0.3 - checksum: fcd037566a4bbb00d61dc991858395ccc06267ab5fe9471aeff28433f2a210bf5dd999e64e8b5473f8244f00dfb7ff3221b5c2fe41ff98af1439e5e2168fc410 + fs-monkey: ^1.0.4 + checksum: 18dfdeacad7c8047b976a6ccd58bc98ba76e122ad3ca0e50a21837fe2075fc0d9aafc58ab9cf2576c2b6889da1dd2503083f2364191b695273f40969db2ecc44 languageName: node linkType: hard @@ -12076,18 +11966,18 @@ __metadata: languageName: node linkType: hard -"minipass-fetch@npm:^2.0.3": - version: 2.1.2 - resolution: "minipass-fetch@npm:2.1.2" +"minipass-fetch@npm:^3.0.0": + version: 3.0.3 + resolution: "minipass-fetch@npm:3.0.3" dependencies: encoding: ^0.1.13 - minipass: ^3.1.6 + minipass: ^5.0.0 minipass-sized: ^1.0.3 minizlib: ^2.1.2 dependenciesMeta: encoding: optional: true - checksum: 3f216be79164e915fc91210cea1850e488793c740534985da017a4cbc7a5ff50506956d0f73bb0cb60e4fe91be08b6b61ef35101706d3ef5da2c8709b5f08f91 + checksum: af5ab2552a16fcf505d35fd7ffb84b57f4a0eeb269e6e1d9a2a75824dda48b36e527083250b7cca4a4def21d9544e2ade441e4730e233c0bc2133f6abda31e18 languageName: node linkType: hard @@ -12118,7 +12008,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^3.0.0, minipass@npm:^3.1.1, minipass@npm:^3.1.6": +"minipass@npm:^3.0.0": version: 3.3.6 resolution: "minipass@npm:3.3.6" dependencies: @@ -12179,7 +12069,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": +"mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -12393,13 +12283,14 @@ __metadata: linkType: hard "node-gyp@npm:latest": - version: 9.3.1 - resolution: "node-gyp@npm:9.3.1" + version: 9.4.0 + resolution: "node-gyp@npm:9.4.0" dependencies: env-paths: ^2.2.0 + exponential-backoff: ^3.1.1 glob: ^7.1.4 graceful-fs: ^4.2.6 - make-fetch-happen: ^10.0.3 + make-fetch-happen: ^11.0.3 nopt: ^6.0.0 npmlog: ^6.0.0 rimraf: ^3.0.2 @@ -12408,14 +12299,14 @@ __metadata: which: ^2.0.2 bin: node-gyp: bin/node-gyp.js - checksum: b860e9976fa645ca0789c69e25387401b4396b93c8375489b5151a6c55cf2640a3b6183c212b38625ef7c508994930b72198338e3d09b9d7ade5acc4aaf51ea7 + checksum: 78b404e2e0639d64e145845f7f5a3cb20c0520cdaf6dda2f6e025e9b644077202ea7de1232396ba5bde3fee84cdc79604feebe6ba3ec84d464c85d407bb5da99 languageName: node linkType: hard -"node-releases@npm:^2.0.8": - version: 2.0.11 - resolution: "node-releases@npm:2.0.11" - checksum: ade1c8e19852aa7d7b45691c2708e6275703dd4994b16bc191cdbf66add29ccf87c595ecdb03a39db54a8aaba645f228bccd7d9477e4066f1d97a94f857dae9d +"node-releases@npm:^2.0.12": + version: 2.0.12 + resolution: "node-releases@npm:2.0.12" + checksum: b8c56db82c4642a0f443332b331a4396dae452a2ac5a65c8dbd93ef89ecb2fbb0da9d42ac5366d4764973febadca816cf7587dad492dce18d2a6b2af59cda260 languageName: node linkType: hard @@ -12567,16 +12458,6 @@ __metadata: languageName: node linkType: hard -"object-is@npm:^1.1.5": - version: 1.1.5 - resolution: "object-is@npm:1.1.5" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe - languageName: node - linkType: hard - "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -13291,13 +13172,13 @@ __metadata: linkType: hard "postcss@npm:^8.4.14": - version: 8.4.23 - resolution: "postcss@npm:8.4.23" + version: 8.4.24 + resolution: "postcss@npm:8.4.24" dependencies: nanoid: ^3.3.6 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 8bb9d1b2ea6e694f8987d4f18c94617971b2b8d141602725fedcc2222fdc413b776a6e1b969a25d627d7b2681ca5aabb56f59e727ef94072e1b6ac8412105a2f + checksum: 814e2126dacfea313588eda09cc99a9b4c26ec55c059188aa7a916d20d26d483483106dc5ff9e560731b59f45c5bb91b945dfadc670aed875cc90ddbbf4e787d languageName: node linkType: hard @@ -13359,13 +13240,6 @@ __metadata: languageName: node linkType: hard -"promise-inflight@npm:^1.0.1": - version: 1.0.1 - resolution: "promise-inflight@npm:1.0.1" - checksum: 22749483091d2c594261517f4f80e05226d4d5ecc1fc917e1886929da56e22b5718b7f2a75f3807e7a7d471bc3be2907fe92e6e8f373ddf5c64bae35b5af3981 - languageName: node - linkType: hard - "promise-retry@npm:^2.0.1": version: 2.0.1 resolution: "promise-retry@npm:2.0.1" @@ -13423,13 +13297,6 @@ __metadata: languageName: node linkType: hard -"punycode@npm:1.3.2": - version: 1.3.2 - resolution: "punycode@npm:1.3.2" - checksum: b8807fd594b1db33335692d1f03e8beeddde6fda7fbb4a2e32925d88d20a3aa4cd8dcc0c109ccaccbd2ba761c208dfaaada83007087ea8bfb0129c9ef1b99ed6 - languageName: node - linkType: hard - "punycode@npm:2.3.0, punycode@npm:^2.1.0, punycode@npm:^2.1.1": version: 2.3.0 resolution: "punycode@npm:2.3.0" @@ -13437,7 +13304,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^1.3.2": +"punycode@npm:^1.3.2, punycode@npm:^1.4.1": version: 1.4.1 resolution: "punycode@npm:1.4.1" checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518 @@ -13476,10 +13343,12 @@ __metadata: languageName: node linkType: hard -"querystring@npm:0.2.0": - version: 0.2.0 - resolution: "querystring@npm:0.2.0" - checksum: 8258d6734f19be27e93f601758858c299bdebe71147909e367101ba459b95446fbe5b975bf9beb76390156a592b6f4ac3a68b6087cea165c259705b8b4e56a69 +"qs@npm:^6.11.0": + version: 6.11.2 + resolution: "qs@npm:6.11.2" + dependencies: + side-channel: ^1.0.4 + checksum: e812f3c590b2262548647d62f1637b6989cc56656dc960b893fe2098d96e1bd633f36576f4cd7564dfbff9db42e17775884db96d846bebe4f37420d073ecdc0b languageName: node linkType: hard @@ -13661,7 +13530,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.4.3, regexp.prototype.flags@npm:^1.5.0": +"regexp.prototype.flags@npm:^1.4.3": version: 1.5.0 resolution: "regexp.prototype.flags@npm:1.5.0" dependencies: @@ -14129,14 +13998,14 @@ __metadata: linkType: hard "schema-utils@npm:^4.0.0": - version: 4.0.1 - resolution: "schema-utils@npm:4.0.1" + version: 4.2.0 + resolution: "schema-utils@npm:4.2.0" dependencies: "@types/json-schema": ^7.0.9 ajv: ^8.9.0 ajv-formats: ^2.1.1 ajv-keywords: ^5.1.0 - checksum: 745e7293c6b6c84940de16753c207311da821aa9911b9e2d158cfd9ffc5bf1f880147abbbe775b96cb8cd3c7f48890950fe0164f54eed9a8aabb948ebf8a3fdd + checksum: 26a0463d47683258106e6652e9aeb0823bf0b85843039e068b57da1892f7ae6b6b1094d48e9ed5ba5cbe9f7166469d880858b9d91abe8bd249421eb813850cde languageName: node linkType: hard @@ -14184,13 +14053,13 @@ __metadata: linkType: hard "semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7": - version: 7.5.1 - resolution: "semver@npm:7.5.1" + version: 7.5.2 + resolution: "semver@npm:7.5.2" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: d16dbedad53c65b086f79524b9ef766bf38670b2395bdad5c957f824dcc566b624988013564f4812bcace3f9d405355c3635e2007396a39d1bffc71cfec4a2fc + checksum: 3fdf5d1e6f170fe8bcc41669e31787649af91af7f54f05c71d0865bb7aa27e8b92f68b3e6b582483e2c1c648008bc84249d2cd86301771fe5cbf7621d1fe5375 languageName: node linkType: hard @@ -14689,12 +14558,12 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^9.0.0": - version: 9.0.1 - resolution: "ssri@npm:9.0.1" +"ssri@npm:^10.0.0": + version: 10.0.4 + resolution: "ssri@npm:10.0.4" dependencies: - minipass: ^3.1.1 - checksum: fb58f5e46b6923ae67b87ad5ef1c5ab6d427a17db0bead84570c2df3cd50b4ceb880ebdba2d60726588272890bae842a744e1ecce5bd2a2a582fccd5068309eb + minipass: ^5.0.0 + checksum: fb14da9f8a72b04eab163eb13a9dda11d5962cd2317f85457c4e0b575e9a6e0e3a6a87b5bf122c75cb36565830cd5f263fb457571bf6f1587eb5f95d095d6165 languageName: node linkType: hard @@ -14736,15 +14605,6 @@ __metadata: languageName: node linkType: hard -"stop-iteration-iterator@npm:^1.0.0": - version: 1.0.0 - resolution: "stop-iteration-iterator@npm:1.0.0" - dependencies: - internal-slot: ^1.0.4 - checksum: d04173690b2efa40e24ab70e5e51a3ff31d56d699550cfad084104ab3381390daccb36652b25755e420245f3b0737de66c1879eaa2a8d4fc0a78f9bf892fcb42 - languageName: node - linkType: hard - "stream-exhaust@npm:^1.0.1": version: 1.0.2 resolution: "stream-exhaust@npm:1.0.2" @@ -14912,11 +14772,11 @@ __metadata: linkType: hard "strip-ansi@npm:^7.0.1": - version: 7.0.1 - resolution: "strip-ansi@npm:7.0.1" + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" dependencies: ansi-regex: ^6.0.1 - checksum: 257f78fa433520e7f9897722731d78599cb3fce29ff26a20a5e12ba4957463b50a01136f37c43707f4951817a75e90820174853d6ccc240997adc5df8f966039 + checksum: 859c73fcf27869c22a4e4d8c6acfe690064659e84bef9458aa6d13719d09ca88dcfd40cbf31fd0be63518ea1a643fe070b4827d353e09533a5b0b9fd4553d64d languageName: node linkType: hard @@ -15139,16 +14999,16 @@ __metadata: linkType: hard "terser@npm:^5.0.0, terser@npm:^5.15.1, terser@npm:^5.16.8": - version: 5.17.4 - resolution: "terser@npm:5.17.4" + version: 5.18.0 + resolution: "terser@npm:5.18.0" dependencies: - "@jridgewell/source-map": ^0.3.2 - acorn: ^8.5.0 + "@jridgewell/source-map": ^0.3.3 + acorn: ^8.8.2 commander: ^2.20.0 source-map-support: ~0.5.20 bin: terser: bin/terser - checksum: 4bb4bbee170bee4cf897545b602999e0b74d2cd035387514c6859fae6a71d623f8d1319de47bcf6a157358355cc7afaa62a5d5661bfc72968d13b35113022486 + checksum: d01eb9805a978b3338b68fd2d9e35c1cd4cad78ea093dc92c7b3c38965232f0af0f95e0c6d90920ecf600a74135c608aebae26302c036c01393a590e1918bb90 languageName: node linkType: hard @@ -15391,9 +15251,9 @@ __metadata: linkType: hard "tslib@npm:^2.0.1, tslib@npm:^2.0.2, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0": - version: 2.5.2 - resolution: "tslib@npm:2.5.2" - checksum: 4d3c1e238b94127ed0e88aa0380db3c2ddae581dc0f4bae5a982345e9f50ee5eda90835b8bfba99b02df10a5734470be197158c36f9129ac49fdc14a6a9da222 + version: 2.5.3 + resolution: "tslib@npm:2.5.3" + checksum: 88902b309afaf83259131c1e13da1dceb0ad1682a213143a1346a649143924d78cf3760c448b84d796938fd76127183894f8d85cbb3bf9c4fddbfcc140c0003c languageName: node linkType: hard @@ -15728,21 +15588,21 @@ __metadata: languageName: node linkType: hard -"unique-filename@npm:^2.0.0": - version: 2.0.1 - resolution: "unique-filename@npm:2.0.1" +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" dependencies: - unique-slug: ^3.0.0 - checksum: 807acf3381aff319086b64dc7125a9a37c09c44af7620bd4f7f3247fcd5565660ac12d8b80534dcbfd067e6fe88a67e621386dd796a8af828d1337a8420a255f + unique-slug: ^4.0.0 + checksum: 8e2f59b356cb2e54aab14ff98a51ac6c45781d15ceaab6d4f1c2228b780193dc70fae4463ce9e1df4479cb9d3304d7c2043a3fb905bdeca71cc7e8ce27e063df languageName: node linkType: hard -"unique-slug@npm:^3.0.0": - version: 3.0.0 - resolution: "unique-slug@npm:3.0.0" +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" dependencies: imurmurhash: ^0.1.4 - checksum: 49f8d915ba7f0101801b922062ee46b7953256c93ceca74303bd8e6413ae10aa7e8216556b54dc5382895e8221d04f1efaf75f945c2e4a515b4139f77aa6640c + checksum: 0884b58365af59f89739e6f71e3feacb5b1b41f2df2d842d0757933620e6de08eff347d27e9d499b43c40476cbaf7988638d3acb2ffbcb9d35fd035591adfd15 languageName: node linkType: hard @@ -15810,7 +15670,7 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.0.10": +"update-browserslist-db@npm:^1.0.11": version: 1.0.11 resolution: "update-browserslist-db@npm:1.0.11" dependencies: @@ -15841,12 +15701,12 @@ __metadata: linkType: hard "url@npm:^0.11.0": - version: 0.11.0 - resolution: "url@npm:0.11.0" + version: 0.11.1 + resolution: "url@npm:0.11.1" dependencies: - punycode: 1.3.2 - querystring: 0.2.0 - checksum: 50d100d3dd2d98b9fe3ada48cadb0b08aa6be6d3ac64112b867b56b19be4bfcba03c2a9a0d7922bfd7ac17d4834e88537749fe182430dfd9b68e520175900d90 + punycode: ^1.4.1 + qs: ^6.11.0 + checksum: a7de4b37bbcbe60ef199acda4ce437ef843c0ef3a4b34ec3e3d97e0446a5f50dc7bfeafbe33ad118cf4e5aa04805e1328f0d0126e254f2b77bb8498fa395c596 languageName: node linkType: hard @@ -16093,9 +15953,9 @@ __metadata: linkType: hard "w3c-keyname@npm:^2.2.4": - version: 2.2.7 - resolution: "w3c-keyname@npm:2.2.7" - checksum: 91e057b1ec28e0bafcaf28def12023f0e083fd473c40d0a9c2aa01a975d227200d75ff6d8eb6961bb4608b967b1df1dd86786b52ee9489cb9a2ebeed881a63ae + version: 2.2.8 + resolution: "w3c-keyname@npm:2.2.8" + checksum: 95bafa4c04fa2f685a86ca1000069c1ec43ace1f8776c10f226a73296caeddd83f893db885c2c220ebeb6c52d424e3b54d7c0c1e963bbf204038ff1a944fbb07 languageName: node linkType: hard @@ -16261,12 +16121,12 @@ __metadata: linkType: hard "webpack-merge@npm:^5.7.3": - version: 5.8.0 - resolution: "webpack-merge@npm:5.8.0" + version: 5.9.0 + resolution: "webpack-merge@npm:5.9.0" dependencies: clone-deep: ^4.0.1 wildcard: ^2.0.0 - checksum: 88786ab91013f1bd2a683834ff381be81c245a4b0f63304a5103e90f6653f44dab496a0768287f8531761f8ad957d1f9f3ccb2cb55df0de1bd9ee343e079da26 + checksum: 64fe2c23aacc5f19684452a0e84ec02c46b990423aee6fcc5c18d7d471155bd14e9a6adb02bd3656eb3e0ac2532c8e97d69412ad14c97eeafe32fa6d10050872 languageName: node linkType: hard @@ -16407,18 +16267,6 @@ __metadata: languageName: node linkType: hard -"which-collection@npm:^1.0.1": - version: 1.0.1 - resolution: "which-collection@npm:1.0.1" - dependencies: - is-map: ^2.0.1 - is-set: ^2.0.1 - is-weakmap: ^2.0.1 - is-weakset: ^2.0.1 - checksum: c815bbd163107ef9cb84f135e6f34453eaf4cca994e7ba85ddb0d27cea724c623fae2a473ceccfd5549c53cc65a5d82692de418166df3f858e1e5dc60818581c - languageName: node - linkType: hard - "which-module@npm:^1.0.0": version: 1.0.0 resolution: "which-module@npm:1.0.0" @@ -16874,9 +16722,9 @@ __metadata: linkType: hard "yaml@npm:^2.2.2": - version: 2.2.2 - resolution: "yaml@npm:2.2.2" - checksum: d90c235e099e30094dcff61ba3350437aef53325db4a6bcd04ca96e1bfe7e348b191f6a7a52b5211e2dbc4eeedb22a00b291527da030de7c189728ef3f2b4eb3 + version: 2.3.1 + resolution: "yaml@npm:2.3.1" + checksum: 2c7bc9a7cd4c9f40d3b0b0a98e370781b68b8b7c4515720869aced2b00d92f5da1762b4ffa947f9e795d6cd6b19f410bd4d15fdd38aca7bd96df59bd9486fb54 languageName: node linkType: hard From 41310007fe06a0c0976c3f430bbf3b1c1ea6a5bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 09:39:22 +0200 Subject: [PATCH 051/162] Bump dessant/lock-threads from 4.0.0 to 4.0.1 (#16962) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lock.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index ad51a2699b..11b831a3df 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -9,7 +9,7 @@ jobs: lock: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v4.0.0 + - uses: dessant/lock-threads@v4.0.1 with: github-token: ${{ github.token }} issue-lock-inactive-days: "30" From 80f3d6aacb3d3e6676ae1e900a6a5166b7e4c0c9 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Mon, 19 Jun 2023 12:52:28 +0200 Subject: [PATCH 052/162] Change all occurrences to use Intl.ListFormat (#16897) --- src/data/automation_i18n.ts | 207 ++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 118 deletions(-) diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index 89ea2257c4..80f9caecad 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -90,22 +90,18 @@ export const describeTrigger = ( // Event Trigger if (trigger.platform === "event" && trigger.event_type) { - let eventTypes = ""; + const eventTypes: string[] = []; if (Array.isArray(trigger.event_type)) { - for (const [index, state] of trigger.event_type.entries()) { - eventTypes += `${index > 0 ? "," : ""} ${ - trigger.event_type.length > 1 && - index === trigger.event_type.length - 1 - ? "or" - : "" - } ${state}`; + for (const state of trigger.event_type.values()) { + eventTypes.push(state); } } else { - eventTypes = trigger.event_type.toString(); + eventTypes.push(trigger.event_type); } - return `When ${eventTypes} event is fired`; + const eventTypesString = disjunctionFormatter.format(eventTypes); + return `When ${eventTypesString} event is fired`; } // Home Assistant Trigger @@ -157,7 +153,7 @@ export const describeTrigger = ( // State Trigger if (trigger.platform === "state") { let base = "When"; - let entities = ""; + const entities: string[] = []; const states = hass.states; if (trigger.attribute) { @@ -173,25 +169,22 @@ export const describeTrigger = ( } if (Array.isArray(trigger.entity_id)) { - for (const [index, entity] of trigger.entity_id.entries()) { + for (const entity of trigger.entity_id.values()) { if (states[entity]) { - entities += `${index > 0 ? "," : ""} ${ - trigger.entity_id.length > 1 && - index === trigger.entity_id.length - 1 - ? "or" - : "" - } ${computeStateName(states[entity]) || entity}`; + entities.push(computeStateName(states[entity]) || entity); } } } else if (trigger.entity_id) { - entities = states[trigger.entity_id] - ? computeStateName(states[trigger.entity_id]) - : trigger.entity_id; + entities.push( + states[trigger.entity_id] + ? computeStateName(states[trigger.entity_id]) + : trigger.entity_id + ); } - if (!entities) { + if (entities.length === 0) { // no entity_id or empty array - entities = "something"; + entities.push("something"); } base += ` ${entities} changes`; @@ -208,13 +201,9 @@ export const describeTrigger = ( base += " from any state"; } } else if (Array.isArray(trigger.from)) { - let from = ""; - for (const [index, state] of trigger.from.entries()) { - from += `${index > 0 ? "," : ""} ${ - trigger.from.length > 1 && index === trigger.from.length - 1 - ? "or" - : "" - } '${ + const from: string[] = []; + for (const state of trigger.from.values()) { + from.push( trigger.attribute ? computeAttributeValueDisplay( hass.localize, @@ -224,7 +213,7 @@ export const describeTrigger = ( hass.entities, trigger.attribute, state - ) + ).toString() : computeStateDisplay( hass.localize, stateObj, @@ -233,13 +222,14 @@ export const describeTrigger = ( hass.entities, state ) - }'`; + ); } - if (from) { - base += ` from ${from}`; + if (from.length !== 0) { + const fromString = disjunctionFormatter.format(from); + base += ` from ${fromString}`; } } else { - base += ` from '${ + base += ` from ${ trigger.attribute ? computeAttributeValueDisplay( hass.localize, @@ -258,7 +248,7 @@ export const describeTrigger = ( hass.entities, trigger.from.toString() ).toString() - }'`; + }`; } } @@ -268,11 +258,9 @@ export const describeTrigger = ( base += " to any state"; } } else if (Array.isArray(trigger.to)) { - let to = ""; - for (const [index, state] of trigger.to.entries()) { - to += `${index > 0 ? "," : ""} ${ - trigger.to.length > 1 && index === trigger.to.length - 1 ? "or" : "" - } '${ + const to: string[] = []; + for (const state of trigger.to.values()) { + to.push( trigger.attribute ? computeAttributeValueDisplay( hass.localize, @@ -291,13 +279,14 @@ export const describeTrigger = ( hass.entities, state ).toString() - }'`; + ); } - if (to) { - base += ` to ${to}`; + if (to.length !== 0) { + const toString = disjunctionFormatter.format(to); + base += ` to ${toString}`; } } else { - base += ` to '${ + base += ` to ${ trigger.attribute ? computeAttributeValueDisplay( hass.localize, @@ -315,8 +304,8 @@ export const describeTrigger = ( hass.config, hass.entities, trigger.to.toString() - ).toString() - }'`; + ) + }`; } } @@ -501,9 +490,9 @@ export const describeTrigger = ( const states = hass.states; if (Array.isArray(trigger.entity_id)) { - for (const [entity] of trigger.entity_id.entries()) { + for (const entity of trigger.entity_id.values()) { if (states[entity]) { - entities.push(`${computeStateName(states[entity]) || entity}`); + entities.push(computeStateName(states[entity]) || entity); } } } else { @@ -515,9 +504,9 @@ export const describeTrigger = ( } if (Array.isArray(trigger.zone)) { - for (const [zone] of trigger.zone.entries()) { + for (const zone of trigger.zone.values()) { if (states[zone]) { - zones.push(`${computeStateName(states[zone]) || zone}`); + zones.push(computeStateName(states[zone]) || zone); } } } else { @@ -537,47 +526,39 @@ export const describeTrigger = ( // Geo Location Trigger if (trigger.platform === "geo_location" && trigger.source && trigger.zone) { - let sources = ""; - let zones = ""; - let zonesPlural = false; + const sources: string[] = []; + const zones: string[] = []; const states = hass.states; if (Array.isArray(trigger.source)) { - for (const [index, source] of trigger.source.entries()) { - sources += `${index > 0 ? "," : ""} ${ - trigger.source.length > 1 && index === trigger.source.length - 1 - ? "or" - : "" - } ${source}`; + for (const source of trigger.source.values()) { + sources.push(source); } } else { - sources = trigger.source; + sources.push(trigger.source); } if (Array.isArray(trigger.zone)) { - if (trigger.zone.length > 1) { - zonesPlural = true; - } - - for (const [index, zone] of trigger.zone.entries()) { + for (const zone of trigger.zone.values()) { if (states[zone]) { - zones += `${index > 0 ? "," : ""} ${ - trigger.zone.length > 1 && index === trigger.zone.length - 1 - ? "or" - : "" - } ${computeStateName(states[zone]) || zone}`; + zones.push(computeStateName(states[zone]) || zone); } } } else { - zones = states[trigger.zone] - ? computeStateName(states[trigger.zone]) - : trigger.zone; + zones.push( + states[trigger.zone] + ? computeStateName(states[trigger.zone]) + : trigger.zone + ); } - return `When ${sources} ${trigger.event}s ${zones} ${ - zonesPlural ? "zones" : "zone" + const sourcesString = disjunctionFormatter.format(sources); + const zonesString = disjunctionFormatter.format(zones); + return `When ${sourcesString} ${trigger.event}s ${zonesString} ${ + zones.length > 1 ? "zones" : "zone" }`; } + // MQTT Trigger if (trigger.platform === "mqtt") { return "When an MQTT message has been received"; @@ -634,6 +615,10 @@ export const describeCondition = ( return condition.alias; } + const conjunctionFormatter = new Intl.ListFormat("en", { + style: "long", + type: "conjunction", + }); const disjunctionFormatter = new Intl.ListFormat("en", { style: "long", type: "disjunction", @@ -708,21 +693,20 @@ export const describeCondition = ( } if (Array.isArray(condition.entity_id)) { - let entities = ""; - for (const [index, entity] of condition.entity_id.entries()) { + const entities: string[] = []; + for (const entity of condition.entity_id.values()) { if (hass.states[entity]) { - entities += `${index > 0 ? "," : ""} ${ - condition.entity_id.length > 1 && - index === condition.entity_id.length - 1 - ? condition.match === "any" - ? "or" - : "and" - : "" - } ${computeStateName(hass.states[entity]) || entity}`; + entities.push(computeStateName(hass.states[entity]) || entity); } } - if (entities) { - base += ` ${entities} ${condition.entity_id.length > 1 ? "are" : "is"}`; + if (entities.length !== 0) { + const entitiesString = + condition.match === "any" + ? disjunctionFormatter.format(entities) + : conjunctionFormatter.format(entities); + base += ` ${entitiesString} ${ + condition.entity_id.length > 1 ? "are" : "is" + }`; } else { // no entity_id or empty array base += " an entity"; @@ -735,7 +719,7 @@ export const describeCondition = ( } is`; } - let states = ""; + const states: string[] = []; const stateObj = hass.states[ Array.isArray(condition.entity_id) @@ -743,12 +727,8 @@ export const describeCondition = ( : condition.entity_id ]; if (Array.isArray(condition.state)) { - for (const [index, state] of condition.state.entries()) { - states += `${index > 0 ? "," : ""} ${ - condition.state.length > 1 && index === condition.state.length - 1 - ? "or" - : "" - } '${ + for (const state of condition.state.values()) { + states.push( condition.attribute ? computeAttributeValueDisplay( hass.localize, @@ -758,7 +738,7 @@ export const describeCondition = ( hass.entities, condition.attribute, state - ) + ).toString() : computeStateDisplay( hass.localize, stateObj, @@ -767,10 +747,10 @@ export const describeCondition = ( hass.entities, state ) - }'`; + ); } } else if (condition.state !== "") { - states = `'${ + states.push( condition.attribute ? computeAttributeValueDisplay( hass.localize, @@ -788,15 +768,16 @@ export const describeCondition = ( hass.config, hass.entities, condition.state.toString() - ).toString() - }'`; + ) + ); } - if (!states) { - states = "a state"; + if (states.length === 0) { + states.push("a state"); } - base += ` ${states}`; + const statesString = disjunctionFormatter.format(states); + base += ` ${statesString}`; if (condition.for) { const duration = describeDuration(condition.for); @@ -885,17 +866,7 @@ export const describeCondition = ( `ui.panel.config.automation.editor.conditions.type.time.weekdays.${d}` ) ); - const last = localizedDays.pop(); - - result += " day is " + localizedDays.join(", "); - - if (localizedDays.length) { - if (localizedDays.length > 1) { - result += ","; - } - result += " or "; - } - result += last; + result += " day is " + disjunctionFormatter.format(localizedDays); } return result; @@ -947,9 +918,9 @@ export const describeCondition = ( const states = hass.states; if (Array.isArray(condition.entity_id)) { - for (const [entity] of condition.entity_id.entries()) { + for (const entity of condition.entity_id.values()) { if (states[entity]) { - entities.push(`${computeStateName(states[entity]) || entity}`); + entities.push(computeStateName(states[entity]) || entity); } } } else { @@ -961,9 +932,9 @@ export const describeCondition = ( } if (Array.isArray(condition.zone)) { - for (const [zone] of condition.zone.entries()) { + for (const zone of condition.zone.values()) { if (states[zone]) { - zones.push(`${computeStateName(states[zone]) || zone}`); + zones.push(computeStateName(states[zone]) || zone); } } } else { From 40c8301df0f9025865a6a8a80ead7902357769dc Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 19 Jun 2023 04:33:28 -0700 Subject: [PATCH 053/162] Allow templates in service template/object selector (#16925) --- .../types/ha-automation-action-service.ts | 46 ++++++++++++++++++- .../service/developer-tools-service.ts | 22 ++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/panels/config/automation/action/types/ha-automation-action-service.ts b/src/panels/config/automation/action/types/ha-automation-action-service.ts index e59c1800dd..af4a525406 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-service.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-service.ts @@ -1,7 +1,10 @@ import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; import { customElement, property, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; import { assert } from "superstruct"; import { fireEvent } from "../../../../../common/dom/fire_event"; +import { computeDomain } from "../../../../../common/entity/compute_domain"; +import { computeObjectId } from "../../../../../common/entity/compute_object_id"; import { hasTemplate } from "../../../../../common/string/has-template"; import "../../../../../components/ha-service-control"; import { ServiceAction, serviceActionStruct } from "../../../../../data/script"; @@ -20,6 +23,26 @@ export class HaServiceAction extends LitElement implements ActionElement { @state() private _action!: ServiceAction; + private _fields = memoizeOne( + ( + serviceDomains: HomeAssistant["services"], + domainService: string | undefined + ): { fields: any } => { + if (!domainService) { + return { fields: {} }; + } + const domain = computeDomain(domainService); + const service = computeObjectId(domainService); + if (!(domain in serviceDomains)) { + return { fields: {} }; + } + if (!(service in serviceDomains[domain])) { + return { fields: {} }; + } + return { fields: serviceDomains[domain][service].fields }; + } + ); + public static get defaultConfig() { return { service: "", data: {} }; } @@ -34,7 +57,28 @@ export class HaServiceAction extends LitElement implements ActionElement { fireEvent(this, "ui-mode-not-available", err); return; } - if (this.action && hasTemplate(this.action)) { + + const fields = this._fields( + this.hass.services, + this.action?.service + ).fields; + if ( + this.action && + (Object.entries(this.action).some( + ([key, val]) => key !== "data" && hasTemplate(val) + ) || + (this.action.data && + Object.entries(this.action.data).some(([key, val]) => { + const field = fields[key]; + if ( + field?.selector && + ("template" in field.selector || "object" in field.selector) + ) { + return false; + } + return hasTemplate(val); + }))) + ) { fireEvent( this, "ui-mode-not-available", diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index 8e45387ed2..a169b0fb27 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -346,7 +346,27 @@ class HaPanelDevService extends LitElement { } private _checkUiSupported() { - if (this._serviceData && hasTemplate(this._serviceData)) { + const fields = this._fields( + this.hass.services, + this._serviceData?.service + ).fields; + if ( + this._serviceData && + (Object.entries(this._serviceData).some( + ([key, val]) => key !== "data" && hasTemplate(val) + ) || + (this._serviceData.data && + Object.entries(this._serviceData.data).some(([key, val]) => { + const field = fields.find((f) => f.key === key); + if ( + field?.selector && + ("template" in field.selector || "object" in field.selector) + ) { + return false; + } + return hasTemplate(val); + }))) + ) { this._yamlMode = true; this._uiAvailable = false; } else { From 8abb58ae7d677930ab357ddabf2e45db89d0a513 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 19 Jun 2023 13:36:19 +0200 Subject: [PATCH 054/162] Add preheating HVAC action to climate (#16922) --- gallery/src/pages/misc/entity-state.ts | 3 +++ src/common/entity/get_states.ts | 10 +++++++++- src/data/climate.ts | 2 ++ .../lovelace/cards/tile/badges/tile-badge-climate.ts | 3 +++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gallery/src/pages/misc/entity-state.ts b/gallery/src/pages/misc/entity-state.ts index aa0905d9b2..c35c9fae1e 100644 --- a/gallery/src/pages/misc/entity-state.ts +++ b/gallery/src/pages/misc/entity-state.ts @@ -135,6 +135,9 @@ const ENTITIES: HassEntity[] = [ createEntity("climate.fan_only", "fan_only"), createEntity("climate.auto_idle", "auto", undefined, { hvac_action: "idle" }), createEntity("climate.auto_off", "auto", undefined, { hvac_action: "off" }), + createEntity("climate.auto_preheating", "auto", undefined, { + hvac_action: "preheating", + }), createEntity("climate.auto_heating", "auto", undefined, { hvac_action: "heating", }), diff --git a/src/common/entity/get_states.ts b/src/common/entity/get_states.ts index 5909dd2938..4ceaf82d26 100644 --- a/src/common/entity/get_states.ts +++ b/src/common/entity/get_states.ts @@ -102,7 +102,15 @@ const FIXED_DOMAIN_ATTRIBUTE_STATES = { frontend_stream_type: ["hls", "web_rtc"], }, climate: { - hvac_action: ["off", "idle", "heating", "cooling", "drying", "fan"], + hvac_action: [ + "off", + "idle", + "preheating", + "heating", + "cooling", + "drying", + "fan", + ], }, cover: { device_class: [ diff --git a/src/data/climate.ts b/src/data/climate.ts index b72f845cbf..705f83fe15 100644 --- a/src/data/climate.ts +++ b/src/data/climate.ts @@ -16,6 +16,7 @@ export const CLIMATE_PRESET_NONE = "none"; export type HvacAction = | "off" + | "preheating" | "heating" | "cooling" | "drying" @@ -77,6 +78,7 @@ export const HVAC_ACTION_TO_MODE: Record = { cooling: "cool", drying: "dry", fan: "fan_only", + preheating: "heat", heating: "heat", idle: "off", off: "off", diff --git a/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts b/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts index 81e7346983..03c959eec6 100644 --- a/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts +++ b/src/panels/lovelace/cards/tile/badges/tile-badge-climate.ts @@ -2,6 +2,7 @@ import { mdiClockOutline, mdiFan, mdiFire, + mdiHeatWave, mdiPower, mdiSnowflake, mdiWaterPercent, @@ -21,6 +22,7 @@ export const CLIMATE_HVAC_ACTION_ICONS: Record = { heating: mdiFire, idle: mdiClockOutline, off: mdiPower, + preheating: mdiHeatWave, }; export const CLIMATE_HVAC_ACTION_MODE: Record = { @@ -30,6 +32,7 @@ export const CLIMATE_HVAC_ACTION_MODE: Record = { heating: "heat", idle: "off", off: "off", + preheating: "heat", }; export const computeClimateBadge: ComputeBadgeFunction = (stateObj) => { From 215f5e341af6dce1eea9214ed0c662a85713549a Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 19 Jun 2023 13:50:37 +0200 Subject: [PATCH 055/162] Put color wheel at the root level for more info light (#16909) --- src/components/ha-hs-color-picker.ts | 12 +- src/components/ha-icon-button-group.ts | 38 ++ src/components/ha-icon-button-toggle.ts | 52 +++ src/components/ha-temp-color-picker.ts | 9 +- src/data/light.ts | 2 + .../lights/dialog-light-color-favorite.ts | 195 +++++++++-- .../ha-more-info-light-favorite-colors.ts | 10 +- .../ha-more-info-view-light-color-picker.ts | 51 --- ...or-picker.ts => light-color-rgb-picker.ts} | 330 +++++------------- .../lights/light-color-temp-picker.ts | 146 ++++++++ .../show-dialog-light-color-favorite.ts | 2 +- .../lights/show-view-light-color-picker.ts | 23 -- .../more-info/controls/more-info-light.ts | 179 ++++++---- src/translations/en.json | 4 +- 14 files changed, 640 insertions(+), 413 deletions(-) create mode 100644 src/components/ha-icon-button-group.ts create mode 100644 src/components/ha-icon-button-toggle.ts delete mode 100644 src/dialogs/more-info/components/lights/ha-more-info-view-light-color-picker.ts rename src/dialogs/more-info/components/lights/{light-color-picker.ts => light-color-rgb-picker.ts} (59%) create mode 100644 src/dialogs/more-info/components/lights/light-color-temp-picker.ts delete mode 100644 src/dialogs/more-info/components/lights/show-view-light-color-picker.ts diff --git a/src/components/ha-hs-color-picker.ts b/src/components/ha-hs-color-picker.ts index 1533e2b6c4..ba5d038526 100644 --- a/src/components/ha-hs-color-picker.ts +++ b/src/components/ha-hs-color-picker.ts @@ -186,9 +186,8 @@ class HaHsColorPicker extends LitElement { } if (changedProps.has("value")) { if ( - this.value !== undefined && - (this._localValue?.[0] !== this.value[0] || - this._localValue?.[1] !== this.value[1]) + this._localValue?.[0] !== this.value?.[0] || + this._localValue?.[1] !== this.value?.[1] ) { this._resetPosition(); } @@ -243,7 +242,11 @@ class HaHsColorPicker extends LitElement { } private _resetPosition() { - if (this.value === undefined) return; + if (this.value === undefined) { + this._cursorPosition = undefined; + this._localValue = undefined; + return; + } this._cursorPosition = this._getCoordsFromValue(this.value); this._localValue = this.value; } @@ -384,6 +387,7 @@ class HaHsColorPicker extends LitElement { canvas { width: 100%; height: 100%; + object-fit: contain; border-radius: 50%; cursor: pointer; } diff --git a/src/components/ha-icon-button-group.ts b/src/components/ha-icon-button-group.ts new file mode 100644 index 0000000000..cd739082ab --- /dev/null +++ b/src/components/ha-icon-button-group.ts @@ -0,0 +1,38 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement } from "lit/decorators"; + +@customElement("ha-icon-button-group") +export class HaIconButtonGroup extends LitElement { + protected render(): TemplateResult { + return html``; + } + + static get styles(): CSSResultGroup { + return css` + :host { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + height: 56px; + border-radius: 28px; + background-color: rgba(139, 145, 151, 0.1); + box-sizing: border-box; + width: auto; + padding: 4px; + gap: 4px; + } + ::slotted(.separator) { + background-color: rgba(var(--rgb-primary-text-color), 0.15); + width: 1px; + height: 40px; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button-group": HaIconButtonGroup; + } +} diff --git a/src/components/ha-icon-button-toggle.ts b/src/components/ha-icon-button-toggle.ts new file mode 100644 index 0000000000..56d0b37c82 --- /dev/null +++ b/src/components/ha-icon-button-toggle.ts @@ -0,0 +1,52 @@ +import { css, CSSResultGroup } from "lit"; +import { customElement, property } from "lit/decorators"; +import { HaIconButton } from "./ha-icon-button"; + +@customElement("ha-icon-button-toggle") +export class HaIconButtonToggle extends HaIconButton { + @property({ type: Boolean, reflect: true }) selected = false; + + static get styles(): CSSResultGroup { + return css` + :host { + position: relative; + } + mwc-icon-button { + position: relative; + transition: color 180ms ease-in-out; + } + mwc-icon-button::before { + opacity: 0; + transition: opacity 180ms ease-in-out; + background-color: var(--primary-text-color); + border-radius: 20px; + height: 40px; + width: 40px; + content: ""; + position: absolute; + top: -10px; + left: -10px; + bottom: -10px; + right: -10px; + margin: auto; + box-sizing: border-box; + } + :host([border-only]) mwc-icon-button::before { + background-color: transparent; + border: 2px solid var(--primary-text-color); + } + :host([selected]) mwc-icon-button { + color: var(--primary-background-color); + } + :host([selected]) mwc-icon-button::before { + opacity: 1; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button-toggle": HaIconButtonToggle; + } +} diff --git a/src/components/ha-temp-color-picker.ts b/src/components/ha-temp-color-picker.ts index 9070a46e28..b2f2b26dfc 100644 --- a/src/components/ha-temp-color-picker.ts +++ b/src/components/ha-temp-color-picker.ts @@ -139,7 +139,7 @@ class HaTempColorPicker extends LitElement { this.setAttribute("aria-valuemax", this.max.toString()); } if (changedProps.has("value")) { - if (this.value != null && this._localValue !== this.value) { + if (this._localValue !== this.value) { this._resetPosition(); } } @@ -197,7 +197,11 @@ class HaTempColorPicker extends LitElement { } private _resetPosition() { - if (this.value === undefined) return; + if (this.value === undefined) { + this._cursorPosition = undefined; + this._localValue = undefined; + return; + } const [, y] = this._getCoordsFromValue(this.value); const currentX = this._cursorPosition?.[0] ?? 0; const x = @@ -391,6 +395,7 @@ class HaTempColorPicker extends LitElement { canvas { width: 100%; height: 100%; + object-fit: contain; border-radius: 50%; transition: box-shadow 180ms ease-in-out; cursor: pointer; diff --git a/src/data/light.ts b/src/data/light.ts index 42a2507731..ed42fdeb5f 100644 --- a/src/data/light.ts +++ b/src/data/light.ts @@ -159,3 +159,5 @@ export const computeDefaultFavoriteColors = ( return colors; }; + +export const formatTempColor = (value: number) => `${value} K`; diff --git a/src/dialogs/more-info/components/lights/dialog-light-color-favorite.ts b/src/dialogs/more-info/components/lights/dialog-light-color-favorite.ts index 3c72999412..410ba70c04 100644 --- a/src/dialogs/more-info/components/lights/dialog-light-color-favorite.ts +++ b/src/dialogs/more-info/components/lights/dialog-light-color-favorite.ts @@ -1,16 +1,28 @@ import { mdiClose } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-button"; import "../../../../components/ha-dialog"; import "../../../../components/ha-dialog-header"; -import { EntityRegistryEntry } from "../../../../data/entity_registry"; -import { LightColor } from "../../../../data/light"; +import "../../../../components/ha-icon-button-toggle"; +import type { EntityRegistryEntry } from "../../../../data/entity_registry"; +import { + formatTempColor, + LightColor, + LightColorMode, + LightEntity, + lightSupportsColor, + lightSupportsColorMode, +} from "../../../../data/light"; import { haStyleDialog } from "../../../../resources/styles"; -import { HomeAssistant } from "../../../../types"; -import "./light-color-picker"; -import { LightColorFavoriteDialogParams } from "./show-dialog-light-color-favorite"; +import type { HomeAssistant } from "../../../../types"; +import "./light-color-rgb-picker"; +import "./light-color-temp-picker"; +import type { LightColorFavoriteDialogParams } from "./show-dialog-light-color-favorite"; + +export type LightPickerMode = "color_temp" | "color"; @customElement("dialog-light-color-favorite") class DialogLightColorFavorite extends LitElement { @@ -22,11 +34,26 @@ class DialogLightColorFavorite extends LitElement { @state() _color?: LightColor; + @state() private _mode?: LightPickerMode; + + @state() private _modes: LightPickerMode[] = []; + + @state() private _currentValue?: string; + + private _colorHovered(ev: CustomEvent) { + if (ev.detail && "color_temp_kelvin" in ev.detail) { + this._currentValue = formatTempColor(ev.detail.color_temp_kelvin); + } else { + this._currentValue = undefined; + } + } + public async showDialog( dialogParams: LightColorFavoriteDialogParams ): Promise { this._entry = dialogParams.entry; this._dialogParams = dialogParams; + this._updateModes(dialogParams.defaultMode); await this.updateComplete; } @@ -37,10 +64,43 @@ class DialogLightColorFavorite extends LitElement { fireEvent(this, "dialog-closed", { dialog: this.localName }); } + private _updateModes(defaultMode?: LightPickerMode) { + const supportsTemp = lightSupportsColorMode( + this.stateObj!, + LightColorMode.COLOR_TEMP + ); + + const supportsColor = lightSupportsColor(this.stateObj!); + + const modes: LightPickerMode[] = []; + if (supportsColor) { + modes.push("color"); + } + if (supportsTemp) { + modes.push("color_temp"); + } + + this._modes = modes; + this._mode = + defaultMode ?? + (this.stateObj!.attributes.color_mode + ? this.stateObj!.attributes.color_mode === LightColorMode.COLOR_TEMP + ? LightColorMode.COLOR_TEMP + : "color" + : this._modes[0]); + } + private _colorChanged(ev: CustomEvent) { this._color = ev.detail; } + get stateObj() { + return ( + this._entry && + (this.hass.states[this._entry.entity_id] as LightEntity | undefined) + ); + } + private async _cancel() { this._dialogParams?.cancel?.(); this.closeDialog(); @@ -55,8 +115,16 @@ class DialogLightColorFavorite extends LitElement { this.closeDialog(); } + private _modeChanged(ev): void { + const newMode = ev.currentTarget.mode; + if (newMode === this._mode) { + return; + } + this._mode = newMode; + } + protected render() { - if (!this._entry) { + if (!this._entry || !this.stateObj) { return nothing; } @@ -76,13 +144,58 @@ class DialogLightColorFavorite extends LitElement { > ${this._dialogParams?.title} - - +
+ ${this._currentValue} + ${this._modes.length > 1 + ? html` +
+ ${this._modes.map( + (value) => + html` + + + + ` + )} +
+ ` + : nothing} +
+ +
+ ${this._mode === "color_temp" + ? html` + + + ` + : nothing} + ${this._mode === "color" + ? html` + + + ` + : nothing} +
${this.hass.localize("ui.common.cancel")} @@ -101,16 +214,10 @@ class DialogLightColorFavorite extends LitElement { --dialog-content-padding: 0; } - light-color-picker { - display: flex; - flex-direction: column; - flex: 1; - } - @media all and (max-width: 450px), all and (max-height: 500px) { ha-dialog { --dialog-surface-margin-top: 100px; - --mdc-dialog-min-height: calc(100% - 100px); + --mdc-dialog-min-height: auto; --mdc-dialog-max-height: calc(100% - 100px); --ha-dialog-border-radius: var( --ha-dialog-bottom-sheet-border-radius, @@ -118,6 +225,54 @@ class DialogLightColorFavorite extends LitElement { ); } } + + .content { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 24px; + flex: 1; + } + .modes { + display: flex; + flex-direction: row; + justify-content: flex-end; + padding: 0 24px; + } + .wheel { + width: 30px; + height: 30px; + flex: none; + border-radius: 15px; + } + .wheel.color { + background-image: url("/static/images/color_wheel.png"); + background-size: cover; + } + .wheel.color_temp { + background: linear-gradient( + 0, + rgb(166, 209, 255) 0%, + white 50%, + rgb(255, 160, 0) 100% + ); + } + .value { + pointer-events: none; + position: absolute; + top: 0; + left: 0; + right: 0; + margin: auto; + font-style: normal; + font-weight: 500; + font-size: 16px; + height: 48px; + line-height: 48px; + letter-spacing: 0.1px; + text-align: center; + } `, ]; } diff --git a/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts b/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts index c8c3c8cc1b..ad00a5b105 100644 --- a/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts +++ b/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts @@ -30,10 +30,16 @@ import { } from "../../../../resources/sortable.ondemand"; import { HomeAssistant } from "../../../../types"; import { showConfirmationDialog } from "../../../generic/show-dialog-box"; +import type { LightPickerMode } from "./dialog-light-color-favorite"; import "./ha-favorite-color-button"; -import type { LightPickerMode } from "./light-color-picker"; import { showLightColorFavoriteDialog } from "./show-dialog-light-color-favorite"; +declare global { + interface HASSDomEvents { + "favorite-color-edit-started"; + } +} + @customElement("ha-more-info-light-favorite-colors") export class HaMoreInfoLightFavoriteColors extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -147,8 +153,8 @@ export class HaMoreInfoLightFavoriteColors extends LitElement { private _edit = async (index) => { // Make sure the current favorite color is set + fireEvent(this, "favorite-color-edit-started"); await this._apply(index); - const defaultMode: LightPickerMode = "color_temp_kelvin" in this._favoriteColors[index] ? "color_temp" diff --git a/src/dialogs/more-info/components/lights/ha-more-info-view-light-color-picker.ts b/src/dialogs/more-info/components/lights/ha-more-info-view-light-color-picker.ts deleted file mode 100644 index b556443f5e..0000000000 --- a/src/dialogs/more-info/components/lights/ha-more-info-view-light-color-picker.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; -import { customElement, property } from "lit/decorators"; -import { HomeAssistant } from "../../../../types"; -import "./light-color-picker"; -import { LightColorPickerViewParams } from "./show-view-light-color-picker"; - -@customElement("ha-more-info-view-light-color-picker") -class MoreInfoViewLightColorPicker extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property() public params?: LightColorPickerViewParams; - - protected render() { - if (!this.params) { - return nothing; - } - - return html` - - - `; - } - - static get styles(): CSSResultGroup { - return [ - css` - :host { - position: relative; - display: flex; - flex-direction: column; - flex: 1; - } - light-color-picker { - display: flex; - flex-direction: column; - flex: 1; - } - `, - ]; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-more-info-view-light-color-picker": MoreInfoViewLightColorPicker; - } -} diff --git a/src/dialogs/more-info/components/lights/light-color-picker.ts b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts similarity index 59% rename from src/dialogs/more-info/components/lights/light-color-picker.ts rename to src/dialogs/more-info/components/lights/light-color-rgb-picker.ts index 720cd2a5bb..cf50ae5c04 100644 --- a/src/dialogs/more-info/components/lights/light-color-picker.ts +++ b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts @@ -23,21 +23,18 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { throttle } from "../../../../common/util/throttle"; import "../../../../components/ha-button-toggle-group"; import "../../../../components/ha-hs-color-picker"; +import "../../../../components/ha-icon"; import "../../../../components/ha-icon-button-prev"; import "../../../../components/ha-labeled-slider"; import "../../../../components/ha-temp-color-picker"; import { - LightColor, getLightCurrentModeRgbColor, + LightColor, LightColorMode, LightEntity, - lightSupportsColor, lightSupportsColorMode, } from "../../../../data/light"; import { HomeAssistant } from "../../../../types"; -import "../../../../components/ha-icon"; - -export type LightPickerMode = "color_temp" | "color"; declare global { interface HASSDomEvents { @@ -45,13 +42,11 @@ declare global { } } -@customElement("light-color-picker") -class LightColorPicker extends LitElement { +@customElement("light-color-rgb-picker") +class LightRgbColorPicker extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property() public entityId!: string; - - @property() public defaultMode?: LightPickerMode; + @property({ attribute: false }) public stateObj!: LightEntity; @state() private _cwSliderValue?: number; @@ -65,16 +60,6 @@ class LightColorPicker extends LitElement { @state() private _hsPickerValue?: [number, number]; - @state() private _ctPickerValue?: number; - - @state() private _mode?: LightPickerMode; - - @state() private _modes: LightPickerMode[] = []; - - get stateObj() { - return this.hass.states[this.entityId] as LightEntity | undefined; - } - protected render() { if (!this.stateObj) { return nothing; @@ -100,135 +85,89 @@ class LightColorPicker extends LitElement { : ""; return html` - ${this._modes.length > 1 +
+ + + + +
+ ${supportsRgbw || supportsRgbww + ? html`` + : nothing} + ${supportsRgbw ? html` - - ${this._modes.map( - (value) => - html`` - )} - + + ` + : nothing} + ${supportsRgbww + ? html` + + ` : nothing} -
- ${this._mode === LightColorMode.COLOR_TEMP - ? html` -

- ${this._ctPickerValue ? `${this._ctPickerValue} K` : nothing} -

- - - ` - : nothing} - ${this._mode === "color" - ? html` -
- - - - -
- ${supportsRgbw || supportsRgbww - ? html`` - : nothing} - ${supportsRgbw - ? html` - - ` - : nothing} - ${supportsRgbww - ? html` - - - ` - : nothing} - ` - : nothing} -
`; } public _updateSliderValues() { const stateObj = this.stateObj; - if (stateObj?.state === "on") { + if (stateObj.state === "on") { this._brightnessAdjusted = undefined; if ( stateObj.attributes.color_mode === LightColorMode.RGB && @@ -242,10 +181,6 @@ class LightColorPicker extends LitElement { this._brightnessAdjusted = maxVal; } } - this._ctPickerValue = - stateObj.attributes.color_mode === LightColorMode.COLOR_TEMP - ? stateObj.attributes.color_temp_kelvin - : undefined; this._wvSliderValue = stateObj.attributes.color_mode === LightColorMode.RGBW && @@ -273,8 +208,7 @@ class LightColorPicker extends LitElement { ? rgb2hs(currentRgbColor.slice(0, 3) as [number, number, number]) : undefined; } else { - this._hsPickerValue = [0, 0]; - this._ctPickerValue = undefined; + this._hsPickerValue = undefined; this._wvSliderValue = undefined; this._cwSliderValue = undefined; this._wwSliderValue = undefined; @@ -288,43 +222,9 @@ class LightColorPicker extends LitElement { return; } - if (changedProps.has("entityId")) { - const supportsTemp = lightSupportsColorMode( - this.stateObj!, - LightColorMode.COLOR_TEMP - ); - - const supportsColor = lightSupportsColor(this.stateObj!); - - const modes: LightPickerMode[] = []; - if (supportsColor) { - modes.push("color"); - } - if (supportsTemp) { - modes.push("color_temp"); - } - - this._modes = modes; - this._mode = - this.defaultMode ?? - (this.stateObj!.attributes.color_mode - ? this.stateObj!.attributes.color_mode === LightColorMode.COLOR_TEMP - ? LightColorMode.COLOR_TEMP - : "color" - : this._modes[0]); - } - this._updateSliderValues(); } - private _handleTabChanged(ev: CustomEvent): void { - const newMode = this._modes[ev.detail.index]; - if (newMode === this._mode) { - return; - } - this._mode = newMode; - } - private _hsColorCursorMoved(ev: CustomEvent) { if (!ev.detail.value) { return; @@ -404,40 +304,6 @@ class LightColorPicker extends LitElement { this._updateColor(); } - private _ctColorCursorMoved(ev: CustomEvent) { - const ct = ev.detail.value; - - if (isNaN(ct) || this._ctPickerValue === ct) { - return; - } - - this._ctPickerValue = ct; - - this._throttleUpdateColorTemp(); - } - - private _throttleUpdateColorTemp = throttle(() => { - this._updateColorTemp(); - }, 500); - - private _ctColorChanged(ev: CustomEvent) { - const ct = ev.detail.value; - - if (isNaN(ct) || this._ctPickerValue === ct) { - return; - } - - this._ctPickerValue = ct; - - this._updateColorTemp(); - } - - private _updateColorTemp() { - const color_temp_kelvin = this._ctPickerValue!; - - this._applyColor({ color_temp_kelvin }); - } - private _wvSliderChanged(ev: CustomEvent) { const target = ev.target as any; let wv = Number(target.value); @@ -574,19 +440,12 @@ class LightColorPicker extends LitElement { display: flex; flex-direction: column; } - .content { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 24px; - flex: 1; - } .native-color-picker { position: absolute; top: 0; right: 0; + z-index: 1; } .native-color-picker ha-svg-icon { @@ -639,37 +498,18 @@ class LightColorPicker extends LitElement { .color-container { position: relative; - max-width: 300px; - min-width: 200px; - margin: 0 0 44px 0; - padding-top: 44px; } ha-hs-color-picker { - width: 100%; - } - - ha-temp-color-picker { - max-width: 300px; - min-width: 200px; - margin: 20px 0 44px 0; + height: 45vh; + max-height: 320px; + min-height: 200px; } ha-labeled-slider { width: 100%; } - .color-temp-value { - font-style: normal; - font-weight: 500; - font-size: 16px; - height: 24px; - line-height: 24px; - letter-spacing: 0.1px; - margin: 0; - direction: ltr; - } - hr { border-color: var(--divider-color); border-bottom: none; @@ -682,6 +522,6 @@ class LightColorPicker extends LitElement { declare global { interface HTMLElementTagNameMap { - "light-color-picker": LightColorPicker; + "light-color-rgb-picker": LightRgbColorPicker; } } diff --git a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts new file mode 100644 index 0000000000..4543c0dc88 --- /dev/null +++ b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts @@ -0,0 +1,146 @@ +import { + css, + CSSResultGroup, + html, + LitElement, + nothing, + PropertyValues, +} from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import { throttle } from "../../../../common/util/throttle"; +import "../../../../components/ha-temp-color-picker"; +import { + LightColor, + LightColorMode, + LightEntity, +} from "../../../../data/light"; +import { HomeAssistant } from "../../../../types"; + +declare global { + interface HASSDomEvents { + "color-changed": LightColor; + "color-hovered": LightColor | undefined; + } +} + +@customElement("light-color-temp-picker") +class LightColorTempPicker extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj!: LightEntity; + + @state() private _ctPickerValue?: number; + + protected render() { + if (!this.stateObj) { + return nothing; + } + + return html` + + + `; + } + + public _updateSliderValues() { + const stateObj = this.stateObj; + + if (stateObj.state === "on") { + this._ctPickerValue = + stateObj.attributes.color_mode === LightColorMode.COLOR_TEMP + ? stateObj.attributes.color_temp_kelvin + : undefined; + } else { + this._ctPickerValue = undefined; + } + } + + public willUpdate(changedProps: PropertyValues) { + super.willUpdate(changedProps); + + if (!changedProps.has("stateObj")) { + return; + } + + this._updateSliderValues(); + } + + private _ctColorCursorMoved(ev: CustomEvent) { + const ct = ev.detail.value; + + if (isNaN(ct) || this._ctPickerValue === ct) { + return; + } + + this._ctPickerValue = ct; + + fireEvent(this, "color-hovered", { + color_temp_kelvin: ct, + }); + + this._throttleUpdateColorTemp(); + } + + private _throttleUpdateColorTemp = throttle(() => { + this._updateColorTemp(); + }, 500); + + private _ctColorChanged(ev: CustomEvent) { + const ct = ev.detail.value; + + fireEvent(this, "color-hovered", undefined); + + if (isNaN(ct) || this._ctPickerValue === ct) { + return; + } + + this._ctPickerValue = ct; + + this._updateColorTemp(); + } + + private _updateColorTemp() { + const color_temp_kelvin = this._ctPickerValue!; + + this._applyColor({ color_temp_kelvin }); + } + + private _applyColor(color: LightColor, params?: Record) { + fireEvent(this, "color-changed", color); + this.hass.callService("light", "turn_on", { + entity_id: this.stateObj!.entity_id, + ...color, + ...params, + }); + } + + static get styles(): CSSResultGroup { + return [ + css` + :host { + display: flex; + flex-direction: column; + } + + ha-temp-color-picker { + height: 45vh; + max-height: 320px; + min-height: 200px; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "light-color-temp-picker": LightColorTempPicker; + } +} diff --git a/src/dialogs/more-info/components/lights/show-dialog-light-color-favorite.ts b/src/dialogs/more-info/components/lights/show-dialog-light-color-favorite.ts index 28f0af8622..d8bc865093 100644 --- a/src/dialogs/more-info/components/lights/show-dialog-light-color-favorite.ts +++ b/src/dialogs/more-info/components/lights/show-dialog-light-color-favorite.ts @@ -1,7 +1,7 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import { ExtEntityRegistryEntry } from "../../../../data/entity_registry"; import { LightColor } from "../../../../data/light"; -import type { LightPickerMode } from "./light-color-picker"; +import type { LightPickerMode } from "./dialog-light-color-favorite"; export interface LightColorFavoriteDialogParams { entry: ExtEntityRegistryEntry; diff --git a/src/dialogs/more-info/components/lights/show-view-light-color-picker.ts b/src/dialogs/more-info/components/lights/show-view-light-color-picker.ts deleted file mode 100644 index 5a2bd40fa1..0000000000 --- a/src/dialogs/more-info/components/lights/show-view-light-color-picker.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { fireEvent } from "../../../../common/dom/fire_event"; -import type { LightPickerMode } from "./light-color-picker"; - -export interface LightColorPickerViewParams { - entityId: string; - defaultMode: LightPickerMode; -} - -export const loadLightColorPickerView = () => - import("./ha-more-info-view-light-color-picker"); - -export const showLightColorPickerView = ( - element: HTMLElement, - title: string, - params: LightColorPickerViewParams -): void => { - fireEvent(element, "show-child-view", { - viewTag: "ha-more-info-view-light-color-picker", - viewImport: loadLightColorPickerView, - viewTitle: title, - viewParams: params, - }); -}; diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts index 45597b228d..730175c8dd 100644 --- a/src/dialogs/more-info/controls/more-info-light.ts +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -1,5 +1,6 @@ import "@material/mwc-list/mwc-list-item"; import { + mdiBrightness6, mdiCreation, mdiFileWordBox, mdiLightbulb, @@ -24,6 +25,8 @@ import { supportsFeature } from "../../../common/entity/supports-feature"; import { blankBeforePercent } from "../../../common/translations/blank_before_percent"; import "../../../components/ha-attributes"; import "../../../components/ha-button-menu"; +import "../../../components/ha-icon-button-group"; +import "../../../components/ha-icon-button-toggle"; import "../../../components/ha-outlined-button"; import "../../../components/ha-outlined-icon-button"; import "../../../components/ha-select"; @@ -31,6 +34,7 @@ import { UNAVAILABLE } from "../../../data/entity"; import { ExtEntityRegistryEntry } from "../../../data/entity_registry"; import { forwardHaptic } from "../../../data/haptics"; import { + formatTempColor, LightColorMode, LightEntity, LightEntityFeature, @@ -46,7 +50,10 @@ import "../components/ha-more-info-toggle"; import "../components/lights/ha-favorite-color-button"; import "../components/lights/ha-more-info-light-brightness"; import "../components/lights/ha-more-info-light-favorite-colors"; -import { showLightColorPickerView } from "../components/lights/show-view-light-color-picker"; +import "../components/lights/light-color-rgb-picker"; +import "../components/lights/light-color-temp-picker"; + +type MainControl = "brightness" | "color_temp" | "color"; @customElement("more-info-light") class MoreInfoLight extends LitElement { @@ -62,12 +69,24 @@ class MoreInfoLight extends LitElement { @state() private _selectedBrightness?: number; + @state() private _colorTempPreview?: number; + + @state() private _mainControl: MainControl = "brightness"; + private _brightnessChanged(ev) { const value = (ev.detail as any).value; if (isNaN(value)) return; this._selectedBrightness = value; } + private _tempColorHovered(ev: CustomEvent) { + if (ev.detail && "color_temp_kelvin" in ev.detail) { + this._colorTempPreview = ev.detail.color_temp_kelvin; + } else { + this._colorTempPreview = undefined; + } + } + protected updated(changedProps: PropertyValues): void { if (changedProps.has("stateObj")) { this._selectedBrightness = this.stateObj?.attributes.brightness @@ -77,6 +96,28 @@ class MoreInfoLight extends LitElement { } } + private _setMainControl(ev: any) { + ev.stopPropagation(); + this._mainControl = ev.currentTarget.control; + } + + private _resetMainControl(ev: any) { + ev.stopPropagation(); + this._mainControl = "brightness"; + } + + private get _stateOverride() { + if (this._colorTempPreview) { + return formatTempColor(this._colorTempPreview); + } + if (this._selectedBrightness) { + return `${Math.round(this._selectedBrightness)}${blankBeforePercent( + this.hass!.locale + )}%`; + } + return undefined; + } + protected render() { if (!this.hass || !this.stateObj) { return nothing; @@ -106,47 +147,60 @@ class MoreInfoLight extends LitElement { (this.entry.options?.light?.favorite_colors == null || this.entry.options.light.favorite_colors.length > 0); - const stateOverride = this._selectedBrightness - ? `${Math.round(this._selectedBrightness)}${blankBeforePercent( - this.hass!.locale - )}%` - : undefined; - return html`
- ${supportsBrightness + ${!supportsBrightness ? html` - - - ` - : html` - `} + ` + : nothing} ${supportsColorTemp || supportsColor || supportsBrightness ? html` -
+ ${supportsBrightness && this._mainControl === "brightness" + ? html` + + + ` + : nothing} + ${supportsColor && this._mainControl === "color" + ? html` + + + ` + : nothing} + ${supportsColorTemp && this._mainControl === "color_temp" + ? html` + + + ` + : nothing} + ${supportsBrightness ? html` ` : nothing} + ${supportsColor || supportsColorTemp + ? html` +
+ + + + ` + : nothing} ${supportsColor ? html` - - + ` : nothing} ${supportsColorTemp ? html` - - + ` : nothing} ${supportsWhite ? html` +
` : nothing} -
+ ${this.entry && lightSupportsFavoriteColors(this.stateObj) && (this.editMode || hasFavoriteColors) @@ -216,6 +281,7 @@ class MoreInfoLight extends LitElement { .stateObj=${this.stateObj} .entry=${this.entry} .editMode=${this.editMode} + @favorite-color-edit-started=${this._resetMainControl} > ` @@ -291,19 +357,6 @@ class MoreInfoLight extends LitElement { }); }; - private _showLightColorPickerView = (ev) => { - showLightColorPickerView( - this, - this.hass.localize( - "ui.dialogs.more_info_control.light.color_picker.title" - ), - { - entityId: this.stateObj!.entity_id, - defaultMode: ev.currentTarget.mode, - } - ); - }; - private _setWhite = () => { this.hass.callService("light", "turn_on", { entity_id: this.stateObj!.entity_id, @@ -347,9 +400,6 @@ class MoreInfoLight extends LitElement { flex: none; border-radius: 15px; } - ha-icon-button[disabled] .wheel { - filter: grayscale(1) opacity(0.5); - } .wheel.color { background-image: url("/static/images/color_wheel.png"); background-size: cover; @@ -362,6 +412,9 @@ class MoreInfoLight extends LitElement { rgb(255, 160, 0) 100% ); } + *[disabled] .wheel { + filter: grayscale(1) opacity(0.5); + } .buttons { flex-wrap: wrap; max-width: 250px; diff --git a/src/translations/en.json b/src/translations/en.json index 2b46e38cca..125ac84814 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -929,8 +929,8 @@ "light": { "edit_mode": "Edit favorite colors", "toggle": "Toggle", - "change_color": "Change color", - "change_color_temp": "Change color temperature", + "color": "Color", + "color_temp": "Temperature", "set_white": "Set white", "select_effect": "Select effect", "brightness": "Brightness", From cdd29c8bf7679b1c01468c070cff13d6d5cc8184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 19 Jun 2023 13:54:47 +0200 Subject: [PATCH 056/162] Add help button to get documentation from mount dialog (#16932) --- .../config/storage/dialog-mount-view.ts | 34 +++++++++++++++++++ src/translations/en.json | 1 + 2 files changed, 35 insertions(+) diff --git a/src/panels/config/storage/dialog-mount-view.ts b/src/panels/config/storage/dialog-mount-view.ts index 624d4889a6..52592a9b67 100644 --- a/src/panels/config/storage/dialog-mount-view.ts +++ b/src/panels/config/storage/dialog-mount-view.ts @@ -1,8 +1,10 @@ import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; +import { mdiHelpCircle } from "@mdi/js"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-form/ha-form"; +import "../../../components/ha-icon-button"; import { extractApiErrorMessage } from "../../../data/hassio/common"; import { createSupervisorMount, @@ -17,6 +19,8 @@ import { HomeAssistant } from "../../../types"; import { MountViewDialogParams } from "./show-dialog-view-mount"; import { LocalizeFunc } from "../../../common/translations/localize"; import type { SchemaUnion } from "../../../components/ha-form/types"; +import { documentationUrl } from "../../../util/documentation-url"; +import { computeRTLDirection } from "../../../common/util/compute_rtl"; const mountSchema = memoizeOne( ( @@ -158,6 +162,33 @@ class ViewMountDialog extends LitElement { )} @closed=${this.closeDialog} > + + ${this._existing + ? this.hass.localize( + "ui.panel.config.storage.network_mounts.update_title" + ) + : this.hass.localize( + "ui.panel.config.storage.network_mounts.add_title" + )} + + + + + ${this._error ? html`${this._error}` : nothing} @@ -274,6 +305,9 @@ class ViewMountDialog extends LitElement { haStyle, haStyleDialog, css` + ha-icon-button { + color: var(--primary-text-color); + } .delete-btn { --mdc-theme-primary: var(--error-color); } diff --git a/src/translations/en.json b/src/translations/en.json index 125ac84814..50ceeab10f 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4055,6 +4055,7 @@ "add_title": "Add network storage", "update_title": "Update network storage", "no_mounts": "No connected network storage", + "documentation": "Documentation", "not_supported": { "title": "The operating system does not support network storage", "supervised": "Network storage is not supported on this host", From fa75b18a6b0ba2a9f5bf058cb55758e9c0efd388 Mon Sep 17 00:00:00 2001 From: Till Date: Mon, 19 Jun 2023 13:59:20 +0200 Subject: [PATCH 057/162] Add self-sufficiency gauge card (#15704) Co-authored-by: Bram Kragten --- .../energy/strategies/energy-strategy.ts | 5 + .../hui-energy-self-sufficiency-gauge-card.ts | 257 ++++++++++++++++++ .../hui-energy-solar-consumed-gauge-card.ts | 9 +- src/panels/lovelace/cards/types.ts | 7 + .../create-element/create-card-element.ts | 2 + src/translations/en.json | 5 + 6 files changed, 281 insertions(+), 4 deletions(-) create mode 100644 src/panels/lovelace/cards/energy/hui-energy-self-sufficiency-gauge-card.ts mode change 100755 => 100644 src/translations/en.json diff --git a/src/panels/energy/strategies/energy-strategy.ts b/src/panels/energy/strategies/energy-strategy.ts index de5d6aca44..42b0c6678a 100644 --- a/src/panels/energy/strategies/energy-strategy.ts +++ b/src/panels/energy/strategies/energy-strategy.ts @@ -141,6 +141,11 @@ export class EnergyStrategy { view_layout: { position: "sidebar" }, collection_key: "energy_dashboard", }); + view.cards!.push({ + type: "energy-self-sufficiency-gauge", + view_layout: { position: "sidebar" }, + collection_key: "energy_dashboard", + }); } // Only include if we have a grid diff --git a/src/panels/lovelace/cards/energy/hui-energy-self-sufficiency-gauge-card.ts b/src/panels/lovelace/cards/energy/hui-energy-self-sufficiency-gauge-card.ts new file mode 100644 index 0000000000..d1b3221f6f --- /dev/null +++ b/src/panels/lovelace/cards/energy/hui-energy-self-sufficiency-gauge-card.ts @@ -0,0 +1,257 @@ +import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; +import { mdiInformation } from "@mdi/js"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { styleMap } from "lit/directives/style-map"; +import "../../../../components/ha-card"; +import "../../../../components/ha-gauge"; +import "../../../../components/ha-svg-icon"; +import { + EnergyData, + energySourcesByType, + getEnergyDataCollection, +} from "../../../../data/energy"; +import { calculateStatisticsSumGrowth } from "../../../../data/recorder"; +import { SubscribeMixin } from "../../../../mixins/subscribe-mixin"; +import type { HomeAssistant } from "../../../../types"; +import type { LovelaceCard } from "../../types"; +import { severityMap } from "../hui-gauge-card"; +import type { EnergySelfSufficiencyGaugeCardConfig } from "../types"; + +@customElement("hui-energy-self-sufficiency-gauge-card") +class HuiEnergySelfSufficiencyGaugeCard + extends SubscribeMixin(LitElement) + implements LovelaceCard +{ + @property({ attribute: false }) public hass?: HomeAssistant; + + @state() private _config?: EnergySelfSufficiencyGaugeCardConfig; + + @state() private _data?: EnergyData; + + protected hassSubscribeRequiredHostProps = ["_config"]; + + public hassSubscribe(): UnsubscribeFunc[] { + return [ + getEnergyDataCollection(this.hass!, { + key: this._config?.collection_key, + }).subscribe((data) => { + this._data = data; + }), + ]; + } + + public getCardSize(): number { + return 4; + } + + public setConfig(config: EnergySelfSufficiencyGaugeCardConfig): void { + this._config = config; + } + + protected render() { + if (!this._config || !this.hass) { + return nothing; + } + + if (!this._data) { + return html`${this.hass.localize( + "ui.panel.lovelace.cards.energy.loading" + )}`; + } + + const prefs = this._data.prefs; + const types = energySourcesByType(prefs); + + // The strategy only includes this card if we have a grid. + const hasConsumption = true; + + const hasSolarProduction = types.solar !== undefined; + const hasBattery = types.battery !== undefined; + const hasReturnToGrid = hasConsumption && types.grid![0].flow_to.length > 0; + + const totalFromGrid = + calculateStatisticsSumGrowth( + this._data.stats, + types.grid![0].flow_from.map((flow) => flow.stat_energy_from) + ) ?? 0; + + let totalSolarProduction: number | null = null; + + if (hasSolarProduction) { + totalSolarProduction = + calculateStatisticsSumGrowth( + this._data.stats, + types.solar!.map((source) => source.stat_energy_from) + ) || 0; + } + + let totalBatteryIn: number | null = null; + let totalBatteryOut: number | null = null; + + if (hasBattery) { + totalBatteryIn = + calculateStatisticsSumGrowth( + this._data.stats, + types.battery!.map((source) => source.stat_energy_to) + ) || 0; + totalBatteryOut = + calculateStatisticsSumGrowth( + this._data.stats, + types.battery!.map((source) => source.stat_energy_from) + ) || 0; + } + + let returnedToGrid: number | null = null; + + if (hasReturnToGrid) { + returnedToGrid = + calculateStatisticsSumGrowth( + this._data.stats, + types.grid![0].flow_to.map((flow) => flow.stat_energy_to) + ) || 0; + } + + let solarConsumption: number | null = null; + if (hasSolarProduction) { + solarConsumption = + (totalSolarProduction || 0) - + (returnedToGrid || 0) - + (totalBatteryIn || 0); + } + + let batteryFromGrid: null | number = null; + let batteryToGrid: null | number = null; + if (solarConsumption !== null && solarConsumption < 0) { + // What we returned to the grid and what went in to the battery is more than produced, + // so we have used grid energy to fill the battery + // or returned battery energy to the grid + if (hasBattery) { + batteryFromGrid = solarConsumption * -1; + if (batteryFromGrid > totalFromGrid) { + batteryToGrid = Math.min(0, batteryFromGrid - totalFromGrid); + batteryFromGrid = totalFromGrid; + } + } + solarConsumption = 0; + } + + let batteryConsumption: number | null = null; + if (hasBattery) { + batteryConsumption = (totalBatteryOut || 0) - (batteryToGrid || 0); + } + + const gridConsumption = Math.max(0, totalFromGrid - (batteryFromGrid || 0)); + + const totalHomeConsumption = Math.max( + 0, + gridConsumption + (solarConsumption || 0) + (batteryConsumption || 0) + ); + + let value: number | undefined; + if ( + totalFromGrid !== null && + totalHomeConsumption !== null && + totalHomeConsumption > 0 + ) { + value = (1 - totalFromGrid / totalHomeConsumption) * 100; + } + + return html` + + ${value !== undefined + ? html` + + + + ${this.hass.localize( + "ui.panel.lovelace.cards.energy.self_sufficiency_gauge.card_indicates_self_sufficiency_quota" + )} + + + +
+ ${this.hass.localize( + "ui.panel.lovelace.cards.energy.self_sufficiency_gauge.self_sufficiency_quota" + )} +
+ ` + : this.hass.localize( + "ui.panel.lovelace.cards.energy.self_sufficiency_gauge.self_sufficiency_could_not_calc" + )} +
+ `; + } + + private _computeSeverity(numberValue: number): string { + if (numberValue > 75) { + return severityMap.green; + } + if (numberValue < 50) { + return severityMap.yellow; + } + return severityMap.normal; + } + + static get styles(): CSSResultGroup { + return css` + ha-card { + height: 100%; + overflow: hidden; + padding: 16px; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + box-sizing: border-box; + } + + ha-gauge { + width: 100%; + max-width: 250px; + direction: ltr; + } + + .name { + text-align: center; + line-height: initial; + color: var(--primary-text-color); + width: 100%; + font-size: 15px; + margin-top: 8px; + } + + ha-svg-icon { + position: absolute; + right: 4px; + top: 4px; + color: var(--secondary-text-color); + } + simple-tooltip > span { + font-size: 12px; + line-height: 12px; + } + simple-tooltip { + width: 80%; + max-width: 250px; + top: 8px !important; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-energy-self-sufficiency-gauge-card": HuiEnergySelfSufficiencyGaugeCard; + } +} diff --git a/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts b/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts index 0365164fb7..4f5e6cbfdf 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-solar-consumed-gauge-card.ts @@ -68,10 +68,11 @@ class HuiEnergySolarGaugeCard return nothing; } - const totalSolarProduction = calculateStatisticsSumGrowth( - this._data.stats, - types.solar.map((source) => source.stat_energy_from) - ); + const totalSolarProduction = + calculateStatisticsSumGrowth( + this._data.stats, + types.solar.map((source) => source.stat_energy_from) + ) || 0; const productionReturnedToGrid = calculateStatisticsSumGrowth( this._data.stats, diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index 0e65d9a46a..fac076ad93 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -159,6 +159,13 @@ export interface EnergySolarGaugeCardConfig extends LovelaceCardConfig { collection_key?: string; } +export interface EnergySelfSufficiencyGaugeCardConfig + extends LovelaceCardConfig { + type: "energy-self-sufficiency-gauge"; + title?: string; + collection_key?: string; +} + export interface EnergyGridGaugeCardConfig extends LovelaceCardConfig { type: "energy-grid-result-gauge"; title?: string; diff --git a/src/panels/lovelace/create-element/create-card-element.ts b/src/panels/lovelace/create-element/create-card-element.ts index 98390dc9bf..3ecd7b4a16 100644 --- a/src/panels/lovelace/create-element/create-card-element.ts +++ b/src/panels/lovelace/create-element/create-card-element.ts @@ -53,6 +53,8 @@ const LAZY_LOAD_TYPES = { import("../cards/energy/hui-energy-grid-neutrality-gauge-card"), "energy-solar-consumed-gauge": () => import("../cards/energy/hui-energy-solar-consumed-gauge-card"), + "energy-self-sufficiency-gauge": () => + import("../cards/energy/hui-energy-self-sufficiency-gauge-card"), "energy-solar-graph": () => import("../cards/energy/hui-energy-solar-graph-card"), "energy-sources-table": () => diff --git a/src/translations/en.json b/src/translations/en.json old mode 100755 new mode 100644 index 50ceeab10f..25900e1209 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4219,6 +4219,11 @@ "not_produced_solar_energy": "You have not produced any solar energy", "self_consumed_solar_could_not_calc": "Self-consumed solar energy couldn't be calculated" }, + "self_sufficiency_gauge": { + "card_indicates_self_sufficiency_quota": "This card indicates how self-sufficient your home is.", + "self_sufficiency_quota": "Self-sufficiency quota", + "self_sufficiency_could_not_calc": "Self-sufficiency quota couldn't be calculated" + }, "grid_neutrality_gauge": { "energy_dependency": "This card indicates your net energy usage.", "color_explain": "If the needle is in the purple, you returned more energy to the grid than you consumed from it. If it's in the blue, you consumed more energy from the grid than you returned.", From 1d0d4755d048659282613eae6dca862c240e6de1 Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Mon, 19 Jun 2023 08:30:16 -0400 Subject: [PATCH 058/162] Update lit-analyzer and ts-lit-plugin to version 2 (#16954) --- package.json | 4 +- yarn.lock | 120 ++++++++++++++++++--------------------------------- 2 files changed, 44 insertions(+), 80 deletions(-) diff --git a/package.json b/package.json index 43c1f40927..1666cce1ec 100644 --- a/package.json +++ b/package.json @@ -215,7 +215,7 @@ "instant-mocha": "1.5.1", "jszip": "3.10.1", "lint-staged": "13.2.2", - "lit-analyzer": "1.2.1", + "lit-analyzer": "2.0.0-pre.3", "lodash.template": "4.5.0", "magic-string": "0.30.0", "map-stream": "0.0.7", @@ -235,7 +235,7 @@ "systemjs": "6.14.1", "tar": "6.1.15", "terser-webpack-plugin": "5.3.9", - "ts-lit-plugin": "1.2.1", + "ts-lit-plugin": "2.0.0-pre.1", "typescript": "4.9.5", "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", diff --git a/yarn.lock b/yarn.lock index 0f0d787f5f..9f00d1a62a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3166,16 +3166,6 @@ __metadata: languageName: node linkType: hard -"@mrmlnc/readdir-enhanced@npm:^2.2.1": - version: 2.2.1 - resolution: "@mrmlnc/readdir-enhanced@npm:2.2.1" - dependencies: - call-me-maybe: ^1.0.1 - glob-to-regexp: ^0.3.0 - checksum: d3b82b29368821154ce8e10bef5ccdbfd070d3e9601643c99ea4607e56f3daeaa4e755dd6d2355da20762c695c1b0570543d9f84b48f70c211ec09c4aaada2e1 - languageName: node - linkType: hard - "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -3193,13 +3183,6 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.stat@npm:^1.1.2": - version: 1.1.3 - resolution: "@nodelib/fs.stat@npm:1.1.3" - checksum: 318deab369b518a34778cdaa0054dd28a4381c0c78e40bbd20252f67d084b1d7bf9295fea4423de2c19ac8e1a34f120add9125f481b2a710f7068bcac7e3e305 - languageName: node - linkType: hard - "@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" @@ -5065,6 +5048,13 @@ __metadata: languageName: node linkType: hard +"@vscode/web-custom-data@npm:^0.4.2": + version: 0.4.6 + resolution: "@vscode/web-custom-data@npm:0.4.6" + checksum: 2d87f3e50dc6eeacdbbca224f1c8837154acd6e1588f733ff812423e72f0a14d819740bbb91732a9c09978faa0fcfe1be339a17fd0beb130e51784752cef4b4f + languageName: node + linkType: hard + "@vue/compiler-sfc@npm:2.7.14": version: 2.7.14 resolution: "@vue/compiler-sfc@npm:2.7.14" @@ -6472,13 +6462,6 @@ __metadata: languageName: node linkType: hard -"call-me-maybe@npm:^1.0.1": - version: 1.0.2 - resolution: "call-me-maybe@npm:1.0.2" - checksum: 42ff2d0bed5b207e3f0122589162eaaa47ba618f79ad2382fe0ba14d9e49fbf901099a6227440acc5946f86a4953e8aa2d242b330b0a5de4d090bb18f8935cae - languageName: node - linkType: hard - "callsites@npm:^3.0.0": version: 3.1.0 resolution: "callsites@npm:3.1.0" @@ -8494,20 +8477,6 @@ __metadata: languageName: node linkType: hard -"fast-glob@npm:^2.2.6": - version: 2.2.7 - resolution: "fast-glob@npm:2.2.7" - dependencies: - "@mrmlnc/readdir-enhanced": ^2.2.1 - "@nodelib/fs.stat": ^1.1.2 - glob-parent: ^3.1.0 - is-glob: ^4.0.0 - merge2: ^1.2.3 - micromatch: ^3.1.10 - checksum: 304ccff1d437fcc44ae0168b0c3899054b92e0fd6af6ad7c3ccc82ab4ddd210b99c7c739d60ee3686da2aa165cd1a31810b31fd91f7c2a575d297342a9fc0534 - languageName: node - linkType: hard - "fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.2, fast-glob@npm:^3.2.9": version: 3.2.12 resolution: "fast-glob@npm:3.2.12" @@ -9141,13 +9110,6 @@ __metadata: languageName: node linkType: hard -"glob-to-regexp@npm:^0.3.0": - version: 0.3.0 - resolution: "glob-to-regexp@npm:0.3.0" - checksum: d34b3219d860042d508c4893b67617cd16e2668827e445ff39cff9f72ef70361d3dc24f429e003cdfb6607c75c9664b8eadc41d2eeb95690af0b0d3113c1b23b - languageName: node - linkType: hard - "glob-to-regexp@npm:^0.4.1": version: 0.4.1 resolution: "glob-to-regexp@npm:0.4.1" @@ -9763,7 +9725,7 @@ __metadata: leaflet-draw: 1.0.4 lint-staged: 13.2.2 lit: 2.7.5 - lit-analyzer: 1.2.1 + lit-analyzer: 2.0.0-pre.3 lodash.template: 4.5.0 magic-string: 0.30.0 map-stream: 0.0.7 @@ -9796,7 +9758,7 @@ __metadata: tar: 6.1.15 terser-webpack-plugin: 5.3.9 tinykeys: 2.1.0 - ts-lit-plugin: 1.2.1 + ts-lit-plugin: 2.0.0-pre.1 tsparticles-engine: 2.10.1 tsparticles-preset-links: 2.10.1 typescript: 4.9.5 @@ -11367,21 +11329,22 @@ __metadata: languageName: node linkType: hard -"lit-analyzer@npm:1.2.1": - version: 1.2.1 - resolution: "lit-analyzer@npm:1.2.1" +"lit-analyzer@npm:2.0.0-pre.3, lit-analyzer@npm:^2.0.0-pre.3": + version: 2.0.0-pre.3 + resolution: "lit-analyzer@npm:2.0.0-pre.3" dependencies: + "@vscode/web-custom-data": ^0.4.2 chalk: ^2.4.2 didyoumean2: 4.1.0 - fast-glob: ^2.2.6 + fast-glob: ^3.2.11 parse5: 5.1.0 - ts-simple-type: ~1.0.5 + ts-simple-type: ~2.0.0-next.0 vscode-css-languageservice: 4.3.0 vscode-html-languageservice: 3.1.0 - web-component-analyzer: ~1.1.1 + web-component-analyzer: ^2.0.0-next.5 bin: lit-analyzer: cli.js - checksum: b89646033b45262a863bf32d8bf177bfa4f22cde4e2c3f2cd006abdd68aeab434505f67c3c5ed213d8a5936d063ec2845efb15b0968ec9cf9e0863e53e6c118c + checksum: c6dcf657a0030342d183fcd9d550753bd5dd0692b478aff271085a5a0e7e08aff39cc6dde3d547ffca72897975ef07aac7de8a97e0060d2db70a85350412efae languageName: node linkType: hard @@ -11798,7 +11761,7 @@ __metadata: languageName: node linkType: hard -"merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 @@ -15215,19 +15178,20 @@ __metadata: languageName: node linkType: hard -"ts-lit-plugin@npm:1.2.1": - version: 1.2.1 - resolution: "ts-lit-plugin@npm:1.2.1" +"ts-lit-plugin@npm:2.0.0-pre.1": + version: 2.0.0-pre.1 + resolution: "ts-lit-plugin@npm:2.0.0-pre.1" dependencies: - lit-analyzer: 1.2.1 - checksum: 3ba191d8924b18ba1aa1072db82cd10bca19f20693d98735dc1bbf3692ec759f2d4c728b789a1c1ade4d96e5ddf25e574fdba7c5e42b557c7e82da7a1ad298d7 + lit-analyzer: ^2.0.0-pre.3 + web-component-analyzer: ^2.0.0-next.5 + checksum: d9c8b3c0d8867e9564c7a3083accaf9f8b48b04c8f42e32c224806a7a606983abb3b7acb912e57d0d8f90ff650745bb1af18b1e379316b433838e37eddccfe1e languageName: node linkType: hard -"ts-simple-type@npm:~1.0.5": - version: 1.0.7 - resolution: "ts-simple-type@npm:1.0.7" - checksum: 3cffb45eab7ab7fd963e2765914c41488d9611dc0619334ac1cf01bc2b02cf9746adf12172d785894474c6c5f3cfbf8212e675e456362373a0c2a61441ad8572 +"ts-simple-type@npm:2.0.0-next.0, ts-simple-type@npm:~2.0.0-next.0": + version: 2.0.0-next.0 + resolution: "ts-simple-type@npm:2.0.0-next.0" + checksum: 025c5c1e4f2f7f2627300b2605a0346d5007f9c3d20d075807b01b3ae8179261e6be2d471f74948f3bae3208ca042203d97e80b984d6cb133396c5c4a3af5301 languageName: node linkType: hard @@ -15450,13 +15414,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^3.8.3": - version: 3.9.10 - resolution: "typescript@npm:3.9.10" +"typescript@npm:~4.4.3": + version: 4.4.4 + resolution: "typescript@npm:4.4.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 46c842e2cd4797b88b66ef06c9c41dd21da48b95787072ccf39d5f2aa3124361bc4c966aa1c7f709fae0509614d76751455b5231b12dbb72eb97a31369e1ff92 + checksum: 89ecb8436bb48ef5594d49289f5f89103071716b6e4844278f4fb3362856e31203e187a9c76d205c3f0b674d221a058fd28310dbcbcf5d95e9a57229bb5203f1 languageName: node linkType: hard @@ -15470,13 +15434,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@^3.8.3#~builtin": - version: 3.9.10 - resolution: "typescript@patch:typescript@npm%3A3.9.10#~builtin::version=3.9.10&hash=3bd3d3" +"typescript@patch:typescript@~4.4.3#~builtin": + version: 4.4.4 + resolution: "typescript@patch:typescript@npm%3A4.4.4#~builtin::version=4.4.4&hash=bbeadb" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: dc7141ab555b23a8650a6787f98845fc11692063d02b75ff49433091b3af2fe3d773650dea18389d7c21f47d620fb3b110ea363dab4ab039417a6ccbbaf96fc2 + checksum: 3d1b04449662193544b81d055479d03b4c5dca95f1a82f8922596f089d894c9fefbe16639d1d9dfe26a7054419645530cef44001bc17aed1fe1eb3c237e9b3c7 languageName: node linkType: hard @@ -15978,18 +15942,18 @@ __metadata: languageName: node linkType: hard -"web-component-analyzer@npm:~1.1.1": - version: 1.1.7 - resolution: "web-component-analyzer@npm:1.1.7" +"web-component-analyzer@npm:^2.0.0-next.5": + version: 2.0.0-next.5 + resolution: "web-component-analyzer@npm:2.0.0-next.5" dependencies: fast-glob: ^3.2.2 - ts-simple-type: ~1.0.5 - typescript: ^3.8.3 + ts-simple-type: 2.0.0-next.0 + typescript: ~4.4.3 yargs: ^15.3.1 bin: wca: cli.js web-component-analyzer: cli.js - checksum: 6c36521b7b79d5547ffdbc359029651ad1d929df6e09f8adfbafb2a34c23199712b7080f08f941f056b6a989718c11eb9221171d97ad397ed8a20cf08dd78e4b + checksum: bc8eaf57884b81d378014376bcab92bce6b127971952831dd5bb06803b590cc99fb6fa17c7476c02ee014dfccfcee80e670d7fdc7aff4aae6aebc2e262055a65 languageName: node linkType: hard From a96d3594ba78699165d41a97b327fca3d1626f9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 13:03:48 +0000 Subject: [PATCH 059/162] Update dependency typescript to v5 (#15877) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Bram Kragten --- package.json | 2 +- src/external_app/external_auth.ts | 2 +- yarn.lock | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 1666cce1ec..07805e051f 100644 --- a/package.json +++ b/package.json @@ -236,7 +236,7 @@ "tar": "6.1.15", "terser-webpack-plugin": "5.3.9", "ts-lit-plugin": "2.0.0-pre.1", - "typescript": "4.9.5", + "typescript": "5.1.3", "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", "webpack": "5.87.0", diff --git a/src/external_app/external_auth.ts b/src/external_app/external_auth.ts index 26b1f1f892..c1f0674278 100644 --- a/src/external_app/external_auth.ts +++ b/src/external_app/external_auth.ts @@ -131,7 +131,7 @@ export class ExternalAuth extends Auth { export const createExternalAuth = async (hassUrl: string) => { const auth = new ExternalAuth(hassUrl); if ( - (window.externalApp && window.externalApp.externalBus) || + window.externalApp?.externalBus || (window.webkit && window.webkit.messageHandlers.externalBus) ) { auth.external = new ExternalMessaging(); diff --git a/yarn.lock b/yarn.lock index 9f00d1a62a..c9cdab2cb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9761,7 +9761,7 @@ __metadata: ts-lit-plugin: 2.0.0-pre.1 tsparticles-engine: 2.10.1 tsparticles-preset-links: 2.10.1 - typescript: 4.9.5 + typescript: 5.1.3 unfetch: 5.0.0 vinyl-buffer: 1.0.1 vinyl-source-stream: 2.0.0 @@ -15404,13 +15404,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:4.9.5": - version: 4.9.5 - resolution: "typescript@npm:4.9.5" +"typescript@npm:5.1.3": + version: 5.1.3 + resolution: "typescript@npm:5.1.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: ee000bc26848147ad423b581bd250075662a354d84f0e06eb76d3b892328d8d4440b7487b5a83e851b12b255f55d71835b008a66cbf8f255a11e4400159237db + checksum: d9d51862d98efa46534f2800a1071a613751b1585dc78884807d0c179bcd93d6e9d4012a508e276742f5f33c480adefc52ffcafaf9e0e00ab641a14cde9a31c7 languageName: node linkType: hard @@ -15424,13 +15424,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@4.9.5#~builtin": - version: 4.9.5 - resolution: "typescript@patch:typescript@npm%3A4.9.5#~builtin::version=4.9.5&hash=289587" +"typescript@patch:typescript@5.1.3#~builtin": + version: 5.1.3 + resolution: "typescript@patch:typescript@npm%3A5.1.3#~builtin::version=5.1.3&hash=5da071" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 1f8f3b6aaea19f0f67cba79057674ba580438a7db55057eb89cc06950483c5d632115c14077f6663ea76fd09fce3c190e6414bb98582ec80aa5a4eaf345d5b68 + checksum: 6f0a9dca6bf4ce9dcaf4e282aade55ef4c56ecb5fb98d0a4a5c0113398815aea66d871b5611e83353e5953a19ed9ef103cf5a76ac0f276d550d1e7cd5344f61e languageName: node linkType: hard From 5381a467e510f93bbd8afe5d043a3ada29768d11 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 19 Jun 2023 06:43:04 -0700 Subject: [PATCH 060/162] Fix blueprint script editor erroneously setting `mode` field (#16934) --- src/panels/config/script/ha-script-editor.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 7db2fcd797..73f9104dbf 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -160,14 +160,16 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { return nothing; } + const useBlueprint = "use_blueprint" in this._config; + const schema = this._schema( !!this.scriptId, - "use_blueprint" in this._config, + useBlueprint, this._config.mode ); const data = { - mode: MODES[0], + ...(!this._config.mode && !useBlueprint && { mode: MODES[0] }), icon: undefined, max: this._config.mode && isMaxMode(this._config.mode) ? 10 : undefined, ...this._config, @@ -332,7 +334,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) {
- ${"use_blueprint" in this._config + ${useBlueprint ? html` Date: Mon, 19 Jun 2023 14:21:08 +0000 Subject: [PATCH 061/162] Update dependency @lit-labs/virtualizer to v2.0.3 (#16761) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Bram Kragten --- build-scripts/webpack.cjs | 2 ++ package.json | 4 +-- src/entrypoints/core.ts | 10 +++++++- src/resources/resize-observer.polyfill.ts | 2 +- yarn.lock | 30 +++++++++++------------ 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs index 0ff76cc832..111dadfc36 100644 --- a/build-scripts/webpack.cjs +++ b/build-scripts/webpack.cjs @@ -167,6 +167,8 @@ const createWebpackConfig = ({ "lit/polyfill-support$": "lit/polyfill-support.js", "@lit-labs/virtualizer/layouts/grid": "@lit-labs/virtualizer/layouts/grid.js", + "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver": + "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver.js", }, }, output: { diff --git a/package.json b/package.json index 07805e051f..0a91516a84 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@lezer/highlight": "1.1.6", "@lit-labs/context": "0.3.2", "@lit-labs/motion": "1.0.3", - "@lit-labs/virtualizer": "2.0.2", + "@lit-labs/virtualizer": "2.0.3", "@lrnwebcomponents/simple-tooltip": "7.0.2", "@material/chips": "=14.0.0-canary.53b3cad2f.0", "@material/data-table": "=14.0.0-canary.53b3cad2f.0", @@ -189,7 +189,7 @@ "babel-plugin-template-html-minifier": "4.1.0", "chai": "4.3.7", "del": "7.0.0", - "eslint": "8.42.0", + "eslint": "8.43.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-typescript": "17.0.0", "eslint-config-prettier": "8.8.0", diff --git a/src/entrypoints/core.ts b/src/entrypoints/core.ts index 74cfd72a5f..cc92ddd5bc 100644 --- a/src/entrypoints/core.ts +++ b/src/entrypoints/core.ts @@ -133,7 +133,15 @@ window.hassConnection.then(({ conn }) => { }); window.addEventListener("error", (e) => { - if (!__DEV__ && e.message === "ResizeObserver loop limit exceeded") { + if ( + !__DEV__ && + typeof e.message === "string" && + (e.message.includes("ResizeObserver loop limit exceeded") || + e.message.includes( + "ResizeObserver loop completed with undelivered notifications" + )) + ) { + e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation(); return; diff --git a/src/resources/resize-observer.polyfill.ts b/src/resources/resize-observer.polyfill.ts index dc5eec0273..5023714d60 100644 --- a/src/resources/resize-observer.polyfill.ts +++ b/src/resources/resize-observer.polyfill.ts @@ -5,7 +5,7 @@ export const loadPolyfillIfNeeded = async () => { } catch (e) { window.ResizeObserver = ( await import( - "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver.js" + "@lit-labs/virtualizer/polyfills/resize-observer-polyfill/ResizeObserver" ) ).default; } diff --git a/yarn.lock b/yarn.lock index c9cdab2cb8..dac1b0d3eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1582,10 +1582,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.42.0": - version: 8.42.0 - resolution: "@eslint/js@npm:8.42.0" - checksum: 750558843ac458f7da666122083ee05306fc087ecc1e5b21e7e14e23885775af6c55bcc92283dff1862b7b0d8863ec676c0f18c7faf1219c722fe91a8ece56b6 +"@eslint/js@npm:8.43.0": + version: 8.43.0 + resolution: "@eslint/js@npm:8.43.0" + checksum: 580487a09c82ac169744d36e4af77bc4f582c9a37749d1e9481eb93626c8f3991b2390c6e4e69e5642e3b6e870912b839229a0e23594fae348156ea5a8ed7e2e languageName: node linkType: hard @@ -2088,13 +2088,13 @@ __metadata: languageName: node linkType: hard -"@lit-labs/virtualizer@npm:2.0.2": - version: 2.0.2 - resolution: "@lit-labs/virtualizer@npm:2.0.2" +"@lit-labs/virtualizer@npm:2.0.3": + version: 2.0.3 + resolution: "@lit-labs/virtualizer@npm:2.0.3" dependencies: lit: ^2.7.0 tslib: ^2.0.3 - checksum: 419aedf72f2b08f8fda43d9729810d5c7f34f470484bd9dff2df49d42cc56e57fcdfd98f69dd84e582d07fd2f372b90077cf42e12c4464b2c04c83755eebb495 + checksum: 594b89aca53210a6c0127c331fd05b795074df41aba086b63cb13ad5990e6962b86ca8403fe3a673e3bf46735e2def75d5412afe582702346fbd92a3331d34e1 languageName: node linkType: hard @@ -8127,14 +8127,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.42.0": - version: 8.42.0 - resolution: "eslint@npm:8.42.0" +"eslint@npm:8.43.0": + version: 8.43.0 + resolution: "eslint@npm:8.43.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.4.0 "@eslint/eslintrc": ^2.0.3 - "@eslint/js": 8.42.0 + "@eslint/js": 8.43.0 "@humanwhocodes/config-array": ^0.11.10 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 @@ -8172,7 +8172,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 07105397b5f2ff4064b983b8971e8c379ec04b1dfcc9d918976b3e00377189000161dac991d82ba14f8759e466091b8c71146f602930ca810c290ee3fcb3faf0 + checksum: 55654ce00b0d128822b57526e40473d0497c7c6be3886afdc0b41b6b0dfbd34d0eae8159911b18451b4db51a939a0e6d2e117e847ae419086884fc3d4fe23c7c languageName: node linkType: hard @@ -9597,7 +9597,7 @@ __metadata: "@lezer/highlight": 1.1.6 "@lit-labs/context": 0.3.2 "@lit-labs/motion": 1.0.3 - "@lit-labs/virtualizer": 2.0.2 + "@lit-labs/virtualizer": 2.0.3 "@lrnwebcomponents/simple-tooltip": 7.0.2 "@material/chips": =14.0.0-canary.53b3cad2f.0 "@material/data-table": =14.0.0-canary.53b3cad2f.0 @@ -9689,7 +9689,7 @@ __metadata: deep-clone-simple: 1.1.1 deep-freeze: 0.0.1 del: 7.0.0 - eslint: 8.42.0 + eslint: 8.43.0 eslint-config-airbnb-base: 15.0.0 eslint-config-airbnb-typescript: 17.0.0 eslint-config-prettier: 8.8.0 From e7c8bd4c413b6e88c7df902261fa1bdc725988be Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 19 Jun 2023 19:48:54 +0200 Subject: [PATCH 062/162] Bump Vaadin (#16971) --- package.json | 4 +- yarn.lock | 166 +++++++++++++++++++++++++-------------------------- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/package.json b/package.json index 0a91516a84..4dab740efd 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,8 @@ "@polymer/paper-toast": "3.0.1", "@polymer/polymer": "3.5.1", "@thomasloven/round-slider": "0.6.0", - "@vaadin/combo-box": "24.1.0", - "@vaadin/vaadin-themable-mixin": "24.1.0", + "@vaadin/combo-box": "24.1.1", + "@vaadin/vaadin-themable-mixin": "24.1.1", "@vibrant/color": "3.2.1-alpha.1", "@vibrant/core": "3.2.1-alpha.1", "@vibrant/quantizer-mmcq": "3.2.1-alpha.1", diff --git a/yarn.lock b/yarn.lock index dac1b0d3eb..d64de2a8c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4768,126 +4768,126 @@ __metadata: languageName: node linkType: hard -"@vaadin/a11y-base@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/a11y-base@npm:24.1.0" +"@vaadin/a11y-base@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/a11y-base@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.1.0 + "@vaadin/component-base": ~24.1.1 lit: ^2.0.0 - checksum: f019f2c04473c60c3714ec3da65a129833e1fab4e2eefb4f88d4caa81eb45da756dce2cec8b222bd259d0b87bc67439a4aa88f636b90e6f704c037197bdc1492 + checksum: 1b83e3e44ebc8c395a5ba9a6bc92d42aeb6afce3bcd6a1c492bbc7eb166a228474bf7dc56fb6509d47618fdd87107c60e4ebc60d2aab3c72dcc1392465fd7ac1 languageName: node linkType: hard -"@vaadin/combo-box@npm:24.1.0": - version: 24.1.0 - resolution: "@vaadin/combo-box@npm:24.1.0" +"@vaadin/combo-box@npm:24.1.1": + version: 24.1.1 + resolution: "@vaadin/combo-box@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/a11y-base": ~24.1.0 - "@vaadin/component-base": ~24.1.0 - "@vaadin/field-base": ~24.1.0 - "@vaadin/input-container": ~24.1.0 - "@vaadin/item": ~24.1.0 - "@vaadin/lit-renderer": ~24.1.0 - "@vaadin/overlay": ~24.1.0 - "@vaadin/vaadin-lumo-styles": ~24.1.0 - "@vaadin/vaadin-material-styles": ~24.1.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 - checksum: cbdbfba535a16faa84a897d61565e91d1b2ec0dad87c1644e287c180fed13fcf3e2b0c436fb85ad7f394a4bb7aceb596b9070e3e171afe8167f2158908e71ea5 + "@vaadin/a11y-base": ~24.1.1 + "@vaadin/component-base": ~24.1.1 + "@vaadin/field-base": ~24.1.1 + "@vaadin/input-container": ~24.1.1 + "@vaadin/item": ~24.1.1 + "@vaadin/lit-renderer": ~24.1.1 + "@vaadin/overlay": ~24.1.1 + "@vaadin/vaadin-lumo-styles": ~24.1.1 + "@vaadin/vaadin-material-styles": ~24.1.1 + "@vaadin/vaadin-themable-mixin": ~24.1.1 + checksum: 0011a1271ebe41c6eaf5d5cf5f15c7cfdfab46534c70b4bdbcc0b1afdd6e83e0c7983d3927db6df4c7669269d7909a3d886586696b9d75d291a6a7876db22ce6 languageName: node linkType: hard -"@vaadin/component-base@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/component-base@npm:24.1.0" +"@vaadin/component-base@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/component-base@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 "@vaadin/vaadin-development-mode-detector": ^2.0.0 "@vaadin/vaadin-usage-statistics": ^2.1.0 lit: ^2.0.0 - checksum: 1df8786d8ef1b3a2a104101c8877464d6fca3ea70fa851b2f99bcf32bb83780ced05f524b6225e95f901edb8ec9379fe625ac18154367a3a684846004277badc + checksum: 34c698266897cf7c3c5f8b8798468f5035ae764b1743e6a93f5ea1921b3d29e642db51e4d6d71c6594ba03dee14fa0704b34ccb70b7f50ecbfd07677bde231ac languageName: node linkType: hard -"@vaadin/field-base@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/field-base@npm:24.1.0" +"@vaadin/field-base@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/field-base@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/a11y-base": ~24.1.0 - "@vaadin/component-base": ~24.1.0 + "@vaadin/a11y-base": ~24.1.1 + "@vaadin/component-base": ~24.1.1 lit: ^2.0.0 - checksum: 5e37ede91e05dd8eb9fa43749b89670904abfc30e522eebb4ec2225318cf72774dd4e94e49deb1b55daea719818803d90968c4d0f4b87132d24289345e728abd + checksum: b16d5579d4a5f43a62df431b7e7e3107bf5a8062ad681b6ce0c1c345dc56ce4f0ae4f0909e2e9ff0fb05d9f2f4b54e12f17b75a680c69b9f24f8f82b63c0b234 languageName: node linkType: hard -"@vaadin/icon@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/icon@npm:24.1.0" +"@vaadin/icon@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/icon@npm:24.1.1" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.1.0 - "@vaadin/vaadin-lumo-styles": ~24.1.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 + "@vaadin/component-base": ~24.1.1 + "@vaadin/vaadin-lumo-styles": ~24.1.1 + "@vaadin/vaadin-themable-mixin": ~24.1.1 lit: ^2.0.0 - checksum: 60ee5e3056d175b032c1ad41b3b208b2289c2ef043e4f073e86f691ed135ea98a8780fe0624c9347858f5f0f44a0cc58c345d51eb3795fac47cdafd6cc1a8c59 + checksum: be3f8986e04f163791c0fdbc51c5d7c8074b12548f151b58a3f357ab639cc5c0c53b3375ded7936cd8c618df19dcfef4c616735b24e81da6ae1fca753d4c0774 languageName: node linkType: hard -"@vaadin/input-container@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/input-container@npm:24.1.0" +"@vaadin/input-container@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/input-container@npm:24.1.1" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/component-base": ~24.1.0 - "@vaadin/vaadin-lumo-styles": ~24.1.0 - "@vaadin/vaadin-material-styles": ~24.1.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 - checksum: d222ec0df6c3e169341d8e1c4bc5b15da6f4324bb962537929b864df389f24474195c0088b1d06d88aaecc18f63938c5f5fa614d8fcda233c8ea5222fc31f183 + "@vaadin/component-base": ~24.1.1 + "@vaadin/vaadin-lumo-styles": ~24.1.1 + "@vaadin/vaadin-material-styles": ~24.1.1 + "@vaadin/vaadin-themable-mixin": ~24.1.1 + checksum: b8934fae0f5578b78f4ee05c506b59e66c247e3fdf6d42b1ba7d198d77af170907b1f3cd98ee5ce7bd540d0f5c1f4c08d8febdfa35f7231ed56d289b0eb7432b languageName: node linkType: hard -"@vaadin/item@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/item@npm:24.1.0" +"@vaadin/item@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/item@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/a11y-base": ~24.1.0 - "@vaadin/component-base": ~24.1.0 - "@vaadin/vaadin-lumo-styles": ~24.1.0 - "@vaadin/vaadin-material-styles": ~24.1.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 - checksum: 643f47f7e4ae74cffa3e891789c0689063d73552d81aa84dad66d3f415e624e734f13ae0b0123710984fa8390ea2df1f468d9415d7d914150695821045e09ea0 + "@vaadin/a11y-base": ~24.1.1 + "@vaadin/component-base": ~24.1.1 + "@vaadin/vaadin-lumo-styles": ~24.1.1 + "@vaadin/vaadin-material-styles": ~24.1.1 + "@vaadin/vaadin-themable-mixin": ~24.1.1 + checksum: a87529f5c0c385920d36173b670afbfaaa83d0c171cea048daf7986fbdfb7d82cfef651bc806043ca007a61c1f92b47bba489240b0917d15c75ad49fabab2153 languageName: node linkType: hard -"@vaadin/lit-renderer@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/lit-renderer@npm:24.1.0" +"@vaadin/lit-renderer@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/lit-renderer@npm:24.1.1" dependencies: lit: ^2.0.0 - checksum: 9f0940e0245f608dc613cb33ffdb4f88c275597f7b25fac04892d29ddfc752801fde118fca47bd8445a9d51bca203c339216186ca9b4941b0b6f07a52cc4fc9a + checksum: 17a22abce1654c9b6c86e8a113778d61d5780e45164d3362741b00f47e061cfd88521127802f16ce2ad3ba92ed1535829c8b154183cc6f4fbececdbbb70f4233 languageName: node linkType: hard -"@vaadin/overlay@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/overlay@npm:24.1.0" +"@vaadin/overlay@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/overlay@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 "@polymer/polymer": ^3.0.0 - "@vaadin/a11y-base": ~24.1.0 - "@vaadin/component-base": ~24.1.0 - "@vaadin/vaadin-lumo-styles": ~24.1.0 - "@vaadin/vaadin-material-styles": ~24.1.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 - checksum: 8362db034347e8186c4397de55fd51b69e645f621614298b68fa383e4957a6ea8290b0770b3d686217ce937a7a18d33ea0ea6844d3da4d3aa3a61d7498210b80 + "@vaadin/a11y-base": ~24.1.1 + "@vaadin/component-base": ~24.1.1 + "@vaadin/vaadin-lumo-styles": ~24.1.1 + "@vaadin/vaadin-material-styles": ~24.1.1 + "@vaadin/vaadin-themable-mixin": ~24.1.1 + checksum: d0def2106e4fff7d7c49931e9b917c68994f371a0246e076442e33d97ac7a25341d9794aee9e41c7c05c94111dacac74cb5648f1814fb45f11cf37ffe6850fa1 languageName: node linkType: hard @@ -4898,34 +4898,34 @@ __metadata: languageName: node linkType: hard -"@vaadin/vaadin-lumo-styles@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/vaadin-lumo-styles@npm:24.1.0" +"@vaadin/vaadin-lumo-styles@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/vaadin-lumo-styles@npm:24.1.1" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/icon": ~24.1.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 - checksum: 68c55fadb2468048b3fe2ae14c8e5fdb90cb35a171c1a2dc7e33b369d8f79565b6e1c5a93a26dbc5e24b3f7b7e5634b87459fd5528e58bf045cc6c5717840703 + "@vaadin/icon": ~24.1.1 + "@vaadin/vaadin-themable-mixin": ~24.1.1 + checksum: ab344ce558de8f1075de6290517169bd3e95cf5038549b987ca7cfb14a9798ca12573e099958fecd518dd74f2bcfa76030dfc5d3b6e46b34dff10e4d675182c5 languageName: node linkType: hard -"@vaadin/vaadin-material-styles@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/vaadin-material-styles@npm:24.1.0" +"@vaadin/vaadin-material-styles@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/vaadin-material-styles@npm:24.1.1" dependencies: "@polymer/polymer": ^3.0.0 - "@vaadin/vaadin-themable-mixin": ~24.1.0 - checksum: 205e67f5a99dda6cdf1410a0786408d42b8ea48c18c26b3a89d9524fd651b89993db12f3ccfff6635d7981a557416aa8656696d42e6f58fe593d6845b88334ac + "@vaadin/vaadin-themable-mixin": ~24.1.1 + checksum: 601e345da8858a62804b1afde06a79f93e9b5c41fcc263bb692b6db167937e3dd1b754b502ceeaf4054586d3e04a68a167ba7bc2719ec4ad8ac10005795d9a6e languageName: node linkType: hard -"@vaadin/vaadin-themable-mixin@npm:24.1.0, @vaadin/vaadin-themable-mixin@npm:~24.1.0": - version: 24.1.0 - resolution: "@vaadin/vaadin-themable-mixin@npm:24.1.0" +"@vaadin/vaadin-themable-mixin@npm:24.1.1, @vaadin/vaadin-themable-mixin@npm:~24.1.1": + version: 24.1.1 + resolution: "@vaadin/vaadin-themable-mixin@npm:24.1.1" dependencies: "@open-wc/dedupe-mixin": ^1.3.0 lit: ^2.0.0 - checksum: 0abe57312bdda606b52ce93843e82628310e419cbfe4c8bd564c574f7883c8979861b1eb34982bab4a488a82a467dd80cd482e018154ce343310b2918146808d + checksum: 5066300dcf6c987e43bb9c2e16d75198188220dfbde0c76d3d875444200f05b4de70d50fd3d082c0ac0b5075953835d1499ed01d51236e06a56d5ca9e6d25e4c languageName: node linkType: hard @@ -9666,8 +9666,8 @@ __metadata: "@types/webspeechapi": 0.0.29 "@typescript-eslint/eslint-plugin": 5.59.11 "@typescript-eslint/parser": 5.59.11 - "@vaadin/combo-box": 24.1.0 - "@vaadin/vaadin-themable-mixin": 24.1.0 + "@vaadin/combo-box": 24.1.1 + "@vaadin/vaadin-themable-mixin": 24.1.1 "@vibrant/color": 3.2.1-alpha.1 "@vibrant/core": 3.2.1-alpha.1 "@vibrant/quantizer-mmcq": 3.2.1-alpha.1 From 540df024d90309ca5aa32978c67800382b4a8464 Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Mon, 19 Jun 2023 13:50:45 -0400 Subject: [PATCH 063/162] Upgrade to python 3.11 (#16948) --- .devcontainer/Dockerfile | 2 +- .github/workflows/nightly.yaml | 2 +- .github/workflows/release.yaml | 4 ++-- pyproject.toml | 2 +- script/bootstrap | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 26ee55e660..17e64a518c 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.148.1/containers/python-3/.devcontainer/base.Dockerfile -FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.10 +FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.11 ENV \ DEBIAN_FRONTEND=noninteractive \ diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 0b22247453..76f0415496 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -6,7 +6,7 @@ on: - cron: "0 1 * * *" env: - PYTHON_VERSION: "3.10" + PYTHON_VERSION: "3.11" NODE_OPTIONS: --max_old_space_size=6144 permissions: diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7d943eda97..a269b30074 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -6,7 +6,7 @@ on: - published env: - PYTHON_VERSION: "3.10" + PYTHON_VERSION: "3.11" NODE_OPTIONS: --max_old_space_size=6144 # Set default workflow permissions @@ -76,7 +76,7 @@ jobs: - name: Build wheels uses: home-assistant/wheels@2023.04.0 with: - abi: cp310 + abi: cp311 tag: musllinux_1_2 arch: amd64 wheels-key: ${{ secrets.WHEELS_KEY }} diff --git a/pyproject.toml b/pyproject.toml index 099766e91b..8cac9f3594 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ readme = "README.md" authors = [ {name = "The Home Assistant Authors", email = "hello@home-assistant.io"} ] -requires-python = ">=3.4.0" +requires-python = ">=3.10.0" [project.urls] "Homepage" = "https://github.com/home-assistant/frontend" diff --git a/script/bootstrap b/script/bootstrap index f18b75d2b8..73e44806f9 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -8,9 +8,9 @@ cd "$(dirname "$0")/.." # Install/upgrade node when inside devcontainer if [[ -n "$DEVCONTAINER" ]]; then - nodeCurrent=$(nvm version default || echo "") + nodeCurrent=$(nvm version default || :) nodeLatest=$(nvm version-remote "$(cat .nvmrc)") - if [[ -z "$nodeCurrent" ]]; then + if [[ -z "$nodeCurrent" || "$nodeCurrent" == "N/A" ]]; then nvm install elif [[ "$nodeCurrent" != "$nodeLatest" ]]; then nvm install --reinstall-packages-from="$nodeCurrent" --default From be1089302fe446a995bed8c7a1cf4a8f890d2ddd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:52:51 +0000 Subject: [PATCH 064/162] Update dependency @octokit/rest to v19.0.12 (#16973) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 4dab740efd..ac250d710d 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ "@koa/cors": "4.0.0", "@octokit/auth-oauth-device": "5.0.0", "@octokit/plugin-retry": "5.0.3", - "@octokit/rest": "19.0.11", + "@octokit/rest": "19.0.12", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", "@rollup/plugin-commonjs": "25.0.1", diff --git a/yarn.lock b/yarn.lock index d64de2a8c5..b51da21ea1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3285,15 +3285,15 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-paginate-rest@npm:^6.1.2": - version: 6.1.2 - resolution: "@octokit/plugin-paginate-rest@npm:6.1.2" +"@octokit/plugin-paginate-rest@npm:^7.0.0": + version: 7.1.2 + resolution: "@octokit/plugin-paginate-rest@npm:7.1.2" dependencies: - "@octokit/tsconfig": ^1.0.2 - "@octokit/types": ^9.2.3 + "@octokit/tsconfig": ^2.0.0 + "@octokit/types": ^9.3.2 peerDependencies: "@octokit/core": ">=4" - checksum: a7b3e686c7cbd27ec07871cde6e0b1dc96337afbcef426bbe3067152a17b535abd480db1861ca28c88d93db5f7bfdbcadd0919ead19818c28a69d0e194038065 + checksum: dcff1593fd0635cff3a6add6bfa375316cce5071b540da55075d1fe4aa0ddf04e0a798707857db229f0705e91398a8a59cb07bdac4c95bda7e2eda48370b00c1 languageName: node linkType: hard @@ -3366,22 +3366,22 @@ __metadata: languageName: node linkType: hard -"@octokit/rest@npm:19.0.11": - version: 19.0.11 - resolution: "@octokit/rest@npm:19.0.11" +"@octokit/rest@npm:19.0.12": + version: 19.0.12 + resolution: "@octokit/rest@npm:19.0.12" dependencies: "@octokit/core": ^4.2.1 - "@octokit/plugin-paginate-rest": ^6.1.2 + "@octokit/plugin-paginate-rest": ^7.0.0 "@octokit/plugin-request-log": ^1.0.4 "@octokit/plugin-rest-endpoint-methods": ^7.1.2 - checksum: 147518ad51d214ead88adc717b5fdc4f33317949d58c124f4069bdf07d2e6b49fa66861036b9e233aed71fcb88ff367a6da0357653484e466175ab4fb7183b3b + checksum: 6e42a3d951461128a26f9634a0d3ac9e1955231286dc0637ae952db06c6296b19279217e6d58071e88bb0675c5bbb84fba5b4847c757ac98f4e3559a102bd93d languageName: node linkType: hard -"@octokit/tsconfig@npm:^1.0.2": - version: 1.0.2 - resolution: "@octokit/tsconfig@npm:1.0.2" - checksum: 74d56f3e9f326a8dd63700e9a51a7c75487180629c7a68bbafee97c612fbf57af8347369bfa6610b9268a3e8b833c19c1e4beb03f26db9a9dce31f6f7a19b5b1 +"@octokit/tsconfig@npm:^2.0.0": + version: 2.0.0 + resolution: "@octokit/tsconfig@npm:2.0.0" + checksum: c19b1c8a316682322a6bee26faf0225b59926770fa796833c7211521f464f915dd6950ab29c7a7996711ccf8986b5c0a088cc5a1c2b4d8848d503682537bccf2 languageName: node linkType: hard @@ -3394,7 +3394,7 @@ __metadata: languageName: node linkType: hard -"@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.2.3": +"@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.3.2": version: 9.3.2 resolution: "@octokit/types@npm:9.3.2" dependencies: @@ -9629,7 +9629,7 @@ __metadata: "@mdi/svg": 7.2.96 "@octokit/auth-oauth-device": 5.0.0 "@octokit/plugin-retry": 5.0.3 - "@octokit/rest": 19.0.11 + "@octokit/rest": 19.0.12 "@open-wc/dev-server-hmr": 0.1.4 "@polymer/app-layout": 3.1.0 "@polymer/iron-flex-layout": 3.0.1 From 13c932a8f85f305b3ca7a001193b2fa507418b2b Mon Sep 17 00:00:00 2001 From: c0ffeeca7 <38767475+c0ffeeca7@users.noreply.github.com> Date: Tue, 20 Jun 2023 10:43:28 +0200 Subject: [PATCH 065/162] Thread: Rename "My network" to "Preferred network" (#16980) - All networks in my household are my networks. Otherwise they are my neighbor's. - within my networks, this one is my preferred one (as opposed to other networks) --- src/translations/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/translations/en.json b/src/translations/en.json index 25900e1209..c803418f1a 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3488,11 +3488,11 @@ }, "thread": { "other_networks": "Other networks", - "my_network": "My network", + "my_network": "Preferred network", "no_preferred_network": "You don't have a preferred network yet.", "add_open_thread_border_router": "Add an OpenThread border router", "reset_border_router": "Reset border router", - "add_to_my_network": "Add to my network", + "add_to_my_network": "Add to preferred network", "no_routers_otbr_network": "No border routers where found, maybe the border router is not configured correctly. You can try to reset it to the factory settings.", "add_dataset_from_tlv": "Add dataset from TLV", "add_dataset": "Add Thread dataset", From 044a44e114f8123dd9c8daf2411dd42e1a3c14a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 11:56:05 +0200 Subject: [PATCH 066/162] Update dependency @lit-labs/context to v0.3.3 (#16975) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index ac250d710d..a9b06d15f1 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "@fullcalendar/list": "6.1.8", "@fullcalendar/timegrid": "6.1.8", "@lezer/highlight": "1.1.6", - "@lit-labs/context": "0.3.2", + "@lit-labs/context": "0.3.3", "@lit-labs/motion": "1.0.3", "@lit-labs/virtualizer": "2.0.3", "@lrnwebcomponents/simple-tooltip": "7.0.2", diff --git a/yarn.lock b/yarn.lock index b51da21ea1..ad6df46af6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2062,13 +2062,13 @@ __metadata: languageName: node linkType: hard -"@lit-labs/context@npm:0.3.2": - version: 0.3.2 - resolution: "@lit-labs/context@npm:0.3.2" +"@lit-labs/context@npm:0.3.3": + version: 0.3.3 + resolution: "@lit-labs/context@npm:0.3.3" dependencies: "@lit/reactive-element": ^1.5.0 lit: ^2.7.0 - checksum: 55920366798a3337a455c627c0b6911c7b78dee94a783ad77edb9a9e237a2e48201d6cf869f3d0b805316e5c8e8fb817f52f663bc556dd40ca6e8b3168662daf + checksum: 3607a7f965f22072feeef8db791e37be45921d9168ea3f432e160cb1fb337de19b2b41a2cd8db5d4fd2675d704d567a24695b796d0b14590616e9232f27579d3 languageName: node linkType: hard @@ -9595,7 +9595,7 @@ __metadata: "@fullcalendar/timegrid": 6.1.8 "@koa/cors": 4.0.0 "@lezer/highlight": 1.1.6 - "@lit-labs/context": 0.3.2 + "@lit-labs/context": 0.3.3 "@lit-labs/motion": 1.0.3 "@lit-labs/virtualizer": 2.0.3 "@lrnwebcomponents/simple-tooltip": 7.0.2 From 332af4003e99137c34c0e46555de28ff4092c990 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 20 Jun 2023 03:00:33 -0700 Subject: [PATCH 067/162] History graph should start at requested time even if sensor is unavailable (#16850) History graph should start at consistent time if sensor is unavailable --- .../chart/state-history-chart-line.ts | 12 +++++++- src/components/chart/state-history-charts.ts | 30 ++++++++++++++----- src/panels/history/ha-panel-history.ts | 1 + .../lovelace/cards/hui-history-graph-card.ts | 1 + 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/components/chart/state-history-chart-line.ts b/src/components/chart/state-history-chart-line.ts index 1e34d204fb..b90d57fb62 100644 --- a/src/components/chart/state-history-chart-line.ts +++ b/src/components/chart/state-history-chart-line.ts @@ -30,6 +30,8 @@ class StateHistoryChartLine extends LitElement { @property({ type: Boolean }) public showNames = true; + @property({ attribute: false }) public startTime!: Date; + @property({ attribute: false }) public endTime!: Date; @property({ type: Number }) public paddingYAxis = 0; @@ -57,7 +59,12 @@ class StateHistoryChartLine extends LitElement { } public willUpdate(changedProps: PropertyValues) { - if (!this.hasUpdated || changedProps.has("showNames")) { + if ( + !this.hasUpdated || + changedProps.has("showNames") || + changedProps.has("startTime") || + changedProps.has("endTime") + ) { this._chartOptions = { parsing: false, animation: false, @@ -74,6 +81,7 @@ class StateHistoryChartLine extends LitElement { config: this.hass.config, }, }, + suggestedMin: this.startTime, suggestedMax: this.endTime, ticks: { maxRotation: 0, @@ -146,6 +154,8 @@ class StateHistoryChartLine extends LitElement { } if ( changedProps.has("data") || + changedProps.has("startTime") || + changedProps.has("endTime") || this._chartTime < new Date(this.endTime.getTime() - MIN_TIME_BETWEEN_UPDATES) ) { diff --git a/src/components/chart/state-history-charts.ts b/src/components/chart/state-history-charts.ts index 0e143284e4..0ce32a583e 100644 --- a/src/components/chart/state-history-charts.ts +++ b/src/components/chart/state-history-charts.ts @@ -52,8 +52,12 @@ export class StateHistoryCharts extends LitElement { @property({ attribute: false }) public endTime?: Date; + @property({ attribute: false }) public startTime?: Date; + @property({ type: Boolean, attribute: "up-to-now" }) public upToNow = false; + @property() public hoursToShow?: number; + @property({ type: Boolean }) public showNames = true; @property({ type: Boolean }) public isLoadingData = false; @@ -95,13 +99,24 @@ export class StateHistoryCharts extends LitElement { this._computedEndTime = this.upToNow || !this.endTime || this.endTime > now ? now : this.endTime; - this._computedStartTime = new Date( - this.historyData.timeline.reduce( - (minTime, stateInfo) => - Math.min(minTime, new Date(stateInfo.data[0].last_changed).getTime()), - new Date().getTime() - ) - ); + if (this.startTime) { + this._computedStartTime = this.startTime; + } else if (this.hoursToShow) { + this._computedStartTime = new Date( + new Date().getTime() - 60 * 60 * this.hoursToShow * 1000 + ); + } else { + this._computedStartTime = new Date( + this.historyData.timeline.reduce( + (minTime, stateInfo) => + Math.min( + minTime, + new Date(stateInfo.data[0].last_changed).getTime() + ), + new Date().getTime() + ) + ); + } const combinedItems = this.historyData.timeline.length ? (this.virtualize @@ -142,6 +157,7 @@ export class StateHistoryCharts extends LitElement { .data=${item.data} .identifier=${item.identifier} .showNames=${this.showNames} + .startTime=${this._computedStartTime} .endTime=${this._computedEndTime} .paddingYAxis=${this._maxYWidth} .names=${this.names} diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts index b88861d44c..bb3c224750 100644 --- a/src/panels/history/ha-panel-history.ts +++ b/src/panels/history/ha-panel-history.ts @@ -190,6 +190,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { diff --git a/src/panels/lovelace/cards/hui-history-graph-card.ts b/src/panels/lovelace/cards/hui-history-graph-card.ts index 64e7809e18..5219027fc9 100644 --- a/src/panels/lovelace/cards/hui-history-graph-card.ts +++ b/src/panels/lovelace/cards/hui-history-graph-card.ts @@ -205,6 +205,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard { .historyData=${this._stateHistory} .names=${this._names} up-to-now + .hoursToShow=${this._hoursToShow} .showNames=${this._config.show_names !== undefined ? this._config.show_names : true} From 3888b1c48b3fed1b782a6b61229f68b8ea0b05e1 Mon Sep 17 00:00:00 2001 From: breakthestatic Date: Tue, 20 Jun 2023 03:03:55 -0700 Subject: [PATCH 068/162] Use fuzzy filter/sort for target pickers (#16912) * Use fuzzy filter/sort for target pickers * PR suggestions * Restore missed sort --- src/components/device/ha-device-picker.ts | 24 +++++++++++- src/components/entity/ha-entity-picker.ts | 45 +++++++++++++++-------- src/components/ha-area-picker.ts | 22 ++++++++--- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/components/device/ha-device-picker.ts b/src/components/device/ha-device-picker.ts index 5fc1bfff80..fb837d15b2 100644 --- a/src/components/device/ha-device-picker.ts +++ b/src/components/device/ha-device-picker.ts @@ -26,6 +26,10 @@ import { SubscribeMixin } from "../../mixins/subscribe-mixin"; import { ValueChangedEvent, HomeAssistant } from "../../types"; import "../ha-combo-box"; import type { HaComboBox } from "../ha-combo-box"; +import { + fuzzyFilterSort, + ScorableTextItem, +} from "../../common/string/filter/sequence-matching"; interface Device { name: string; @@ -33,6 +37,8 @@ interface Device { id: string; } +type ScorableDevice = ScorableTextItem & Device; + export type HaDevicePickerDeviceFilterFunc = ( device: DeviceRegistryEntry ) => boolean; @@ -119,13 +125,14 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { deviceFilter: this["deviceFilter"], entityFilter: this["entityFilter"], excludeDevices: this["excludeDevices"] - ): Device[] => { + ): ScorableDevice[] => { if (!devices.length) { return [ { id: "no_devices", area: "", name: this.hass.localize("ui.components.device-picker.no_devices"), + strings: [], }, ]; } @@ -235,6 +242,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { device.area_id && areaLookup[device.area_id] ? areaLookup[device.area_id].name : this.hass.localize("ui.components.device-picker.no_area"), + strings: [device.name || ""], })); if (!outputDevices.length) { return [ @@ -242,6 +250,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { id: "no_devices", area: "", name: this.hass.localize("ui.components.device-picker.no_match"), + strings: [], }, ]; } @@ -284,7 +293,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { (this._init && changedProps.has("_opened") && this._opened) ) { this._init = true; - (this.comboBox as any).items = this._getDevices( + const devices = this._getDevices( this.devices!, this.areas!, this.entities!, @@ -295,6 +304,8 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { this.entityFilter, this.excludeDevices ); + this.comboBox.items = devices; + this.comboBox.filteredItems = devices; } } @@ -314,6 +325,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { item-label-path="name" @opened-changed=${this._openedChanged} @value-changed=${this._deviceChanged} + @filter-changed=${this._filterChanged} > `; } @@ -322,6 +334,14 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { return this.value || ""; } + private _filterChanged(ev: CustomEvent): void { + const target = ev.target as HaComboBox; + const filterString = ev.detail.value.toLowerCase(); + target.filteredItems = filterString.length + ? fuzzyFilterSort(filterString, target.items || []) + : target.items; + } + private _deviceChanged(ev: ValueChangedEvent) { ev.stopPropagation(); let newValue = ev.detail.value; diff --git a/src/components/entity/ha-entity-picker.ts b/src/components/entity/ha-entity-picker.ts index c06d2cd5a9..115e0795aa 100644 --- a/src/components/entity/ha-entity-picker.ts +++ b/src/components/entity/ha-entity-picker.ts @@ -7,15 +7,19 @@ import memoizeOne from "memoize-one"; import { fireEvent } from "../../common/dom/fire_event"; import { computeDomain } from "../../common/entity/compute_domain"; import { computeStateName } from "../../common/entity/compute_state_name"; -import { caseInsensitiveStringCompare } from "../../common/string/compare"; +import { + fuzzyFilterSort, + ScorableTextItem, +} from "../../common/string/filter/sequence-matching"; import { ValueChangedEvent, HomeAssistant } from "../../types"; import "../ha-combo-box"; import type { HaComboBox } from "../ha-combo-box"; import "../ha-icon-button"; import "../ha-svg-icon"; import "./state-badge"; +import { caseInsensitiveStringCompare } from "../../common/string/compare"; -interface HassEntityWithCachedName extends HassEntity { +interface HassEntityWithCachedName extends HassEntity, ScorableTextItem { friendly_name: string; } @@ -159,6 +163,7 @@ export class HaEntityPicker extends LitElement { ), icon: "mdi:magnify", }, + strings: [], }, ]; } @@ -169,10 +174,14 @@ export class HaEntityPicker extends LitElement { ); return entityIds - .map((key) => ({ - ...hass!.states[key], - friendly_name: computeStateName(hass!.states[key]) || key, - })) + .map((key) => { + const friendly_name = computeStateName(hass!.states[key]) || key; + return { + ...hass!.states[key], + friendly_name, + strings: [key, friendly_name], + }; + }) .sort((entityA, entityB) => caseInsensitiveStringCompare( entityA.friendly_name, @@ -201,10 +210,14 @@ export class HaEntityPicker extends LitElement { } states = entityIds - .map((key) => ({ - ...hass!.states[key], - friendly_name: computeStateName(hass!.states[key]) || key, - })) + .map((key) => { + const friendly_name = computeStateName(hass!.states[key]) || key; + return { + ...hass!.states[key], + friendly_name, + strings: [key, friendly_name], + }; + }) .sort((entityA, entityB) => caseInsensitiveStringCompare( entityA.friendly_name, @@ -260,6 +273,7 @@ export class HaEntityPicker extends LitElement { ), icon: "mdi:magnify", }, + strings: [], }, ]; } @@ -293,7 +307,7 @@ export class HaEntityPicker extends LitElement { this.excludeEntities ); if (this._initedStates) { - (this.comboBox as any).filteredItems = this._states; + this.comboBox.filteredItems = this._states; } this._initedStates = true; } @@ -340,12 +354,11 @@ export class HaEntityPicker extends LitElement { } private _filterChanged(ev: CustomEvent): void { + const target = ev.target as HaComboBox; const filterString = ev.detail.value.toLowerCase(); - (this.comboBox as any).filteredItems = this._states.filter( - (entityState) => - entityState.entity_id.toLowerCase().includes(filterString) || - computeStateName(entityState).toLowerCase().includes(filterString) - ); + target.filteredItems = filterString.length + ? fuzzyFilterSort(filterString, this._states) + : this._states; } private _setValue(value: string) { diff --git a/src/components/ha-area-picker.ts b/src/components/ha-area-picker.ts index 9c06dd8015..1ea409aafe 100644 --- a/src/components/ha-area-picker.ts +++ b/src/components/ha-area-picker.ts @@ -7,6 +7,10 @@ import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; import { fireEvent } from "../common/dom/fire_event"; import { computeDomain } from "../common/entity/compute_domain"; +import { + fuzzyFilterSort, + ScorableTextItem, +} from "../common/string/filter/sequence-matching"; import { AreaRegistryEntry, createAreaRegistryEntry, @@ -28,6 +32,8 @@ import type { HaComboBox } from "./ha-combo-box"; import "./ha-icon-button"; import "./ha-svg-icon"; +type ScorableAreaRegistryEntry = ScorableTextItem & AreaRegistryEntry; + const rowRenderer: ComboBoxLitRenderer = ( item ) => html` ({ + ...area, + strings: [area.area_id, ...area.aliases, area.name], + })); + this.comboBox.items = areas; + this.comboBox.filteredItems = areas; } } @@ -345,8 +354,9 @@ export class HaAreaPicker extends LitElement { return; } - const filteredItems = this.comboBox.items?.filter((item) => - item.name.toLowerCase().includes(filter!.toLowerCase()) + const filteredItems = fuzzyFilterSort( + filter, + this.comboBox?.items || [] ); if (!this.noAdd && filteredItems?.length === 0) { this._suggestion = filter; @@ -409,7 +419,7 @@ export class HaAreaPicker extends LitElement { name, }); const areas = [...Object.values(this.hass.areas), area]; - (this.comboBox as any).filteredItems = this._getAreas( + this.comboBox.filteredItems = this._getAreas( areas, Object.values(this.hass.devices)!, Object.values(this.hass.entities)!, From baaa012101b482637d1fb68f7efb0283719a4490 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 12:07:01 +0200 Subject: [PATCH 069/162] Update octokit monorepo (#16979) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 6 +-- yarn.lock | 120 ++++++++++++++++++++++++++++++--------------------- 2 files changed, 75 insertions(+), 51 deletions(-) diff --git a/package.json b/package.json index a9b06d15f1..587d38410a 100644 --- a/package.json +++ b/package.json @@ -156,9 +156,9 @@ "@babel/preset-env": "7.22.5", "@babel/preset-typescript": "7.22.5", "@koa/cors": "4.0.0", - "@octokit/auth-oauth-device": "5.0.0", - "@octokit/plugin-retry": "5.0.3", - "@octokit/rest": "19.0.12", + "@octokit/auth-oauth-device": "5.0.2", + "@octokit/plugin-retry": "5.0.4", + "@octokit/rest": "19.0.13", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", "@rollup/plugin-commonjs": "25.0.1", diff --git a/yarn.lock b/yarn.lock index ad6df46af6..2b607381f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3202,15 +3202,15 @@ __metadata: languageName: node linkType: hard -"@octokit/auth-oauth-device@npm:5.0.0": - version: 5.0.0 - resolution: "@octokit/auth-oauth-device@npm:5.0.0" +"@octokit/auth-oauth-device@npm:5.0.2": + version: 5.0.2 + resolution: "@octokit/auth-oauth-device@npm:5.0.2" dependencies: - "@octokit/oauth-methods": ^2.0.0 - "@octokit/request": ^6.0.0 - "@octokit/types": ^9.0.0 + "@octokit/oauth-methods": ^3.0.1 + "@octokit/request": ^7.0.0 + "@octokit/types": ^10.0.0 universal-user-agent: ^6.0.0 - checksum: 7089bf13bc01629e501af88dc01c18b29b70dba87e26bd4eb2b7faf6baefe3ba9e4ed92f77d5b7a8a56afbbdb1a01b4b264c140c10c4ca6fbd28a7976fcfdc6e + checksum: b625a2d7604351e52df46d3fdad04d1eb2ec68f80bce065047691ea83044967ef1e7dd0a70e9f8aab818d8c5ecf7f2550d2aa029ffdba85e0ff8c0ce2e25736a languageName: node linkType: hard @@ -3247,6 +3247,17 @@ __metadata: languageName: node linkType: hard +"@octokit/endpoint@npm:^8.0.0": + version: 8.0.1 + resolution: "@octokit/endpoint@npm:8.0.1" + dependencies: + "@octokit/types": ^10.0.0 + is-plain-object: ^5.0.0 + universal-user-agent: ^6.0.0 + checksum: 0cff7c972d8304cb59c4cc28016c15bca05e6d7e9e2d9b00af88ce05bf9abdfdb17025f38080162a71ea15b21c740bcb5079361396f18a24bbe55134c504a581 + languageName: node + linkType: hard + "@octokit/graphql@npm:^5.0.0": version: 5.0.6 resolution: "@octokit/graphql@npm:5.0.6" @@ -3258,23 +3269,23 @@ __metadata: languageName: node linkType: hard -"@octokit/oauth-authorization-url@npm:^5.0.0": - version: 5.0.0 - resolution: "@octokit/oauth-authorization-url@npm:5.0.0" - checksum: bc457c4af9559e9e8f752e643fc9d116247f4e4246e69959d99b9e39196c93d7af53c1c8e3bd946bd0e4fc29f7ba27efe9bced8525ffa41fe45ef56a8281014b +"@octokit/oauth-authorization-url@npm:^6.0.2": + version: 6.0.2 + resolution: "@octokit/oauth-authorization-url@npm:6.0.2" + checksum: 0f11169a3eeb782cc08312c923de1a702b25ae033b972ba40380b6d72cb3f684543c8b6a5cf6f05936fdc6b8892070d4f7581138d8efc1b4c4a55ae6d7762327 languageName: node linkType: hard -"@octokit/oauth-methods@npm:^2.0.0": - version: 2.0.6 - resolution: "@octokit/oauth-methods@npm:2.0.6" +"@octokit/oauth-methods@npm:^3.0.1": + version: 3.0.1 + resolution: "@octokit/oauth-methods@npm:3.0.1" dependencies: - "@octokit/oauth-authorization-url": ^5.0.0 - "@octokit/request": ^6.2.3 - "@octokit/request-error": ^3.0.3 - "@octokit/types": ^9.0.0 + "@octokit/oauth-authorization-url": ^6.0.2 + "@octokit/request": ^7.0.0 + "@octokit/request-error": ^4.0.1 + "@octokit/types": ^10.0.0 btoa-lite: ^1.0.0 - checksum: 151b933d79d6fbf36fdfae8cdc868a3d43316352eaccf46cb8c420cfd238658275e41996d2d377177553bc0c637c3aefe8ca99c1ab7fd62054654b6119b7b1cc + checksum: ad327084f97d2f3be270d8957545dbd06c35df3e99d8e58702217beb7ac3574c361b49dfe28ba5d96b7f1911ac9c8e26ae07d6180a0598eef8b7fab4b0fe4ad5 languageName: node linkType: hard @@ -3285,15 +3296,15 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-paginate-rest@npm:^7.0.0": - version: 7.1.2 - resolution: "@octokit/plugin-paginate-rest@npm:7.1.2" +"@octokit/plugin-paginate-rest@npm:^6.1.2": + version: 6.1.2 + resolution: "@octokit/plugin-paginate-rest@npm:6.1.2" dependencies: - "@octokit/tsconfig": ^2.0.0 - "@octokit/types": ^9.3.2 + "@octokit/tsconfig": ^1.0.2 + "@octokit/types": ^9.2.3 peerDependencies: "@octokit/core": ">=4" - checksum: dcff1593fd0635cff3a6add6bfa375316cce5071b540da55075d1fe4aa0ddf04e0a798707857db229f0705e91398a8a59cb07bdac4c95bda7e2eda48370b00c1 + checksum: a7b3e686c7cbd27ec07871cde6e0b1dc96337afbcef426bbe3067152a17b535abd480db1861ca28c88d93db5f7bfdbcadd0919ead19818c28a69d0e194038065 languageName: node linkType: hard @@ -3317,20 +3328,20 @@ __metadata: languageName: node linkType: hard -"@octokit/plugin-retry@npm:5.0.3": - version: 5.0.3 - resolution: "@octokit/plugin-retry@npm:5.0.3" +"@octokit/plugin-retry@npm:5.0.4": + version: 5.0.4 + resolution: "@octokit/plugin-retry@npm:5.0.4" dependencies: "@octokit/request-error": ^4.0.1 - "@octokit/types": ^9.0.0 + "@octokit/types": ^10.0.0 bottleneck: ^2.15.3 peerDependencies: "@octokit/core": ">=3" - checksum: f98b90333e26a214f057557ee5b13a926e0472a47d103345c504f99e6c3d8564a8fa54bf2871eda8ef47a8f9c1dba84fb68e749ab7a1a749c0a86a3ae74bdfa7 + checksum: 0c5645613f7ff758ac126da11ba20b4d49e4067676e30808f5ee3ee471adbd2ccfdea2200adfa5a4663b207964b3d60987f4c5e8682fb275bf134b33f2ef5178 languageName: node linkType: hard -"@octokit/request-error@npm:^3.0.0, @octokit/request-error@npm:^3.0.3": +"@octokit/request-error@npm:^3.0.0": version: 3.0.3 resolution: "@octokit/request-error@npm:3.0.3" dependencies: @@ -3352,7 +3363,7 @@ __metadata: languageName: node linkType: hard -"@octokit/request@npm:^6.0.0, @octokit/request@npm:^6.2.3": +"@octokit/request@npm:^6.0.0": version: 6.2.8 resolution: "@octokit/request@npm:6.2.8" dependencies: @@ -3366,22 +3377,35 @@ __metadata: languageName: node linkType: hard -"@octokit/rest@npm:19.0.12": - version: 19.0.12 - resolution: "@octokit/rest@npm:19.0.12" +"@octokit/request@npm:^7.0.0": + version: 7.0.0 + resolution: "@octokit/request@npm:7.0.0" dependencies: - "@octokit/core": ^4.2.1 - "@octokit/plugin-paginate-rest": ^7.0.0 - "@octokit/plugin-request-log": ^1.0.4 - "@octokit/plugin-rest-endpoint-methods": ^7.1.2 - checksum: 6e42a3d951461128a26f9634a0d3ac9e1955231286dc0637ae952db06c6296b19279217e6d58071e88bb0675c5bbb84fba5b4847c757ac98f4e3559a102bd93d + "@octokit/endpoint": ^8.0.0 + "@octokit/request-error": ^4.0.1 + "@octokit/types": ^10.0.0 + is-plain-object: ^5.0.0 + universal-user-agent: ^6.0.0 + checksum: d3b8ac25c3702bb69c5b345f7a9f16b158209db7e244cc2d60dbcbfbaf1edec8252d78885de3607ee85eb86db7c1d2e07fa2515ba6e25cf2880440c0df5e918a languageName: node linkType: hard -"@octokit/tsconfig@npm:^2.0.0": - version: 2.0.0 - resolution: "@octokit/tsconfig@npm:2.0.0" - checksum: c19b1c8a316682322a6bee26faf0225b59926770fa796833c7211521f464f915dd6950ab29c7a7996711ccf8986b5c0a088cc5a1c2b4d8848d503682537bccf2 +"@octokit/rest@npm:19.0.13": + version: 19.0.13 + resolution: "@octokit/rest@npm:19.0.13" + dependencies: + "@octokit/core": ^4.2.1 + "@octokit/plugin-paginate-rest": ^6.1.2 + "@octokit/plugin-request-log": ^1.0.4 + "@octokit/plugin-rest-endpoint-methods": ^7.1.2 + checksum: ca1553e3fe46efabffef60e68e4a228d4cc0f0d545daf7f019560f666d3e934c6f3a6402a42bbd786af4f3c0a6e69380776312f01b7d52998fe1bbdd1b068f69 + languageName: node + linkType: hard + +"@octokit/tsconfig@npm:^1.0.2": + version: 1.0.2 + resolution: "@octokit/tsconfig@npm:1.0.2" + checksum: 74d56f3e9f326a8dd63700e9a51a7c75487180629c7a68bbafee97c612fbf57af8347369bfa6610b9268a3e8b833c19c1e4beb03f26db9a9dce31f6f7a19b5b1 languageName: node linkType: hard @@ -3394,7 +3418,7 @@ __metadata: languageName: node linkType: hard -"@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.3.2": +"@octokit/types@npm:^9.0.0, @octokit/types@npm:^9.2.3": version: 9.3.2 resolution: "@octokit/types@npm:9.3.2" dependencies: @@ -9627,9 +9651,9 @@ __metadata: "@material/web": =1.0.0-pre.10 "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 - "@octokit/auth-oauth-device": 5.0.0 - "@octokit/plugin-retry": 5.0.3 - "@octokit/rest": 19.0.12 + "@octokit/auth-oauth-device": 5.0.2 + "@octokit/plugin-retry": 5.0.4 + "@octokit/rest": 19.0.13 "@open-wc/dev-server-hmr": 0.1.4 "@polymer/app-layout": 3.1.0 "@polymer/iron-flex-layout": 3.0.1 From 922e95b895fcb369dc397db5c047c78baf8327dc Mon Sep 17 00:00:00 2001 From: "Christoph Wen, B.Sc" <43651938+christophwen@users.noreply.github.com> Date: Tue, 20 Jun 2023 12:52:53 +0200 Subject: [PATCH 070/162] Fix time and date-time 12h formats (#16692) (#16805) * Fix time and date-time 12h formats (#16692) - am/pm check possible for other languages - adjusted date format gallery page for consistency - added gallery pages for date-time and time formats * Fix typo in am/pm check (#16692) --- gallery/src/data/date-options.ts | 24 ++++ .../date-time/date-time-numeric.markdown | 7 + .../src/pages/date-time/date-time-numeric.ts | 136 ++++++++++++++++++ .../date-time/date-time-seconds.markdown | 7 + .../src/pages/date-time/date-time-seconds.ts | 136 ++++++++++++++++++ .../date-time/date-time-short-year.markdown | 7 + .../pages/date-time/date-time-short-year.ts | 136 ++++++++++++++++++ .../pages/date-time/date-time-short.markdown | 7 + .../src/pages/date-time/date-time-short.ts | 136 ++++++++++++++++++ .../src/pages/date-time/date-time.markdown | 7 + gallery/src/pages/date-time/date-time.ts | 136 ++++++++++++++++++ gallery/src/pages/date-time/date.markdown | 2 +- .../src/pages/date-time/time-seconds.markdown | 7 + gallery/src/pages/date-time/time-seconds.ts | 135 +++++++++++++++++ .../src/pages/date-time/time-weekday.markdown | 7 + gallery/src/pages/date-time/time-weekday.ts | 135 +++++++++++++++++ gallery/src/pages/date-time/time.markdown | 7 + gallery/src/pages/date-time/time.ts | 136 ++++++++++++++++++ src/common/datetime/format_date_time.ts | 92 +++++------- src/common/datetime/format_time.ts | 55 +++---- src/common/datetime/use_am_pm.ts | 6 +- 21 files changed, 1227 insertions(+), 94 deletions(-) create mode 100644 gallery/src/data/date-options.ts create mode 100644 gallery/src/pages/date-time/date-time-numeric.markdown create mode 100644 gallery/src/pages/date-time/date-time-numeric.ts create mode 100644 gallery/src/pages/date-time/date-time-seconds.markdown create mode 100644 gallery/src/pages/date-time/date-time-seconds.ts create mode 100644 gallery/src/pages/date-time/date-time-short-year.markdown create mode 100644 gallery/src/pages/date-time/date-time-short-year.ts create mode 100644 gallery/src/pages/date-time/date-time-short.markdown create mode 100644 gallery/src/pages/date-time/date-time-short.ts create mode 100644 gallery/src/pages/date-time/date-time.markdown create mode 100644 gallery/src/pages/date-time/date-time.ts create mode 100644 gallery/src/pages/date-time/time-seconds.markdown create mode 100644 gallery/src/pages/date-time/time-seconds.ts create mode 100644 gallery/src/pages/date-time/time-weekday.markdown create mode 100644 gallery/src/pages/date-time/time-weekday.ts create mode 100644 gallery/src/pages/date-time/time.markdown create mode 100644 gallery/src/pages/date-time/time.ts diff --git a/gallery/src/data/date-options.ts b/gallery/src/data/date-options.ts new file mode 100644 index 0000000000..9bb856a26e --- /dev/null +++ b/gallery/src/data/date-options.ts @@ -0,0 +1,24 @@ +import type { ControlSelectOption } from "../../../src/components/ha-control-select"; + +export const timeOptions: ControlSelectOption[] = [ + { + value: "now", + label: "Now", + }, + { + value: "00:15:30", + label: "12:15:30 AM", + }, + { + value: "06:15:30", + label: "06:15:30 AM", + }, + { + value: "12:15:30", + label: "12:15:30 PM", + }, + { + value: "18:15:30", + label: "06:15:30 PM", + }, +]; diff --git a/gallery/src/pages/date-time/date-time-numeric.markdown b/gallery/src/pages/date-time/date-time-numeric.markdown new file mode 100644 index 0000000000..3310f315a1 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-numeric.markdown @@ -0,0 +1,7 @@ +--- +title: Date-Time Format (Numeric) +--- + +This pages lists all supported languages with their available date-time formats. + +Formatting function: `const formatDateTimeNumeric: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/date-time-numeric.ts b/gallery/src/pages/date-time/date-time-numeric.ts new file mode 100644 index 0000000000..608b3fc152 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-numeric.ts @@ -0,0 +1,136 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-select"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatDateTimeNumeric } from "../../../../src/common/datetime/format_date_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-date-time-numeric") +export class DemoDateTimeDateTimeNumeric extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatDateTimeNumeric( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatDateTimeNumeric( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatDateTimeNumeric( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 900px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-date-time-numeric": DemoDateTimeDateTimeNumeric; + } +} diff --git a/gallery/src/pages/date-time/date-time-seconds.markdown b/gallery/src/pages/date-time/date-time-seconds.markdown new file mode 100644 index 0000000000..01cfa6c729 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-seconds.markdown @@ -0,0 +1,7 @@ +--- +title: Date-Time Format (Seconds) +--- + +This pages lists all supported languages with their available date-time formats. + +Formatting function: `const formatDateTimeWithSeconds: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/date-time-seconds.ts b/gallery/src/pages/date-time/date-time-seconds.ts new file mode 100644 index 0000000000..5f5b48f989 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-seconds.ts @@ -0,0 +1,136 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-select"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatDateTimeWithSeconds } from "../../../../src/common/datetime/format_date_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-date-time-seconds") +export class DemoDateTimeDateTimeSeconds extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatDateTimeWithSeconds( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatDateTimeWithSeconds( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatDateTimeWithSeconds( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 900px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-date-time-seconds": DemoDateTimeDateTimeSeconds; + } +} diff --git a/gallery/src/pages/date-time/date-time-short-year.markdown b/gallery/src/pages/date-time/date-time-short-year.markdown new file mode 100644 index 0000000000..19e77b55b9 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-short-year.markdown @@ -0,0 +1,7 @@ +--- +title: Date-Time Format (Short w/ Year) +--- + +This pages lists all supported languages with their available date-time formats. + +Formatting function: `const formatShortDateTimeWithYear: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/date-time-short-year.ts b/gallery/src/pages/date-time/date-time-short-year.ts new file mode 100644 index 0000000000..f132f2a047 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-short-year.ts @@ -0,0 +1,136 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-select"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatShortDateTimeWithYear } from "../../../../src/common/datetime/format_date_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-date-time-short-year") +export class DemoDateTimeDateTimeShortYear extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatShortDateTimeWithYear( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatShortDateTimeWithYear( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatShortDateTimeWithYear( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 900px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-date-time-short-year": DemoDateTimeDateTimeShortYear; + } +} diff --git a/gallery/src/pages/date-time/date-time-short.markdown b/gallery/src/pages/date-time/date-time-short.markdown new file mode 100644 index 0000000000..3564a7afa0 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-short.markdown @@ -0,0 +1,7 @@ +--- +title: Date-Time Format (Short) +--- + +This pages lists all supported languages with their available date-time formats. + +Formatting function: `const formatShortDateTime: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/date-time-short.ts b/gallery/src/pages/date-time/date-time-short.ts new file mode 100644 index 0000000000..21f7eb1294 --- /dev/null +++ b/gallery/src/pages/date-time/date-time-short.ts @@ -0,0 +1,136 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-select"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatShortDateTime } from "../../../../src/common/datetime/format_date_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-date-time-short") +export class DemoDateTimeDateTimeShort extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatShortDateTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatShortDateTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatShortDateTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 900px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-date-time-short": DemoDateTimeDateTimeShort; + } +} diff --git a/gallery/src/pages/date-time/date-time.markdown b/gallery/src/pages/date-time/date-time.markdown new file mode 100644 index 0000000000..cef6195ab1 --- /dev/null +++ b/gallery/src/pages/date-time/date-time.markdown @@ -0,0 +1,7 @@ +--- +title: Date-Time Format +--- + +This pages lists all supported languages with their available date-time formats. + +Formatting function: `const formatDateTime: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/date-time.ts b/gallery/src/pages/date-time/date-time.ts new file mode 100644 index 0000000000..4bb4b75865 --- /dev/null +++ b/gallery/src/pages/date-time/date-time.ts @@ -0,0 +1,136 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-select"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatDateTime } from "../../../../src/common/datetime/format_date_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-date-time") +export class DemoDateTimeDateTime extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatDateTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatDateTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatDateTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 900px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-date-time": DemoDateTimeDateTime; + } +} diff --git a/gallery/src/pages/date-time/date.markdown b/gallery/src/pages/date-time/date.markdown index 5eb64bb19e..599921e1c7 100644 --- a/gallery/src/pages/date-time/date.markdown +++ b/gallery/src/pages/date-time/date.markdown @@ -1,5 +1,5 @@ --- -title: (Numeric) Date Formatting +title: Date Format (Numeric) --- This pages lists all supported languages with their available (numeric) date formats. diff --git a/gallery/src/pages/date-time/time-seconds.markdown b/gallery/src/pages/date-time/time-seconds.markdown new file mode 100644 index 0000000000..23136c29f4 --- /dev/null +++ b/gallery/src/pages/date-time/time-seconds.markdown @@ -0,0 +1,7 @@ +--- +title: Time Format (Seconds) +--- + +This pages lists all supported languages with their available time formats. + +Formatting function: `const formatTimeWithSeconds: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/time-seconds.ts b/gallery/src/pages/date-time/time-seconds.ts new file mode 100644 index 0000000000..761bc6ed58 --- /dev/null +++ b/gallery/src/pages/date-time/time-seconds.ts @@ -0,0 +1,135 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatTimeWithSeconds } from "../../../../src/common/datetime/format_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-time-seconds") +export class DemoDateTimeTimeSeconds extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatTimeWithSeconds( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatTimeWithSeconds( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatTimeWithSeconds( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 600px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-time-seconds": DemoDateTimeTimeSeconds; + } +} diff --git a/gallery/src/pages/date-time/time-weekday.markdown b/gallery/src/pages/date-time/time-weekday.markdown new file mode 100644 index 0000000000..637be6afe3 --- /dev/null +++ b/gallery/src/pages/date-time/time-weekday.markdown @@ -0,0 +1,7 @@ +--- +title: Time Format (Weekday) +--- + +This pages lists all supported languages with their available time formats. + +Formatting function: `const formatTimeWeekday: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/time-weekday.ts b/gallery/src/pages/date-time/time-weekday.ts new file mode 100644 index 0000000000..8ed5c951f5 --- /dev/null +++ b/gallery/src/pages/date-time/time-weekday.ts @@ -0,0 +1,135 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatTimeWeekday } from "../../../../src/common/datetime/format_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-time-weekday") +export class DemoDateTimeTimeWeekday extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatTimeWeekday( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatTimeWeekday( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatTimeWeekday( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 800px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-time-weekday": DemoDateTimeTimeWeekday; + } +} diff --git a/gallery/src/pages/date-time/time.markdown b/gallery/src/pages/date-time/time.markdown new file mode 100644 index 0000000000..df90d8931a --- /dev/null +++ b/gallery/src/pages/date-time/time.markdown @@ -0,0 +1,7 @@ +--- +title: Time Format +--- + +This pages lists all supported languages with their available time formats. + +Formatting function: `const formatTime: (dateObj: Date, locale: FrontendLocaleData) => string` \ No newline at end of file diff --git a/gallery/src/pages/date-time/time.ts b/gallery/src/pages/date-time/time.ts new file mode 100644 index 0000000000..df7b101653 --- /dev/null +++ b/gallery/src/pages/date-time/time.ts @@ -0,0 +1,136 @@ +import { html, css, LitElement } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-select"; +import { translationMetadata } from "../../../../src/resources/translations-metadata"; +import { formatTime } from "../../../../src/common/datetime/format_time"; +import { timeOptions } from "../../data/date-options"; +import { demoConfig } from "../../../../src/fake_data/demo_config"; +import { + FrontendLocaleData, + NumberFormat, + TimeFormat, + DateFormat, + FirstWeekday, + TimeZone, +} from "../../../../src/data/translation"; + +@customElement("demo-date-time-time") +export class DemoDateTimeTime extends LitElement { + @state() private selection?: string = "now"; + + @state() private date: Date = new Date(); + + handleValueChanged(e: CustomEvent) { + this.selection = e.detail.value as string; + this.date = new Date(); + if (this.selection !== "now") { + const [hours, minutes, seconds] = this.selection.split(":").map(Number); + this.date.setHours(hours); + this.date.setMinutes(minutes); + this.date.setSeconds(seconds); + } + } + + protected render() { + const defaultLocale: FrontendLocaleData = { + language: "en", + number_format: NumberFormat.language, + time_format: TimeFormat.language, + date_format: DateFormat.language, + first_weekday: FirstWeekday.language, + time_zone: TimeZone.local, + }; + return html` + + + +
+
Language
+
Default (lang)
+
12 Hours
+
24 Hours
+
+ ${Object.entries(translationMetadata.translations) + .filter(([key, _]) => key !== "test") + .map( + ([key, value]) => html` +
+
${value.nativeName}
+
+ ${formatTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.language, + }, + demoConfig + )} +
+
+ ${formatTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.am_pm, + }, + demoConfig + )} +
+
+ ${formatTime( + this.date, + { + ...defaultLocale, + language: key, + time_format: TimeFormat.twenty_four, + }, + demoConfig + )} +
+
+ ` + )} +
+ `; + } + + static get styles() { + return css` + ha-control-select { + max-width: 800px; + margin: 12px auto; + } + .header { + font-weight: bold; + } + .center { + text-align: center; + } + .container { + max-width: 600px; + margin: 12px auto; + display: flex; + align-items: center; + justify-content: space-evenly; + } + + .container > div { + flex-grow: 1; + width: 20%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-date-time-time": DemoDateTimeTime; + } +} diff --git a/src/common/datetime/format_date_time.ts b/src/common/datetime/format_date_time.ts index d9b7a3a862..52700b4a23 100644 --- a/src/common/datetime/format_date_time.ts +++ b/src/common/datetime/format_date_time.ts @@ -15,20 +15,15 @@ export const formatDateTime = ( const formatDateTimeMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - year: "numeric", - month: "long", - day: "numeric", - hour: useAmPm(locale) ? "numeric" : "2-digit", - minute: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + year: "numeric", + month: "long", + day: "numeric", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // Aug 9, 2021, 8:23 AM @@ -40,20 +35,15 @@ export const formatShortDateTimeWithYear = ( const formatShortDateTimeWithYearMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - year: "numeric", - month: "short", - day: "numeric", - hour: useAmPm(locale) ? "numeric" : "2-digit", - minute: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + year: "numeric", + month: "short", + day: "numeric", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // Aug 9, 8:23 AM @@ -65,19 +55,14 @@ export const formatShortDateTime = ( const formatShortDateTimeMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - month: "short", - day: "numeric", - hour: useAmPm(locale) ? "numeric" : "2-digit", - minute: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + month: "short", + day: "numeric", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // August 9, 2021, 8:23:15 AM @@ -89,21 +74,16 @@ export const formatDateTimeWithSeconds = ( const formatDateTimeWithSecondsMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - year: "numeric", - month: "long", - day: "numeric", - hour: useAmPm(locale) ? "numeric" : "2-digit", - minute: "2-digit", - second: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + year: "numeric", + month: "long", + day: "numeric", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + second: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // 9/8/2021, 8:23 AM diff --git a/src/common/datetime/format_time.ts b/src/common/datetime/format_time.ts index 41827b4f8d..948eb553fe 100644 --- a/src/common/datetime/format_time.ts +++ b/src/common/datetime/format_time.ts @@ -13,17 +13,12 @@ export const formatTime = ( const formatTimeMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - hour: "numeric", - minute: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + hour: "numeric", + minute: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // 9:15:24 PM || 21:15:24 @@ -35,18 +30,13 @@ export const formatTimeWithSeconds = ( const formatTimeWithSecondsMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - hour: useAmPm(locale) ? "numeric" : "2-digit", - minute: "2-digit", - second: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + second: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // Tuesday 7:00 PM || Tuesday 19:00 @@ -58,18 +48,13 @@ export const formatTimeWeekday = ( const formatTimeWeekdayMem = memoizeOne( (locale: FrontendLocaleData, serverTimeZone: string) => - new Intl.DateTimeFormat( - locale.language === "en" && !useAmPm(locale) - ? "en-u-hc-h23" - : locale.language, - { - weekday: "long", - hour: useAmPm(locale) ? "numeric" : "2-digit", - minute: "2-digit", - hour12: useAmPm(locale), - timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, - } - ) + new Intl.DateTimeFormat(locale.language, { + weekday: "long", + hour: useAmPm(locale) ? "numeric" : "2-digit", + minute: "2-digit", + hourCycle: useAmPm(locale) ? "h12" : "h23", + timeZone: locale.time_zone === "server" ? serverTimeZone : undefined, + }) ); // 21:15 diff --git a/src/common/datetime/use_am_pm.ts b/src/common/datetime/use_am_pm.ts index 97bf2911b8..4510fee522 100644 --- a/src/common/datetime/use_am_pm.ts +++ b/src/common/datetime/use_am_pm.ts @@ -8,8 +8,10 @@ export const useAmPm = memoizeOne((locale: FrontendLocaleData): boolean => { ) { const testLanguage = locale.time_format === TimeFormat.language ? locale.language : undefined; - const test = new Date().toLocaleString(testLanguage); - return test.includes("AM") || test.includes("PM"); + const test = new Date("January 1, 2023 22:00:00").toLocaleString( + testLanguage + ); + return test.includes("10"); } return locale.time_format === TimeFormat.am_pm; From 7bc2ca3b6551422bb2ff9237077bfd35bad10d41 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 20 Jun 2023 15:25:26 +0200 Subject: [PATCH 071/162] Add more info lock (#15995) * Add more info lock * Use same height for pending state * Fix attributes * Add unlocking/locking to switch * Improve code support --- src/data/lock.ts | 20 ++ .../dialog-enter-code.ts | 21 +- .../show-enter-code-dialog.ts | 3 +- .../ha-more-info-alarm_control_panel-modes.ts | 2 +- .../lock/ha-more-info-lock-toggle.ts | 199 ++++++++++++++ src/dialogs/more-info/const.ts | 1 + .../controls/more-info-alarm_control_panel.ts | 2 +- .../more-info/controls/more-info-lock.ts | 248 ++++++++++++++---- .../hui-alarm-modes-tile-feature.ts | 2 +- src/translations/en.json | 5 + 10 files changed, 438 insertions(+), 65 deletions(-) create mode 100644 src/data/lock.ts rename src/dialogs/{more-info/components/alarm_control_panel => enter-code}/dialog-enter-code.ts (91%) rename src/dialogs/{more-info/components/alarm_control_panel => enter-code}/show-enter-code-dialog.ts (91%) create mode 100644 src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts diff --git a/src/data/lock.ts b/src/data/lock.ts new file mode 100644 index 0000000000..a6c9914559 --- /dev/null +++ b/src/data/lock.ts @@ -0,0 +1,20 @@ +import { + HassEntityAttributeBase, + HassEntityBase, +} from "home-assistant-js-websocket"; + +export const FORMAT_TEXT = "text"; +export const FORMAT_NUMBER = "number"; + +export const enum LockEntityFeature { + OPEN = 1, +} + +interface LockEntityAttributes extends HassEntityAttributeBase { + code_format?: string; + changed_by?: string | null; +} + +export interface LockEntity extends HassEntityBase { + attributes: LockEntityAttributes; +} diff --git a/src/dialogs/more-info/components/alarm_control_panel/dialog-enter-code.ts b/src/dialogs/enter-code/dialog-enter-code.ts similarity index 91% rename from src/dialogs/more-info/components/alarm_control_panel/dialog-enter-code.ts rename to src/dialogs/enter-code/dialog-enter-code.ts index acacb74666..b4cfc63016 100644 --- a/src/dialogs/more-info/components/alarm_control_panel/dialog-enter-code.ts +++ b/src/dialogs/enter-code/dialog-enter-code.ts @@ -1,14 +1,15 @@ import { mdiCheck, mdiClose } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/ha-button"; -import "../../../../components/ha-control-button"; -import { createCloseHeading } from "../../../../components/ha-dialog"; -import "../../../../components/ha-textfield"; -import type { HaTextField } from "../../../../components/ha-textfield"; -import { HomeAssistant } from "../../../../types"; -import { HassDialog } from "../../../make-dialog-manager"; +import { ifDefined } from "lit/directives/if-defined"; +import { fireEvent } from "../../common/dom/fire_event"; +import "../../components/ha-button"; +import "../../components/ha-control-button"; +import { createCloseHeading } from "../../components/ha-dialog"; +import "../../components/ha-textfield"; +import type { HaTextField } from "../../components/ha-textfield"; +import { HomeAssistant } from "../../types"; +import { HassDialog } from "../make-dialog-manager"; import { EnterCodeDialogParams } from "./show-enter-code-dialog"; const BUTTONS = [ @@ -72,7 +73,8 @@ export class DialogEnterCode } private _inputValueChange(e) { - const val = (e.currentTarget! as any).value; + const field = e.currentTarget as HaTextField; + const val = field.value; this._showClearButton = !!val; } @@ -97,6 +99,7 @@ export class DialogEnterCode id="code" .label=${this.hass.localize("ui.dialogs.enter_code.input_label")} type="password" + pattern=${ifDefined(this._dialogParams.codePattern)} input-mode="text" > diff --git a/src/dialogs/more-info/components/alarm_control_panel/show-enter-code-dialog.ts b/src/dialogs/enter-code/show-enter-code-dialog.ts similarity index 91% rename from src/dialogs/more-info/components/alarm_control_panel/show-enter-code-dialog.ts rename to src/dialogs/enter-code/show-enter-code-dialog.ts index 802ae23fb1..6356c20364 100644 --- a/src/dialogs/more-info/components/alarm_control_panel/show-enter-code-dialog.ts +++ b/src/dialogs/enter-code/show-enter-code-dialog.ts @@ -1,7 +1,8 @@ -import { fireEvent } from "../../../../common/dom/fire_event"; +import { fireEvent } from "../../common/dom/fire_event"; export interface EnterCodeDialogParams { codeFormat: "text" | "number"; + codePattern?: string; submitText?: string; cancelText?: string; title?: string; diff --git a/src/dialogs/more-info/components/alarm_control_panel/ha-more-info-alarm_control_panel-modes.ts b/src/dialogs/more-info/components/alarm_control_panel/ha-more-info-alarm_control_panel-modes.ts index ea8881c5b5..22f028621b 100644 --- a/src/dialogs/more-info/components/alarm_control_panel/ha-more-info-alarm_control_panel-modes.ts +++ b/src/dialogs/more-info/components/alarm_control_panel/ha-more-info-alarm_control_panel-modes.ts @@ -14,7 +14,7 @@ import { } from "../../../../data/alarm_control_panel"; import { UNAVAILABLE } from "../../../../data/entity"; import { HomeAssistant } from "../../../../types"; -import { showEnterCodeDialogDialog } from "./show-enter-code-dialog"; +import { showEnterCodeDialogDialog } from "../../../enter-code/show-enter-code-dialog"; @customElement("ha-more-info-alarm_control_panel-modes") export class HaMoreInfoAlarmControlPanelModes extends LitElement { diff --git a/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts b/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts new file mode 100644 index 0000000000..f8a005002c --- /dev/null +++ b/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts @@ -0,0 +1,199 @@ +import { + css, + CSSResultGroup, + html, + LitElement, + PropertyValues, + TemplateResult, +} from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { styleMap } from "lit/directives/style-map"; +import { domainIcon } from "../../../../common/entity/domain_icon"; +import { stateColorCss } from "../../../../common/entity/state_color"; +import "../../../../components/ha-control-button"; +import "../../../../components/ha-control-switch"; +import { UNAVAILABLE, UNKNOWN } from "../../../../data/entity"; +import { forwardHaptic } from "../../../../data/haptics"; +import { LockEntity } from "../../../../data/lock"; +import { HomeAssistant } from "../../../../types"; +import { showEnterCodeDialogDialog } from "../../../enter-code/show-enter-code-dialog"; + +@customElement("ha-more-info-lock-toggle") +export class HaMoreInfoLockToggle extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj!: LockEntity; + + @state() private _isOn = false; + + public willUpdate(changedProps: PropertyValues): void { + super.willUpdate(changedProps); + if (changedProps.has("stateObj")) { + this._isOn = + this.stateObj.state === "locked" || this.stateObj.state === "locking"; + } + } + + private _valueChanged(ev) { + const checked = ev.target.checked as boolean; + + if (checked) { + this._turnOn(); + } else { + this._turnOff(); + } + } + + private async _turnOn() { + this._isOn = true; + try { + await this._callService(true); + } catch (err) { + this._isOn = false; + } + } + + private async _turnOff() { + this._isOn = false; + try { + await this._callService(false); + } catch (err) { + this._isOn = true; + } + } + + private async _callService(turnOn: boolean): Promise { + if (!this.hass || !this.stateObj) { + return; + } + forwardHaptic("light"); + + let code: string | undefined; + + if (this.stateObj.attributes.code_format) { + const response = await showEnterCodeDialogDialog(this, { + codeFormat: "text", + codePattern: this.stateObj.attributes.code_format, + title: this.hass.localize( + `ui.dialogs.more_info_control.lock.${turnOn ? "lock" : "unlock"}` + ), + submitText: this.hass.localize( + `ui.dialogs.more_info_control.lock.${turnOn ? "lock" : "unlock"}` + ), + }); + if (response == null) { + throw new Error("cancel"); + } + code = response; + } + + await this.hass.callService("lock", turnOn ? "lock" : "unlock", { + entity_id: this.stateObj.entity_id, + code, + }); + } + + protected render(): TemplateResult { + const locking = this.stateObj.state === "locking"; + const unlocking = this.stateObj.state === "unlocking"; + + const color = stateColorCss(this.stateObj); + + const onIcon = domainIcon( + "lock", + this.stateObj, + locking ? "locking" : "locked" + ); + + const offIcon = domainIcon( + "lock", + this.stateObj, + unlocking ? "unlocking" : "unlocked" + ); + + if (this.stateObj.state === UNKNOWN) { + return html` +
+ + + + + + +
+ `; + } + + return html` + + + `; + } + + static get styles(): CSSResultGroup { + return css` + ha-control-switch { + height: 45vh; + max-height: 320px; + min-height: 200px; + --control-switch-thickness: 100px; + --control-switch-border-radius: 24px; + --control-switch-padding: 6px; + --mdc-icon-size: 24px; + } + .buttons { + display: flex; + flex-direction: column; + width: 100px; + height: 45vh; + max-height: 320px; + min-height: 200px; + padding: 6px; + box-sizing: border-box; + } + ha-control-button { + flex: 1; + width: 100%; + --control-button-border-radius: 18px; + --mdc-icon-size: 24px; + } + ha-control-button.active { + --control-button-icon-color: white; + --control-button-background-color: var(--color); + --control-button-background-opacity: 1; + } + ha-control-button:not(:last-child) { + margin-bottom: 6px; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-more-info-lock-toggle": HaMoreInfoLockToggle; + } +} diff --git a/src/dialogs/more-info/const.ts b/src/dialogs/more-info/const.ts index 8675c499e1..79af1e13d3 100644 --- a/src/dialogs/more-info/const.ts +++ b/src/dialogs/more-info/const.ts @@ -22,6 +22,7 @@ export const DOMAINS_WITH_NEW_MORE_INFO = [ "fan", "input_boolean", "light", + "lock", "siren", "switch", ]; diff --git a/src/dialogs/more-info/controls/more-info-alarm_control_panel.ts b/src/dialogs/more-info/controls/more-info-alarm_control_panel.ts index 7fadaa5776..7f73407ae1 100644 --- a/src/dialogs/more-info/controls/more-info-alarm_control_panel.ts +++ b/src/dialogs/more-info/controls/more-info-alarm_control_panel.ts @@ -7,8 +7,8 @@ import { stateColorCss } from "../../../common/entity/state_color"; import "../../../components/ha-outlined-button"; import { AlarmControlPanelEntity } from "../../../data/alarm_control_panel"; import type { HomeAssistant } from "../../../types"; +import { showEnterCodeDialogDialog } from "../../enter-code/show-enter-code-dialog"; import "../components/alarm_control_panel/ha-more-info-alarm_control_panel-modes"; -import { showEnterCodeDialogDialog } from "../components/alarm_control_panel/show-enter-code-dialog"; import { moreInfoControlStyle } from "../components/ha-more-info-control-style"; import "../components/ha-more-info-state-header"; diff --git a/src/dialogs/more-info/controls/more-info-lock.ts b/src/dialogs/more-info/controls/more-info-lock.ts index 33afb0e93f..5fa6ec5df3 100644 --- a/src/dialogs/more-info/controls/more-info-lock.ts +++ b/src/dialogs/more-info/controls/more-info-lock.ts @@ -1,43 +1,156 @@ -import "@material/mwc-button"; -import type { HassEntity } from "home-assistant-js-websocket"; -import { css, html, LitElement, nothing } from "lit"; -import { customElement, property, query } from "lit/decorators"; +import "@material/web/iconbutton/outlined-icon-button"; +import { mdiDoorOpen, mdiLock, mdiLockOff } from "@mdi/js"; +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { customElement, property } from "lit/decorators"; +import { styleMap } from "lit/directives/style-map"; +import { domainIcon } from "../../../common/entity/domain_icon"; +import { stateColorCss } from "../../../common/entity/state_color"; +import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-attributes"; -import "../../../components/ha-textfield"; -import type { HaTextField } from "../../../components/ha-textfield"; +import { UNAVAILABLE } from "../../../data/entity"; +import { LockEntity, LockEntityFeature } from "../../../data/lock"; import type { HomeAssistant } from "../../../types"; +import { showEnterCodeDialogDialog } from "../../enter-code/show-enter-code-dialog"; +import { moreInfoControlStyle } from "../components/ha-more-info-control-style"; +import "../components/ha-more-info-state-header"; +import "../components/lock/ha-more-info-lock-toggle"; @customElement("more-info-lock") class MoreInfoLock extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public stateObj?: HassEntity; + @property({ attribute: false }) public stateObj?: LockEntity; - @query("ha-textfield") private _textfield?: HaTextField; + private async _open() { + this._callService("open"); + } + + private async _lock() { + this._callService("lock"); + } + + private async _unlock() { + this._callService("unlock"); + } + + private async _callService(service: "open" | "lock" | "unlock") { + let code: string | undefined; + + if (this.stateObj!.attributes.code_format) { + const response = await showEnterCodeDialogDialog(this, { + codeFormat: "text", + codePattern: this.stateObj!.attributes.code_format, + title: this.hass.localize( + `ui.dialogs.more_info_control.lock.${service}` + ), + submitText: this.hass.localize( + `ui.dialogs.more_info_control.lock.${service}` + ), + }); + if (!response) { + return; + } + code = response; + } + + this.hass.callService("lock", service, { + entity_id: this.stateObj!.entity_id, + code, + }); + } protected render() { if (!this.hass || !this.stateObj) { return nothing; } + + const supportsOpen = supportsFeature(this.stateObj, LockEntityFeature.OPEN); + + const color = stateColorCss(this.stateObj); + const style = { + "--icon-color": color, + }; + + const isJammed = this.stateObj.state === "jammed"; + return html` - ${this.stateObj.attributes.code_format - ? html`
- - ${this.stateObj.state === "locked" - ? html`${this.hass.localize("ui.card.lock.unlock")}` - : html`${this.hass.localize("ui.card.lock.lock")}`} -
` - : ""} + +
+ ${ + this.stateObj.state === "jammed" + ? html` +
+ +
+ +
+
+ ` + : html` + + + ` + } + ${ + supportsOpen || isJammed + ? html` +
+ ${supportsOpen + ? html` + + + + ` + : nothing} + ${isJammed + ? html` + + + + + + + ` + : nothing} +
+ ` + : nothing + } +
+ { const domain = computeDomain(stateObj.entity_id); diff --git a/src/translations/en.json b/src/translations/en.json index c803418f1a..706882414a 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -978,6 +978,11 @@ "disarm_action": "Disarm", "arm_title": "Arm", "arm_action": "Arm" + }, + "lock": { + "open": "Open", + "lock": "Lock", + "unlock": "Unlock" } }, "entity_registry": { From 13b864e2618a9bee475839794a291190a7ea3241 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 20 Jun 2023 16:45:45 +0200 Subject: [PATCH 072/162] Use ha-icon-button-group in more info cover (#16911) --- .../more-info/controls/more-info-cover.ts | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/dialogs/more-info/controls/more-info-cover.ts b/src/dialogs/more-info/controls/more-info-cover.ts index 7fd9d9a8ac..3ea0907245 100644 --- a/src/dialogs/more-info/controls/more-info-cover.ts +++ b/src/dialogs/more-info/controls/more-info-cover.ts @@ -11,6 +11,8 @@ import { customElement, property, state } from "lit/decorators"; import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-attributes"; +import "../../../components/ha-icon-button-group"; +import "../../../components/ha-icon-button-toggle"; import { computeCoverPositionStateDisplay, CoverEntity, @@ -24,6 +26,8 @@ import "../components/cover/ha-more-info-cover-toggle"; import { moreInfoControlStyle } from "../components/ha-more-info-control-style"; import "../components/ha-more-info-state-header"; +type Mode = "position" | "button"; + @customElement("more-info-cover") class MoreInfoCover extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -34,10 +38,10 @@ class MoreInfoCover extends LitElement { @state() private _liveTilt?: number; - @state() private _mode?: "position" | "button"; + @state() private _mode?: Mode; - private _toggleMode() { - this._mode = this._mode === "position" ? "button" : "position"; + private _setMode(ev) { + this._mode = ev.currentTarget.mode; } private _positionSliderMoved(ev) { @@ -192,19 +196,26 @@ class MoreInfoCover extends LitElement { (supportsPosition || supportsTiltPosition) && (supportsOpenClose || supportsTilt) ? html` -
- + -
+ .selected=${this._mode === "position"} + .path=${mdiMenu} + .mode=${"position"} + @click=${this._setMode} + > + + ` : nothing } From 1cf24ffc8dc7039ceec952e9b33e38f3d2efe230 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 20 Jun 2023 07:53:13 -0700 Subject: [PATCH 073/162] Allow continue_on_error in the UI action editor (#16834) --- src/data/script.ts | 15 +++++++---- .../action/ha-automation-action-row.ts | 27 +++++++++++++++++-- src/translations/en.json | 1 + 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/data/script.ts b/src/data/script.ts index a1288158db..b679b0a22f 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -33,6 +33,7 @@ export const isMaxMode = arrayLiteralIncludes(MODES_MAX); export const baseActionStruct = object({ alias: optional(string()), + continue_on_error: optional(boolean()), enabled: optional(boolean()), }); @@ -99,6 +100,7 @@ export interface BlueprintScriptConfig extends ManualScriptConfig { interface BaseAction { alias?: string; + continue_on_error?: boolean; enabled?: boolean; } @@ -230,14 +232,10 @@ interface UnknownAction extends BaseAction { [key: string]: unknown; } -export type Action = +export type NonConditionAction = | EventAction | DeviceAction | ServiceAction - | Condition - | ShorthandAndCondition - | ShorthandOrCondition - | ShorthandNotCondition | DelayAction | SceneAction | WaitAction @@ -251,6 +249,13 @@ export type Action = | ParallelAction | UnknownAction; +export type Action = + | NonConditionAction + | Condition + | ShorthandAndCondition + | ShorthandOrCondition + | ShorthandNotCondition; + export interface ActionTypes { delay: DelayAction; wait_template: WaitAction; diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts index 0819a14287..242fd3173f 100644 --- a/src/panels/config/automation/action/ha-automation-action-row.ts +++ b/src/panels/config/automation/action/ha-automation-action-row.ts @@ -1,6 +1,7 @@ import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { + mdiAlertCircleCheck, mdiCheck, mdiContentDuplicate, mdiContentCopy, @@ -14,7 +15,14 @@ import { mdiStopCircleOutline, } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; +import { + css, + CSSResultGroup, + html, + LitElement, + nothing, + PropertyValues, +} from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; @@ -34,7 +42,11 @@ import { subscribeEntityRegistry, } from "../../../../data/entity_registry"; import { Clipboard } from "../../../../data/automation"; -import { Action, getActionType } from "../../../../data/script"; +import { + Action, + NonConditionAction, + getActionType, +} from "../../../../data/script"; import { describeAction } from "../../../../data/script_i18n"; import { callExecuteScript } from "../../../../data/service"; import { @@ -184,6 +196,17 @@ export default class HaAutomationActionRow extends LitElement { + ${type !== "condition" && + (this.action as NonConditionAction).continue_on_error === true + ? html`
+ + + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.continue_on_error" + )} + +
` + : nothing} ${this.hideMenu ? "" : html` diff --git a/src/translations/en.json b/src/translations/en.json index 706882414a..a82e7b34af 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2501,6 +2501,7 @@ "delete_confirm_text": "[%key:ui::panel::config::automation::editor::triggers::delete_confirm_text%]", "unsupported_action": "No visual editor support for action: {action}", "type_select": "Action type", + "continue_on_error": "Continue on error", "type": { "service": { "label": "Call service" From 1cb1bcf2747044cfb6f98a0523fa3ccf253593f7 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 21 Jun 2023 08:02:09 +0200 Subject: [PATCH 074/162] Open assist from dashboard (#16829) --- src/data/lovelace.ts | 7 ++ .../ha-voice-command-dialog.ts | 27 +++++-- .../show-ha-voice-command-dialog.ts | 14 +++- src/panels/lovelace/common/handle-action.ts | 8 ++ .../lovelace/components/hui-action-editor.ts | 73 +++++++++++++++++-- .../lovelace/editor/structs/action-struct.ts | 10 +++ src/translations/en.json | 3 + 7 files changed, 128 insertions(+), 14 deletions(-) diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts index 432cb6167b..091ced7c7b 100644 --- a/src/data/lovelace.ts +++ b/src/data/lovelace.ts @@ -152,6 +152,12 @@ export interface MoreInfoActionConfig extends BaseActionConfig { action: "more-info"; } +export interface AssistActionConfig extends BaseActionConfig { + action: "assist"; + pipeline_id?: string; + start_listening?: boolean; +} + export interface NoActionConfig extends BaseActionConfig { action: "none"; } @@ -180,6 +186,7 @@ export type ActionConfig = | NavigateActionConfig | UrlActionConfig | MoreInfoActionConfig + | AssistActionConfig | NoActionConfig | CustomActionConfig; diff --git a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts index e0ec5db5de..b3a83bfce5 100644 --- a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts +++ b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts @@ -24,10 +24,10 @@ import { stopPropagation } from "../../common/dom/stop_propagation"; import "../../components/ha-button"; import "../../components/ha-button-menu"; import "../../components/ha-dialog"; +import "../../components/ha-dialog-header"; import "../../components/ha-icon-button"; import "../../components/ha-list-item"; import "../../components/ha-textfield"; -import "../../components/ha-dialog-header"; import type { HaTextField } from "../../components/ha-textfield"; import { AssistPipeline, @@ -41,6 +41,7 @@ import type { HomeAssistant } from "../../types"; import { AudioRecorder } from "../../util/audio-recorder"; import { documentationUrl } from "../../util/documentation-url"; import { showAlertDialog } from "../generic/show-dialog-box"; +import { VoiceCommandDialogParams } from "./show-ha-voice-command-dialog"; interface Message { who: string; @@ -82,7 +83,13 @@ export class HaVoiceCommandDialog extends LitElement { private _stt_binary_handler_id?: number | null; - public async showDialog(): Promise { + private _pipelinePromise?: Promise; + + public async showDialog(params?: VoiceCommandDialogParams): Promise { + if (params?.pipeline_id) { + this._pipelineId = params?.pipeline_id; + } + this._conversation = [ { who: "hass", @@ -92,6 +99,11 @@ export class HaVoiceCommandDialog extends LitElement { this._opened = true; await this.updateComplete; this._scrollMessagesBottom(); + + await this._pipelinePromise; + if (params?.start_listening && this._pipeline?.stt_engine) { + this._toggleListening(); + } } public async closeDialog(): Promise { @@ -230,7 +242,7 @@ export class HaVoiceCommandDialog extends LitElement {
import("./ha-voice-command-dialog"); +export interface VoiceCommandDialogParams { + pipeline_id?: string; + start_listening?: boolean; +} + export const showVoiceCommandDialog = ( element: HTMLElement, - hass: HomeAssistant + hass: HomeAssistant, + dialogParams?: VoiceCommandDialogParams ): void => { if (hass.auth.external?.config.hasAssist) { hass.auth.external!.fireMessage({ type: "assist/show", + payload: { + pipeline_id: dialogParams?.pipeline_id, + start_listening: dialogParams?.start_listening, + }, }); return; } fireEvent(element, "show-dialog", { dialogTag: "ha-voice-command-dialog", dialogImport: loadVoiceCommandDialog, - dialogParams: {}, + dialogParams, }); }; diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index 7ea895d723..f782d6ad53 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -4,6 +4,7 @@ import { forwardHaptic } from "../../../data/haptics"; import { domainToName } from "../../../data/integration"; import { ActionConfig } from "../../../data/lovelace"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; +import { showVoiceCommandDialog } from "../../../dialogs/voice-command-dialog/show-ha-voice-command-dialog"; import { HomeAssistant } from "../../../types"; import { showToast } from "../../../util/toast"; import { toggleEntity } from "./entity/toggle-entity"; @@ -155,6 +156,13 @@ export const handleAction = async ( forwardHaptic("light"); break; } + case "assist": { + showVoiceCommandDialog(node, hass, { + start_listening: actionConfig.start_listening, + pipeline_id: actionConfig.pipeline_id, + }); + break; + } case "fire-dom-event": { fireEvent(node, "ll-custom", actionConfig); } diff --git a/src/panels/lovelace/components/hui-action-editor.ts b/src/panels/lovelace/components/hui-action-editor.ts index 4077ae9a09..20d5e0f597 100644 --- a/src/panels/lovelace/components/hui-action-editor.ts +++ b/src/panels/lovelace/components/hui-action-editor.ts @@ -3,6 +3,8 @@ import { customElement, property } from "lit/decorators"; import memoizeOne from "memoize-one"; import { fireEvent } from "../../../common/dom/fire_event"; import { stopPropagation } from "../../../common/dom/stop_propagation"; +import "../../../components/ha-assist-pipeline-picker"; +import { HaFormSchema, SchemaUnion } from "../../../components/ha-form/types"; import "../../../components/ha-help-tooltip"; import "../../../components/ha-navigation-picker"; import "../../../components/ha-service-control"; @@ -24,9 +26,31 @@ const DEFAULT_ACTIONS: UiAction[] = [ "navigate", "url", "call-service", + "assist", "none", ]; +const ASSIST_SCHEMA = [ + { + type: "grid", + name: "", + schema: [ + { + name: "pipeline_id", + selector: { + assist_pipeline: {}, + }, + }, + { + name: "start_listening", + selector: { + boolean: {}, + }, + }, + ], + }, +] as const satisfies readonly HaFormSchema[]; + @customElement("hui-action-editor") export class HuiActionEditor extends LitElement { @property() public config?: ActionConfig; @@ -101,7 +125,7 @@ export class HuiActionEditor extends LitElement { ? html` ` - : ""} + : nothing}
${this.config?.action === "navigate" ? html` @@ -114,7 +138,7 @@ export class HuiActionEditor extends LitElement { @value-changed=${this._navigateValueChanged} > ` - : ""} + : nothing} ${this.config?.action === "url" ? html` ` - : ""} + : nothing} ${this.config?.action === "call-service" ? html` ` - : ""} + : nothing} + ${this.config?.action === "assist" + ? html` + + + ` + : nothing} `; } @@ -182,7 +218,7 @@ export class HuiActionEditor extends LitElement { return; } const target = ev.target! as EditorTarget; - const value = ev.target.value; + const value = ev.target.value ?? ev.target.checked; if (this[`_${target.configValue}`] === value) { return; } @@ -193,6 +229,21 @@ export class HuiActionEditor extends LitElement { } } + private _formValueChanged(ev): void { + ev.stopPropagation(); + const value = ev.detail.value; + + fireEvent(this, "value-changed", { + value: value, + }); + } + + private _computeFormLabel(schema: SchemaUnion) { + return this.hass?.localize( + `ui.panel.lovelace.editor.action-editor.${schema.name}` + ); + } + private _serviceValueChanged(ev: CustomEvent) { ev.stopPropagation(); const value = { @@ -240,17 +291,25 @@ export class HuiActionEditor extends LitElement { width: 100%; } ha-service-control, - ha-navigation-picker { + ha-navigation-picker, + ha-form { display: block; } ha-textfield, ha-service-control, - ha-navigation-picker { + ha-navigation-picker, + ha-form { margin-top: 8px; } ha-service-control { --service-control-padding: 0; } + ha-formfield { + display: flex; + height: 56px; + align-items: center; + --mdc-typography-body2-font-size: 1em; + } `; } } diff --git a/src/panels/lovelace/editor/structs/action-struct.ts b/src/panels/lovelace/editor/structs/action-struct.ts index e8a6ec82be..512e45aa84 100644 --- a/src/panels/lovelace/editor/structs/action-struct.ts +++ b/src/panels/lovelace/editor/structs/action-struct.ts @@ -51,6 +51,12 @@ const actionConfigStructNavigate = object({ confirmation: optional(actionConfigStructConfirmation), }); +const actionConfigStructAssist = type({ + action: literal("assist"), + pipeline_id: optional(string()), + start_listening: optional(boolean()), +}); + const actionConfigStructCustom = type({ action: literal("fire-dom-event"), }); @@ -63,6 +69,7 @@ export const actionConfigStructType = object({ "call-service", "url", "navigate", + "assist", ]), confirmation: optional(actionConfigStructConfirmation), }); @@ -82,6 +89,9 @@ export const actionConfigStruct = dynamic((value) => { case "url": { return actionConfigStructUrl; } + case "assist": { + return actionConfigStructAssist; + } } } diff --git a/src/translations/en.json b/src/translations/en.json index a82e7b34af..5f28ae09ad 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4417,12 +4417,15 @@ "action-editor": { "navigation_path": "Navigation Path", "url_path": "URL Path", + "start_listening": "Start listening", + "pipeline_id": "Assistant", "actions": { "default_action": "Default Action", "call-service": "Call Service", "more-info": "More Info", "toggle": "Toggle", "navigate": "Navigate", + "assist": "Assist", "url": "URL", "none": "No Action" } From c63c717d9f6abcd6e46f2bfe1074e2d784453f86 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 20 Jun 2023 23:03:17 -0700 Subject: [PATCH 075/162] Add 'Default' option to theme-picker (#16915) --- .../ha-selector/ha-selector-theme.ts | 1 + src/components/ha-theme-picker.ts | 20 ++++++++++++++++++- src/data/selector.ts | 3 +-- src/translations/en.json | 3 ++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/components/ha-selector/ha-selector-theme.ts b/src/components/ha-selector/ha-selector-theme.ts index eccf3c5b23..b00d523413 100644 --- a/src/components/ha-selector/ha-selector-theme.ts +++ b/src/components/ha-selector/ha-selector-theme.ts @@ -24,6 +24,7 @@ export class HaThemeSelector extends LitElement { .hass=${this.hass} .value=${this.value} .label=${this.label} + .includeDefault=${this.selector.theme?.include_default} .disabled=${this.disabled} .required=${this.required} > diff --git a/src/components/ha-theme-picker.ts b/src/components/ha-theme-picker.ts index 47aadd7e62..8835a5b186 100644 --- a/src/components/ha-theme-picker.ts +++ b/src/components/ha-theme-picker.ts @@ -1,17 +1,28 @@ import "@material/mwc-list/mwc-list-item"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { + css, + CSSResultGroup, + html, + nothing, + LitElement, + TemplateResult, +} from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { stopPropagation } from "../common/dom/stop_propagation"; import { HomeAssistant } from "../types"; import "./ha-select"; +const DEFAULT_THEME = "default"; + @customElement("ha-theme-picker") export class HaThemePicker extends LitElement { @property() public value?: string; @property() public label?: string; + @property() includeDefault?: boolean = false; + @property({ attribute: false }) public hass?: HomeAssistant; @property({ type: Boolean, reflect: true }) public disabled = false; @@ -36,6 +47,13 @@ export class HaThemePicker extends LitElement { "ui.components.theme-picker.no_theme" )}
+ ${this.includeDefault + ? html`${this.hass!.localize( + "ui.components.theme-picker.default" + )}` + : nothing} ${Object.keys(this.hass!.themes.themes) .sort() .map( diff --git a/src/data/selector.ts b/src/data/selector.ts index 6523ede4f6..acbac41a43 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -345,8 +345,7 @@ export interface TemplateSelector { } export interface ThemeSelector { - // eslint-disable-next-line @typescript-eslint/ban-types - theme: {} | null; + theme: { include_default?: boolean } | null; } export interface TimeSelector { // eslint-disable-next-line @typescript-eslint/ban-types diff --git a/src/translations/en.json b/src/translations/en.json index 5f28ae09ad..c6a560da92 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -396,7 +396,8 @@ }, "theme-picker": { "theme": "Theme", - "no_theme": "No theme" + "no_theme": "No theme", + "default": "[%key:ui::panel::profile::themes::default%]" }, "language-picker": { "language": "Language", From 221f4f34a7d2e0b2cb6c2772f50ee6c88a86c91a Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 20 Jun 2023 23:04:39 -0700 Subject: [PATCH 076/162] Use new automation dialog for new scripts (#16933) --- .../automation/dialog-new-automation.ts | 41 +++++++++++++------ .../config/automation/ha-automation-picker.ts | 2 +- .../automation/show-dialog-new-automation.ts | 11 ++++- src/panels/config/script/ha-script-picker.ts | 36 ++++++++++------ src/translations/en.json | 15 +++++++ 5 files changed, 76 insertions(+), 29 deletions(-) diff --git a/src/panels/config/automation/dialog-new-automation.ts b/src/panels/config/automation/dialog-new-automation.ts index 0c160900b9..735d6aa9de 100644 --- a/src/panels/config/automation/dialog-new-automation.ts +++ b/src/panels/config/automation/dialog-new-automation.ts @@ -18,8 +18,10 @@ import "../../../components/ha-icon-next"; import "../../../components/ha-list-item"; import "../../../components/ha-tip"; import { showAutomationEditor } from "../../../data/automation"; +import { showScriptEditor } from "../../../data/script"; import { Blueprint, + BlueprintDomain, Blueprints, BlueprintSourceType, fetchBlueprints, @@ -29,6 +31,7 @@ import { HassDialog } from "../../../dialogs/make-dialog-manager"; import { haStyle, haStyleDialog } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; +import type { NewAutomationDialogParams } from "./show-dialog-new-automation"; const SOURCE_TYPE_ICONS: Record = { local: mdiFile, @@ -42,11 +45,15 @@ class DialogNewAutomation extends LitElement implements HassDialog { @state() private _opened = false; + @state() private _mode: BlueprintDomain = "automation"; + @state() public blueprints?: Blueprints; - public showDialog(): void { + public showDialog(params: NewAutomationDialogParams): void { this._opened = true; - fetchBlueprints(this.hass!, "automation").then((blueprints) => { + this._mode = params?.mode || "automation"; + + fetchBlueprints(this.hass!, this._mode).then((blueprints) => { this.blueprints = blueprints; }); } @@ -92,14 +99,14 @@ class DialogNewAutomation extends LitElement implements HassDialog { @closed=${this.closeDialog} .heading=${createCloseHeading( this.hass, - this.hass.localize("ui.panel.config.automation.dialog_new.header") + this.hass.localize(`ui.panel.config.${this._mode}.dialog_new.header`) )} > ${this.hass.localize( - "ui.panel.config.automation.dialog_new.create_empty" + `ui.panel.config.${this._mode}.dialog_new.create_empty` )} ${this.hass.localize( - "ui.panel.config.automation.dialog_new.create_empty_description" + `ui.panel.config.${this._mode}.dialog_new.create_empty_description` )} @@ -139,11 +146,11 @@ class DialogNewAutomation extends LitElement implements HassDialog { ${blueprint.author ? this.hass.localize( - `ui.panel.config.automation.dialog_new.blueprint_source.author`, + `ui.panel.config.${this._mode}.dialog_new.blueprint_source.author`, { author: blueprint.author } ) : this.hass.localize( - `ui.panel.config.automation.dialog_new.blueprint_source.${blueprint.sourceType}` + `ui.panel.config.${this._mode}.dialog_new.blueprint_source.${blueprint.sourceType}` )} @@ -161,11 +168,11 @@ class DialogNewAutomation extends LitElement implements HassDialog { ${this.hass.localize( - "ui.panel.config.automation.dialog_new.create_blueprint" + `ui.panel.config.${this._mode}.dialog_new.create_blueprint` )} ${this.hass.localize( - "ui.panel.config.automation.dialog_new.create_blueprint_description" + `ui.panel.config.${this._mode}.dialog_new.create_blueprint_description` )} @@ -180,7 +187,7 @@ class DialogNewAutomation extends LitElement implements HassDialog { rel="noreferrer noopener" > ${this.hass.localize( - "ui.panel.config.automation.dialog_new.discover_blueprint_tip" + `ui.panel.config.${this._mode}.dialog_new.discover_blueprint_tip` )} @@ -196,7 +203,11 @@ class DialogNewAutomation extends LitElement implements HassDialog { } const path = (ev.currentTarget! as any).path; this.closeDialog(); - showAutomationEditor({ use_blueprint: { path } }); + if (this._mode === "script") { + showScriptEditor({ use_blueprint: { path } }); + } else { + showAutomationEditor({ use_blueprint: { path } }); + } } private async _blank(ev) { @@ -204,7 +215,11 @@ class DialogNewAutomation extends LitElement implements HassDialog { return; } this.closeDialog(); - showAutomationEditor(); + if (this._mode === "script") { + showScriptEditor(); + } else { + showAutomationEditor(); + } } static get styles(): CSSResultGroup { diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index cdf33e2b50..eb1003aa0b 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -486,7 +486,7 @@ class HaAutomationPicker extends LitElement { private _createNew() { if (isComponentLoaded(this.hass, "blueprint")) { - showNewAutomationDialog(this); + showNewAutomationDialog(this, { mode: "automation" }); } else { navigate("/config/automation/edit/new"); } diff --git a/src/panels/config/automation/show-dialog-new-automation.ts b/src/panels/config/automation/show-dialog-new-automation.ts index 0a618c178b..1425842e80 100644 --- a/src/panels/config/automation/show-dialog-new-automation.ts +++ b/src/panels/config/automation/show-dialog-new-automation.ts @@ -1,11 +1,18 @@ import { fireEvent } from "../../../common/dom/fire_event"; +export interface NewAutomationDialogParams { + mode: "script" | "automation"; +} + export const loadNewAutomationDialog = () => import("./dialog-new-automation"); -export const showNewAutomationDialog = (element: HTMLElement): void => { +export const showNewAutomationDialog = ( + element: HTMLElement, + newAutomationDialogParams: NewAutomationDialogParams +): void => { fireEvent(element, "show-dialog", { dialogTag: "ha-dialog-new-automation", dialogImport: loadNewAutomationDialog, - dialogParams: {}, + dialogParams: newAutomationDialogParams, }); }; diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index 61ac52dc3f..491d13599d 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -12,6 +12,7 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { differenceInDays } from "date-fns/esm"; +import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { formatShortDateTime } from "../../../common/datetime/format_date_time"; import { relativeTime } from "../../../common/datetime/relative_time"; import { fireEvent, HASSDomEvent } from "../../../common/dom/fire_event"; @@ -44,6 +45,7 @@ import { HomeAssistant, Route } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; import { showToast } from "../../../util/toast"; import { configSections } from "../ha-panel-config"; +import { showNewAutomationDialog } from "../automation/show-dialog-new-automation"; import { EntityRegistryEntry } from "../../../data/entity_registry"; import { findRelated } from "../../../data/search"; import { fetchBlueprints } from "../../../data/blueprint"; @@ -242,19 +244,19 @@ class HaScriptPicker extends LitElement { @related-changed=${this._relatedFilterChanged} > - - - - - + + + `; } @@ -312,6 +314,14 @@ class HaScriptPicker extends LitElement { } } + private _createNew() { + if (isComponentLoaded(this.hass, "blueprint")) { + showNewAutomationDialog(this, { mode: "script" }); + } else { + navigate("/config/script/edit/new"); + } + } + private _runScript = async (script: any) => { const entry = this.entityRegistry.find( (e) => e.entity_id === script.entity_id diff --git a/src/translations/en.json b/src/translations/en.json index c6a560da92..bcad0d6848 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2699,6 +2699,21 @@ "delete": "[%key:ui::common::delete%]", "duplicate": "[%key:ui::common::duplicate%]" }, + "dialog_new": { + "header": "Create script", + "create_empty": "Create new script", + "create_empty_description": "Start with an empty script from scratch", + "create_blueprint": "[%key:ui::panel::config::automation::dialog_new::create_blueprint%]", + "create_blueprint_description": "[%key:ui::panel::config::automation::dialog_new::create_blueprint_description%]", + "blueprint_source": { + "author": "[%key:ui::panel::config::automation::dialog_new::blueprint_source::author%]", + "local": "[%key:ui::panel::config::automation::dialog_new::blueprint_source::local%]", + "community": "[%key:ui::panel::config::automation::dialog_new::blueprint_source::community%]", + "homeassistant": "[%key:ui::panel::config::automation::dialog_new::blueprint_source::homeassistant%]" + }, + "discover_blueprint_tip": "[%key:ui::panel::config::automation::dialog_new::discover_blueprint_tip%]" + }, + "editor": { "alias": "Name", "icon": "Icon", From 386ed2167f49db661bbbc264ff54c62d8be5a419 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 21 Jun 2023 08:12:04 +0200 Subject: [PATCH 077/162] Make automation editor card headers translateable (triggers partly) (#16969) --- src/data/automation_i18n.ts | 71 +++++++++++++++++++++---------------- src/translations/en.json | 42 +++++++++++++++++----- 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index 80f9caecad..b7ea6dcaab 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -24,6 +24,9 @@ import { EntityRegistryEntry } from "./entity_registry"; import "../resources/intl-polyfill"; import { FrontendLocaleData } from "./translation"; +const triggerTranslationBaseKey = + "ui.panel.config.automation.editor.triggers.type"; + const describeDuration = (forTime: number | string | ForDict) => { let duration: string | null; if (typeof forTime === "number") { @@ -101,14 +104,19 @@ export const describeTrigger = ( } const eventTypesString = disjunctionFormatter.format(eventTypes); - return `When ${eventTypesString} event is fired`; + return hass.localize( + `${triggerTranslationBaseKey}.event.description.full`, + { eventTypes: eventTypesString } + ); } // Home Assistant Trigger if (trigger.platform === "homeassistant" && trigger.event) { - return `When Home Assistant is ${ - trigger.event === "start" ? "started" : "shutdown" - }`; + return hass.localize( + trigger.event === "start" + ? `${triggerTranslationBaseKey}.homeassistant.description.started` + : `${triggerTranslationBaseKey}.homeassistant.description.shutdown` + ); } // Numeric State Trigger @@ -329,29 +337,28 @@ export const describeTrigger = ( // Sun Trigger if (trigger.platform === "sun" && trigger.event) { - let base = `When the sun ${trigger.event === "sunset" ? "sets" : "rises"}`; - + let duration = ""; if (trigger.offset) { - let duration = ""; - - if (trigger.offset) { - if (typeof trigger.offset === "number") { - duration = ` offset by ${secondsToDuration(trigger.offset)!}`; - } else if (typeof trigger.offset === "string") { - duration = ` offset by ${trigger.offset}`; - } else { - duration = ` offset by ${JSON.stringify(trigger.offset)}`; - } + if (typeof trigger.offset === "number") { + duration = secondsToDuration(trigger.offset)!; + } else if (typeof trigger.offset === "string") { + duration = trigger.offset; + } else { + duration = JSON.stringify(trigger.offset); } - base += duration; } - return base; + return hass.localize( + trigger.event === "sunset" + ? `${triggerTranslationBaseKey}.sun.description.sets` + : `${triggerTranslationBaseKey}.sun.description.rises`, + { hasDuration: duration !== "", duration: duration } + ); } // Tag Trigger if (trigger.platform === "tag") { - return "When a tag is scanned"; + return hass.localize(`${triggerTranslationBaseKey}.tag.description.full`); } // Time Trigger @@ -364,10 +371,9 @@ export const describeTrigger = ( : localizeTimeString(at, hass.locale, hass.config) ); - const last = result.splice(-1, 1)[0]; - return `When the time is equal to ${ - result.length ? `${result.join(", ")} or ` : "" - }${last}`; + return hass.localize(`${triggerTranslationBaseKey}.time.description.full`, { + time: disjunctionFormatter.format(result), + }); } // Time Pattern Trigger @@ -561,24 +567,27 @@ export const describeTrigger = ( // MQTT Trigger if (trigger.platform === "mqtt") { - return "When an MQTT message has been received"; + return hass.localize(`${triggerTranslationBaseKey}.mqtt.description.full`); } // Template Trigger if (trigger.platform === "template") { - let base = "When a template triggers"; + let duration = ""; if (trigger.for) { - const duration = describeDuration(trigger.for); - if (duration) { - base += ` for ${duration}`; - } + duration = describeDuration(trigger.for) ?? ""; } - return base; + + return hass.localize( + `${triggerTranslationBaseKey}.template.description.full`, + { hasDuration: duration !== "", duration: duration } + ); } // Webhook Trigger if (trigger.platform === "webhook") { - return "When a Webhook payload has been received"; + return hass.localize( + `${triggerTranslationBaseKey}.webhook.description.full` + ); } if (trigger.platform === "device") { diff --git a/src/translations/en.json b/src/translations/en.json index bcad0d6848..16ca1df024 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2292,7 +2292,10 @@ "event_data": "Event data", "context_users": "Limit to events triggered by", "context_user_picked": "User firing event", - "context_user_pick": "Select user" + "context_user_pick": "Select user", + "description": { + "full": "When {eventTypes} event is fired" + } }, "geo_location": { "label": "Geolocation", @@ -2314,12 +2317,19 @@ "label": "Home Assistant", "event": "Event:", "start": "Start", - "shutdown": "Shutdown" + "shutdown": "Shutdown", + "description": { + "started": "When Home Assistant is started", + "shutdown": "When Home Assistant is shutdown" + } }, "mqtt": { "label": "MQTT", "topic": "Topic", - "payload": "Payload (optional)" + "payload": "Payload (optional)", + "description": { + "full": "When an MQTT message has been received" + } }, "numeric_state": { "label": "Numeric state", @@ -2336,22 +2346,35 @@ "event": "[%key:ui::panel::config::automation::editor::triggers::type::homeassistant::event%]", "sunrise": "Sunrise", "sunset": "Sunset", - "offset": "Offset (optional)" + "offset": "Offset (optional)", + "description": { + "sets": "When the sun sets{hasDuration, select, \n true { offset by {duration}} \n other {}\n }", + "rises": "When the sun rises{hasDuration, select, \n true { offset by {duration}} \n other {}\n }" + } }, "tag": { - "label": "Tag" + "label": "Tag", + "description": { + "full": "When a tag is scanned" + } }, "template": { "label": "Template", "value_template": "Value template", - "for": "For" + "for": "For", + "description": { + "full": "When a template triggers{hasDuration, select, \n true { for {duration}} \n other {}\n }" + } }, "time": { "type_value": "Fixed time", "type_input": "Value of a date/time helper or timestamp-class sensor", "label": "Time", "at": "At time", - "mode": "Mode" + "mode": "Mode", + "description": { + "full": "When the time is equal to {time}" + } }, "time_pattern": { "label": "Time Pattern", @@ -2365,7 +2388,10 @@ "local_only": "Only accessible from the local network", "webhook_id": "Webhook ID", "webhook_id_helper": "Treat this ID like a password: keep it secret, and make it hard to guess.", - "webhook_settings": "Webhook Settings" + "webhook_settings": "Webhook Settings", + "description": { + "full": "When a Webhook payload has been received" + } }, "zone": { "label": "Zone", From 33d6ad1b0b3caa573624ded6af3475cfc862c130 Mon Sep 17 00:00:00 2001 From: Lasse Bang Mikkelsen Date: Wed, 21 Jun 2023 08:19:25 +0200 Subject: [PATCH 078/162] Add copy-to-clipboard button for long-lived tokens (#16956) --- src/components/ha-textfield.ts | 4 +++ .../ha-long-lived-access-token-dialog.ts | 33 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/components/ha-textfield.ts b/src/components/ha-textfield.ts index e411469252..c18b49c2d4 100644 --- a/src/components/ha-textfield.ts +++ b/src/components/ha-textfield.ts @@ -99,6 +99,10 @@ export class HaTextField extends TextFieldBase { direction: var(--direction); } + .mdc-text-field__icon--trailing { + padding: var(--textfield-icon-trailing-padding, 12px); + } + .mdc-floating-label:not(.mdc-floating-label--float-above) { text-overflow: ellipsis; width: inherit; diff --git a/src/panels/profile/ha-long-lived-access-token-dialog.ts b/src/panels/profile/ha-long-lived-access-token-dialog.ts index c16cb7b332..7841e4918a 100644 --- a/src/panels/profile/ha-long-lived-access-token-dialog.ts +++ b/src/panels/profile/ha-long-lived-access-token-dialog.ts @@ -1,4 +1,5 @@ import "@material/mwc-button"; +import { mdiContentCopy } from "@mdi/js"; import { css, CSSResultGroup, @@ -11,9 +12,13 @@ import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import { createCloseHeading } from "../../components/ha-dialog"; import "../../components/ha-textfield"; +import "../../components/ha-icon-button"; import { haStyleDialog } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; import { LongLivedAccessTokenDialogParams } from "./show-long-lived-access-token-dialog"; +import type { HaTextField } from "../../components/ha-textfield"; +import { copyToClipboard } from "../../common/util/copy-clipboard"; +import { showToast } from "../../util/toast"; const QR_LOGO_URL = "/static/icons/favicon-192x192.png"; @@ -55,8 +60,15 @@ export class HaLongLivedAccessTokenDialog extends LitElement { "ui.panel.profile.long_lived_access_tokens.prompt_copy_token" )} type="text" + iconTrailing readOnly - > + > + +
${this._qrCode ? this._qrCode @@ -71,6 +83,14 @@ export class HaLongLivedAccessTokenDialog extends LitElement { `; } + private async _copyToken(ev): Promise { + const textField = ev.target.parentElement as HaTextField; + await copyToClipboard(textField.value); + showToast(this, { + message: this.hass.localize("ui.common.copied_clipboard"), + }); + } + private async _generateQR() { const qrcode = await import("qrcode"); const canvas = await qrcode.toCanvas(this._params!.token, { @@ -111,6 +131,17 @@ export class HaLongLivedAccessTokenDialog extends LitElement { } ha-textfield { display: block; + --textfield-icon-trailing-padding: 0; + } + ha-textfield > ha-icon-button { + position: relative; + right: -8px; + --mdc-icon-button-size: 36px; + --mdc-icon-size: 20px; + color: var(--secondary-text-color); + inset-inline-start: initial; + inset-inline-end: -8px; + direction: var(--direction); } `, ]; From 07d37dd89f25dae045ce21856db243276a8a8b3a Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 20 Jun 2023 23:50:01 -0700 Subject: [PATCH 079/162] Handle multiple triggers in trigger condition UI (#16983) --- .../ha-selector/ha-selector-select.ts | 34 ++++---- .../types/ha-automation-condition-trigger.ts | 81 ++++++++++++------- 2 files changed, 72 insertions(+), 43 deletions(-) diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts index f4b07b55aa..e8bd3ac4b4 100644 --- a/src/components/ha-selector/ha-selector-select.ts +++ b/src/components/ha-selector/ha-selector-select.ts @@ -4,6 +4,7 @@ import { css, html, LitElement } from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; import { stopPropagation } from "../../common/dom/stop_propagation"; +import { ensureArray } from "../../common/array/ensure-array"; import type { SelectOption, SelectSelector } from "../../data/selector"; import type { HomeAssistant } from "../../types"; import "../ha-checkbox"; @@ -40,7 +41,7 @@ export class HaSelectSelector extends LitElement { protected render() { const options = - this.selector.select?.options.map((option) => + this.selector.select?.options?.map((option) => typeof option === "object" ? (option as SelectOption) : ({ value: option, label: option } as SelectOption) @@ -77,7 +78,8 @@ export class HaSelectSelector extends LitElement { ${this._renderHelper()} `; } - + const value = + !this.value || this.value === "" ? [] : ensureArray(this.value); return html`
${this.label} @@ -85,7 +87,7 @@ export class HaSelectSelector extends LitElement { (item: SelectOption) => html` !option.disabled && !value?.includes(option.value) @@ -231,19 +233,19 @@ export class HaSelectSelector extends LitElement { const value: string = ev.target.value; const checked = ev.target.checked; + const oldValue = + !this.value || this.value === "" ? [] : ensureArray(this.value); + if (checked) { - if (!this.value) { - newValue = [value]; - } else if (this.value.includes(value)) { + if (oldValue.includes(value)) { return; - } else { - newValue = [...this.value, value]; } + newValue = [...oldValue, value]; } else { - if (!this.value?.includes(value)) { + if (!oldValue?.includes(value)) { return; } - newValue = (this.value as string[]).filter((v) => v !== value); + newValue = oldValue.filter((v) => v !== value); } fireEvent(this, "value-changed", { @@ -252,7 +254,7 @@ export class HaSelectSelector extends LitElement { } private async _removeItem(ev) { - const value: string[] = [...(this.value! as string[])]; + const value: string[] = [...ensureArray(this.value!)]; value.splice(ev.target.idx, 1); fireEvent(this, "value-changed", { @@ -277,7 +279,10 @@ export class HaSelectSelector extends LitElement { return; } - if (newValue !== undefined && this.value?.includes(newValue)) { + const currentValue = + !this.value || this.value === "" ? [] : ensureArray(this.value); + + if (newValue !== undefined && currentValue.includes(newValue)) { return; } @@ -286,9 +291,6 @@ export class HaSelectSelector extends LitElement { this.comboBox.setInputValue(""); }, 0); - const currentValue = - !this.value || this.value === "" ? [] : (this.value as string[]); - fireEvent(this, "value-changed", { value: [...currentValue, newValue], }); diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-trigger.ts b/src/panels/config/automation/condition/types/ha-automation-condition-trigger.ts index 3eb72d48d2..8935668618 100644 --- a/src/panels/config/automation/condition/types/ha-automation-condition-trigger.ts +++ b/src/panels/config/automation/condition/types/ha-automation-condition-trigger.ts @@ -1,9 +1,11 @@ import "@material/mwc-list/mwc-list-item"; +import memoizeOne from "memoize-one"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../../common/dom/fire_event"; import { ensureArray } from "../../../../../common/array/ensure-array"; +import type { SchemaUnion } from "../../../../../components/ha-form/types"; import "../../../../../components/ha-select"; import type { AutomationConfig, @@ -30,6 +32,22 @@ export class HaTriggerCondition extends LitElement { }; } + private _schema = memoizeOne( + (triggers: Trigger[]) => + [ + { + name: "id", + selector: { + select: { + multiple: true, + options: triggers.map((trigger) => trigger.id!), + }, + }, + required: true, + }, + ] as const + ); + connectedCallback() { super.connectedCallback(); const details = { callback: (config) => this._automationUpdated(config) }; @@ -45,30 +63,33 @@ export class HaTriggerCondition extends LitElement { } protected render() { - const { id } = this.condition; - if (!this._triggers.length) { return this.hass.localize( "ui.panel.config.automation.editor.conditions.type.trigger.no_triggers" ); } - return html` - ${this._triggers.map( - (trigger) => - html` - ${trigger.id} - ` - )} - `; + + const schema = this._schema(this._triggers); + + return html` + + `; } + private _computeLabelCallback = ( + schema: SchemaUnion> + ): string => + this.hass.localize( + `ui.panel.config.automation.editor.conditions.type.trigger.${schema.name}` + ); + private _automationUpdated(config?: AutomationConfig) { const seenIds = new Set(); this._triggers = config?.trigger @@ -78,18 +99,24 @@ export class HaTriggerCondition extends LitElement { : []; } - private _triggerPicked(ev) { + private _valueChanged(ev: CustomEvent): void { ev.stopPropagation(); - if (!ev.target.value) { - return; + const newValue = ev.detail.value; + + if (typeof newValue.id === "string") { + if (!this._triggers.some((trigger) => trigger.id === newValue.id)) { + newValue.id = ""; + } + } else if (Array.isArray(newValue.id)) { + newValue.id = newValue.id.filter((id) => + this._triggers.some((trigger) => trigger.id === id) + ); + if (!newValue.id.length) { + newValue.id = ""; + } } - const newTrigger = ev.target.value; - if (this.condition.id === newTrigger) { - return; - } - fireEvent(this, "value-changed", { - value: { ...this.condition, id: newTrigger }, - }); + + fireEvent(this, "value-changed", { value: newValue }); } } From 5aa6ffe2e4412e8332eb3b01710db771fe69ee23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 21 Jun 2023 11:35:02 +0200 Subject: [PATCH 080/162] Map GitHub block quotes to our ha-alert component (#16757) --- gallery/src/pages/lovelace/markdown-card.ts | 11 +++++++- src/components/ha-markdown-element.ts | 30 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gallery/src/pages/lovelace/markdown-card.ts b/gallery/src/pages/lovelace/markdown-card.ts index 1abca4bdcc..700283b6b8 100644 --- a/gallery/src/pages/lovelace/markdown-card.ts +++ b/gallery/src/pages/lovelace/markdown-card.ts @@ -9,7 +9,7 @@ const CONFIGS = [ heading: "markdown-it demo", config: ` - type: markdown - content: >- + content: | # h1 Heading 8-) ## h2 Heading @@ -65,6 +65,15 @@ const CONFIGS = [ >> ...by using additional greater-than signs right next to each other... > > > ...or with spaces between arrows. + > **Warning** Hey there + > This is a warning with a title + + > **Note** + > This is a note + + > **Note** + > This is a multiline note + > Lorem ipsum... ## Lists diff --git a/src/components/ha-markdown-element.ts b/src/components/ha-markdown-element.ts index 1a4691c917..7a15e35e0b 100644 --- a/src/components/ha-markdown-element.ts +++ b/src/components/ha-markdown-element.ts @@ -3,6 +3,8 @@ import { customElement, property } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import { renderMarkdown } from "../resources/render-markdown"; +const _blockQuoteToAlert = { Note: "info", Warning: "warning" }; + @customElement("ha-markdown-element") class HaMarkdownElement extends ReactiveElement { @property() public content?; @@ -65,6 +67,34 @@ class HaMarkdownElement extends ReactiveElement { node.loading = "lazy"; } node.addEventListener("load", this._resize); + } else if (node instanceof HTMLQuoteElement) { + // Map GitHub blockquote elements to our ha-alert element + const firstElementChild = node.firstElementChild; + const quoteTitleElement = firstElementChild?.firstElementChild; + const quoteType = + quoteTitleElement?.textContent && + _blockQuoteToAlert[quoteTitleElement.textContent]; + + // GitHub is strict on how these are defined, we need to make sure we know what we have before starting to replace it + if (quoteTitleElement?.nodeName === "STRONG" && quoteType) { + const alertNote = document.createElement("ha-alert"); + alertNote.alertType = quoteType; + alertNote.title = + (firstElementChild!.childNodes[1].nodeName === "#text" && + firstElementChild!.childNodes[1].textContent?.trimStart()) || + ""; + + const childNodes = Array.from(firstElementChild!.childNodes); + for (const child of childNodes.slice( + childNodes.findIndex( + // There is always a line break between the title and the content, we want to skip that + (childNode) => childNode instanceof HTMLBRElement + ) + 1 + )) { + alertNote.appendChild(child); + } + node.firstElementChild!.replaceWith(alertNote); + } } } } From b46c74fe7635ee194b780fe318efa785f767aa5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Wed, 21 Jun 2023 11:35:17 +0200 Subject: [PATCH 081/162] Add haStyleScrollbar to hass-subpage (#16745) --- src/layouts/hass-subpage.ts | 162 +++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 78 deletions(-) diff --git a/src/layouts/hass-subpage.ts b/src/layouts/hass-subpage.ts index 5c2d73436e..75decf778a 100644 --- a/src/layouts/hass-subpage.ts +++ b/src/layouts/hass-subpage.ts @@ -13,6 +13,7 @@ import { computeRTL } from "../common/util/compute_rtl"; import "../components/ha-icon-button-arrow-prev"; import "../components/ha-menu-button"; import { HomeAssistant } from "../types"; +import { haStyleScrollbar } from "../resources/styles"; @customElement("hass-subpage") class HassSubpage extends LitElement { @@ -73,7 +74,9 @@ class HassSubpage extends LitElement {
${this.header}
-
+
+ +
@@ -94,88 +97,91 @@ class HassSubpage extends LitElement { } static get styles(): CSSResultGroup { - return css` - :host { - display: block; - height: 100%; - background-color: var(--primary-background-color); - overflow: hidden; - position: relative; - } - - :host([narrow]) { - width: 100%; - position: fixed; - } - - .toolbar { - display: flex; - align-items: center; - font-size: 20px; - height: var(--header-height); - padding: 8px 12px; - pointer-events: none; - background-color: var(--app-header-background-color); - font-weight: 400; - color: var(--app-header-text-color, white); - border-bottom: var(--app-header-border-bottom, none); - box-sizing: border-box; - } - @media (max-width: 599px) { - .toolbar { - padding: 4px; + return [ + haStyleScrollbar, + css` + :host { + display: block; + height: 100%; + background-color: var(--primary-background-color); + overflow: hidden; + position: relative; } - } - .toolbar a { - color: var(--sidebar-text-color); - text-decoration: none; - } - ha-menu-button, - ha-icon-button-arrow-prev, - ::slotted([slot="toolbar-icon"]) { - pointer-events: auto; - color: var(--sidebar-icon-color); - } + :host([narrow]) { + width: 100%; + position: fixed; + } - .main-title { - margin: 0 0 0 24px; - line-height: 20px; - flex-grow: 1; - } + .toolbar { + display: flex; + align-items: center; + font-size: 20px; + height: var(--header-height); + padding: 8px 12px; + pointer-events: none; + background-color: var(--app-header-background-color); + font-weight: 400; + color: var(--app-header-text-color, white); + border-bottom: var(--app-header-border-bottom, none); + box-sizing: border-box; + } + @media (max-width: 599px) { + .toolbar { + padding: 4px; + } + } + .toolbar a { + color: var(--sidebar-text-color); + text-decoration: none; + } - .content { - position: relative; - width: 100%; - height: calc(100% - 1px - var(--header-height)); - overflow-y: auto; - overflow: auto; - -webkit-overflow-scrolling: touch; - } + ha-menu-button, + ha-icon-button-arrow-prev, + ::slotted([slot="toolbar-icon"]) { + pointer-events: auto; + color: var(--sidebar-icon-color); + } - #fab { - position: absolute; - right: calc(16px + env(safe-area-inset-right)); - bottom: calc(16px + env(safe-area-inset-bottom)); - z-index: 1; - } - :host([narrow]) #fab.tabs { - bottom: calc(84px + env(safe-area-inset-bottom)); - } - #fab[is-wide] { - bottom: 24px; - right: 24px; - } - :host([rtl]) #fab { - right: auto; - left: calc(16px + env(safe-area-inset-left)); - } - :host([rtl][is-wide]) #fab { - bottom: 24px; - left: 24px; - right: auto; - } - `; + .main-title { + margin: 0 0 0 24px; + line-height: 20px; + flex-grow: 1; + } + + .content { + position: relative; + width: 100%; + height: calc(100% - 1px - var(--header-height)); + overflow-y: auto; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + #fab { + position: absolute; + right: calc(16px + env(safe-area-inset-right)); + bottom: calc(16px + env(safe-area-inset-bottom)); + z-index: 1; + } + :host([narrow]) #fab.tabs { + bottom: calc(84px + env(safe-area-inset-bottom)); + } + #fab[is-wide] { + bottom: 24px; + right: 24px; + } + :host([rtl]) #fab { + right: auto; + left: calc(16px + env(safe-area-inset-left)); + } + :host([rtl][is-wide]) #fab { + bottom: 24px; + left: 24px; + right: auto; + } + `, + ]; } } From 9b35c06eefc6e9942aa9757fe9b550b9552a987c Mon Sep 17 00:00:00 2001 From: RoboMagus <68224306+RoboMagus@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:55:55 +0200 Subject: [PATCH 082/162] Add persistent_notification trigger (#16967) Co-authored-by: J. Nick Koston --- .../src/pages/automation/describe-trigger.ts | 1 + .../src/pages/automation/editor-trigger.ts | 11 ++ src/data/automation.ts | 7 ++ src/data/automation_i18n.ts | 6 + src/data/trigger.ts | 2 + .../trigger/ha-automation-trigger-row.ts | 1 + .../trigger/ha-automation-trigger.ts | 1 + ...omation-trigger-persistent_notification.ts | 117 ++++++++++++++++++ src/translations/en.json | 11 ++ 9 files changed, 157 insertions(+) create mode 100644 src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts diff --git a/gallery/src/pages/automation/describe-trigger.ts b/gallery/src/pages/automation/describe-trigger.ts index 6ed8163912..3ebb26f017 100644 --- a/gallery/src/pages/automation/describe-trigger.ts +++ b/gallery/src/pages/automation/describe-trigger.ts @@ -41,6 +41,7 @@ const triggers = [ { platform: "sun", event: "sunset" }, { platform: "time_pattern" }, { platform: "webhook" }, + { platform: "persistent_notification" }, { platform: "zone", entity_id: "person.person", diff --git a/gallery/src/pages/automation/editor-trigger.ts b/gallery/src/pages/automation/editor-trigger.ts index bff2947bb3..5dccee4fa0 100644 --- a/gallery/src/pages/automation/editor-trigger.ts +++ b/gallery/src/pages/automation/editor-trigger.ts @@ -19,6 +19,7 @@ import { HaTemplateTrigger } from "../../../../src/panels/config/automation/trig 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"; @@ -72,6 +73,16 @@ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ triggers: [{ platform: "webhook", ...HaWebhookTrigger.defaultConfig }], }, + { + name: "Persistent Notification", + triggers: [ + { + platform: "persistent_notification", + ...HaPersistentNotificationTrigger.defaultConfig, + }, + ], + }, + { name: "Zone", triggers: [{ platform: "zone", ...HaZoneTrigger.defaultConfig }], diff --git a/src/data/automation.ts b/src/data/automation.ts index aeeaa356d2..6ff6eca45f 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -127,6 +127,12 @@ export interface WebhookTrigger extends BaseTrigger { local_only?: boolean; } +export interface PersistentNotificationTrigger extends BaseTrigger { + platform: "persistent_notification"; + notification_id?: string; + update_type?: string[]; +} + export interface ZoneTrigger extends BaseTrigger { platform: "zone"; entity_id: string; @@ -174,6 +180,7 @@ export type Trigger = | SunTrigger | TimePatternTrigger | WebhookTrigger + | PersistentNotificationTrigger | ZoneTrigger | TagTrigger | TimeTrigger diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index b7ea6dcaab..854d8501f7 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -590,6 +590,12 @@ export const describeTrigger = ( ); } + // Persistent Notification Trigger + if (trigger.platform === "persistent_notification") { + return "When a persistent notification is updated"; + } + + // Device Trigger if (trigger.platform === "device") { if (!trigger.device_id) { return "Device trigger"; diff --git a/src/data/trigger.ts b/src/data/trigger.ts index 847c4ee50b..3d6cf2558b 100644 --- a/src/data/trigger.ts +++ b/src/data/trigger.ts @@ -8,6 +8,7 @@ import { mdiHomeAssistant, mdiMapMarker, mdiMapMarkerRadius, + mdiMessageAlert, mdiNfcVariant, mdiNumeric, mdiStateMachine, @@ -31,5 +32,6 @@ export const TRIGGER_TYPES = { time: mdiClockOutline, time_pattern: mdiAvTimer, webhook: mdiWebhook, + persistent_notification: mdiMessageAlert, zone: mdiMapMarkerRadius, }; diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index 52b51686bc..fc8ce54e79 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -50,6 +50,7 @@ import "./types/ha-automation-trigger-geo_location"; import "./types/ha-automation-trigger-homeassistant"; import "./types/ha-automation-trigger-mqtt"; import "./types/ha-automation-trigger-numeric_state"; +import "./types/ha-automation-trigger-persistent_notification"; import "./types/ha-automation-trigger-state"; import "./types/ha-automation-trigger-sun"; import "./types/ha-automation-trigger-tag"; diff --git a/src/panels/config/automation/trigger/ha-automation-trigger.ts b/src/panels/config/automation/trigger/ha-automation-trigger.ts index 66d59f3552..d30e42ba98 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger.ts @@ -42,6 +42,7 @@ import "./types/ha-automation-trigger-geo_location"; import "./types/ha-automation-trigger-homeassistant"; import "./types/ha-automation-trigger-mqtt"; import "./types/ha-automation-trigger-numeric_state"; +import "./types/ha-automation-trigger-persistent_notification"; import "./types/ha-automation-trigger-state"; import "./types/ha-automation-trigger-sun"; import "./types/ha-automation-trigger-tag"; diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts new file mode 100644 index 0000000000..0e942c1860 --- /dev/null +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-persistent_notification.ts @@ -0,0 +1,117 @@ +import memoizeOne from "memoize-one"; + +import { css, html, LitElement } from "lit"; +import { customElement, property } from "lit/decorators"; +import { fireEvent } from "../../../../../common/dom/fire_event"; +import "../../../../../components/ha-button-menu"; +import "../../../../../components/ha-check-list-item"; +import "../../../../../components/ha-icon-button"; +import "../../../../../components/ha-textfield"; +import { PersistentNotificationTrigger } from "../../../../../data/automation"; +import { HomeAssistant } from "../../../../../types"; +import type { TriggerElement } from "../ha-automation-trigger-row"; +import type { LocalizeFunc } from "../../../../../common/translations/localize"; +import type { SchemaUnion } from "../../../../../components/ha-form/types"; + +const DEFAULT_UPDATE_TYPES = ["added", "removed"]; +const DEFAULT_NOTIFICATION_ID = ""; + +@customElement("ha-automation-trigger-persistent_notification") +export class HaPersistentNotificationTrigger + extends LitElement + implements TriggerElement +{ + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public trigger!: PersistentNotificationTrigger; + + @property({ type: Boolean }) public disabled = false; + + private _schema = memoizeOne( + (localize: LocalizeFunc) => + [ + { + name: "notification_id", + required: false, + selector: { text: {} }, + }, + { + name: "update_type", + type: "multi_select", + required: false, + options: [ + [ + "added", + localize( + "ui.panel.config.automation.editor.triggers.type.persistent_notification.update_types.added" + ), + ], + [ + "removed", + localize( + "ui.panel.config.automation.editor.triggers.type.persistent_notification.update_types.removed" + ), + ], + [ + "current", + localize( + "ui.panel.config.automation.editor.triggers.type.persistent_notification.update_types.current" + ), + ], + [ + "updated", + localize( + "ui.panel.config.automation.editor.triggers.type.persistent_notification.update_types.updated" + ), + ], + ], + }, + ] as const + ); + + public static get defaultConfig() { + return { + update_type: [...DEFAULT_UPDATE_TYPES], + notification_id: DEFAULT_NOTIFICATION_ID, + }; + } + + protected render() { + const schema = this._schema(this.hass.localize); + return html` + + `; + } + + private _valueChanged(ev: CustomEvent): void { + ev.stopPropagation(); + const newTrigger = ev.detail.value; + fireEvent(this, "value-changed", { value: newTrigger }); + } + + private _computeLabelCallback = ( + schema: SchemaUnion> + ): string => + this.hass.localize( + `ui.panel.config.automation.editor.triggers.type.persistent_notification.${schema.name}` + ); + + static styles = css` + ha-textfield { + display: block; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-automation-trigger-persistent_notification": HaPersistentNotificationTrigger; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index 16ca1df024..8e46f03ee8 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2341,6 +2341,17 @@ "type_value": "Fixed number", "type_input": "Numeric value of another entity" }, + "persistent_notification": { + "label": "Persistent notification", + "notification_id": "Notification Id", + "update_type": "Update type", + "update_types": { + "added": "added", + "removed": "removed", + "current": "current", + "updated": "updated" + } + }, "sun": { "label": "Sun", "event": "[%key:ui::panel::config::automation::editor::triggers::type::homeassistant::event%]", From 3d6cfc403747f65a074cdc468f1ccf0fead28d52 Mon Sep 17 00:00:00 2001 From: Vasilis Koulis Date: Wed, 21 Jun 2023 12:59:28 +0300 Subject: [PATCH 083/162] open option for lock (#14852) Co-authored-by: Bram Kragten --- src/state-summary/state-card-lock.js | 13 +++++++++++++ src/translations/en.json | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/state-summary/state-card-lock.js b/src/state-summary/state-card-lock.js index d0280b7a1d..94ee6e27aa 100644 --- a/src/state-summary/state-card-lock.js +++ b/src/state-summary/state-card-lock.js @@ -3,8 +3,10 @@ import "@polymer/iron-flex-layout/iron-flex-layout-classes"; import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ import { PolymerElement } from "@polymer/polymer/polymer-element"; +import { supportsFeature } from "../common/entity/supports-feature"; import "../components/entity/state-info"; import LocalizeMixin from "../mixins/localize-mixin"; +import { LockEntityFeature } from "../data/lock"; /* * @appliesMixin LocalizeMixin @@ -19,10 +21,19 @@ class StateCardLock extends LocalizeMixin(PolymerElement) { height: 37px; margin-right: -0.57em; } + [hidden] { + display: none !important; + }
${this.stateInfoTemplate} + [[localize('ui.card.lock.open')]] Date: Wed, 21 Jun 2023 13:46:08 +0200 Subject: [PATCH 084/162] TTS and STT: standardize spelling (#16685) --- .../voice-assistants/debug/assist-render-pipeline-run.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts index 739a829d75..f30d5cf5d7 100644 --- a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts +++ b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts @@ -200,7 +200,7 @@ export class AssistPipelineDebug extends LitElement {
- Speech-to-Text + Speech-to-text ${renderProgress(this.hass, this.pipelineRun, "stt")}
${this.pipelineRun.stt @@ -274,7 +274,7 @@ export class AssistPipelineDebug extends LitElement {
- Text-to-Speech + Text-to-speech ${renderProgress(this.hass, this.pipelineRun, "tts")}
${this.pipelineRun.tts From e9961b93f98a54840e0d47bfbc20a6a3c86c0406 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 21 Jun 2023 17:01:45 +0200 Subject: [PATCH 085/162] Add circular slider (#16981) * WIP Create round slider * Fix interaction on iOS * Add dual and simple gauge * Add events * Rename events * Use low and high * Improve dual slider selection * Add min and max * Rename component * Prevents setting a high value lower than low and vice versa * Add keyboard support * Fix typings * Use html * Update current indicator * Improve doc * Fix keyboard focus after mouse interaction * Don't fallback to value --- .../ha-control-circular-slider.markdown | 3 + .../components/ha-control-circular-slider.ts | 153 +++++ src/components/ha-control-circular-slider.ts | 546 ++++++++++++++++++ src/components/ha-control-slider.ts | 2 +- src/resources/svg-arc.ts | 67 +++ 5 files changed, 770 insertions(+), 1 deletion(-) create mode 100644 gallery/src/pages/components/ha-control-circular-slider.markdown create mode 100644 gallery/src/pages/components/ha-control-circular-slider.ts create mode 100644 src/components/ha-control-circular-slider.ts create mode 100644 src/resources/svg-arc.ts diff --git a/gallery/src/pages/components/ha-control-circular-slider.markdown b/gallery/src/pages/components/ha-control-circular-slider.markdown new file mode 100644 index 0000000000..7a5a234cf2 --- /dev/null +++ b/gallery/src/pages/components/ha-control-circular-slider.markdown @@ -0,0 +1,3 @@ +--- +title: Control Circular Slider +--- diff --git a/gallery/src/pages/components/ha-control-circular-slider.ts b/gallery/src/pages/components/ha-control-circular-slider.ts new file mode 100644 index 0000000000..791fff7829 --- /dev/null +++ b/gallery/src/pages/components/ha-control-circular-slider.ts @@ -0,0 +1,153 @@ +import { css, html, LitElement, TemplateResult } from "lit"; +import { customElement, state } from "lit/decorators"; +import "../../../../src/components/ha-card"; +import "../../../../src/components/ha-control-circular-slider"; +import "../../../../src/components/ha-slider"; + +@customElement("demo-components-ha-control-circular-slider") +export class DemoHaCircularSlider extends LitElement { + @state() + private current = 22; + + @state() + private value = 19; + + @state() + private high = 25; + + @state() + private changingValue?: number; + + @state() + private changingHigh?: number; + + private _valueChanged(ev) { + this.value = ev.detail.value; + } + + private _valueChanging(ev) { + this.changingValue = ev.detail.value; + } + + private _highChanged(ev) { + this.high = ev.detail.value; + } + + private _highChanging(ev) { + this.changingHigh = ev.detail.value; + } + + private _currentChanged(ev) { + this.current = ev.currentTarget.value; + } + + protected render(): TemplateResult { + return html` + +
+

Config

+
+

Current

+ +

${this.current} °C

+
+
+
+ +
+

Single

+ +
+ Value: ${this.value} °C +
+ Changing: + ${this.changingValue != null ? `${this.changingValue} °C` : "-"} +
+
+
+ +
+

Dual

+ +
+ Low value: ${this.value} °C +
+ Low changing: + ${this.changingValue != null ? `${this.changingValue} °C` : "-"} +
+ High value: ${this.high} °C +
+ High changing: + ${this.changingHigh != null ? `${this.changingHigh} °C` : "-"} +
+
+
+ `; + } + + static get styles() { + return css` + ha-card { + max-width: 600px; + margin: 24px auto; + } + pre { + margin-top: 0; + margin-bottom: 8px; + } + p { + margin: 0; + } + p.title { + margin-bottom: 12px; + } + ha-control-circular-slider { + --control-circular-slider-color: #ff9800; + --control-circular-slider-background: #ff9800; + --control-circular-slider-background-opacity: 0.3; + } + ha-control-circular-slider[dual] { + --control-circular-slider-high-color: #2196f3; + --control-circular-slider-low-color: #ff9800; + --control-circular-slider-background: var(--disabled-color); + } + .field { + display: flex; + flex-direction: row; + align-items: center; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "demo-components-ha-control-circular-slider": DemoHaCircularSlider; + } +} diff --git a/src/components/ha-control-circular-slider.ts b/src/components/ha-control-circular-slider.ts new file mode 100644 index 0000000000..7b7472ddbc --- /dev/null +++ b/src/components/ha-control-circular-slider.ts @@ -0,0 +1,546 @@ +import { + DIRECTION_ALL, + Manager, + Pan, + Tap, + TouchMouseInput, +} from "@egjs/hammerjs"; +import { + CSSResultGroup, + LitElement, + PropertyValues, + TemplateResult, + css, + html, + nothing, + svg, +} from "lit"; +import { customElement, property, query, state } from "lit/decorators"; +import { classMap } from "lit/directives/class-map"; +import { ifDefined } from "lit/directives/if-defined"; +import { styleMap } from "lit/directives/style-map"; +import { fireEvent } from "../common/dom/fire_event"; +import { clamp } from "../common/number/clamp"; +import { arc } from "../resources/svg-arc"; + +const MAX_ANGLE = 270; +const ROTATE_ANGLE = 360 - MAX_ANGLE / 2 - 90; +const RADIUS = 145; + +function xy2polar(x: number, y: number) { + const r = Math.sqrt(x * x + y * y); + const phi = Math.atan2(y, x); + return [r, phi]; +} + +function rad2deg(rad: number) { + return (rad / (2 * Math.PI)) * 360; +} + +type ActiveSlider = "low" | "high" | "value"; + +declare global { + interface HASSDomEvents { + "value-changing": { value: unknown }; + "low-changing": { value: unknown }; + "low-changed": { value: unknown }; + "high-changing": { value: unknown }; + "high-changed": { value: unknown }; + } +} + +const A11Y_KEY_CODES = new Set([ + "ArrowRight", + "ArrowUp", + "ArrowLeft", + "ArrowDown", + "PageUp", + "PageDown", + "Home", + "End", +]); + +@customElement("ha-control-circular-slider") +export class HaControlCircularSlider extends LitElement { + @property({ type: Boolean, reflect: true }) + public disabled = false; + + @property({ type: Boolean }) + public dual?: boolean; + + @property({ type: String }) + public label?: string; + + @property({ type: String, attribute: "low-label" }) + public lowLabel?: string; + + @property({ type: String, attribute: "high-label" }) + public highLabel?: string; + + @property({ type: Number }) + public value?: number; + + @property({ type: Number }) + public current?: number; + + @property({ type: Number }) + public low?: number; + + @property({ type: Number }) + public high?: number; + + @property({ type: Number }) + public step = 1; + + @property({ type: Number }) + public min = 0; + + @property({ type: Number }) + public max = 100; + + @state() + public _activeSlider?: ActiveSlider; + + @state() + public _lastSlider?: ActiveSlider; + + private _valueToPercentage(value: number) { + return ( + (clamp(value, this.min, this.max) - this.min) / (this.max - this.min) + ); + } + + private _percentageToValue(value: number) { + return (this.max - this.min) * value + this.min; + } + + private _steppedValue(value: number) { + return Math.round(value / this.step) * this.step; + } + + private _boundedValue(value: number) { + const min = + this._activeSlider === "high" ? Math.min(this.low ?? this.max) : this.min; + const max = + this._activeSlider === "low" ? Math.max(this.high ?? this.min) : this.max; + return Math.min(Math.max(value, min), max); + } + + protected firstUpdated(changedProperties: PropertyValues): void { + super.firstUpdated(changedProperties); + this._setupListeners(); + } + + connectedCallback(): void { + super.connectedCallback(); + this._setupListeners(); + } + + disconnectedCallback(): void { + super.disconnectedCallback(); + } + + private _mc?: HammerManager; + + private _getPercentageFromEvent = (e: HammerInput) => { + const bound = this._slider.getBoundingClientRect(); + const x = (2 * (e.center.x - bound.left - bound.width / 2)) / bound.width; + const y = (2 * (e.center.y - bound.top - bound.height / 2)) / bound.height; + + const [, phi] = xy2polar(x, y); + + const offset = (360 - MAX_ANGLE) / 2; + + const angle = ((rad2deg(phi) + offset - ROTATE_ANGLE + 360) % 360) - offset; + + return Math.max(Math.min(angle / MAX_ANGLE, 1), 0); + }; + + @query("#slider") + private _slider; + + @query("#interaction") + private _interaction; + + private _findActiveSlider(value: number): ActiveSlider { + if (!this.dual) return "value"; + const low = Math.max(this.low ?? this.min, this.min); + const high = Math.min(this.high ?? this.max, this.max); + if (low >= value) { + return "low"; + } + if (high <= value) { + return "high"; + } + const lowDistance = Math.abs(value - low); + const highDistance = Math.abs(value - high); + return lowDistance <= highDistance ? "low" : "high"; + } + + private _setActiveValue(value: number) { + if (!this._activeSlider) return; + this[this._activeSlider] = value; + } + + private _getActiveValue(): number | undefined { + if (!this._activeSlider) return undefined; + return this[this._activeSlider]; + } + + _setupListeners() { + if (this._interaction && !this._mc) { + this._mc = new Manager(this._interaction, { + inputClass: TouchMouseInput, + }); + this._mc.add( + new Pan({ + direction: DIRECTION_ALL, + enable: true, + threshold: 0, + }) + ); + + this._mc.add(new Tap({ event: "singletap" })); + + this._mc.on("pan", (e) => { + e.srcEvent.stopPropagation(); + e.srcEvent.preventDefault(); + }); + this._mc.on("panstart", (e) => { + if (this.disabled) return; + const percentage = this._getPercentageFromEvent(e); + const raw = this._percentageToValue(percentage); + this._activeSlider = this._findActiveSlider(raw); + this._lastSlider = this._activeSlider; + this.shadowRoot?.getElementById("#slider")?.focus(); + }); + this._mc.on("pancancel", () => { + if (this.disabled) return; + this._activeSlider = undefined; + }); + this._mc.on("panmove", (e) => { + if (this.disabled) return; + const percentage = this._getPercentageFromEvent(e); + const raw = this._percentageToValue(percentage); + const bounded = this._boundedValue(raw); + this._setActiveValue(bounded); + const stepped = this._steppedValue(bounded); + if (this._activeSlider) { + fireEvent(this, `${this._activeSlider}-changing`, { value: stepped }); + } + }); + this._mc.on("panend", (e) => { + if (this.disabled) return; + const percentage = this._getPercentageFromEvent(e); + const raw = this._percentageToValue(percentage); + const bounded = this._boundedValue(raw); + const stepped = this._steppedValue(bounded); + if (this._activeSlider) { + fireEvent(this, `${this._activeSlider}-changing`, { + value: undefined, + }); + fireEvent(this, `${this._activeSlider}-changed`, { value: stepped }); + } + this._activeSlider = undefined; + }); + this._mc.on("singletap", (e) => { + if (this.disabled) return; + const percentage = this._getPercentageFromEvent(e); + const raw = this._percentageToValue(percentage); + this._activeSlider = this._findActiveSlider(raw); + const bounded = this._boundedValue(raw); + const stepped = this._steppedValue(bounded); + this._setActiveValue(stepped); + if (this._activeSlider) { + fireEvent(this, `${this._activeSlider}-changing`, { + value: undefined, + }); + fireEvent(this, `${this._activeSlider}-changed`, { value: stepped }); + } + this._lastSlider = this._activeSlider; + this.shadowRoot?.getElementById("#slider")?.focus(); + this._activeSlider = undefined; + }); + } + } + + private get _tenPercentStep() { + return Math.max(this.step, (this.max - this.min) / 10); + } + + private _handleKeyDown(e: KeyboardEvent) { + if (!A11Y_KEY_CODES.has(e.code)) return; + e.preventDefault(); + if (this._lastSlider) { + this.shadowRoot?.getElementById(this._lastSlider)?.focus(); + } + this._activeSlider = + this._lastSlider ?? ((e.currentTarget as any).id as ActiveSlider); + this._lastSlider = undefined; + + const value = this._getActiveValue(); + + switch (e.code) { + case "ArrowRight": + case "ArrowUp": + this._setActiveValue( + this._boundedValue((value ?? this.min) + this.step) + ); + break; + case "ArrowLeft": + case "ArrowDown": + this._setActiveValue( + this._boundedValue((value ?? this.min) - this.step) + ); + break; + case "PageUp": + this._setActiveValue( + this._steppedValue( + this._boundedValue((value ?? this.min) + this._tenPercentStep) + ) + ); + break; + case "PageDown": + this._setActiveValue( + this._steppedValue( + this._boundedValue((value ?? this.min) - this._tenPercentStep) + ) + ); + break; + case "Home": + this._setActiveValue(this._boundedValue(this.min)); + break; + case "End": + this._setActiveValue(this._boundedValue(this.max)); + break; + } + fireEvent(this, `${this._activeSlider}-changing`, { + value: this._getActiveValue(), + }); + this._activeSlider = undefined; + } + + _handleKeyUp(e: KeyboardEvent) { + if (!A11Y_KEY_CODES.has(e.code)) return; + this._activeSlider = (e.currentTarget as any).id as ActiveSlider; + e.preventDefault(); + fireEvent(this, `${this._activeSlider}-changing`, { + value: undefined, + }); + fireEvent(this, `${this._activeSlider}-changed`, { + value: this._getActiveValue(), + }); + this._activeSlider = undefined; + } + + destroyListeners() { + if (this._mc) { + this._mc.destroy(); + this._mc = undefined; + } + } + + protected render(): TemplateResult { + const trackPath = arc({ x: 0, y: 0, start: 0, end: MAX_ANGLE, r: RADIUS }); + + const maxRatio = MAX_ANGLE / 360; + + const f = RADIUS * 2 * Math.PI; + const lowValue = this.dual ? this.low : this.value; + const highValue = this.high; + const lowPercentage = this._valueToPercentage(lowValue ?? this.min); + const highPercentage = this._valueToPercentage(highValue ?? this.max); + + const lowArcLength = lowPercentage * f * maxRatio; + const lowStrokeDasharray = `${lowArcLength} ${f - lowArcLength}`; + + const highArcLength = (1 - highPercentage) * f * maxRatio; + const highStrokeDasharray = `${highArcLength} ${f - highArcLength}`; + const highStrokeDashOffset = `${highArcLength + f * (1 - maxRatio)}`; + + const currentPercentage = this._valueToPercentage(this.current ?? 0); + const currentAngle = currentPercentage * MAX_ANGLE; + + return html` + + + + + + + + + ${this.dual + ? svg` + + ` + : nothing} + ${this.current != null + ? svg` + + + + + ` + : nothing} + + + + `; + } + + static get styles(): CSSResultGroup { + return css` + :host { + --control-circular-slider-color: var(--primary-color); + --control-circular-slider-background: #8b97a3; + --control-circular-slider-background-opacity: 0.3; + --control-circular-slider-low-color: var( + --control-circular-slider-color + ); + --control-circular-slider-high-color: var( + --control-circular-slider-color + ); + } + svg { + width: 320px; + display: block; + } + #slider { + outline: none; + } + #interaction { + display: flex; + fill: none; + stroke: transparent; + stroke-linecap: round; + stroke-width: 48px; + cursor: pointer; + } + #display { + pointer-events: none; + } + :host([disabled]) #interaction { + cursor: initial; + } + + .background { + fill: none; + stroke: var(--control-circular-slider-background); + opacity: var(--control-circular-slider-background-opacity); + stroke-linecap: round; + stroke-width: 24px; + } + + .track { + outline: none; + fill: none; + stroke-linecap: round; + stroke-width: 24px; + transition: stroke-width 300ms ease-in-out, + stroke-dasharray 300ms ease-in-out, + stroke-dashoffset 300ms ease-in-out; + } + + .track:focus-visible { + stroke-width: 28px; + } + + .pressed .track { + transition: stroke-width 300ms ease-in-out; + } + + .current { + stroke: var(--primary-text-color); + transform: rotate(var(--current-angle, 0)); + transition: transform 300ms ease-in-out; + } + + #value { + stroke: var(--control-circular-slider-color); + } + + #low { + stroke: var(--control-circular-slider-low-color); + } + + #high { + stroke: var(--control-circular-slider-high-color); + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-control-circular-slider": HaControlCircularSlider; + } +} diff --git a/src/components/ha-control-slider.ts b/src/components/ha-control-slider.ts index 2cc172969a..3f4abcf4e3 100644 --- a/src/components/ha-control-slider.ts +++ b/src/components/ha-control-slider.ts @@ -176,7 +176,7 @@ export class HaControlSlider extends LitElement { this._mc = undefined; } this.removeEventListener("keydown", this._handleKeyDown); - this.removeEventListener("keyup", this._handleKeyDown); + this.removeEventListener("keyup", this._handleKeyUp); } private get _tenPercentStep() { diff --git a/src/resources/svg-arc.ts b/src/resources/svg-arc.ts new file mode 100644 index 0000000000..67e29b5157 --- /dev/null +++ b/src/resources/svg-arc.ts @@ -0,0 +1,67 @@ +type Vector = [number, number]; +type Matrix = [Vector, Vector]; + +const rotateVector = ([[a, b], [c, d]]: Matrix, [x, y]: Vector): Vector => [ + a * x + b * y, + c * x + d * y, +]; +const createRotateMatrix = (x: number): Matrix => [ + [Math.cos(x), -Math.sin(x)], + [Math.sin(x), Math.cos(x)], +]; +const addVector = ([a1, a2]: Vector, [b1, b2]: Vector): Vector => [ + a1 + b1, + a2 + b2, +]; + +export const toRadian = (angle: number) => (angle / 180) * Math.PI; + +type ArcOptions = { + x: number; + y: number; + r: number; + start: number; + end: number; + rotate?: number; +}; + +export const arc = (options: ArcOptions) => { + const { x, y, r, start, end, rotate = 0 } = options; + const cx = x; + const cy = y; + const rx = r; + const ry = r; + const t1 = toRadian(start); + const t2 = toRadian(end); + const delta = (t2 - t1) % (2 * Math.PI); + const phi = toRadian(rotate); + + const rotMatrix = createRotateMatrix(phi); + const [sX, sY] = addVector( + rotateVector(rotMatrix, [rx * Math.cos(t1), ry * Math.sin(t1)]), + [cx, cy] + ); + const [eX, eY] = addVector( + rotateVector(rotMatrix, [ + rx * Math.cos(t1 + delta), + ry * Math.sin(t1 + delta), + ]), + [cx, cy] + ); + const fA = delta > Math.PI ? 1 : 0; + const fS = delta > 0 ? 1 : 0; + + return [ + "M", + sX, + sY, + "A", + rx, + ry, + (phi / (2 * Math.PI)) * 360, + fA, + fS, + eX, + eY, + ].join(" "); +}; From 752bc192cd11b96b74cc008237fda171b0eab0ee Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 21 Jun 2023 08:10:00 -0700 Subject: [PATCH 086/162] Fix types selection for statistics-graph-card (#16988) --- src/data/recorder.ts | 4 ++-- .../hui-statistics-graph-card-editor.ts | 16 ++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/data/recorder.ts b/src/data/recorder.ts index 23752d16f2..32b471f4a7 100644 --- a/src/data/recorder.ts +++ b/src/data/recorder.ts @@ -260,10 +260,10 @@ export const calculateStatisticsSumGrowth = ( export const statisticsHaveType = ( stats: StatisticValue[], type: StatisticType -) => stats.some((stat) => stat[type] !== null); +) => stats.some((stat) => stat[type] !== undefined && stat[type] !== null); const mean_stat_types: readonly StatisticType[] = ["mean", "min", "max"]; -const sum_stat_types: readonly StatisticType[] = ["sum"]; +const sum_stat_types: readonly StatisticType[] = ["sum", "state", "change"]; export const statisticsMetaHasType = ( metadata: StatisticsMetaData, diff --git a/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts index e16a629b8f..8cb52183c5 100644 --- a/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-statistics-graph-card-editor.ts @@ -187,7 +187,7 @@ export class HuiStatisticsGraphCardEditor ), disabled: !metaDatas || - !metaDatas.every((metaData) => + !metaDatas.some((metaData) => statisticsMetaHasType( metaData, supportedStatTypeMap[stat_type] @@ -246,12 +246,10 @@ export class HuiStatisticsGraphCardEditor ); const configured_stat_types = this._config!.stat_types ? ensureArray(this._config.stat_types) - : stat_types.filter( - (stat_type) => - stat_type !== "change" && - this._metaDatas?.every((metaData) => - statisticsMetaHasType(metaData, stat_type) - ) + : stat_types.filter((stat_type) => + this._metaDatas?.some((metaData) => + statisticsMetaHasType(metaData, stat_type) + ) ); const data = { chart_type: "line", @@ -320,9 +318,7 @@ export class HuiStatisticsGraphCardEditor : undefined; if (config.stat_types && config.entities.length) { config.stat_types = ensureArray(config.stat_types).filter((stat_type) => - metadata!.every((metaData) => - statisticsMetaHasType(metaData, stat_type) - ) + metadata!.some((metaData) => statisticsMetaHasType(metaData, stat_type)) ); if (!config.stat_types.length) { delete config.stat_types; From 7faa165558db9bc62b212ef731715c69f294d1ba Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 21 Jun 2023 17:22:10 +0200 Subject: [PATCH 087/162] Refactor Storage decorator (#16987) --- .../{local-storage.ts => storage.ts} | 87 ++++++++++++------- src/components/ha-sidebar.ts | 26 +++--- .../media-player/ha-browse-media-tts.ts | 9 +- src/dialogs/tts-try/dialog-tts-try.ts | 12 +-- .../ha-voice-command-dialog.ts | 9 +- src/panels/calendar/ha-panel-calendar.ts | 7 +- .../automation/manual-automation-editor.ts | 9 +- .../cloud/account/dialog-cloud-tts-try.ts | 16 +++- .../mqtt/mqtt-config-panel.ts | 32 +++++-- .../mqtt/mqtt-subscribe-card.ts | 20 ++++- .../config/script/manual-script-editor.ts | 9 +- .../service/developer-tools-service.ts | 14 ++- src/panels/history/ha-panel-history.ts | 8 +- .../media-browser/ha-panel-media-browser.ts | 8 +- 14 files changed, 187 insertions(+), 79 deletions(-) rename src/common/decorators/{local-storage.ts => storage.ts} (64%) diff --git a/src/common/decorators/local-storage.ts b/src/common/decorators/storage.ts similarity index 64% rename from src/common/decorators/local-storage.ts rename to src/common/decorators/storage.ts index 752b95933e..a35f0b414a 100644 --- a/src/common/decorators/local-storage.ts +++ b/src/common/decorators/storage.ts @@ -1,13 +1,15 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket"; -import { PropertyDeclaration, ReactiveElement } from "lit"; +import { ReactiveElement } from "lit"; +import { InternalPropertyDeclaration } from "lit/decorators"; import type { ClassElement } from "../../types"; type Callback = (oldValue: any, newValue: any) => void; -class Storage { - constructor(subscribe = true, storage = window.localStorage) { +class StorageClass { + constructor(storage = window.localStorage) { this.storage = storage; - if (!subscribe) { + if (storage !== window.localStorage) { + // storage events only work for localStorage return; } window.addEventListener("storage", (ev: StorageEvent) => { @@ -77,6 +79,7 @@ class Storage { } public setValue(storageKey: string, value: any): any { + const oldValue = this._storage[storageKey]; this._storage[storageKey] = value; try { if (value === undefined) { @@ -86,49 +89,68 @@ class Storage { } } catch (err: any) { // Safari in private mode doesn't allow localstorage + } finally { + if (this._listeners[storageKey]) { + this._listeners[storageKey].forEach((listener) => + listener(oldValue, value) + ); + } } } } -const subscribeStorage = new Storage(); +const storages: Record = {}; -export const LocalStorage = - ( - storageKey?: string, - property?: boolean, - subscribe = true, - storageType?: globalThis.Storage, - propertyOptions?: PropertyDeclaration - ): any => +export const storage = + (options: { + key?: string; + storage?: "localStorage" | "sessionStorage"; + subscribe?: boolean; + state?: boolean; + stateOptions?: InternalPropertyDeclaration; + }): any => (clsElement: ClassElement) => { - const storage = - subscribe && !storageType - ? subscribeStorage - : new Storage(subscribe, storageType); + const storageName = options.storage || "localStorage"; + + let storageInstance: StorageClass; + if (storageName && storageName in storages) { + storageInstance = storages[storageName]; + } else { + storageInstance = new StorageClass(window[storageName]); + storages[storageName] = storageInstance; + } const key = String(clsElement.key); - storageKey = storageKey || String(clsElement.key); + const storageKey = options.key || String(clsElement.key); const initVal = clsElement.initializer ? clsElement.initializer() : undefined; - storage.addFromStorage(storageKey); + storageInstance.addFromStorage(storageKey); - const subscribeChanges = (el: ReactiveElement): UnsubscribeFunc => - storage.subscribeChanges(storageKey!, (oldValue) => { - el.requestUpdate(clsElement.key, oldValue); - }); + const subscribeChanges = + options.subscribe !== false + ? (el: ReactiveElement): UnsubscribeFunc => + storageInstance.subscribeChanges( + storageKey!, + (oldValue, _newValue) => { + el.requestUpdate(clsElement.key, oldValue); + } + ) + : undefined; const getValue = (): any => - storage.hasKey(storageKey!) ? storage.getValue(storageKey!) : initVal; + storageInstance.hasKey(storageKey!) + ? storageInstance.getValue(storageKey!) + : initVal; const setValue = (el: ReactiveElement, value: any) => { let oldValue: unknown | undefined; - if (property) { + if (options.state) { oldValue = getValue(); } - storage.setValue(storageKey!, value); - if (property) { + storageInstance.setValue(storageKey!, value); + if (options.state) { el.requestUpdate(clsElement.key, oldValue); } }; @@ -148,22 +170,23 @@ export const LocalStorage = configurable: true, }, finisher(cls: typeof ReactiveElement) { - if (property && subscribe) { + if (options.state && options.subscribe) { const connectedCallback = cls.prototype.connectedCallback; const disconnectedCallback = cls.prototype.disconnectedCallback; cls.prototype.connectedCallback = function () { connectedCallback.call(this); - this[`__unbsubLocalStorage${key}`] = subscribeChanges(this); + this[`__unbsubLocalStorage${key}`] = subscribeChanges?.(this); }; cls.prototype.disconnectedCallback = function () { disconnectedCallback.call(this); - this[`__unbsubLocalStorage${key}`](); + this[`__unbsubLocalStorage${key}`]?.(); + this[`__unbsubLocalStorage${key}`] = undefined; }; } - if (property) { + if (options.state) { cls.createProperty(clsElement.key, { noAccessor: true, - ...propertyOptions, + ...options.stateOptions, }); } }, diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index f443ca9eee..0f95bbae23 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -23,19 +23,19 @@ import "@polymer/paper-item/paper-item"; import "@polymer/paper-listbox/paper-listbox"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { - css, CSSResult, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, + css, + html, + nothing, } from "lit"; import { customElement, eventOptions, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { guard } from "lit/directives/guard"; import memoizeOne from "memoize-one"; -import { LocalStorage } from "../common/decorators/local-storage"; +import { storage } from "../common/decorators/storage"; import { fireEvent } from "../common/dom/fire_event"; import { toggleAttribute } from "../common/dom/toggle_attribute"; import { stringCompare } from "../common/string/compare"; @@ -47,10 +47,10 @@ import { subscribeNotifications, } from "../data/persistent_notification"; import { subscribeRepairsIssueRegistry } from "../data/repairs"; -import { updateCanInstall, UpdateEntity } from "../data/update"; +import { UpdateEntity, updateCanInstall } from "../data/update"; import { SubscribeMixin } from "../mixins/subscribe-mixin"; import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive"; -import { loadSortable, SortableInstance } from "../resources/sortable.ondemand"; +import { SortableInstance, loadSortable } from "../resources/sortable.ondemand"; import { haStyleScrollbar } from "../resources/styles"; import type { HomeAssistant, PanelInfo, Route } from "../types"; import "./ha-icon"; @@ -214,15 +214,17 @@ class HaSidebar extends SubscribeMixin(LitElement) { private sortableStyleLoaded = false; - // @ts-ignore - @LocalStorage("sidebarPanelOrder", true, { - attribute: false, + @storage({ + key: "sidebarPanelOrder", + state: true, + subscribe: true, }) private _panelOrder: string[] = []; - // @ts-ignore - @LocalStorage("sidebarHiddenPanels", true, { - attribute: false, + @storage({ + key: "sidebarHiddenPanels", + state: true, + subscribe: true, }) private _hiddenPanels: string[] = []; diff --git a/src/components/media-player/ha-browse-media-tts.ts b/src/components/media-player/ha-browse-media-tts.ts index d16f2bbe15..39e36b60b7 100644 --- a/src/components/media-player/ha-browse-media-tts.ts +++ b/src/components/media-player/ha-browse-media-tts.ts @@ -1,7 +1,7 @@ import "@material/mwc-list/mwc-list-item"; import { css, html, LitElement, nothing, PropertyValues } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { LocalStorage } from "../../common/decorators/local-storage"; +import { storage } from "../../common/decorators/storage"; import { fireEvent } from "../../common/dom/fire_event"; import { MediaPlayerBrowseAction, @@ -43,7 +43,12 @@ class BrowseMediaTTS extends LitElement { @state() private _provider?: TTSEngine; - @LocalStorage("TtsMessage", true, false) private _message!: string; + @storage({ + key: "TtsMessage", + state: true, + subscribe: false, + }) + private _message!: string; protected render() { return html` diff --git a/src/dialogs/tts-try/dialog-tts-try.ts b/src/dialogs/tts-try/dialog-tts-try.ts index 113b5345ca..0854133bba 100644 --- a/src/dialogs/tts-try/dialog-tts-try.ts +++ b/src/dialogs/tts-try/dialog-tts-try.ts @@ -1,7 +1,7 @@ import { mdiPlayCircleOutline } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { LocalStorage } from "../../common/decorators/local-storage"; +import { storage } from "../../common/decorators/storage"; import { fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-button"; import { createCloseHeading } from "../../components/ha-dialog"; @@ -25,10 +25,12 @@ export class TTSTryDialog extends LitElement { @query("#message") private _messageInput?: HaTextArea; - @LocalStorage("ttsTryMessages", false, false) private _messages?: Record< - string, - string - >; + @storage({ + key: "ttsTryMessages", + state: false, + subscribe: false, + }) + private _messages?: Record; public showDialog(params: TTSTryDialogParams) { this._params = params; diff --git a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts index b3a83bfce5..1aa6695ba2 100644 --- a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts +++ b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts @@ -18,7 +18,7 @@ import { TemplateResult, } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { LocalStorage } from "../../common/decorators/local-storage"; +import { storage } from "../../common/decorators/storage"; import { fireEvent } from "../../common/dom/fire_event"; import { stopPropagation } from "../../common/dom/stop_propagation"; import "../../components/ha-button"; @@ -57,7 +57,12 @@ export class HaVoiceCommandDialog extends LitElement { @state() private _opened = false; - @LocalStorage("AssistPipelineId", true, false) private _pipelineId?: string; + @storage({ + key: "AssistPipelineId", + state: true, + subscribe: false, + }) + private _pipelineId?: string; @state() private _pipeline?: AssistPipeline; diff --git a/src/panels/calendar/ha-panel-calendar.ts b/src/panels/calendar/ha-panel-calendar.ts index 43c824eff9..878d6348fa 100644 --- a/src/panels/calendar/ha-panel-calendar.ts +++ b/src/panels/calendar/ha-panel-calendar.ts @@ -11,7 +11,7 @@ import { } from "lit"; import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; -import { LocalStorage } from "../../common/decorators/local-storage"; +import { storage } from "../../common/decorators/storage"; import { HASSDomEvent } from "../../common/dom/fire_event"; import { computeStateName } from "../../common/entity/compute_state_name"; import "../../components/ha-card"; @@ -41,7 +41,10 @@ class PanelCalendar extends LitElement { @state() private _error?: string = undefined; - @LocalStorage("deSelectedCalendars", true) + @storage({ + key: "deSelectedCalendars", + state: true, + }) private _deSelectedCalendars: string[] = []; private _start?: Date; diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index 7324f8d5a4..c8cf4fa69b 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -20,7 +20,7 @@ import { documentationUrl } from "../../../util/documentation-url"; import "./action/ha-automation-action"; import "./condition/ha-automation-condition"; import "./trigger/ha-automation-trigger"; -import { LocalStorage } from "../../../common/decorators/local-storage"; +import { storage } from "../../../common/decorators/storage"; @customElement("manual-automation-editor") export class HaManualAutomationEditor extends LitElement { @@ -36,7 +36,12 @@ export class HaManualAutomationEditor extends LitElement { @property({ attribute: false }) public stateObj?: HassEntity; - @LocalStorage("automationClipboard", true, false, window.sessionStorage) + @storage({ + key: "automationClipboard", + state: true, + subscribe: false, + storage: "sessionStorage", + }) private _clipboard: Clipboard = {}; protected render() { diff --git a/src/panels/config/cloud/account/dialog-cloud-tts-try.ts b/src/panels/config/cloud/account/dialog-cloud-tts-try.ts index effed9dea4..bd079a5854 100644 --- a/src/panels/config/cloud/account/dialog-cloud-tts-try.ts +++ b/src/panels/config/cloud/account/dialog-cloud-tts-try.ts @@ -3,7 +3,7 @@ import "@material/mwc-list/mwc-list-item"; import { mdiPlayCircleOutline, mdiRobot } from "@mdi/js"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { LocalStorage } from "../../../../common/decorators/local-storage"; +import { storage } from "../../../../common/decorators/storage"; import { fireEvent } from "../../../../common/dom/fire_event"; import { stopPropagation } from "../../../../common/dom/stop_propagation"; import { computeStateDomain } from "../../../../common/entity/compute_state_domain"; @@ -31,9 +31,19 @@ export class DialogTryTts extends LitElement { @query("#message") private _messageInput?: HaTextArea; - @LocalStorage("cloudTtsTryMessage", false, false) private _message!: string; + @storage({ + key: "cloudTtsTryMessage", + state: false, + subscribe: false, + }) + private _message!: string; - @LocalStorage("cloudTtsTryTarget", false, false) private _target!: string; + @storage({ + key: "cloudTtsTryTarget", + state: false, + subscribe: false, + }) + private _target!: string; public showDialog(params: TryTtsDialogParams) { this._params = params; diff --git a/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts b/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts index 297ad0c9d9..032ebf38ed 100644 --- a/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts +++ b/src/panels/config/integrations/integration-panels/mqtt/mqtt-config-panel.ts @@ -1,7 +1,7 @@ import "@material/mwc-button"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import { LocalStorage } from "../../../../../common/decorators/local-storage"; +import { storage } from "../../../../../common/decorators/storage"; import "../../../../../components/ha-card"; import "../../../../../components/ha-code-editor"; import "../../../../../components/ha-formfield"; @@ -21,19 +21,39 @@ class HaPanelDevMqtt extends LitElement { @property({ type: Boolean }) public narrow!: boolean; - @LocalStorage("panel-dev-mqtt-topic-ls", true, false) + @storage({ + key: "panel-dev-mqtt-topic-ls", + state: true, + subscribe: false, + }) private _topic = ""; - @LocalStorage("panel-dev-mqtt-payload-ls", true, false) + @storage({ + key: "panel-dev-mqtt-payload-ls", + state: true, + subscribe: false, + }) private _payload = ""; - @LocalStorage("panel-dev-mqtt-qos-ls", true, false) + @storage({ + key: "panel-dev-mqtt-qos-ls", + state: true, + subscribe: false, + }) private _qos = "0"; - @LocalStorage("panel-dev-mqtt-retain-ls", true, false) + @storage({ + key: "panel-dev-mqtt-retain-ls", + state: true, + subscribe: false, + }) private _retain = false; - @LocalStorage("panel-dev-mqtt-allow-template-ls", true, false) + @storage({ + key: "panel-dev-mqtt-allow-template-ls", + state: true, + subscribe: false, + }) private _allowTemplate = false; protected render(): TemplateResult { diff --git a/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts b/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts index bb04eb4f78..b1bf864377 100644 --- a/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts +++ b/src/panels/config/integrations/integration-panels/mqtt/mqtt-subscribe-card.ts @@ -8,7 +8,7 @@ import { formatTime } from "../../../../../common/datetime/format_time"; import { MQTTMessage, subscribeMQTTTopic } from "../../../../../data/mqtt"; import { HomeAssistant } from "../../../../../types"; import "@material/mwc-list/mwc-list-item"; -import { LocalStorage } from "../../../../../common/decorators/local-storage"; +import { storage } from "../../../../../common/decorators/storage"; import "../../../../../components/ha-formfield"; import "../../../../../components/ha-switch"; @@ -18,13 +18,25 @@ const qosLevel = ["0", "1", "2"]; class MqttSubscribeCard extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @LocalStorage("panel-dev-mqtt-topic-subscribe", true, false) + @storage({ + key: "panel-dev-mqtt-topic-subscribe", + state: true, + subscribe: false, + }) private _topic = ""; - @LocalStorage("panel-dev-mqtt-qos-subscribe", true, false) + @storage({ + key: "panel-dev-mqtt-qos-subscribe", + state: true, + subscribe: false, + }) private _qos = "0"; - @LocalStorage("panel-dev-mqtt-json-format", true, false) + @storage({ + key: "panel-dev-mqtt-json-format", + state: true, + subscribe: false, + }) private _json_format = false; @state() private _subscribed?: () => void; diff --git a/src/panels/config/script/manual-script-editor.ts b/src/panels/config/script/manual-script-editor.ts index 333c052500..585623dc3b 100644 --- a/src/panels/config/script/manual-script-editor.ts +++ b/src/panels/config/script/manual-script-editor.ts @@ -3,7 +3,7 @@ import { mdiHelpCircle } from "@mdi/js"; import deepClone from "deep-clone-simple"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; -import { LocalStorage } from "../../../common/decorators/local-storage"; +import { storage } from "../../../common/decorators/storage"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; @@ -26,7 +26,12 @@ export class HaManualScriptEditor extends LitElement { @property({ attribute: false }) public config!: ScriptConfig; - @LocalStorage("automationClipboard", true, false, window.sessionStorage) + @storage({ + key: "automationClipboard", + state: true, + subscribe: false, + storage: "sessionStorage", + }) private _clipboard: Clipboard = {}; protected render() { diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index a169b0fb27..6096bd16b4 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -4,7 +4,7 @@ import { load } from "js-yaml"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { property, query, state } from "lit/decorators"; import memoizeOne from "memoize-one"; -import { LocalStorage } from "../../../common/decorators/local-storage"; +import { storage } from "../../../common/decorators/storage"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeObjectId } from "../../../common/entity/compute_object_id"; import { hasTemplate } from "../../../common/string/has-template"; @@ -38,10 +38,18 @@ class HaPanelDevService extends LitElement { @state() private _uiAvailable = true; - @LocalStorage("panel-dev-service-state-service-data", true, false) + @storage({ + key: "panel-dev-service-state-service-data", + state: true, + subscribe: false, + }) private _serviceData?: ServiceAction = { service: "", target: {}, data: {} }; - @LocalStorage("panel-dev-service-state-yaml-mode", true, false) + @storage({ + key: "panel-dev-service-state-yaml-mode", + state: true, + subscribe: false, + }) private _yamlMode = false; @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; diff --git a/src/panels/history/ha-panel-history.ts b/src/panels/history/ha-panel-history.ts index bb3c224750..94d5ab6c15 100644 --- a/src/panels/history/ha-panel-history.ts +++ b/src/panels/history/ha-panel-history.ts @@ -7,7 +7,7 @@ import { import { css, html, LitElement, PropertyValues } from "lit"; import { property, query, state } from "lit/decorators"; import { ensureArray } from "../../common/array/ensure-array"; -import { LocalStorage } from "../../common/decorators/local-storage"; +import { storage } from "../../common/decorators/storage"; import { navigate } from "../../common/navigate"; import { constructUrlCurrentPath } from "../../common/url/construct-url"; import { @@ -58,7 +58,11 @@ class HaPanelHistory extends SubscribeMixin(LitElement) { @state() private _endDate: Date; - @LocalStorage("historyPickedValue", true, false) + @storage({ + key: "historyPickedValue", + state: true, + subscribe: false, + }) private _targetPickerValue?: HassServiceTarget; @state() private _isLoading = false; diff --git a/src/panels/media-browser/ha-panel-media-browser.ts b/src/panels/media-browser/ha-panel-media-browser.ts index 3bd5da6fc9..e71291bec8 100644 --- a/src/panels/media-browser/ha-panel-media-browser.ts +++ b/src/panels/media-browser/ha-panel-media-browser.ts @@ -9,7 +9,7 @@ import { TemplateResult, } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { LocalStorage } from "../../common/decorators/local-storage"; +import { storage } from "../../common/decorators/storage"; import { fireEvent, HASSDomEvent } from "../../common/dom/fire_event"; import { navigate } from "../../common/navigate"; import "../../components/ha-menu-button"; @@ -71,7 +71,11 @@ class PanelMediaBrowser extends LitElement { }, ]; - @LocalStorage("mediaBrowseEntityId", true, false) + @storage({ + key: "mediaBrowseEntityId", + state: true, + subscribe: false, + }) private _entityId = BROWSER_PLAYER; @query("ha-media-player-browse") private _browser!: HaMediaPlayerBrowse; From 1fe5d66a6874842460c302215a0ccc2535f2bf4a Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 21 Jun 2023 17:22:33 +0200 Subject: [PATCH 088/162] Allow cards and tile features to provide a schema to create the editor (#16142) Co-authored-by: Bram Kragten --- src/panels/lovelace/cards/hui-entity-card.ts | 20 ++--- .../card-editor/hui-card-element-editor.ts | 13 ++- .../config-elements/hui-entity-card-editor.ts | 84 ++++--------------- .../editor/config-elements/hui-form-editor.ts | 82 ++++++++++++++++++ .../lovelace/editor/hui-element-editor.ts | 35 +++++++- .../hui-tile-feature-element-editor.ts | 16 +++- src/panels/lovelace/types.ts | 22 ++++- 7 files changed, 185 insertions(+), 87 deletions(-) create mode 100644 src/panels/lovelace/editor/config-elements/hui-form-editor.ts diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index 548dbd80ec..7424877f52 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -4,14 +4,15 @@ import { CSSResultGroup, html, LitElement, - PropertyValues, nothing, + PropertyValues, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; +import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; @@ -27,7 +28,6 @@ import "../../../components/ha-card"; import "../../../components/ha-icon"; import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { isUnavailableState } from "../../../data/entity"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { LightEntity } from "../../../data/light"; import { HomeAssistant } from "../../../types"; import { computeCardSize } from "../common/compute-card-size"; @@ -35,21 +35,12 @@ import { findEntities } from "../common/find-entities"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { createHeaderFooterElement } from "../create-element/create-header-footer-element"; -import { - LovelaceCard, - LovelaceCardEditor, - LovelaceHeaderFooter, -} from "../types"; +import { LovelaceCard, LovelaceHeaderFooter } from "../types"; import { HuiErrorCard } from "./hui-error-card"; import { EntityCardConfig } from "./types"; @customElement("hui-entity-card") export class HuiEntityCard extends LitElement implements LovelaceCard { - public static async getConfigElement(): Promise { - await import("../editor/config-elements/hui-entity-card-editor"); - return document.createElement("hui-entity-card-editor"); - } - public static getStubConfig( hass: HomeAssistant, entities: string[], @@ -70,6 +61,11 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { }; } + public static async getConfigForm() { + return (await import("../editor/config-elements/hui-entity-card-editor")) + .default; + } + @property({ attribute: false }) public hass?: HomeAssistant; @state() private _config?: EntityCardConfig; diff --git a/src/panels/lovelace/editor/card-editor/hui-card-element-editor.ts b/src/panels/lovelace/editor/card-editor/hui-card-element-editor.ts index 08a0b9bd42..be036fb404 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-element-editor.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-element-editor.ts @@ -1,7 +1,7 @@ import { customElement } from "lit/decorators"; import type { LovelaceCardConfig } from "../../../../data/lovelace"; import { getCardElementClass } from "../../create-element/create-card-element"; -import type { LovelaceCardEditor } from "../../types"; +import type { LovelaceCardEditor, LovelaceConfigForm } from "../../types"; import { HuiElementEditor } from "../hui-element-editor"; @customElement("hui-card-element-editor") @@ -16,6 +16,17 @@ export class HuiCardElementEditor extends HuiElementEditor { return undefined; } + + protected async getConfigForm(): Promise { + const elClass = await getCardElementClass(this.configElementType!); + + // Check if a schema exists + if (elClass && elClass.getConfigForm) { + return elClass.getConfigForm(); + } + + return undefined; + } } declare global { diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts index 3379792b6f..4c93882620 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-entity-card-editor.ts @@ -1,16 +1,12 @@ -import { html, LitElement, nothing } from "lit"; -import { customElement, property, state } from "lit/decorators"; import { assert, assign, boolean, object, optional, string } from "superstruct"; -import { fireEvent } from "../../../../common/dom/fire_event"; -import "../../../../components/ha-form/ha-form"; -import type { SchemaUnion } from "../../../../components/ha-form/types"; -import type { HomeAssistant } from "../../../../types"; -import type { EntityCardConfig } from "../../cards/types"; +import { LocalizeFunc } from "../../../../common/translations/localize"; +import { HaFormSchema } from "../../../../components/ha-form/types"; +import { EntityCardConfig } from "../../cards/types"; import { headerFooterConfigStructs } from "../../header-footer/structs"; -import type { LovelaceCardEditor } from "../../types"; +import { LovelaceConfigForm } from "../../types"; import { baseLovelaceCardConfig } from "../structs/base-card-struct"; -const cardConfigStruct = assign( +const struct = assign( baseLovelaceCardConfig, object({ entity: optional(string()), @@ -54,67 +50,19 @@ const SCHEMA = [ { name: "state_color", selector: { boolean: {} } }, ], }, -] as const; - -@customElement("hui-entity-card-editor") -export class HuiEntityCardEditor - extends LitElement - implements LovelaceCardEditor -{ - @property({ attribute: false }) public hass?: HomeAssistant; - - @state() private _config?: EntityCardConfig; - - public setConfig(config: EntityCardConfig): void { - assert(config, cardConfigStruct); - this._config = config; - } - - protected render() { - if (!this.hass || !this._config) { - return nothing; - } - - return html` - - `; - } - - private _valueChanged(ev: CustomEvent): void { - const config = ev.detail.value; - Object.keys(config).forEach((k) => config[k] === "" && delete config[k]); - fireEvent(this, "config-changed", { config }); - } - - private _computeLabelCallback = (schema: SchemaUnion) => { - if (schema.name === "entity") { - return this.hass!.localize( - "ui.panel.lovelace.editor.card.generic.entity" - ); - } +] as HaFormSchema[]; +const entityCardConfigForm: LovelaceConfigForm = { + schema: SCHEMA, + assertConfig: (config: EntityCardConfig) => assert(config, struct), + computeLabel: (schema: HaFormSchema, localize: LocalizeFunc) => { if (schema.name === "theme") { - return `${this.hass!.localize( + return `${localize( "ui.panel.lovelace.editor.card.generic.theme" - )} (${this.hass!.localize( - "ui.panel.lovelace.editor.card.config.optional" - )})`; + )} (${localize("ui.panel.lovelace.editor.card.config.optional")})`; } + return localize(`ui.panel.lovelace.editor.card.generic.${schema.name}`); + }, +}; - return this.hass!.localize( - `ui.panel.lovelace.editor.card.generic.${schema.name}` - ); - }; -} - -declare global { - interface HTMLElementTagNameMap { - "hui-entity-card-editor": HuiEntityCardEditor; - } -} +export default entityCardConfigForm; diff --git a/src/panels/lovelace/editor/config-elements/hui-form-editor.ts b/src/panels/lovelace/editor/config-elements/hui-form-editor.ts new file mode 100644 index 0000000000..9db046adfe --- /dev/null +++ b/src/panels/lovelace/editor/config-elements/hui-form-editor.ts @@ -0,0 +1,82 @@ +import { CSSResultGroup, html, LitElement, nothing } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter"; +import { LocalizeFunc } from "../../../../common/translations/localize"; +import "../../../../components/ha-form/ha-form"; +import type { HaFormSchema } from "../../../../components/ha-form/types"; +import { LovelaceCardConfig } from "../../../../data/lovelace"; +import type { HomeAssistant } from "../../../../types"; +import type { LovelaceGenericElementEditor } from "../../types"; +import { configElementStyle } from "./config-elements-style"; + +@customElement("hui-form-editor") +export class HuiFormEditor + extends LitElement + implements LovelaceGenericElementEditor +{ + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public schema!: HaFormSchema[]; + + @state() private _config?: LovelaceCardConfig; + + public assertConfig(_config: LovelaceCardConfig): void { + return undefined; + } + + public setConfig(config: LovelaceCardConfig): void { + this.assertConfig(config); + this._config = config; + } + + protected render() { + if (!this._config) { + return nothing; + } + + return html` + + `; + } + + public computeLabel = ( + _schema: HaFormSchema, + _localize: LocalizeFunc + ): string | undefined => undefined; + + public computeHelper = ( + _schema: HaFormSchema, + _localize: LocalizeFunc + ): string | undefined => undefined; + + private _computeLabelCallback = (schema: HaFormSchema) => + this.computeLabel(schema, this.hass.localize) || + this.hass.localize( + `ui.panel.lovelace.editor.card.generic.${schema.name}` + ) || + capitalizeFirstLetter(schema.name.split("_").join(" ")); + + private _computeHelperCallback = (schema: HaFormSchema) => + this.computeHelper(schema, this.hass.localize); + + private _valueChanged(ev: CustomEvent): void { + const config = ev.detail.value; + fireEvent(this, "config-changed", { config }); + } + + static styles: CSSResultGroup = configElementStyle; +} + +declare global { + interface HTMLElementTagNameMap { + "hui-form-editor": HuiFormEditor; + } +} diff --git a/src/panels/lovelace/editor/hui-element-editor.ts b/src/panels/lovelace/editor/hui-element-editor.ts index b7b2dbf324..f711c63210 100644 --- a/src/panels/lovelace/editor/hui-element-editor.ts +++ b/src/panels/lovelace/editor/hui-element-editor.ts @@ -8,13 +8,13 @@ import { PropertyValues, TemplateResult, } from "lit"; -import { property, state, query } from "lit/decorators"; +import { property, query, state } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; import { handleStructError } from "../../../common/structs/handle-errors"; import { deepEqual } from "../../../common/util/deep-equal"; +import "../../../components/ha-alert"; import "../../../components/ha-circular-progress"; import "../../../components/ha-code-editor"; -import "../../../components/ha-alert"; import type { HaCodeEditor } from "../../../components/ha-code-editor"; import type { LovelaceCardConfig, @@ -23,11 +23,15 @@ import type { import type { HomeAssistant } from "../../../types"; import type { LovelaceRowConfig } from "../entity-rows/types"; import { LovelaceHeaderFooterConfig } from "../header-footer/types"; -import type { LovelaceGenericElementEditor } from "../types"; +import { LovelaceTileFeatureConfig } from "../tile-features/types"; +import type { + LovelaceConfigForm, + LovelaceGenericElementEditor, +} from "../types"; +import type { HuiFormEditor } from "./config-elements/hui-form-editor"; import "./config-elements/hui-generic-entity-row-editor"; import { GUISupportError } from "./gui-support-error"; import { EditSubElementEvent, GUIModeChangedEvent } from "./types"; -import { LovelaceTileFeatureConfig } from "../tile-features/types"; export interface ConfigChangedEvent { config: @@ -182,6 +186,10 @@ export abstract class HuiElementEditor extends LitElement { return undefined; } + protected async getConfigForm(): Promise { + return undefined; + } + protected get configElementType(): string | undefined { return this.value ? (this.value as any).type : undefined; } @@ -328,6 +336,25 @@ export abstract class HuiElementEditor extends LitElement { this._loading = true; configElement = await this.getConfigElement(); + if (!configElement) { + const form = await this.getConfigForm(); + if (form) { + await import("./config-elements/hui-form-editor"); + configElement = document.createElement("hui-form-editor"); + const { schema, assertConfig, computeLabel, computeHelper } = form; + (configElement as HuiFormEditor).schema = schema; + if (computeLabel) { + (configElement as HuiFormEditor).computeLabel = computeLabel; + } + if (computeHelper) { + (configElement as HuiFormEditor).computeHelper = computeHelper; + } + if (assertConfig) { + (configElement as HuiFormEditor).assertConfig = assertConfig; + } + } + } + if (configElement) { configElement.hass = this.hass; if ("lovelace" in configElement) { diff --git a/src/panels/lovelace/editor/tile-feature-editor/hui-tile-feature-element-editor.ts b/src/panels/lovelace/editor/tile-feature-editor/hui-tile-feature-element-editor.ts index 573d1e075c..58fb381399 100644 --- a/src/panels/lovelace/editor/tile-feature-editor/hui-tile-feature-element-editor.ts +++ b/src/panels/lovelace/editor/tile-feature-editor/hui-tile-feature-element-editor.ts @@ -4,7 +4,10 @@ import { LovelaceTileFeatureConfig, LovelaceTileFeatureContext, } from "../../tile-features/types"; -import type { LovelaceTileFeatureEditor } from "../../types"; +import type { + LovelaceConfigForm, + LovelaceTileFeatureEditor, +} from "../../types"; import { HuiElementEditor } from "../hui-element-editor"; @customElement("hui-tile-feature-element-editor") @@ -24,6 +27,17 @@ export class HuiTileFeatureElementEditor extends HuiElementEditor< return undefined; } + + protected async getConfigForm(): Promise { + const elClass = await getTileFeatureElementClass(this.configElementType!); + + // Check if a schema exists + if (elClass && elClass.getConfigForm) { + return elClass.getConfigForm(); + } + + return undefined; + } } declare global { diff --git a/src/panels/lovelace/types.ts b/src/panels/lovelace/types.ts index c99e6a51c9..180c923d2e 100644 --- a/src/panels/lovelace/types.ts +++ b/src/panels/lovelace/types.ts @@ -1,4 +1,6 @@ import { HassEntity } from "home-assistant-js-websocket"; +import { LocalizeFunc } from "../../common/translations/localize"; +import { HaFormSchema } from "../../components/ha-form/types"; import { LovelaceBadgeConfig, LovelaceCardConfig, @@ -45,6 +47,19 @@ export interface LovelaceCard extends HTMLElement { setConfig(config: LovelaceCardConfig): void; } +export interface LovelaceConfigForm { + schema: HaFormSchema[]; + assertConfig?: (config: LovelaceCardConfig) => void; + computeLabel?: ( + schema: HaFormSchema, + localize: LocalizeFunc + ) => string | undefined; + computeHelper?: ( + schema: HaFormSchema, + localize: LocalizeFunc + ) => string | undefined; +} + export interface LovelaceCardConstructor extends Constructor { getStubConfig?: ( hass: HomeAssistant, @@ -52,6 +67,7 @@ export interface LovelaceCardConstructor extends Constructor { entitiesFallback: string[] ) => LovelaceCardConfig; getConfigElement?: () => LovelaceCardEditor; + getConfigForm?: () => LovelaceConfigForm; } export interface LovelaceHeaderFooterConstructor @@ -104,11 +120,15 @@ export interface LovelaceTileFeature extends HTMLElement { export interface LovelaceTileFeatureConstructor extends Constructor { - getConfigElement?: () => LovelaceTileFeatureEditor; getStubConfig?: ( hass: HomeAssistant, stateObj?: HassEntity ) => LovelaceTileFeatureConfig; + getConfigElement?: () => LovelaceTileFeatureEditor; + getConfigForm?: () => { + schema: HaFormSchema[]; + assertConfig?: (config: LovelaceCardConfig) => void; + }; isSupported?: (stateObj?: HassEntity) => boolean; } From eb552530e2514a51c995a4e750e8ceff8684342b Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 21 Jun 2023 17:46:40 +0200 Subject: [PATCH 089/162] Add support for image entity (#16877) --- src/common/const.ts | 2 + src/common/entity/compute_state_display.ts | 4 +- src/components/ha-picture-upload.ts | 2 +- src/data/image.ts | 59 ++----- src/data/image_upload.ts | 54 ++++++ src/dialogs/more-info/const.ts | 1 + .../more-info/controls/more-info-image.ts | 40 +++++ .../more-info/state_more_info_control.ts | 1 + src/panels/lovelace/cards/hui-picture-card.ts | 59 +++++-- .../cards/hui-picture-elements-card.ts | 15 +- .../lovelace/cards/hui-picture-entity-card.ts | 11 +- .../lovelace/cards/hui-picture-glance-card.ts | 50 ++++-- src/panels/lovelace/cards/types.ts | 2 + .../common/generate-lovelace-config.ts | 7 + src/panels/lovelace/common/handle-action.ts | 7 +- src/panels/lovelace/components/hui-image.ts | 4 + .../hui-picture-card-editor.ts | 160 +++++------------- .../hui-picture-glance-card-editor.ts | 2 + .../lovelace/elements/hui-image-element.ts | 7 +- src/panels/lovelace/elements/types.ts | 1 + src/translations/en.json | 1 + 21 files changed, 287 insertions(+), 202 deletions(-) create mode 100644 src/data/image_upload.ts create mode 100644 src/dialogs/more-info/controls/more-info-image.ts diff --git a/src/common/const.ts b/src/common/const.ts index 35bd81a3e2..76275f55a2 100644 --- a/src/common/const.ts +++ b/src/common/const.ts @@ -33,6 +33,7 @@ import { mdiGoogleCirclesCommunities, mdiHomeAssistant, mdiHomeAutomation, + mdiImage, mdiImageFilterFrames, mdiLightbulb, mdiLightningBolt, @@ -90,6 +91,7 @@ export const FIXED_DOMAIN_ICONS = { group: mdiGoogleCirclesCommunities, homeassistant: mdiHomeAssistant, homekit: mdiHomeAutomation, + image: mdiImage, image_processing: mdiImageFilterFrames, input_button: mdiGestureTapButton, input_datetime: mdiCalendarClock, diff --git a/src/common/entity/compute_state_display.ts b/src/common/entity/compute_state_display.ts index 34db8700d1..9c768bd55e 100644 --- a/src/common/entity/compute_state_display.ts +++ b/src/common/entity/compute_state_display.ts @@ -191,7 +191,9 @@ export const computeStateDisplayFromEntityAttributes = ( // state is a timestamp if ( - ["button", "input_button", "scene", "stt", "tts"].includes(domain) || + ["button", "image", "input_button", "scene", "stt", "tts"].includes( + domain + ) || (domain === "sensor" && attributes.device_class === "timestamp") ) { try { diff --git a/src/components/ha-picture-upload.ts b/src/components/ha-picture-upload.ts index 15d2fef7ae..0a21f82ec7 100644 --- a/src/components/ha-picture-upload.ts +++ b/src/components/ha-picture-upload.ts @@ -2,7 +2,7 @@ import { mdiImagePlus } from "@mdi/js"; import { html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; -import { createImage, generateImageThumbnailUrl } from "../data/image"; +import { createImage, generateImageThumbnailUrl } from "../data/image_upload"; import { showAlertDialog } from "../dialogs/generic/show-dialog-box"; import { CropOptions, diff --git a/src/data/image.ts b/src/data/image.ts index 94198de6dc..f28ea74860 100644 --- a/src/data/image.ts +++ b/src/data/image.ts @@ -1,54 +1,15 @@ -import { HomeAssistant } from "../types"; +import { + HassEntityAttributeBase, + HassEntityBase, +} from "home-assistant-js-websocket"; -interface Image { - filesize: number; - name: string; - uploaded_at: string; // isoformat date - content_type: string; - id: string; +interface ImageEntityAttributes extends HassEntityAttributeBase { + access_token: string; } -export interface ImageMutableParams { - name: string; +export interface ImageEntity extends HassEntityBase { + attributes: ImageEntityAttributes; } -export const generateImageThumbnailUrl = (mediaId: string, size: number) => - `/api/image/serve/${mediaId}/${size}x${size}`; - -export const fetchImages = (hass: HomeAssistant) => - hass.callWS({ type: "image/list" }); - -export const createImage = async ( - hass: HomeAssistant, - file: File -): Promise => { - const fd = new FormData(); - fd.append("file", file); - const resp = await hass.fetchWithAuth("/api/image/upload", { - method: "POST", - body: fd, - }); - if (resp.status === 413) { - throw new Error(`Uploaded image is too large (${file.name})`); - } else if (resp.status !== 200) { - throw new Error("Unknown error"); - } - return resp.json(); -}; - -export const updateImage = ( - hass: HomeAssistant, - id: string, - updates: Partial -) => - hass.callWS({ - type: "image/update", - media_id: id, - ...updates, - }); - -export const deleteImage = (hass: HomeAssistant, id: string) => - hass.callWS({ - type: "image/delete", - media_id: id, - }); +export const computeImageUrl = (entity: ImageEntity): string => + `/api/image_proxy/${entity.entity_id}?token=${entity.attributes.access_token}&state=${entity.state}`; diff --git a/src/data/image_upload.ts b/src/data/image_upload.ts new file mode 100644 index 0000000000..94198de6dc --- /dev/null +++ b/src/data/image_upload.ts @@ -0,0 +1,54 @@ +import { HomeAssistant } from "../types"; + +interface Image { + filesize: number; + name: string; + uploaded_at: string; // isoformat date + content_type: string; + id: string; +} + +export interface ImageMutableParams { + name: string; +} + +export const generateImageThumbnailUrl = (mediaId: string, size: number) => + `/api/image/serve/${mediaId}/${size}x${size}`; + +export const fetchImages = (hass: HomeAssistant) => + hass.callWS({ type: "image/list" }); + +export const createImage = async ( + hass: HomeAssistant, + file: File +): Promise => { + const fd = new FormData(); + fd.append("file", file); + const resp = await hass.fetchWithAuth("/api/image/upload", { + method: "POST", + body: fd, + }); + if (resp.status === 413) { + throw new Error(`Uploaded image is too large (${file.name})`); + } else if (resp.status !== 200) { + throw new Error("Unknown error"); + } + return resp.json(); +}; + +export const updateImage = ( + hass: HomeAssistant, + id: string, + updates: Partial +) => + hass.callWS({ + type: "image/update", + media_id: id, + ...updates, + }); + +export const deleteImage = (hass: HomeAssistant, id: string) => + hass.callWS({ + type: "image/delete", + media_id: id, + }); diff --git a/src/dialogs/more-info/const.ts b/src/dialogs/more-info/const.ts index 79af1e13d3..d6d6d615aa 100644 --- a/src/dialogs/more-info/const.ts +++ b/src/dialogs/more-info/const.ts @@ -40,6 +40,7 @@ export const DOMAINS_WITH_MORE_INFO = [ "fan", "group", "humidifier", + "image", "input_boolean", "input_datetime", "light", diff --git a/src/dialogs/more-info/controls/more-info-image.ts b/src/dialogs/more-info/controls/more-info-image.ts new file mode 100644 index 0000000000..d54ed0cf43 --- /dev/null +++ b/src/dialogs/more-info/controls/more-info-image.ts @@ -0,0 +1,40 @@ +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { customElement, property } from "lit/decorators"; +import "../../../components/ha-camera-stream"; +import { computeImageUrl, ImageEntity } from "../../../data/image"; +import type { HomeAssistant } from "../../../types"; + +@customElement("more-info-image") +class MoreInfoImage extends LitElement { + @property({ attribute: false }) public hass?: HomeAssistant; + + @property({ attribute: false }) public stateObj?: ImageEntity; + + protected render() { + if (!this.hass || !this.stateObj) { + return nothing; + } + return html`${this.stateObj.attributes.friendly_name `; + } + + static get styles(): CSSResultGroup { + return css` + :host { + display: block; + text-align: center; + } + img { + max-width: 100%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "more-info-image": MoreInfoImage; + } +} diff --git a/src/dialogs/more-info/state_more_info_control.ts b/src/dialogs/more-info/state_more_info_control.ts index 7c85f0db71..cc0d07eb67 100644 --- a/src/dialogs/more-info/state_more_info_control.ts +++ b/src/dialogs/more-info/state_more_info_control.ts @@ -18,6 +18,7 @@ const LAZY_LOADED_MORE_INFO_CONTROL = { fan: () => import("./controls/more-info-fan"), group: () => import("./controls/more-info-group"), humidifier: () => import("./controls/more-info-humidifier"), + image: () => import("./controls/more-info-image"), input_boolean: () => import("./controls/more-info-input_boolean"), input_datetime: () => import("./controls/more-info-input_datetime"), light: () => import("./controls/more-info-light"), diff --git a/src/panels/lovelace/cards/hui-picture-card.ts b/src/panels/lovelace/cards/hui-picture-card.ts index c72bf72bc9..843d447a67 100644 --- a/src/panels/lovelace/cards/hui-picture-card.ts +++ b/src/panels/lovelace/cards/hui-picture-card.ts @@ -3,19 +3,22 @@ import { CSSResultGroup, html, LitElement, - PropertyValues, nothing, + PropertyValues, } from "lit"; import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { ifDefined } from "lit/directives/if-defined"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import "../../../components/ha-card"; +import { computeImageUrl, ImageEntity } from "../../../data/image"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { handleAction } from "../common/handle-action"; import { hasAction } from "../common/has-action"; +import { hasConfigChanged } from "../common/has-changed"; +import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { PictureCardConfig } from "./types"; @@ -30,8 +33,6 @@ export class HuiPictureCard extends LitElement implements LovelaceCard { return { type: "picture", image: "https://demo.home-assistant.io/stub_config/t-shirt-promo.png", - tap_action: { action: "none" }, - hold_action: { action: "none" }, }; } @@ -44,7 +45,7 @@ export class HuiPictureCard extends LitElement implements LovelaceCard { } public setConfig(config: PictureCardConfig): void { - if (!config || !config.image) { + if (!config || (!config.image && !config.image_entity)) { throw new Error("Image required"); } @@ -52,10 +53,21 @@ export class HuiPictureCard extends LitElement implements LovelaceCard { } protected shouldUpdate(changedProps: PropertyValues): boolean { - if (changedProps.size === 1 && changedProps.has("hass")) { - return !changedProps.get("hass"); + if (!this._config || hasConfigChanged(this, changedProps)) { + return true; } - return true; + if (this._config.image_entity && changedProps.has("hass")) { + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if ( + !oldHass || + oldHass.states[this._config.image_entity] !== + this.hass!.states[this._config.image_entity] + ) { + return true; + } + } + + return false; } protected updated(changedProps: PropertyValues): void { @@ -83,6 +95,17 @@ export class HuiPictureCard extends LitElement implements LovelaceCard { return nothing; } + let stateObj: ImageEntity | undefined; + + if (this._config.image_entity) { + stateObj = this.hass.states[this._config.image_entity] as ImageEntity; + if (!stateObj) { + return html` + ${createEntityNotFoundWarning(this.hass, this._config.image_entity)} + `; + } + } + return html` ${this._config.alt_text} `; diff --git a/src/panels/lovelace/cards/hui-picture-elements-card.ts b/src/panels/lovelace/cards/hui-picture-elements-card.ts index fad22f2c66..15c7f02e1f 100644 --- a/src/panels/lovelace/cards/hui-picture-elements-card.ts +++ b/src/panels/lovelace/cards/hui-picture-elements-card.ts @@ -9,6 +9,7 @@ import { import { customElement, property, state } from "lit/decorators"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import "../../../components/ha-card"; +import { ImageEntity, computeImageUrl } from "../../../data/image"; import { HomeAssistant } from "../../../types"; import { findEntities } from "../common/find-entities"; import { LovelaceElement, LovelaceElementConfig } from "../elements/types"; @@ -62,7 +63,12 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard { if (!config) { throw new Error("Invalid configuration"); } else if ( - !(config.image || config.camera_image || config.state_image) || + !( + config.image || + config.image_entity || + config.camera_image || + config.state_image + ) || (config.state_image && !config.entity) ) { throw new Error("Image required"); @@ -115,12 +121,17 @@ class HuiPictureElementsCard extends LitElement implements LovelaceCard { return nothing; } + let stateObj: ImageEntity | undefined; + if (this._config.image_entity) { + stateObj = this.hass.states[this._config.image_entity] as ImageEntity; + } + return html`
${entityState}
`; } + const domain = computeDomain(this._config.entity); + return html`
${this._config.title - ? html`
${this._config.title}
` + ? html`
${this._config.title}
` : ""}
${this._entitiesDialog!.map((entityConf) => diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index fac076ad93..082b6c4b53 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -335,6 +335,7 @@ export interface StatisticCardConfig extends LovelaceCardConfig { export interface PictureCardConfig extends LovelaceCardConfig { image?: string; + image_entity?: string; tap_action?: ActionConfig; hold_action?: ActionConfig; double_tap_action?: ActionConfig; @@ -345,6 +346,7 @@ export interface PictureCardConfig extends LovelaceCardConfig { export interface PictureElementsCardConfig extends LovelaceCardConfig { title?: string; image?: string; + image_entity?: string; camera_image?: string; camera_view?: HuiImage["cameraView"]; state_image?: Record; diff --git a/src/panels/lovelace/common/generate-lovelace-config.ts b/src/panels/lovelace/common/generate-lovelace-config.ts index 99bfbdc634..65b66c3ce1 100644 --- a/src/panels/lovelace/common/generate-lovelace-config.ts +++ b/src/panels/lovelace/common/generate-lovelace-config.ts @@ -20,6 +20,7 @@ import { AlarmPanelCardConfig, EntitiesCardConfig, HumidifierCardConfig, + PictureCardConfig, PictureEntityCardConfig, ThermostatCardConfig, } from "../cards/types"; @@ -125,6 +126,12 @@ export const computeCards = ( entity: entityId, }; cards.push(cardConfig); + } else if (domain === "image") { + const cardConfig: PictureCardConfig = { + type: "picture", + image_entity: entityId, + }; + cards.push(cardConfig); } else if (domain === "climate") { const cardConfig: ThermostatCardConfig = { type: "thermostat", diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index f782d6ad53..83deadf5db 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -18,6 +18,7 @@ declare global { export type ActionConfigParams = { entity?: string; camera_image?: string; + image_entity?: string; hold_action?: ActionConfig; tap_action?: ActionConfig; double_tap_action?: ActionConfig; @@ -87,9 +88,11 @@ export const handleAction = async ( switch (actionConfig.action) { case "more-info": { - if (config.entity || config.camera_image) { + if (config.entity || config.camera_image || config.image_entity) { fireEvent(node, "hass-more-info", { - entityId: config.entity ? config.entity : config.camera_image!, + entityId: (config.entity || + config.camera_image || + config.image_entity)!, }); } else { showToast(node, { diff --git a/src/panels/lovelace/components/hui-image.ts b/src/panels/lovelace/components/hui-image.ts index 56c0873608..33201fd7af 100644 --- a/src/panels/lovelace/components/hui-image.ts +++ b/src/panels/lovelace/components/hui-image.ts @@ -10,12 +10,14 @@ import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import { STATES_OFF } from "../../../common/const"; +import { computeDomain } from "../../../common/entity/compute_domain"; import parseAspectRatio from "../../../common/util/parse-aspect-ratio"; import "../../../components/ha-camera-stream"; import type { HaCameraStream } from "../../../components/ha-camera-stream"; import "../../../components/ha-circular-progress"; import { CameraEntity, fetchThumbnailUrlWithCache } from "../../../data/camera"; import { UNAVAILABLE } from "../../../data/entity"; +import { computeImageUrl, ImageEntity } from "../../../data/image"; import { HomeAssistant } from "../../../types"; const UPDATE_INTERVAL = 10000; @@ -164,6 +166,8 @@ export class HuiImage extends LitElement { } } else if (this.darkModeImage && this.hass.themes.darkMode) { imageSrc = this.darkModeImage; + } else if (stateObj && computeDomain(stateObj.entity_id) === "image") { + imageSrc = computeImageUrl(stateObj as ImageEntity); } else { imageSrc = this.image; } diff --git a/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts index 29e001688d..1ce62d6a78 100644 --- a/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-picture-card-editor.ts @@ -1,22 +1,21 @@ -import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { assert, assign, object, optional, string } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; +import { SchemaUnion } from "../../../../components/ha-form/types"; import "../../../../components/ha-theme-picker"; -import { ActionConfig } from "../../../../data/lovelace"; import { HomeAssistant } from "../../../../types"; import { PictureCardConfig } from "../../cards/types"; import "../../components/hui-action-editor"; import { LovelaceCardEditor } from "../../types"; import { actionConfigStruct } from "../structs/action-struct"; import { baseLovelaceCardConfig } from "../structs/base-card-struct"; -import { EditorTarget } from "../types"; -import { configElementStyle } from "./config-elements-style"; const cardConfigStruct = assign( baseLovelaceCardConfig, object({ image: optional(string()), + image_entity: optional(string()), tap_action: optional(actionConfigStruct), hold_action: optional(actionConfigStruct), theme: optional(string()), @@ -24,6 +23,21 @@ const cardConfigStruct = assign( }) ); +const SCHEMA = [ + { name: "image", selector: { text: {} } }, + { name: "image_entity", selector: { entity: { domain: "image" } } }, + { name: "alt_text", selector: { text: {} } }, + { name: "theme", selector: { theme: {} } }, + { + name: "tap_action", + selector: { ui_action: {} }, + }, + { + name: "hold_action", + selector: { ui_action: {} }, + }, +] as const; + @customElement("hui-picture-card-editor") export class HuiPictureCardEditor extends LitElement @@ -38,129 +52,45 @@ export class HuiPictureCardEditor this._config = config; } - get _image(): string { - return this._config!.image || ""; - } - - get _tap_action(): ActionConfig { - return this._config!.tap_action || { action: "none" }; - } - - get _hold_action(): ActionConfig { - return this._config!.hold_action || { action: "none" }; - } - - get _theme(): string { - return this._config!.theme || ""; - } - - get _alt_text(): string { - return this._config!.alt_text || ""; - } - protected render() { if (!this.hass || !this._config) { return nothing; } - const actions = ["navigate", "url", "call-service", "none"]; - return html` -
- - - - - -
+ `; } private _valueChanged(ev: CustomEvent): void { - if (!this._config || !this.hass) { - return; - } - const target = ev.target! as EditorTarget; - const value = ev.detail?.value ?? target.value; - - if (this[`_${target.configValue}`] === value) { - return; - } - if (target.configValue) { - if (value !== false && !value) { - this._config = { ...this._config }; - delete this._config[target.configValue!]; - } else { - this._config = { - ...this._config, - [target.configValue!]: value, - }; - } - } - fireEvent(this, "config-changed", { config: this._config }); + fireEvent(this, "config-changed", { config: ev.detail.value }); } - static get styles(): CSSResultGroup { - return [ - configElementStyle, - css` - ha-textfield { - display: block; - margin-bottom: 8px; - } - `, - ]; - } + private _computeLabelCallback = (schema: SchemaUnion) => { + switch (schema.name) { + case "theme": + return `${this.hass!.localize( + "ui.panel.lovelace.editor.card.generic.theme" + )} (${this.hass!.localize( + "ui.panel.lovelace.editor.card.config.optional" + )})`; + default: + return ( + this.hass!.localize( + `ui.panel.lovelace.editor.card.picture-card.${schema.name}` + ) || + this.hass!.localize( + `ui.panel.lovelace.editor.card.generic.${schema.name}` + ) + ); + } + }; } declare global { diff --git a/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts index 76c0634698..c6c3d12146 100644 --- a/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-picture-glance-card-editor.ts @@ -22,6 +22,7 @@ const cardConfigStruct = assign( title: optional(string()), entity: optional(string()), image: optional(string()), + image_entity: optional(string()), camera_image: optional(string()), camera_view: optional(string()), aspect_ratio: optional(string()), @@ -35,6 +36,7 @@ const cardConfigStruct = assign( const SCHEMA = [ { name: "title", selector: { text: {} } }, { name: "image", selector: { text: {} } }, + { name: "image_entity", selector: { entity: { domain: "image" } } }, { name: "camera_image", selector: { entity: { domain: "camera" } } }, { name: "", diff --git a/src/panels/lovelace/elements/hui-image-element.ts b/src/panels/lovelace/elements/hui-image-element.ts index e54e23fb68..e86058a183 100644 --- a/src/panels/lovelace/elements/hui-image-element.ts +++ b/src/panels/lovelace/elements/hui-image-element.ts @@ -1,6 +1,7 @@ import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; +import { ImageEntity, computeImageUrl } from "../../../data/image"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { computeTooltip } from "../common/compute-tooltip"; @@ -34,12 +35,16 @@ export class HuiImageElement extends LitElement implements LovelaceElement { if (!this._config || !this.hass) { return nothing; } + let stateObj: ImageEntity | undefined; + if (this._config.image_entity) { + stateObj = this.hass.states[this._config.image_entity] as ImageEntity; + } return html` Date: Thu, 22 Jun 2023 10:55:39 +0200 Subject: [PATCH 090/162] Simplify usage on clipboard for automations and scripts (#16989) --- src/data/automation.ts | 2 +- .../action/ha-automation-action-row.ts | 32 +++++++++++++------ .../automation/action/ha-automation-action.ts | 18 +++++++---- .../types/ha-automation-action-choose.ts | 13 +++----- .../types/ha-automation-action-condition.ts | 5 +-- .../action/types/ha-automation-action-if.ts | 8 +---- .../types/ha-automation-action-parallel.ts | 6 +--- .../types/ha-automation-action-repeat.ts | 8 +---- .../ha-automation-action-wait_for_trigger.ts | 14 +++----- .../ha-automation-condition-editor.ts | 5 +-- .../condition/ha-automation-condition-row.ts | 28 ++++++++++++---- .../condition/ha-automation-condition.ts | 27 +++++++++++----- .../types/ha-automation-condition-logical.ts | 8 +---- .../config/automation/ha-automation-editor.ts | 12 ++----- .../automation/manual-automation-editor.ts | 22 ------------- .../trigger/ha-automation-trigger-row.ts | 27 +++++++++++++--- .../trigger/ha-automation-trigger.ts | 17 +++++++--- .../config/script/manual-script-editor.ts | 18 ----------- 18 files changed, 127 insertions(+), 143 deletions(-) diff --git a/src/data/automation.ts b/src/data/automation.ts index 6ff6eca45f..3bb0dfff66 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -387,7 +387,7 @@ export const testCondition = ( variables, }); -export type Clipboard = { +export type AutomationClipboard = { trigger?: Trigger; condition?: Condition; action?: Action; diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts index 242fd3173f..b601f9906e 100644 --- a/src/panels/config/automation/action/ha-automation-action-row.ts +++ b/src/panels/config/automation/action/ha-automation-action-row.ts @@ -3,9 +3,9 @@ import "@material/mwc-list/mwc-list-item"; import { mdiAlertCircleCheck, mdiCheck, - mdiContentDuplicate, mdiContentCopy, mdiContentCut, + mdiContentDuplicate, mdiDelete, mdiDotsVertical, mdiPlay, @@ -14,17 +14,19 @@ import { mdiSort, mdiStopCircleOutline, } from "@mdi/js"; +import deepClone from "deep-clone-simple"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, + css, + html, + nothing, } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; +import { storage } from "../../../../common/decorators/storage"; import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../common/dom/fire_event"; import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter"; @@ -36,12 +38,12 @@ import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-icon-button"; import type { HaYamlEditor } from "../../../../components/ha-yaml-editor"; import { ACTION_TYPES, YAML_ONLY_ACTION_TYPES } from "../../../../data/action"; +import { AutomationClipboard } from "../../../../data/automation"; import { validateConfig } from "../../../../data/config"; import { EntityRegistryEntry, subscribeEntityRegistry, } from "../../../../data/entity_registry"; -import { Clipboard } from "../../../../data/automation"; import { Action, NonConditionAction, @@ -127,7 +129,13 @@ export default class HaAutomationActionRow extends LitElement { @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; + @storage({ + key: "automationClipboard", + state: false, + subscribe: true, + storage: "sessionStorage", + }) + public _clipboard?: AutomationClipboard; @state() private _entityReg: EntityRegistryEntry[] = []; @@ -396,7 +404,6 @@ export default class HaAutomationActionRow extends LitElement { narrow: this.narrow, reOrderMode: this.reOrderMode, disabled: this.disabled, - clipboard: this.clipboard, })}
`} @@ -431,10 +438,10 @@ export default class HaAutomationActionRow extends LitElement { fireEvent(this, "duplicate"); break; case 4: - fireEvent(this, "set-clipboard", { action: this.action }); + this._setClipboard(); break; case 5: - fireEvent(this, "set-clipboard", { action: this.action }); + this._setClipboard(); fireEvent(this, "value-changed", { value: null }); break; case 6: @@ -454,6 +461,13 @@ export default class HaAutomationActionRow extends LitElement { } } + private _setClipboard() { + this._clipboard = { + ...this._clipboard, + action: deepClone(this.action), + }; + } + private _onDisable() { const enabled = !(this.action.enabled ?? true); const value = { ...this.action, enabled }; diff --git a/src/panels/config/automation/action/ha-automation-action.ts b/src/panels/config/automation/action/ha-automation-action.ts index 91a6df75ae..dd9d2ad909 100644 --- a/src/panels/config/automation/action/ha-automation-action.ts +++ b/src/panels/config/automation/action/ha-automation-action.ts @@ -29,7 +29,7 @@ import type { HaSelect } from "../../../../components/ha-select"; import "../../../../components/ha-svg-icon"; import { ACTION_TYPES } from "../../../../data/action"; import { Action } from "../../../../data/script"; -import { Clipboard } from "../../../../data/automation"; +import { AutomationClipboard } from "../../../../data/automation"; import { sortableStyles } from "../../../../resources/ha-sortable-style"; import { loadSortable, @@ -52,6 +52,7 @@ import "./types/ha-automation-action-service"; import "./types/ha-automation-action-stop"; import "./types/ha-automation-action-wait_for_trigger"; import "./types/ha-automation-action-wait_template"; +import { storage } from "../../../../common/decorators/storage"; const PASTE_VALUE = "__paste__"; @@ -69,7 +70,13 @@ export default class HaAutomationAction extends LitElement { @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; + @storage({ + key: "automationClipboard", + state: true, + subscribe: true, + storage: "sessionStorage", + }) + public _clipboard?: AutomationClipboard; private _focusLastActionOnChange = false; @@ -113,7 +120,6 @@ export default class HaAutomationAction extends LitElement { @duplicate=${this._duplicateAction} @value-changed=${this._actionChanged} @re-order=${this._enterReOrderMode} - .clipboard=${this.clipboard} .hass=${this.hass} > ${this.reOrderMode @@ -162,14 +168,14 @@ export default class HaAutomationAction extends LitElement { > - ${this.clipboard?.action + ${this._clipboard?.action ? html` ${this.hass.localize( "ui.panel.config.automation.editor.actions.paste" )} (${this.hass.localize( `ui.panel.config.automation.editor.actions.type.${getType( - this.clipboard.action + this._clipboard.action )}.label` )})

${this.hass.localize( @@ -80,7 +77,6 @@ export class HaChooseAction extends LitElement implements ActionElement { .hass=${this.hass} .idx=${idx} @value-changed=${this._actionChanged} - .clipboard=${this.clipboard} >

` @@ -109,7 +105,6 @@ export class HaChooseAction extends LitElement implements ActionElement { .disabled=${this.disabled} @value-changed=${this._defaultChanged} .hass=${this.hass} - .clipboard=${this.clipboard} > ` : html` @@ -114,7 +109,6 @@ export class HaRepeatAction extends LitElement implements ActionElement { .reOrderMode=${this.reOrderMode} .disabled=${this.disabled} @value-changed=${this._actionChanged} - .clipboard=${this.clipboard} .hass=${this.hass} > `; diff --git a/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts b/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts index d5c21b5989..b6bd373831 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-wait_for_trigger.ts @@ -1,17 +1,16 @@ -import "../../../../../components/ha-textfield"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; +import { ensureArray } from "../../../../../common/array/ensure-array"; +import { createDurationData } from "../../../../../common/datetime/create_duration_data"; import { fireEvent } from "../../../../../common/dom/fire_event"; +import { TimeChangedEvent } from "../../../../../components/ha-base-time-input"; +import "../../../../../components/ha-duration-input"; import "../../../../../components/ha-formfield"; +import "../../../../../components/ha-textfield"; import { WaitForTriggerAction } from "../../../../../data/script"; -import type { Clipboard } from "../../../../../data/automation"; import { HomeAssistant } from "../../../../../types"; import "../../trigger/ha-automation-trigger"; import { ActionElement, handleChangeEvent } from "../ha-automation-action-row"; -import "../../../../../components/ha-duration-input"; -import { createDurationData } from "../../../../../common/datetime/create_duration_data"; -import { TimeChangedEvent } from "../../../../../components/ha-base-time-input"; -import { ensureArray } from "../../../../../common/array/ensure-array"; @customElement("ha-automation-action-wait_for_trigger") export class HaWaitForTriggerAction @@ -26,8 +25,6 @@ export class HaWaitForTriggerAction @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; - public static get defaultConfig() { return { wait_for_trigger: [] }; } @@ -65,7 +62,6 @@ export class HaWaitForTriggerAction .name=${"wait_for_trigger"} .reOrderMode=${this.reOrderMode} @value-changed=${this._valueChanged} - .clipboard=${this.clipboard} > `; } diff --git a/src/panels/config/automation/condition/ha-automation-condition-editor.ts b/src/panels/config/automation/condition/ha-automation-condition-editor.ts index 2adf0512aa..eb4558569e 100644 --- a/src/panels/config/automation/condition/ha-automation-condition-editor.ts +++ b/src/panels/config/automation/condition/ha-automation-condition-editor.ts @@ -4,7 +4,7 @@ import memoizeOne from "memoize-one"; import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-yaml-editor"; -import type { Condition, Clipboard } from "../../../../data/automation"; +import type { Condition } from "../../../../data/automation"; import { expandConditionWithShorthand } from "../../../../data/automation"; import { haStyle } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; @@ -32,8 +32,6 @@ export default class HaAutomationConditionEditor extends LitElement { @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; - private _processedCondition = memoizeOne((condition) => expandConditionWithShorthand(condition) ); @@ -72,7 +70,6 @@ export default class HaAutomationConditionEditor extends LitElement { condition: condition, reOrderMode: this.reOrderMode, disabled: this.disabled, - clipboard: this.clipboard, } )}
diff --git a/src/panels/config/automation/condition/ha-automation-condition-row.ts b/src/panels/config/automation/condition/ha-automation-condition-row.ts index 8f6cd63441..7e8bb4e270 100644 --- a/src/panels/config/automation/condition/ha-automation-condition-row.ts +++ b/src/panels/config/automation/condition/ha-automation-condition-row.ts @@ -3,9 +3,9 @@ import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiCheck, - mdiContentDuplicate, mdiContentCopy, mdiContentCut, + mdiContentDuplicate, mdiDelete, mdiDotsVertical, mdiFlask, @@ -14,9 +14,11 @@ import { mdiSort, mdiStopCircleOutline, } from "@mdi/js"; -import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import deepClone from "deep-clone-simple"; +import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; +import { storage } from "../../../../common/decorators/storage"; import { fireEvent } from "../../../../common/dom/fire_event"; import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter"; import { handleStructError } from "../../../../common/structs/handle-errors"; @@ -24,8 +26,8 @@ import "../../../../components/ha-button-menu"; import "../../../../components/ha-card"; import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-icon-button"; +import type { AutomationClipboard } from "../../../../data/automation"; import { Condition, testCondition } from "../../../../data/automation"; -import type { Clipboard } from "../../../../data/automation"; import { describeCondition } from "../../../../data/automation_i18n"; import { CONDITION_TYPES } from "../../../../data/condition"; import { validateConfig } from "../../../../data/config"; @@ -83,7 +85,13 @@ export default class HaAutomationConditionRow extends LitElement { @property({ type: Boolean }) public disabled = false; - @property() public clipboard?: Clipboard; + @storage({ + key: "automationClipboard", + state: false, + subscribe: true, + storage: "sessionStorage", + }) + public _clipboard?: AutomationClipboard; @state() private _yamlMode = false; @@ -290,7 +298,6 @@ export default class HaAutomationConditionRow extends LitElement { .hass=${this.hass} .condition=${this.condition} .reOrderMode=${this.reOrderMode} - .clipboard=${this.clipboard} >
@@ -343,10 +350,10 @@ export default class HaAutomationConditionRow extends LitElement { fireEvent(this, "duplicate"); break; case 4: - fireEvent(this, "set-clipboard", { condition: this.condition }); + this._setClipboard(); break; case 5: - fireEvent(this, "set-clipboard", { condition: this.condition }); + this._setClipboard(); fireEvent(this, "value-changed", { value: null }); break; case 6: @@ -366,6 +373,13 @@ export default class HaAutomationConditionRow extends LitElement { } } + private _setClipboard() { + this._clipboard = { + ...this._clipboard, + condition: deepClone(this.condition), + }; + } + private _onDisable() { const enabled = !(this.condition.enabled ?? true); const value = { ...this.condition, enabled }; diff --git a/src/panels/config/automation/condition/ha-automation-condition.ts b/src/panels/config/automation/condition/ha-automation-condition.ts index 3b64474463..8ee6552bae 100644 --- a/src/panels/config/automation/condition/ha-automation-condition.ts +++ b/src/panels/config/automation/condition/ha-automation-condition.ts @@ -3,9 +3,9 @@ import type { ActionDetail } from "@material/mwc-list"; import { mdiArrowDown, mdiArrowUp, + mdiContentPaste, mdiDrag, mdiPlus, - mdiContentPaste, } from "@mdi/js"; import deepClone from "deep-clone-simple"; import { @@ -13,8 +13,8 @@ import { CSSResultGroup, html, LitElement, - PropertyValues, nothing, + PropertyValues, } from "lit"; import { customElement, property } from "lit/decorators"; import { repeat } from "lit/directives/repeat"; @@ -24,7 +24,10 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-button"; import "../../../../components/ha-button-menu"; import "../../../../components/ha-svg-icon"; -import type { Condition, Clipboard } from "../../../../data/automation"; +import type { + AutomationClipboard, + Condition, +} from "../../../../data/automation"; import type { HomeAssistant } from "../../../../types"; import "./ha-automation-condition-row"; import type HaAutomationConditionRow from "./ha-automation-condition-row"; @@ -49,6 +52,7 @@ import "./types/ha-automation-condition-template"; import "./types/ha-automation-condition-time"; import "./types/ha-automation-condition-trigger"; import "./types/ha-automation-condition-zone"; +import { storage } from "../../../../common/decorators/storage"; const PASTE_VALUE = "__paste__"; @@ -64,7 +68,13 @@ export default class HaAutomationCondition extends LitElement { @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; + @storage({ + key: "automationClipboard", + state: true, + subscribe: true, + storage: "sessionStorage", + }) + public _clipboard?: AutomationClipboard; private _focusLastConditionOnChange = false; @@ -157,7 +167,6 @@ export default class HaAutomationCondition extends LitElement { @move-condition=${this._move} @value-changed=${this._conditionChanged} @re-order=${this._enterReOrderMode} - .clipboard=${this.clipboard} .hass=${this.hass} > ${this.reOrderMode @@ -206,13 +215,13 @@ export default class HaAutomationCondition extends LitElement { > - ${this.clipboard?.condition + ${this._clipboard?.condition ? html` ${this.hass.localize( "ui.panel.config.automation.editor.conditions.paste" )} (${this.hass.localize( - `ui.panel.config.automation.editor.conditions.type.${this.clipboard.condition.condition}.label` + `ui.panel.config.automation.editor.conditions.type.${this._clipboard.condition.condition}.label` )}) ` @@ -281,7 +290,9 @@ export default class HaAutomationCondition extends LitElement { let conditions: Condition[]; if (value === PASTE_VALUE) { - conditions = this.conditions.concat(deepClone(this.clipboard!.condition)); + conditions = this.conditions.concat( + deepClone(this._clipboard!.condition) + ); } else { const condition = value as Condition["condition"]; diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts b/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts index 527e2b7234..a7aa3fb9a6 100644 --- a/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts +++ b/src/panels/config/automation/condition/types/ha-automation-condition-logical.ts @@ -1,10 +1,7 @@ import { html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../../../common/dom/fire_event"; -import type { - LogicalCondition, - Clipboard, -} from "../../../../../data/automation"; +import type { LogicalCondition } from "../../../../../data/automation"; import type { HomeAssistant } from "../../../../../types"; import "../ha-automation-condition"; import type { ConditionElement } from "../ha-automation-condition-row"; @@ -19,8 +16,6 @@ export class HaLogicalCondition extends LitElement implements ConditionElement { @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; - public static get defaultConfig() { return { conditions: [], @@ -35,7 +30,6 @@ export class HaLogicalCondition extends LitElement implements ConditionElement { @value-changed=${this._valueChanged} .hass=${this.hass} .disabled=${this.disabled} - .clipboard=${this.clipboard} .reOrderMode=${this.reOrderMode} > `; diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 3aa074c345..ecc97fb23d 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -16,12 +16,12 @@ import { } from "@mdi/js"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, TemplateResult, + css, + html, } from "lit"; import { property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -46,10 +46,7 @@ import { saveAutomationConfig, showAutomationEditor, triggerAutomationActions, - Trigger, - Condition, } from "../../../data/automation"; -import { Action } from "../../../data/script"; import { fetchEntityRegistry } from "../../../data/entity_registry"; import { showAlertDialog, @@ -79,11 +76,6 @@ declare global { "ui-mode-not-available": Error; duplicate: undefined; "re-order": undefined; - "set-clipboard": { - trigger?: Trigger; - condition?: Condition; - action?: Action; - }; } } diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index c8cf4fa69b..e0417269b6 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -3,7 +3,6 @@ import { mdiHelpCircle } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; -import deepClone from "deep-clone-simple"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; @@ -11,7 +10,6 @@ import { Condition, ManualAutomationConfig, Trigger, - Clipboard, } from "../../../data/automation"; import { Action } from "../../../data/script"; import { haStyle } from "../../../resources/styles"; @@ -20,7 +18,6 @@ import { documentationUrl } from "../../../util/documentation-url"; import "./action/ha-automation-action"; import "./condition/ha-automation-condition"; import "./trigger/ha-automation-trigger"; -import { storage } from "../../../common/decorators/storage"; @customElement("manual-automation-editor") export class HaManualAutomationEditor extends LitElement { @@ -36,14 +33,6 @@ export class HaManualAutomationEditor extends LitElement { @property({ attribute: false }) public stateObj?: HassEntity; - @storage({ - key: "automationClipboard", - state: true, - subscribe: false, - storage: "sessionStorage", - }) - private _clipboard: Clipboard = {}; - protected render() { return html` ${this.disabled @@ -102,8 +91,6 @@ export class HaManualAutomationEditor extends LitElement { @value-changed=${this._triggerChanged} .hass=${this.hass} .disabled=${this.disabled} - @set-clipboard=${this._setClipboard} - .clipboard=${this._clipboard} >
@@ -133,8 +120,6 @@ export class HaManualAutomationEditor extends LitElement { @value-changed=${this._conditionChanged} .hass=${this.hass} .disabled=${this.disabled} - @set-clipboard=${this._setClipboard} - .clipboard=${this._clipboard} >
@@ -167,8 +152,6 @@ export class HaManualAutomationEditor extends LitElement { .hass=${this.hass} .narrow=${this.narrow} .disabled=${this.disabled} - @set-clipboard=${this._setClipboard} - .clipboard=${this._clipboard} > `; } @@ -180,11 +163,6 @@ export class HaManualAutomationEditor extends LitElement { }); } - private _setClipboard(ev: CustomEvent): void { - ev.stopPropagation(); - this._clipboard = { ...this._clipboard, ...deepClone(ev.detail) }; - } - private _conditionChanged(ev: CustomEvent): void { ev.stopPropagation(); fireEvent(this, "value-changed", { diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index fc8ce54e79..4719bc4074 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -3,9 +3,9 @@ import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiCheck, - mdiContentDuplicate, mdiContentCopy, mdiContentCut, + mdiContentDuplicate, mdiDelete, mdiDotsVertical, mdiIdentifier, @@ -15,9 +15,10 @@ import { mdiStopCircleOutline, } from "@mdi/js"; import type { UnsubscribeFunc } from "home-assistant-js-websocket"; -import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; +import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; +import { storage } from "../../../../common/decorators/storage"; import { dynamicElement } from "../../../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../../../common/dom/fire_event"; import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter"; @@ -30,7 +31,8 @@ import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-icon-button"; import "../../../../components/ha-textfield"; import { HaYamlEditor } from "../../../../components/ha-yaml-editor"; -import { subscribeTrigger, Trigger } from "../../../../data/automation"; +import type { AutomationClipboard } from "../../../../data/automation"; +import { Trigger, subscribeTrigger } from "../../../../data/automation"; import { describeTrigger } from "../../../../data/automation_i18n"; import { validateConfig } from "../../../../data/config"; import { fullEntitiesContext } from "../../../../data/context"; @@ -110,6 +112,14 @@ export default class HaAutomationTriggerRow extends LitElement { @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; + @storage({ + key: "automationClipboard", + state: false, + subscribe: true, + storage: "sessionStorage", + }) + public _clipboard?: AutomationClipboard; + @state() @consume({ context: fullEntitiesContext, subscribe: true }) _entityReg!: EntityRegistryEntry[]; @@ -469,10 +479,10 @@ export default class HaAutomationTriggerRow extends LitElement { fireEvent(this, "duplicate"); break; case 4: - fireEvent(this, "set-clipboard", { trigger: this.trigger }); + this._setClipboard(); break; case 5: - fireEvent(this, "set-clipboard", { trigger: this.trigger }); + this._setClipboard(); fireEvent(this, "value-changed", { value: null }); break; case 6: @@ -492,6 +502,13 @@ export default class HaAutomationTriggerRow extends LitElement { } } + private _setClipboard() { + this._clipboard = { + ...this._clipboard, + trigger: this.trigger, + }; + } + private _onDelete() { showConfirmationDialog(this, { title: this.hass.localize( diff --git a/src/panels/config/automation/trigger/ha-automation-trigger.ts b/src/panels/config/automation/trigger/ha-automation-trigger.ts index d30e42ba98..fbe0539f8d 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger.ts @@ -27,7 +27,7 @@ import "../../../../components/ha-button-menu"; import "../../../../components/ha-button"; import type { HaSelect } from "../../../../components/ha-select"; import "../../../../components/ha-svg-icon"; -import { Trigger, Clipboard } from "../../../../data/automation"; +import { Trigger, AutomationClipboard } from "../../../../data/automation"; import { TRIGGER_TYPES } from "../../../../data/trigger"; import { sortableStyles } from "../../../../resources/ha-sortable-style"; import { SortableInstance } from "../../../../resources/sortable"; @@ -51,6 +51,7 @@ import "./types/ha-automation-trigger-time"; import "./types/ha-automation-trigger-time_pattern"; import "./types/ha-automation-trigger-webhook"; import "./types/ha-automation-trigger-zone"; +import { storage } from "../../../../common/decorators/storage"; const PASTE_VALUE = "__paste__"; @@ -66,7 +67,13 @@ export default class HaAutomationTrigger extends LitElement { @property({ type: Boolean }) public reOrderMode = false; - @property() public clipboard?: Clipboard; + @storage({ + key: "automationClipboard", + state: true, + subscribe: true, + storage: "sessionStorage", + }) + public _clipboard?: AutomationClipboard; private _focusLastTriggerOnChange = false; @@ -155,13 +162,13 @@ export default class HaAutomationTrigger extends LitElement { > - ${this.clipboard?.trigger + ${this._clipboard?.trigger ? html` ${this.hass.localize( "ui.panel.config.automation.editor.triggers.paste" )} (${this.hass.localize( - `ui.panel.config.automation.editor.triggers.type.${this.clipboard.trigger.platform}.label` + `ui.panel.config.automation.editor.triggers.type.${this._clipboard.trigger.platform}.label` )}) `; } @@ -83,11 +70,6 @@ export class HaManualScriptEditor extends LitElement { }); } - private _setClipboard(ev: CustomEvent): void { - ev.stopPropagation(); - this._clipboard = { ...this._clipboard, ...deepClone(ev.detail) }; - } - private _duplicate() { fireEvent(this, "duplicate"); } From b748fee3218421cb67f2e2d1ea7681b9f821db6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Thu, 22 Jun 2023 10:58:26 +0200 Subject: [PATCH 091/162] Allow selecting CIFS version in mount dialog (#16833) --- src/components/ha-form/ha-form.ts | 20 +++++ src/data/supervisor/mounts.ts | 4 + .../config/storage/dialog-mount-view.ts | 76 ++++++++++++++++++- src/translations/en.json | 11 +++ 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/src/components/ha-form/ha-form.ts b/src/components/ha-form/ha-form.ts index 3062c2317d..98c177f482 100644 --- a/src/components/ha-form/ha-form.ts +++ b/src/components/ha-form/ha-form.ts @@ -34,6 +34,8 @@ const getValue = (obj, item) => const getError = (obj, item) => (obj && item.name ? obj[item.name] : null); +const getWarning = (obj, item) => (obj && item.name ? obj[item.name] : null); + @customElement("ha-form") export class HaForm extends LitElement implements HaFormElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -44,10 +46,14 @@ export class HaForm extends LitElement implements HaFormElement { @property() public error?: Record; + @property() public warning?: Record; + @property({ type: Boolean }) public disabled = false; @property() public computeError?: (schema: any, error) => string; + @property() public computeWarning?: (schema: any, warning) => string; + @property() public computeLabel?: ( schema: any, data: HaFormDataContainer @@ -98,6 +104,7 @@ export class HaForm extends LitElement implements HaFormElement { : ""} ${this.schema.map((item) => { const error = getError(this.error, item); + const warning = getWarning(this.warning, item); return html` ${error @@ -106,6 +113,12 @@ export class HaForm extends LitElement implements HaFormElement { ${this._computeError(error, item)} ` + : warning + ? html` + + ${this._computeWarning(warning, item)} + + ` : ""} ${"selector" in item ? html` * { diff --git a/src/data/supervisor/mounts.ts b/src/data/supervisor/mounts.ts index 474991fd93..ea4fc8da6f 100644 --- a/src/data/supervisor/mounts.ts +++ b/src/data/supervisor/mounts.ts @@ -22,6 +22,8 @@ interface MountOptions { default_backup_mount?: string | null; } +export type CIFSVersion = "auto" | "1.0" | "2.0"; + interface SupervisorMountBase { name: string; usage: SupervisorMountUsage; @@ -42,6 +44,7 @@ export interface SupervisorNFSMount extends SupervisorMountResponse { export interface SupervisorCIFSMount extends SupervisorMountResponse { type: SupervisorMountType.CIFS; share: string; + version?: CIFSVersion; } export type SupervisorMount = SupervisorNFSMount | SupervisorCIFSMount; @@ -51,6 +54,7 @@ export type SupervisorNFSMountRequestParams = SupervisorNFSMount; export interface SupervisorCIFSMountRequestParams extends SupervisorCIFSMount { username?: string; password?: string; + version?: CIFSVersion; } export type SupervisorMountRequestParams = diff --git a/src/panels/config/storage/dialog-mount-view.ts b/src/panels/config/storage/dialog-mount-view.ts index 52592a9b67..e0b0b6302d 100644 --- a/src/panels/config/storage/dialog-mount-view.ts +++ b/src/panels/config/storage/dialog-mount-view.ts @@ -26,7 +26,8 @@ const mountSchema = memoizeOne( ( localize: LocalizeFunc, existing?: boolean, - mountType?: SupervisorMountType + mountType?: SupervisorMountType, + showCIFSVersion?: boolean ) => [ { @@ -90,6 +91,41 @@ const mountSchema = memoizeOne( ] as const) : mountType === "cifs" ? ([ + ...(showCIFSVersion + ? ([ + { + name: "version", + required: true, + selector: { + select: { + options: [ + { + label: localize( + "ui.panel.config.storage.network_mounts.cifs_versions.auto" + ), + value: "auto", + }, + { + label: localize( + "ui.panel.config.storage.network_mounts.cifs_versions.legacy", + { version: "2.0" } + ), + value: "2.0", + }, + { + label: localize( + "ui.panel.config.storage.network_mounts.cifs_versions.legacy", + { version: "1.0" } + ), + value: "1.0", + }, + ], + mode: "dropdown", + }, + }, + }, + ] as const) + : ([] as const)), { name: "share", required: true, @@ -122,8 +158,12 @@ class ViewMountDialog extends LitElement { @state() private _validationError?: Record; + @state() private _validationWarning?: Record; + @state() private _existing?: boolean; + @state() private _showCIFSVersion?: boolean; + @state() private _reloadMounts?: () => void; public async showDialog( @@ -132,6 +172,13 @@ class ViewMountDialog extends LitElement { this._data = dialogParams.mount; this._existing = dialogParams.mount !== undefined; this._reloadMounts = dialogParams.reloadMounts; + if ( + dialogParams.mount?.type === "cifs" && + dialogParams.mount.version && + dialogParams.mount.version !== "auto" + ) { + this._showCIFSVersion = true; + } } public closeDialog(): void { @@ -139,7 +186,9 @@ class ViewMountDialog extends LitElement { this._waiting = undefined; this._error = undefined; this._validationError = undefined; + this._validationWarning = undefined; this._existing = undefined; + this._showCIFSVersion = undefined; this._reloadMounts = undefined; fireEvent(this, "dialog-closed", { dialog: this.localName }); } @@ -197,12 +246,15 @@ class ViewMountDialog extends LitElement { .schema=${mountSchema( this.hass.localize, this._existing, - this._data?.type + this._data?.type, + this._showCIFSVersion )} .error=${this._validationError} + .warning=${this._validationWarning} .computeLabel=${this._computeLabelCallback} .computeHelper=${this._computeHelperCallback} .computeError=${this._computeErrorCallback} + .computeWarning=${this._computeWarningCallback} @value-changed=${this._valueChanged} dialogInitialFocus > @@ -256,12 +308,29 @@ class ViewMountDialog extends LitElement { `ui.panel.config.storage.network_mounts.errors.${error}` ) || error; + private _computeWarningCallback = (warning: string): string => + this.hass.localize( + // @ts-ignore + `ui.panel.config.storage.network_mounts.warnings.${warning}` + ) || warning; + private _valueChanged(ev: CustomEvent) { this._validationError = {}; + this._validationWarning = {}; this._data = ev.detail.value; if (this._data?.name && !/^\w+$/.test(this._data.name)) { this._validationError.name = "invalid_name"; } + if (this._data?.type === "cifs" && !this._data.version) { + this._data.version = "auto"; + } + if ( + this._data?.type === "cifs" && + this._data.version && + ["1.0", "2.0"].includes(this._data.version) + ) { + this._validationWarning.version = "not_recomeded_cifs_version"; + } } private async _connectMount() { @@ -276,6 +345,9 @@ class ViewMountDialog extends LitElement { } catch (err: any) { this._error = extractApiErrorMessage(err); this._waiting = false; + if (this._data!.type === "cifs" && !this._showCIFSVersion) { + this._showCIFSVersion = true; + } return; } if (this._reloadMounts) { diff --git a/src/translations/en.json b/src/translations/en.json index 6e3b200d7f..6a4f63360d 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4131,6 +4131,10 @@ "nfs": "Network File Share (NFS)", "cifs": "Samba/Windows (CIFS)" }, + "cifs_versions": { + "auto": "Auto (2.1+)", + "legacy": "Legacy ({version})" + }, "options": { "name": { "title": "Name", @@ -4160,6 +4164,10 @@ "title": "Usage", "description": "This determines how the share is intended to be used" }, + "version": { + "title": "Samba/Windows (CIFS) version", + "description": "This choses the version of the protocol to use" + }, "username": { "title": "Username", "description": "This is your username for the samba share" @@ -4174,6 +4182,9 @@ "errors": { "reload": "Could not reload mount {mount}", "invalid_name": "Invalid name, can only contain alphanumeric characters and underscores" + }, + "warnings": { + "not_recomeded_cifs_version": "The selected CIFS version is not recommended to use, you should only use this if you have problems with auto and your server does not support version 2.1 or newer" } } }, From 80c57fa326085610f29c9a16021ec4b27ebdcb53 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 22 Jun 2023 11:09:02 +0200 Subject: [PATCH 092/162] Don't allow to change the domain in entity registry settings (#16800) --- src/components/ha-textfield.ts | 3 ++ .../entity-registry-settings-editor.ts | 45 ++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/components/ha-textfield.ts b/src/components/ha-textfield.ts index c18b49c2d4..289b37924c 100644 --- a/src/components/ha-textfield.ts +++ b/src/components/ha-textfield.ts @@ -160,6 +160,9 @@ export class HaTextField extends TextFieldBase { .mdc-text-field__input[type="number"] { direction: var(--direction); } + .mdc-text-field__affix--prefix { + padding-right: var(--text-field-prefix-padding-right, 2px); + } `, // safari workaround - must be explicit document.dir === "rtl" diff --git a/src/panels/config/entities/entity-registry-settings-editor.ts b/src/panels/config/entities/entity-registry-settings-editor.ts index 84764efc74..a1ce59f5ef 100644 --- a/src/panels/config/entities/entity-registry-settings-editor.ts +++ b/src/panels/config/entities/entity-registry-settings-editor.ts @@ -11,10 +11,12 @@ import { } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; +import { mdiContentCopy } from "@mdi/js"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { fireEvent } from "../../../common/dom/fire_event"; import { stopPropagation } from "../../../common/dom/stop_propagation"; import { computeDomain } from "../../../common/entity/compute_domain"; +import { computeObjectId } from "../../../common/entity/compute_object_id"; import { domainIcon } from "../../../common/entity/domain_icon"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { formatNumber } from "../../../common/number/format_number"; @@ -79,6 +81,8 @@ import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info import { haStyle } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { showDeviceRegistryDetailDialog } from "../devices/device-registry-detail/show-dialog-device-registry-detail"; +import { copyToClipboard } from "../../../common/util/copy-clipboard"; +import { showToast } from "../../../util/toast"; const OVERRIDE_DEVICE_CLASSES = { cover: [ @@ -325,8 +329,6 @@ export class EntityRegistrySettingsEditor extends LitElement { const domain = computeDomain(this.entry.entity_id); - const invalidDomainUpdate = computeDomain(this._entityId.trim()) !== domain; - const invalidDefaultCode = domain === "lock" && this._isInvalidDefaultCode( @@ -675,15 +677,23 @@ export class EntityRegistrySettingsEditor extends LitElement { ` : ""} + iconTrailing + > + + ${!this.entry.device_id ? html` { + await copyToClipboard(this._entityId); + showToast(this, { + message: this.hass.localize("ui.common.copied_clipboard"), + }); + } + private _entityIdChanged(ev): void { fireEvent(this, "change"); - this._entityId = ev.target.value; + this._entityId = `${computeDomain(this._origEntityId)}.${ev.target.value}`; } private _deviceClassChanged(ev): void { @@ -1343,6 +1360,20 @@ export class EntityRegistrySettingsEditor extends LitElement { :host { display: block; } + ha-textfield.entityId { + --text-field-prefix-padding-right: 0; + --textfield-icon-trailing-padding: 0; + } + ha-textfield.entityId > ha-icon-button { + position: relative; + right: -8px; + --mdc-icon-button-size: 36px; + --mdc-icon-size: 20px; + color: var(--secondary-text-color); + inset-inline-start: initial; + inset-inline-end: -8px; + direction: var(--direction); + } ha-switch { margin-right: 16px; } From b3fa134198f8d44d8dd1885d37740550303812a3 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 22 Jun 2023 11:53:06 +0200 Subject: [PATCH 093/162] Add haStyleScrollbar to hass-tabs-subpage (#16993) --- src/layouts/hass-tabs-subpage.ts | 258 ++++++++++++++++--------------- 1 file changed, 131 insertions(+), 127 deletions(-) diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index 08da982715..bbc978fd7d 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -19,6 +19,7 @@ import "../components/ha-menu-button"; import "../components/ha-svg-icon"; import "../components/ha-tab"; import { HomeAssistant, Route } from "../types"; +import { haStyleScrollbar } from "../resources/styles"; export interface PageNavigation { path: string; @@ -186,7 +187,7 @@ class HassTabsSubpage extends LitElement {
@@ -211,143 +212,146 @@ class HassTabsSubpage extends LitElement { } static get styles(): CSSResultGroup { - return css` - :host { - display: block; - height: 100%; - background-color: var(--primary-background-color); - } - - :host([narrow]) { - width: 100%; - position: fixed; - } - - ha-menu-button { - margin-right: 24px; - } - - .toolbar { - display: flex; - align-items: center; - font-size: 20px; - height: var(--header-height); - background-color: var(--sidebar-background-color); - font-weight: 400; - border-bottom: 1px solid var(--divider-color); - padding: 8px 12px; - box-sizing: border-box; - } - @media (max-width: 599px) { - .toolbar { - padding: 4px; + return [ + haStyleScrollbar, + css` + :host { + display: block; + height: 100%; + background-color: var(--primary-background-color); } - } - .toolbar a { - color: var(--sidebar-text-color); - text-decoration: none; - } - .bottom-bar a { - width: 25%; - } - #tabbar { - display: flex; - font-size: 14px; - overflow: hidden; - } + :host([narrow]) { + width: 100%; + position: fixed; + } - #tabbar > a { - overflow: hidden; - max-width: 45%; - } + ha-menu-button { + margin-right: 24px; + } - #tabbar.bottom-bar { - position: absolute; - bottom: 0; - left: 0; - padding: 0 16px; - box-sizing: border-box; - background-color: var(--sidebar-background-color); - border-top: 1px solid var(--divider-color); - justify-content: space-around; - z-index: 2; - font-size: 12px; - width: 100%; - padding-bottom: env(safe-area-inset-bottom); - } + .toolbar { + display: flex; + align-items: center; + font-size: 20px; + height: var(--header-height); + background-color: var(--sidebar-background-color); + font-weight: 400; + border-bottom: 1px solid var(--divider-color); + padding: 8px 12px; + box-sizing: border-box; + } + @media (max-width: 599px) { + .toolbar { + padding: 4px; + } + } + .toolbar a { + color: var(--sidebar-text-color); + text-decoration: none; + } + .bottom-bar a { + width: 25%; + } - #tabbar:not(.bottom-bar) { - flex: 1; - justify-content: center; - } + #tabbar { + display: flex; + font-size: 14px; + overflow: hidden; + } - :host(:not([narrow])) #toolbar-icon { - min-width: 40px; - } + #tabbar > a { + overflow: hidden; + max-width: 45%; + } - ha-menu-button, - ha-icon-button-arrow-prev, - ::slotted([slot="toolbar-icon"]) { - display: flex; - flex-shrink: 0; - pointer-events: auto; - color: var(--sidebar-icon-color); - } + #tabbar.bottom-bar { + position: absolute; + bottom: 0; + left: 0; + padding: 0 16px; + box-sizing: border-box; + background-color: var(--sidebar-background-color); + border-top: 1px solid var(--divider-color); + justify-content: space-around; + z-index: 2; + font-size: 12px; + width: 100%; + padding-bottom: env(safe-area-inset-bottom); + } - .main-title { - flex: 1; - max-height: var(--header-height); - line-height: 20px; - color: var(--sidebar-text-color); - margin: var(--main-title-margin, 0 0 0 24px); - } + #tabbar:not(.bottom-bar) { + flex: 1; + justify-content: center; + } - .content { - position: relative; - width: calc( - 100% - env(safe-area-inset-left) - env(safe-area-inset-right) - ); - margin-left: env(safe-area-inset-left); - margin-right: env(safe-area-inset-right); - height: calc(100% - 1px - var(--header-height)); - height: calc( - 100% - 1px - var(--header-height) - env(safe-area-inset-bottom) - ); - overflow: auto; - -webkit-overflow-scrolling: touch; - } + :host(:not([narrow])) #toolbar-icon { + min-width: 40px; + } - :host([narrow]) .content.tabs { - height: calc(100% - 2 * var(--header-height)); - height: calc( - 100% - 2 * var(--header-height) - env(safe-area-inset-bottom) - ); - } + ha-menu-button, + ha-icon-button-arrow-prev, + ::slotted([slot="toolbar-icon"]) { + display: flex; + flex-shrink: 0; + pointer-events: auto; + color: var(--sidebar-icon-color); + } - #fab { - position: fixed; - right: calc(16px + env(safe-area-inset-right)); - bottom: calc(16px + env(safe-area-inset-bottom)); - z-index: 1; - } - :host([narrow]) #fab.tabs { - bottom: calc(84px + env(safe-area-inset-bottom)); - } - #fab[is-wide] { - bottom: 24px; - right: 24px; - } - :host([rtl]) #fab { - right: auto; - left: calc(16px + env(safe-area-inset-left)); - } - :host([rtl][is-wide]) #fab { - bottom: 24px; - left: 24px; - right: auto; - } - `; + .main-title { + flex: 1; + max-height: var(--header-height); + line-height: 20px; + color: var(--sidebar-text-color); + margin: var(--main-title-margin, 0 0 0 24px); + } + + .content { + position: relative; + width: calc( + 100% - env(safe-area-inset-left) - env(safe-area-inset-right) + ); + margin-left: env(safe-area-inset-left); + margin-right: env(safe-area-inset-right); + height: calc(100% - 1px - var(--header-height)); + height: calc( + 100% - 1px - var(--header-height) - env(safe-area-inset-bottom) + ); + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + :host([narrow]) .content.tabs { + height: calc(100% - 2 * var(--header-height)); + height: calc( + 100% - 2 * var(--header-height) - env(safe-area-inset-bottom) + ); + } + + #fab { + position: fixed; + right: calc(16px + env(safe-area-inset-right)); + bottom: calc(16px + env(safe-area-inset-bottom)); + z-index: 1; + } + :host([narrow]) #fab.tabs { + bottom: calc(84px + env(safe-area-inset-bottom)); + } + #fab[is-wide] { + bottom: 24px; + right: 24px; + } + :host([rtl]) #fab { + right: auto; + left: calc(16px + env(safe-area-inset-left)); + } + :host([rtl][is-wide]) #fab { + bottom: 24px; + left: 24px; + right: auto; + } + `, + ]; } } From f19dcba1ce911edd696d109f71acd4c23b373b8f Mon Sep 17 00:00:00 2001 From: Petro31 <35082313+Petro31@users.noreply.github.com> Date: Thu, 22 Jun 2023 08:28:07 -0400 Subject: [PATCH 094/162] Update _dismissAll to use persistent_notification.dismiss_all service (#16997) --- src/dialogs/notifications/notification-drawer.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/dialogs/notifications/notification-drawer.ts b/src/dialogs/notifications/notification-drawer.ts index 5b4eacb27e..b11a45a345 100644 --- a/src/dialogs/notifications/notification-drawer.ts +++ b/src/dialogs/notifications/notification-drawer.ts @@ -139,11 +139,7 @@ export class HuiNotificationDrawer extends LitElement { } private _dismissAll() { - this._notifications.forEach((notification) => { - this.hass.callService("persistent_notification", "dismiss", { - notification_id: notification.notification_id, - }); - }); + this.hass.callService("persistent_notification", "dismiss_all"); this.closeDialog(); } From bf18deb83cde79ad84e281ee236af785dc156518 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Jun 2023 00:28:22 +0200 Subject: [PATCH 095/162] Update dependency @rollup/plugin-commonjs to v25.0.2 (#17000) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 587d38410a..64b38aeea6 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "@octokit/rest": "19.0.13", "@open-wc/dev-server-hmr": "0.1.4", "@rollup/plugin-babel": "6.0.3", - "@rollup/plugin-commonjs": "25.0.1", + "@rollup/plugin-commonjs": "25.0.2", "@rollup/plugin-json": "6.0.0", "@rollup/plugin-node-resolve": "15.1.0", "@rollup/plugin-replace": "5.0.2", diff --git a/yarn.lock b/yarn.lock index 2b607381f9..0414e27d27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3878,9 +3878,9 @@ __metadata: languageName: node linkType: hard -"@rollup/plugin-commonjs@npm:25.0.1": - version: 25.0.1 - resolution: "@rollup/plugin-commonjs@npm:25.0.1" +"@rollup/plugin-commonjs@npm:25.0.2": + version: 25.0.2 + resolution: "@rollup/plugin-commonjs@npm:25.0.2" dependencies: "@rollup/pluginutils": ^5.0.1 commondir: ^1.0.1 @@ -3893,7 +3893,7 @@ __metadata: peerDependenciesMeta: rollup: optional: true - checksum: 886340bac6ba8c20bb16e3b7fa4d0357019708043697153e7b18cecb7e1fdbe7ec6f26974079f32091c6168c67300960f023ad3d167d2d0d9a9e3bd713cd22a4 + checksum: d8c4e22d264c5b9286f697653c2f9288149c0fe0169d49b83b5dc8b542f96cc0b9113da3f30d241f2f277513fbf3f8c207d95def5559eb3800190f1872add794 languageName: node linkType: hard @@ -9667,7 +9667,7 @@ __metadata: "@polymer/paper-toast": 3.0.1 "@polymer/polymer": 3.5.1 "@rollup/plugin-babel": 6.0.3 - "@rollup/plugin-commonjs": 25.0.1 + "@rollup/plugin-commonjs": 25.0.2 "@rollup/plugin-json": 6.0.0 "@rollup/plugin-node-resolve": 15.1.0 "@rollup/plugin-replace": 5.0.2 From 76490cc69007d3f40c067f6e8398dfcc16fa2f92 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 24 Jun 2023 01:37:38 -0500 Subject: [PATCH 096/162] Fix media player list when there are entities not in the registry (#17015) --- src/panels/media-browser/ha-bar-media-player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/media-browser/ha-bar-media-player.ts b/src/panels/media-browser/ha-bar-media-player.ts index d4f276e3ec..a365bb9720 100644 --- a/src/panels/media-browser/ha-bar-media-player.ts +++ b/src/panels/media-browser/ha-bar-media-player.ts @@ -464,7 +464,7 @@ export class BarMediaPlayer extends SubscribeMixin(LitElement) { (entity) => computeStateDomain(entity) === "media_player" && supportsFeature(entity, MediaPlayerEntityFeature.BROWSE_MEDIA) && - !this.hass.entities[entity.entity_id].hidden + !this.hass.entities[entity.entity_id]?.hidden ); } From 3528f5c7aa1f9ab83ebb33252260f01fd59cc305 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 00:50:21 -0700 Subject: [PATCH 097/162] Fix dialog-device-registry-detail missing labels (#17001) --- .../dialog-device-registry-detail.ts | 18 ++++++++++-------- src/translations/en.json | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts b/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts index 65b4509713..204d115b24 100644 --- a/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts +++ b/src/panels/config/devices/device-registry-detail/dialog-device-registry-detail.ts @@ -67,7 +67,9 @@ class DialogDeviceRegistryDetail extends LitElement {
${this.hass.localize( - "ui.panel.config.devices.enabled_label", + "ui.dialogs.device-registry-detail.enabled_label", "type", this.hass.localize( - `ui.panel.config.devices.type.${ + `ui.dialogs.device-registry-detail.type.${ device.entry_type || "device" }` ) @@ -99,10 +101,10 @@ class DialogDeviceRegistryDetail extends LitElement {
${this._disabledBy && this._disabledBy !== "user" ? this.hass.localize( - "ui.panel.config.devices.enabled_cause", + "ui.dialogs.device-registry-detail.enabled_cause", "type", this.hass.localize( - `ui.panel.config.devices.type.${ + `ui.dialogs.device-registry-detail.type.${ device.entry_type || "device" }` ), @@ -113,7 +115,7 @@ class DialogDeviceRegistryDetail extends LitElement { ) : ""} ${this.hass.localize( - "ui.panel.config.devices.enabled_description" + "ui.dialogs.device-registry-detail.enabled_description" )}
@@ -132,7 +134,7 @@ class DialogDeviceRegistryDetail extends LitElement { @click=${this._updateEntry} .disabled=${this._submitting} > - ${this.hass.localize("ui.panel.config.devices.update")} + ${this.hass.localize("ui.dialogs.device-registry-detail.update")} `; @@ -163,7 +165,7 @@ class DialogDeviceRegistryDetail extends LitElement { } catch (err: any) { this._error = err.message || - this.hass.localize("ui.panel.config.devices.unknown_error"); + this.hass.localize("ui.dialogs.device-registry-detail.unknown_error"); } finally { this._submitting = false; } diff --git a/src/translations/en.json b/src/translations/en.json index 6a4f63360d..6ed1039023 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1103,6 +1103,20 @@ "no_aliases": "Configure aliases and expose settings for voice assistants" } }, + "device-registry-detail": { + "name": "[%key:ui::panel::config::devices::name%]", + "enabled_label": "[%key:ui::panel::config::devices::enabled_label%]", + "enabled_cause": "[%key:ui::panel::config::devices::enabled_cause%]", + "type": { + "device_heading": "[%key:ui::panel::config::devices::type::device_heading%]", + "device": "[%key:ui::panel::config::devices::type::device%]", + "service_heading": "[%key:ui::panel::config::devices::type::service_heading%]", + "service": "[%key:ui::panel::config::devices::type::service%]" + }, + "enabled_description": "[%key:ui::panel::config::devices::enabled_description%]", + "update": "[%key:ui::panel::config::devices::update%]", + "unknown_error": "[%key:ui::panel::config::devices::unknown_error%]" + }, "voice-settings": { "expose_header": "Expose", "aliases_header": "Aliases", From 1645208f62056a7f6d088c4d9d777282acf5cc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 26 Jun 2023 09:50:43 +0200 Subject: [PATCH 098/162] Export base create config functions (#17007) --- build-scripts/rollup.cjs | 1 + build-scripts/webpack.cjs | 1 + 2 files changed, 2 insertions(+) diff --git a/build-scripts/rollup.cjs b/build-scripts/rollup.cjs index f321e9f33e..e3becb97ae 100644 --- a/build-scripts/rollup.cjs +++ b/build-scripts/rollup.cjs @@ -142,4 +142,5 @@ module.exports = { createCastConfig, createHassioConfig, createGalleryConfig, + createRollupConfig, }; diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs index 111dadfc36..c5f8334149 100644 --- a/build-scripts/webpack.cjs +++ b/build-scripts/webpack.cjs @@ -253,4 +253,5 @@ module.exports = { createCastConfig, createHassioConfig, createGalleryConfig, + createWebpackConfig, }; From 152ca754990f47fe43fc29c5e3768d79e1399879 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 26 Jun 2023 09:58:59 +0200 Subject: [PATCH 099/162] Adjust codemirror gutter background color (#17018) --- src/resources/codemirror.ts | 2 +- src/resources/styles.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/resources/codemirror.ts b/src/resources/codemirror.ts index c419dd4a0c..d21e3ee511 100644 --- a/src/resources/codemirror.ts +++ b/src/resources/codemirror.ts @@ -180,7 +180,7 @@ export const haTheme = EditorView.theme({ ".cm-gutters": { backgroundColor: - "var(--code-editor-gutter-color, var(--mdc-text-field-fill-color, whitesmoke))", + "var(--code-editor-gutter-color, var(--secondary-background-color, whitesmoke))", color: "var(--paper-dialog-color, var(--secondary-text-color))", border: "none", borderRight: diff --git a/src/resources/styles.ts b/src/resources/styles.ts index ccec54cc01..37b4f65577 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -3,7 +3,7 @@ import { css } from "lit"; export const darkStyles = { "primary-background-color": "#111111", "card-background-color": "#1c1c1c", - "secondary-background-color": "#202020", + "secondary-background-color": "#282828", "primary-text-color": "#e1e1e1", "secondary-text-color": "#9b9b9b", "disabled-text-color": "#6f6f6f", From 655cf053c7081634c6812a740dff94734998705b Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 00:59:43 -0700 Subject: [PATCH 100/162] Include blueprint type in row id key (#16998) --- src/panels/config/blueprint/ha-blueprint-overview.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/panels/config/blueprint/ha-blueprint-overview.ts b/src/panels/config/blueprint/ha-blueprint-overview.ts index 0cbc479f48..44fd7f79c8 100644 --- a/src/panels/config/blueprint/ha-blueprint-overview.ts +++ b/src/panels/config/blueprint/ha-blueprint-overview.ts @@ -96,6 +96,7 @@ class HaBlueprintOverview extends LitElement { type, error: true, path, + fullpath: `${type}/${path}`, }); } else { result.push({ @@ -103,6 +104,7 @@ class HaBlueprintOverview extends LitElement { type, error: false, path, + fullpath: `${type}/${path}`, }); } }) @@ -154,6 +156,10 @@ class HaBlueprintOverview extends LitElement { direction: "asc", width: "25%", }, + fullpath: { + title: "fullpath", + hidden: true, + }, actions: { title: "", width: this.narrow ? undefined : "10%", @@ -233,7 +239,7 @@ class HaBlueprintOverview extends LitElement { .tabs=${configSections.automations} .columns=${this._columns(this.narrow, this.hass.language)} .data=${this._processedBlueprints(this.blueprints)} - id="path" + id="fullpath" .noDataText=${this.hass.localize( "ui.panel.config.blueprint.overview.no_blueprints" )} @@ -318,7 +324,7 @@ class HaBlueprintOverview extends LitElement { private _handleRowClicked(ev: HASSDomEvent) { const blueprint = this._processedBlueprints(this.blueprints).find( - (b) => b.path === ev.detail.id + (b) => b.fullpath === ev.detail.id ); if (blueprint.error) { showAlertDialog(this, { From 976fcab1462a870d9c4bee526fee57f676ab61eb Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 01:02:41 -0700 Subject: [PATCH 101/162] Don't apply brightness filter to plant icons (#17029) --- src/common/entity/state_color.ts | 12 ++++++++++++ src/components/entity/state-badge.ts | 8 +++++--- src/panels/lovelace/cards/hui-button-card.ts | 18 +++++------------- src/panels/lovelace/cards/hui-entity-card.ts | 16 +++++----------- src/panels/lovelace/cards/hui-light-card.ts | 4 ++-- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/common/entity/state_color.ts b/src/common/entity/state_color.ts index efcac098f2..5223076767 100644 --- a/src/common/entity/state_color.ts +++ b/src/common/entity/state_color.ts @@ -110,3 +110,15 @@ export const stateColorProperties = ( return undefined; }; + +export const stateColorBrightness = (stateObj: HassEntity): string => { + if ( + stateObj.attributes.brightness && + computeDomain(stateObj.entity_id) !== "plant" + ) { + // lowest brightness will be around 50% (that's pretty dark) + const brightness = stateObj.attributes.brightness; + return `brightness(${(brightness + 245) / 5}%)`; + } + return ""; +}; diff --git a/src/components/entity/state-badge.ts b/src/components/entity/state-badge.ts index 4fbfcaf853..2b6f936497 100644 --- a/src/components/entity/state-badge.ts +++ b/src/components/entity/state-badge.ts @@ -13,7 +13,10 @@ import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; import { computeDomain } from "../../common/entity/compute_domain"; import { computeStateDomain } from "../../common/entity/compute_state_domain"; -import { stateColorCss } from "../../common/entity/state_color"; +import { + stateColorCss, + stateColorBrightness, +} from "../../common/entity/state_color"; import { iconColorCSS } from "../../common/style/icon_color_css"; import { cameraUrlWithWidthHeight } from "../../data/camera"; import { HVAC_ACTION_TO_MODE } from "../../data/climate"; @@ -153,8 +156,7 @@ export class StateBadge extends LitElement { // eslint-disable-next-line console.warn(errorMessage); } - // lowest brightness will be around 50% (that's pretty dark) - iconStyle.filter = `brightness(${(brightness + 245) / 5}%)`; + iconStyle.filter = stateColorBrightness(stateObj); } if (stateObj.attributes.hvac_action) { const hvacAction = stateObj.attributes.hvac_action; diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index b98607fcc2..670e69b0e9 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -26,7 +26,10 @@ import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDisplaySingleEntity } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; -import { stateColorCss } from "../../../common/entity/state_color"; +import { + stateColorCss, + stateColorBrightness, +} from "../../../common/entity/state_color"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; import { iconColorCSS } from "../../../common/style/icon_color_css"; import { LocalizeFunc } from "../../../common/translations/localize"; @@ -41,7 +44,6 @@ import { themesContext, } from "../../../data/context"; import { EntityRegistryDisplayEntry } from "../../../data/entity_registry"; -import { LightEntity } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { FrontendLocaleData } from "../../../data/translation"; import { Themes } from "../../../data/ws-themes"; @@ -213,9 +215,7 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { .state=${stateObj} style=${styleMap({ color: colored ? this._computeColor(stateObj) : undefined, - filter: colored - ? this._computeBrightness(stateObj) - : undefined, + filter: colored ? stateColorBrightness(stateObj) : undefined, height: this._config.icon_height ? this._config.icon_height : "", @@ -337,14 +337,6 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { ]; } - private _computeBrightness(stateObj: HassEntity | LightEntity): string { - if (stateObj.attributes.brightness) { - const brightness = stateObj.attributes.brightness; - return `brightness(${(brightness + 245) / 5}%)`; - } - return ""; - } - private _computeColor(stateObj: HassEntity): string | undefined { if (stateObj.attributes.rgb_color) { return `rgb(${stateObj.attributes.rgb_color.join(",")})`; diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index 7424877f52..201c4b9dd6 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -16,7 +16,10 @@ import { computeAttributeValueDisplay } from "../../../common/entity/compute_att import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; -import { stateColorCss } from "../../../common/entity/state_color"; +import { + stateColorCss, + stateColorBrightness, +} from "../../../common/entity/state_color"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; import { formatNumber, @@ -28,7 +31,6 @@ import "../../../components/ha-card"; import "../../../components/ha-icon"; import { HVAC_ACTION_TO_MODE } from "../../../data/climate"; import { isUnavailableState } from "../../../data/entity"; -import { LightEntity } from "../../../data/light"; import { HomeAssistant } from "../../../types"; import { computeCardSize } from "../common/compute-card-size"; import { findEntities } from "../common/find-entities"; @@ -143,7 +145,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { data-state=${stateObj.state} style=${styleMap({ color: colored ? this._computeColor(stateObj) : undefined, - filter: colored ? this._computeBrightness(stateObj) : undefined, + filter: colored ? stateColorBrightness(stateObj) : undefined, height: this._config.icon_height ? this._config.icon_height : "", @@ -214,14 +216,6 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { return undefined; } - private _computeBrightness(stateObj: HassEntity | LightEntity): string { - if (stateObj.attributes.brightness) { - const brightness = stateObj.attributes.brightness; - return `brightness(${(brightness + 245) / 5}%)`; - } - return ""; - } - protected shouldUpdate(changedProps: PropertyValues): boolean { // Side Effect used to update footer hass while keeping optimizations if (this._footerElement) { diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 9c2041c7ba..c2715b8007 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -30,6 +30,7 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LightCardConfig } from "./types"; +import { stateColorBrightness } from "../../../common/entity/state_color"; @customElement("hui-light-card") export class HuiLightCard extends LitElement implements LovelaceCard { @@ -239,8 +240,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard { if (stateObj.state === "off" || !stateObj.attributes.brightness) { return ""; } - const brightness = stateObj.attributes.brightness; - return `brightness(${(brightness + 245) / 5}%)`; + return stateColorBrightness(stateObj); } private _computeColor(stateObj: LightEntity): string { From 2929bf5b1adf61280c232659400ac3ac95d83519 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 08:50:53 +0000 Subject: [PATCH 102/162] Update CodeMirror (#17031) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 ++-- yarn.lock | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 64b38aeea6..262eef0ab3 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,13 @@ "dependencies": { "@babel/runtime": "7.22.5", "@braintree/sanitize-url": "6.0.2", - "@codemirror/autocomplete": "6.8.0", + "@codemirror/autocomplete": "6.8.1", "@codemirror/commands": "6.2.4", "@codemirror/language": "6.8.0", "@codemirror/legacy-modes": "6.3.2", "@codemirror/search": "6.5.0", "@codemirror/state": "6.2.1", - "@codemirror/view": "6.13.2", + "@codemirror/view": "6.14.0", "@egjs/hammerjs": "2.0.17", "@formatjs/intl-datetimeformat": "6.10.0", "@formatjs/intl-displaynames": "6.5.0", diff --git a/yarn.lock b/yarn.lock index 0414e27d27..f15981e4b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1450,9 +1450,9 @@ __metadata: languageName: node linkType: hard -"@codemirror/autocomplete@npm:6.8.0": - version: 6.8.0 - resolution: "@codemirror/autocomplete@npm:6.8.0" +"@codemirror/autocomplete@npm:6.8.1": + version: 6.8.1 + resolution: "@codemirror/autocomplete@npm:6.8.1" dependencies: "@codemirror/language": ^6.0.0 "@codemirror/state": ^6.0.0 @@ -1463,7 +1463,7 @@ __metadata: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.0.0 - checksum: b251a21065a954be7a4a9cf6fd1dce6027bd79ac7006728c0fde364b50c75ee4079bd53acf9890fdfdca78453c863f0c010010c26010cd9acdede3480273ad23 + checksum: 8599cd91defa3fea5276a7f9aff43ced323d9c4401dfb867e43608ba72ded48cb458256c5c784949a6332c0c20ba2fedac16a5708335cd809d269e4ea5076957 languageName: node linkType: hard @@ -1520,14 +1520,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:6.13.2, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.6.0": - version: 6.13.2 - resolution: "@codemirror/view@npm:6.13.2" +"@codemirror/view@npm:6.14.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.6.0": + version: 6.14.0 + resolution: "@codemirror/view@npm:6.14.0" dependencies: "@codemirror/state": ^6.1.4 style-mod: ^4.0.0 w3c-keyname: ^2.2.4 - checksum: db0d638fbbe2f9a832674f06512ca55cdb7576a265c01ab8a7b6715d2a50ddf53200f597637b146adebe1df51255fe5bd2d2c74cf1fa539b0434764c0550d3a5 + checksum: f8fbb8e8cf1bc23de8cd64b1e645112d13f72cd2f1609fb9047d616908c2189ff518b89f21484371e7a37ba1804288452558e96488791f0c850f62b8e28dc163 languageName: node linkType: hard @@ -9596,13 +9596,13 @@ __metadata: "@babel/preset-typescript": 7.22.5 "@babel/runtime": 7.22.5 "@braintree/sanitize-url": 6.0.2 - "@codemirror/autocomplete": 6.8.0 + "@codemirror/autocomplete": 6.8.1 "@codemirror/commands": 6.2.4 "@codemirror/language": 6.8.0 "@codemirror/legacy-modes": 6.3.2 "@codemirror/search": 6.5.0 "@codemirror/state": 6.2.1 - "@codemirror/view": 6.13.2 + "@codemirror/view": 6.14.0 "@egjs/hammerjs": 2.0.17 "@formatjs/intl-datetimeformat": 6.10.0 "@formatjs/intl-displaynames": 6.5.0 From 9bcbb6f9146dd549d666df139d636bf5abdbe83b Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 02:14:14 -0700 Subject: [PATCH 103/162] Support cut/copy/paste in dashboard UI editor (#16707) --- .../lovelace/components/hui-card-options.ts | 45 ++++++++++++-- .../editor/card-editor/hui-card-picker.ts | 61 ++++++++++++++++--- .../hui-conditional-card-editor.ts | 26 ++++++++ .../config-elements/hui-stack-card-editor.ts | 47 +++++++++++++- src/panels/lovelace/views/hui-view.ts | 10 ++- src/translations/en.json | 4 ++ 6 files changed, 178 insertions(+), 15 deletions(-) diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 18c32eafa4..6a39d8b590 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -11,10 +11,12 @@ import { TemplateResult, } from "lit"; import { customElement, property, queryAssignedNodes } from "lit/decorators"; +import deepClone from "deep-clone-simple"; +import { storage } from "../../../common/decorators/storage"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-button-menu"; import "../../../components/ha-icon-button"; -import { saveConfig } from "../../../data/lovelace"; +import { saveConfig, LovelaceCardConfig } from "../../../data/lovelace"; import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../../../types"; import { showSaveSuccessToast } from "../../../util/toast-saved-success"; @@ -34,6 +36,14 @@ export class HuiCardOptions extends LitElement { @queryAssignedNodes() private _assignedNodes?: NodeListOf; + @storage({ + key: "lovelaceClipboard", + state: false, + subscribe: false, + storage: "sessionStorage", + }) + protected _clipboard?: LovelaceCardConfig; + public getCardSize() { return this._assignedNodes ? computeCardSize(this._assignedNodes[0]) : 1; } @@ -98,6 +108,16 @@ export class HuiCardOptions extends LitElement { "ui.panel.lovelace.editor.edit_card.duplicate" )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_card.copy" + )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_card.cut" + )} ${this.hass!.localize( "ui.panel.lovelace.editor.edit_card.delete" @@ -163,7 +183,13 @@ export class HuiCardOptions extends LitElement { this._duplicateCard(); break; case 2: - this._deleteCard(); + this._copyCard(); + break; + case 3: + this._cutCard(); + break; + case 4: + this._deleteCard(true); break; } } @@ -183,6 +209,17 @@ export class HuiCardOptions extends LitElement { fireEvent(this, "ll-edit-card", { path: this.path! }); } + private _cutCard(): void { + this._copyCard(); + this._deleteCard(false); + } + + private _copyCard(): void { + const cardConfig = + this.lovelace!.config.views[this.path![0]].cards![this.path![1]]; + this._clipboard = deepClone(cardConfig); + } + private _cardUp(): void { const lovelace = this.lovelace!; const path = this.path!; @@ -236,8 +273,8 @@ export class HuiCardOptions extends LitElement { }); } - private _deleteCard(): void { - fireEvent(this, "ll-delete-card", { path: this.path! }); + private _deleteCard(confirm: boolean): void { + fireEvent(this, "ll-delete-card", { path: this.path!, confirm }); } } diff --git a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts index 16f2a4cead..415b89b993 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts @@ -15,6 +15,7 @@ import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import { until } from "lit/directives/until"; import memoizeOne from "memoize-one"; +import { storage } from "../../../../common/decorators/storage"; import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-circular-progress"; import "../../../../components/search-input"; @@ -49,6 +50,14 @@ interface CardElement { export class HuiCardPicker extends LitElement { @property({ attribute: false }) public hass?: HomeAssistant; + @storage({ + key: "lovelaceClipboard", + state: true, + subscribe: true, + storage: "sessionStorage", + }) + private _clipboard?: LovelaceCardConfig; + @state() private _cards: CardElement[] = []; public lovelace?: LovelaceConfig; @@ -114,6 +123,37 @@ export class HuiCardPicker extends LitElement { })} >
+ ${this._clipboard + ? html` + ${until( + this._renderCardElement( + { + type: this._clipboard.type, + showElement: true, + isCustom: false, + name: this.hass!.localize( + "ui.panel.lovelace.editor.card.generic.paste" + ), + description: `${this.hass!.localize( + "ui.panel.lovelace.editor.card.generic.paste_description", + { + type: this._clipboard.type, + } + )}`, + }, + this._clipboard + ), + html` +
+ +
+ ` + )} + ` + : nothing} ${this._filterCards(this._cards, this._filter).map( (cardElement: CardElement) => cardElement.element )} @@ -272,7 +312,10 @@ export class HuiCardPicker extends LitElement { } } - private async _renderCardElement(card: Card): Promise { + private async _renderCardElement( + card: Card, + config?: LovelaceCardConfig + ): Promise { let { type } = card; const { showElement, isCustom, name, description } = card; const customCard = isCustom ? getCustomCardEntry(type) : undefined; @@ -281,15 +324,17 @@ export class HuiCardPicker extends LitElement { } let element: LovelaceCard | undefined; - let cardConfig: LovelaceCardConfig = { type }; + let cardConfig: LovelaceCardConfig = config ?? { type }; if (this.hass && this.lovelace) { - cardConfig = await getCardStubConfig( - this.hass, - type, - this._unusedEntities!, - this._usedEntities! - ); + if (!config) { + cardConfig = await getCardStubConfig( + this.hass, + type, + this._unusedEntities!, + this._usedEntities! + ); + } if (showElement) { try { diff --git a/src/panels/lovelace/editor/config-elements/hui-conditional-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-conditional-card-editor.ts index 69c48fb105..b2c8566af6 100644 --- a/src/panels/lovelace/editor/config-elements/hui-conditional-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-conditional-card-editor.ts @@ -1,6 +1,8 @@ import "@material/mwc-list/mwc-list-item"; import "@material/mwc-tab-bar/mwc-tab-bar"; import "@material/mwc-tab/mwc-tab"; +import { mdiContentCopy } from "@mdi/js"; +import deepClone from "deep-clone-simple"; import type { MDCTabBarActivatedEvent } from "@material/tab-bar"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; @@ -13,6 +15,7 @@ import { optional, string, } from "superstruct"; +import { storage } from "../../../../common/decorators/storage"; import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; import { stopPropagation } from "../../../../common/dom/stop_propagation"; import "../../../../components/entity/ha-entity-picker"; @@ -56,6 +59,14 @@ export class HuiConditionalCardEditor @property({ attribute: false }) public lovelace?: LovelaceConfig; + @storage({ + key: "lovelaceClipboard", + state: false, + subscribe: false, + storage: "sessionStorage", + }) + protected _clipboard?: LovelaceCardConfig; + @state() private _config?: ConditionalCardConfig; @state() private _GUImode = true; @@ -114,6 +125,14 @@ export class HuiConditionalCardEditor : "ui.panel.lovelace.editor.edit_card.show_visual_editor" )} + + ${this.hass!.localize( "ui.panel.lovelace.editor.card.conditional.change_type" @@ -238,6 +257,13 @@ export class HuiConditionalCardEditor fireEvent(this, "config-changed", { config: this._config }); } + protected _handleCopyCard() { + if (!this._config) { + return; + } + this._clipboard = deepClone(this._config.card); + } + private _handleCardChanged(ev: HASSDomEvent): void { ev.stopPropagation(); if (!this._config) { diff --git a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts index 9809a3ac6a..79dafd0aaf 100644 --- a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts @@ -1,6 +1,14 @@ -import { mdiArrowLeft, mdiArrowRight, mdiDelete, mdiPlus } from "@mdi/js"; +import { + mdiArrowLeft, + mdiArrowRight, + mdiDelete, + mdiContentCut, + mdiContentCopy, + mdiPlus, +} from "@mdi/js"; import "@polymer/paper-tabs"; import "@polymer/paper-tabs/paper-tab"; +import deepClone from "deep-clone-simple"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import { @@ -12,6 +20,7 @@ import { optional, string, } from "superstruct"; +import { storage } from "../../../../common/decorators/storage"; import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-icon-button"; import { LovelaceCardConfig, LovelaceConfig } from "../../../../data/lovelace"; @@ -43,6 +52,14 @@ export class HuiStackCardEditor @property({ attribute: false }) public lovelace?: LovelaceConfig; + @storage({ + key: "lovelaceClipboard", + state: false, + subscribe: false, + storage: "sessionStorage", + }) + protected _clipboard?: LovelaceCardConfig; + @state() protected _config?: StackCardConfig; @state() protected _selectedCard = 0; @@ -129,6 +146,22 @@ export class HuiStackCardEditor .move=${1} > + + + + { - confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path); + if (ev.detail.confirm) { + confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path); + } else { + const newLovelace = deleteCard(this.lovelace!.config, ev.detail.path); + this.lovelace.saveConfig(newLovelace); + } }); } diff --git a/src/translations/en.json b/src/translations/en.json index 6ed1039023..883659695f 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4454,6 +4454,8 @@ "edit": "Edit", "clear": "Clear", "delete": "Delete card", + "copy": "Copy card", + "cut": "Cut card", "duplicate": "Duplicate card", "move": "Move to view", "move_up": "Move card up", @@ -4708,6 +4710,8 @@ "manual_description": "Need to add a custom card or just want to manually write the YAML?", "minimum": "Minimum", "name": "Name", + "paste": "Paste from Clipboard", + "paste_description": "Paste a {type} card from the clipboard", "refresh_interval": "Refresh Interval", "show_icon": "Show Icon?", "show_name": "Show Name?", From 0f0d1d6e6f16f5f133a8f9b87f24007b3e5c7633 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:26:52 +0200 Subject: [PATCH 104/162] Update dependency glob to v10.3.0 (#17024) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 262eef0ab3..068ea6852e 100644 --- a/package.json +++ b/package.json @@ -203,7 +203,7 @@ "esprima": "4.0.1", "fancy-log": "2.0.0", "fs-extra": "11.1.1", - "glob": "10.2.7", + "glob": "10.3.0", "gulp": "4.0.2", "gulp-flatmap": "1.0.2", "gulp-json-transform": "0.4.8", diff --git a/yarn.lock b/yarn.lock index f15981e4b4..ebadacd2be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9156,9 +9156,9 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.2.7, glob@npm:^10.2.2": - version: 10.2.7 - resolution: "glob@npm:10.2.7" +"glob@npm:10.3.0, glob@npm:^10.2.2": + version: 10.3.0 + resolution: "glob@npm:10.3.0" dependencies: foreground-child: ^3.1.0 jackspeak: ^2.0.3 @@ -9167,7 +9167,7 @@ __metadata: path-scurry: ^1.7.0 bin: glob: dist/cjs/src/bin.js - checksum: 555205a74607d6f8d9874ba888924b305b5ea1abfaa2e9ccb11ac713d040aac7edbf7d8702a2f4a1cd81b2d7666412170ce7ef061d33cddde189dae8c1a1a054 + checksum: 6fa4ac0a86ffec1c5715a2e6fbdd63e1e7f1c2c8f5db08cc3256cdfcb81093678e7c80a3d100b502a1b9d141369ecf87bc24fe2bcb72acec7b14626d358a4eb0 languageName: node linkType: hard @@ -9728,7 +9728,7 @@ __metadata: fancy-log: 2.0.0 fs-extra: 11.1.1 fuse.js: 6.6.2 - glob: 10.2.7 + glob: 10.3.0 google-timezones-json: 1.1.0 gulp: 4.0.2 gulp-flatmap: 1.0.2 From d2199dfa3418b809f49b646a984fdd41ceea1f04 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:29:07 +0200 Subject: [PATCH 105/162] Update dependency webpack to v5.88.0 (#17025) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 068ea6852e..9239d66116 100644 --- a/package.json +++ b/package.json @@ -239,7 +239,7 @@ "typescript": "5.1.3", "vinyl-buffer": "1.0.1", "vinyl-source-stream": "2.0.0", - "webpack": "5.87.0", + "webpack": "5.88.0", "webpack-cli": "5.1.4", "webpack-dev-server": "4.15.1", "webpack-manifest-plugin": "5.0.0", diff --git a/yarn.lock b/yarn.lock index ebadacd2be..6678d64b79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9793,7 +9793,7 @@ __metadata: vis-network: 9.1.6 vue: 2.7.14 vue2-daterange-picker: 0.6.8 - webpack: 5.87.0 + webpack: 5.88.0 webpack-cli: 5.1.4 webpack-dev-server: 4.15.1 webpack-manifest-plugin: 5.0.0 @@ -16135,9 +16135,9 @@ __metadata: languageName: node linkType: hard -"webpack@npm:5.87.0": - version: 5.87.0 - resolution: "webpack@npm:5.87.0" +"webpack@npm:5.88.0": + version: 5.88.0 + resolution: "webpack@npm:5.88.0" dependencies: "@types/eslint-scope": ^3.7.3 "@types/estree": ^1.0.0 @@ -16168,7 +16168,7 @@ __metadata: optional: true bin: webpack: bin/webpack.js - checksum: b7d0e390f9d30627e303d54b17cb87b62f49ecffe2d35481f830679904993bae208e23748ffe0e6091b6dd4810562b2f2e88bb0f23b96515d74fb1e3c2898210 + checksum: 9fd1568b34ec2e99ba97c8509a15ab2576ec80c396e7015551ec814b24cfc11de173acba3e114dafe95f1a6d460781b09d6201e6a1fb15110e1d01a09f61a283 languageName: node linkType: hard From a77167e9d9578c4f72019c81fa24e68a121b2521 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:32:51 +0200 Subject: [PATCH 106/162] Update dependency @lrnwebcomponents/simple-tooltip to v7.0.5 (#17014) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 9239d66116..070b482c1f 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@lit-labs/context": "0.3.3", "@lit-labs/motion": "1.0.3", "@lit-labs/virtualizer": "2.0.3", - "@lrnwebcomponents/simple-tooltip": "7.0.2", + "@lrnwebcomponents/simple-tooltip": "7.0.5", "@material/chips": "=14.0.0-canary.53b3cad2f.0", "@material/data-table": "=14.0.0-canary.53b3cad2f.0", "@material/mwc-button": "0.27.0", diff --git a/yarn.lock b/yarn.lock index 6678d64b79..adca4fa057 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2107,12 +2107,12 @@ __metadata: languageName: node linkType: hard -"@lrnwebcomponents/simple-tooltip@npm:7.0.2": - version: 7.0.2 - resolution: "@lrnwebcomponents/simple-tooltip@npm:7.0.2" +"@lrnwebcomponents/simple-tooltip@npm:7.0.5": + version: 7.0.5 + resolution: "@lrnwebcomponents/simple-tooltip@npm:7.0.5" dependencies: - lit: ^2.7.4 - checksum: 2f8642c7b503e6093d01b5fcadea461de062c9380df6454f04a08e5b8f4ef36e0cbd52a9f0842238554f6881802895fb442f21c0a4b6345bebd99b43f18a366c + lit: ^2.7.5 + checksum: 57a50ed30be103f8fbe37fbef33bb4071f8c2bbecba6964643404532883f3479fe034ee64b1d71d11d7ea60ee63e39bb5ef5f53dc0b9c88d6ec525627135602b languageName: node linkType: hard @@ -9622,7 +9622,7 @@ __metadata: "@lit-labs/context": 0.3.3 "@lit-labs/motion": 1.0.3 "@lit-labs/virtualizer": 2.0.3 - "@lrnwebcomponents/simple-tooltip": 7.0.2 + "@lrnwebcomponents/simple-tooltip": 7.0.5 "@material/chips": =14.0.0-canary.53b3cad2f.0 "@material/data-table": =14.0.0-canary.53b3cad2f.0 "@material/mwc-button": 0.27.0 @@ -11403,7 +11403,7 @@ __metadata: languageName: node linkType: hard -"lit@npm:2.7.5, lit@npm:^2.0.0, lit@npm:^2.0.0-rc.2, lit@npm:^2.2.1, lit@npm:^2.7.0, lit@npm:^2.7.4": +"lit@npm:2.7.5, lit@npm:^2.0.0, lit@npm:^2.0.0-rc.2, lit@npm:^2.2.1, lit@npm:^2.7.0, lit@npm:^2.7.4, lit@npm:^2.7.5": version: 2.7.5 resolution: "lit@npm:2.7.5" dependencies: From 96d66877240d9d565d33bb48c1bbc9d3000783c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:33:39 +0200 Subject: [PATCH 107/162] Update dependency sinon to v15.2.0 (#17013) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 070b482c1f..38f17b7395 100644 --- a/package.json +++ b/package.json @@ -230,7 +230,7 @@ "rollup-plugin-terser": "7.0.2", "rollup-plugin-visualizer": "5.9.2", "serve-handler": "6.1.5", - "sinon": "15.1.2", + "sinon": "15.2.0", "source-map-url": "0.4.1", "systemjs": "6.14.1", "tar": "6.1.15", diff --git a/yarn.lock b/yarn.lock index adca4fa057..2d37844ca7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4036,12 +4036,12 @@ __metadata: languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^10.0.2, @sinonjs/fake-timers@npm:^10.1.0": - version: 10.1.0 - resolution: "@sinonjs/fake-timers@npm:10.1.0" +"@sinonjs/fake-timers@npm:^10.0.2, @sinonjs/fake-timers@npm:^10.3.0": + version: 10.3.0 + resolution: "@sinonjs/fake-timers@npm:10.3.0" dependencies: "@sinonjs/commons": ^3.0.0 - checksum: f8f7e23a136e32ba0128493207e4223f453e033471257a971acb43840927e738a0838004b1e4fa046279609762a2dd8d700606616e9264dc3891c4f8d45889a2 + checksum: 614d30cb4d5201550c940945d44c9e0b6d64a888ff2cd5b357f95ad6721070d6b8839cd10e15b76bf5e14af0bcc1d8f9ec00d49a46318f1f669a4bec1d7f3148 languageName: node linkType: hard @@ -9774,7 +9774,7 @@ __metadata: rollup-plugin-visualizer: 5.9.2 rrule: 2.7.2 serve-handler: 6.1.5 - sinon: 15.1.2 + sinon: 15.2.0 sortablejs: 1.15.0 source-map-url: 0.4.1 superstruct: 1.0.3 @@ -14238,17 +14238,17 @@ __metadata: languageName: node linkType: hard -"sinon@npm:15.1.2": - version: 15.1.2 - resolution: "sinon@npm:15.1.2" +"sinon@npm:15.2.0": + version: 15.2.0 + resolution: "sinon@npm:15.2.0" dependencies: "@sinonjs/commons": ^3.0.0 - "@sinonjs/fake-timers": ^10.1.0 + "@sinonjs/fake-timers": ^10.3.0 "@sinonjs/samsam": ^8.0.0 diff: ^5.1.0 nise: ^5.1.4 supports-color: ^7.2.0 - checksum: 4484235fe4e84cc142cb8810a3a80f5b016178d739c1e2cc0b5eb1f0e05e05dd2dffaf53878826ac40743791acabb7265297affced727b0480c8bfe9abead8e8 + checksum: 1641b9af8a73ba57c73c9b6fd955a2d062a5d78cce719887869eca45faf33b0fd20cabfeffdfd856bb35bfbd3d49debb2d954ff6ae5e9825a3da5ff4f604ab6c languageName: node linkType: hard From d961f5be5f5ef46cd6cf9644879f06e52a97db48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:34:30 +0200 Subject: [PATCH 108/162] Update typescript-eslint monorepo to v5.60.0 (#17004) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +-- yarn.lock | 100 +++++++++++++++++++++++++-------------------------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 38f17b7395..42f96f6885 100644 --- a/package.json +++ b/package.json @@ -181,8 +181,8 @@ "@types/sortablejs": "1.15.1", "@types/tar": "6.1.5", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "5.59.11", - "@typescript-eslint/parser": "5.59.11", + "@typescript-eslint/eslint-plugin": "5.60.0", + "@typescript-eslint/parser": "5.60.0", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.2", diff --git a/yarn.lock b/yarn.lock index 2d37844ca7..a1d518b53e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4671,14 +4671,14 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/eslint-plugin@npm:5.59.11" +"@typescript-eslint/eslint-plugin@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/eslint-plugin@npm:5.60.0" dependencies: "@eslint-community/regexpp": ^4.4.0 - "@typescript-eslint/scope-manager": 5.59.11 - "@typescript-eslint/type-utils": 5.59.11 - "@typescript-eslint/utils": 5.59.11 + "@typescript-eslint/scope-manager": 5.60.0 + "@typescript-eslint/type-utils": 5.60.0 + "@typescript-eslint/utils": 5.60.0 debug: ^4.3.4 grapheme-splitter: ^1.0.4 ignore: ^5.2.0 @@ -4691,43 +4691,43 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: ff03eaa65a9fa4415cc1a14c2d4382289b9483f11dd3e0746233c2148d941cdbef421c1693304502f42307c72e049d4c3f3b58d30ce5d2ae452f31906e394e62 + checksum: 61dd70a1ea9787e69d0d4cd14f6a4c94ba786b535a3f519ade7926d965ee1d4f8fefa8bf0224ee57c5c6517eec3674c0fd06f9226536aa428c2bdddeed1e70f4 languageName: node linkType: hard -"@typescript-eslint/parser@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/parser@npm:5.59.11" +"@typescript-eslint/parser@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/parser@npm:5.60.0" dependencies: - "@typescript-eslint/scope-manager": 5.59.11 - "@typescript-eslint/types": 5.59.11 - "@typescript-eslint/typescript-estree": 5.59.11 + "@typescript-eslint/scope-manager": 5.60.0 + "@typescript-eslint/types": 5.60.0 + "@typescript-eslint/typescript-estree": 5.60.0 debug: ^4.3.4 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 75eb6e60577690e3c9dd66fde83c9b4e9e5fd818fe9673e532052d5ba8fa21a5f7a69aad19be99e6ef5825e9f52036262b25e918e51f96e1dc26e862448d2d3a + checksum: 94e7931a5b356b16638b281b8e1d661f8b1660f0c75a323537f68b311dae91b7a575a0a019d4ea05a79cc5d42b5cb41cc367205691cdfd292ef96a3b66b1e58b languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/scope-manager@npm:5.59.11" +"@typescript-eslint/scope-manager@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/scope-manager@npm:5.60.0" dependencies: - "@typescript-eslint/types": 5.59.11 - "@typescript-eslint/visitor-keys": 5.59.11 - checksum: f5c4e6d26da0a983b8f0c016f3ae63b3462442fe9c04d7510ca397461e13f6c48332b09b584258a7f336399fa7cd866f3ab55eaad89c5096a411c0d05d296475 + "@typescript-eslint/types": 5.60.0 + "@typescript-eslint/visitor-keys": 5.60.0 + checksum: b21ee1ef57be948a806aa31fd65a9186766b3e1a727030dc47025edcadc54bd1aa6133a439acd5f44a93e2b983dd55bc5571bb01cb834461dab733682d66256a languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/type-utils@npm:5.59.11" +"@typescript-eslint/type-utils@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/type-utils@npm:5.60.0" dependencies: - "@typescript-eslint/typescript-estree": 5.59.11 - "@typescript-eslint/utils": 5.59.11 + "@typescript-eslint/typescript-estree": 5.60.0 + "@typescript-eslint/utils": 5.60.0 debug: ^4.3.4 tsutils: ^3.21.0 peerDependencies: @@ -4735,23 +4735,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 3570ba21af35e7e0a916b606c1af311c00d20fe354a5837e0e937191b5e99ceb0076a5ba2924eaa028d4614e03981b20cfdd83a2be780c39e02be3b3bd365b63 + checksum: b90ce97592f2db899d88d7a325fec4d2ea11a7b8b4306787310890c27fb51862a6c003675252e9dc465908f791ad5320ea7307260ecd10e89ca1d209fbf8616d languageName: node linkType: hard -"@typescript-eslint/types@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/types@npm:5.59.11" - checksum: 4bb667571a7254f8c2b0dc3e37100e7290f9be14978722cc31c7204dfababd8a346bed4125e70dcafd15d07be386fb55bb9738bd86662ac10b98a6c964716396 +"@typescript-eslint/types@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/types@npm:5.60.0" + checksum: 48f29e5c084c5663cfed1a6c4458799a6690a213e7861a24501f9b96698ae59e89a1df1c77e481777e4da78f1b0a5573a549f7b8880e3f4071a7a8b686254db8 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/typescript-estree@npm:5.59.11" +"@typescript-eslint/typescript-estree@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.60.0" dependencies: - "@typescript-eslint/types": 5.59.11 - "@typescript-eslint/visitor-keys": 5.59.11 + "@typescript-eslint/types": 5.60.0 + "@typescript-eslint/visitor-keys": 5.60.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -4760,35 +4760,35 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 516a828884e6939000aac17a27208088055670b0fd9bd22d137a7b2d359a8db9ce9cd09eedffed6f498f968be90ce3c2695a91d46abbd4049f87fd3b7bb986b5 + checksum: 0f4f342730ead42ba60b5fca4bf1950abebd83030010c38b5df98ff9fd95d0ce1cfc3974a44c90c65f381f4f172adcf1a540e018d7968cc845d937bf6c734dae languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/utils@npm:5.59.11" +"@typescript-eslint/utils@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/utils@npm:5.60.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@types/json-schema": ^7.0.9 "@types/semver": ^7.3.12 - "@typescript-eslint/scope-manager": 5.59.11 - "@typescript-eslint/types": 5.59.11 - "@typescript-eslint/typescript-estree": 5.59.11 + "@typescript-eslint/scope-manager": 5.60.0 + "@typescript-eslint/types": 5.60.0 + "@typescript-eslint/typescript-estree": 5.60.0 eslint-scope: ^5.1.1 semver: ^7.3.7 peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: a61f3e761dbdc5d0bdb6c78bca7b2e628f7a1920192286d002219cc3acb516757613c2ec2a4adc416858ba1751ecbe2784457d6ebcec6bbb109cfc2ca210572b + checksum: cbe56567f0b53e24ad7ef7d2fb4cdc8596e2559c21ee639aa0560879b6216208550e51e9d8ae4b388ff21286809c6dc985cec66738294871051396a8ae5bccbc languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.59.11": - version: 5.59.11 - resolution: "@typescript-eslint/visitor-keys@npm:5.59.11" +"@typescript-eslint/visitor-keys@npm:5.60.0": + version: 5.60.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.60.0" dependencies: - "@typescript-eslint/types": 5.59.11 + "@typescript-eslint/types": 5.60.0 eslint-visitor-keys: ^3.3.0 - checksum: 4894ec4b2b8da773b1f44398c836fcacb7f5a0c81f9404ecd193920e88d618091a7328659e0aa24697edda10479534db30bec7c8b0ba9fa0fce43f78222d5619 + checksum: d39b2485d030f9755820d0f6f3748a8ec44e1ca23cb36ddcba67a9eb1f258c8ec83c61fc015c50e8f4a00d05df62d719dbda445625e3e71a64a659f1d248157e languageName: node linkType: hard @@ -9688,8 +9688,8 @@ __metadata: "@types/sortablejs": 1.15.1 "@types/tar": 6.1.5 "@types/webspeechapi": 0.0.29 - "@typescript-eslint/eslint-plugin": 5.59.11 - "@typescript-eslint/parser": 5.59.11 + "@typescript-eslint/eslint-plugin": 5.60.0 + "@typescript-eslint/parser": 5.60.0 "@vaadin/combo-box": 24.1.1 "@vaadin/vaadin-themable-mixin": 24.1.1 "@vibrant/color": 3.2.1-alpha.1 From 897f11854740ff54ac0303d858948ba78a33a732 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:35:13 +0200 Subject: [PATCH 109/162] Update dependency @material/web to v1.0.0-pre.11 (#17012) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 42f96f6885..bc2fb3dd90 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "@material/mwc-top-app-bar": "0.27.0", "@material/mwc-top-app-bar-fixed": "0.27.0", "@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0", - "@material/web": "=1.0.0-pre.10", + "@material/web": "=1.0.0-pre.11", "@mdi/js": "7.2.96", "@mdi/svg": "7.2.96", "@polymer/app-layout": "3.1.0", diff --git a/yarn.lock b/yarn.lock index a1d518b53e..31dfffcb1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3141,14 +3141,14 @@ __metadata: languageName: node linkType: hard -"@material/web@npm:=1.0.0-pre.10": - version: 1.0.0-pre.10 - resolution: "@material/web@npm:1.0.0-pre.10" +"@material/web@npm:=1.0.0-pre.11": + version: 1.0.0-pre.11 + resolution: "@material/web@npm:1.0.0-pre.11" dependencies: lit: ^2.7.4 safevalues: ^0.4.3 tslib: ^2.4.0 - checksum: 977ef988279c96b93f7e20761595b71cd8a07cb0b59969e374fcc003293e9353b948cc9f0dbf43b407e49ab4b11fdc566d3daa693d5a26482e48e0351be20ecb + checksum: 6c08d5d1b159472032d8a274eb29c22229dbcd29a80c478bbf680906903a9542dab9916d547e40c3b607a0ecfe51484bc8681b8c2f1fcd521b2b20fe23d84a66 languageName: node linkType: hard @@ -9648,7 +9648,7 @@ __metadata: "@material/mwc-top-app-bar": 0.27.0 "@material/mwc-top-app-bar-fixed": 0.27.0 "@material/top-app-bar": =14.0.0-canary.53b3cad2f.0 - "@material/web": =1.0.0-pre.10 + "@material/web": =1.0.0-pre.11 "@mdi/js": 7.2.96 "@mdi/svg": 7.2.96 "@octokit/auth-oauth-device": 5.0.2 From b6ed8acd028ba7dd5ca743840d9242be93bfc029 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 02:38:39 -0700 Subject: [PATCH 110/162] Dont mark blueprint fields with defaults as required (#16785) --- src/panels/config/automation/blueprint-automation-editor.ts | 3 ++- src/panels/config/script/blueprint-script-editor.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 3131a44b26..74d3d0586e 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -138,11 +138,12 @@ export class HaBlueprintAutomationEditor extends LitElement { this.config.use_blueprint.input[key]) ?? value?.default} .disabled=${this.disabled} + .required=${value?.default === undefined} @value-changed=${this._inputChanged} >` : html`` : html` Date: Mon, 26 Jun 2023 02:39:13 -0700 Subject: [PATCH 111/162] Add plant domain to enumerated states list (#17026) --- src/common/entity/get_states.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/entity/get_states.ts b/src/common/entity/get_states.ts index 4ceaf82d26..76e36ada3c 100644 --- a/src/common/entity/get_states.ts +++ b/src/common/entity/get_states.ts @@ -30,6 +30,7 @@ export const FIXED_DOMAIN_STATES = { lock: ["jammed", "locked", "locking", "unlocked", "unlocking"], media_player: ["idle", "off", "paused", "playing", "standby"], person: ["home", "not_home"], + plant: ["ok", "problem"], remote: ["on", "off"], scene: [], schedule: ["on", "off"], From 82463c2ef652205fa3a8c893115863eabe195f3c Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 02:42:32 -0700 Subject: [PATCH 112/162] Fix overview failing to render in some cases with toUpperCase exception (#17021) --- src/common/entity/strip_prefix_from_entity_name.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/common/entity/strip_prefix_from_entity_name.ts b/src/common/entity/strip_prefix_from_entity_name.ts index e976b7b18f..bbb024fa37 100644 --- a/src/common/entity/strip_prefix_from_entity_name.ts +++ b/src/common/entity/strip_prefix_from_entity_name.ts @@ -17,12 +17,13 @@ export const stripPrefixFromEntityName = ( if (lowerCasedEntityName.startsWith(lowerCasedPrefixWithSuffix)) { const newName = entityName.substring(lowerCasedPrefixWithSuffix.length); - - // If first word already has an upper case letter (e.g. from brand name) - // leave as-is, otherwise capitalize the first word. - return hasUpperCase(newName.substr(0, newName.indexOf(" "))) - ? newName - : newName[0].toUpperCase() + newName.slice(1); + if (newName.length) { + // If first word already has an upper case letter (e.g. from brand name) + // leave as-is, otherwise capitalize the first word. + return hasUpperCase(newName.substr(0, newName.indexOf(" "))) + ? newName + : newName[0].toUpperCase() + newName.slice(1); + } } } From f77f7b3c3611ecf7ff62dc3ec0d7fda8a124184b Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 26 Jun 2023 02:47:22 -0700 Subject: [PATCH 113/162] Catch errors when describeTrigger throws an exception (#17022) --- src/data/automation_i18n.ts | 40 +++++++++++++++++++++++++++++++++++++ src/data/script_i18n.ts | 26 ++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index 854d8501f7..f2ee1e0f17 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -81,6 +81,26 @@ export const describeTrigger = ( hass: HomeAssistant, entityRegistry: EntityRegistryEntry[], ignoreAlias = false +) => { + try { + return tryDescribeTrigger(trigger, hass, entityRegistry, ignoreAlias); + } catch (error: any) { + // eslint-disable-next-line no-console + console.error(error); + + let msg = "Error in describing trigger"; + if (error.message) { + msg += ": " + error.message; + } + return msg; + } +}; + +const tryDescribeTrigger = ( + trigger: Trigger, + hass: HomeAssistant, + entityRegistry: EntityRegistryEntry[], + ignoreAlias = false ) => { if (trigger.alias && !ignoreAlias) { return trigger.alias; @@ -625,6 +645,26 @@ export const describeCondition = ( hass: HomeAssistant, entityRegistry: EntityRegistryEntry[], ignoreAlias = false +) => { + try { + return tryDescribeCondition(condition, hass, entityRegistry, ignoreAlias); + } catch (error: any) { + // eslint-disable-next-line no-console + console.error(error); + + let msg = "Error in describing condition"; + if (error.message) { + msg += ": " + error.message; + } + return msg; + } +}; + +const tryDescribeCondition = ( + condition: Condition, + hass: HomeAssistant, + entityRegistry: EntityRegistryEntry[], + ignoreAlias = false ) => { if (condition.alias && !ignoreAlias) { return condition.alias; diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts index 90d807fb85..04819d448a 100644 --- a/src/data/script_i18n.ts +++ b/src/data/script_i18n.ts @@ -38,6 +38,32 @@ export const describeAction = ( action: ActionTypes[T], actionType?: T, ignoreAlias = false +): string => { + try { + return tryDescribeAction( + hass, + entityRegistry, + action, + actionType, + ignoreAlias + ); + } catch (error: any) { + // eslint-disable-next-line no-console + console.error(error); + let msg = "Error in describing action"; + if (error.message) { + msg += ": " + error.message; + } + return msg; + } +}; + +const tryDescribeAction = ( + hass: HomeAssistant, + entityRegistry: EntityRegistryEntry[], + action: ActionTypes[T], + actionType?: T, + ignoreAlias = false ): string => { if (action.alias && !ignoreAlias) { return action.alias; From 1dfd859a2d89407d5fa76f35eece4eda37ec75f7 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 26 Jun 2023 11:49:11 +0200 Subject: [PATCH 114/162] Circular slider improvements (#17008) --- .../components/ha-control-circular-slider.ts | 57 ++++-- src/components/ha-control-circular-slider.ts | 162 +++++++++++++----- 2 files changed, 158 insertions(+), 61 deletions(-) diff --git a/gallery/src/pages/components/ha-control-circular-slider.ts b/gallery/src/pages/components/ha-control-circular-slider.ts index 791fff7829..8c6fca52d4 100644 --- a/gallery/src/pages/components/ha-control-circular-slider.ts +++ b/gallery/src/pages/components/ha-control-circular-slider.ts @@ -10,23 +10,23 @@ export class DemoHaCircularSlider extends LitElement { private current = 22; @state() - private value = 19; + private low = 19; @state() private high = 25; @state() - private changingValue?: number; + private changingLow?: number; @state() private changingHigh?: number; - private _valueChanged(ev) { - this.value = ev.detail.value; + private _lowChanged(ev) { + this.low = ev.detail.value; } - private _valueChanging(ev) { - this.changingValue = ev.detail.value; + private _lowChanging(ev) { + this.changingLow = ev.detail.value; } private _highChanged(ev) { @@ -63,19 +63,40 @@ export class DemoHaCircularSlider extends LitElement {

Single

- Value: ${this.value} °C + Low: ${this.low} °C
Changing: - ${this.changingValue != null ? `${this.changingValue} °C` : "-"} + ${this.changingLow != null ? `${this.changingLow} °C` : "-"} +
+
+ + +
+

Inverted

+ +
+ High: ${this.high} °C +
+ Changing: + ${this.changingHigh != null ? `${this.changingHigh} °C` : "-"}
@@ -84,11 +105,11 @@ export class DemoHaCircularSlider extends LitElement {

Dual

- Low value: ${this.value} °C + Low value: ${this.low} °C
Low changing: - ${this.changingValue != null ? `${this.changingValue} °C` : "-"} + ${this.changingLow != null ? `${this.changingLow} °C` : "-"}
High value: ${this.high} °C
@@ -132,6 +153,10 @@ export class DemoHaCircularSlider extends LitElement { --control-circular-slider-background: #ff9800; --control-circular-slider-background-opacity: 0.3; } + ha-control-circular-slider[inverted] { + --control-circular-slider-color: #2196f3; + --control-circular-slider-background: #2196f3; + } ha-control-circular-slider[dual] { --control-circular-slider-high-color: #2196f3; --control-circular-slider-low-color: #ff9800; diff --git a/src/components/ha-control-circular-slider.ts b/src/components/ha-control-circular-slider.ts index 7b7472ddbc..97bc2ea566 100644 --- a/src/components/ha-control-circular-slider.ts +++ b/src/components/ha-control-circular-slider.ts @@ -68,6 +68,9 @@ export class HaControlCircularSlider extends LitElement { @property({ type: Boolean }) public dual?: boolean; + @property({ type: Boolean, reflect: true }) + public inverted?: boolean; + @property({ type: String }) public label?: string; @@ -80,15 +83,15 @@ export class HaControlCircularSlider extends LitElement { @property({ type: Number }) public value?: number; - @property({ type: Number }) - public current?: number; - @property({ type: Number }) public low?: number; @property({ type: Number }) public high?: number; + @property({ type: Number }) + public current?: number; + @property({ type: Number }) public step = 1; @@ -98,6 +101,15 @@ export class HaControlCircularSlider extends LitElement { @property({ type: Number }) public max = 100; + @state() + public _localValue?: number = this.value; + + @state() + public _localLow?: number = this.low; + + @state() + public _localHigh?: number = this.high; + @state() public _activeSlider?: ActiveSlider; @@ -120,17 +132,36 @@ export class HaControlCircularSlider extends LitElement { private _boundedValue(value: number) { const min = - this._activeSlider === "high" ? Math.min(this.low ?? this.max) : this.min; + this._activeSlider === "high" + ? Math.min(this._localLow ?? this.max) + : this.min; const max = - this._activeSlider === "low" ? Math.max(this.high ?? this.min) : this.max; + this._activeSlider === "low" + ? Math.max(this._localHigh ?? this.min) + : this.max; return Math.min(Math.max(value, min), max); } - protected firstUpdated(changedProperties: PropertyValues): void { - super.firstUpdated(changedProperties); + protected firstUpdated(changedProps: PropertyValues): void { + super.firstUpdated(changedProps); this._setupListeners(); } + protected updated(changedProps: PropertyValues): void { + super.updated(changedProps); + if (!this._activeSlider) { + if (changedProps.has("value")) { + this._localValue = this.value; + } + if (changedProps.has("low")) { + this._localLow = this.low; + } + if (changedProps.has("high")) { + this._localHigh = this.high; + } + } + } + connectedCallback(): void { super.connectedCallback(); this._setupListeners(); @@ -164,8 +195,8 @@ export class HaControlCircularSlider extends LitElement { private _findActiveSlider(value: number): ActiveSlider { if (!this.dual) return "value"; - const low = Math.max(this.low ?? this.min, this.min); - const high = Math.min(this.high ?? this.max, this.max); + const low = Math.max(this._localLow ?? this.min, this.min); + const high = Math.min(this._localHigh ?? this.max, this.max); if (low >= value) { return "low"; } @@ -178,13 +209,29 @@ export class HaControlCircularSlider extends LitElement { } private _setActiveValue(value: number) { - if (!this._activeSlider) return; - this[this._activeSlider] = value; + switch (this._activeSlider) { + case "high": + this._localHigh = value; + break; + case "low": + this._localLow = value; + break; + case "value": + this._localValue = value; + break; + } } private _getActiveValue(): number | undefined { - if (!this._activeSlider) return undefined; - return this[this._activeSlider]; + switch (this._activeSlider) { + case "high": + return this._localHigh; + case "low": + return this._localLow; + case "value": + return this._localValue; + } + return undefined; } _setupListeners() { @@ -235,6 +282,7 @@ export class HaControlCircularSlider extends LitElement { const raw = this._percentageToValue(percentage); const bounded = this._boundedValue(raw); const stepped = this._steppedValue(bounded); + this._setActiveValue(stepped); if (this._activeSlider) { fireEvent(this, `${this._activeSlider}-changing`, { value: undefined, @@ -340,23 +388,41 @@ export class HaControlCircularSlider extends LitElement { } } + private _strokeDashArc( + percentage: number, + inverted?: boolean + ): [string, string] { + const maxRatio = MAX_ANGLE / 360; + const f = RADIUS * 2 * Math.PI; + if (inverted) { + const arcLength = (1 - percentage) * f * maxRatio; + const strokeDasharray = `${arcLength} ${f - arcLength}`; + const strokeDashOffset = `${arcLength + f * (1 - maxRatio)}`; + return [strokeDasharray, strokeDashOffset]; + } + const arcLength = percentage * f * maxRatio; + const strokeDasharray = `${arcLength} ${f - arcLength}`; + const strokeDashOffset = "0"; + return [strokeDasharray, strokeDashOffset]; + } + protected render(): TemplateResult { const trackPath = arc({ x: 0, y: 0, start: 0, end: MAX_ANGLE, r: RADIUS }); - const maxRatio = MAX_ANGLE / 360; - - const f = RADIUS * 2 * Math.PI; - const lowValue = this.dual ? this.low : this.value; - const highValue = this.high; + const lowValue = this.dual ? this._localLow : this._localValue; + const highValue = this._localHigh; const lowPercentage = this._valueToPercentage(lowValue ?? this.min); const highPercentage = this._valueToPercentage(highValue ?? this.max); - const lowArcLength = lowPercentage * f * maxRatio; - const lowStrokeDasharray = `${lowArcLength} ${f - lowArcLength}`; + const [lowStrokeDasharray, lowStrokeDashOffset] = this._strokeDashArc( + lowPercentage, + this.inverted + ); - const highArcLength = (1 - highPercentage) * f * maxRatio; - const highStrokeDasharray = `${highArcLength} ${f - highArcLength}`; - const highStrokeDashOffset = `${highArcLength + f * (1 - maxRatio)}`; + const [highStrokeDasharray, highStrokeDashOffset] = this._strokeDashArc( + highPercentage, + true + ); const currentPercentage = this._valueToPercentage(this.current ?? 0); const currentAngle = currentPercentage * MAX_ANGLE; @@ -381,27 +447,31 @@ export class HaControlCircularSlider extends LitElement { - - ${this.dual + ${lowValue != null + ? svg` + + ` + : nothing} + ${this.dual && highValue != null ? svg` Date: Mon, 26 Jun 2023 12:33:05 +0200 Subject: [PATCH 115/162] Add missing aria-label to integration configure button (#17033) --- src/panels/config/integrations/ha-integration-card.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 9a620e3ed3..274fc92ed4 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -83,6 +83,9 @@ export class HaIntegrationCard extends LitElement { > From 68fb98454f76763973ce04c2179897f180af30f9 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 26 Jun 2023 12:50:51 +0200 Subject: [PATCH 116/162] Fix logbook for binary sensor (missing device class) (#17034) --- src/data/logbook.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data/logbook.ts b/src/data/logbook.ts index a30b9cde02..1bb048abdc 100644 --- a/src/data/logbook.ts +++ b/src/data/logbook.ts @@ -360,14 +360,14 @@ export const localizeStateMessage = ( if (isOn) { return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_device_class`, { device_class: localize( - `component.binary_sensor.device_class.${device_class}` + `component.binary_sensor.entity_component.${device_class}.name` ), }); } if (isOff) { return localize(`${LOGBOOK_LOCALIZE_PATH}.cleared_device_class`, { device_class: localize( - `component.binary_sensor.device_class.${device_class}` + `component.binary_sensor.entity_component.${device_class}.name` ), }); } From b40a3224fc0a3b5d0ea8837a9adcd8d23ea8fbdd Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 26 Jun 2023 14:21:08 +0200 Subject: [PATCH 117/162] Add "Clear" button to template editor + confirmation dialog (#17020) --- .../template/developer-tools-template.ts | 37 ++++++++++++++++++- src/translations/en.json | 2 + 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/panels/developer-tools/template/developer-tools-template.ts b/src/panels/developer-tools/template/developer-tools-template.ts index b21abece9f..fe0a0c158c 100644 --- a/src/panels/developer-tools/template/developer-tools-template.ts +++ b/src/panels/developer-tools/template/developer-tools-template.ts @@ -10,6 +10,7 @@ import { RenderTemplateResult, subscribeRenderTemplate, } from "../../../data/ws-templates"; +import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; @@ -142,6 +143,9 @@ class HaPanelDevTemplate extends LitElement { "ui.panel.developer-tools.tabs.templates.reset" )} + + ${this.hass.localize("ui.common.clear")} +
@@ -378,11 +382,42 @@ class HaPanelDevTemplate extends LitElement { localStorage["panel-dev-template-template"] = this._template; } - private _restoreDemo() { + private async _restoreDemo() { + if ( + !(await showConfirmationDialog(this, { + text: this.hass.localize( + "ui.panel.developer-tools.tabs.templates.confirm_reset" + ), + warning: true, + })) + ) { + return; + } this._template = DEMO_TEMPLATE; this._subscribeTemplate(); delete localStorage["panel-dev-template-template"]; } + + private async _clear() { + if ( + !(await showConfirmationDialog(this, { + text: this.hass.localize( + "ui.panel.developer-tools.tabs.templates.confirm_clear" + ), + warning: true, + })) + ) { + return; + } + this._unsubscribeTemplate(); + this._template = ""; + // Reset to empty result. Setting to 'undefined' results in a different visual + // behaviour compared to manually emptying the template input box. + this._templateResult = { + result: "", + listeners: { all: false, entities: [], domains: [], time: false }, + }; + } } declare global { diff --git a/src/translations/en.json b/src/translations/en.json index 883659695f..4479abbf2d 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5348,6 +5348,8 @@ "description": "Templates are rendered using the Jinja2 template engine with some Home Assistant specific extensions.", "editor": "Template editor", "reset": "Reset to demo template", + "confirm_reset": "Do you want to reset your current template back to the demo template?", + "confirm_clear": "Do you want to clear your current template?", "result_type": "Result type", "jinja_documentation": "Jinja2 template documentation", "template_extensions": "Home Assistant template extensions", From a3f0c428f85b66821869355771f8a9735f4aa972 Mon Sep 17 00:00:00 2001 From: ildar170975 <71872483+ildar170975@users.noreply.github.com> Date: Mon, 26 Jun 2023 15:25:14 +0300 Subject: [PATCH 118/162] Update hui-glance-card.ts: fix padding & margin for a focused entity (#17005) Co-authored-by: Bram Kragten --- src/panels/lovelace/cards/hui-glance-card.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-glance-card.ts b/src/panels/lovelace/cards/hui-glance-card.ts index 1e42db66c7..7e1bbedb0c 100644 --- a/src/panels/lovelace/cards/hui-glance-card.ts +++ b/src/panels/lovelace/cards/hui-glance-card.ts @@ -215,7 +215,8 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard { background: var(--divider-color); border-radius: 14px; padding: 4px; - margin: -4px 0; + margin-top: -4px; + margin-bottom: 8px; } .entity div { width: 100%; From 96a6261a099376dc03eb32d97f3a50157adbaaa4 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Mon, 26 Jun 2023 14:58:14 +0200 Subject: [PATCH 119/162] Automatic casing of nouns based on language (#17035) --- src/common/translations/auto_case_noun.ts | 19 +++++++++++++++++++ src/data/logbook.ts | 15 +++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 src/common/translations/auto_case_noun.ts diff --git a/src/common/translations/auto_case_noun.ts b/src/common/translations/auto_case_noun.ts new file mode 100644 index 0000000000..5099003631 --- /dev/null +++ b/src/common/translations/auto_case_noun.ts @@ -0,0 +1,19 @@ +// In a few languages nouns are always capitalized. This helper +// indicates if for a given language that is the case. + +import { capitalizeFirstLetter } from "../string/capitalize-first-letter"; + +export const useCapitalizedNouns = (language: string): boolean => { + switch (language) { + case "de": + case "lb": + return true; + default: + return false; + } +}; + +export const autoCaseNoun = (noun: string, language: string): string => + useCapitalizedNouns(language) + ? capitalizeFirstLetter(noun) + : noun.toLocaleLowerCase(language); diff --git a/src/data/logbook.ts b/src/data/logbook.ts index 1bb048abdc..f5caa718b7 100644 --- a/src/data/logbook.ts +++ b/src/data/logbook.ts @@ -7,6 +7,7 @@ import { import { computeDomain } from "../common/entity/compute_domain"; import { computeStateDisplay } from "../common/entity/compute_state_display"; import { computeStateDomain } from "../common/entity/compute_state_domain"; +import { autoCaseNoun } from "../common/translations/auto_case_noun"; import { LocalizeFunc } from "../common/translations/localize"; import { HaEntityPickerEntityFilterFunc } from "../components/entity/ha-entity-picker"; import { HomeAssistant } from "../types"; @@ -359,15 +360,21 @@ export const localizeStateMessage = ( case "vibration": if (isOn) { return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_device_class`, { - device_class: localize( - `component.binary_sensor.entity_component.${device_class}.name` + device_class: autoCaseNoun( + localize( + `component.binary_sensor.entity_component.${device_class}.name` + ), + hass.language ), }); } if (isOff) { return localize(`${LOGBOOK_LOCALIZE_PATH}.cleared_device_class`, { - device_class: localize( - `component.binary_sensor.entity_component.${device_class}.name` + device_class: autoCaseNoun( + localize( + `component.binary_sensor.entity_component.${device_class}.name` + ), + hass.language ), }); } From a637b7db758304c60061935a9ae99ca615bba906 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 26 Jun 2023 09:15:20 -0400 Subject: [PATCH 120/162] Automatically refresh when showing debug for a pipeline in progress (#17030) --- .../debug/assist-pipeline-debug.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts b/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts index e75f3a230f..9fb7782474 100644 --- a/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts +++ b/src/panels/config/voice-assistants/debug/assist-pipeline-debug.ts @@ -35,6 +35,8 @@ export class AssistPipelineDebug extends LitElement { @state() private _events?: PipelineRunEvent[]; + private _unsubRefreshEventsID?: number; + protected render() { return html` { + this._fetchEvents(); + }, 2000); } } From 06d9517e27a228015ba36b883fda7c5c06fa2f7a Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 26 Jun 2023 15:47:06 +0200 Subject: [PATCH 121/162] Add identify device class to button (#17036) --- src/common/entity/domain_icon.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/common/entity/domain_icon.ts b/src/common/entity/domain_icon.ts index fe4a911c79..fa92cc59b2 100644 --- a/src/common/entity/domain_icon.ts +++ b/src/common/entity/domain_icon.ts @@ -15,6 +15,7 @@ import { mdiCheckCircleOutline, mdiClock, mdiCloseCircleOutline, + mdiCrosshairsQuestion, mdiFan, mdiFanOff, mdiGestureTapButton, @@ -98,6 +99,8 @@ export const domainIconWithoutDefault = ( case "button": switch (stateObj?.attributes.device_class) { + case "identify": + return mdiCrosshairsQuestion; case "restart": return mdiRestart; case "update": From d169ff6a96669750e37491106ff63fc30f3f1ba6 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Mon, 26 Jun 2023 21:24:03 +0200 Subject: [PATCH 122/162] Update build system (#17040) --- pyproject.toml | 2 +- setup.cfg | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 setup.cfg diff --git a/pyproject.toml b/pyproject.toml index 8cac9f3594..a2db861dc4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools~=62.3", "wheel~=0.37.1"] +requires = ["setuptools~=68.0", "wheel~=0.40.0"] build-backend = "setuptools.build_meta" [project] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index e14c0e7b08..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -# Setuptools v62.3 doesn't support editable installs with just 'pyproject.toml' (PEP 660). -# Keep this file until it does! From d656269d7567299dc8b7d12731521520275178e2 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 26 Jun 2023 17:18:57 -0400 Subject: [PATCH 123/162] Remove attribution from Assist dialog (#17038) --- src/data/conversation.ts | 13 ---------- .../ha-voice-command-dialog.ts | 26 ------------------- 2 files changed, 39 deletions(-) diff --git a/src/data/conversation.ts b/src/data/conversation.ts index a51006a562..c63e6ba430 100644 --- a/src/data/conversation.ts +++ b/src/data/conversation.ts @@ -52,10 +52,6 @@ export interface ConversationResult { | IntentResultError; } -export interface AgentInfo { - attribution?: { name: string; url: string }; -} - export interface Agent { id: string; name: string; @@ -87,15 +83,6 @@ export const listAgents = ( country, }); -export const getAgentInfo = ( - hass: HomeAssistant, - agent_id?: string -): Promise => - hass.callWS({ - type: "conversation/agent/info", - agent_id, - }); - export const prepareConversation = ( hass: HomeAssistant, language?: string diff --git a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts index 1aa6695ba2..de68790067 100644 --- a/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts +++ b/src/dialogs/voice-command-dialog/ha-voice-command-dialog.ts @@ -35,7 +35,6 @@ import { listAssistPipelines, runAssistPipeline, } from "../../data/assist_pipeline"; -import { AgentInfo, getAgentInfo } from "../../data/conversation"; import { haStyleDialog } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; import { AudioRecorder } from "../../util/audio-recorder"; @@ -66,8 +65,6 @@ export class HaVoiceCommandDialog extends LitElement { @state() private _pipeline?: AssistPipeline; - @state() private _agentInfo?: AgentInfo; - @state() private _showSendButton = false; @state() private _pipelines?: AssistPipeline[]; @@ -115,7 +112,6 @@ export class HaVoiceCommandDialog extends LitElement { this._opened = false; this._pipeline = undefined; this._pipelines = undefined; - this._agentInfo = undefined; this._conversation = undefined; this._conversationId = null; this._audioRecorder?.close(); @@ -265,17 +261,6 @@ export class HaVoiceCommandDialog extends LitElement { `} - ${this._agentInfo && this._agentInfo.attribution - ? html` - ${this._agentInfo.attribution.name} - ` - : ""}
`; @@ -298,12 +283,7 @@ export class HaVoiceCommandDialog extends LitElement { if (e.code === "not_found") { this._pipelineId = undefined; } - return; } - this._agentInfo = await getAgentInfo( - this.hass, - this._pipeline.conversation_engine - ); } private async _loadPipelines() { @@ -728,12 +708,6 @@ export class HaVoiceCommandDialog extends LitElement { flex: 1 0; padding: 4px; } - .attribution { - display: block; - color: var(--secondary-text-color); - padding-top: 4px; - margin-bottom: -8px; - } .messages { display: block; height: 400px; From 87aad75cc78ad742f747eac705e008f47c55cc55 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 10:58:27 +0200 Subject: [PATCH 124/162] Add UI for conversation trigger (#17037) --- .../src/pages/automation/describe-trigger.ts | 5 + .../src/pages/automation/editor-trigger.ts | 11 ++ src/data/automation.ts | 6 + src/data/automation_i18n.ts | 18 ++ src/data/trigger.ts | 2 + .../trigger/ha-automation-trigger-row.ts | 1 + .../trigger/ha-automation-trigger.ts | 1 + .../ha-automation-trigger-conversation.ts | 174 ++++++++++++++++++ src/translations/en.json | 10 + 9 files changed, 228 insertions(+) create mode 100644 src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts diff --git a/gallery/src/pages/automation/describe-trigger.ts b/gallery/src/pages/automation/describe-trigger.ts index 3ebb26f017..f86c452340 100644 --- a/gallery/src/pages/automation/describe-trigger.ts +++ b/gallery/src/pages/automation/describe-trigger.ts @@ -51,6 +51,11 @@ const triggers = [ { platform: "tag" }, { platform: "time", at: "15:32" }, { platform: "template" }, + { platform: "conversation", command: "Turn on the lights" }, + { + platform: "conversation", + command: ["Turn on the lights", "Turn the lights on"], + }, { platform: "event", event_type: "homeassistant_started" }, ]; diff --git a/gallery/src/pages/automation/editor-trigger.ts b/gallery/src/pages/automation/editor-trigger.ts index 5dccee4fa0..cdc9ed2c83 100644 --- a/gallery/src/pages/automation/editor-trigger.ts +++ b/gallery/src/pages/automation/editor-trigger.ts @@ -25,6 +25,7 @@ import { HaDeviceTrigger } from "../../../../src/panels/config/automation/trigge 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"; const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ { @@ -112,6 +113,16 @@ const SCHEMAS: { name: string; triggers: Trigger[] }[] = [ name: "Device Trigger", triggers: [{ platform: "device", ...HaDeviceTrigger.defaultConfig }], }, + { + name: "Sentence", + triggers: [ + { platform: "conversation", ...HaConversationTrigger.defaultConfig }, + { + platform: "conversation", + command: ["Turn on the lights", "Turn the lights on"], + }, + ], + }, ]; @customElement("demo-automation-editor-trigger") diff --git a/src/data/automation.ts b/src/data/automation.ts index 3bb0dfff66..eff766e10d 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -107,6 +107,11 @@ export interface NumericStateTrigger extends BaseTrigger { for?: string | number | ForDict; } +export interface ConversationTrigger extends BaseTrigger { + platform: "conversation"; + command: string | string[]; +} + export interface SunTrigger extends BaseTrigger { platform: "sun"; offset: number; @@ -178,6 +183,7 @@ export type Trigger = | HassTrigger | NumericStateTrigger | SunTrigger + | ConversationTrigger | TimePatternTrigger | WebhookTrigger | PersistentNotificationTrigger diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index f2ee1e0f17..7b4e249386 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -610,6 +610,24 @@ const tryDescribeTrigger = ( ); } + // Conversation Trigger + if (trigger.platform === "conversation") { + if (!trigger.command) { + return hass.localize( + `${triggerTranslationBaseKey}.conversation.description.empty` + ); + } + + return hass.localize( + `${triggerTranslationBaseKey}.conversation.description.full`, + { + sentence: disjunctionFormatter.format( + ensureArray(trigger.command).map((cmd) => `'${cmd}'`) + ), + } + ); + } + // Persistent Notification Trigger if (trigger.platform === "persistent_notification") { return "When a persistent notification is updated"; diff --git a/src/data/trigger.ts b/src/data/trigger.ts index 3d6cf2558b..65ce25d726 100644 --- a/src/data/trigger.ts +++ b/src/data/trigger.ts @@ -9,6 +9,7 @@ import { mdiMapMarker, mdiMapMarkerRadius, mdiMessageAlert, + mdiMicrophoneMessage, mdiNfcVariant, mdiNumeric, mdiStateMachine, @@ -27,6 +28,7 @@ export const TRIGGER_TYPES = { mqtt: mdiSwapHorizontal, numeric_state: mdiNumeric, sun: mdiWeatherSunny, + conversation: mdiMicrophoneMessage, tag: mdiNfcVariant, template: mdiCodeBraces, time: mdiClockOutline, diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index 4719bc4074..cbc1e7bff3 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -53,6 +53,7 @@ import "./types/ha-automation-trigger-homeassistant"; import "./types/ha-automation-trigger-mqtt"; import "./types/ha-automation-trigger-numeric_state"; import "./types/ha-automation-trigger-persistent_notification"; +import "./types/ha-automation-trigger-conversation"; import "./types/ha-automation-trigger-state"; import "./types/ha-automation-trigger-sun"; import "./types/ha-automation-trigger-tag"; diff --git a/src/panels/config/automation/trigger/ha-automation-trigger.ts b/src/panels/config/automation/trigger/ha-automation-trigger.ts index fbe0539f8d..31acd3b0c4 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger.ts @@ -43,6 +43,7 @@ import "./types/ha-automation-trigger-homeassistant"; import "./types/ha-automation-trigger-mqtt"; import "./types/ha-automation-trigger-numeric_state"; import "./types/ha-automation-trigger-persistent_notification"; +import "./types/ha-automation-trigger-conversation"; import "./types/ha-automation-trigger-state"; import "./types/ha-automation-trigger-sun"; import "./types/ha-automation-trigger-tag"; diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts new file mode 100644 index 0000000000..f5cc84d862 --- /dev/null +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-conversation.ts @@ -0,0 +1,174 @@ +import { mdiClose } from "@mdi/js"; +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { customElement, property, query } from "lit/decorators"; +import { ensureArray } from "../../../../../common/array/ensure-array"; +import { fireEvent } from "../../../../../common/dom/fire_event"; +import "../../../../../components/ha-textfield"; +import type { HaTextField } from "../../../../../components/ha-textfield"; +import { ConversationTrigger } from "../../../../../data/automation"; +import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box"; +import { HomeAssistant } from "../../../../../types"; +import { TriggerElement } from "../ha-automation-trigger-row"; + +@customElement("ha-automation-trigger-conversation") +export class HaConversationTrigger + extends LitElement + implements TriggerElement +{ + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public trigger!: ConversationTrigger; + + @property({ type: Boolean }) public disabled = false; + + @query("#option_input", true) private _optionInput?: HaTextField; + + public static get defaultConfig(): Omit { + return { command: "" }; + } + + protected render() { + const { command } = this.trigger; + const commands = command ? ensureArray(command) : []; + + return html`${commands.length + ? commands.map( + (option, index) => html` + + + + ` + ) + : nothing} + `; + } + + private _handleKeyAdd(ev: KeyboardEvent) { + ev.stopPropagation(); + if (ev.key !== "Enter") { + return; + } + this._addOption(); + } + + private _addOption() { + const input = this._optionInput; + if (!input?.value) { + return; + } + fireEvent(this, "value-changed", { + value: { + ...this.trigger, + command: this.trigger.command.length + ? [ + ...(Array.isArray(this.trigger.command) + ? this.trigger.command + : [this.trigger.command]), + input.value, + ] + : input.value, + }, + }); + input.value = ""; + } + + private async _updateOption(ev: Event) { + const index = (ev.target as any).index; + const command = [...this.trigger.command]; + command.splice(index, 1, (ev.target as HaTextField).value); + fireEvent(this, "value-changed", { + value: { ...this.trigger, command }, + }); + } + + private async _removeOption(ev: Event) { + const index = (ev.target as any).parentElement.index; + if ( + !(await showConfirmationDialog(this, { + title: this.hass.localize( + "ui.panel.config.automation.editor.triggers.type.conversation.delete" + ), + text: this.hass.localize( + "ui.panel.config.automation.editor.triggers.type.conversation.confirm_delete" + ), + destructive: true, + })) + ) { + return; + } + let command: string[] | string; + if (!Array.isArray(this.trigger.command)) { + command = ""; + } else { + command = [...this.trigger.command]; + command.splice(index, 1); + } + fireEvent(this, "value-changed", { + value: { ...this.trigger, command }, + }); + } + + static get styles(): CSSResultGroup { + return css` + .layout { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + justify-content: flex-start; + } + .option { + margin-top: 4px; + } + mwc-button { + margin-left: 8px; + } + ha-textfield { + display: block; + margin-bottom: 8px; + --textfield-icon-trailing-padding: 0; + } + ha-textfield > ha-icon-button { + position: relative; + right: -8px; + --mdc-icon-button-size: 36px; + --mdc-icon-size: 20px; + color: var(--secondary-text-color); + inset-inline-start: initial; + inset-inline-end: -8px; + direction: var(--direction); + } + #option_input { + margin-top: 8px; + } + .header { + margin-top: 8px; + margin-bottom: 8px; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-automation-trigger-conversation": HaConversationTrigger; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index 4479abbf2d..14c9a0123b 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2378,6 +2378,16 @@ "rises": "When the sun rises{hasDuration, select, \n true { offset by {duration}} \n other {}\n }" } }, + "conversation": { + "label": "Sentence", + "add_sentence": "Add sentence", + "delete": "Delete sentence", + "confirm_delete": "Are you sure you want to delete this sentence?", + "description": { + "empty": "When a sentence is said", + "full": "When the sentence {sentence} is said" + } + }, "tag": { "label": "Tag", "description": { From 3111c29049f4161fa9603590cd1eb261b1eae02a Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 27 Jun 2023 07:54:18 -0700 Subject: [PATCH 125/162] Fix group more-info to show the state of the group entity (#17052) --- src/dialogs/more-info/controls/more-info-group.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/dialogs/more-info/controls/more-info-group.ts b/src/dialogs/more-info/controls/more-info-group.ts index 0f5131c395..8006228e16 100644 --- a/src/dialogs/more-info/controls/more-info-group.ts +++ b/src/dialogs/more-info/controls/more-info-group.ts @@ -46,7 +46,8 @@ class MoreInfoGroup extends LitElement { return; } - const baseStateObj = states.find((s) => s.state === "on") || states[0]; + const baseStateObj = + states.find((s) => s.state === this.stateObj!.state) || states[0]; const groupDomain = computeGroupDomain(this.stateObj); @@ -56,6 +57,8 @@ class MoreInfoGroup extends LitElement { this._groupDomainStateObj = { ...baseStateObj, entity_id: this.stateObj.entity_id, + last_updated: this.stateObj.last_updated, + last_changed: this.stateObj.last_changed, attributes: { ...baseStateObj.attributes, friendly_name: this.stateObj.attributes.friendly_name, From d63d3a681ca24b2b5e76a2fc20fcb2959ce8bba6 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:19:19 +0200 Subject: [PATCH 126/162] Fix split area into separate devices and entities (#17017) --- src/components/ha-service-control.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/components/ha-service-control.ts b/src/components/ha-service-control.ts index bc0cc718c1..21e5289e5f 100644 --- a/src/components/ha-service-control.ts +++ b/src/components/ha-service-control.ts @@ -249,12 +249,16 @@ export class HaServiceControl extends LitElement { ) { const targetSelector = target ? { target } : { target: {} }; const targetEntities = - ensureArray(value?.target?.entity_id || value?.data?.entity_id) || []; + ensureArray( + value?.target?.entity_id || value?.data?.entity_id + )?.slice() || []; const targetDevices = - ensureArray(value?.target?.device_id || value?.data?.device_id) || []; + ensureArray( + value?.target?.device_id || value?.data?.device_id + )?.slice() || []; const targetAreas = ensureArray( value?.target?.area_id || value?.data?.area_id - ); + )?.slice(); if (targetAreas) { targetAreas.forEach((areaId) => { const expanded = expandAreaTarget( From 9a116d40229cb0f1c4cf8bfb8bdb5d087e3ad62c Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 27 Jun 2023 17:19:56 +0200 Subject: [PATCH 127/162] Update dialog-add-user input fields (#17039) --- src/panels/config/users/dialog-add-user.ts | 53 ++++++++++++---------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/src/panels/config/users/dialog-add-user.ts b/src/panels/config/users/dialog-add-user.ts index c8154991ea..345dfcfc1a 100644 --- a/src/panels/config/users/dialog-add-user.ts +++ b/src/panels/config/users/dialog-add-user.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@polymer/paper-input/paper-input"; import { css, CSSResultGroup, @@ -14,6 +13,7 @@ import "../../../components/ha-circular-progress"; import { createCloseHeading } from "../../../components/ha-dialog"; import "../../../components/ha-formfield"; import "../../../components/ha-switch"; +import type { HaSwitch } from "../../../components/ha-switch"; import { createAuthForUser } from "../../../data/auth"; import { createUser, @@ -25,6 +25,8 @@ import { import { ValueChangedEvent, HomeAssistant } from "../../../types"; import { haStyleDialog } from "../../../resources/styles"; import { AddUserDialogParams } from "./show-dialog-add-user"; +import "../../../components/ha-textfield"; +import type { HaTextField } from "../../../components/ha-textfield"; @customElement("dialog-add-user") export class DialogAddUser extends LitElement { @@ -97,7 +99,7 @@ export class DialogAddUser extends LitElement {
${this._error ? html`
${this._error}
` : ""} ${this._allowChangeName - ? html` ` + >` : ""} - + > - + > - + >
): void { this._error = undefined; - const name = (ev.target as any).name; - this[`_${name}`] = ev.detail.value; + const target = ev.target as HaTextField; + this[`_${target.name}`] = target.value; } - private async _adminChanged(ev): Promise { - this._isAdmin = ev.target.checked; + private async _adminChanged(ev: Event): Promise { + const target = ev.target as HaSwitch; + this._isAdmin = target.checked; } - private _localOnlyChanged(ev): void { - this._localOnly = ev.target.checked; + private _localOnlyChanged(ev: Event): void { + const target = ev.target as HaSwitch; + this._localOnly = target.checked; } - private async _createUser(ev) { + private async _createUser(ev: Event) { ev.preventDefault(); if (!this._name || !this._username || !this._password) { return; @@ -299,6 +298,10 @@ export class DialogAddUser extends LitElement { display: flex; padding: 8px 0; } + ha-textfield { + display: block; + margin-bottom: 16px; + } `, ]; } From 381c9f97d671c3117fc74814738a61893214ee96 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Tue, 27 Jun 2023 08:21:23 -0700 Subject: [PATCH 128/162] Bar chart should start from zero (#16815) --- src/components/chart/statistics-chart.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index d9f30d9d67..d3edd154f7 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -166,7 +166,7 @@ class StatisticsChart extends LitElement { }, }, y: { - beginAtZero: false, + beginAtZero: this.chartType === "bar", ticks: { maxTicksLimit: 7, }, From 48b6c2a9251c79f4c92bf083974aa98b6151819e Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 27 Jun 2023 17:23:46 +0200 Subject: [PATCH 129/162] Add animation for locking and unlocking state (#17053) --- .../lock/ha-more-info-lock-toggle.ts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts b/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts index f8a005002c..aafecef40d 100644 --- a/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts +++ b/src/dialogs/more-info/components/lock/ha-more-info-lock-toggle.ts @@ -7,6 +7,7 @@ import { TemplateResult, } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import { domainIcon } from "../../../../common/entity/domain_icon"; import { stateColorCss } from "../../../../common/entity/state_color"; @@ -136,8 +137,6 @@ export class HaMoreInfoLockToggle extends LitElement { return html` + + `; } static get styles(): CSSResultGroup { return css` + @keyframes pulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0; + } + 100% { + opacity: 1; + } + } ha-control-switch { height: 45vh; max-height: 320px; @@ -164,6 +184,9 @@ export class HaMoreInfoLockToggle extends LitElement { --control-switch-padding: 6px; --mdc-icon-size: 24px; } + .pulse { + animation: pulse 1s infinite; + } .buttons { display: flex; flex-direction: column; From 349311a18d4629fbd4a326ca7da62813d6f3437f Mon Sep 17 00:00:00 2001 From: Denis Shulyaka Date: Tue, 27 Jun 2023 18:24:45 +0300 Subject: [PATCH 130/162] humidifier card: display the current humidity (#14645) * humidifier card: display the value of current humidity sensor Signed-off-by: Denis Shulyaka * rename set-values and current-humidity to main-humidity and secondary-humidity * removed more-info dialog for current-humidity * swap target and current humidity * remove current humidity rounding * use current_humidity attribute * Add current_humidity attribute * prettier * Revert hui-humidifier-card-editor.ts * Revert types.ts * Revert en.json * Update hui-humidifier-card.ts * Update hui-humidifier-card.ts * prettier * Use formatNumber * Apply suggestions from code review * Swap back current humidity and target humidity --------- Signed-off-by: Denis Shulyaka --- src/data/humidifier.ts | 1 + .../lovelace/cards/hui-humidifier-card.ts | 53 +++++++++++++++---- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/data/humidifier.ts b/src/data/humidifier.ts index dbf0093c61..ace536b9ca 100644 --- a/src/data/humidifier.ts +++ b/src/data/humidifier.ts @@ -13,6 +13,7 @@ export type HumidifierEntity = HassEntityBase & { state: HumidifierState; attributes: HassEntityAttributeBase & { humidity?: number; + current_humidity?: number; min_humidity?: number; max_humidity?: number; mode?: string; diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index 9e24121a29..0f65259d24 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -17,6 +17,7 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; +import { formatNumber } from "../../../common/number/format_number"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; import { isUnavailableState } from "../../../data/entity"; @@ -88,6 +89,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { const name = this._config!.name || computeStateName(this.hass!.states[this._config!.entity]); + const targetHumidity = stateObj.attributes.humidity !== null && Number.isFinite(Number(stateObj.attributes.humidity)) @@ -96,6 +98,12 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { const setHumidity = this._setHum ? this._setHum : targetHumidity; + const curHumidity = + stateObj.attributes.current_humidity !== null && + Number.isFinite(Number(stateObj.attributes.current_humidity)) + ? stateObj.attributes.current_humidity + : undefined; + const rtlDirection = computeRTLDirection(this.hass); const slider = isUnavailableState(stateObj.state) @@ -114,23 +122,36 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { `; const setValues = html` - + ${isUnavailableState(stateObj.state) || setHumidity === undefined || setHumidity === null ? "" : svg` - ${setHumidity.toFixed()} - - % - - `} + ${formatNumber(setHumidity, this.hass.locale, { + maximumFractionDigits: 0, + })} + + % + + `} `; + + const currentHumidity = html` + + + ${curHumidity + ? svg`${formatNumber(curHumidity, this.hass.locale)}` + : ""} + + + `; + const currentMode = html` - + ${this.hass!.localize(`state.default.${stateObj.state}`)} ${stateObj.attributes.mode && !isUnavailableState(stateObj.state) @@ -172,7 +193,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { > ${setValues} - ${currentMode} + ${currentHumidity} ${currentMode}
@@ -335,9 +356,9 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { overflow-wrap: break-word; } - #humidity { + #mode { max-width: 80%; - transform: translate(0, 350%); + transform: translate(0, 250%); } #set-values { @@ -351,9 +372,19 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { font-size: 4px; } + #current_humidity { + max-width: 80%; + transform: translate(0, 300%); + } + + #current-humidity { + fill: var(--primary-text-color); + font-size: 5px; + } + .toggle-button { color: var(--primary-text-color); - width: 60%; + width: 75%; height: auto; position: absolute; max-width: calc(100% - 40px); From 9e5774525fd7a3b29cffcc38fbb6b553a90ddfbf Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:22:02 +0200 Subject: [PATCH 131/162] Add service response support to dev tools (#17044) * Add service response support to dev tools * Change to `response_variable` --- src/data/script.ts | 2 + src/data/service.ts | 4 +- .../service/developer-tools-service.ts | 43 ++++++++++++++++--- src/translations/en.json | 1 + 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/data/script.ts b/src/data/script.ts index b679b0a22f..942296cef8 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -116,6 +116,7 @@ export interface ServiceAction extends BaseAction { entity_id?: string; target?: HassServiceTarget; data?: Record; + response_variable?: string; } export interface DeviceAction extends BaseAction { @@ -221,6 +222,7 @@ export interface VariablesAction extends BaseAction { export interface StopAction extends BaseAction { stop: string; + response_variable?: string; error?: boolean; } diff --git a/src/data/service.ts b/src/data/service.ts index b9ca93fe87..f93312ecf2 100644 --- a/src/data/service.ts +++ b/src/data/service.ts @@ -1,10 +1,10 @@ -import { HomeAssistant } from "../types"; +import { Context, HomeAssistant } from "../types"; import { Action } from "./script"; export const callExecuteScript = ( hass: HomeAssistant, sequence: Action | Action[] -) => +): Promise<{ context: Context; response: Record }> => hass.callWS({ type: "execute_script", sequence, diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index 6096bd16b4..996f377f5f 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -1,7 +1,7 @@ import { mdiHelpCircle } from "@mdi/js"; import { ERR_CONNECTION_LOST } from "home-assistant-js-websocket"; import { load } from "js-yaml"; -import { css, CSSResultGroup, html, LitElement } from "lit"; +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { property, query, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { storage } from "../../../common/decorators/storage"; @@ -20,7 +20,7 @@ import "../../../components/ha-service-picker"; import "../../../components/ha-yaml-editor"; import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import { forwardHaptic } from "../../../data/haptics"; -import { ServiceAction } from "../../../data/script"; +import { Action, ServiceAction } from "../../../data/script"; import { callExecuteScript, serviceCallWillDisconnect, @@ -38,6 +38,8 @@ class HaPanelDevService extends LitElement { @state() private _uiAvailable = true; + @state() private _response?: Record; + @storage({ key: "panel-dev-service-state-service-data", state: true, @@ -52,7 +54,7 @@ class HaPanelDevService extends LitElement { }) private _yamlMode = false; - @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; + @query("#yaml-editor") private _yamlEditor?: HaYamlEditor; protected firstUpdated(params) { super.firstUpdated(params); @@ -109,6 +111,7 @@ class HaPanelDevService extends LitElement { @value-changed=${this._serviceChanged} >
- + ${this._response + ? html`
+ +
+ +
+
+
` + : nothing} ${(this._yamlMode ? fields : this._filterSelectorFields(fields)).length ? html`
${this._yamlMode - ? html`
+ ? html`

${target ? html` @@ -317,10 +336,20 @@ class HaPanelDevService extends LitElement { if (!this._serviceData?.service) { return; } + const [domain, service] = this._serviceData.service.split(".", 2); + const script: Action[] = []; + if ("response" in this.hass.services[domain][service]) { + script.push({ + ...this._serviceData, + response_variable: "service_result", + }); + script.push({ stop: "done", response_variable: "service_result" }); + } else { + script.push(this._serviceData); + } try { - await callExecuteScript(this.hass, [this._serviceData]); + this._response = (await callExecuteScript(this.hass, script)).response; } catch (err: any) { - const [domain, service] = this._serviceData.service.split(".", 2); if ( err.error?.code === ERR_CONNECTION_LOST && serviceCallWillDisconnect(domain, service) diff --git a/src/translations/en.json b/src/translations/en.json index 14c9a0123b..865a1d23db 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5322,6 +5322,7 @@ "title": "Services", "description": "The service dev tool allows you to call any available service in Home Assistant.", "call_service": "Call Service", + "response": "Response", "column_parameter": "Parameter", "column_description": "Description", "column_example": "Example", From 3bb5e95c505f18303a7a59462384181f18843cf7 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:28:20 +0200 Subject: [PATCH 132/162] Show if automation is unavailable and why (#17048) --- src/common/entity/domain_icon.ts | 7 ++- .../config/automation/ha-automation-editor.ts | 50 +++++++++++++++++-- .../config/automation/ha-automation-picker.ts | 12 ++++- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/common/entity/domain_icon.ts b/src/common/entity/domain_icon.ts index fa92cc59b2..3ced61b3f8 100644 --- a/src/common/entity/domain_icon.ts +++ b/src/common/entity/domain_icon.ts @@ -32,6 +32,7 @@ import { mdiPowerPlugOff, mdiRestart, mdiRobot, + mdiRobotConfused, mdiRobotOff, mdiSpeaker, mdiSpeakerOff, @@ -92,7 +93,11 @@ export const domainIconWithoutDefault = ( return alarmPanelIcon(compareState); case "automation": - return compareState === "off" ? mdiRobotOff : mdiRobot; + return compareState === "unavailable" + ? mdiRobotConfused + : compareState === "off" + ? mdiRobotOff + : mdiRobot; case "binary_sensor": return binarySensorIcon(compareState, stateObj); diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index ecc97fb23d..9238852502 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -11,6 +11,7 @@ import { mdiPlay, mdiPlayCircleOutline, mdiRenameBox, + mdiRobotConfused, mdiStopCircleOutline, mdiTransitConnection, } from "@mdi/js"; @@ -22,6 +23,7 @@ import { TemplateResult, css, html, + nothing, } from "lit"; import { property, query, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; @@ -62,6 +64,8 @@ import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-a import { showAutomationRenameDialog } from "./automation-rename-dialog/show-dialog-automation-rename"; import "./blueprint-automation-editor"; import "./manual-automation-editor"; +import { UNAVAILABLE } from "../../../data/entity"; +import { validateConfig } from "../../../data/config"; declare global { interface HTMLElementTagNameMap { @@ -106,6 +110,8 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { @state() private _readOnly = false; + @state() private _validationErrors?: (string | TemplateResult)[]; + @query("ha-yaml-editor", true) private _yamlEditor?: HaYamlEditor; private _configSubscriptions: Record< @@ -291,9 +297,20 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { })}" @subscribe-automation-config=${this._subscribeAutomationConfig} > - ${this._errors - ? html` - ${this._errors} + ${this._errors || stateObj?.state === UNAVAILABLE + ? html` + ${this._errors || this._validationErrors} + ${stateObj?.state === UNAVAILABLE + ? html`` + : nothing} ` : ""} ${this._mode === "gui" @@ -427,6 +444,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { if (changedProps.has("entityId") && this.entityId) { getAutomationStateConfig(this.hass, this.entityId).then((c) => { this._config = this._normalizeConfig(c.config); + this._checkValidation(); }); this._entityId = this.entityId; this._dirty = false; @@ -455,6 +473,30 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { this._entityId = automation?.entity_id; } + private async _checkValidation() { + this._validationErrors = undefined; + if (!this._entityId || !this._config) { + return; + } + const stateObj = this.hass.states[this._entityId]; + if (stateObj?.state !== UNAVAILABLE) { + return; + } + const validation = await validateConfig(this.hass, { + trigger: this._config.trigger, + condition: this._config.condition, + action: this._config.action, + }); + this._validationErrors = Object.entries(validation).map(([key, value]) => + value.valid + ? "" + : html`${this.hass.localize( + `ui.panel.config.automation.editor.${key}s.header` + )}: + ${value.error}
` + ); + } + private _normalizeConfig(config: AutomationConfig): AutomationConfig { // Normalize data: ensure trigger, action and condition are lists // Happens when people copy paste their automations into the config @@ -476,6 +518,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { this._dirty = false; this._readOnly = false; this._config = this._normalizeConfig(config); + this._checkValidation(); } catch (err: any) { const entityRegistry = await fetchEntityRegistry(this.hass.connection); const entity = entityRegistry.find( @@ -686,6 +729,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { await this._promptAutomationAlias(); } + this._validationErrors = undefined; try { await saveAutomationConfig(this.hass, id, this._config!); } catch (errors: any) { diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index eb1003aa0b..65af78bae3 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -15,6 +15,7 @@ import { CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { differenceInDays } from "date-fns/esm"; +import { styleMap } from "lit/directives/style-map"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { formatShortDateTime } from "../../../common/datetime/format_date_time"; import { relativeTime } from "../../../common/datetime/relative_time"; @@ -52,6 +53,7 @@ import { configSections } from "../ha-panel-config"; import { showNewAutomationDialog } from "./show-dialog-new-automation"; import { findRelated } from "../../../data/search"; import { fetchBlueprints } from "../../../data/blueprint"; +import { UNAVAILABLE } from "../../../data/entity"; @customElement("ha-automation-picker") class HaAutomationPicker extends LitElement { @@ -106,7 +108,15 @@ class HaAutomationPicker extends LitElement { ), type: "icon", template: (_, automation) => - html``, + html``, }, name: { title: this.hass.localize( From 4761036816231b768b2180c9cd4dd3dcd60b753e Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:28:53 +0200 Subject: [PATCH 133/162] Show if script is unavailable and why (#17051) --- src/panels/config/script/ha-script-editor.ts | 81 ++++++++++++++------ src/panels/config/script/ha-script-picker.ts | 10 ++- 2 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 73f9104dbf..a64a53b9fa 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -60,6 +60,8 @@ import { documentationUrl } from "../../../util/documentation-url"; import { showToast } from "../../../util/toast"; import "./blueprint-script-editor"; import "./manual-script-editor"; +import { UNAVAILABLE } from "../../../data/entity"; +import { validateConfig } from "../../../data/config"; export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; @@ -92,6 +94,8 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @query("ha-yaml-editor", true) private _yamlEditor?: HaYamlEditor; + @state() private _validationErrors?: (string | TemplateResult)[]; + private _schema = memoizeOne( ( hasID: boolean, @@ -160,6 +164,10 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { return nothing; } + const stateObj = this._entityId + ? this.hass.states[this._entityId] + : undefined; + const useBlueprint = "use_blueprint" in this._config; const schema = this._schema( @@ -302,6 +310,26 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { "yaml-mode": this._mode === "yaml", })}" > + ${this._errors || stateObj?.state === UNAVAILABLE + ? html` + + ${this._errors || this._validationErrors} + + ` + : ""} + ${this._readOnly + ? html` + ${this.hass.localize("ui.panel.config.script.editor.read_only")} + + ${this.hass.localize("ui.panel.config.script.editor.migrate")} + + ` + : ""} ${this._mode === "gui" ? html`
- ${this._errors - ? html` - - ${this._errors} - - ` - : ""}
- ${this.hass.localize( - "ui.panel.config.script.editor.read_only" - )} - - ${this.hass.localize( - "ui.panel.config.script.editor.migrate" - )} - - ` - : ""} - ${this._errors - ? html` - ${this._errors} - ` - : ""} + ent.platform === "script" && ent.unique_id === this.scriptId + ); + this._entityId = entity?.entity_id; + this._checkValidation(); }, (resp) => { const entity = this.entityRegistry.find( @@ -479,6 +489,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { if (changedProps.has("entityId") && this.entityId) { getScriptStateConfig(this.hass, this.entityId).then((c) => { this._config = this._normalizeConfig(c.config); + this._checkValidation(); }); const regEntry = this.entityRegistry.find( (ent) => ent.entity_id === this.entityId @@ -502,6 +513,28 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { return config; } + private async _checkValidation() { + this._validationErrors = undefined; + if (!this._entityId || !this._config) { + return; + } + const stateObj = this.hass.states[this._entityId]; + if (stateObj?.state !== UNAVAILABLE) { + return; + } + const validation = await validateConfig(this.hass, { + action: this._config.sequence, + }); + this._validationErrors = Object.entries(validation).map(([key, value]) => + value.valid + ? "" + : html`${this.hass.localize( + `ui.panel.config.automation.editor.${key}s.header` + )}: + ${value.error}
` + ); + } + private _computeLabelCallback = ( schema: SchemaUnion>, data: HaFormDataContainer diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index 491d13599d..7433bb98e5 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -12,6 +12,7 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { differenceInDays } from "date-fns/esm"; +import { styleMap } from "lit/directives/style-map"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { formatShortDateTime } from "../../../common/datetime/format_date_time"; import { relativeTime } from "../../../common/datetime/relative_time"; @@ -49,6 +50,7 @@ import { showNewAutomationDialog } from "../automation/show-dialog-new-automatio import { EntityRegistryEntry } from "../../../data/entity_registry"; import { findRelated } from "../../../data/search"; import { fetchBlueprints } from "../../../data/blueprint"; +import { UNAVAILABLE } from "../../../data/entity"; @customElement("ha-script-picker") class HaScriptPicker extends LitElement { @@ -100,7 +102,13 @@ class HaScriptPicker extends LitElement { ), type: "icon", template: (_icon, script) => - html``, + html``, }, name: { title: this.hass.localize("ui.panel.config.script.picker.headers.name"), From 3b8ea5edbe08e9feac7fdeed0f5adf1b0ca19fc6 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:29:37 +0200 Subject: [PATCH 134/162] Add keyfunction to datatable virtualizer (#17049) --- src/components/data-table/ha-data-table.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index 8ca1d6f68b..6aa6233b6d 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -349,6 +349,7 @@ export class HaDataTable extends LitElement { class="mdc-data-table__content scroller ha-scrollbar" @scroll=${this._saveScrollPos} .items=${this._items} + .keyFunction=${this._keyFunction} .renderItem=${this._renderRow} > `} @@ -357,6 +358,8 @@ export class HaDataTable extends LitElement { `; } + private _keyFunction = (row: DataTableRowData) => row[this.id] || row; + private _renderRow = (row: DataTableRowData, index: number) => { // not sure how this happens... if (!row) { From 343708cdaaff8c594c535493ee7c069b0f05e215 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 27 Jun 2023 18:36:56 +0200 Subject: [PATCH 135/162] Align humidifier thermostat card (#17054) --- src/common/entity/compute_state_display.ts | 6 - .../lovelace/cards/hui-humidifier-card.ts | 295 +++++++++++------- .../lovelace/cards/hui-thermostat-card.ts | 79 ++--- src/panels/lovelace/cards/hui-tile-card.ts | 30 +- 4 files changed, 233 insertions(+), 177 deletions(-) diff --git a/src/common/entity/compute_state_display.ts b/src/common/entity/compute_state_display.ts index 9c768bd55e..c41bde1263 100644 --- a/src/common/entity/compute_state_display.ts +++ b/src/common/entity/compute_state_display.ts @@ -169,12 +169,6 @@ export const computeStateDisplayFromEntityAttributes = ( } } - if (domain === "humidifier") { - if (state === "on" && attributes.humidity) { - return `${attributes.humidity} %`; - } - } - // `counter` `number` and `input_number` domains do not have a unit of measurement but should still use `formatNumber` if ( domain === "counter" || diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index 0f65259d24..bca4924cc1 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -1,26 +1,30 @@ -import { mdiDotsVertical } from "@mdi/js"; +import { mdiDotsVertical, mdiPower, mdiWaterPercent } from "@mdi/js"; import "@thomasloven/round-slider"; import { HassEntity } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, - svg, + css, + html, nothing, + svg, } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; +import { styleMap } from "lit/directives/style-map"; import { classMap } from "lit/directives/class-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; +import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; -import { computeRTLDirection } from "../../../common/util/compute_rtl"; +import { stateColorCss } from "../../../common/entity/state_color"; import { formatNumber } from "../../../common/number/format_number"; +import { computeRTLDirection } from "../../../common/util/compute_rtl"; import "../../../components/ha-card"; +import type { HaCard } from "../../../components/ha-card"; import "../../../components/ha-icon-button"; -import { isUnavailableState } from "../../../data/entity"; +import { UNAVAILABLE, isUnavailableState } from "../../../data/entity"; import { HumidifierEntity } from "../../../data/humidifier"; import { HomeAssistant } from "../../../types"; import { findEntities } from "../common/find-entities"; @@ -60,8 +64,10 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { @state() private _setHum?: number; + @query("ha-card") private _card?: HaCard; + public getCardSize(): number { - return 6; + return 7; } public setConfig(config: HumidifierCardConfig): void { @@ -98,19 +104,12 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { const setHumidity = this._setHum ? this._setHum : targetHumidity; - const curHumidity = - stateObj.attributes.current_humidity !== null && - Number.isFinite(Number(stateObj.attributes.current_humidity)) - ? stateObj.attributes.current_humidity - : undefined; - const rtlDirection = computeRTLDirection(this.hass); const slider = isUnavailableState(stateObj.state) ? html` ` : html` `; - const setValues = html` - - - ${isUnavailableState(stateObj.state) || - setHumidity === undefined || - setHumidity === null - ? "" - : svg` - ${formatNumber(setHumidity, this.hass.locale, { - maximumFractionDigits: 0, - })} - - % - - `} + const currentHumidity = svg` + + + ${ + stateObj.state !== UNAVAILABLE && + stateObj.attributes.current_humidity != null && + !isNaN(stateObj.attributes.current_humidity) + ? svg` + ${formatNumber( + stateObj.attributes.current_humidity, + this.hass.locale + )} + + % + + ` + : nothing + } - `; + `; - const currentHumidity = html` - - - ${curHumidity - ? svg`${formatNumber(curHumidity, this.hass.locale)}` - : ""} - - - `; - - const currentMode = html` - - - ${this.hass!.localize(`state.default.${stateObj.state}`)} - ${stateObj.attributes.mode && !isUnavailableState(stateObj.state) - ? html` - - - ${computeAttributeValueDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "mode" - )} - ` - : ""} - + const setValues = svg` + + + + ${ + stateObj.state !== UNAVAILABLE && setHumidity != null + ? formatNumber(setHumidity, this.hass.locale, { + maximumFractionDigits: 0, + }) + : nothing + } + + + ${computeStateDisplay( + this.hass.localize, + stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities + )} + ${ + stateObj.state !== UNAVAILABLE && stateObj.attributes.mode + ? html` + - + ${computeAttributeValueDisplay( + this.hass.localize, + stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities, + "mode" + )} + ` + : nothing + } + + `; return html` - + ${slider}
- - ${setValues} - - ${currentHumidity} ${currentMode} +
${currentHumidity} ${setValues}
-
${name}
+
+
+ + + + +
+ ${name} +

`; @@ -231,6 +275,15 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { ) { applyThemesOnElement(this, this.hass.themes, this._config.theme); } + + const stateObj = this.hass.states[this._config.entity]; + if (!stateObj) { + return; + } + + if (!oldHass || oldHass.states[this._config.entity] !== stateObj) { + this._rescale_svg(); + } } public willUpdate(changedProps: PropertyValues) { @@ -250,6 +303,27 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { } } + private _rescale_svg() { + // Set the viewbox of the SVG containing the set temperature to perfectly + // fit the text + // That way it will auto-scale correctly + // This is not done to the SVG containing the current temperature, because + // it should not be centered on the text, but only on the value + const card = this._card; + if (card) { + card.updateComplete.then(() => { + const svgRoot = this.shadowRoot!.querySelector("#set-values")!; + const box = svgRoot.querySelector("g")!.getBBox()!; + svgRoot.setAttribute( + "viewBox", + `${box.x} ${box!.y} ${box.width} ${box.height}` + ); + svgRoot.setAttribute("width", `${box.width}`); + svgRoot.setAttribute("height", `${box.height}`); + }); + } + } + private _getSetHum(stateObj: HassEntity): undefined | number { if (isUnavailableState(stateObj.state)) { return undefined; @@ -269,8 +343,14 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { }); } - private _toggle(): void { - this.hass!.callService("humidifier", "toggle", { + private _turnOn(): void { + this.hass!.callService("humidifier", "turn_on", { + entity_id: this._config!.entity, + }); + } + + private _turnOff(): void { + this.hass!.callService("humidifier", "turn_off", { entity_id: this._config!.entity, }); } @@ -294,6 +374,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { --name-font-size: 1.2rem; --brightness-font-size: 1.2rem; --rail-border-color: transparent; + --mode-color: var(--state-inactive-color); } .more-info { @@ -301,11 +382,11 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { cursor: pointer; top: 0; right: 0; + inset-inline-end: 0px; + inset-inline-start: initial; border-radius: 100%; color: var(--secondary-text-color); - z-index: 25; - inset-inline-start: initial; - inset-inline-end: 0; + z-index: 1; direction: var(--direction); } @@ -321,7 +402,6 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { justify-content: center; padding: 16px; position: relative; - direction: ltr; } #slider { @@ -334,13 +414,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { round-slider { --round-slider-path-color: var(--slider-track-color); - --round-slider-bar-color: var(--primary-color); - padding-bottom: 10%; - } - - .round-slider_off { - --round-slider-path-color: var(--slider-track-color); - --round-slider-bar-color: var(--disabled-text-color); + --round-slider-bar-color: var(--mode-color); padding-bottom: 10%; } @@ -354,47 +428,28 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { top: 20px; text-align: center; overflow-wrap: break-word; + pointer-events: none; } - #mode { - max-width: 80%; - transform: translate(0, 250%); + #humidity { + position: absolute; + transform: translate(-50%, -50%); + width: 100%; + height: 50%; + top: 45%; + left: 50%; + direction: ltr; } #set-values { - font-size: 13px; - font-family: var(--paper-font-body1_-_font-family); - font-weight: var(--paper-font-body1_-_font-weight); + max-width: 80%; + transform: translate(0, -50%); + font-size: 20px; } #set-mode { fill: var(--secondary-text-color); - font-size: 4px; - } - - #current_humidity { - max-width: 80%; - transform: translate(0, 300%); - } - - #current-humidity { - fill: var(--primary-text-color); - font-size: 5px; - } - - .toggle-button { - color: var(--primary-text-color); - width: 75%; - height: auto; - position: absolute; - max-width: calc(100% - 40px); - box-sizing: border-box; - border-radius: 100%; - top: 39%; - left: 50%; - transform: translate(-50%, -50%); - --mdc-icon-button-size: 100%; - --mdc-icon-size: 100%; + font-size: 16px; } #info { @@ -406,6 +461,16 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { font-size: var(--name-font-size); } + #modes > * { + color: var(--disabled-text-color); + cursor: pointer; + display: inline-block; + } + + #modes .selected-icon { + color: var(--mode-color); + } + text { fill: var(--primary-text-color); } diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 0438374c7a..b48978274c 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -166,16 +166,19 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { style="font-size: 13px;" > ${ - stateObj.attributes.current_temperature !== null && + stateObj.state !== UNAVAILABLE && + stateObj.attributes.current_temperature != null && !isNaN(stateObj.attributes.current_temperature) - ? svg`${formatNumber( - stateObj.attributes.current_temperature, - this.hass.locale - )} - - ${this.hass.config.unit_system.temperature} - ` - : "" + ? svg` + ${formatNumber( + stateObj.attributes.current_temperature, + this.hass.locale + )} + + ${this.hass.config.unit_system.temperature} + + ` + : nothing } @@ -186,42 +189,14 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { ${ - stateObj.state === UNAVAILABLE - ? this.hass.localize("state.default.unavailable") - : this._setTemp === undefined || this._setTemp === null - ? "" - : Array.isArray(this._setTemp) - ? this._stepSize === 1 + stateObj.state !== UNAVAILABLE && this._setTemp != null + ? Array.isArray(this._setTemp) ? svg` - ${formatNumber(this._setTemp[0], this.hass.locale, { - maximumFractionDigits: 0, - })} - - ${formatNumber(this._setTemp[1], this.hass.locale, { - maximumFractionDigits: 0, - })} - ` - : svg` - ${formatNumber(this._setTemp[0], this.hass.locale, { - minimumFractionDigits: 1, - maximumFractionDigits: 1, - })} - - ${formatNumber(this._setTemp[1], this.hass.locale, { - minimumFractionDigits: 1, - maximumFractionDigits: 1, - })} - ` - : this._stepSize === 1 - ? svg` - ${formatNumber(this._setTemp, this.hass.locale, { - maximumFractionDigits: 0, - })} - ` - : svg` - ${formatNumber(this._setTemp, this.hass.locale, { - minimumFractionDigits: 1, - maximumFractionDigits: 1, - })} - ` + ${this._formatSetTemp(this._setTemp[0])} - + ${this._formatSetTemp(this._setTemp[1])} + ` + : this._formatSetTemp(this._setTemp) + : nothing } ${ - stateObj.attributes.hvac_action + stateObj.state !== UNAVAILABLE && stateObj.attributes.hvac_action ? computeAttributeValueDisplay( this.hass.localize, stateObj, @@ -248,6 +223,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { ) } ${ + stateObj.state !== UNAVAILABLE && stateObj.attributes.preset_mode && stateObj.attributes.preset_mode !== CLIMATE_PRESET_NONE ? html` @@ -261,7 +237,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { "preset_mode" )} ` - : "" + : nothing } @@ -374,6 +350,17 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { } } + private _formatSetTemp(temp: number) { + return this._stepSize === 1 + ? formatNumber(temp, this.hass!.locale, { + maximumFractionDigits: 0, + }) + : formatNumber(temp, this.hass!.locale, { + minimumFractionDigits: 1, + maximumFractionDigits: 1, + }); + } + private _rescale_svg() { // Set the viewbox of the SVG containing the set temperature to perfectly // fit the text diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 0afb105c2f..6afd8be31d 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -3,11 +3,11 @@ import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; import { mdiExclamationThick, mdiHelp } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, TemplateResult, + css, + html, nothing, } from "lit"; import { @@ -37,13 +37,14 @@ import "../../../components/tile/ha-tile-image"; import "../../../components/tile/ha-tile-info"; import { cameraUrlWithWidthHeight } from "../../../data/camera"; import { - computeCoverPositionStateDisplay, CoverEntity, + computeCoverPositionStateDisplay, } from "../../../data/cover"; import { isUnavailableState } from "../../../data/entity"; -import { computeFanSpeedStateDisplay, FanEntity } from "../../../data/fan"; -import { LightEntity } from "../../../data/light"; -import { ActionHandlerEvent } from "../../../data/lovelace"; +import { FanEntity, computeFanSpeedStateDisplay } from "../../../data/fan"; +import type { HumidifierEntity } from "../../../data/humidifier"; +import type { LightEntity } from "../../../data/light"; +import type { ActionHandlerEvent } from "../../../data/lovelace"; import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; import { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; @@ -51,15 +52,15 @@ import { findEntities } from "../common/find-entities"; import { handleAction } from "../common/handle-action"; import "../components/hui-timestamp-display"; import { createTileFeatureElement } from "../create-element/create-tile-feature-element"; -import { LovelaceTileFeatureConfig } from "../tile-features/types"; -import { +import type { LovelaceTileFeatureConfig } from "../tile-features/types"; +import type { LovelaceCard, LovelaceCardEditor, LovelaceTileFeature, } from "../types"; -import { HuiErrorCard } from "./hui-error-card"; +import type { HuiErrorCard } from "./hui-error-card"; import { computeTileBadge } from "./tile/badges/tile-badge"; -import { ThermostatCardConfig, TileCardConfig } from "./types"; +import type { ThermostatCardConfig, TileCardConfig } from "./types"; const TIMESTAMP_STATE_DOMAINS = ["button", "input_button", "scene"]; @@ -224,6 +225,15 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } } + if (domain === "humidifier" && stateActive(stateObj)) { + const humidity = (stateObj as HumidifierEntity).attributes.humidity; + if (humidity) { + return `${Math.round(humidity)}${blankBeforePercent( + this.hass!.locale + )}%`; + } + } + const stateDisplay = computeStateDisplay( this.hass!.localize, stateObj, From b15754a6a77ae7a522647d702b296293aed51332 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:49:24 +0200 Subject: [PATCH 136/162] Ingress: offer to start addon on ingress page (#16458) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Joakim Sørensen --- .../src/addon-view/info/hassio-addon-info.ts | 43 +++++- .../src/ingress-view/hassio-ingress-view.ts | 129 +++++++++++++++--- src/data/hassio/addon.ts | 8 +- src/translations/en.json | 12 +- 4 files changed, 168 insertions(+), 24 deletions(-) diff --git a/hassio/src/addon-view/info/hassio-addon-info.ts b/hassio/src/addon-view/info/hassio-addon-info.ts index 986090e53f..5800d2e1b0 100644 --- a/hassio/src/addon-view/info/hassio-addon-info.ts +++ b/hassio/src/addon-view/info/hassio-addon-info.ts @@ -114,11 +114,22 @@ class HassioAddonInfo extends LitElement { @state() private _error?: string; + private _fetchDataTimeout?: number; + private _addonStoreInfo = memoizeOne( (slug: string, storeAddons: StoreAddon[]) => storeAddons.find((addon) => addon.slug === slug) ); + public disconnectedCallback() { + super.disconnectedCallback(); + + if (this._fetchDataTimeout) { + clearInterval(this._fetchDataTimeout); + this._fetchDataTimeout = undefined; + } + } + protected render(): TemplateResult { const addonStoreInfo = !this.addon.detached && !this.addon.available @@ -592,7 +603,10 @@ class HassioAddonInfo extends LitElement { ` : html` - + ${this.supervisor.localize("addon.dashboard.start")} ` @@ -672,9 +686,36 @@ class HassioAddonInfo extends LitElement { super.updated(changedProps); if (changedProps.has("addon")) { this._loadData(); + if ( + !this._fetchDataTimeout && + this.addon && + "state" in this.addon && + this.addon.state === "startup" + ) { + // Addon is starting up, wait for it to start + this._scheduleDataUpdate(); + } } } + private _scheduleDataUpdate() { + this._fetchDataTimeout = window.setTimeout(async () => { + const addon = await fetchHassioAddonInfo(this.hass, this.addon.slug); + if (addon.state !== "startup") { + this._fetchDataTimeout = undefined; + this.addon = addon; + const eventdata = { + success: true, + response: undefined, + path: "start", + }; + fireEvent(this, "hass-api-called", eventdata); + } else { + this._scheduleDataUpdate(); + } + }, 500); + } + private async _loadData(): Promise { if ("state" in this.addon && this.addon.state === "started") { this._metrics = await fetchHassioStats( diff --git a/hassio/src/ingress-view/hassio-ingress-view.ts b/hassio/src/ingress-view/hassio-ingress-view.ts index f2ac689f87..5f50d0600c 100644 --- a/hassio/src/ingress-view/hassio-ingress-view.ts +++ b/hassio/src/ingress-view/hassio-ingress-view.ts @@ -16,6 +16,7 @@ import "../../../src/components/ha-icon-button"; import { fetchHassioAddonInfo, HassioAddonDetails, + startHassioAddon, } from "../../../src/data/hassio/addon"; import { extractApiErrorMessage } from "../../../src/data/hassio/common"; import { @@ -23,7 +24,10 @@ import { validateHassioSession, } from "../../../src/data/hassio/ingress"; import { Supervisor } from "../../../src/data/supervisor/supervisor"; -import { showAlertDialog } from "../../../src/dialogs/generic/show-dialog-box"; +import { + showAlertDialog, + showConfirmationDialog, +} from "../../../src/dialogs/generic/show-dialog-box"; import "../../../src/layouts/hass-loading-screen"; import "../../../src/layouts/hass-subpage"; import { HomeAssistant, Route } from "../../../src/types"; @@ -45,6 +49,8 @@ class HassioIngressView extends LitElement { private _sessionKeepAlive?: number; + private _fetchDataTimeout?: number; + public disconnectedCallback() { super.disconnectedCallback(); @@ -52,16 +58,21 @@ class HassioIngressView extends LitElement { clearInterval(this._sessionKeepAlive); this._sessionKeepAlive = undefined; } + if (this._fetchDataTimeout) { + clearInterval(this._fetchDataTimeout); + this._fetchDataTimeout = undefined; + } } protected render(): TemplateResult { if (!this._addon) { - return html` `; + return html``; } const iframe = html``; @@ -132,10 +143,10 @@ class HassioIngressView extends LitElement { return; } - const addon = this.route.path.substr(1); + const addon = this.route.path.substring(1); const oldRoute = changedProps.get("route") as this["route"] | undefined; - const oldAddon = oldRoute ? oldRoute.path.substr(1) : undefined; + const oldAddon = oldRoute ? oldRoute.path.substring(1) : undefined; if (addon && addon !== oldAddon) { this._fetchData(addon); @@ -145,33 +156,23 @@ class HassioIngressView extends LitElement { private async _fetchData(addonSlug: string) { const createSessionPromise = createHassioSession(this.hass); - let addon; + let addon: HassioAddonDetails; try { addon = await fetchHassioAddonInfo(this.hass, addonSlug); } catch (err: any) { await showAlertDialog(this, { - text: "Unable to fetch add-on info to start Ingress", + text: this.supervisor.localize("ingress.error_addon_info"), title: "Supervisor", }); await nextRender(); - history.back(); + navigate("/hassio/store", { replace: true }); return; } - if (!addon.ingress_url) { + if (!addon.version) { await showAlertDialog(this, { - text: "Add-on does not support Ingress", - title: addon.name, - }); - await nextRender(); - history.back(); - return; - } - - if (addon.state !== "started") { - await showAlertDialog(this, { - text: "Add-on is not running. Please start it first", + text: this.supervisor.localize("ingress.error_addon_not_installed"), title: addon.name, }); await nextRender(); @@ -179,13 +180,74 @@ class HassioIngressView extends LitElement { return; } - let session; + if (!addon.ingress_url) { + await showAlertDialog(this, { + text: this.supervisor.localize("ingress.error_addon_not_supported"), + title: addon.name, + }); + await nextRender(); + history.back(); + return; + } + + if (!addon.state || !["startup", "started"].includes(addon.state)) { + const confirm = await showConfirmationDialog(this, { + text: this.supervisor.localize("ingress.error_addon_not_running"), + title: addon.name, + confirmText: this.supervisor.localize("ingress.start_addon"), + dismissText: this.supervisor.localize("common.no"), + }); + if (confirm) { + try { + await startHassioAddon(this.hass, addonSlug); + fireEvent(this, "supervisor-collection-refresh", { + collection: "addon", + }); + this._fetchData(addonSlug); + return; + } catch (e) { + await showAlertDialog(this, { + text: this.supervisor.localize("ingress.error_starting_addon"), + title: addon.name, + }); + await nextRender(); + navigate(`/hassio/addon/${addon.slug}/logs`, { replace: true }); + return; + } + } else { + await nextRender(); + navigate(`/hassio/addon/${addon.slug}/info`, { replace: true }); + return; + } + } + + if (addon.state === "startup") { + // Addon is starting up, wait for it to start + this._fetchDataTimeout = window.setTimeout(() => { + this._fetchData(addonSlug); + }, 500); + return; + } + + if (addon.state !== "started") { + return; + } + + if (this._fetchDataTimeout) { + clearInterval(this._fetchDataTimeout); + this._fetchDataTimeout = undefined; + } + + let session: string; try { session = await createSessionPromise; } catch (err: any) { + if (this._sessionKeepAlive) { + clearInterval(this._sessionKeepAlive); + } await showAlertDialog(this, { - text: "Unable to create an Ingress session", + text: this.supervisor.localize("ingress.error_creating_session"), title: addon.name, }); await nextRender(); @@ -207,6 +269,31 @@ class HassioIngressView extends LitElement { this._addon = addon; } + private _checkLoaded(ev): void { + if (!this._addon) { + return; + } + if (ev.target.contentDocument.body.textContent === "502: Bad Gateway") { + showConfirmationDialog(this, { + text: this.supervisor.localize("ingress.error_addon_not_ready"), + title: this._addon.name, + confirmText: this.supervisor.localize("ingress.retry"), + dismissText: this.supervisor.localize("common.no"), + confirm: async () => { + const addon = this._addon; + this._addon = undefined; + await Promise.all([ + this.updateComplete, + new Promise((resolve) => { + setTimeout(resolve, 500); + }), + ]); + this._addon = addon; + }, + }); + } + } + private _toggleMenu(): void { fireEvent(this, "hass-toggle-menu"); } diff --git a/src/data/hassio/addon.ts b/src/data/hassio/addon.ts index 9b8aa7c2c6..def1e765e5 100644 --- a/src/data/hassio/addon.ts +++ b/src/data/hassio/addon.ts @@ -23,7 +23,13 @@ export type AddonStartup = | "services" | "application" | "once"; -export type AddonState = "started" | "stopped" | null; +export type AddonState = + | "startup" + | "started" + | "stopped" + | "unknown" + | "error" + | null; export type AddonRepository = "core" | "local" | string; interface AddonTranslations { diff --git a/src/translations/en.json b/src/translations/en.json index 865a1d23db..405eb44332 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5834,10 +5834,20 @@ "error": "[%key:ui::panel::my::error%]", "error_addon_not_found": "Add-on not found", "error_repository_not_found": "The required repository for this Add-on was not found", - "error_addon_not_started": "The requested add-on is not running. Please start it first", "error_addon_not_installed": "The requested add-on is not installed. Please install it first", "error_addon_no_ingress": "The requested add-on does not support ingress" }, + "ingress": { + "error_addon_info": "Unable to fetch add-on info to start Ingress", + "error_addon_not_installed": "The add-on is not installed. Please install it first", + "error_addon_not_supported": "This add-on does not support Ingress", + "error_addon_not_running": "Add-on is not running. Do you want to start it now?", + "start_addon": "Start add-on", + "error_starting_addon": "Error starting the add-on", + "error_creating_session": "Unable to create an Ingress session", + "error_addon_not_ready": "The add-on seems to not be ready, it might still be starting. Do you want to try again?", + "retry": "Retry" + }, "system": { "log": { "log_provider": "Log Provider", From c3c062cc294672d0a57600fe291112313eb5deb9 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 18:57:08 +0200 Subject: [PATCH 137/162] Unsubscribe from supervisor collection immediately (#17047) * Unsubscribe from supervisor collection immediately * bump home-assistant-js-websocket --- package.json | 2 +- src/data/supervisor/supervisor.ts | 3 ++- yarn.lock | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index bc2fb3dd90..0c1018da1f 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "fuse.js": "6.6.2", "google-timezones-json": "1.1.0", "hls.js": "1.4.6", - "home-assistant-js-websocket": "8.0.1", + "home-assistant-js-websocket": "8.1.0", "idb-keyval": "6.2.1", "intl-messageformat": "10.5.0", "js-yaml": "4.1.0", diff --git a/src/data/supervisor/supervisor.ts b/src/data/supervisor/supervisor.ts index e884ed271b..cc721e5b61 100644 --- a/src/data/supervisor/supervisor.ts +++ b/src/data/supervisor/supervisor.ts @@ -129,5 +129,6 @@ export const getSupervisorEventCollection = ( `_supervisor${key}Event`, (conn2) => supervisorApiWsRequest(conn2, { endpoint }), (connection, store) => - subscribeSupervisorEventUpdates(connection, store, key) + subscribeSupervisorEventUpdates(connection, store, key), + { unsubGrace: false } ); diff --git a/yarn.lock b/yarn.lock index 31dfffcb1d..f82ee35bb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9737,7 +9737,7 @@ __metadata: gulp-rename: 2.0.0 gulp-zopfli-green: 6.0.1 hls.js: 1.4.6 - home-assistant-js-websocket: 8.0.1 + home-assistant-js-websocket: 8.1.0 html-minifier-terser: 7.2.0 husky: 8.0.3 idb-keyval: 6.2.1 @@ -9810,10 +9810,10 @@ __metadata: languageName: unknown linkType: soft -"home-assistant-js-websocket@npm:8.0.1": - version: 8.0.1 - resolution: "home-assistant-js-websocket@npm:8.0.1" - checksum: e8b2204d58b2b1fbdf26ca1ad196fcc02ec5d18e6d867179f27246a9f2d4fe5f91de9dbbe7b82806c19dcb0af0e2b77fb48d393668b5c8c0844c201a16832023 +"home-assistant-js-websocket@npm:8.1.0": + version: 8.1.0 + resolution: "home-assistant-js-websocket@npm:8.1.0" + checksum: 74f9afc5affe491921d7fd9e743c1a6841cb0409c2c5454fff266d14ea893f5be476cb85f584ff1836722de77cfe2777d4133890f00fc1983ad448eba50f6240 languageName: node linkType: hard From 6b4300950dedc42c42954b3837882122fdf68469 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 27 Jun 2023 19:02:05 +0200 Subject: [PATCH 138/162] Add response UI to stop action (#17045) --- .../action/types/ha-automation-action-stop.ts | 21 ++++++++++++++++--- src/translations/en.json | 1 + 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/panels/config/automation/action/types/ha-automation-action-stop.ts b/src/panels/config/automation/action/types/ha-automation-action-stop.ts index 6281c8b634..6ca7177e4f 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-stop.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-stop.ts @@ -19,7 +19,7 @@ export class HaStopAction extends LitElement implements ActionElement { } protected render() { - const { error, stop } = this.action; + const { error, stop, response_variable } = this.action; return html` + Date: Tue, 27 Jun 2023 19:12:38 +0200 Subject: [PATCH 139/162] Add response variable support to service action (#17046) --- src/data/script.ts | 1 + .../types/ha-automation-action-service.ts | 106 +++++++++++++++++- src/translations/en.json | 5 +- 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/src/data/script.ts b/src/data/script.ts index 942296cef8..6fb4fbb596 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -51,6 +51,7 @@ export const serviceActionStruct: Describe = assign( entity_id: optional(string()), target: optional(targetStruct), data: optional(object()), + response_variable: optional(string()), }) ); diff --git a/src/panels/config/automation/action/types/ha-automation-action-service.ts b/src/panels/config/automation/action/types/ha-automation-action-service.ts index af4a525406..0c403a13dd 100644 --- a/src/panels/config/automation/action/types/ha-automation-action-service.ts +++ b/src/panels/config/automation/action/types/ha-automation-action-service.ts @@ -1,4 +1,11 @@ -import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit"; +import { + css, + CSSResultGroup, + html, + LitElement, + nothing, + PropertyValues, +} from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { assert } from "superstruct"; @@ -21,7 +28,9 @@ export class HaServiceAction extends LitElement implements ActionElement { @property({ type: Boolean }) public narrow = false; - @state() private _action!: ServiceAction; + @state() private _action?: ServiceAction; + + @state() private _responseChecked = false; private _fields = memoizeOne( ( @@ -98,6 +107,12 @@ export class HaServiceAction extends LitElement implements ActionElement { } protected render() { + if (!this._action) { + return nothing; + } + const [domain, service] = this._action.service + ? this._action.service.split(".", 2) + : [undefined, undefined]; return html` + ${domain && service && this.hass.services[domain]?.[service]?.response + ? html` + ${this.hass.services[domain][service].response!.optional + ? html`` + : html`
`} + ${this.hass.localize( + "ui.panel.config.automation.editor.actions.type.service.response_variable" + )} + + ${this.hass.services[domain][service].response!.optional + ? this.hass.localize( + "ui.panel.config.automation.editor.actions.type.service.has_optional_response" + ) + : this.hass.localize( + "ui.panel.config.automation.editor.actions.type.service.has_response" + )} + + +
` + : nothing} `; } @@ -114,6 +164,39 @@ export class HaServiceAction extends LitElement implements ActionElement { if (ev.detail.value === this._action) { ev.stopPropagation(); } + const value = { ...this.action, ...ev.detail.value }; + if ("response_variable" in this.action) { + const [domain, service] = this._action!.service + ? this._action!.service.split(".", 2) + : [undefined, undefined]; + if ( + domain && + service && + this.hass.services[domain]?.[service] && + !("response" in this.hass.services[domain][service]) + ) { + delete value.response_variable; + this._responseChecked = false; + } + } + fireEvent(this, "value-changed", { value }); + } + + private _responseVariableChanged(ev) { + const value = { ...this.action, response_variable: ev.target.value }; + if (!ev.target.value) { + delete value.response_variable; + } + fireEvent(this, "value-changed", { value }); + } + + private _responseCheckboxChanged(ev) { + this._responseChecked = ev.target.checked; + if (!this._responseChecked) { + const value = { ...this.action }; + delete value.response_variable; + fireEvent(this, "value-changed", { value }); + } } static get styles(): CSSResultGroup { @@ -122,6 +205,25 @@ export class HaServiceAction extends LitElement implements ActionElement { display: block; margin: 0 -16px; } + ha-settings-row { + margin: 0 -16px; + padding: var(--service-control-padding, 0 16px); + } + ha-settings-row { + --paper-time-input-justify-content: flex-end; + --settings-row-content-width: 100%; + --settings-row-prefix-display: contents; + border-top: var( + --service-control-items-border-top, + 1px solid var(--divider-color) + ); + } + ha-checkbox { + margin-left: -16px; + } + .checkbox-spacer { + width: 32px; + } `; } } diff --git a/src/translations/en.json b/src/translations/en.json index 6e9da65bba..7e081c3070 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2567,7 +2567,10 @@ "continue_on_error": "Continue on error", "type": { "service": { - "label": "Call service" + "label": "Call service", + "response_variable": "Response variable", + "has_optional_response": "This service can return a response, if you want to use the response, enter the name of a variable the response will be saved in", + "has_response": "This service returns a response, enter the name of a variable the response will be saved in" }, "play_media": { "label": "Play media" From 73e1b4b1d135bfcfb7dabdb85ef981cbb0abdfb7 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 28 Jun 2023 12:40:59 +0200 Subject: [PATCH 140/162] Add basic assist dev tools (#17062) --- src/data/conversation.ts | 32 +++ .../assist/developer-tools-assist.ts | 240 ++++++++++++++++++ .../developer-tools/developer-tools-router.ts | 4 + .../ha-panel-developer-tools.ts | 1 + 4 files changed, 277 insertions(+) create mode 100644 src/panels/developer-tools/assist/developer-tools-assist.ts diff --git a/src/data/conversation.ts b/src/data/conversation.ts index c63e6ba430..c76f6a2ecf 100644 --- a/src/data/conversation.ts +++ b/src/data/conversation.ts @@ -1,3 +1,4 @@ +import { ensureArray } from "../common/array/ensure-array"; import { HomeAssistant } from "../types"; interface IntentTarget { @@ -58,6 +59,24 @@ export interface Agent { supported_languages: "*" | string[]; } +export interface AssitDebugResult { + intent: { + name: string; + }; + entities: Record< + string, + { + name: string; + value: string; + text: string; + } + >; +} + +export interface AssistDebugResponse { + results: (AssitDebugResult | null)[]; +} + export const processConversationInput = ( hass: HomeAssistant, text: string, @@ -91,3 +110,16 @@ export const prepareConversation = ( type: "conversation/prepare", language, }); + +export const debugAgent = ( + hass: HomeAssistant, + sentences: string[] | string, + language: string, + device_id?: string +): Promise => + hass.callWS({ + type: "conversation/agent/homeassistant/debug", + sentences: ensureArray(sentences), + language, + device_id, + }); diff --git a/src/panels/developer-tools/assist/developer-tools-assist.ts b/src/panels/developer-tools/assist/developer-tools-assist.ts new file mode 100644 index 0000000000..89e3890f5c --- /dev/null +++ b/src/panels/developer-tools/assist/developer-tools-assist.ts @@ -0,0 +1,240 @@ +import { dump } from "js-yaml"; +import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; +import { customElement, property, query, state } from "lit/decorators"; +import "../../../components/ha-button"; +import "../../../components/ha-code-editor"; +import "../../../components/ha-language-picker"; +import "../../../components/ha-textarea"; +import "../../../components/ha-absolute-time"; +import type { HaTextArea } from "../../../components/ha-textarea"; +import { + AssitDebugResult, + debugAgent, + listAgents, +} from "../../../data/conversation"; +import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; +import { haStyle } from "../../../resources/styles"; +import { HomeAssistant } from "../../../types"; +import { formatLanguageCode } from "../../../common/language/format_language"; +import { storage } from "../../../common/decorators/storage"; + +type SentenceParsingResult = { + sentence: string; + language: string; + result: AssitDebugResult | null; + time: Date; +}; + +@customElement("developer-tools-assist") +class HaPanelDevAssist extends SubscribeMixin(LitElement) { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ type: Boolean }) public narrow!: boolean; + + @state() supportedLanguages?: string[]; + + @storage({ + key: "assist_debug_language", + state: true, + subscribe: false, + storage: "localStorage", + }) + _language?: string; + + @state() _results: SentenceParsingResult[] = []; + + @query("#sentences-input") _sentencesInput!: HaTextArea; + + @state() _validInput = false; + + private _languageChanged(ev) { + this._language = ev.detail.value; + } + + private _textAreaInput(ev) { + const value = ev.target.value; + const valid = Boolean(value); + if (valid !== this._validInput) { + this._validInput = valid; + } + } + + private async _parse() { + const sentences = this._sentencesInput.value + .split("\n") + .filter((a) => a !== ""); + const { results } = await debugAgent(this.hass, sentences, this._language!); + + this._sentencesInput.value = ""; + + const now = new Date(); + + const newResults: SentenceParsingResult[] = []; + sentences.forEach((sentence, index) => { + const result = results[index]; + + newResults.push({ + sentence, + language: this._language!, + result, + time: now, + }); + }); + this._results = [...newResults, ...this._results]; + } + + private async _fetchLanguages() { + const { agents } = await listAgents(this.hass); + const assistAgent = agents.find((agent) => agent.id === "homeassistant"); + this.supportedLanguages = + assistAgent?.supported_languages === "*" + ? undefined + : assistAgent?.supported_languages; + } + + protected firstUpdated(): void { + this._fetchLanguages(); + } + + protected render() { + return html` +
+ +
+

+ Enter sentences and see how they will be parsed by Home Assistant. + Each line will be processed as individual sentence. Intents will + not be executed on your instance. +

+ ${this.supportedLanguages + ? html` + + ` + : nothing} + +
+
+ + Parse sentences + +
+
+ + ${this._results.map((r) => { + const { sentence, result, language, time } = r; + const matched = result != null; + + return html` + +
+
+

${sentence}

+

${matched ? "✅" : "❌"}

+
+
+

+ Language: ${formatLanguageCode( + language, + this.hass.locale + )} (${language}) +

+

Execution time: + + +

+ +

+
+ ${ + result + ? html` + + ` + : html`No intent matched` + } +
+
+ `; + })} +
+ `; + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + .content { + padding: 28px 20px 16px; + padding: max(28px, calc(12px + env(safe-area-inset-top))) + max(20px, calc(4px + env(safe-area-inset-right))) + max(16px, env(safe-area-inset-bottom)) + max(20px, calc(4px + env(safe-area-inset-left))); + max-width: 1040px; + margin: 0 auto; + } + .description { + margin: 0; + margin-bottom: 16px; + } + ha-textarea { + width: 100%; + } + .card-actions { + text-align: right; + } + .form { + margin-bottom: 16px; + } + .result { + margin-bottom: 16px; + } + .sentence { + font-weight: 500; + margin-bottom: 8px; + display: flex; + flex-direction: row; + justify-content: space-between; + } + .sentence p { + margin: 0; + } + .info p { + margin: 0; + } + ha-code-editor, + ha-alert { + display: block; + margin-top: 16px; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "developer-tools-assist": HaPanelDevAssist; + } +} diff --git a/src/panels/developer-tools/developer-tools-router.ts b/src/panels/developer-tools/developer-tools-router.ts index b614f5e817..5b8baf3899 100644 --- a/src/panels/developer-tools/developer-tools-router.ts +++ b/src/panels/developer-tools/developer-tools-router.ts @@ -45,6 +45,10 @@ class DeveloperToolsRouter extends HassRouterPage { tag: "developer-yaml-config", load: () => import("./yaml_configuration/developer-yaml-config"), }, + assist: { + tag: "developer-tools-assist", + load: () => import("./assist/developer-tools-assist"), + }, }, }; diff --git a/src/panels/developer-tools/ha-panel-developer-tools.ts b/src/panels/developer-tools/ha-panel-developer-tools.ts index 54c5666e9f..813cc014e7 100644 --- a/src/panels/developer-tools/ha-panel-developer-tools.ts +++ b/src/panels/developer-tools/ha-panel-developer-tools.ts @@ -65,6 +65,7 @@ class PanelDeveloperTools extends LitElement { "ui.panel.developer-tools.tabs.statistics.title" )} + Assist
Date: Wed, 28 Jun 2023 12:45:34 +0200 Subject: [PATCH 141/162] Handle "unknown" for date, time and datetime entities (#17043) --- .../more-info/controls/more-info-date.ts | 14 +++++--- .../more-info/controls/more-info-datetime.ts | 36 +++++++++++-------- .../more-info/controls/more-info-time.ts | 14 +++++--- .../entity-rows/hui-date-entity-row.ts | 12 ++++--- .../entity-rows/hui-datetime-entity-row.ts | 36 +++++++++++-------- .../entity-rows/hui-time-entity-row.ts | 14 +++++--- 6 files changed, 77 insertions(+), 49 deletions(-) diff --git a/src/dialogs/more-info/controls/more-info-date.ts b/src/dialogs/more-info/controls/more-info-date.ts index b53829b557..6d489fe22f 100644 --- a/src/dialogs/more-info/controls/more-info-date.ts +++ b/src/dialogs/more-info/controls/more-info-date.ts @@ -4,7 +4,7 @@ import { customElement, property } from "lit/decorators"; import "../../../components/ha-date-input"; import "../../../components/ha-time-input"; import { setDateValue } from "../../../data/date"; -import { isUnavailableState } from "../../../data/entity"; +import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; import type { HomeAssistant } from "../../../types"; @customElement("more-info-date") @@ -14,15 +14,17 @@ class MoreInfoDate extends LitElement { @property({ attribute: false }) public stateObj?: HassEntity; protected render() { - if (!this.stateObj || isUnavailableState(this.stateObj.state)) { + if (!this.stateObj || this.stateObj.state === UNAVAILABLE) { return nothing; } return html` @@ -30,7 +32,9 @@ class MoreInfoDate extends LitElement { } private _dateChanged(ev: CustomEvent<{ value: string }>): void { - setDateValue(this.hass!, this.stateObj!.entity_id, ev.detail.value); + if (ev.detail.value) { + setDateValue(this.hass!, this.stateObj!.entity_id, ev.detail.value); + } } static get styles(): CSSResultGroup { diff --git a/src/dialogs/more-info/controls/more-info-datetime.ts b/src/dialogs/more-info/controls/more-info-datetime.ts index b0b25f9bc9..85d7f44bd3 100644 --- a/src/dialogs/more-info/controls/more-info-datetime.ts +++ b/src/dialogs/more-info/controls/more-info-datetime.ts @@ -5,7 +5,7 @@ import { customElement, property } from "lit/decorators"; import "../../../components/ha-date-input"; import "../../../components/ha-time-input"; import { setDateTimeValue } from "../../../data/datetime"; -import { isUnavailableState } from "../../../data/entity"; +import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; import type { HomeAssistant } from "../../../types"; @customElement("more-info-datetime") @@ -15,25 +15,27 @@ class MoreInfoDatetime extends LitElement { @property({ attribute: false }) public stateObj?: HassEntity; protected render() { - if (!this.stateObj || isUnavailableState(this.stateObj.state)) { + if (!this.stateObj || this.stateObj.state === UNAVAILABLE) { return nothing; } - const dateObj = new Date(this.stateObj.state); - const time = format(dateObj, "HH:mm:ss"); - const date = format(dateObj, "yyyy-MM-dd"); + const dateObj = isUnavailableState(this.stateObj.state) + ? undefined + : new Date(this.stateObj.state); + const time = dateObj ? format(dateObj, "HH:mm:ss") : undefined; + const date = dateObj ? format(dateObj, "yyyy-MM-dd") : undefined; return html` `; @@ -44,19 +46,23 @@ class MoreInfoDatetime extends LitElement { } private _timeChanged(ev: CustomEvent<{ value: string }>): void { - const dateObj = new Date(this.stateObj!.state); - const newTime = ev.detail.value.split(":").map(Number); - dateObj.setHours(newTime[0], newTime[1], newTime[2]); + if (ev.detail.value) { + const dateObj = new Date(this.stateObj!.state); + const newTime = ev.detail.value.split(":").map(Number); + dateObj.setHours(newTime[0], newTime[1], newTime[2]); - setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj); + setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj); + } } private _dateChanged(ev: CustomEvent<{ value: string }>): void { - const dateObj = new Date(this.stateObj!.state); - const newDate = ev.detail.value.split("-").map(Number); - dateObj.setFullYear(newDate[0], newDate[1] - 1, newDate[2]); + if (ev.detail.value) { + const dateObj = new Date(this.stateObj!.state); + const newDate = ev.detail.value.split("-").map(Number); + dateObj.setFullYear(newDate[0], newDate[1] - 1, newDate[2]); - setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj); + setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj); + } } static get styles(): CSSResultGroup { diff --git a/src/dialogs/more-info/controls/more-info-time.ts b/src/dialogs/more-info/controls/more-info-time.ts index c131f7e3de..8e5a99bc34 100644 --- a/src/dialogs/more-info/controls/more-info-time.ts +++ b/src/dialogs/more-info/controls/more-info-time.ts @@ -3,7 +3,7 @@ import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import "../../../components/ha-date-input"; import "../../../components/ha-time-input"; -import { isUnavailableState } from "../../../data/entity"; +import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; import { setTimeValue } from "../../../data/time"; import type { HomeAssistant } from "../../../types"; @@ -14,15 +14,17 @@ class MoreInfoTime extends LitElement { @property({ attribute: false }) public stateObj?: HassEntity; protected render() { - if (!this.stateObj || isUnavailableState(this.stateObj.state)) { + if (!this.stateObj || this.stateObj.state === UNAVAILABLE) { return nothing; } return html` @@ -34,7 +36,9 @@ class MoreInfoTime extends LitElement { } private _timeChanged(ev: CustomEvent<{ value: string }>): void { - setTimeValue(this.hass!, this.stateObj!.entity_id, ev.detail.value); + if (ev.detail.value) { + setTimeValue(this.hass!, this.stateObj!.entity_id, ev.detail.value); + } } static get styles(): CSSResultGroup { diff --git a/src/panels/lovelace/entity-rows/hui-date-entity-row.ts b/src/panels/lovelace/entity-rows/hui-date-entity-row.ts index 9cbec26d87..82a8286db1 100644 --- a/src/panels/lovelace/entity-rows/hui-date-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-date-entity-row.ts @@ -1,7 +1,7 @@ import { html, LitElement, nothing, PropertyValues, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import "../../../components/ha-date-input"; -import { isUnavailableState } from "../../../data/entity"; +import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; import { setDateValue } from "../../../data/date"; import type { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; @@ -41,14 +41,16 @@ class HuiDateEntityRow extends LitElement implements LovelaceRow { `; } - const unavailable = isUnavailableState(stateObj.state); + const unavailable = stateObj.state === UNAVAILABLE; return html` @@ -57,7 +59,9 @@ class HuiDateEntityRow extends LitElement implements LovelaceRow { } private _dateChanged(ev: CustomEvent<{ value: string }>): void { - setDateValue(this.hass!, this._config!.entity, ev.detail.value); + if (ev.detail.value) { + setDateValue(this.hass!, this._config!.entity, ev.detail.value); + } } } diff --git a/src/panels/lovelace/entity-rows/hui-datetime-entity-row.ts b/src/panels/lovelace/entity-rows/hui-datetime-entity-row.ts index e4aecd4cbf..b215f51121 100644 --- a/src/panels/lovelace/entity-rows/hui-datetime-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-datetime-entity-row.ts @@ -10,7 +10,7 @@ import { import { customElement, property, state } from "lit/decorators"; import "../../../components/ha-date-input"; import { format } from "date-fns"; -import { isUnavailableState } from "../../../data/entity"; +import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; import { setDateTimeValue } from "../../../data/datetime"; import type { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; @@ -52,11 +52,13 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { `; } - const unavailable = isUnavailableState(stateObj.state); + const unavailable = stateObj.state === UNAVAILABLE; - const dateObj = unavailable ? undefined : new Date(stateObj.state); - const time = dateObj ? format(dateObj, "HH:mm:ss") : ""; - const date = dateObj ? format(dateObj, "yyyy-MM-dd") : ""; + const dateObj = isUnavailableState(stateObj.state) + ? undefined + : new Date(stateObj.state); + const time = dateObj ? format(dateObj, "HH:mm:ss") : undefined; + const date = dateObj ? format(dateObj, "yyyy-MM-dd") : undefined; return html` ): void { - const stateObj = this.hass!.states[this._config!.entity]; - const dateObj = new Date(stateObj.state); - const newTime = ev.detail.value.split(":").map(Number); - dateObj.setHours(newTime[0], newTime[1], newTime[2]); + if (ev.detail.value) { + const stateObj = this.hass!.states[this._config!.entity]; + const dateObj = new Date(stateObj.state); + const newTime = ev.detail.value.split(":").map(Number); + dateObj.setHours(newTime[0], newTime[1], newTime[2]); - setDateTimeValue(this.hass!, stateObj.entity_id, dateObj); + setDateTimeValue(this.hass!, stateObj.entity_id, dateObj); + } } private _dateChanged(ev: CustomEvent<{ value: string }>): void { - const stateObj = this.hass!.states[this._config!.entity]; - const dateObj = new Date(stateObj.state); - const newDate = ev.detail.value.split("-").map(Number); - dateObj.setFullYear(newDate[0], newDate[1] - 1, newDate[2]); + if (ev.detail.value) { + const stateObj = this.hass!.states[this._config!.entity]; + const dateObj = new Date(stateObj.state); + const newDate = ev.detail.value.split("-").map(Number); + dateObj.setFullYear(newDate[0], newDate[1] - 1, newDate[2]); - setDateTimeValue(this.hass!, stateObj.entity_id, dateObj); + setDateTimeValue(this.hass!, stateObj.entity_id, dateObj); + } } static get styles(): CSSResultGroup { diff --git a/src/panels/lovelace/entity-rows/hui-time-entity-row.ts b/src/panels/lovelace/entity-rows/hui-time-entity-row.ts index 66cf5c68b1..932fe99f66 100644 --- a/src/panels/lovelace/entity-rows/hui-time-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-time-entity-row.ts @@ -1,7 +1,7 @@ import { html, LitElement, nothing, PropertyValues, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import "../../../components/ha-date-input"; -import { isUnavailableState } from "../../../data/entity"; +import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; import { setTimeValue } from "../../../data/time"; import type { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; @@ -42,12 +42,14 @@ class HuiTimeEntityRow extends LitElement implements LovelaceRow { `; } - const unavailable = isUnavailableState(stateObj.state); + const unavailable = stateObj.state === UNAVAILABLE; return html` ): void { - const stateObj = this.hass!.states[this._config!.entity]; - setTimeValue(this.hass!, stateObj.entity_id, ev.detail.value); + if (ev.detail.value) { + const stateObj = this.hass!.states[this._config!.entity]; + setTimeValue(this.hass!, stateObj.entity_id, ev.detail.value); + } } } From 927c6dd77868b7bcd745b58af1cc1a6cb59bfbe5 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 13:31:26 +0200 Subject: [PATCH 142/162] Fix state display in vacuum more info (#17063) --- .../more-info/controls/more-info-vacuum.ts | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/dialogs/more-info/controls/more-info-vacuum.ts b/src/dialogs/more-info/controls/more-info-vacuum.ts index dfa940e31f..c470b33cba 100644 --- a/src/dialogs/more-info/controls/more-info-vacuum.ts +++ b/src/dialogs/more-info/controls/more-info-vacuum.ts @@ -105,36 +105,34 @@ class MoreInfoVacuum extends LitElement { return html` ${stateObj.state !== UNAVAILABLE ? html`
- ${supportsFeature(stateObj, VacuumEntityFeature.STATUS) - ? html` -
- ${this.hass!.localize( - "ui.dialogs.more_info_control.vacuum.status" - )}: - - - - ${computeAttributeValueDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "status" - ) || - computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} - - -
- ` - : ""} +
+ ${this.hass!.localize( + "ui.dialogs.more_info_control.vacuum.status" + )}: + + + + ${supportsFeature(stateObj, VacuumEntityFeature.STATUS) && + stateObj.attributes.status + ? computeAttributeValueDisplay( + this.hass.localize, + stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities, + "status" + ) + : computeStateDisplay( + this.hass.localize, + stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities + )} + + +
${supportsFeature(stateObj, VacuumEntityFeature.BATTERY) && stateObj.attributes.battery_level ? html` From ce9380e4d7d2714fd6538b171dca3ba82abb320c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 13:34:48 +0200 Subject: [PATCH 143/162] Fix menu button when sidebar is always_hidden (#17059) --- src/components/ha-menu-button.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/ha-menu-button.ts b/src/components/ha-menu-button.ts index 3bb80a0e04..2246dd136b 100644 --- a/src/components/ha-menu-button.ts +++ b/src/components/ha-menu-button.ts @@ -73,25 +73,25 @@ class HaMenuButton extends LitElement { return; } - const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + const oldHass = changedProps.has("hass") + ? (changedProps.get("hass") as HomeAssistant | undefined) + : this.hass; + const oldNarrow = changedProps.has("narrow") + ? (changedProps.get("narrow") as boolean | undefined) + : this.narrow; - let oldNarrow: boolean | undefined; - let newNarrow: boolean | undefined; - if (changedProps.has("narrow")) { - oldNarrow = changedProps.get("narrow"); - newNarrow = this.narrow; - } else if (oldHass) { - oldNarrow = oldHass.dockedSidebar === "always_hidden"; - newNarrow = this.hass.dockedSidebar === "always_hidden"; - } + const oldShowButton = + oldNarrow || oldHass?.dockedSidebar === "always_hidden"; + const showButton = + this.narrow || this.hass.dockedSidebar === "always_hidden"; - if (oldNarrow === newNarrow) { + if (oldShowButton === showButton) { return; } - this.style.display = newNarrow || this._alwaysVisible ? "initial" : "none"; + this.style.display = showButton || this._alwaysVisible ? "initial" : "none"; - if (!newNarrow) { + if (!showButton) { if (this._unsubNotifications) { this._unsubNotifications(); this._unsubNotifications = undefined; From 5ac9a6c9cc8e21979843416875ae3ea7e7a5114d Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 28 Jun 2023 05:00:10 -0700 Subject: [PATCH 144/162] Sort tooltips in energy graphs and filter zeros (#17057) --- .../cards/energy/hui-energy-gas-graph-card.ts | 4 ++++ .../cards/energy/hui-energy-solar-graph-card.ts | 4 ++++ .../cards/energy/hui-energy-usage-graph-card.ts | 12 ++++++++++++ .../cards/energy/hui-energy-water-graph-card.ts | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts index 432dada500..68ac83ab67 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-gas-graph-card.ts @@ -217,6 +217,10 @@ export class HuiEnergyGasGraphCard plugins: { tooltip: { position: "nearest", + filter: (val) => val.formattedValue !== "0", + itemSort: function (a, b) { + return b.datasetIndex - a.datasetIndex; + }, callbacks: { title: (datasets) => { if (dayDifference > 0) { diff --git a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts index 49290b5647..778ccb77d1 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-solar-graph-card.ts @@ -213,6 +213,10 @@ export class HuiEnergySolarGraphCard plugins: { tooltip: { position: "nearest", + filter: (val) => val.formattedValue !== "0", + itemSort: function (a, b) { + return b.datasetIndex - a.datasetIndex; + }, callbacks: { title: (datasets) => { if (dayDifference > 0) { diff --git a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts index 5b97bd290d..b804dedc0a 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-usage-graph-card.ts @@ -209,6 +209,18 @@ export class HuiEnergyUsageGraphCard tooltip: { position: "nearest", filter: (val) => val.formattedValue !== "0", + itemSort: function (a: any, b: any) { + if (a.raw?.y > 0 && b.raw?.y < 0) { + return -1; + } + if (b.raw?.y > 0 && a.raw?.y < 0) { + return 1; + } + if (a.raw?.y > 0) { + return b.datasetIndex - a.datasetIndex; + } + return a.datasetIndex - b.datasetIndex; + }, callbacks: { title: (datasets) => { if (dayDifference > 0) { diff --git a/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts b/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts index 84f21089c2..41d4029c04 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-water-graph-card.ts @@ -217,6 +217,10 @@ export class HuiEnergyWaterGraphCard plugins: { tooltip: { position: "nearest", + filter: (val) => val.formattedValue !== "0", + itemSort: function (a, b) { + return b.datasetIndex - a.datasetIndex; + }, callbacks: { title: (datasets) => { if (dayDifference > 0) { From 8945650b6219ecde6a91c32dfb7fa6e619d83fd6 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 28 Jun 2023 05:01:21 -0700 Subject: [PATCH 145/162] Show card positions in edit dashboard mode (#17055) --- .../lovelace/components/hui-card-options.ts | 26 +++++++++++++++++++ src/translations/en.json | 1 + 2 files changed, 27 insertions(+) diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 6a39d8b590..6f87fb30f0 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -81,6 +81,18 @@ export class HuiCardOptions extends LitElement { .length === this.path![1] + 1} > +
+ ${this.path![1] + 1} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_card.position", + "position", + `${this.path![1] + 1}`, + "total", + `${this.lovelace!.config.views[this.path![0]].cards!.length}` + )} +
Date: Wed, 28 Jun 2023 14:09:02 +0200 Subject: [PATCH 146/162] Refactor integration card (#17061) --- .../integrations/ha-integration-card.ts | 199 +++++++++++++----- .../integrations/ha-integration-header.ts | 105 +-------- 2 files changed, 160 insertions(+), 144 deletions(-) diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts index 274fc92ed4..7866cd8343 100644 --- a/src/panels/config/integrations/ha-integration-card.ts +++ b/src/panels/config/integrations/ha-integration-card.ts @@ -1,19 +1,29 @@ import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; import "@material/mwc-button"; import "@material/mwc-list"; +import "@material/mwc-ripple"; +import type { Ripple } from "@material/mwc-ripple"; +import { RippleHandlers } from "@material/mwc-ripple/ripple-handlers"; +import { mdiCloud, mdiPackageVariant } from "@mdi/js"; import { - mdiCogOutline, - mdiDevices, - mdiHandExtendedOutline, - mdiPuzzleOutline, - mdiShapeOutline, -} from "@mdi/js"; -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; -import { customElement, property } from "lit/decorators"; + CSSResultGroup, + LitElement, + TemplateResult, + css, + html, + nothing, +} from "lit"; +import { + customElement, + eventOptions, + property, + queryAsync, + state, +} from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import memoizeOne from "memoize-one"; +import { computeRTL } from "../../../common/util/compute_rtl"; import "../../../components/ha-card"; -import "../../../components/ha-icon-button"; import "../../../components/ha-icon-next"; import "../../../components/ha-list-item"; import "../../../components/ha-svg-icon"; @@ -47,8 +57,12 @@ export class HaIntegrationCard extends LitElement { @property() public logInfo?: IntegrationLogInfo; + @queryAsync("mwc-ripple") private _ripple!: Promise; + + @state() private _shouldRenderRipple = false; + protected render(): TemplateResult { - const state = this._getState(this.items); + const entryState = this._getState(this.items); const debugLoggingEnabled = this.logInfo && this.logInfo.level === LogSeverity.DEBUG; @@ -57,22 +71,35 @@ export class HaIntegrationCard extends LitElement { - + + ${this._shouldRenderRipple ? html`` : ""} - + > @@ -105,18 +131,14 @@ export class HaIntegrationCard extends LitElement { const services = !devices.some((device) => device.entry_type !== "service"); return html` -
+
${devices.length > 0 ? html` - - + ${this.hass.localize( `ui.panel.config.integrations.config_entry.${ services ? "services" : "devices" @@ -124,40 +146,57 @@ export class HaIntegrationCard extends LitElement { "count", devices.length )} - - + ` : entities.length > 0 ? html` - - + ${this.hass.localize( `ui.panel.config.integrations.config_entry.entities`, "count", entities.length )} - - + ` : html` - - + ${this.hass.localize( `ui.panel.config.integrations.config_entry.entries`, "count", this.items.length )} - - + `} +
+ ${this.manifest && !this.manifest.is_built_in + ? html` + + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.custom_integration" + )} + ` + : nothing} + ${this.manifest && this.manifest.iot_class?.startsWith("cloud_") + ? html`
+ + ${this.hass.localize( + "ui.panel.config.integrations.config_entry.depends_on_cloud" + )} +
` + : nothing} +
`; } @@ -167,14 +206,14 @@ export class HaIntegrationCard extends LitElement { if (configEntry.length === 1) { return configEntry[0].state; } - let state: ConfigEntry["state"]; + let entryState: ConfigEntry["state"]; for (const entry of configEntry) { if (ERROR_STATES.includes(entry.state)) { return entry.state; } - state = entry.state; + entryState = entry.state; } - return state!; + return entryState!; } ); @@ -209,6 +248,36 @@ export class HaIntegrationCard extends LitElement { } ); + private _rippleHandlers: RippleHandlers = new RippleHandlers(() => { + this._shouldRenderRipple = true; + return this._ripple; + }); + + @eventOptions({ passive: true }) + private handleRippleActivate(evt?: Event) { + this._rippleHandlers.startPress(evt); + } + + private handleRippleDeactivate() { + this._rippleHandlers.endPress(); + } + + private handleRippleFocus() { + this._rippleHandlers.startFocus(); + } + + private handleRippleBlur() { + this._rippleHandlers.endFocus(); + } + + protected handleRippleMouseEnter() { + this._rippleHandlers.startHover(); + } + + protected handleRippleMouseLeave() { + this._rippleHandlers.endHover(); + } + static get styles(): CSSResultGroup { return [ haStyle, @@ -216,12 +285,25 @@ export class HaIntegrationCard extends LitElement { ha-card { display: flex; flex-direction: column; + justify-content: space-between; height: 100%; overflow: hidden; --state-color: var(--divider-color, #e0e0e0); --ha-card-border-color: var(--state-color); --state-message-color: var(--state-color); } + .ripple-anchor { + flex-grow: 1; + position: relative; + } + ha-integration-header { + height: 100%; + } + .card-actions { + display: flex; + align-items: center; + justify-content: space-between; + } .debug-logging { --state-color: var(--warning-color); --text-on-state-color: var(--primary-text-color); @@ -254,9 +336,32 @@ export class HaIntegrationCard extends LitElement { text-decoration: none; color: var(--primary-text-color); } - a ha-icon-button { + a ha-icon-next { color: var(--secondary-text-color); } + .icons { + display: flex; + } + .icon { + border-radius: 50%; + color: var(--text-primary-color); + padding: 4px; + margin-left: 8px; + } + .icon.cloud { + background: var(--info-color); + } + .icon.custom { + background: var(--warning-color); + } + .icon ha-svg-icon { + width: 16px; + height: 16px; + display: block; + } + simple-tooltip { + white-space: nowrap; + } `, ]; } diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts index b151114c61..16085d5ead 100644 --- a/src/panels/config/integrations/ha-integration-header.ts +++ b/src/panels/config/integrations/ha-integration-header.ts @@ -1,11 +1,7 @@ -import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; -import { mdiCloud, mdiPackageVariant } from "@mdi/js"; -import { css, html, LitElement, TemplateResult } from "lit"; +import { LitElement, TemplateResult, css, html } from "lit"; import { customElement, property } from "lit/decorators"; -import { classMap } from "lit/directives/class-map"; -import { computeRTL } from "../../../common/util/compute_rtl"; import "../../../components/ha-svg-icon"; -import { domainToName, IntegrationManifest } from "../../../data/integration"; +import { IntegrationManifest, domainToName } from "../../../data/integration"; import { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; @@ -23,8 +19,6 @@ export class HaIntegrationHeader extends LitElement { @property({ attribute: false }) public manifest?: IntegrationManifest; - @property({ attribute: false }) public debugLoggingEnabled?: boolean; - protected render(): TemplateResult { let primary: string; let secondary: string | undefined; @@ -43,31 +37,8 @@ export class HaIntegrationHeader extends LitElement { primary = domainName; } - const icons: [string, string][] = []; - - if (this.manifest) { - if (!this.manifest.is_built_in) { - icons.push([ - mdiPackageVariant, - this.hass.localize( - "ui.panel.config.integrations.config_entry.custom_integration" - ), - ]); - } - - if (this.manifest.iot_class?.startsWith("cloud_")) { - icons.push([ - mdiCloud, - this.hass.localize( - "ui.panel.config.integrations.config_entry.depends_on_cloud" - ), - ]); - } - } - return html` ${!this.banner ? "" : html``} -
- ${icons.length === 0 - ? "" - : html` -
- ${icons.map( - ([icon, description]) => html` - - - ${description} - - ` - )} -
- `}
${primary}
${secondary}
@@ -139,14 +84,13 @@ export class HaIntegrationHeader extends LitElement { .header { display: flex; position: relative; - padding-top: 0px; - padding-bottom: 8px; + padding-top: 16px; + padding-bottom: 16px; padding-inline-start: 16px; padding-inline-end: 8px; direction: var(--direction); } .header img { - margin-top: 16px; margin-inline-start: initial; margin-inline-end: 16px; width: 40px; @@ -166,11 +110,13 @@ export class HaIntegrationHeader extends LitElement { text-overflow: ellipsis; } .header-button { - margin-top: 8px; + display: flex; + align-items: center; + justify-content: center; + width: 36px; } .primary { font-size: 16px; - margin-top: 16px; font-weight: 400; word-break: break-word; color: var(--primary-text-color); @@ -179,41 +125,6 @@ export class HaIntegrationHeader extends LitElement { font-size: 14px; color: var(--secondary-text-color); } - .icons { - background: var(--warning-color); - border: 1px solid var(--card-background-color); - border-radius: 14px; - color: var(--text-primary-color); - position: absolute; - left: 40px; - top: 40px; - display: flex; - padding: 4px; - inset-inline-start: 40px; - inset-inline-end: initial; - } - .icons.cloud { - background: var(--info-color); - } - .icons.double { - background: var(--warning-color); - left: 28px; - inset-inline-start: 28px; - inset-inline-end: initial; - } - .icons ha-svg-icon { - width: 16px; - height: 16px; - display: block; - } - .icons span:not(:first-child) ha-svg-icon { - margin-left: 4px; - margin-inline-start: 4px; - margin-inline-end: inherit; - } - simple-tooltip { - white-space: nowrap; - } `; } From c90c4d88af90cfba24a2e051fd031c7aba9a5b17 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 14:29:35 +0200 Subject: [PATCH 147/162] Fix discovery flow title (#17065) --- src/panels/config/integrations/ha-config-integrations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/panels/config/integrations/ha-config-integrations.ts b/src/panels/config/integrations/ha-config-integrations.ts index 7604d69d36..42ff9330b4 100644 --- a/src/panels/config/integrations/ha-config-integrations.ts +++ b/src/panels/config/integrations/ha-config-integrations.ts @@ -135,13 +135,13 @@ class HaConfigIntegrations extends SubscribeMixin(HassRouterPage) { integrations.add(flow.handler); } }); - await this.hass.loadBackendTranslation( + const localize = await this.hass.loadBackendTranslation( "config", Array.from(integrations) ); this._configEntriesInProgress = flowsInProgress.map((flow) => ({ ...flow, - localized_title: localizeConfigFlowTitle(this.hass.localize, flow), + localized_title: localizeConfigFlowTitle(localize, flow), })); }), ]; From 32a9b13af0a4f5b62ee87489976f117277c943a2 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Wed, 28 Jun 2023 14:38:10 +0200 Subject: [PATCH 148/162] Translate message that script/automation is unavailable (#17066) --- src/panels/config/automation/ha-automation-editor.ts | 4 +++- src/panels/config/script/ha-script-editor.ts | 4 +++- src/translations/en.json | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 9238852502..4dba153f71 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -301,7 +301,9 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ? html` ${this._errors || this._validationErrors} diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index a64a53b9fa..177a5ac8a3 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -315,7 +315,9 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ${this._errors || this._validationErrors} diff --git a/src/translations/en.json b/src/translations/en.json index d6f4567648..371c4c706f 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2206,6 +2206,7 @@ "disable": "[%key:ui::common::disable%]", "disabled": "Automation is disabled", "read_only": "This automation cannot be edited from the UI, because it is not stored in the automations.yaml file, or doesn't have an ID.", + "unavailable": "Automation is unavailable", "migrate": "Migrate", "duplicate": "[%key:ui::common::duplicate%]", "run": "[%key:ui::panel::config::automation::editor::actions::run%]", @@ -2790,6 +2791,7 @@ "show_trace": "[%key:ui::panel::config::automation::editor::show_trace%]", "show_info": "[%key:ui::panel::config::automation::editor::show_info%]", "read_only": "This script cannot be edited from the UI, because it is not stored in the ''scripts.yaml'' file.", + "unavailable": "Script is unavailable", "migrate": "Migrate", "duplicate": "[%key:ui::common::duplicate%]", "header": "Script: {name}", From 24e531a16c1ea94378315226e30c4caaef8754a2 Mon Sep 17 00:00:00 2001 From: Philip Allgaier Date: Wed, 28 Jun 2023 14:48:37 +0200 Subject: [PATCH 149/162] Catch exception if diagnostics are not supported for domain (#17067) --- .../integrations/ha-config-integration-page.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/panels/config/integrations/ha-config-integration-page.ts b/src/panels/config/integrations/ha-config-integration-page.ts index 672b6c26a8..cc4819c05f 100644 --- a/src/panels/config/integrations/ha-config-integration-page.ts +++ b/src/panels/config/integrations/ha-config-integration-page.ts @@ -898,10 +898,14 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) { if (!this.domain || !isComponentLoaded(this.hass, "diagnostics")) { return; } - this._diagnosticHandler = await fetchDiagnosticHandler( - this.hass, - this.domain - ); + try { + this._diagnosticHandler = await fetchDiagnosticHandler( + this.hass, + this.domain + ); + } catch (err: any) { + // No issue, as diagnostics are not required + } } private async _handleEnableDebugLogging() { From 7727bf79019bc44e66d13928b2e1fda3e549aca3 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 15:10:33 +0200 Subject: [PATCH 150/162] Tweak lovelace editor position badge (#17069) --- .../lovelace/components/hui-card-options.ts | 48 +++++++++++-------- src/panels/lovelace/views/hui-masonry-view.ts | 1 + 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 6f87fb30f0..826759cc1e 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -7,6 +7,7 @@ import { CSSResultGroup, html, LitElement, + nothing, PropertyValues, TemplateResult, } from "lit"; @@ -34,6 +35,8 @@ export class HuiCardOptions extends LitElement { @property() public path?: [number, number]; + @property({ type: Boolean }) public showPosition = false; + @queryAssignedNodes() private _assignedNodes?: NodeListOf; @storage({ @@ -68,7 +71,7 @@ export class HuiCardOptions extends LitElement { "ui.panel.lovelace.editor.edit_card.edit" )} -
+
-
- ${this.path![1] + 1} - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_card.position", - "position", - `${this.path![1] + 1}`, - "total", - `${this.lovelace!.config.views[this.path![0]].cards!.length}` - )} -
+ ${this.showPosition + ? html`
+ ${this.path![1] + 1} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_card.position", + "position", + `${this.path![1] + 1}`, + "total", + `${ + this.lovelace!.config.views[this.path![0]].cards!.length + }` + )} +
` + : nothing} Date: Wed, 28 Jun 2023 15:50:43 +0200 Subject: [PATCH 151/162] Fix assist devtools default language (#17071) --- .../developer-tools/assist/developer-tools-assist.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/panels/developer-tools/assist/developer-tools-assist.ts b/src/panels/developer-tools/assist/developer-tools-assist.ts index 89e3890f5c..6cc8470dfb 100644 --- a/src/panels/developer-tools/assist/developer-tools-assist.ts +++ b/src/panels/developer-tools/assist/developer-tools-assist.ts @@ -90,6 +90,15 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { assistAgent?.supported_languages === "*" ? undefined : assistAgent?.supported_languages; + + if ( + !this._language && + this.supportedLanguages?.includes(this.hass.locale.language) + ) { + this._language = this.hass.locale.language; + } else if (!this._language) { + this._language = "en"; + } } protected firstUpdated(): void { @@ -111,7 +120,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { ` From e6d77af4383b6f3a065d32e1aa95a831a7040124 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 15:55:12 +0200 Subject: [PATCH 152/162] Make space for fab (#17070) --- src/panels/lovelace/views/hui-masonry-view.ts | 11 +++++++++-- src/panels/lovelace/views/hui-sidebar-view.ts | 8 +++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/panels/lovelace/views/hui-masonry-view.ts b/src/panels/lovelace/views/hui-masonry-view.ts index ea41c5d69a..45d3d3f1a0 100644 --- a/src/panels/lovelace/views/hui-masonry-view.ts +++ b/src/panels/lovelace/views/hui-masonry-view.ts @@ -90,9 +90,12 @@ export class MasonryView extends LitElement implements LovelaceViewElement { protected render(): TemplateResult { return html` ${this.badges.length > 0 - ? html`
${this.badges}
` + ? html`
${this.badges}
` : ""} -
+
${this.lovelace?.editMode ? html`
+
${this.lovelace?.editMode ? html` Date: Wed, 28 Jun 2023 15:55:46 +0200 Subject: [PATCH 153/162] Make helper forms lazy load (#17068) --- .../config/helpers/dialog-helper-detail.ts | 91 +++++++++++++------ 1 file changed, 61 insertions(+), 30 deletions(-) diff --git a/src/panels/config/helpers/dialog-helper-detail.ts b/src/panels/config/helpers/dialog-helper-detail.ts index 7497b3d608..76efa6e17e 100644 --- a/src/panels/config/helpers/dialog-helper-detail.ts +++ b/src/panels/config/helpers/dialog-helper-detail.ts @@ -33,38 +33,59 @@ import { haStyleDialog } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; import { Helper, HelperDomain } from "./const"; -import "./forms/ha-counter-form"; -import "./forms/ha-input_boolean-form"; -import "./forms/ha-input_button-form"; -import "./forms/ha-input_datetime-form"; -import "./forms/ha-input_number-form"; -import "./forms/ha-input_select-form"; -import "./forms/ha-input_text-form"; -import "./forms/ha-schedule-form"; -import "./forms/ha-timer-form"; import type { ShowDialogHelperDetailParams } from "./show-dialog-helper-detail"; type HelperCreators = { - [domain in HelperDomain]: ( - hass: HomeAssistant, - // Not properly typed because there is currently a mismatch for this._item between: - // 1. Type passed to form should be Helper - // 2. Type received by creator should be MutableParams version - // The two are not compatible. - params: any - ) => Promise; + [domain in HelperDomain]: { + create: ( + hass: HomeAssistant, + // Not properly typed because there is currently a mismatch for this._item between: + // 1. Type passed to form should be Helper + // 2. Type received by creator should be MutableParams version + // The two are not compatible. + params: any + ) => Promise; + import: () => Promise; + }; }; const HELPERS: HelperCreators = { - input_boolean: createInputBoolean, - input_button: createInputButton, - input_text: createInputText, - input_number: createInputNumber, - input_datetime: createInputDateTime, - input_select: createInputSelect, - counter: createCounter, - timer: createTimer, - schedule: createSchedule, + input_boolean: { + create: createInputBoolean, + import: () => import("./forms/ha-input_boolean-form"), + }, + input_button: { + create: createInputButton, + import: () => import("./forms/ha-input_button-form"), + }, + input_text: { + create: createInputText, + import: () => import("./forms/ha-input_text-form"), + }, + input_number: { + create: createInputNumber, + import: () => import("./forms/ha-input_number-form"), + }, + input_datetime: { + create: createInputDateTime, + import: () => import("./forms/ha-input_datetime-form"), + }, + input_select: { + create: createInputSelect, + import: () => import("./forms/ha-input_select-form"), + }, + counter: { + create: createCounter, + import: () => import("./forms/ha-counter-form"), + }, + timer: { + create: createTimer, + import: () => import("./forms/ha-timer-form"), + }, + schedule: { + create: createSchedule, + import: () => import("./forms/ha-schedule-form"), + }, }; @customElement("dialog-helper-detail") @@ -85,6 +106,8 @@ export class DialogHelperDetail extends LitElement { @state() private _helperFlows?: string[]; + @state() private _loading = false; + private _params?: ShowDialogHelperDetailParams; public async showDialog(params: ShowDialogHelperDetailParams): Promise { @@ -140,7 +163,7 @@ export class DialogHelperDetail extends LitElement { ${this.hass!.localize("ui.common.back")} `; - } else if (this._helperFlows === undefined) { + } else if (this._loading || this._helperFlows === undefined) { content = html``; } else { const items: [string, string][] = []; @@ -250,7 +273,7 @@ export class DialogHelperDetail extends LitElement { this._submitting = true; this._error = ""; try { - await HELPERS[this._domain](this.hass, this._item); + await HELPERS[this._domain].create(this.hass, this._item); this.closeDialog(); } catch (err: any) { this._error = err.message || "Unknown error"; @@ -259,14 +282,22 @@ export class DialogHelperDetail extends LitElement { } } - private _domainPicked(ev: CustomEvent): void { + private async _domainPicked( + ev: CustomEvent + ): Promise { if (!shouldHandleRequestSelectedEvent(ev)) { return; } const domain = (ev.currentTarget! as any).domain; if (domain in HELPERS) { - this._domain = domain; + this._loading = true; + try { + await HELPERS[domain].import(); + this._domain = domain; + } finally { + this._loading = false; + } this._focusForm(); } else { showConfigFlowDialog(this, { From eaeb37da4dc23587a53b45979b6deed5f6442ad5 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 28 Jun 2023 16:14:18 +0200 Subject: [PATCH 154/162] Update humidifier Ui with current humidity and action (#17072) --- src/common/const.ts | 1 + src/common/entity/get_states.ts | 1 + src/components/ha-humidifier-state.ts | 137 ++++++++++++++++++ src/data/humidifier.ts | 10 +- .../controls/more-info-humidifier.ts | 59 +++++++- src/panels/lovelace/cards/hui-tile-card.ts | 19 +-- .../tile/badges/tile-badge-humidifier.ts | 41 ++++++ .../lovelace/cards/tile/badges/tile-badge.ts | 3 + .../entity-rows/hui-humidifier-entity-row.ts | 45 +++--- src/state-summary/state-card-content.js | 1 + src/state-summary/state-card-humidifier.js | 55 +++++++ src/translations/en.json | 1 + 12 files changed, 331 insertions(+), 42 deletions(-) create mode 100644 src/components/ha-humidifier-state.ts create mode 100644 src/panels/lovelace/cards/tile/badges/tile-badge-humidifier.ts create mode 100644 src/state-summary/state-card-humidifier.js diff --git a/src/common/const.ts b/src/common/const.ts index 76275f55a2..b4f79e5126 100644 --- a/src/common/const.ts +++ b/src/common/const.ts @@ -182,6 +182,7 @@ export const DOMAINS_WITH_CARD = [ "input_select", "input_number", "input_text", + "humidifier", "lock", "media_player", "number", diff --git a/src/common/entity/get_states.ts b/src/common/entity/get_states.ts index 76e36ada3c..f8d10ad99f 100644 --- a/src/common/entity/get_states.ts +++ b/src/common/entity/get_states.ts @@ -135,6 +135,7 @@ const FIXED_DOMAIN_ATTRIBUTE_STATES = { }, humidifier: { device_class: ["humidifier", "dehumidifier"], + action: ["off", "idle", "humidifying", "drying"], }, media_player: { device_class: ["tv", "speaker", "receiver"], diff --git a/src/components/ha-humidifier-state.ts b/src/components/ha-humidifier-state.ts new file mode 100644 index 0000000000..fbf9cfe519 --- /dev/null +++ b/src/components/ha-humidifier-state.ts @@ -0,0 +1,137 @@ +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { customElement, property } from "lit/decorators"; +import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display"; +import { computeStateDisplay } from "../common/entity/compute_state_display"; +import { formatNumber } from "../common/number/format_number"; +import { blankBeforePercent } from "../common/translations/blank_before_percent"; +import { isUnavailableState, OFF } from "../data/entity"; +import { HumidifierEntity } from "../data/humidifier"; +import type { HomeAssistant } from "../types"; + +@customElement("ha-humidifier-state") +class HaHumidifierState extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj!: HumidifierEntity; + + protected render(): TemplateResult { + const currentStatus = this._computeCurrentStatus(); + + return html`
+ ${!isUnavailableState(this.stateObj.state) + ? html` + ${this._localizeState()} + ${this.stateObj.attributes.mode + ? html`- + ${computeAttributeValueDisplay( + this.hass.localize, + this.stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities, + "mode" + )}` + : ""} + +
${this._computeTarget()}
` + : this._localizeState()} +
+ + ${currentStatus && !isUnavailableState(this.stateObj.state) + ? html`
+ ${this.hass.localize("ui.card.climate.currently")}: +
${currentStatus}
+
` + : ""}`; + } + + private _computeCurrentStatus(): string | undefined { + if (!this.hass || !this.stateObj) { + return undefined; + } + + if (this.stateObj.attributes.current_humidity != null) { + return `${formatNumber( + this.stateObj.attributes.current_humidity, + this.hass.locale + )}${blankBeforePercent(this.hass.locale)}%`; + } + + return undefined; + } + + private _computeTarget(): string { + if (!this.hass || !this.stateObj) { + return ""; + } + + if (this.stateObj.attributes.humidity != null) { + return `${formatNumber( + this.stateObj.attributes.humidity, + this.hass.locale + )}${blankBeforePercent(this.hass.locale)}%`; + } + + return ""; + } + + private _localizeState(): string { + if (isUnavailableState(this.stateObj.state)) { + return this.hass.localize(`state.default.${this.stateObj.state}`); + } + + const stateString = computeStateDisplay( + this.hass.localize, + this.stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities + ); + + return this.stateObj.attributes.action && this.stateObj.state !== OFF + ? `${computeAttributeValueDisplay( + this.hass.localize, + this.stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities, + "action" + )} (${stateString})` + : stateString; + } + + static get styles(): CSSResultGroup { + return css` + :host { + display: flex; + flex-direction: column; + justify-content: center; + white-space: nowrap; + } + + .target { + color: var(--primary-text-color); + } + + .current { + color: var(--secondary-text-color); + } + + .state-label { + font-weight: bold; + text-transform: capitalize; + } + + .unit { + display: inline-block; + direction: ltr; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-humidifier-state": HaHumidifierState; + } +} diff --git a/src/data/humidifier.ts b/src/data/humidifier.ts index ace536b9ca..dd83e21003 100644 --- a/src/data/humidifier.ts +++ b/src/data/humidifier.ts @@ -2,21 +2,19 @@ import { HassEntityAttributeBase, HassEntityBase, } from "home-assistant-js-websocket"; -import { FIXED_DOMAIN_STATES } from "../common/entity/get_states"; -import { UNAVAILABLE_STATES } from "./entity"; -type HumidifierState = - | (typeof FIXED_DOMAIN_STATES.humidifier)[number] - | (typeof UNAVAILABLE_STATES)[number]; +export type HumidifierState = "on" | "off"; + +export type HumidifierAction = "off" | "idle" | "humidifying" | "drying"; export type HumidifierEntity = HassEntityBase & { - state: HumidifierState; attributes: HassEntityAttributeBase & { humidity?: number; current_humidity?: number; min_humidity?: number; max_humidity?: number; mode?: string; + action: HumidifierAction; available_modes?: string[]; }; }; diff --git a/src/dialogs/more-info/controls/more-info-humidifier.ts b/src/dialogs/more-info/controls/more-info-humidifier.ts index 527c82461f..75dba4faf8 100644 --- a/src/dialogs/more-info/controls/more-info-humidifier.ts +++ b/src/dialogs/more-info/controls/more-info-humidifier.ts @@ -10,7 +10,10 @@ import { import { property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../../common/dom/fire_event"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; +import { + computeAttributeNameDisplay, + computeAttributeValueDisplay, +} from "../../../common/entity/compute_attribute_display"; import { stopPropagation } from "../../../common/dom/stop_propagation"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; @@ -22,6 +25,7 @@ import { HUMIDIFIER_SUPPORT_MODES, } from "../../../data/humidifier"; import { HomeAssistant } from "../../../types"; +import { computeStateDisplay } from "../../../common/entity/compute_state_display"; class MoreInfoHumidifier extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -49,7 +53,14 @@ class MoreInfoHumidifier extends LitElement { })} >
-
${hass.localize("ui.card.humidifier.humidity")}
+
+ ${computeAttributeNameDisplay( + hass.localize, + stateObj, + hass.entities, + "humidity" + )} +
${stateObj.attributes.humidity} %
+ + + ${computeStateDisplay( + hass.localize, + stateObj, + hass.locale, + this.hass.config, + hass.entities, + "off" + )} + + + ${computeStateDisplay( + hass.localize, + stateObj, + hass.locale, + this.hass.config, + hass.entities, + "on" + )} + + ${supportModes ? html` @@ -123,6 +163,16 @@ class MoreInfoHumidifier extends LitElement { ); } + private _handleStateChanged(ev) { + const newVal = ev.target.value || null; + this._callServiceHelper( + this.stateObj!.state, + newVal, + newVal === "on" ? "turn_on" : "turn_off", + {} + ); + } + private _handleModeChanged(ev) { const newVal = ev.target.value || null; this._callServiceHelper( @@ -179,6 +229,11 @@ class MoreInfoHumidifier extends LitElement { ha-select { width: 100%; + margin-top: 8px; + } + + ha-slider { + width: 100%; } .container-humidity .single-row { diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 6afd8be31d..3471b6348b 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -225,15 +225,6 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } } - if (domain === "humidifier" && stateActive(stateObj)) { - const humidity = (stateObj as HumidifierEntity).attributes.humidity; - if (humidity) { - return `${Math.round(humidity)}${blankBeforePercent( - this.hass!.locale - )}%`; - } - } - const stateDisplay = computeStateDisplay( this.hass!.localize, stateObj, @@ -251,6 +242,16 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return `${stateDisplay} ⸱ ${positionStateDisplay}`; } } + + if (domain === "humidifier" && stateActive(stateObj)) { + const humidity = (stateObj as HumidifierEntity).attributes.humidity; + if (humidity) { + return `${stateDisplay} ⸱ ${Math.round(humidity)}${blankBeforePercent( + this.hass!.locale + )}%`; + } + } + return stateDisplay; } diff --git a/src/panels/lovelace/cards/tile/badges/tile-badge-humidifier.ts b/src/panels/lovelace/cards/tile/badges/tile-badge-humidifier.ts new file mode 100644 index 0000000000..c4901e0b2d --- /dev/null +++ b/src/panels/lovelace/cards/tile/badges/tile-badge-humidifier.ts @@ -0,0 +1,41 @@ +import { + mdiArrowDownBold, + mdiArrowUpBold, + mdiClockOutline, + mdiPower, +} from "@mdi/js"; +import { stateColorCss } from "../../../../../common/entity/state_color"; +import { + HumidifierAction, + HumidifierEntity, + HumidifierState, +} from "../../../../../data/humidifier"; +import { ComputeBadgeFunction } from "./tile-badge"; + +export const HUMIDIFIER_ACTION_ICONS: Record = { + drying: mdiArrowDownBold, + humidifying: mdiArrowUpBold, + idle: mdiClockOutline, + off: mdiPower, +}; + +export const HUMIDIFIER_ACTION_MODE: Record = + { + drying: "on", + humidifying: "on", + idle: "off", + off: "off", + }; + +export const computeHumidifierBadge: ComputeBadgeFunction = (stateObj) => { + const hvacAction = (stateObj as HumidifierEntity).attributes.action; + + if (!hvacAction || hvacAction === "off") { + return undefined; + } + + return { + iconPath: HUMIDIFIER_ACTION_ICONS[hvacAction], + color: stateColorCss(stateObj, HUMIDIFIER_ACTION_MODE[hvacAction]), + }; +}; diff --git a/src/panels/lovelace/cards/tile/badges/tile-badge.ts b/src/panels/lovelace/cards/tile/badges/tile-badge.ts index e303c49129..5281f3591d 100644 --- a/src/panels/lovelace/cards/tile/badges/tile-badge.ts +++ b/src/panels/lovelace/cards/tile/badges/tile-badge.ts @@ -5,6 +5,7 @@ import { UNAVAILABLE, UNKNOWN } from "../../../../../data/entity"; import { HomeAssistant } from "../../../../../types"; import { computeClimateBadge } from "./tile-badge-climate"; import { computePersonBadge } from "./tile-badge-person"; +import { computeHumidifierBadge } from "./tile-badge-humidifier"; export type TileBadge = { color?: string; @@ -34,6 +35,8 @@ export const computeTileBadge: ComputeBadgeFunction = (stateObj, hass) => { return computePersonBadge(stateObj, hass); case "climate": return computeClimateBadge(stateObj, hass); + case "humidifier": + return computeHumidifierBadge(stateObj, hass); default: return undefined; } diff --git a/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts b/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts index 4aa7738253..4463710945 100644 --- a/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-humidifier-entity-row.ts @@ -1,11 +1,18 @@ -import { html, LitElement, PropertyValues, nothing } from "lit"; +import { + CSSResultGroup, + LitElement, + PropertyValues, + css, + html, + nothing, +} from "lit"; import { customElement, property } from "lit/decorators"; import "../../../components/entity/ha-entity-toggle"; +import "../../../components/ha-humidifier-state"; import { HumidifierEntity } from "../../../data/humidifier"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-generic-entity-row"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { EntityConfig, LovelaceRow } from "./types"; @@ -43,32 +50,20 @@ class HuiHumidifierEntityRow extends LitElement implements LovelaceRow { } return html` - - + + + `; } + + static get styles(): CSSResultGroup { + return css` + ha-humidifier-state { + text-align: right; + } + `; + } } declare global { diff --git a/src/state-summary/state-card-content.js b/src/state-summary/state-card-content.js index 21ca9d08c1..b1669ae994 100644 --- a/src/state-summary/state-card-content.js +++ b/src/state-summary/state-card-content.js @@ -4,6 +4,7 @@ import dynamicContentUpdater from "../common/dom/dynamic_content_updater"; import { stateCardType } from "../common/entity/state_card_type"; import "./state-card-button"; import "./state-card-climate"; +import "./state-card-humidifier"; import "./state-card-configurator"; import "./state-card-cover"; import "./state-card-display"; diff --git a/src/state-summary/state-card-humidifier.js b/src/state-summary/state-card-humidifier.js new file mode 100644 index 0000000000..a99b6a539d --- /dev/null +++ b/src/state-summary/state-card-humidifier.js @@ -0,0 +1,55 @@ +import "@polymer/iron-flex-layout/iron-flex-layout-classes"; +import { html } from "@polymer/polymer/lib/utils/html-tag"; +/* eslint-plugin-disable lit */ +import { PolymerElement } from "@polymer/polymer/polymer-element"; +import "../components/entity/state-info"; +import "../components/ha-humidifier-state"; + +class StateCardHumidifier extends PolymerElement { + static get template() { + return html` + + + +
+ ${this.stateInfoTemplate} + +
+ `; + } + + static get stateInfoTemplate() { + return html` + + `; + } + + static get properties() { + return { + hass: Object, + stateObj: Object, + inDialog: { + type: Boolean, + value: false, + }, + }; + } +} +customElements.define("state-card-humidifier", StateCardHumidifier); diff --git a/src/translations/en.json b/src/translations/en.json index 371c4c706f..68dd5c721f 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -131,6 +131,7 @@ }, "humidifier": { "humidity": "Target humidity", + "state": "State", "mode": "Mode", "target_humidity_entity": "{name} target humidity", "on_entity": "{name} on" From 345aef8d6584303d759362295ab8349c064039ad Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 28 Jun 2023 07:37:18 -0700 Subject: [PATCH 155/162] Add fab spacer for backups table (#17075) --- src/panels/config/backup/ha-config-backup.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/panels/config/backup/ha-config-backup.ts b/src/panels/config/backup/ha-config-backup.ts index 8d0dfca0d4..07ebf618e6 100644 --- a/src/panels/config/backup/ha-config-backup.ts +++ b/src/panels/config/backup/ha-config-backup.ts @@ -128,6 +128,7 @@ class HaConfigBackup extends LitElement { return html` Date: Wed, 28 Jun 2023 17:47:39 +0300 Subject: [PATCH 156/162] Humidifier action (#17056) * Add action attribute to humidifier * Humidifier: Use action instead of state if that is available * rebase --------- Co-authored-by: Bram Kragten --- src/data/humidifier.ts | 2 +- .../lovelace/cards/hui-humidifier-card.ts | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/data/humidifier.ts b/src/data/humidifier.ts index dd83e21003..90d70f68d4 100644 --- a/src/data/humidifier.ts +++ b/src/data/humidifier.ts @@ -14,7 +14,7 @@ export type HumidifierEntity = HassEntityBase & { min_humidity?: number; max_humidity?: number; mode?: string; - action: HumidifierAction; + action?: HumidifierAction; available_modes?: string[]; }; }; diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index bca4924cc1..57e9ee8ee5 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -165,13 +165,24 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { text-anchor="middle" id="set-mode" > - ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + ${ + stateObj.attributes.action + ? computeAttributeValueDisplay( + this.hass.localize, + stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities, + "action" + ) + : computeStateDisplay( + this.hass.localize, + stateObj, + this.hass.locale, + this.hass.config, + this.hass.entities + ) + } ${ stateObj.state !== UNAVAILABLE && stateObj.attributes.mode ? html` From e2daa89941f41de70c5d7dc64a35f8b997c71d11 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 16:48:06 +0200 Subject: [PATCH 157/162] Add space for FAB on addon page (#17076) --- hassio/src/dashboard/hassio-addons.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hassio/src/dashboard/hassio-addons.ts b/hassio/src/dashboard/hassio-addons.ts index 10f883c3d3..6c9ce1d5f2 100644 --- a/hassio/src/dashboard/hassio-addons.ts +++ b/hassio/src/dashboard/hassio-addons.ts @@ -137,6 +137,9 @@ class HassioAddons extends LitElement { --mdc-text-field-fill-color: var(--sidebar-background-color); --mdc-text-field-idle-line-color: var(--divider-color); } + .content { + margin-bottom: 72px; + } `, ]; } From ce88c594b75a5777baaa7950a7309e688da2a75c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 16:48:32 +0200 Subject: [PATCH 158/162] Submit assist dev tools on enter (#17073) --- .../developer-tools/assist/developer-tools-assist.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/panels/developer-tools/assist/developer-tools-assist.ts b/src/panels/developer-tools/assist/developer-tools-assist.ts index 6cc8470dfb..45279d0b22 100644 --- a/src/panels/developer-tools/assist/developer-tools-assist.ts +++ b/src/panels/developer-tools/assist/developer-tools-assist.ts @@ -51,6 +51,14 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { this._language = ev.detail.value; } + private _handleKeyDown(e: KeyboardEvent) { + if (e.code !== "Enter" || e.shiftKey) { + return; + } + e.preventDefault(); + this._parse(); + } + private _textAreaInput(ev) { const value = ev.target.value; const valid = Boolean(value); @@ -130,6 +138,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { label="Sentences" id="sentences-input" @input=${this._textAreaInput} + @keydown=${this._handleKeyDown} >
From 6fea7a710661efbf62a037de039a612c7d8cb3fa Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 16:58:32 +0200 Subject: [PATCH 159/162] Move integration sections into their own container (#17078) --- .../ha-config-integrations-dashboard.ts | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/panels/config/integrations/ha-config-integrations-dashboard.ts b/src/panels/config/integrations/ha-config-integrations-dashboard.ts index 5524c31d26..179167cd22 100644 --- a/src/panels/config/integrations/ha-config-integrations-dashboard.ts +++ b/src/panels/config/integrations/ha-config-integrations-dashboard.ts @@ -376,10 +376,9 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) {
`} - -
- ${this._showIgnored - ? ignoredConfigEntries.map( + ${this._showIgnored + ? html`
+ ${ignoredConfigEntries.map( (entry: ConfigEntryExtended) => html` ` - ) - : ""} - ${configEntriesInProgress.length - ? configEntriesInProgress.map( + )} +
` + : ""} + ${configEntriesInProgress.length + ? html`
+ ${configEntriesInProgress.map( (flow: DataEntryFlowProgressExtended) => html` ` - ) - : ""} - ${this._showDisabled - ? disabledConfigEntries.map( + )} +
` + : ""} + ${this._showDisabled + ? html`
+ ${disabledConfigEntries.map( (entry: ConfigEntryExtended) => html` ` - ) - : ""} + )} +
` + : ""} +
${integrations.length ? integrations.map( ([domain, items]) => @@ -744,6 +749,8 @@ class HaConfigIntegrationsDashboard extends SubscribeMixin(LitElement) { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); grid-gap: 16px 16px; padding: 8px 16px 16px; + } + .container:last-of-type { margin-bottom: 64px; } .container > * { From c3c6c631694072f19724b275532e56bbebe5a7b1 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 28 Jun 2023 17:14:10 +0200 Subject: [PATCH 160/162] Add move card to position on dashboard editor (#17077) * Add move card to position on dashboard editor * Feedbacks --- .../lovelace/components/hui-card-options.ts | 78 +++++++++++++------ src/panels/lovelace/editor/config-util.ts | 29 +++++++ src/translations/en.json | 6 +- 3 files changed, 87 insertions(+), 26 deletions(-) diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 826759cc1e..37d5a4d27e 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -2,28 +2,37 @@ import "@material/mwc-button"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import "@material/mwc-list/mwc-list-item"; import { mdiArrowDown, mdiArrowUp, mdiDotsVertical } from "@mdi/js"; +import deepClone from "deep-clone-simple"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, TemplateResult, + css, + html, + nothing, } from "lit"; import { customElement, property, queryAssignedNodes } from "lit/decorators"; -import deepClone from "deep-clone-simple"; import { storage } from "../../../common/decorators/storage"; import { fireEvent } from "../../../common/dom/fire_event"; import "../../../components/ha-button-menu"; import "../../../components/ha-icon-button"; -import { saveConfig, LovelaceCardConfig } from "../../../data/lovelace"; -import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; +import { LovelaceCardConfig, saveConfig } from "../../../data/lovelace"; +import { + showAlertDialog, + showPromptDialog, +} from "../../../dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../../../types"; import { showSaveSuccessToast } from "../../../util/toast-saved-success"; import { computeCardSize } from "../common/compute-card-size"; import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog"; -import { addCard, deleteCard, moveCard, swapCard } from "../editor/config-util"; +import { + addCard, + deleteCard, + moveCard, + moveCardToPosition, + swapCard, +} from "../editor/config-util"; import { showSelectViewDialog } from "../editor/select-view/show-select-view-dialog"; import { Lovelace, LovelaceCard } from "../types"; @@ -35,10 +44,10 @@ export class HuiCardOptions extends LitElement { @property() public path?: [number, number]; - @property({ type: Boolean }) public showPosition = false; - @queryAssignedNodes() private _assignedNodes?: NodeListOf; + @property({ type: Boolean }) public showPosition = false; + @storage({ key: "lovelaceClipboard", state: false, @@ -85,20 +94,14 @@ export class HuiCardOptions extends LitElement { this.path![1] + 1} > ${this.showPosition - ? html`
- ${this.path![1] + 1} - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_card.position", - "position", - `${this.path![1] + 1}`, - "total", - `${ - this.lovelace!.config.views[this.path![0]].cards!.length - }` - )} -
` + ? html` +
${this.path![1] + 1}
+
` : nothing} { + const lovelace = this.lovelace!; + const path = this.path!; + + const positionString = await showPromptDialog(this, { + title: this.hass!.localize( + "ui.panel.lovelace.editor.change_position.title" + ), + text: this.hass!.localize( + "ui.panel.lovelace.editor.change_position.text" + ), + inputType: "number", + placeholder: String(path[1] + 1), + }); + + if (!positionString) return; + + const position = parseInt(positionString); + + if (isNaN(position)) return; + + lovelace.saveConfig(moveCardToPosition(lovelace.config, path, position)); + } + private _moveCard(): void { showSelectViewDialog(this, { lovelaceConfig: this.lovelace!.config, diff --git a/src/panels/lovelace/editor/config-util.ts b/src/panels/lovelace/editor/config-util.ts index bf15aafbdc..ce8f11bfbb 100644 --- a/src/panels/lovelace/editor/config-util.ts +++ b/src/panels/lovelace/editor/config-util.ts @@ -185,6 +185,35 @@ export const swapCard = ( }; }; +export const moveCardToPosition = ( + config: LovelaceConfig, + path: [number, number], + position: number +) => { + const view = config.views[path[0]]; + + const oldIndex = path[1]; + const newIndex = Math.max(Math.min(position - 1, view.cards!.length - 1), 0); + + const newCards = [...view.cards!]; + + const card = newCards[oldIndex]; + newCards.splice(oldIndex, 1); + newCards.splice(newIndex, 0, card); + + const newView = { + ...view, + cards: newCards, + }; + + return { + ...config, + views: config.views.map((origView, index) => + index === path[0] ? newView : origView + ), + }; +}; + export const moveCard = ( config: LovelaceConfig, fromPath: [number, number], diff --git a/src/translations/en.json b/src/translations/en.json index 68dd5c721f..2f71088f55 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -4479,13 +4479,17 @@ "move_down": "Move card down", "move_before": "Move card before", "move_after": "Move card after", - "position": "Card is in position {position} of {total}", + "change_position": "Change card position", "options": "More options", "search_cards": "Search cards" }, "move_card": { "header": "Choose a view to move the card to" }, + "change_position": { + "title": "Change card position", + "text": "What position do you want to move your card to?" + }, "select_view": { "header": "Choose a view", "dashboard_label": "Dashboard", From de7f055419bbfa7be5b4cbd106476570c92f9700 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 17:19:04 +0200 Subject: [PATCH 161/162] Bumped version to 20230628.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a2db861dc4..421f20a4ab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20230608.0" +version = "20230628.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From f6d06f5e26ebaa41e9bc9f1f437db753d5e60834 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 28 Jun 2023 17:19:47 +0200 Subject: [PATCH 162/162] Remove time from assist dev tools (#17079) --- .../assist/developer-tools-assist.ts | 49 ++++++------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/src/panels/developer-tools/assist/developer-tools-assist.ts b/src/panels/developer-tools/assist/developer-tools-assist.ts index 45279d0b22..9080e13394 100644 --- a/src/panels/developer-tools/assist/developer-tools-assist.ts +++ b/src/panels/developer-tools/assist/developer-tools-assist.ts @@ -5,7 +5,6 @@ import "../../../components/ha-button"; import "../../../components/ha-code-editor"; import "../../../components/ha-language-picker"; import "../../../components/ha-textarea"; -import "../../../components/ha-absolute-time"; import type { HaTextArea } from "../../../components/ha-textarea"; import { AssitDebugResult, @@ -22,7 +21,6 @@ type SentenceParsingResult = { sentence: string; language: string; result: AssitDebugResult | null; - time: Date; }; @customElement("developer-tools-assist") @@ -75,8 +73,6 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { this._sentencesInput.value = ""; - const now = new Date(); - const newResults: SentenceParsingResult[] = []; sentences.forEach((sentence, index) => { const result = results[index]; @@ -85,7 +81,6 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { sentence, language: this._language!, result, - time: now, }); }); this._results = [...newResults, ...this._results]; @@ -152,7 +147,7 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) { ${this._results.map((r) => { - const { sentence, result, language, time } = r; + const { sentence, result, language } = r; const matched = result != null; return html` @@ -163,34 +158,22 @@ class HaPanelDevAssist extends SubscribeMixin(LitElement) {

${matched ? "✅" : "❌"}

-

- Language: ${formatLanguageCode( - language, - this.hass.locale - )} (${language}) -

-

Execution time: - - -

- -

+ Language: ${formatLanguageCode(language, this.hass.locale)} + (${language})
- ${ - result - ? html` - - ` - : html`No intent matched` - } + ${result + ? html` + + ` + : html` + No intent matched + `}
`;