Compare commits

..

53 Commits

Author SHA1 Message Date
Paul Bottein
261cc6598d Add conditional form schema 2023-06-08 16:38:07 +02:00
Paul Bottein
8580d3f9bf Bumped version to 20230608.0 2023-06-08 15:08:18 +02:00
Bram Kragten
6d29b764d3 Integration page fixes (#16822) 2023-06-08 14:11:52 +02:00
Joakim Sørensen
78cff3a921 Use menu_options instead of menu_issues for translation (#16823) 2023-06-08 11:13:12 +00:00
Paul Bottein
e3c312feaf Sort related entities by name (#16821) 2023-06-08 13:01:46 +02:00
Paul Bottein
31e4166248 Make to full integration card header clickable (#16819) 2023-06-08 10:42:26 +02:00
Bram Kragten
0442e3e06e Bumped version to 20230607.0 2023-06-07 12:15:32 +02:00
english-ra
0a8252c16a Fixed issue where the cursor would not change to grabbing when a user… (#16808) 2023-06-07 09:44:54 +00:00
puddly
0a62d711f2 Allow the ZHA serial port path to wrap if it is too long (#16806)
Allow the serial port path to wrap if it is too long
2023-06-07 11:34:17 +02:00
karwosts
d7c3ff3e9d Fix cancel button in automation row alias rename dialog (#16810) 2023-06-07 11:27:50 +02:00
renovate[bot]
2767f866f3 Update dependency @octokit/plugin-retry to v5 (#16803)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 19:53:57 +00:00
renovate[bot]
040d5af0aa Update dependency eslint to v8.42.0 (#16789)
* Update dependency eslint to v8.42.0

* Update resize-observer.polyfill.ts

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-06-06 19:44:54 +00:00
renovate[bot]
06c6e312b0 Update workbox monorepo to v7 (major) (#16747)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 21:41:04 +02:00
renovate[bot]
841dffe563 Update Yarn to v3.6.0 (#16759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 21:39:10 +02:00
renovate[bot]
a41e0d446f Update vaadinWebComponents monorepo to v24.0.8 (#16768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 21:38:08 +02:00
renovate[bot]
9a0f24cd8b Update dependency @lrnwebcomponents/simple-tooltip to v7.0.2 (#16758)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 21:37:20 +02:00
puddly
2e531a9006 Add channel 26 to ZHA channel changing dialog dropdown (#16801)
Add 26 to list of valid ZHA network channels
2023-06-06 19:31:50 +00:00
karwosts
76255f2efb Fix ha-devices-picker when changing or deleting devices (#16739) 2023-06-06 21:28:07 +02:00
karwosts
19fc92419a Add miscellaneous UI elements for translation (#16797) 2023-06-06 16:37:58 +02:00
Bram Kragten
e7c2625cf1 Bumped version to 20230606.0 2023-06-06 16:32:45 +02:00
Bram Kragten
c39fdcda6e Fix 403 on state-badge connect (#16795) 2023-06-06 13:42:45 +02:00
Paul Bottein
fd1381ab3b Update history chart when entity change in the more info dialog (#16794) 2023-06-06 11:14:11 +02:00
Paul Bottein
7b8f4d1e72 Fix label for cover button mode (#16791) 2023-06-06 09:07:53 +02:00
renovate[bot]
b0a278df97 Update dependency @octokit/plugin-retry to v4.1.6 (#16788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 01:25:59 -04:00
Bram Kragten
93e31df106 Use integration_type as header for config entries (#16786) 2023-06-05 19:18:42 +02:00
Bram Kragten
47fdae764f Improve display of disabled config entries (#16784) 2023-06-05 19:00:06 +02:00
Bram Kragten
b8efc06caa Bumped version to 20230605.0 2023-06-05 18:22:38 +02:00
Bram Kragten
fcacdf6534 Add all devices and entities link to integration page (#16781) 2023-06-05 15:52:11 +00:00
Paul Bottein
45d260f0ce Move add config entry button to card (#16783) 2023-06-05 15:49:05 +00:00
renovate[bot]
d5f46a69b0 Update dependency @octokit/plugin-retry to v4.1.5 (#16782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-05 17:45:44 +02:00
Bram Kragten
fe8eb333b9 Limit integration card to 1 action row (#16780) 2023-06-05 17:23:28 +02:00
Paul Bottein
677cd2de10 Fix integration card tooltip (#16779)
* Fix integration card tooltip

* Update src/panels/config/integrations/ha-integration-header.ts

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

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-06-05 14:13:27 +00:00
Bram Kragten
1470eb484f Add more info controls for date/time/datetime (#16775)
* Add more info controls for date/time/datetime

* Discard changes to src/panels/lovelace/entity-rows/hui-date-entity-row.ts

* handle unavailable
2023-06-05 16:10:38 +02:00
Bram Kragten
10ee8fda5b Improve protocol integration add device / integration (#16767) 2023-06-05 14:08:55 +00:00
Bram Kragten
e044ddcb57 Align+fix date time entity rows (#16774) 2023-06-05 13:55:15 +00:00
Bram Kragten
29c564bb69 Fix maps card with location sources (#16778) 2023-06-05 15:53:57 +02:00
Bram Kragten
1bf03f020e Fix closing notification drawer (#16769) 2023-06-05 14:26:51 +02:00
Bram Kragten
6c684fd8ee Show number config entries when no devices/entities (#16766) 2023-06-05 14:17:03 +02:00
Simon Lamon
ddaf403378 Fix dropdown selection in General Settings (#16754) 2023-06-05 11:57:20 +00:00
Paul Bottein
b337074758 Fix collapsed masonry view in safari (#16772) 2023-06-05 13:48:16 +02:00
Bram Kragten
a96eff4d25 Fix padding on thread config panel (#16770) 2023-06-05 13:06:54 +02:00
puddly
e6bdc3a15e Disable ZHA channel changing when multi-PAN is in use (#16731)
* Show baudrate and port in the ZHA network info

* Do not allow changing the Zigbee channel with the multiprotocol addon

* Include translations as well

* Update src/translations/en.json

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2023-06-05 10:27:36 +00:00
renovate[bot]
33e15eec22 Update dependency @lit-labs/context to v0.3.2 (#16760)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-05 09:50:00 +02:00
renovate[bot]
3c0afd6cde Update dependency lit to v2.7.5 (#16763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-05 09:48:45 +02:00
Joakim Sørensen
31a3fa02d9 Allow for lazy loading images in markdown (#16746) 2023-06-05 09:46:38 +02:00
Paul Bottein
71954f545c Fix white brightness effect on color wheel (#16738) 2023-06-05 09:39:53 +02:00
Paul Bottein
9f3e8abe69 Don't show edit favorite colors button if the light doesn't support it (#16750) 2023-06-05 09:39:36 +02:00
renovate[bot]
21f983572c Update dependency @octokit/plugin-retry to v4.1.4 (#16762)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-05 01:20:24 -04:00
renovate[bot]
5667d71b02 Update dependency @rollup/plugin-node-resolve to v15.1.0 (#16741)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-02 23:40:50 -04:00
Bram Kragten
0d0e5fdaaa Hide ignored entries (#16737) 2023-06-02 12:08:02 +02:00
karwosts
b1f5ff26d9 Fix device selector when picking devices with no entities (#16734) 2023-06-02 11:26:07 +02:00
renovate[bot]
27451ca30e Update typescript-eslint monorepo to v5.59.8 (#16730) 2023-06-01 22:09:45 -04:00
Paul Bottein
928b4e6f1e Add native color picker option (fix for firefox) (#16729) 2023-06-01 16:31:18 +00:00
61 changed files with 1791 additions and 1064 deletions

File diff suppressed because one or more lines are too long

View File

@@ -8,4 +8,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools" spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-3.5.1.cjs yarnPath: .yarn/releases/yarn-3.6.0.cjs

View File

@@ -44,7 +44,10 @@ class HassioAddonDocumentationDashboard extends LitElement {
: ""} : ""}
<div class="card-content"> <div class="card-content">
${this._content ${this._content
? html`<ha-markdown .content=${this._content}></ha-markdown>` ? html`<ha-markdown
.content=${this._content}
lazy-images
></ha-markdown>`
: html`<hass-loading-screen no-toolbar></hass-loading-screen>`} : html`<hass-loading-screen no-toolbar></hass-loading-screen>`}
</div> </div>
</ha-card> </ha-card>

View File

@@ -659,6 +659,7 @@ class HassioAddonInfo extends LitElement {
<div class="card-content"> <div class="card-content">
<ha-markdown <ha-markdown
.content=${this.addon.long_description} .content=${this.addon.long_description}
lazy-images
></ha-markdown> ></ha-markdown>
</div> </div>
</ha-card> </ha-card>

View File

@@ -48,10 +48,10 @@
"@fullcalendar/list": "6.1.8", "@fullcalendar/list": "6.1.8",
"@fullcalendar/timegrid": "6.1.8", "@fullcalendar/timegrid": "6.1.8",
"@lezer/highlight": "1.1.6", "@lezer/highlight": "1.1.6",
"@lit-labs/context": "0.3.1", "@lit-labs/context": "0.3.2",
"@lit-labs/motion": "1.0.3", "@lit-labs/motion": "1.0.3",
"@lit-labs/virtualizer": "2.0.2", "@lit-labs/virtualizer": "2.0.2",
"@lrnwebcomponents/simple-tooltip": "7.0.0", "@lrnwebcomponents/simple-tooltip": "7.0.2",
"@material/chips": "=14.0.0-canary.53b3cad2f.0", "@material/chips": "=14.0.0-canary.53b3cad2f.0",
"@material/data-table": "=14.0.0-canary.53b3cad2f.0", "@material/data-table": "=14.0.0-canary.53b3cad2f.0",
"@material/mwc-button": "0.27.0", "@material/mwc-button": "0.27.0",
@@ -92,8 +92,8 @@
"@polymer/paper-toast": "3.0.1", "@polymer/paper-toast": "3.0.1",
"@polymer/polymer": "3.5.1", "@polymer/polymer": "3.5.1",
"@thomasloven/round-slider": "0.6.0", "@thomasloven/round-slider": "0.6.0",
"@vaadin/combo-box": "24.0.7", "@vaadin/combo-box": "24.0.8",
"@vaadin/vaadin-themable-mixin": "24.0.7", "@vaadin/vaadin-themable-mixin": "24.0.8",
"@vibrant/color": "3.2.1-alpha.1", "@vibrant/color": "3.2.1-alpha.1",
"@vibrant/core": "3.2.1-alpha.1", "@vibrant/core": "3.2.1-alpha.1",
"@vibrant/quantizer-mmcq": "3.2.1-alpha.1", "@vibrant/quantizer-mmcq": "3.2.1-alpha.1",
@@ -118,7 +118,7 @@
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"leaflet": "1.9.4", "leaflet": "1.9.4",
"leaflet-draw": "1.0.4", "leaflet-draw": "1.0.4",
"lit": "2.7.4", "lit": "2.7.5",
"marked": "4.3.0", "marked": "4.3.0",
"memoize-one": "6.0.0", "memoize-one": "6.0.0",
"node-vibrant": "3.2.1-alpha.1", "node-vibrant": "3.2.1-alpha.1",
@@ -140,12 +140,12 @@
"vue": "2.7.14", "vue": "2.7.14",
"vue2-daterange-picker": "0.6.8", "vue2-daterange-picker": "0.6.8",
"weekstart": "2.0.0", "weekstart": "2.0.0",
"workbox-cacheable-response": "6.6.0", "workbox-cacheable-response": "7.0.0",
"workbox-core": "6.6.0", "workbox-core": "7.0.0",
"workbox-expiration": "6.6.0", "workbox-expiration": "7.0.0",
"workbox-precaching": "6.6.0", "workbox-precaching": "7.0.0",
"workbox-routing": "6.6.0", "workbox-routing": "7.0.0",
"workbox-strategies": "6.6.0", "workbox-strategies": "7.0.0",
"xss": "1.0.14" "xss": "1.0.14"
}, },
"devDependencies": { "devDependencies": {
@@ -156,13 +156,13 @@
"@babel/preset-typescript": "7.21.5", "@babel/preset-typescript": "7.21.5",
"@koa/cors": "4.0.0", "@koa/cors": "4.0.0",
"@octokit/auth-oauth-device": "4.0.4", "@octokit/auth-oauth-device": "4.0.4",
"@octokit/plugin-retry": "4.1.3", "@octokit/plugin-retry": "5.0.0",
"@octokit/rest": "19.0.11", "@octokit/rest": "19.0.11",
"@open-wc/dev-server-hmr": "0.1.4", "@open-wc/dev-server-hmr": "0.1.4",
"@rollup/plugin-babel": "6.0.3", "@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-commonjs": "25.0.0", "@rollup/plugin-commonjs": "25.0.0",
"@rollup/plugin-json": "6.0.0", "@rollup/plugin-json": "6.0.0",
"@rollup/plugin-node-resolve": "15.0.2", "@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-replace": "5.0.2", "@rollup/plugin-replace": "5.0.2",
"@types/babel__plugin-transform-runtime": "7.9.2", "@types/babel__plugin-transform-runtime": "7.9.2",
"@types/chromecast-caf-receiver": "6.0.9", "@types/chromecast-caf-receiver": "6.0.9",
@@ -180,15 +180,15 @@
"@types/sortablejs": "1.15.1", "@types/sortablejs": "1.15.1",
"@types/tar": "6.1.5", "@types/tar": "6.1.5",
"@types/webspeechapi": "0.0.29", "@types/webspeechapi": "0.0.29",
"@typescript-eslint/eslint-plugin": "5.59.7", "@typescript-eslint/eslint-plugin": "5.59.8",
"@typescript-eslint/parser": "5.59.7", "@typescript-eslint/parser": "5.59.8",
"@web/dev-server": "0.1.38", "@web/dev-server": "0.1.38",
"@web/dev-server-rollup": "0.4.1", "@web/dev-server-rollup": "0.4.1",
"babel-loader": "9.1.2", "babel-loader": "9.1.2",
"babel-plugin-template-html-minifier": "4.1.0", "babel-plugin-template-html-minifier": "4.1.0",
"chai": "4.3.7", "chai": "4.3.7",
"del": "7.0.0", "del": "7.0.0",
"eslint": "8.41.0", "eslint": "8.42.0",
"eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-base": "15.0.0",
"eslint-config-airbnb-typescript": "17.0.0", "eslint-config-airbnb-typescript": "17.0.0",
"eslint-config-prettier": "8.8.0", "eslint-config-prettier": "8.8.0",
@@ -243,7 +243,7 @@
"webpack-dev-server": "4.15.0", "webpack-dev-server": "4.15.0",
"webpack-manifest-plugin": "5.0.0", "webpack-manifest-plugin": "5.0.0",
"webpackbar": "5.0.2", "webpackbar": "5.0.2",
"workbox-build": "6.6.0" "workbox-build": "7.0.0"
}, },
"_comment": "Polymer 3.2 contained a bug, fixed in https://github.com/Polymer/polymer/pull/5569, add as patch", "_comment": "Polymer 3.2 contained a bug, fixed in https://github.com/Polymer/polymer/pull/5569, add as patch",
"resolutions": { "resolutions": {
@@ -255,5 +255,5 @@
"trailingComma": "es5", "trailingComma": "es5",
"arrowParens": "always" "arrowParens": "always"
}, },
"packageManager": "yarn@3.5.1" "packageManager": "yarn@3.6.0"
} }

View File

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

View File

@@ -17,7 +17,7 @@ export const protocolIntegrationPicked = async (
element: HTMLElement, element: HTMLElement,
hass: HomeAssistant, hass: HomeAssistant,
domain: string, domain: string,
options?: { brand?: string; domain?: string } options?: { brand?: string; domain?: string; config_entry?: string }
) => { ) => {
if (options?.domain) { if (options?.domain) {
const localize = await hass.loadBackendTranslation("title", options.domain); const localize = await hass.loadBackendTranslation("title", options.domain);
@@ -32,11 +32,16 @@ export const protocolIntegrationPicked = async (
} }
if (domain === "zwave_js") { if (domain === "zwave_js") {
const entries = await getConfigEntries(hass, { const entries = options?.config_entry
domain, ? undefined
}); : await getConfigEntries(hass, {
domain,
});
if (!isComponentLoaded(hass, "zwave_js") || !entries.length) { if (
!isComponentLoaded(hass, "zwave_js") ||
(!options?.config_entry && !entries?.length)
) {
// If the component isn't loaded, ask them to load the integration first // If the component isn't loaded, ask them to load the integration first
showConfirmationDialog(element, { showConfirmationDialog(element, {
title: hass.localize( title: hass.localize(
@@ -71,14 +76,19 @@ export const protocolIntegrationPicked = async (
} }
showZWaveJSAddNodeDialog(element, { showZWaveJSAddNodeDialog(element, {
entry_id: entries[0].entry_id, entry_id: options?.config_entry || entries![0].entry_id,
}); });
} else if (domain === "zha") { } else if (domain === "zha") {
const entries = await getConfigEntries(hass, { const entries = options?.config_entry
domain, ? undefined
}); : await getConfigEntries(hass, {
domain,
});
if (!isComponentLoaded(hass, "zha") || !entries.length) { if (
!isComponentLoaded(hass, "zha") ||
(!options?.config_entry && !entries?.length)
) {
// If the component isn't loaded, ask them to load the integration first // If the component isn't loaded, ask them to load the integration first
showConfirmationDialog(element, { showConfirmationDialog(element, {
title: hass.localize( title: hass.localize(
@@ -117,10 +127,15 @@ export const protocolIntegrationPicked = async (
navigate("/config/zha/add"); navigate("/config/zha/add");
} else if (domain === "matter") { } else if (domain === "matter") {
const entries = await getConfigEntries(hass, { const entries = options?.config_entry
domain, ? undefined
}); : await getConfigEntries(hass, {
if (!isComponentLoaded(hass, domain) || !entries.length) { domain,
});
if (
!isComponentLoaded(hass, domain) ||
(!options?.config_entry && !entries?.length)
) {
// If the component isn't loaded, ask them to load the integration first // If the component isn't loaded, ask them to load the integration first
showConfirmationDialog(element, { showConfirmationDialog(element, {
title: hass.localize( title: hass.localize(

View File

@@ -111,10 +111,10 @@ class HaDevicesPicker extends LitElement {
event.stopPropagation(); event.stopPropagation();
const curValue = (event.currentTarget as any).curValue; const curValue = (event.currentTarget as any).curValue;
const newValue = event.detail.value; const newValue = event.detail.value;
if (newValue === curValue || newValue !== "") { if (newValue === curValue) {
return; return;
} }
if (newValue === "") { if (newValue === undefined) {
this._updateDevices( this._updateDevices(
this._currentDevices.filter((dev) => dev !== curValue) this._currentDevices.filter((dev) => dev !== curValue)
); );

View File

@@ -38,6 +38,31 @@ export class StateBadge extends LitElement {
@state() private _iconStyle: { [name: string]: string | undefined } = {}; @state() private _iconStyle: { [name: string]: string | undefined } = {};
connectedCallback(): void {
super.connectedCallback();
if (
this.hasUpdated &&
this.overrideImage === undefined &&
(this.stateObj?.attributes.entity_picture ||
this.stateObj?.attributes.entity_picture_local)
) {
// Update image on connect, so we get new auth token
this.requestUpdate("stateObj");
}
}
disconnectedCallback() {
super.disconnectedCallback();
if (
this.overrideImage === undefined &&
(this.stateObj?.attributes.entity_picture ||
this.stateObj?.attributes.entity_picture_local)
) {
// Clear image on disconnect so we don't fetch with old auth when we reconnect
this.style.backgroundImage = "";
}
}
private get _stateColor() { private get _stateColor() {
const domain = this.stateObj const domain = this.stateObj
? computeStateDomain(this.stateObj) ? computeStateDomain(this.stateObj)

View File

@@ -0,0 +1,74 @@
import {
css,
CSSResultGroup,
html,
LitElement,
nothing,
PropertyValues,
} from "lit";
import { customElement, property } from "lit/decorators";
import type { HomeAssistant } from "../../types";
import "./ha-form";
import type {
HaFormDataContainer,
HaFormElement,
HaFormConditionalSchema,
HaFormSchema,
} from "./types";
@customElement("ha-form-conditional")
export class HaFormConditional extends LitElement implements HaFormElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public data!: HaFormDataContainer;
@property({ attribute: false }) public schema!: HaFormConditionalSchema;
@property({ type: Boolean }) public disabled = false;
@property() public computeLabel?: (
schema: HaFormSchema,
data?: HaFormDataContainer
) => string;
@property() public computeHelper?: (schema: HaFormSchema) => string;
protected updated(changedProps: PropertyValues): void {
if (changedProps.has("schema") || changedProps.has("data")) {
this.toggleAttribute("hidden", !this.schema.condition(this.data));
}
}
protected render() {
if (!this.schema.condition(this.data)) {
return nothing;
}
return html`
<ha-form
.hass=${this.hass}
.data=${this.data}
.schema=${this.schema.schema}
.disabled=${this.disabled}
.computeLabel=${this.computeLabel}
.computeHelper=${this.computeHelper}
></ha-form>
`;
}
static get styles(): CSSResultGroup {
return css`
:host([hidden]) {
display: none !important;
}
:host ha-form {
display: block;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-form-conditional": HaFormConditional;
}
}

View File

@@ -21,6 +21,7 @@ const LOAD_ELEMENTS = {
float: () => import("./ha-form-float"), float: () => import("./ha-form-float"),
grid: () => import("./ha-form-grid"), grid: () => import("./ha-form-grid"),
expandable: () => import("./ha-form-expandable"), expandable: () => import("./ha-form-expandable"),
conditional: () => import("./ha-form-conditional"),
integer: () => import("./ha-form-integer"), integer: () => import("./ha-form-integer"),
multi_select: () => import("./ha-form-multi_select"), multi_select: () => import("./ha-form-multi_select"),
positive_time_period_dict: () => positive_time_period_dict: () =>
@@ -189,12 +190,13 @@ export class HaForm extends LitElement implements HaFormElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
.root {
display: grid;
row-gap: 24px;
}
.root > * { .root > * {
display: block; display: block;
} }
.root > *:not([own-margin]):not(:last-child) {
margin-bottom: 24px;
}
ha-alert[own-margin] { ha-alert[own-margin] {
margin-bottom: 4px; margin-bottom: 4px;
} }

View File

@@ -13,7 +13,8 @@ export type HaFormSchema =
| HaFormTimeSchema | HaFormTimeSchema
| HaFormSelector | HaFormSelector
| HaFormGridSchema | HaFormGridSchema
| HaFormExpandableSchema; | HaFormExpandableSchema
| HaFormConditionalSchema;
export interface HaFormBaseSchema { export interface HaFormBaseSchema {
name: string; name: string;
@@ -47,6 +48,13 @@ export interface HaFormExpandableSchema extends HaFormBaseSchema {
schema: readonly HaFormSchema[]; schema: readonly HaFormSchema[];
} }
export interface HaFormConditionalSchema extends HaFormBaseSchema {
type: "conditional";
name: "";
condition: (data: HaFormDataContainer) => boolean;
schema: readonly HaFormSchema[];
}
export interface HaFormSelector extends HaFormBaseSchema { export interface HaFormSelector extends HaFormBaseSchema {
type?: never; type?: never;
selector: Selector; selector: Selector;
@@ -99,7 +107,10 @@ export interface HaFormTimeSchema extends HaFormBaseSchema {
export type SchemaUnion< export type SchemaUnion<
SchemaArray extends readonly HaFormSchema[], SchemaArray extends readonly HaFormSchema[],
Schema = SchemaArray[number] Schema = SchemaArray[number]
> = Schema extends HaFormGridSchema | HaFormExpandableSchema > = Schema extends
| HaFormGridSchema
| HaFormExpandableSchema
| HaFormConditionalSchema
? SchemaUnion<Schema["schema"]> ? SchemaUnion<Schema["schema"]>
: Schema; : Schema;

View File

@@ -176,7 +176,7 @@ class HaHsColorPicker extends LitElement {
super.updated(changedProps); super.updated(changedProps);
if ( if (
changedProps.has("colorBrightness") || changedProps.has("colorBrightness") ||
changedProps.has("vw") || changedProps.has("wv") ||
changedProps.has("ww") || changedProps.has("ww") ||
changedProps.has("cw") || changedProps.has("cw") ||
changedProps.has("minKelvin") || changedProps.has("minKelvin") ||

View File

@@ -11,6 +11,9 @@ class HaMarkdownElement extends ReactiveElement {
@property({ type: Boolean }) public breaks = false; @property({ type: Boolean }) public breaks = false;
@property({ type: Boolean, attribute: "lazy-images" }) public lazyImages =
false;
protected createRenderRoot() { protected createRenderRoot() {
return this; return this;
} }
@@ -58,6 +61,9 @@ class HaMarkdownElement extends ReactiveElement {
// Fire a resize event when images loaded to notify content resized // Fire a resize event when images loaded to notify content resized
} else if (node instanceof HTMLImageElement) { } else if (node instanceof HTMLImageElement) {
if (this.lazyImages) {
node.loading = "lazy";
}
node.addEventListener("load", this._resize); node.addEventListener("load", this._resize);
} }
} }

View File

@@ -15,6 +15,9 @@ export class HaMarkdown extends LitElement {
@property({ type: Boolean }) public breaks = false; @property({ type: Boolean }) public breaks = false;
@property({ type: Boolean, attribute: "lazy-images" }) public lazyImages =
false;
protected render() { protected render() {
if (!this.content) { if (!this.content) {
return nothing; return nothing;
@@ -24,6 +27,7 @@ export class HaMarkdown extends LitElement {
.content=${this.content} .content=${this.content}
.allowSvg=${this.allowSvg} .allowSvg=${this.allowSvg}
.breaks=${this.breaks} .breaks=${this.breaks}
.lazyImages=${this.lazyImages}
></ha-markdown-element>`; ></ha-markdown-element>`;
} }

View File

@@ -1,6 +1,10 @@
import "@material/mwc-list/mwc-list"; import "@material/mwc-list/mwc-list";
import { mdiDevices, mdiPaletteSwatch, mdiSofa } from "@mdi/js"; import {
import { HassEntity } from "home-assistant-js-websocket"; mdiAlertCircleOutline,
mdiDevices,
mdiPaletteSwatch,
mdiSofa,
} from "@mdi/js";
import { import {
css, css,
CSSResultGroup, CSSResultGroup,
@@ -11,10 +15,11 @@ import {
} from "lit"; } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map"; import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { caseInsensitiveStringCompare } from "../common/string/compare";
import { Blueprints, fetchBlueprints } from "../data/blueprint"; import { Blueprints, fetchBlueprints } from "../data/blueprint";
import { ConfigEntry, getConfigEntries } from "../data/config_entries"; import { ConfigEntry, getConfigEntries } from "../data/config_entries";
import { SceneEntity } from "../data/scene";
import { findRelated, ItemType, RelatedResult } from "../data/search"; import { findRelated, ItemType, RelatedResult } from "../data/search";
import { haStyle } from "../resources/styles"; import { haStyle } from "../resources/styles";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
@@ -72,13 +77,55 @@ export class HaRelatedItems extends LitElement {
} }
} }
private _relatedEntities = memoizeOne((entityIds: string[]) =>
this._toEntities(entityIds)
);
private _relatedAutomations = memoizeOne((automationEntityIds: string[]) =>
this._toEntities(automationEntityIds)
);
private _relatedScripts = memoizeOne((scriptEntityIds: string[]) =>
this._toEntities(scriptEntityIds)
);
private _relatedGroups = memoizeOne((groupEntityIds: string[]) =>
this._toEntities(groupEntityIds)
);
private _relatedScenes = memoizeOne((sceneEntityIds: string[]) =>
this._toEntities(sceneEntityIds)
);
private _toEntities = (entityIds: string[]) =>
entityIds
.map((entityId) => this.hass.states[entityId])
.filter((entity) => entity)
.sort((a, b) =>
caseInsensitiveStringCompare(
a.attributes.friendly_name ?? a.entity_id,
b.attributes.friendly_name ?? b.entity_id,
this.hass.language
)
);
protected render() { protected render() {
if (!this._related) { if (!this._related) {
return nothing; return nothing;
} }
if (Object.keys(this._related).length === 0) { if (Object.keys(this._related).length === 0) {
return html` return html`
${this.hass.localize("ui.components.related-items.no_related_found")} <mwc-list>
<ha-list-item hasMeta graphic="icon" noninteractive>
<ha-svg-icon
.path=${mdiAlertCircleOutline}
slot="graphic"
></ha-svg-icon>
${this.hass.localize(
"ui.components.related-items.no_related_found"
)}
</ha-list-item>
</mwc-list>
`; `;
} }
return html` return html`
@@ -92,7 +139,7 @@ export class HaRelatedItems extends LitElement {
(configEntry) => configEntry.entry_id === relatedConfigEntryId (configEntry) => configEntry.entry_id === relatedConfigEntryId
); );
if (!entry) { if (!entry) {
return ""; return nothing;
} }
return html` return html`
<a <a
@@ -117,7 +164,7 @@ export class HaRelatedItems extends LitElement {
`; `;
})}</mwc-list })}</mwc-list
>` >`
: ""} : nothing}
${this._related.device ${this._related.device
? html`<h3> ? html`<h3>
${this.hass.localize("ui.components.related-items.device")} ${this.hass.localize("ui.components.related-items.device")}
@@ -125,7 +172,7 @@ export class HaRelatedItems extends LitElement {
${this._related.device.map((relatedDeviceId) => { ${this._related.device.map((relatedDeviceId) => {
const device = this.hass.devices[relatedDeviceId]; const device = this.hass.devices[relatedDeviceId];
if (!device) { if (!device) {
return ""; return nothing;
} }
return html` return html`
<a <a
@@ -144,7 +191,7 @@ export class HaRelatedItems extends LitElement {
`; `;
})} </mwc-list> })} </mwc-list>
` `
: ""} : nothing}
${this._related.area ${this._related.area
? html`<h3> ? html`<h3>
${this.hass.localize("ui.components.related-items.area")} ${this.hass.localize("ui.components.related-items.area")}
@@ -153,7 +200,7 @@ export class HaRelatedItems extends LitElement {
>${this._related.area.map((relatedAreaId) => { >${this._related.area.map((relatedAreaId) => {
const area = this.hass.areas[relatedAreaId]; const area = this.hass.areas[relatedAreaId];
if (!area) { if (!area) {
return ""; return nothing;
} }
return html` return html`
<a <a
@@ -183,21 +230,16 @@ export class HaRelatedItems extends LitElement {
`; `;
})}</mwc-list })}</mwc-list
>` >`
: ""} : nothing}
${this._related.entity ${this._related.entity
? html` ? html`
<h3>${this.hass.localize("ui.components.related-items.entity")}</h3> <h3>${this.hass.localize("ui.components.related-items.entity")}</h3>
<mwc-list> <mwc-list>
${this._related.entity.map((entityId) => { ${this._relatedEntities(this._related.entity).map(
const entity: HassEntity | undefined = (entity) => html`
this.hass.states[entityId];
if (!entity) {
return "";
}
return html`
<ha-list-item <ha-list-item
@click=${this._openMoreInfo} @click=${this._openMoreInfo}
.entityId=${entityId} .entityId=${entity.entity_id}
hasMeta hasMeta
graphic="icon" graphic="icon"
> >
@@ -208,24 +250,20 @@ export class HaRelatedItems extends LitElement {
${entity.attributes.friendly_name || entity.entity_id} ${entity.attributes.friendly_name || entity.entity_id}
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
`; `
})} )}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
${this._related.group ${this._related.group
? html` ? html`
<h3>${this.hass.localize("ui.components.related-items.group")}</h3> <h3>${this.hass.localize("ui.components.related-items.group")}</h3>
<mwc-list> <mwc-list>
${this._related.group.map((groupId) => { ${this._relatedGroups(this._related.group).map(
const group: HassEntity | undefined = this.hass.states[groupId]; (group) => html`
if (!group) {
return "";
}
return html`
<ha-list-item <ha-list-item
@click=${this._openMoreInfo} @click=${this._openMoreInfo}
.entityId=${groupId} .entityId=${group.entity_id}
hasMeta hasMeta
graphic="icon" graphic="icon"
> >
@@ -236,25 +274,20 @@ export class HaRelatedItems extends LitElement {
${group.attributes.friendly_name || group.entity_id} ${group.attributes.friendly_name || group.entity_id}
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
`; `
})} )}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
${this._related.scene ${this._related.scene
? html` ? html`
<h3>${this.hass.localize("ui.components.related-items.scene")}</h3> <h3>${this.hass.localize("ui.components.related-items.scene")}</h3>
<mwc-list> <mwc-list>
${this._related.scene.map((sceneId) => { ${this._relatedScenes(this._related.scene).map(
const scene: SceneEntity | undefined = (scene) => html`
this.hass.states[sceneId];
if (!scene) {
return "";
}
return html`
<ha-list-item <ha-list-item
@click=${this._openMoreInfo} @click=${this._openMoreInfo}
.entityId=${sceneId} .entityId=${scene.entity_id}
hasMeta hasMeta
graphic="icon" graphic="icon"
> >
@@ -265,11 +298,11 @@ export class HaRelatedItems extends LitElement {
${scene.attributes.friendly_name || scene.entity_id} ${scene.attributes.friendly_name || scene.entity_id}
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
`; `
})} )}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
${this._related.automation_blueprint ${this._related.automation_blueprint
? html` ? html`
<h3> <h3>
@@ -298,23 +331,18 @@ export class HaRelatedItems extends LitElement {
})} })}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
${this._related.automation ${this._related.automation
? html` ? html`
<h3> <h3>
${this.hass.localize("ui.components.related-items.automation")} ${this.hass.localize("ui.components.related-items.automation")}
</h3> </h3>
<mwc-list> <mwc-list>
${this._related.automation.map((automationId) => { ${this._relatedAutomations(this._related.automation).map(
const automation: HassEntity | undefined = (automation) => html`
this.hass.states[automationId];
if (!automation) {
return "";
}
return html`
<ha-list-item <ha-list-item
@click=${this._openMoreInfo} @click=${this._openMoreInfo}
.entityId=${automationId} .entityId=${automation.entity_id}
hasMeta hasMeta
graphic="icon" graphic="icon"
> >
@@ -326,11 +354,11 @@ export class HaRelatedItems extends LitElement {
automation.entity_id} automation.entity_id}
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
`; `
})} )}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
${this._related.script_blueprint ${this._related.script_blueprint
? html` ? html`
<h3> <h3>
@@ -359,21 +387,16 @@ export class HaRelatedItems extends LitElement {
})} })}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
${this._related.script ${this._related.script
? html` ? html`
<h3>${this.hass.localize("ui.components.related-items.script")}</h3> <h3>${this.hass.localize("ui.components.related-items.script")}</h3>
<mwc-list> <mwc-list>
${this._related.script.map((scriptId) => { ${this._relatedScripts(this._related.script).map(
const script: HassEntity | undefined = (script) => html`
this.hass.states[scriptId];
if (!script) {
return "";
}
return html`
<ha-list-item <ha-list-item
@click=${this._openMoreInfo} @click=${this._openMoreInfo}
.entityId=${scriptId} .entityId=${script.entity_id}
hasMeta hasMeta
graphic="icon" graphic="icon"
> >
@@ -384,11 +407,11 @@ export class HaRelatedItems extends LitElement {
${script.attributes.friendly_name || script.entity_id} ${script.attributes.friendly_name || script.entity_id}
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
`; `
})} )}
</mwc-list> </mwc-list>
` `
: ""} : nothing}
`; `;
} }

View File

@@ -77,7 +77,9 @@ export class HaDeviceSelector extends LitElement {
.label=${this.label} .label=${this.label}
.helper=${this.helper} .helper=${this.helper}
.deviceFilter=${this._filterDevices} .deviceFilter=${this._filterDevices}
.entityFilter=${this._filterEntities} .entityFilter=${this.selector.device?.entity
? this._filterEntities
: undefined}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
allow-custom-entity allow-custom-entity
@@ -92,7 +94,9 @@ export class HaDeviceSelector extends LitElement {
.value=${this.value} .value=${this.value}
.helper=${this.helper} .helper=${this.helper}
.deviceFilter=${this._filterDevices} .deviceFilter=${this._filterDevices}
.entityFilter=${this._filterEntities} .entityFilter=${this.selector.device?.entity
? this._filterEntities
: undefined}
.disabled=${this.disabled} .disabled=${this.disabled}
.required=${this.required} .required=${this.required}
></ha-devices-picker> ></ha-devices-picker>
@@ -115,14 +119,10 @@ export class HaDeviceSelector extends LitElement {
); );
}; };
private _filterEntities = (entity: HassEntity): boolean => { private _filterEntities = (entity: HassEntity): boolean =>
if (!this.selector.device?.entity) { ensureArray(this.selector.device!.entity).some((filter) =>
return true;
}
return ensureArray(this.selector.device.entity).some((filter) =>
filterSelectorEntities(filter, entity, this._entitySources) filterSelectorEntities(filter, entity, this._entitySources)
); );
};
} }
declare global { declare global {

View File

@@ -471,6 +471,11 @@ export class HaMap extends ReactiveElement {
background: #090909; background: #090909;
--map-filter: invert(0.9) hue-rotate(170deg) grayscale(0.7); --map-filter: invert(0.9) hue-rotate(170deg) grayscale(0.7);
} }
#map:active {
cursor: grabbing;
cursor: -moz-grabbing;
cursor: -webkit-grabbing;
}
.light { .light {
color: #000000; color: #000000;
} }

View File

@@ -58,6 +58,10 @@ export const lightSupportsBrightness = (entity: LightEntity) =>
modesSupportingBrightness.includes(mode) modesSupportingBrightness.includes(mode)
) || false; ) || false;
export const lightSupportsFavoriteColors = (entity: LightEntity) =>
lightSupportsColor(entity) ||
lightSupportsColorMode(entity, LightColorMode.COLOR_TEMP);
export const getLightCurrentModeRgbColor = ( export const getLightCurrentModeRgbColor = (
entity: LightEntity entity: LightEntity
): number[] | undefined => ): number[] | undefined =>

View File

@@ -169,9 +169,16 @@ export interface ZHANetworkBackup {
node_info: ZHANetworkBackupNodeInfo; node_info: ZHANetworkBackupNodeInfo;
} }
export interface ZHADeviceSettings {
path: string;
baudrate?: number;
flow_control?: string;
}
export interface ZHANetworkSettings { export interface ZHANetworkSettings {
settings: ZHANetworkBackup; settings: ZHANetworkBackup;
radio_type: "ezsp" | "znp" | "deconz" | "zigate" | "xbee"; radio_type: "ezsp" | "znp" | "deconz" | "zigate" | "xbee";
device: ZHADeviceSettings;
} }
export interface ZHANetworkBackupAndMetadata { export interface ZHANetworkBackupAndMetadata {

View File

@@ -603,6 +603,7 @@ class LightColorPicker extends LitElement {
input[type="color"] { input[type="color"] {
appearance: none; appearance: none;
-webkit-appearance: none; -webkit-appearance: none;
-moz-appearance: none;
border: none; border: none;
outline: none; outline: none;
display: block; display: block;
@@ -628,6 +629,10 @@ class LightColorPicker extends LitElement {
background: none; background: none;
} }
input[type="color"]::-moz-color-swatch {
display: none;
}
input[type="color"]::-webkit-color-swatch { input[type="color"]::-webkit-color-swatch {
border: none; border: none;
} }

View File

@@ -34,6 +34,8 @@ export const DOMAINS_WITH_MORE_INFO = [
"configurator", "configurator",
"counter", "counter",
"cover", "cover",
"date",
"datetime",
"fan", "fan",
"group", "group",
"humidifier", "humidifier",
@@ -49,6 +51,7 @@ export const DOMAINS_WITH_MORE_INFO = [
"siren", "siren",
"sun", "sun",
"switch", "switch",
"time",
"timer", "timer",
"update", "update",
"vacuum", "vacuum",

View File

@@ -195,7 +195,7 @@ class MoreInfoCover extends LitElement {
<ha-icon-button <ha-icon-button
.label=${this.hass.localize( .label=${this.hass.localize(
`ui.dialogs.more_info_control.cover.switch_mode.${ `ui.dialogs.more_info_control.cover.switch_mode.${
this._mode || "position" this._mode === "position" ? "button" : "position"
}` }`
)} )}
.path=${this._mode === "position" .path=${this._mode === "position"

View File

@@ -0,0 +1,51 @@
import { HassEntity } from "home-assistant-js-websocket";
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 { setDateValue } from "../../../data/date";
import { isUnavailableState } from "../../../data/entity";
import type { HomeAssistant } from "../../../types";
@customElement("more-info-date")
class MoreInfoDate extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
protected render() {
if (!this.stateObj || isUnavailableState(this.stateObj.state)) {
return nothing;
}
return html`
<ha-date-input
.locale=${this.hass.locale}
.value=${this.stateObj.state}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._dateChanged}
>
</ha-date-input>
`;
}
private _dateChanged(ev: CustomEvent<{ value: string }>): void {
setDateValue(this.hass!, this.stateObj!.entity_id, ev.detail.value);
}
static get styles(): CSSResultGroup {
return css`
:host {
display: flex;
align-items: center;
justify-content: flex-end;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-date": MoreInfoDate;
}
}

View File

@@ -0,0 +1,80 @@
import { format } from "date-fns";
import { HassEntity } from "home-assistant-js-websocket";
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 { setDateTimeValue } from "../../../data/datetime";
import { isUnavailableState } from "../../../data/entity";
import type { HomeAssistant } from "../../../types";
@customElement("more-info-datetime")
class MoreInfoDatetime extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
protected render() {
if (!this.stateObj || isUnavailableState(this.stateObj.state)) {
return nothing;
}
const dateObj = new Date(this.stateObj.state);
const time = format(dateObj, "HH:mm:ss");
const date = format(dateObj, "yyyy-MM-dd");
return html`<ha-date-input
.locale=${this.hass.locale}
.value=${date}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._dateChanged}
>
</ha-date-input>
<ha-time-input
.value=${time}
.locale=${this.hass.locale}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._timeChanged}
@click=${this._stopEventPropagation}
></ha-time-input>`;
}
private _stopEventPropagation(ev: Event): void {
ev.stopPropagation();
}
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]);
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]);
setDateTimeValue(this.hass!, this.stateObj!.entity_id, dateObj);
}
static get styles(): CSSResultGroup {
return css`
:host {
display: flex;
align-items: center;
justify-content: flex-end;
}
ha-date-input + ha-time-input {
margin-left: 4px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-datetime": MoreInfoDatetime;
}
}

View File

@@ -22,37 +22,32 @@ class MoreInfoInputDatetime extends LitElement {
} }
return html` return html`
${ ${this.stateObj.attributes.has_date
this.stateObj.attributes.has_date ? html`
? html` <ha-date-input
<ha-date-input .locale=${this.hass.locale}
.locale=${this.hass.locale} .value=${stateToIsoDateString(this.stateObj)}
.value=${stateToIsoDateString(this.stateObj)} .disabled=${isUnavailableState(this.stateObj.state)}
.disabled=${isUnavailableState(this.stateObj.state)} @value-changed=${this._dateChanged}
@value-changed=${this._dateChanged} >
> </ha-date-input>
</ha-date-input> `
` : ``}
: `` ${this.stateObj.attributes.has_time
} ? html`
${ <ha-time-input
this.stateObj.attributes.has_time .value=${this.stateObj.state === UNKNOWN
? html` ? ""
<ha-time-input : this.stateObj.attributes.has_date
.value=${this.stateObj.state === UNKNOWN ? this.stateObj.state.split(" ")[1]
? "" : this.stateObj.state}
: this.stateObj.attributes.has_date .locale=${this.hass.locale}
? this.stateObj.state.split(" ")[1] .disabled=${isUnavailableState(this.stateObj.state)}
: this.stateObj.state} @value-changed=${this._timeChanged}
.locale=${this.hass.locale} @click=${this._stopEventPropagation}
.disabled=${isUnavailableState(this.stateObj.state)} ></ha-time-input>
@value-changed=${this._timeChanged} `
@click=${this._stopEventPropagation} : ``}
></ha-time-input>
`
: ``
}
</hui-generic-entity-row>
`; `;
} }

View File

@@ -37,6 +37,7 @@ import {
lightSupportsBrightness, lightSupportsBrightness,
lightSupportsColor, lightSupportsColor,
lightSupportsColorMode, lightSupportsColorMode,
lightSupportsFavoriteColors,
} from "../../../data/light"; } from "../../../data/light";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { moreInfoControlStyle } from "../components/ha-more-info-control-style"; import { moreInfoControlStyle } from "../components/ha-more-info-control-style";
@@ -206,7 +207,9 @@ class MoreInfoLight extends LitElement {
` `
: nothing} : nothing}
</div> </div>
${this.entry && (this.editMode || hasFavoriteColors) ${this.entry &&
lightSupportsFavoriteColors(this.stateObj) &&
(this.editMode || hasFavoriteColors)
? html` ? html`
<ha-more-info-light-favorite-colors <ha-more-info-light-favorite-colors
.hass=${this.hass} .hass=${this.hass}

View File

@@ -0,0 +1,55 @@
import { HassEntity } from "home-assistant-js-websocket";
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 { setTimeValue } from "../../../data/time";
import type { HomeAssistant } from "../../../types";
@customElement("more-info-time")
class MoreInfoTime extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
protected render() {
if (!this.stateObj || isUnavailableState(this.stateObj.state)) {
return nothing;
}
return html`
<ha-time-input
.value=${this.stateObj.state}
.locale=${this.hass.locale}
.disabled=${isUnavailableState(this.stateObj.state)}
@value-changed=${this._timeChanged}
@click=${this._stopEventPropagation}
></ha-time-input>
`;
}
private _stopEventPropagation(ev: Event): void {
ev.stopPropagation();
}
private _timeChanged(ev: CustomEvent<{ value: string }>): void {
setTimeValue(this.hass!, this.stateObj!.entity_id, ev.detail.value);
}
static get styles(): CSSResultGroup {
return css`
:host {
display: flex;
align-items: center;
justify-content: flex-end;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"more-info-time": MoreInfoTime;
}
}

View File

@@ -32,6 +32,7 @@ import {
ExtEntityRegistryEntry, ExtEntityRegistryEntry,
getExtendedEntityRegistryEntry, getExtendedEntityRegistryEntry,
} from "../../data/entity_registry"; } from "../../data/entity_registry";
import { lightSupportsFavoriteColors } from "../../data/light";
import { SearchableDomains } from "../../data/search"; import { SearchableDomains } from "../../data/search";
import { haStyleDialog } from "../../resources/styles"; import { haStyleDialog } from "../../resources/styles";
import "../../state-summary/state-card-content"; import "../../state-summary/state-card-content";
@@ -359,7 +360,10 @@ export class MoreInfoDialog extends LitElement {
</ha-list-item> </ha-list-item>
` `
: nothing} : nothing}
${this._entry && domain === "light" ${this._entry &&
stateObj &&
domain === "light" &&
lightSupportsFavoriteColors(stateObj)
? html` ? html`
<ha-list-item <ha-list-item
graphic="icon" graphic="icon"

View File

@@ -192,7 +192,8 @@ export class MoreInfoHistory extends LitElement {
} }
} }
} }
if (!isComponentLoaded(this.hass, "history") || this._subscribed) {
if (!isComponentLoaded(this.hass, "history")) {
return; return;
} }
if (this._subscribed) { if (this._subscribed) {

View File

@@ -13,6 +13,8 @@ const LAZY_LOADED_MORE_INFO_CONTROL = {
configurator: () => import("./controls/more-info-configurator"), configurator: () => import("./controls/more-info-configurator"),
counter: () => import("./controls/more-info-counter"), counter: () => import("./controls/more-info-counter"),
cover: () => import("./controls/more-info-cover"), cover: () => import("./controls/more-info-cover"),
date: () => import("./controls/more-info-date"),
datetime: () => import("./controls/more-info-datetime"),
fan: () => import("./controls/more-info-fan"), fan: () => import("./controls/more-info-fan"),
group: () => import("./controls/more-info-group"), group: () => import("./controls/more-info-group"),
humidifier: () => import("./controls/more-info-humidifier"), humidifier: () => import("./controls/more-info-humidifier"),
@@ -27,6 +29,7 @@ const LAZY_LOADED_MORE_INFO_CONTROL = {
siren: () => import("./controls/more-info-siren"), siren: () => import("./controls/more-info-siren"),
sun: () => import("./controls/more-info-sun"), sun: () => import("./controls/more-info-sun"),
switch: () => import("./controls/more-info-switch"), switch: () => import("./controls/more-info-switch"),
time: () => import("./controls/more-info-time"),
timer: () => import("./controls/more-info-timer"), timer: () => import("./controls/more-info-timer"),
update: () => import("./controls/more-info-update"), update: () => import("./controls/more-info-update"),
vacuum: () => import("./controls/more-info-vacuum"), vacuum: () => import("./controls/more-info-vacuum"),

View File

@@ -1,7 +1,7 @@
import "@material/mwc-button"; import "@material/mwc-button";
import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { LitElement, html, css, nothing } from "lit"; import { LitElement, html, css, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event"; import { fireEvent } from "../../common/dom/fire_event";
import { computeDomain } from "../../common/entity/compute_domain"; import { computeDomain } from "../../common/entity/compute_domain";
import "../../components/ha-icon-button-prev"; import "../../components/ha-icon-button-prev";
@@ -13,6 +13,7 @@ import { HomeAssistant } from "../../types";
import "./notification-item"; import "./notification-item";
import "../../components/ha-header-bar"; import "../../components/ha-header-bar";
import "../../components/ha-drawer"; import "../../components/ha-drawer";
import type { HaDrawer } from "../../components/ha-drawer";
@customElement("notification-drawer") @customElement("notification-drawer")
export class HuiNotificationDrawer extends LitElement { export class HuiNotificationDrawer extends LitElement {
@@ -22,6 +23,8 @@ export class HuiNotificationDrawer extends LitElement {
@state() private _open = false; @state() private _open = false;
@query("ha-drawer") private _drawer?: HaDrawer;
private _unsubNotifications?: UnsubscribeFunc; private _unsubNotifications?: UnsubscribeFunc;
connectedCallback() { connectedCallback() {
@@ -53,12 +56,14 @@ export class HuiNotificationDrawer extends LitElement {
} }
closeDialog = () => { closeDialog = () => {
if (this._drawer) {
this._drawer.open = false;
}
if (this._unsubNotifications) { if (this._unsubNotifications) {
this._unsubNotifications(); this._unsubNotifications();
this._unsubNotifications = undefined; this._unsubNotifications = undefined;
} }
this._notifications = []; this._notifications = [];
this._open = false;
fireEvent(this, "dialog-closed", { dialog: this.localName }); fireEvent(this, "dialog-closed", { dialog: this.localName });
}; };
@@ -87,11 +92,7 @@ export class HuiNotificationDrawer extends LitElement {
}); });
return html` return html`
<ha-drawer <ha-drawer type="modal" open @MDCDrawer:closed=${this._dialogClosed}>
type="modal"
.open=${this._open}
@MDCDrawer:closed=${this._closeDrawer}
>
<ha-header-bar> <ha-header-bar>
<div slot="title"> <div slot="title">
${this.hass.localize("ui.notification_drawer.title")} ${this.hass.localize("ui.notification_drawer.title")}
@@ -99,7 +100,7 @@ export class HuiNotificationDrawer extends LitElement {
<ha-icon-button-prev <ha-icon-button-prev
slot="actionItems" slot="actionItems"
.hass=${this.hass} .hass=${this.hass}
@click=${this._closeDrawer} @click=${this.closeDialog}
.label=${this.hass.localize("ui.notification_drawer.close")} .label=${this.hass.localize("ui.notification_drawer.close")}
> >
</ha-icon-button-prev> </ha-icon-button-prev>
@@ -132,9 +133,9 @@ export class HuiNotificationDrawer extends LitElement {
`; `;
} }
private _closeDrawer(ev) { private _dialogClosed(ev: Event) {
ev.stopPropagation(); ev.stopPropagation();
this.closeDialog(); this._open = false;
} }
private _dismissAll() { private _dismissAll() {

View File

@@ -128,9 +128,9 @@ class OnboardingCoreConfig extends LitElement {
</div> </div>
<div class="row"> <div class="row">
<ha-country-picker <ha-country-picker
class="flex" class="flex"
.language=${this.hass.locale.language} .language=${this.hass.locale.language}
.label=${ .label=${
this.hass.localize( this.hass.localize(
"ui.panel.config.core.section.core.core_config.country" "ui.panel.config.core.section.core.core_config.country"
@@ -335,12 +335,12 @@ class OnboardingCoreConfig extends LitElement {
] ]
); );
private _handleValueChanged(ev) { private _handleValueChanged(ev: ValueChangedEvent<string>) {
const target = ev.currentTarget; const target = ev.currentTarget as HTMLElement;
this[`_${target.getAttribute("name")}`] = ev.detail.value; this[`_${target.getAttribute("name")}`] = ev.detail.value;
} }
private _handleChange(ev: ValueChangedEvent<string>) { private _handleChange(ev: Event) {
const target = ev.currentTarget as HaTextField; const target = ev.currentTarget as HaTextField;
this[`_${target.name}`] = target.value; this[`_${target.name}`] = target.value;
} }

View File

@@ -524,17 +524,19 @@ export default class HaAutomationActionRow extends LitElement {
defaultValue: this.action.alias, defaultValue: this.action.alias,
confirmText: this.hass.localize("ui.common.submit"), confirmText: this.hass.localize("ui.common.submit"),
}); });
const value = { ...this.action }; if (alias !== null) {
if (!alias) { const value = { ...this.action };
delete value.alias; if (alias === "") {
} else { delete value.alias;
value.alias = alias; } else {
} value.alias = alias;
fireEvent(this, "value-changed", { }
value, fireEvent(this, "value-changed", {
}); value,
if (this._yamlMode) { });
this._yamlEditor?.setValue(value); if (this._yamlMode) {
this._yamlEditor?.setValue(value);
}
} }
} }

View File

@@ -471,16 +471,17 @@ export default class HaAutomationConditionRow extends LitElement {
defaultValue: this.condition.alias, defaultValue: this.condition.alias,
confirmText: this.hass.localize("ui.common.submit"), confirmText: this.hass.localize("ui.common.submit"),
}); });
if (alias !== null) {
const value = { ...this.condition }; const value = { ...this.condition };
if (!alias) { if (alias === "") {
delete value.alias; delete value.alias;
} else { } else {
value.alias = alias; value.alias = alias;
}
fireEvent(this, "value-changed", {
value,
});
} }
fireEvent(this, "value-changed", {
value,
});
} }
public expand() { public expand() {

View File

@@ -581,17 +581,19 @@ export default class HaAutomationTriggerRow extends LitElement {
confirmText: this.hass.localize("ui.common.submit"), confirmText: this.hass.localize("ui.common.submit"),
}); });
const value = { ...this.trigger }; if (alias !== null) {
if (!alias) { const value = { ...this.trigger };
delete value.alias; if (alias === "") {
} else { delete value.alias;
value.alias = alias; } else {
} value.alias = alias;
fireEvent(this, "value-changed", { }
value, fireEvent(this, "value-changed", {
}); value,
if (this._yamlMode) { });
this._yamlEditor?.setValue(value); if (this._yamlMode) {
this._yamlEditor?.setValue(value);
}
} }
} }

View File

@@ -27,7 +27,8 @@ import { ConfigUpdateValues, saveCoreConfig } from "../../../data/core";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/hass-subpage"; import "../../../layouts/hass-subpage";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant, ValueChangedEvent } from "../../../types";
import type { HaTextField } from "../../../components/ha-textfield";
@customElement("ha-config-section-general") @customElement("ha-config-section-general")
class HaConfigSectionGeneral extends LitElement { class HaConfigSectionGeneral extends LitElement {
@@ -301,13 +302,13 @@ class HaConfigSectionGeneral extends LitElement {
this._updateUnits = true; this._updateUnits = true;
} }
private _handleValueChanged(ev) { private _handleValueChanged(ev: ValueChangedEvent<string>) {
const target = ev.currentTarget; const target = ev.currentTarget as HTMLElement;
this[`_${target.name}`] = ev.detail.value; this[`_${target.getAttribute("name")}`] = ev.detail.value;
} }
private _handleChange(ev) { private _handleChange(ev: Event) {
const target = ev.currentTarget; const target = ev.currentTarget as HaTextField;
this[`_${target.name}`] = target.value; this[`_${target.name}`] = target.value;
} }

View File

@@ -1,11 +1,15 @@
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item"; import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import { mdiCancel, mdiFilterVariant, mdiPlus } from "@mdi/js"; import { mdiCancel, mdiFilterVariant, mdiPlus } from "@mdi/js";
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { HASSDomEvent } from "../../../common/dom/fire_event"; import { HASSDomEvent } from "../../../common/dom/fire_event";
import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain";
import {
protocolIntegrationPicked,
PROTOCOL_INTEGRATIONS,
} from "../../../common/integrations/protocolIntegrationPicked";
import { navigate } from "../../../common/navigate"; import { navigate } from "../../../common/navigate";
import { blankBeforePercent } from "../../../common/translations/blank_before_percent"; import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
import { LocalizeFunc } from "../../../common/translations/localize"; import { LocalizeFunc } from "../../../common/translations/localize";
@@ -39,8 +43,6 @@ import { HomeAssistant, Route } from "../../../types";
import { brandsUrl } from "../../../util/brands-url"; import { brandsUrl } from "../../../util/brands-url";
import { configSections } from "../ha-panel-config"; import { configSections } from "../ha-panel-config";
import "../integrations/ha-integration-overflow-menu"; import "../integrations/ha-integration-overflow-menu";
import { showMatterAddDeviceDialog } from "../integrations/integration-panels/matter/show-dialog-add-matter-device";
import { showZWaveJSAddNodeDialog } from "../integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node";
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog"; import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
interface DeviceRowData extends DeviceRegistryEntry { interface DeviceRowData extends DeviceRegistryEntry {
@@ -186,6 +188,8 @@ export class HaConfigDeviceDashboard extends LitElement {
let filterConfigEntry: ConfigEntry | undefined; let filterConfigEntry: ConfigEntry | undefined;
const filteredDomains = new Set<string>();
filters.forEach((value, key) => { filters.forEach((value, key) => {
if (key === "config_entry") { if (key === "config_entry") {
outputDevices = outputDevices.filter((device) => outputDevices = outputDevices.filter((device) =>
@@ -193,6 +197,9 @@ export class HaConfigDeviceDashboard extends LitElement {
); );
startLength = outputDevices.length; startLength = outputDevices.length;
filterConfigEntry = entries.find((entry) => entry.entry_id === value); filterConfigEntry = entries.find((entry) => entry.entry_id === value);
if (filterConfigEntry) {
filteredDomains.add(filterConfigEntry.domain);
}
} }
if (key === "domain") { if (key === "domain") {
const entryIds = entries const entryIds = entries
@@ -202,6 +209,7 @@ export class HaConfigDeviceDashboard extends LitElement {
device.config_entries.some((entryId) => entryIds.includes(entryId)) device.config_entries.some((entryId) => entryIds.includes(entryId))
); );
startLength = outputDevices.length; startLength = outputDevices.length;
filteredDomains.add(value);
} }
}); });
@@ -216,8 +224,12 @@ export class HaConfigDeviceDashboard extends LitElement {
this.hass, this.hass,
deviceEntityLookup[device.id] deviceEntityLookup[device.id]
), ),
model: device.model || "<unknown>", model:
manufacturer: device.manufacturer || "<unknown>", device.model ||
`<${localize("ui.panel.config.devices.data_table.unknown")}>`,
manufacturer:
device.manufacturer ||
`<${localize("ui.panel.config.devices.data_table.unknown")}>`,
area: area:
device.area_id && areaLookup[device.area_id] device.area_id && areaLookup[device.area_id]
? areaLookup[device.area_id].name ? areaLookup[device.area_id].name
@@ -251,6 +263,7 @@ export class HaConfigDeviceDashboard extends LitElement {
return { return {
devicesOutput: outputDevices, devicesOutput: outputDevices,
filteredConfigEntry: filterConfigEntry, filteredConfigEntry: filterConfigEntry,
filteredDomains,
}; };
} }
); );
@@ -546,25 +559,25 @@ export class HaConfigDeviceDashboard extends LitElement {
} }
private _addDevice() { private _addDevice() {
const { filteredConfigEntry } = this._devicesAndFilterDomains( const { filteredConfigEntry, filteredDomains } =
this.devices, this._devicesAndFilterDomains(
this.entries, this.devices,
this.entities, this.entries,
this.areas, this.entities,
this._searchParms, this.areas,
this._showDisabled, this._searchParms,
this.hass.localize this._showDisabled,
); this.hass.localize
if (filteredConfigEntry?.domain === "zha") { );
navigate(`/config/zha/add`); if (
return; filteredDomains.size === 1 &&
} (PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
if (filteredConfigEntry?.domain === "zwave_js") { [...filteredDomains][0]
this._showZJSAddDeviceDialog(filteredConfigEntry); )
return; ) {
} protocolIntegrationPicked(this, this.hass, [...filteredDomains][0], {
if (filteredConfigEntry?.domain === "matter") { config_entry: filteredConfigEntry?.entry_id,
showMatterAddDeviceDialog(this); });
return; return;
} }
showAddIntegrationDialog(this, { showAddIntegrationDialog(this, {
@@ -572,12 +585,6 @@ export class HaConfigDeviceDashboard extends LitElement {
}); });
} }
private _showZJSAddDeviceDialog(filteredConfigEntry: ConfigEntry) {
showZWaveJSAddNodeDialog(this, {
entry_id: filteredConfigEntry!.entry_id,
});
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
css` css`

View File

@@ -67,6 +67,11 @@ import { haStyle } from "../../../resources/styles";
import type { HomeAssistant, Route } from "../../../types"; import type { HomeAssistant, Route } from "../../../types";
import { configSections } from "../ha-panel-config"; import { configSections } from "../ha-panel-config";
import "../integrations/ha-integration-overflow-menu"; import "../integrations/ha-integration-overflow-menu";
import {
protocolIntegrationPicked,
PROTOCOL_INTEGRATIONS,
} from "../../../common/integrations/protocolIntegrationPicked";
import { showAddIntegrationDialog } from "../integrations/show-add-integration-dialog";
export interface StateEntity export interface StateEntity
extends Omit<EntityRegistryEntry, "id" | "unique_id"> { extends Omit<EntityRegistryEntry, "id" | "unique_id"> {
@@ -348,7 +353,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
? entities.concat(stateEntities) ? entities.concat(stateEntities)
: entities; : entities;
const filteredDomains: string[] = []; let filteredConfigEntry: ConfigEntry | undefined;
const filteredDomains = new Set<string>();
filters.forEach((value, key) => { filters.forEach((value, key) => {
if (key === "config_entry") { if (key === "config_entry") {
@@ -373,7 +379,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
const configEntry = entries.find((entry) => entry.entry_id === value); const configEntry = entries.find((entry) => entry.entry_id === value);
if (configEntry) { if (configEntry) {
filteredDomains.push(configEntry.domain); filteredDomains.add(configEntry.domain);
filteredConfigEntry = configEntry;
} }
} }
if (key === "domain") { if (key === "domain") {
@@ -389,7 +396,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
entity.config_entry_id && entity.config_entry_id &&
entryIds.includes(entity.config_entry_id) entryIds.includes(entity.config_entry_id)
); );
filteredDomains.push(value); filteredDomains.add(value);
startLength = filteredEntities.length; startLength = filteredEntities.length;
} }
}); });
@@ -444,7 +451,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
} }
this._numHiddenEntities = startLength - result.length; this._numHiddenEntities = startLength - result.length;
return { filteredEntities: result, filteredDomains: filteredDomains }; return { filteredEntities: result, filteredConfigEntry, filteredDomains };
} }
); );
@@ -509,7 +516,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
this._entries this._entries
); );
const includeZHAFab = filteredDomains.includes("zha"); const includeAddDeviceFab =
filteredDomains.size === 1 &&
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
[...filteredDomains][0]
);
return html` return html`
<hass-tabs-subpage-data-table <hass-tabs-subpage-data-table
@@ -545,7 +556,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
@search-changed=${this._handleSearchChange} @search-changed=${this._handleSearchChange}
@row-click=${this._openEditEntry} @row-click=${this._openEditEntry}
id="entity_id" id="entity_id"
.hasFab=${includeZHAFab} .hasFab=${includeAddDeviceFab}
> >
<ha-integration-overflow-menu <ha-integration-overflow-menu
.hass=${this.hass} .hass=${this.hass}
@@ -701,16 +712,16 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
</ha-check-list-item> </ha-check-list-item>
</ha-button-menu> </ha-button-menu>
`} `}
${includeZHAFab ${includeAddDeviceFab
? html`<a href="/config/zha/add" slot="fab"> ? html`<ha-fab
<ha-fab .label=${this.hass.localize("ui.panel.config.devices.add_device")}
.label=${this.hass.localize("ui.panel.config.zha.add_device")} extended
extended @click=${this._addDevice}
?rtl=${computeRTL(this.hass)} slot="fab"
> ?rtl=${computeRTL(this.hass)}
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon> >
</ha-fab> <ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
</a>` </ha-fab>`
: nothing} : nothing}
</hass-tabs-subpage-data-table> </hass-tabs-subpage-data-table>
`; `;
@@ -959,6 +970,36 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
this._showHidden = true; this._showHidden = true;
} }
private _addDevice() {
const { filteredConfigEntry, filteredDomains } =
this._filteredEntitiesAndDomains(
this._entities!,
this._devices,
this._areas,
this._stateEntities,
this._searchParms,
this._showDisabled,
this._showUnavailable,
this._showReadOnly,
this._showHidden,
this._entries
);
if (
filteredDomains.size === 1 &&
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
[...filteredDomains][0]
)
) {
protocolIntegrationPicked(this, this.hass, [...filteredDomains][0], {
config_entry: filteredConfigEntry?.entry_id,
});
return;
}
showAddIntegrationDialog(this, {
domain: this._searchParms.get("domain") || undefined,
});
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
haStyle, haStyle,

View File

@@ -10,16 +10,18 @@ import {
mdiCloud, mdiCloud,
mdiCog, mdiCog,
mdiDelete, mdiDelete,
mdiDevices,
mdiDotsVertical, mdiDotsVertical,
mdiDownload, mdiDownload,
mdiHandExtendedOutline,
mdiOpenInNew, mdiOpenInNew,
mdiPackageVariant, mdiPackageVariant,
mdiPlayCircleOutline, mdiPlayCircleOutline,
mdiPlus,
mdiProgressHelper, mdiProgressHelper,
mdiReload, mdiReload,
mdiReloadAlert, mdiReloadAlert,
mdiRenameBox, mdiRenameBox,
mdiShapeOutline,
mdiStopCircleOutline, mdiStopCircleOutline,
} from "@mdi/js"; } from "@mdi/js";
import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { UnsubscribeFunc } from "home-assistant-js-websocket";
@@ -213,6 +215,27 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
ERROR_STATES.includes(entry.state) ERROR_STATES.includes(entry.state)
); );
const normalEntries = configEntries
.filter(
(entry) =>
entry.source !== "ignore" && !ERROR_STATES.includes(entry.state)
)
.sort((a, b) => {
if (Boolean(a.disabled_by) !== Boolean(b.disabled_by)) {
return a.disabled_by ? 1 : -1;
}
return caseInsensitiveStringCompare(
a.title,
b.title,
this.hass.locale.language
);
});
const devices = this._getDevices(configEntries, this.hass.devices);
const entities = this._getEntities(configEntries, this._entities);
const services = !devices.some((device) => device.entry_type !== "service");
return html` return html`
<hass-subpage <hass-subpage
.hass=${this.hass} .hass=${this.hass}
@@ -221,7 +244,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
> >
<div class="container"> <div class="container">
<div class="column small"> <div class="column small">
<ha-card> <ha-card class="overview">
<div class="card-content"> <div class="card-content">
<div class="logo-container"> <div class="logo-container">
<img <img
@@ -243,7 +266,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
path=${mdiPackageVariant} path=${mdiPackageVariant}
></ha-svg-icon> ></ha-svg-icon>
${this.hass.localize( ${this.hass.localize(
"ui.panel.config.integrations.config_entry.provided_by_custom_integration" "ui.panel.config.integrations.config_entry.custom_integration"
)}</ha-alert )}</ha-alert
>` >`
: ""} : ""}
@@ -258,28 +281,47 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
</div> </div>
<div class="card-actions"> <div class="card-actions">
${this._logInfo ${devices.length > 0
? html`<ha-list-item ? html`<a
@request-selected=${this._logInfo.level === href=${devices.length === 1
LogSeverity.DEBUG ? `/config/devices/device/${devices[0].id}`
? this._handleDisableDebugLogging : `/config/devices/dashboard?historyBack=1&domain=${this.domain}`}
: this._handleEnableDebugLogging}
graphic="icon"
> >
${this._logInfo.level === LogSeverity.DEBUG <ha-list-item hasMeta graphic="icon">
? this.hass.localize( <ha-svg-icon
"ui.panel.config.integrations.config_entry.disable_debug_logging" .path=${services
) ? mdiHandExtendedOutline
: this.hass.localize( : mdiDevices}
"ui.panel.config.integrations.config_entry.enable_debug_logging" slot="graphic"
)} ></ha-svg-icon>
<ha-svg-icon ${this.hass.localize(
slot="graphic" `ui.panel.config.integrations.config_entry.${
.path=${this._logInfo.level === LogSeverity.DEBUG services ? "services" : "devices"
? mdiBugStop }`,
: mdiBugPlay} "count",
></ha-svg-icon> devices.length
</ha-list-item>` )}
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""}
${entities.length > 0
? html`<a
href=${`/config/entities?historyBack=1&domain=${this.domain}`}
>
<ha-list-item hasMeta graphic="icon">
<ha-svg-icon
.path=${mdiShapeOutline}
slot="graphic"
></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.integrations.config_entry.entities`,
"count",
entities.length
)}
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""} : ""}
${this._manifest ${this._manifest
? html`<a ? html`<a
@@ -329,6 +371,32 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
</ha-list-item> </ha-list-item>
</a>` </a>`
: ""} : ""}
${this._logInfo
? html`<ha-list-item
@request-selected=${this._logInfo.level ===
LogSeverity.DEBUG
? this._handleDisableDebugLogging
: this._handleEnableDebugLogging}
graphic="icon"
>
${this._logInfo.level === LogSeverity.DEBUG
? this.hass.localize(
"ui.panel.config.integrations.config_entry.disable_debug_logging"
)
: this.hass.localize(
"ui.panel.config.integrations.config_entry.enable_debug_logging"
)}
<ha-svg-icon
slot="graphic"
class=${this._logInfo.level === LogSeverity.DEBUG
? "warning"
: ""}
.path=${this._logInfo.level === LogSeverity.DEBUG
? mdiBugStop
: mdiBugPlay}
></ha-svg-icon>
</ha-list-item>`
: ""}
</div> </div>
</ha-card> </ha-card>
</div> </div>
@@ -354,7 +422,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
.flow=${flow} .flow=${flow}
@click=${this._continueFlow} @click=${this._continueFlow}
.label=${this.hass.localize( .label=${this.hass.localize(
"config_entry.disabled_by.config_entry" "ui.panel.config.integrations.configure"
)} )}
></ha-button> ></ha-button>
</ha-list-item>` </ha-list-item>`
@@ -410,43 +478,38 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
<ha-card> <ha-card>
<h1 class="card-header"> <h1 class="card-header">
${this.hass.localize( ${this._manifest?.integration_type
`ui.panel.config.integrations.integration_page.entries` ? this.hass.localize(
)} `ui.panel.config.integrations.integration_page.entries_${this._manifest?.integration_type}`
)
: this.hass.localize(
`ui.panel.config.integrations.integration_page.entries`
)}
</h1> </h1>
${configEntries.length === 0 ${normalEntries.length === 0
? html`<div class="card-content no-entries"> ? html`<div class="card-content no-entries">
${this.hass.localize( ${this.hass.localize(
`ui.panel.config.integrations.integration_page.no_entries` "ui.panel.config.integrations.integration_page.no_entries"
)} )}
</div>` </div>`
: nothing} : nothing}
<mwc-list> <mwc-list>
${configEntries ${normalEntries.map((item) => this._renderConfigEntry(item))}
.filter((entry) => !ERROR_STATES.includes(entry.state))
.sort((a, b) => {
if (Boolean(a.disabled_by) !== Boolean(b.disabled_by)) {
return a.disabled_by ? 1 : -1;
}
return caseInsensitiveStringCompare(
a.title,
b.title,
this.hass.locale.language
);
})
.map((item) => this._renderConfigEntry(item))}
</mwc-list> </mwc-list>
<div class="card-actions">
<ha-button @click=${this._addIntegration}>
${this._manifest?.integration_type
? this.hass.localize(
`ui.panel.config.integrations.integration_page.add_${this._manifest?.integration_type}`
)
: this.hass.localize(
`ui.panel.config.integrations.integration_page.add_entry`
)}
</ha-button>
</div>
</ha-card> </ha-card>
</div> </div>
</div> </div>
<ha-fab
slot="fab"
@click=${this._addIntegration}
.label=${`Add ${domainToName(this.hass.localize, this.domain)}`}
extended
>
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
</ha-fab>
</hass-subpage> </hass-subpage>
`; `;
} }
@@ -464,21 +527,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
let stateTextExtra: TemplateResult | string | undefined; let stateTextExtra: TemplateResult | string | undefined;
let icon: string = mdiAlertCircle; let icon: string = mdiAlertCircle;
if (item.disabled_by) { if (!item.disabled_by && item.state === "not_loaded") {
stateText = [
"ui.panel.config.integrations.config_entry.disable.disabled_cause",
"cause",
this.hass.localize(
`ui.panel.config.integrations.config_entry.disable.disabled_by.${item.disabled_by}`
) || item.disabled_by,
];
if (item.state === "failed_unload") {
stateTextExtra = html`.
${this.hass.localize(
"ui.panel.config.integrations.config_entry.disable_restart_confirm"
)}.`;
}
} else if (item.state === "not_loaded") {
stateText = ["ui.panel.config.integrations.config_entry.not_loaded"]; stateText = ["ui.panel.config.integrations.config_entry.not_loaded"];
} else if (item.state === "setup_in_progress") { } else if (item.state === "setup_in_progress") {
icon = mdiProgressHelper; icon = mdiProgressHelper;
@@ -508,66 +557,87 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
} }
} }
const devices = this._getDevices(item, this.hass.devices); const devices = this._getConfigEntryDevices(item);
const services = this._getServices(item, this.hass.devices); const services = this._getConfigEntryServices(item);
const entities = this._getEntities(item, this._entities); const entities = this._getConfigEntryEntities(item);
let devicesLine: (TemplateResult | string)[] = []; let devicesLine: (TemplateResult | string)[] = [];
for (const [items, localizeKey] of [ if (item.disabled_by) {
[devices, "devices"], devicesLine.push(
[services, "services"], this.hass.localize(
] as const) { "ui.panel.config.integrations.config_entry.disable.disabled_cause",
if (items.length === 0) { {
continue; cause:
this.hass.localize(
`ui.panel.config.integrations.config_entry.disable.disabled_by.${item.disabled_by}`
) || item.disabled_by,
}
)
);
if (item.state === "failed_unload") {
devicesLine.push(`.
${this.hass.localize(
"ui.panel.config.integrations.config_entry.disable_restart_confirm"
)}.`);
}
} else {
for (const [items, localizeKey] of [
[devices, "devices"],
[services, "services"],
] as const) {
if (items.length === 0) {
continue;
}
const url =
items.length === 1
? `/config/devices/device/${items[0].id}`
: `/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}`;
devicesLine.push(
// no white space before/after template on purpose
html`<a href=${url}
>${this.hass.localize(
`ui.panel.config.integrations.config_entry.${localizeKey}`,
"count",
items.length
)}</a
>`
);
}
if (entities.length) {
devicesLine.push(
// no white space before/after template on purpose
html`<a
href=${`/config/entities?historyBack=1&config_entry=${item.entry_id}`}
>${this.hass.localize(
"ui.panel.config.integrations.config_entry.entities",
"count",
entities.length
)}</a
>`
);
}
if (devicesLine.length === 0) {
devicesLine = ["No devices or entities"];
} else if (devicesLine.length === 2) {
devicesLine = [
devicesLine[0],
` ${this.hass.localize("ui.common.and")} `,
devicesLine[1],
];
} else if (devicesLine.length === 3) {
devicesLine = [
devicesLine[0],
", ",
devicesLine[1],
` ${this.hass.localize("ui.common.and")} `,
devicesLine[2],
];
} }
const url =
items.length === 1
? `/config/devices/device/${items[0].id}`
: `/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}`;
devicesLine.push(
// no white space before/after template on purpose
html`<a href=${url}
>${this.hass.localize(
`ui.panel.config.integrations.config_entry.${localizeKey}`,
"count",
items.length
)}</a
>`
);
} }
if (entities.length) {
devicesLine.push(
// no white space before/after template on purpose
html`<a
href=${`/config/entities?historyBack=1&config_entry=${item.entry_id}`}
>${this.hass.localize(
"ui.panel.config.integrations.config_entry.entities",
"count",
entities.length
)}</a
>`
);
}
if (devicesLine.length === 0) {
devicesLine = ["No devices or entities"];
} else if (devicesLine.length === 2) {
devicesLine = [
devicesLine[0],
` ${this.hass.localize("ui.common.and")} `,
devicesLine[1],
];
} else if (devicesLine.length === 3) {
devicesLine = [
devicesLine[0],
", ",
devicesLine[1],
` ${this.hass.localize("ui.common.and")} `,
devicesLine[2],
];
}
return html`<ha-list-item return html`<ha-list-item
hasMeta hasMeta
class="config_entry ${classMap({ class="config_entry ${classMap({
@@ -577,6 +647,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
"state-error": ERROR_STATES.includes(item!.state), "state-error": ERROR_STATES.includes(item!.state),
})}" })}"
data-entry-id=${item.entry_id} data-entry-id=${item.entry_id}
.disabled=${item.disabled_by}
.configEntry=${item} .configEntry=${item}
twoline twoline
noninteractive noninteractive
@@ -637,6 +708,61 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
)} )}
</ha-list-item>` </ha-list-item>`
: ""} : ""}
${item.disabled_by && devices.length
? html`<a
href=${devices.length === 1
? `/config/devices/device/${devices[0].id}`
: `/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}`}
>
<ha-list-item hasMeta graphic="icon">
<ha-svg-icon .path=${mdiDevices} slot="graphic"></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.integrations.config_entry.devices`,
"count",
devices.length
)}
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""}
${item.disabled_by && services.length
? html`<a
href=${services.length === 1
? `/config/devices/device/${services[0].id}`
: `/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}`}
>
<ha-list-item hasMeta graphic="icon">
<ha-svg-icon
.path=${mdiHandExtendedOutline}
slot="graphic"
></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.integrations.config_entry.services`,
"count",
services.length
)}
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""}
${item.disabled_by && entities.length
? html`<a
href=${`/config/entities?historyBack=1&config_entry=${item.entry_id}`}
>
<ha-list-item hasMeta graphic="icon">
<ha-svg-icon
.path=${mdiShapeOutline}
slot="graphic"
></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.integrations.config_entry.entities`,
"count",
entities.length
)}
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`
: ""}
${!item.disabled_by && ${!item.disabled_by &&
RECOVERABLE_STATES.includes(item.state) && RECOVERABLE_STATES.includes(item.state) &&
item.supports_unload && item.supports_unload &&
@@ -807,49 +933,77 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
private _getEntities = memoizeOne( private _getEntities = memoizeOne(
( (
configEntry: ConfigEntry, configEntry: ConfigEntry[],
entityRegistryEntries: EntityRegistryEntry[] entityRegistryEntries: EntityRegistryEntry[]
): EntityRegistryEntry[] => { ): EntityRegistryEntry[] => {
if (!entityRegistryEntries) { if (!entityRegistryEntries) {
return []; return [];
} }
const entryIds = configEntry.map((entry) => entry.entry_id);
return entityRegistryEntries.filter( return entityRegistryEntries.filter(
(entity) => entity.config_entry_id === configEntry.entry_id (entity) =>
entity.config_entry_id && entryIds.includes(entity.config_entry_id)
); );
} }
); );
private _getDevices = memoizeOne( private _getDevices = memoizeOne(
( (
configEntry: ConfigEntry, configEntry: ConfigEntry[],
deviceRegistryEntries: HomeAssistant["devices"] deviceRegistryEntries: HomeAssistant["devices"]
): DeviceRegistryEntry[] => { ): DeviceRegistryEntry[] => {
if (!deviceRegistryEntries) { if (!deviceRegistryEntries) {
return []; return [];
} }
return Object.values(deviceRegistryEntries).filter( const entryIds = configEntry.map((entry) => entry.entry_id);
(device) => return Object.values(deviceRegistryEntries).filter((device) =>
device.config_entries.includes(configEntry.entry_id) && device.config_entries.some((entryId) => entryIds.includes(entryId))
device.entry_type !== "service"
); );
} }
); );
private _getServices = memoizeOne( private _getConfigEntryEntities = (
( configEntry: ConfigEntry
configEntry: ConfigEntry, ): EntityRegistryEntry[] => {
deviceRegistryEntries: HomeAssistant["devices"] const entries = this._domainConfigEntries(
): DeviceRegistryEntry[] => { this.domain,
if (!deviceRegistryEntries) { this._extraConfigEntries || this.configEntries
return []; );
} const entityRegistryEntries = this._getEntities(entries, this._entities);
return Object.values(deviceRegistryEntries).filter( return entityRegistryEntries.filter(
(device) => (entity) => entity.config_entry_id === configEntry.entry_id
device.config_entries.includes(configEntry.entry_id) && );
device.entry_type === "service" };
);
} private _getConfigEntryDevices = (
); configEntry: ConfigEntry
): DeviceRegistryEntry[] => {
const entries = this._domainConfigEntries(
this.domain,
this._extraConfigEntries || this.configEntries
);
const deviceRegistryEntries = this._getDevices(entries, this.hass.devices);
return Object.values(deviceRegistryEntries).filter(
(device) =>
device.config_entries.includes(configEntry.entry_id) &&
device.entry_type !== "service"
);
};
private _getConfigEntryServices = (
configEntry: ConfigEntry
): DeviceRegistryEntry[] => {
const entries = this._domainConfigEntries(
this.domain,
this._extraConfigEntries || this.configEntries
);
const deviceRegistryEntries = this._getDevices(entries, this.hass.devices);
return Object.values(deviceRegistryEntries).filter(
(device) =>
device.config_entries.includes(configEntry.entry_id) &&
device.entry_type === "service"
);
};
private _showOptions(ev) { private _showOptions(ev) {
showOptionsFlowDialog( showOptionsFlowDialog(
@@ -1175,7 +1329,7 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.card-actions { .overview .card-actions {
padding: 0; padding: 0;
} }
img { img {
@@ -1199,6 +1353,9 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
--mdc-list-item-meta-size: auto; --mdc-list-item-meta-size: auto;
--mdc-list-item-meta-display: flex; --mdc-list-item-meta-display: flex;
} }
ha-button-menu ha-list-item {
--mdc-list-item-meta-size: 24px;
}
ha-list-item.config_entry::after { ha-list-item.config_entry::after {
position: absolute; position: absolute;
top: 0; top: 0;
@@ -1221,6 +1378,9 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
.attention { .attention {
primary-color: var(--error-color); primary-color: var(--error-color);
} }
.warning {
color: var(--error-color);
}
.state-error { .state-error {
--state-message-color: var(--error-color); --state-message-color: var(--error-color);
--text-on-state-color: var(--text-primary-color); --text-on-state-color: var(--text-primary-color);

View File

@@ -5,6 +5,7 @@ import {
mdiCogOutline, mdiCogOutline,
mdiDevices, mdiDevices,
mdiHandExtendedOutline, mdiHandExtendedOutline,
mdiPuzzleOutline,
mdiShapeOutline, mdiShapeOutline,
} from "@mdi/js"; } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
@@ -64,28 +65,28 @@ export class HaIntegrationCard extends LitElement {
"debug-logging": Boolean(debugLoggingEnabled), "debug-logging": Boolean(debugLoggingEnabled),
})} })}
> >
<ha-integration-header <a href=${`/config/integrations/integration/${this.domain}`}>
.hass=${this.hass} <ha-integration-header
.domain=${this.domain} .hass=${this.hass}
.localizedDomainName=${this.items[0].localized_domain_name} .domain=${this.domain}
.banner=${state !== "loaded" .localizedDomainName=${this.items[0].localized_domain_name}
? this.hass.localize( .banner=${state !== "loaded"
`ui.panel.config.integrations.config_entry.state.${state}` ? this.hass.localize(
) `ui.panel.config.integrations.config_entry.state.${state}`
: debugLoggingEnabled )
? this.hass.localize( : debugLoggingEnabled
"ui.panel.config.integrations.config_entry.debug_logging_enabled" ? this.hass.localize(
) "ui.panel.config.integrations.config_entry.debug_logging_enabled"
: undefined} )
.manifest=${this.manifest} : undefined}
> .manifest=${this.manifest}
<a
href=${`/config/integrations/integration/${this.domain}`}
slot="header-button"
> >
<ha-icon-button .path=${mdiCogOutline}></ha-icon-button> <ha-icon-button
</a> slot="header-button"
</ha-integration-header> .path=${mdiCogOutline}
></ha-icon-button>
</ha-integration-header>
</a>
${this._renderSingleEntry()} ${this._renderSingleEntry()}
</ha-card> </ha-card>
@@ -94,7 +95,9 @@ export class HaIntegrationCard extends LitElement {
private _renderSingleEntry(): TemplateResult { private _renderSingleEntry(): TemplateResult {
const devices = this._getDevices(this.items, this.hass.devices); const devices = this._getDevices(this.items, this.hass.devices);
const entities = this._getEntities(this.items, this.entityRegistryEntries); const entities = devices.length
? []
: this._getEntities(this.items, this.entityRegistryEntries);
const services = !devices.some((device) => device.entry_type !== "service"); const services = !devices.some((device) => device.entry_type !== "service");
@@ -121,8 +124,7 @@ export class HaIntegrationCard extends LitElement {
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
</a>` </a>`
: ""} : entities.length > 0
${entities.length > 0
? html`<a ? html`<a
href=${`/config/entities?historyBack=1&domain=${this.domain}`} href=${`/config/entities?historyBack=1&domain=${this.domain}`}
> >
@@ -139,7 +141,20 @@ export class HaIntegrationCard extends LitElement {
<ha-icon-next slot="meta"></ha-icon-next> <ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item> </ha-list-item>
</a>` </a>`
: ""} : html`<a href=${`/config/integrations/integration/${this.domain}`}>
<ha-list-item hasMeta graphic="icon">
<ha-svg-icon
.path=${mdiPuzzleOutline}
slot="graphic"
></ha-svg-icon>
${this.hass.localize(
`ui.panel.config.integrations.config_entry.entries`,
"count",
this.items.length
)}
<ha-icon-next slot="meta"></ha-icon-next>
</ha-list-item>
</a>`}
</div> </div>
`; `;
} }
@@ -234,7 +249,7 @@ export class HaIntegrationCard extends LitElement {
} }
a { a {
text-decoration: none; text-decoration: none;
color: var(--primary-color); color: var(--primary-text-color);
} }
a ha-icon-button { a ha-icon-button {
color: var(--secondary-text-color); color: var(--secondary-text-color);

View File

@@ -3,6 +3,7 @@ import { mdiCloud, mdiPackageVariant } from "@mdi/js";
import { css, html, LitElement, TemplateResult } from "lit"; import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { classMap } from "lit/directives/class-map"; import { classMap } from "lit/directives/class-map";
import { computeRTL } from "../../../common/util/compute_rtl";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import { domainToName, IntegrationManifest } from "../../../data/integration"; import { domainToName, IntegrationManifest } from "../../../data/integration";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
@@ -49,7 +50,7 @@ export class HaIntegrationHeader extends LitElement {
icons.push([ icons.push([
mdiPackageVariant, mdiPackageVariant,
this.hass.localize( this.hass.localize(
"ui.panel.config.integrations.config_entry.provided_by_custom_integration" "ui.panel.config.integrations.config_entry.custom_integration"
), ),
]); ]);
} }
@@ -94,7 +95,10 @@ export class HaIntegrationHeader extends LitElement {
([icon, description]) => html` ([icon, description]) => html`
<span> <span>
<ha-svg-icon .path=${icon}></ha-svg-icon> <ha-svg-icon .path=${icon}></ha-svg-icon>
<simple-tooltip animation-delay="0" <simple-tooltip
animation-delay="0"
.position=${computeRTL(this.hass) ? "left" : "right"}
offset="4"
>${description}</simple-tooltip >${description}</simple-tooltip
> >
</span> </span>
@@ -184,6 +188,9 @@ export class HaIntegrationHeader extends LitElement {
left: 40px; left: 40px;
top: 40px; top: 40px;
display: flex; display: flex;
padding: 4px;
inset-inline-start: 40px;
inset-inline-end: initial;
} }
.icons.cloud { .icons.cloud {
background: var(--info-color); background: var(--info-color);
@@ -191,14 +198,18 @@ export class HaIntegrationHeader extends LitElement {
.icons.double { .icons.double {
background: var(--warning-color); background: var(--warning-color);
left: 28px; left: 28px;
inset-inline-start: 28px;
inset-inline-end: initial;
} }
.icons ha-svg-icon { .icons ha-svg-icon {
width: 16px; width: 16px;
height: 16px; height: 16px;
margin: 4px; display: block;
} }
.icons span:not(:first-child) ha-svg-icon { .icons span:not(:first-child) ha-svg-icon {
margin-left: 0; margin-left: 4px;
margin-inline-start: 4px;
margin-inline-end: inherit;
} }
simple-tooltip { simple-tooltip {
white-space: nowrap; white-space: nowrap;

View File

@@ -84,7 +84,7 @@ export class HaIntegrationListItem extends ListItemBase {
><ha-svg-icon .path=${mdiPackageVariant}></ha-svg-icon ><ha-svg-icon .path=${mdiPackageVariant}></ha-svg-icon
><simple-tooltip animation-delay="0" position="left" ><simple-tooltip animation-delay="0" position="left"
>${this.hass.localize( >${this.hass.localize(
"ui.panel.config.integrations.config_entry.provided_by_custom_integration" "ui.panel.config.integrations.config_entry.custom_integration"
)}</simple-tooltip )}</simple-tooltip
></span ></span
>` >`

View File

@@ -501,7 +501,7 @@ export class ThreadConfigPanel extends SubscribeMixin(LitElement) {
haStyle, haStyle,
css` css`
.content { .content {
padding: 24px 0 32px; padding: 24px 8px 32px;
max-width: 600px; max-width: 600px;
margin: 0 auto; margin: 0 auto;
direction: ltr; direction: ltr;

View File

@@ -30,6 +30,7 @@ const VALID_CHANNELS = [
23, 23,
24, 24,
25, 25,
26,
]; ];
@customElement("dialog-zha-change-channel") @customElement("dialog-zha-change-channel")

View File

@@ -46,6 +46,8 @@ import {
} from "../../../../../data/zha"; } from "../../../../../data/zha";
import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box"; import { showAlertDialog } from "../../../../../dialogs/generic/show-dialog-box";
const MULTIPROTOCOL_ADDON_URL = "socket://core-silabs-multiprotocol:9999";
export const zhaTabs: PageNavigation[] = [ export const zhaTabs: PageNavigation[] = [
{ {
translationKey: "ui.panel.config.zha.network.caption", translationKey: "ui.panel.config.zha.network.caption",
@@ -181,6 +183,25 @@ class ZHAConfigDashboard extends LitElement {
>${this._networkSettings.radio_type}</span >${this._networkSettings.radio_type}</span
> >
</ha-settings-row> </ha-settings-row>
<ha-settings-row>
<span slot="description">Serial port</span>
<span slot="heading"
>${this._networkSettings.device.path}</span
>
</ha-settings-row>
${this._networkSettings.device.baudrate &&
!this._networkSettings.device.path.startsWith("socket://")
? html`
<ha-settings-row>
<span slot="description">Baudrate</span>
<span slot="heading"
>${this._networkSettings.device.baudrate}</span
>
</ha-settings-row>
`
: ""}
</div>` </div>`
: ""} : ""}
<div class="card-actions"> <div class="card-actions">
@@ -255,6 +276,19 @@ class ZHAConfigDashboard extends LitElement {
} }
private async _showChannelMigrationDialog(): Promise<void> { private async _showChannelMigrationDialog(): Promise<void> {
if (this._networkSettings!.device.path === MULTIPROTOCOL_ADDON_URL) {
showAlertDialog(this, {
title: this.hass.localize(
"ui.panel.config.zha.configuration_page.channel_dialog.title"
),
text: this.hass.localize(
"ui.panel.config.zha.configuration_page.channel_dialog.text"
),
warning: true,
});
return;
}
showZHAChangeChannelDialog(this, { showZHAChangeChannelDialog(this, {
currentChannel: this._networkSettings!.settings.network_info.channel, currentChannel: this._networkSettings!.settings.network_info.channel,
}); });
@@ -341,11 +375,6 @@ class ZHAConfigDashboard extends LitElement {
max-width: 500px; max-width: 500px;
} }
.network-settings > div {
word-break: break-all;
margin-top: 2px;
}
.network-settings ha-settings-row { .network-settings ha-settings-row {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
@@ -353,6 +382,13 @@ class ZHAConfigDashboard extends LitElement {
--paper-item-body-two-line-min-height: 55px; --paper-item-body-two-line-min-height: 55px;
} }
.network-settings ha-settings-row span[slot="heading"] {
white-space: normal;
word-break: break-all;
text-indent: -1em;
padding-left: 1em;
}
.network-settings ha-settings-row ha-icon-button { .network-settings ha-settings-row ha-icon-button {
margin-top: -16px; margin-top: -16px;
margin-bottom: -16px; margin-bottom: -16px;

View File

@@ -217,7 +217,7 @@ export const showRepairsFlowDialog = (
return hass.localize( return hass.localize(
`component.${issue.domain}.issues.${ `component.${issue.domain}.issues.${
issue.translation_key || issue.issue_id issue.translation_key || issue.issue_id
}.fix_flow.step.${step.step_id}.menu_issues.${option}`, }.fix_flow.step.${step.step_id}.menu_options.${option}`,
step.description_placeholders step.description_placeholders
); );
}, },

View File

@@ -71,33 +71,43 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
private _columns = memoizeOne( private _columns = memoizeOne(
(localize): DataTableColumnContainer => ({ (localize): DataTableColumnContainer => ({
displayName: { displayName: {
title: "Name", title: localize(
"ui.panel.developer-tools.tabs.statistics.data_table.name"
),
sortable: true, sortable: true,
filterable: true, filterable: true,
grows: true, grows: true,
}, },
statistic_id: { statistic_id: {
title: "Statistic id", title: localize(
"ui.panel.developer-tools.tabs.statistics.data_table.statistic_id"
),
sortable: true, sortable: true,
filterable: true, filterable: true,
hidden: this.narrow, hidden: this.narrow,
width: "20%", width: "20%",
}, },
statistics_unit_of_measurement: { statistics_unit_of_measurement: {
title: "Statistics unit", title: localize(
"ui.panel.developer-tools.tabs.statistics.data_table.statistics_unit"
),
sortable: true, sortable: true,
filterable: true, filterable: true,
width: "10%", width: "10%",
forceLTR: true, forceLTR: true,
}, },
source: { source: {
title: "Source", title: localize(
"ui.panel.developer-tools.tabs.statistics.data_table.source"
),
sortable: true, sortable: true,
filterable: true, filterable: true,
width: "10%", width: "10%",
}, },
issues: { issues: {
title: "Issue", title: localize(
"ui.panel.developer-tools.tabs.statistics.data_table.issue"
),
sortable: true, sortable: true,
filterable: true, filterable: true,
direction: "asc", direction: "asc",

View File

@@ -34,7 +34,10 @@ import {
HistoryStates, HistoryStates,
subscribeHistoryStatesTimeWindow, subscribeHistoryStatesTimeWindow,
} from "../../../data/history"; } from "../../../data/history";
import { hasConfigOrEntitiesChanged } from "../common/has-changed"; import {
hasConfigChanged,
hasConfigOrEntitiesChanged,
} from "../common/has-changed";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entities"; import { findEntities } from "../common/find-entities";
import { processConfigEntities } from "../common/process-config-entities"; import { processConfigEntities } from "../common/process-config-entities";
@@ -194,7 +197,15 @@ class HuiMapCard extends LitElement implements LovelaceCard {
return true; return true;
} }
return hasConfigOrEntitiesChanged(this, changedProps); if (this._config?.geo_location_sources) {
if (oldHass.states !== this.hass.states) {
return true;
}
}
return this._config?.entities
? hasConfigOrEntitiesChanged(this, changedProps)
: hasConfigChanged(this, changedProps);
} }
public connectedCallback() { public connectedCallback() {

View File

@@ -4,7 +4,10 @@ import { EntityRegistryDisplayEntry } from "../../../data/entity_registry";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import { processConfigEntities } from "./process-config-entities"; import { processConfigEntities } from "./process-config-entities";
function hasConfigChanged(element: any, changedProps: PropertyValues): boolean { export function hasConfigChanged(
element: any,
changedProps: PropertyValues
): boolean {
if (changedProps.has("_config")) { if (changedProps.has("_config")) {
return true; return true;
} }

View File

@@ -85,7 +85,7 @@ class HuiGenericEntityRow extends LitElement {
tabindex=${ifDefined(pointer ? "0" : undefined)} tabindex=${ifDefined(pointer ? "0" : undefined)}
></state-badge> ></state-badge>
${!this.hideName ${!this.hideName
? html` <div ? html`<div
class="info ${classMap({ class="info ${classMap({
pointer, pointer,
"text-content": !hasSecondary, "text-content": !hasSecondary,

View File

@@ -1,6 +1,5 @@
import { html, LitElement, nothing } from "lit"; import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { import {
array, array,
assert, assert,
@@ -13,7 +12,10 @@ import {
} from "superstruct"; } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-form/ha-form"; import "../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../components/ha-form/types"; import type {
HaFormSchema,
SchemaUnion,
} from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { GaugeCardConfig } from "../../cards/types"; import type { GaugeCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types"; import type { LovelaceCardEditor } from "../../types";
@@ -41,6 +43,75 @@ const cardConfigStruct = assign(
}) })
); );
const SCHEMA = [
{
name: "entity",
selector: {
entity: {
domain: ["counter", "input_number", "number", "sensor"],
},
},
},
{
name: "",
type: "grid",
schema: [
{ name: "name", selector: { text: {} } },
{ name: "unit", selector: { text: {} } },
],
},
{ name: "theme", selector: { theme: {} } },
{
name: "",
type: "grid",
schema: [
{
name: "min",
default: DEFAULT_MIN,
selector: { number: { mode: "box" } },
},
{
name: "max",
default: DEFAULT_MAX,
selector: { number: { mode: "box" } },
},
],
},
{
name: "",
type: "grid",
schema: [
{ name: "needle", selector: { boolean: {} } },
{ name: "show_severity", selector: { boolean: {} } },
],
},
{
name: "",
type: "conditional",
condition: (data) => !!data.show_severity,
schema: [
{
name: "severity",
type: "grid",
schema: [
{
name: "green",
selector: { number: { mode: "box" } },
},
{
name: "yellow",
selector: { number: { mode: "box" } },
},
{
name: "red",
selector: { number: { mode: "box" } },
},
],
},
],
},
] as const satisfies readonly HaFormSchema[];
@customElement("hui-gauge-card-editor") @customElement("hui-gauge-card-editor")
export class HuiGaugeCardEditor export class HuiGaugeCardEditor
extends LitElement extends LitElement
@@ -55,81 +126,11 @@ export class HuiGaugeCardEditor
this._config = config; this._config = config;
} }
private _schema = memoizeOne(
(showSeverity: boolean) =>
[
{
name: "entity",
selector: {
entity: {
domain: ["counter", "input_number", "number", "sensor"],
},
},
},
{
name: "",
type: "grid",
schema: [
{ name: "name", selector: { text: {} } },
{ name: "unit", selector: { text: {} } },
],
},
{ name: "theme", selector: { theme: {} } },
{
name: "",
type: "grid",
schema: [
{
name: "min",
default: DEFAULT_MIN,
selector: { number: { mode: "box" } },
},
{
name: "max",
default: DEFAULT_MAX,
selector: { number: { mode: "box" } },
},
],
},
{
name: "",
type: "grid",
schema: [
{ name: "needle", selector: { boolean: {} } },
{ name: "show_severity", selector: { boolean: {} } },
],
},
...(showSeverity
? ([
{
name: "severity",
type: "grid",
schema: [
{
name: "green",
selector: { number: { mode: "box" } },
},
{
name: "yellow",
selector: { number: { mode: "box" } },
},
{
name: "red",
selector: { number: { mode: "box" } },
},
],
},
] as const)
: []),
] as const
);
protected render() { protected render() {
if (!this.hass || !this._config) { if (!this.hass || !this._config) {
return nothing; return nothing;
} }
const schema = this._schema(this._config!.severity !== undefined);
const data = { const data = {
show_severity: this._config!.severity !== undefined, show_severity: this._config!.severity !== undefined,
...this._config, ...this._config,
@@ -139,7 +140,7 @@ export class HuiGaugeCardEditor
<ha-form <ha-form
.hass=${this.hass} .hass=${this.hass}
.data=${data} .data=${data}
.schema=${schema} .schema=${SCHEMA}
.computeLabel=${this._computeLabelCallback} .computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged} @value-changed=${this._valueChanged}
></ha-form> ></ha-form>
@@ -153,7 +154,7 @@ export class HuiGaugeCardEditor
config = { config = {
...config, ...config,
severity: { severity: {
green: config.green || config.severity?.green || 0, green: config.green || config.severity?.green,
yellow: config.yellow || config.severity?.yellow || 0, yellow: config.yellow || config.severity?.yellow || 0,
red: config.red || config.severity?.red || 0, red: config.red || config.severity?.red || 0,
}, },
@@ -170,9 +171,7 @@ export class HuiGaugeCardEditor
fireEvent(this, "config-changed", { config }); fireEvent(this, "config-changed", { config });
} }
private _computeLabelCallback = ( private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
schema: SchemaUnion<ReturnType<typeof this._schema>>
) => {
switch (schema.name) { switch (schema.name) {
case "name": case "name":
return this.hass!.localize( return this.hass!.localize(

View File

@@ -2,7 +2,7 @@ import { html, LitElement, nothing, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import "../../../components/ha-date-input"; import "../../../components/ha-date-input";
import { isUnavailableState } from "../../../data/entity"; import { isUnavailableState } from "../../../data/entity";
import { setDateValue, stateToIsoDateString } from "../../../data/date"; import { setDateValue } from "../../../data/date";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { hasConfigOrEntityChanged } from "../common/has-changed"; import { hasConfigOrEntityChanged } from "../common/has-changed";
import "../components/hui-generic-entity-row"; import "../components/hui-generic-entity-row";
@@ -41,16 +41,14 @@ class HuiDateEntityRow extends LitElement implements LovelaceRow {
`; `;
} }
const unavailable = isUnavailableState(stateObj.state);
return html` return html`
<hui-generic-entity-row <hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
.hass=${this.hass}
.config=${this._config}
hideName="true"
>
<ha-date-input <ha-date-input
.locale=${this.hass.locale} .locale=${this.hass.locale}
.disabled=${isUnavailableState(stateObj.state)} .disabled=${unavailable}
.value=${stateToIsoDateString(stateObj)} .value=${unavailable ? "" : stateObj.state}
@value-changed=${this._dateChanged} @value-changed=${this._dateChanged}
> >
</ha-date-input> </ha-date-input>
@@ -59,9 +57,7 @@ class HuiDateEntityRow extends LitElement implements LovelaceRow {
} }
private _dateChanged(ev: CustomEvent<{ value: string }>): void { private _dateChanged(ev: CustomEvent<{ value: string }>): void {
const stateObj = this.hass!.states[this._config!.entity]; setDateValue(this.hass!, this._config!.entity, ev.detail.value);
setDateValue(this.hass!, stateObj.entity_id, ev.detail.value);
} }
} }

View File

@@ -18,6 +18,7 @@ import "../components/hui-generic-entity-row";
import { createEntityNotFoundWarning } from "../components/hui-warning"; import { createEntityNotFoundWarning } from "../components/hui-warning";
import type { EntityConfig, LovelaceRow } from "./types"; import type { EntityConfig, LovelaceRow } from "./types";
import "../../../components/ha-time-input"; import "../../../components/ha-time-input";
import { computeStateName } from "../../../common/entity/compute_state_name";
@customElement("hui-datetime-entity-row") @customElement("hui-datetime-entity-row")
class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow { class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
@@ -51,30 +52,35 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
`; `;
} }
const dateObj = new Date(stateObj.state); const unavailable = isUnavailableState(stateObj.state);
const time = format(dateObj, "HH:mm:ss");
const date = format(dateObj, "yyyy-MM-dd"); const dateObj = unavailable ? undefined : new Date(stateObj.state);
const time = dateObj ? format(dateObj, "HH:mm:ss") : "";
const date = dateObj ? format(dateObj, "yyyy-MM-dd") : "";
return html` return html`
<hui-generic-entity-row <hui-generic-entity-row
.hass=${this.hass} .hass=${this.hass}
.config=${this._config} .config=${this._config}
hideName="true" hideName
> >
<ha-date-input <div>
.locale=${this.hass.locale} <ha-date-input
.value=${date} .label=${this._config.name || computeStateName(stateObj)}
.disabled=${isUnavailableState(stateObj.state)} .locale=${this.hass.locale}
@value-changed=${this._dateChanged} .value=${date}
> .disabled=${unavailable}
</ha-date-input> @value-changed=${this._dateChanged}
<ha-time-input >
.value=${time} </ha-date-input>
.disabled=${isUnavailableState(stateObj.state)} <ha-time-input
.locale=${this.hass.locale} .value=${time}
@value-changed=${this._timeChanged} .disabled=${unavailable}
@click=${this._stopEventPropagation} .locale=${this.hass.locale}
></ha-time-input> @value-changed=${this._timeChanged}
@click=${this._stopEventPropagation}
></ha-time-input>
</div>
</hui-generic-entity-row> </hui-generic-entity-row>
`; `;
} }
@@ -103,12 +109,17 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
ha-date-input + ha-time-input { ha-time-input {
margin-left: 4px; margin-left: 4px;
margin-inline-start: 4px; margin-inline-start: 4px;
margin-inline-end: initial; margin-inline-end: initial;
direction: var(--direction); direction: var(--direction);
} }
div {
display: flex;
justify-content: flex-end;
width: 100%;
}
`; `;
} }
} }

View File

@@ -62,33 +62,39 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
.hideName=${stateObj.attributes.has_date && .hideName=${stateObj.attributes.has_date &&
stateObj.attributes.has_time} stateObj.attributes.has_time}
> >
${stateObj.attributes.has_date <div
? html` class=${stateObj.attributes.has_date && stateObj.attributes.has_time
<ha-date-input ? "both"
.label=${stateObj.attributes.has_time ? name : undefined} : ""}
.locale=${this.hass.locale} >
.disabled=${isUnavailableState(stateObj.state)} ${stateObj.attributes.has_date
.value=${stateToIsoDateString(stateObj)} ? html`
@value-changed=${this._dateChanged} <ha-date-input
> .label=${stateObj.attributes.has_time ? name : undefined}
</ha-date-input> .locale=${this.hass.locale}
` .disabled=${isUnavailableState(stateObj.state)}
: ``} .value=${stateToIsoDateString(stateObj)}
${stateObj.attributes.has_time @value-changed=${this._dateChanged}
? html` >
<ha-time-input </ha-date-input>
.value=${stateObj.state === UNKNOWN `
? "" : ``}
: stateObj.attributes.has_date ${stateObj.attributes.has_time
? stateObj.state.split(" ")[1] ? html`
: stateObj.state} <ha-time-input
.locale=${this.hass.locale} .value=${stateObj.state === UNKNOWN
.disabled=${isUnavailableState(stateObj.state)} ? ""
@value-changed=${this._timeChanged} : stateObj.attributes.has_date
@click=${this._stopEventPropagation} ? stateObj.state.split(" ")[1]
></ha-time-input> : stateObj.state}
` .locale=${this.hass.locale}
: ``} .disabled=${isUnavailableState(stateObj.state)}
@value-changed=${this._timeChanged}
@click=${this._stopEventPropagation}
></ha-time-input>
`
: ``}
</div>
</hui-generic-entity-row> </hui-generic-entity-row>
`; `;
} }
@@ -126,6 +132,11 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
margin-inline-end: initial; margin-inline-end: initial;
direction: var(--direction); direction: var(--direction);
} }
div.both {
display: flex;
justify-content: flex-end;
width: 100%;
}
`; `;
} }
} }

View File

@@ -42,16 +42,14 @@ class HuiTimeEntityRow extends LitElement implements LovelaceRow {
`; `;
} }
const unavailable = isUnavailableState(stateObj.state);
return html` return html`
<hui-generic-entity-row <hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
.hass=${this.hass}
.config=${this._config}
hideName="true"
>
<ha-time-input <ha-time-input
.value=${stateObj.state} .value=${unavailable ? "" : stateObj.state}
.locale=${this.hass.locale} .locale=${this.hass.locale}
.disabled=${isUnavailableState(stateObj.state)} .disabled=${unavailable}
@value-changed=${this._timeChanged} @value-changed=${this._timeChanged}
@click=${this._stopEventPropagation} @click=${this._stopEventPropagation}
></ha-time-input> ></ha-time-input>

View File

@@ -802,7 +802,7 @@ class HUIRoot extends LitElement {
} }
if (this._yamlMode) { if (this._yamlMode) {
showAlertDialog(this, { showAlertDialog(this, {
text: "The edit UI is not available when in YAML mode.", text: this.hass!.localize("ui.panel.lovelace.editor.yaml_unsupported"),
}); });
return; return;
} }

View File

@@ -320,6 +320,11 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
min-width: 0; min-width: 0;
} }
/* Fix for safari */
.column:has(> *) {
flex-grow: 1;
}
.column:not(:has(> *:not([hidden]))) { .column:not(:has(> *:not([hidden]))) {
flex-grow: 0; flex-grow: 0;
} }

View File

@@ -2,7 +2,6 @@ export const loadPolyfillIfNeeded = async () => {
try { try {
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new ResizeObserver(() => {}); new ResizeObserver(() => {});
return;
} catch (e) { } catch (e) {
window.ResizeObserver = ( window.ResizeObserver = (
await import( await import(

View File

@@ -3062,7 +3062,8 @@
"battery": "Battery", "battery": "Battery",
"disabled_by": "Disabled", "disabled_by": "Disabled",
"no_devices": "No devices", "no_devices": "No devices",
"no_integration": "No integration" "no_integration": "No integration",
"unknown": "unknown"
}, },
"delete": "Delete", "delete": "Delete",
"confirm_delete": "Are you sure you want to delete this device?", "confirm_delete": "Are you sure you want to delete this device?",
@@ -3251,8 +3252,19 @@
}, },
"integration_page": { "integration_page": {
"entries": "Integration entries", "entries": "Integration entries",
"entries_device": "Devices",
"entries_hub": "Hubs",
"entries_service": "Services",
"entries_helper": "Helpers",
"entries_hardware": "Hardware",
"no_entries": "No entries", "no_entries": "No entries",
"attention_entries": "Needs attention" "attention_entries": "Needs attention",
"add_entry": "Add entry",
"add_device": "Add device",
"add_hub": "Add hub",
"add_service": "Add service",
"add_helper": "Add helper",
"add_hardware": "Add hardware"
}, },
"config_entry": { "config_entry": {
"application_credentials": { "application_credentials": {
@@ -3266,6 +3278,7 @@
"devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}",
"entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}", "entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}",
"services": "{count} {count, plural,\n one {service}\n other {services}\n}", "services": "{count} {count, plural,\n one {service}\n other {services}\n}",
"entries": "{count} {count, plural,\n one {entry}\n other {entries}\n}",
"rename": "Rename", "rename": "Rename",
"configure": "Configure", "configure": "Configure",
"system_options": "System options", "system_options": "System options",
@@ -3307,7 +3320,7 @@
"device": "device" "device": "device"
} }
}, },
"provided_by_custom_integration": "Provided by a custom integration", "custom_integration": "Custom integration",
"depends_on_cloud": "Depends on the cloud", "depends_on_cloud": "Depends on the cloud",
"yaml_only": "Needs manual configuration", "yaml_only": "Needs manual configuration",
"disabled_polling": "Automatic polling for updated data disabled", "disabled_polling": "Automatic polling for updated data disabled",
@@ -3509,7 +3522,11 @@
"download_backup": "Download Backup", "download_backup": "Download Backup",
"migrate_radio": "Migrate Radio", "migrate_radio": "Migrate Radio",
"network_settings_title": "Network Settings", "network_settings_title": "Network Settings",
"change_channel": "Change channel" "change_channel": "Change channel",
"channel_dialog": {
"title": "Multiprotocol addon in use",
"text": "Zigbee and Thread share the same radio and must use the same channel. Change the channel of both networks by reconfiguring multiprotocol from the hardware menu."
}
}, },
"add_device_page": { "add_device_page": {
"spinner": "Searching for Zigbee devices…", "spinner": "Searching for Zigbee devices…",
@@ -4268,6 +4285,7 @@
}, },
"editor": { "editor": {
"header": "Edit UI", "header": "Edit UI",
"yaml_unsupported": "The edit UI is not available when in YAML mode.",
"menu": { "menu": {
"open": "Open dashboard menu", "open": "Open dashboard menu",
"raw_editor": "Raw configuration editor", "raw_editor": "Raw configuration editor",
@@ -5253,7 +5271,14 @@
"clear": "Delete all old statistic data for this entity" "clear": "Delete all old statistic data for this entity"
} }
}, },
"adjust_sum": "Adjust sum" "adjust_sum": "Adjust sum",
"data_table": {
"name": "Name",
"statistic_id": "Statistic id",
"statistics_unit": "Statistics unit",
"source": "Source",
"issue": "Issue"
}
}, },
"yaml": { "yaml": {
"title": "YAML", "title": "YAML",

550
yarn.lock
View File

@@ -1587,10 +1587,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint/js@npm:8.41.0": "@eslint/js@npm:8.42.0":
version: 8.41.0 version: 8.42.0
resolution: "@eslint/js@npm:8.41.0" resolution: "@eslint/js@npm:8.42.0"
checksum: af013d70fe8d0429cdf5cd8b5dcc6fc384ed026c1eccb0cfe30f5849b968ab91645111373fd1b83282b38955b1bdfbe667c1a7dbda3b06cae753521223cad775 checksum: 750558843ac458f7da666122083ee05306fc087ecc1e5b21e7e14e23885775af6c55bcc92283dff1862b7b0d8863ec676c0f18c7faf1219c722fe91a8ece56b6
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1791,14 +1791,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@humanwhocodes/config-array@npm:^0.11.8": "@humanwhocodes/config-array@npm:^0.11.10":
version: 0.11.8 version: 0.11.10
resolution: "@humanwhocodes/config-array@npm:0.11.8" resolution: "@humanwhocodes/config-array@npm:0.11.10"
dependencies: dependencies:
"@humanwhocodes/object-schema": ^1.2.1 "@humanwhocodes/object-schema": ^1.2.1
debug: ^4.1.1 debug: ^4.1.1
minimatch: ^3.0.5 minimatch: ^3.0.5
checksum: 0fd6b3c54f1674ce0a224df09b9c2f9846d20b9e54fabae1281ecfc04f2e6ad69bf19e1d6af6a28f88e8aa3990168b6cb9e1ef755868c3256a630605ec2cb1d3 checksum: 1b1302e2403d0e35bc43e66d67a2b36b0ad1119efc704b5faff68c41f791a052355b010fb2d27ef022670f550de24cd6d08d5ecf0821c16326b7dcd0ee5d5d8a
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2063,13 +2063,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@lit-labs/context@npm:0.3.1": "@lit-labs/context@npm:0.3.2":
version: 0.3.1 version: 0.3.2
resolution: "@lit-labs/context@npm:0.3.1" resolution: "@lit-labs/context@npm:0.3.2"
dependencies: dependencies:
"@lit/reactive-element": ^1.5.0 "@lit/reactive-element": ^1.5.0
lit: ^2.7.0 lit: ^2.7.0
checksum: eca24343bf63a092662a45c0483a77191348514c84aa7fa1a497d45c5741c16e8e61fb294ed8e56d73536b4e7fe96c49beb416417a2c879e670e553e19f5a3f5 checksum: 55920366798a3337a455c627c0b6911c7b78dee94a783ad77edb9a9e237a2e48201d6cf869f3d0b805316e5c8e8fb817f52f663bc556dd40ca6e8b3168662daf
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2108,12 +2108,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@lrnwebcomponents/simple-tooltip@npm:7.0.0": "@lrnwebcomponents/simple-tooltip@npm:7.0.2":
version: 7.0.0 version: 7.0.2
resolution: "@lrnwebcomponents/simple-tooltip@npm:7.0.0" resolution: "@lrnwebcomponents/simple-tooltip@npm:7.0.2"
dependencies: dependencies:
lit: ^2.7.2 lit: ^2.7.4
checksum: 2db3b2d07cceecbf4869f24d47800d2f3fadb2d3d671ecd79664019fe3fc4cf757052a3a14ca8f8d2719e459d65c26509df8f6a1719d36cbb6a1ae51a789653b checksum: 2f8642c7b503e6093d01b5fcadea461de062c9380df6454f04a08e5b8f4ef36e0cbd52a9f0842238554f6881802895fb442f21c0a4b6345bebd99b43f18a366c
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3349,15 +3349,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@octokit/plugin-retry@npm:4.1.3": "@octokit/plugin-retry@npm:5.0.0":
version: 4.1.3 version: 5.0.0
resolution: "@octokit/plugin-retry@npm:4.1.3" resolution: "@octokit/plugin-retry@npm:5.0.0"
dependencies: dependencies:
"@octokit/types": ^9.0.0 "@octokit/types": ^9.0.0
bottleneck: ^2.15.3 bottleneck: ^2.15.3
peerDependencies: peerDependencies:
"@octokit/core": ">=3" "@octokit/core": ">=3"
checksum: f9ed5869be23dddcf1ee896ce996e46a412a586259b55612ba44c82cdeed91436102e6e3ec57db879bd91a4446dcafbaa94632e4e059c6af56d9cca9b163eacb checksum: 3ffea3da379f724f476ba053de3b43c6509684c33cd7a5015b936ea77324cf5801259e20867ab5dccee07af6c23000ccb13c924ce4eef1f4d28e69e4c9056beb
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3898,9 +3898,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/plugin-node-resolve@npm:15.0.2": "@rollup/plugin-node-resolve@npm:15.1.0":
version: 15.0.2 version: 15.1.0
resolution: "@rollup/plugin-node-resolve@npm:15.0.2" resolution: "@rollup/plugin-node-resolve@npm:15.1.0"
dependencies: dependencies:
"@rollup/pluginutils": ^5.0.1 "@rollup/pluginutils": ^5.0.1
"@types/resolve": 1.20.2 "@types/resolve": 1.20.2
@@ -3913,7 +3913,7 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
rollup: rollup:
optional: true optional: true
checksum: 328eafee06ff967a36441b55e77fbd0d4f599d256e5d1977800ee71915846c46bc1b6185df35c7b512ad2b4023b05b65a332be77b8b00b9d8a20f87d056b8166 checksum: 83617cdbb90cb780251e8b16dc1671e35bde90b8d4d30e008aefe706b5b643057f6299bdd3226b2a30bf5e4f807a880169de3faa47b9f2ba38d39f294f85f951
languageName: node languageName: node
linkType: hard linkType: hard
@@ -4658,14 +4658,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/eslint-plugin@npm:5.59.7": "@typescript-eslint/eslint-plugin@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/eslint-plugin@npm:5.59.7" resolution: "@typescript-eslint/eslint-plugin@npm:5.59.8"
dependencies: dependencies:
"@eslint-community/regexpp": ^4.4.0 "@eslint-community/regexpp": ^4.4.0
"@typescript-eslint/scope-manager": 5.59.7 "@typescript-eslint/scope-manager": 5.59.8
"@typescript-eslint/type-utils": 5.59.7 "@typescript-eslint/type-utils": 5.59.8
"@typescript-eslint/utils": 5.59.7 "@typescript-eslint/utils": 5.59.8
debug: ^4.3.4 debug: ^4.3.4
grapheme-splitter: ^1.0.4 grapheme-splitter: ^1.0.4
ignore: ^5.2.0 ignore: ^5.2.0
@@ -4678,43 +4678,43 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 10d28bac7a5af9e41767be0bb9c270ee3dcdfeaa38d1b036c6822e7260b88821c460699ba943664eb1ef272d00de6a81b99d7d955332044ea87b624e7ead84a1 checksum: 3e05cd06149ec3741c3c2fb638e2d19a55687b4614a5c8820433db82997687650297e51c17828d320162ccf4241798cf5712c405561e7605cb17e984a6967f7b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/parser@npm:5.59.7": "@typescript-eslint/parser@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/parser@npm:5.59.7" resolution: "@typescript-eslint/parser@npm:5.59.8"
dependencies: dependencies:
"@typescript-eslint/scope-manager": 5.59.7 "@typescript-eslint/scope-manager": 5.59.8
"@typescript-eslint/types": 5.59.7 "@typescript-eslint/types": 5.59.8
"@typescript-eslint/typescript-estree": 5.59.7 "@typescript-eslint/typescript-estree": 5.59.8
debug: ^4.3.4 debug: ^4.3.4
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: bc44f37a11a44f84ae5f0156213f3e2e49aef2ecac94d9e161a0c721acd29462e288f306ad4648095ac1c0e5a5f62b78280c1735883cf39f79ee3afcba312119 checksum: bac9f09d8552086ceb882a7b87ce4d98dfaa41579249216c75d97e3fc07af33cddc4cbbd07a127a5823c826a258882643aaf658bec19cb2a434002b55c5f0d12
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/scope-manager@npm:5.59.7": "@typescript-eslint/scope-manager@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/scope-manager@npm:5.59.7" resolution: "@typescript-eslint/scope-manager@npm:5.59.8"
dependencies: dependencies:
"@typescript-eslint/types": 5.59.7 "@typescript-eslint/types": 5.59.8
"@typescript-eslint/visitor-keys": 5.59.7 "@typescript-eslint/visitor-keys": 5.59.8
checksum: 43f7ea93fddbe2902122a41050677fe3eff2ea468f435b981592510cfc6136e8c28ac7d3a3e05fb332c0b3078a29bd0c91c35b2b1f4e788b4eb9aaeb70e21583 checksum: e1e810ee991cfeb433330b04ee949bb6784abe4dbdb7d9480aa7a7536671b4fec914b7803edf662516c8ecb1b31dcff126797f9923270a529c26e2b00b0ea96f
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/type-utils@npm:5.59.7": "@typescript-eslint/type-utils@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/type-utils@npm:5.59.7" resolution: "@typescript-eslint/type-utils@npm:5.59.8"
dependencies: dependencies:
"@typescript-eslint/typescript-estree": 5.59.7 "@typescript-eslint/typescript-estree": 5.59.8
"@typescript-eslint/utils": 5.59.7 "@typescript-eslint/utils": 5.59.8
debug: ^4.3.4 debug: ^4.3.4
tsutils: ^3.21.0 tsutils: ^3.21.0
peerDependencies: peerDependencies:
@@ -4722,23 +4722,23 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: 9cbeffad27b145b478e4cbbab2b44c5b246a9b922f01fd06d401ea4c41a4fa6dc8ba75d13a6409b3b4474ccaf2018770a4c6c599172e22ec2004110e00f4e721 checksum: d9fde31397da0f0e62a5568f64bad99d06bcd324b7e3aac7fd997a3d045a0fe4c084b2e85d440e0a39645acd2269ad6593f196399c2c0f880d293417fec894e3
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/types@npm:5.59.7": "@typescript-eslint/types@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/types@npm:5.59.7" resolution: "@typescript-eslint/types@npm:5.59.8"
checksum: 52eccec9e2d631eb2808e48b5dc33a837b5e242fa9eddace89fc707c9f2283b5364f1d38b33d418a08d64f45f6c22f051800898e1881a912f8aac0c3ae300d0a checksum: 559473d5601c849eb0da1874a2ac67c753480beed484ad6f6cda62fa6023273f2c3005c7f2864d9c2afb7c6356412d0d304b57db10c53597207f18a7f6cd4f18
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/typescript-estree@npm:5.59.7": "@typescript-eslint/typescript-estree@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/typescript-estree@npm:5.59.7" resolution: "@typescript-eslint/typescript-estree@npm:5.59.8"
dependencies: dependencies:
"@typescript-eslint/types": 5.59.7 "@typescript-eslint/types": 5.59.8
"@typescript-eslint/visitor-keys": 5.59.7 "@typescript-eslint/visitor-keys": 5.59.8
debug: ^4.3.4 debug: ^4.3.4
globby: ^11.1.0 globby: ^11.1.0
is-glob: ^4.0.3 is-glob: ^4.0.3
@@ -4747,142 +4747,142 @@ __metadata:
peerDependenciesMeta: peerDependenciesMeta:
typescript: typescript:
optional: true optional: true
checksum: eefe82eedf9ee2e14463c3f2b5b18df084c1328a859b245ee897a9a7075acce7cca0216a21fd7968b75aa64189daa008bfde1e2f9afbcc336f3dfe856e7f342e checksum: d93371cc866f573a6a1ddc0eb10d498a8e59f36763a99ce21da0737fff2b4c942eef1587216aad273f8d896ebc0b19003677cba63a27d2646aa2c087638963eb
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/utils@npm:5.59.7": "@typescript-eslint/utils@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/utils@npm:5.59.7" resolution: "@typescript-eslint/utils@npm:5.59.8"
dependencies: dependencies:
"@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/eslint-utils": ^4.2.0
"@types/json-schema": ^7.0.9 "@types/json-schema": ^7.0.9
"@types/semver": ^7.3.12 "@types/semver": ^7.3.12
"@typescript-eslint/scope-manager": 5.59.7 "@typescript-eslint/scope-manager": 5.59.8
"@typescript-eslint/types": 5.59.7 "@typescript-eslint/types": 5.59.8
"@typescript-eslint/typescript-estree": 5.59.7 "@typescript-eslint/typescript-estree": 5.59.8
eslint-scope: ^5.1.1 eslint-scope: ^5.1.1
semver: ^7.3.7 semver: ^7.3.7
peerDependencies: peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
checksum: d8682700187ca94cc6441480cb6b87d0514a9748103c15dd93206c5b1c6fefa59063662f27a4103e16abbcfb654a61d479bc55af8f23d96f342431b87f31bb4e checksum: cbaa057485c7f52c45d0dfb4f5a8e9273abccb1c52dcb4426a79f9e71d2c1062cf2525bad6d4aca5ec42db3fe723d749843bcade5a323bde7fbe4b5d5b5d5c3b
languageName: node languageName: node
linkType: hard linkType: hard
"@typescript-eslint/visitor-keys@npm:5.59.7": "@typescript-eslint/visitor-keys@npm:5.59.8":
version: 5.59.7 version: 5.59.8
resolution: "@typescript-eslint/visitor-keys@npm:5.59.7" resolution: "@typescript-eslint/visitor-keys@npm:5.59.8"
dependencies: dependencies:
"@typescript-eslint/types": 5.59.7 "@typescript-eslint/types": 5.59.8
eslint-visitor-keys: ^3.3.0 eslint-visitor-keys: ^3.3.0
checksum: 4367f2ea68dd96a0520485434ad11e1bd26239eeeb3a2150bee7478a0f1df3c2099a39f96486722932be0456bcb7a47a483b452876d1d30bdeb9b81d354eef3d checksum: 6bfa7918dbb0e08d8a7404aeeef7bcd1a85736dc8d01614d267c0c5ec10f94d2746b50a945bf5c82c54fda67926e8deaeba8565c919da17f725fc11209ef8987
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/combo-box@npm:24.0.7": "@vaadin/combo-box@npm:24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/combo-box@npm:24.0.7" resolution: "@vaadin/combo-box@npm:24.0.8"
dependencies: dependencies:
"@open-wc/dedupe-mixin": ^1.3.0 "@open-wc/dedupe-mixin": ^1.3.0
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/component-base": ~24.0.7 "@vaadin/component-base": ~24.0.8
"@vaadin/field-base": ~24.0.7 "@vaadin/field-base": ~24.0.8
"@vaadin/input-container": ~24.0.7 "@vaadin/input-container": ~24.0.8
"@vaadin/item": ~24.0.7 "@vaadin/item": ~24.0.8
"@vaadin/lit-renderer": ~24.0.7 "@vaadin/lit-renderer": ~24.0.8
"@vaadin/overlay": ~24.0.7 "@vaadin/overlay": ~24.0.8
"@vaadin/vaadin-lumo-styles": ~24.0.7 "@vaadin/vaadin-lumo-styles": ~24.0.8
"@vaadin/vaadin-material-styles": ~24.0.7 "@vaadin/vaadin-material-styles": ~24.0.8
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
checksum: cadd2f701c3134da8ad3128427ca55a6158b5e3bc1df78e7a6da63986fafdf1ed9e79f3bbb8a21501da072cac1c69c24a8bfa8e59e3291a7ab8f31afb28a0b14 checksum: 14bea4c273a96393e8cd3338f0aee6da417026d5712adc82e4dc7f2964e9ccb3b338f950788bc22ec7e7805ababb98f624d44415d969788c0ea896cdc7480084
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/component-base@npm:~24.0.7": "@vaadin/component-base@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/component-base@npm:24.0.7" resolution: "@vaadin/component-base@npm:24.0.8"
dependencies: dependencies:
"@open-wc/dedupe-mixin": ^1.3.0 "@open-wc/dedupe-mixin": ^1.3.0
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/vaadin-development-mode-detector": ^2.0.0 "@vaadin/vaadin-development-mode-detector": ^2.0.0
"@vaadin/vaadin-usage-statistics": ^2.1.0 "@vaadin/vaadin-usage-statistics": ^2.1.0
lit: ^2.0.0 lit: ^2.0.0
checksum: 8498c05582f6b919be655a76d7580a4fcc528e0a7f2a2a9cfccc2f0736920dfd3f99280c17293efaa2c52edee1642321eb575ff4f5d62c9877afe0d38df6ca2c checksum: 6406ee2f2bdca164a15480f870611caa91f4b5cfd083de2b838ddf2e6438415d1fce236edebfc8509057ee64f1f1c59712af49e2b41d938a6fa6bc6593b0b00e
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/field-base@npm:~24.0.7": "@vaadin/field-base@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/field-base@npm:24.0.7" resolution: "@vaadin/field-base@npm:24.0.8"
dependencies: dependencies:
"@open-wc/dedupe-mixin": ^1.3.0 "@open-wc/dedupe-mixin": ^1.3.0
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/component-base": ~24.0.7 "@vaadin/component-base": ~24.0.8
lit: ^2.0.0 lit: ^2.0.0
checksum: c9032cf15cada54fd0563ea3d8adc8970330c51819afeb76c1289da44594f9b0df1a9c5c0c33f25d71f692630b3fba07ce2f146c88f3e324b18bbf1b8c2c15d5 checksum: 7603960e86e705ead7bddaa24252cf733b43b8f08a4b0d4f7c7941f01a2c45fc6a8a50d98ccc49a50a5e1e40b7bbd6327db6762a6fa449a3b31c2934d46f64b0
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/icon@npm:~24.0.7": "@vaadin/icon@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/icon@npm:24.0.7" resolution: "@vaadin/icon@npm:24.0.8"
dependencies: dependencies:
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/component-base": ~24.0.7 "@vaadin/component-base": ~24.0.8
"@vaadin/vaadin-lumo-styles": ~24.0.7 "@vaadin/vaadin-lumo-styles": ~24.0.8
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
lit: ^2.0.0 lit: ^2.0.0
checksum: 09ccb17b6476c7a2d2964b49e02fc7b73a8e90fd8040de51092897e401a98fb11d27125a8bd1f2ad08f3180c06d3f5d5d414e71daefbaaac5e4f11e26f13e09d checksum: bfec0d0048649817dd40f5aec2ad3c94d51557161c5af5f04aebadf56d6546b34a5b29013008207e71deaa4ccf9aad0b5a82beb00541f246cb0707396b72e327
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/input-container@npm:~24.0.7": "@vaadin/input-container@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/input-container@npm:24.0.7" resolution: "@vaadin/input-container@npm:24.0.8"
dependencies: dependencies:
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/component-base": ~24.0.7 "@vaadin/component-base": ~24.0.8
"@vaadin/vaadin-lumo-styles": ~24.0.7 "@vaadin/vaadin-lumo-styles": ~24.0.8
"@vaadin/vaadin-material-styles": ~24.0.7 "@vaadin/vaadin-material-styles": ~24.0.8
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
checksum: a86e20890f8e193c09018b2c111e5616191b563ea111cb8199b2a923956865f7e28920cd3824c353f72ad902f05e7f74b43bed30d755c542e39b22b31355a02c checksum: d323b2e5b74c72107a9cb6f833bd20b09b2f419d2fbac45136acd535e50ac78d216779ed56aaf510fc73d28677e850d2ed2588f44189289687625cb51a0617d2
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/item@npm:~24.0.7": "@vaadin/item@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/item@npm:24.0.7" resolution: "@vaadin/item@npm:24.0.8"
dependencies: dependencies:
"@open-wc/dedupe-mixin": ^1.3.0 "@open-wc/dedupe-mixin": ^1.3.0
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/component-base": ~24.0.7 "@vaadin/component-base": ~24.0.8
"@vaadin/vaadin-lumo-styles": ~24.0.7 "@vaadin/vaadin-lumo-styles": ~24.0.8
"@vaadin/vaadin-material-styles": ~24.0.7 "@vaadin/vaadin-material-styles": ~24.0.8
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
checksum: 12150979ff1789ab05737bc36ccf4c4b305523031398c7c32709b8e04bf7a42c73f9e833bf91c883f2769408352a109283917731d36cf900f2f7e3be9c822f59 checksum: 7d2ebcd7b9a04dd093c22fdf4e5fe8e37f96c5bafd480f4cd69471d12d675d8fd966f3cea2b82f3fb7bd3f77a1d1f05cc07d7799345df0885ad3cea63d579c20
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/lit-renderer@npm:~24.0.7": "@vaadin/lit-renderer@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/lit-renderer@npm:24.0.7" resolution: "@vaadin/lit-renderer@npm:24.0.8"
dependencies: dependencies:
lit: ^2.0.0 lit: ^2.0.0
checksum: 12493343c19cf0b5e1495ca7d1d7542cc67caffdf06e13ebbc69f3cdf493b149d49ece1bcc0c23c944978f4ac2c061ab8f7103784fb6177ad4f121b2083aa371 checksum: d624c779e2b4682923322cb952255490b5f58f392bfd24121fffc347f8cb89be9e90de760c24e846bc98e0f9bb76b658ed99a5446dfaa8f81e61270f8adcf06f
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/overlay@npm:~24.0.7": "@vaadin/overlay@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/overlay@npm:24.0.7" resolution: "@vaadin/overlay@npm:24.0.8"
dependencies: dependencies:
"@open-wc/dedupe-mixin": ^1.3.0 "@open-wc/dedupe-mixin": ^1.3.0
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/component-base": ~24.0.7 "@vaadin/component-base": ~24.0.8
"@vaadin/vaadin-lumo-styles": ~24.0.7 "@vaadin/vaadin-lumo-styles": ~24.0.8
"@vaadin/vaadin-material-styles": ~24.0.7 "@vaadin/vaadin-material-styles": ~24.0.8
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
checksum: 256c3472b57045211be9c9021d0236443197d4cde0b52c496560e57b68e61f3d221a99ea24c7113a4a29f348984188bf1399e4aec16e3e653f0992a66a879394 checksum: f274cfd0cd2bd0f2a75b0f4f494e1d82e0947d7faaa8cb791801c0b2aa90020113ece50fa9736dc59015436ea07c053261efa096ca39ed458c072a7fb98b8110
languageName: node languageName: node
linkType: hard linkType: hard
@@ -4893,34 +4893,34 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/vaadin-lumo-styles@npm:~24.0.7": "@vaadin/vaadin-lumo-styles@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/vaadin-lumo-styles@npm:24.0.7" resolution: "@vaadin/vaadin-lumo-styles@npm:24.0.8"
dependencies: dependencies:
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/icon": ~24.0.7 "@vaadin/icon": ~24.0.8
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
checksum: 54b711d9b028a2792884c3f7ff655b12cedfc94a7c615966fb3cf5bc6098d684b54c91e45a86756b9abb3e325b98f38fa77adc003d635979abe3e1e16117f436 checksum: 351516cf34d95d3800f82d067ef8c539d67a8cde4c0becbc5bc2467f805999c3ba66d9ba3e493aff3708cde3684be937ed766828af7ad956c9ec48f6209650f7
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/vaadin-material-styles@npm:~24.0.7": "@vaadin/vaadin-material-styles@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/vaadin-material-styles@npm:24.0.7" resolution: "@vaadin/vaadin-material-styles@npm:24.0.8"
dependencies: dependencies:
"@polymer/polymer": ^3.0.0 "@polymer/polymer": ^3.0.0
"@vaadin/vaadin-themable-mixin": ~24.0.7 "@vaadin/vaadin-themable-mixin": ~24.0.8
checksum: 74528c370cfc624635d312f088a4d1cc341115d9e60c6433caecbcf40b63b7078e267d056a1d389ee4d841535d784e6e38c1ba356c29837ec0a3fd21b2858051 checksum: 667719adb4efbf9544025a2c59887a359321190e15c5cd902f17c53b7138a23720ddbf0986b2315884163c92e61c1847419844b604651efb0118bc985af47645
languageName: node languageName: node
linkType: hard linkType: hard
"@vaadin/vaadin-themable-mixin@npm:24.0.7, @vaadin/vaadin-themable-mixin@npm:~24.0.7": "@vaadin/vaadin-themable-mixin@npm:24.0.8, @vaadin/vaadin-themable-mixin@npm:~24.0.8":
version: 24.0.7 version: 24.0.8
resolution: "@vaadin/vaadin-themable-mixin@npm:24.0.7" resolution: "@vaadin/vaadin-themable-mixin@npm:24.0.8"
dependencies: dependencies:
"@open-wc/dedupe-mixin": ^1.3.0 "@open-wc/dedupe-mixin": ^1.3.0
lit: ^2.0.0 lit: ^2.0.0
checksum: 03bbff9b0caa7d236ecaa39224b42a548054a4032ec83667ac98485441e0277bfc0179e1020a2015dffd601c341742df371fe33870477a07da1e41bc048df408 checksum: 5ffcacd49f2f42e01fee55033375ebcf46e93abcb2c7df02b460b635dfb3d7bef5629e7fdafb0813027a4239d6e11ff1ddca31f9281abf5a5f08db8c5418807d
languageName: node languageName: node
linkType: hard linkType: hard
@@ -8164,15 +8164,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint@npm:8.41.0": "eslint@npm:8.42.0":
version: 8.41.0 version: 8.42.0
resolution: "eslint@npm:8.41.0" resolution: "eslint@npm:8.42.0"
dependencies: dependencies:
"@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/eslint-utils": ^4.2.0
"@eslint-community/regexpp": ^4.4.0 "@eslint-community/regexpp": ^4.4.0
"@eslint/eslintrc": ^2.0.3 "@eslint/eslintrc": ^2.0.3
"@eslint/js": 8.41.0 "@eslint/js": 8.42.0
"@humanwhocodes/config-array": ^0.11.8 "@humanwhocodes/config-array": ^0.11.10
"@humanwhocodes/module-importer": ^1.0.1 "@humanwhocodes/module-importer": ^1.0.1
"@nodelib/fs.walk": ^1.2.8 "@nodelib/fs.walk": ^1.2.8
ajv: ^6.10.0 ajv: ^6.10.0
@@ -8209,7 +8209,7 @@ __metadata:
text-table: ^0.2.0 text-table: ^0.2.0
bin: bin:
eslint: bin/eslint.js eslint: bin/eslint.js
checksum: 09979a6f8451dcc508a7005b6670845c8a518376280b3fd96657a406b8b6ef29d0e480d1ba11b4eb48da93d607e0c55c9b877676fe089d09973ec152354e23b2 checksum: 07105397b5f2ff4064b983b8971e8c379ec04b1dfcc9d918976b3e00377189000161dac991d82ba14f8759e466091b8c71146f602930ca810c290ee3fcb3faf0
languageName: node languageName: node
linkType: hard linkType: hard
@@ -9636,10 +9636,10 @@ __metadata:
"@fullcalendar/timegrid": 6.1.8 "@fullcalendar/timegrid": 6.1.8
"@koa/cors": 4.0.0 "@koa/cors": 4.0.0
"@lezer/highlight": 1.1.6 "@lezer/highlight": 1.1.6
"@lit-labs/context": 0.3.1 "@lit-labs/context": 0.3.2
"@lit-labs/motion": 1.0.3 "@lit-labs/motion": 1.0.3
"@lit-labs/virtualizer": 2.0.2 "@lit-labs/virtualizer": 2.0.2
"@lrnwebcomponents/simple-tooltip": 7.0.0 "@lrnwebcomponents/simple-tooltip": 7.0.2
"@material/chips": =14.0.0-canary.53b3cad2f.0 "@material/chips": =14.0.0-canary.53b3cad2f.0
"@material/data-table": =14.0.0-canary.53b3cad2f.0 "@material/data-table": =14.0.0-canary.53b3cad2f.0
"@material/mwc-button": 0.27.0 "@material/mwc-button": 0.27.0
@@ -9669,7 +9669,7 @@ __metadata:
"@mdi/js": 7.2.96 "@mdi/js": 7.2.96
"@mdi/svg": 7.2.96 "@mdi/svg": 7.2.96
"@octokit/auth-oauth-device": 4.0.4 "@octokit/auth-oauth-device": 4.0.4
"@octokit/plugin-retry": 4.1.3 "@octokit/plugin-retry": 5.0.0
"@octokit/rest": 19.0.11 "@octokit/rest": 19.0.11
"@open-wc/dev-server-hmr": 0.1.4 "@open-wc/dev-server-hmr": 0.1.4
"@polymer/app-layout": 3.1.0 "@polymer/app-layout": 3.1.0
@@ -9686,7 +9686,7 @@ __metadata:
"@rollup/plugin-babel": 6.0.3 "@rollup/plugin-babel": 6.0.3
"@rollup/plugin-commonjs": 25.0.0 "@rollup/plugin-commonjs": 25.0.0
"@rollup/plugin-json": 6.0.0 "@rollup/plugin-json": 6.0.0
"@rollup/plugin-node-resolve": 15.0.2 "@rollup/plugin-node-resolve": 15.1.0
"@rollup/plugin-replace": 5.0.2 "@rollup/plugin-replace": 5.0.2
"@thomasloven/round-slider": 0.6.0 "@thomasloven/round-slider": 0.6.0
"@types/babel__plugin-transform-runtime": 7.9.2 "@types/babel__plugin-transform-runtime": 7.9.2
@@ -9705,10 +9705,10 @@ __metadata:
"@types/sortablejs": 1.15.1 "@types/sortablejs": 1.15.1
"@types/tar": 6.1.5 "@types/tar": 6.1.5
"@types/webspeechapi": 0.0.29 "@types/webspeechapi": 0.0.29
"@typescript-eslint/eslint-plugin": 5.59.7 "@typescript-eslint/eslint-plugin": 5.59.8
"@typescript-eslint/parser": 5.59.7 "@typescript-eslint/parser": 5.59.8
"@vaadin/combo-box": 24.0.7 "@vaadin/combo-box": 24.0.8
"@vaadin/vaadin-themable-mixin": 24.0.7 "@vaadin/vaadin-themable-mixin": 24.0.8
"@vibrant/color": 3.2.1-alpha.1 "@vibrant/color": 3.2.1-alpha.1
"@vibrant/core": 3.2.1-alpha.1 "@vibrant/core": 3.2.1-alpha.1
"@vibrant/quantizer-mmcq": 3.2.1-alpha.1 "@vibrant/quantizer-mmcq": 3.2.1-alpha.1
@@ -9730,7 +9730,7 @@ __metadata:
deep-clone-simple: 1.1.1 deep-clone-simple: 1.1.1
deep-freeze: 0.0.1 deep-freeze: 0.0.1
del: 7.0.0 del: 7.0.0
eslint: 8.41.0 eslint: 8.42.0
eslint-config-airbnb-base: 15.0.0 eslint-config-airbnb-base: 15.0.0
eslint-config-airbnb-typescript: 17.0.0 eslint-config-airbnb-typescript: 17.0.0
eslint-config-prettier: 8.8.0 eslint-config-prettier: 8.8.0
@@ -9765,7 +9765,7 @@ __metadata:
leaflet: 1.9.4 leaflet: 1.9.4
leaflet-draw: 1.0.4 leaflet-draw: 1.0.4
lint-staged: 13.2.2 lint-staged: 13.2.2
lit: 2.7.4 lit: 2.7.5
lit-analyzer: 1.2.1 lit-analyzer: 1.2.1
lodash.template: 4.5.0 lodash.template: 4.5.0
magic-string: 0.30.0 magic-string: 0.30.0
@@ -9816,13 +9816,13 @@ __metadata:
webpack-manifest-plugin: 5.0.0 webpack-manifest-plugin: 5.0.0
webpackbar: 5.0.2 webpackbar: 5.0.2
weekstart: 2.0.0 weekstart: 2.0.0
workbox-build: 6.6.0 workbox-build: 7.0.0
workbox-cacheable-response: 6.6.0 workbox-cacheable-response: 7.0.0
workbox-core: 6.6.0 workbox-core: 7.0.0
workbox-expiration: 6.6.0 workbox-expiration: 7.0.0
workbox-precaching: 6.6.0 workbox-precaching: 7.0.0
workbox-routing: 6.6.0 workbox-routing: 7.0.0
workbox-strategies: 6.6.0 workbox-strategies: 7.0.0
xss: 1.0.14 xss: 1.0.14
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -11474,14 +11474,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lit@npm:2.7.4, 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.2, 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":
version: 2.7.4 version: 2.7.5
resolution: "lit@npm:2.7.4" resolution: "lit@npm:2.7.5"
dependencies: dependencies:
"@lit/reactive-element": ^1.6.0 "@lit/reactive-element": ^1.6.0
lit-element: ^3.3.0 lit-element: ^3.3.0
lit-html: ^2.7.0 lit-html: ^2.7.0
checksum: 7494f4e814fca0ebf7a73923c85454531aac26ff83f0d4d5afe62ebbc6225363c9df41f88147d79d5d3ab518925ceb9b27a557bee610bbb414ae0339c513f5a3 checksum: 61a3f87c57136618f47a30b36cdfb592fcba42dcfbdb104d2b5ca291148c2d9a32fcb713bb91090bd08d6897a00e73f8425da6e3626aa080eaf410a32397ae69
languageName: node languageName: node
linkType: hard linkType: hard
@@ -16455,28 +16455,28 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-background-sync@npm:6.6.0": "workbox-background-sync@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-background-sync@npm:6.6.0" resolution: "workbox-background-sync@npm:7.0.0"
dependencies: dependencies:
idb: ^7.0.1 idb: ^7.0.1
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: ac2990110643aef62ca0be54e962296de7b09593b0262bd09fe4893978a42fa1f256c6d989ed472a31ae500b2255b80c6678530a6024eafb0b2f3a93a3c94a5f checksum: 79b64416563761d36b91342d6ce2618d1c984bebcd511ce56b80098127e42c676d4831dd566a0a80a6bb52a618ad815b277ce6b310e4a5c5043e7394829d30c6
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-broadcast-update@npm:6.6.0": "workbox-broadcast-update@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-broadcast-update@npm:6.6.0" resolution: "workbox-broadcast-update@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: 46a74b3b703244eb363e1731a2d6fe1fb2cd9b82d454733dfc6941fd35b76a852685f56db92408383ac50d564c2fd4282f0c6c4db60ba9beb5f311ea8f944dc7 checksum: eee5c09fd78b3439348c7c92013f63700f14004d46161f19b0daf0d01303c6785f0953b746258cfb2627932108631370c8fa52ec5b526177cd528ae02530370e
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-build@npm:6.6.0": "workbox-build@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-build@npm:6.6.0" resolution: "workbox-build@npm:7.0.0"
dependencies: dependencies:
"@apideck/better-ajv-errors": ^0.3.1 "@apideck/better-ajv-errors": ^0.3.1
"@babel/core": ^7.11.1 "@babel/core": ^7.11.1
@@ -16500,148 +16500,148 @@ __metadata:
strip-comments: ^2.0.1 strip-comments: ^2.0.1
tempy: ^0.6.0 tempy: ^0.6.0
upath: ^1.2.0 upath: ^1.2.0
workbox-background-sync: 6.6.0 workbox-background-sync: 7.0.0
workbox-broadcast-update: 6.6.0 workbox-broadcast-update: 7.0.0
workbox-cacheable-response: 6.6.0 workbox-cacheable-response: 7.0.0
workbox-core: 6.6.0 workbox-core: 7.0.0
workbox-expiration: 6.6.0 workbox-expiration: 7.0.0
workbox-google-analytics: 6.6.0 workbox-google-analytics: 7.0.0
workbox-navigation-preload: 6.6.0 workbox-navigation-preload: 7.0.0
workbox-precaching: 6.6.0 workbox-precaching: 7.0.0
workbox-range-requests: 6.6.0 workbox-range-requests: 7.0.0
workbox-recipes: 6.6.0 workbox-recipes: 7.0.0
workbox-routing: 6.6.0 workbox-routing: 7.0.0
workbox-strategies: 6.6.0 workbox-strategies: 7.0.0
workbox-streams: 6.6.0 workbox-streams: 7.0.0
workbox-sw: 6.6.0 workbox-sw: 7.0.0
workbox-window: 6.6.0 workbox-window: 7.0.0
checksum: cd1a6c413659c2fd66f4438012f65b211cc748bb594c79bf0d9a60de0cefff3f8a4a23ab06f32c62064c37397ffffc1b77d3328658b7556ea7ff88e57f6ee4fd checksum: f230463833a8b6d1beadbfb4db5526d1b6b047ffa23abcd2afdc306510e1f3f942a74d1c59c76ee371a326bb2fe616ced05d0c53aefee5902c68a3f31faa27dc
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-cacheable-response@npm:6.6.0": "workbox-cacheable-response@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-cacheable-response@npm:6.6.0" resolution: "workbox-cacheable-response@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: 9e4e00c53679fd2020874cbdf54bb17560fd12353120ea08ca6213e5a11bf08139072616d79f5f8ab80d09f00efde94b003fe9bf5b6e23815be30d7aca760835 checksum: c9d834b25564ee01dd4df17b1f27e61160a3b610f40c0e297a9973712878fe617e168e3b1541c7b70b0de3828cb4b62de3088424b4a2872ed5a106e7e777772f
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-core@npm:6.6.0": "workbox-core@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-core@npm:6.6.0" resolution: "workbox-core@npm:7.0.0"
checksum: 7d773a866b73a733780c52b895f9cf7bec926c9187395c307174deefba9a0a2fcd1edce0d1ca12b8a6c95ca9cf7755ccc1885b03bc82ebcfc4843e015bd84d7b checksum: ca64872f9ce59ee1f3f32a5ecbde36377081a221930c6f925e2c0d7fe39d3fdc309166c430d56d972eba4f7c40d2e7e91a0020699a0745790fbef578ff8f34f6
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-expiration@npm:6.6.0": "workbox-expiration@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-expiration@npm:6.6.0" resolution: "workbox-expiration@npm:7.0.0"
dependencies: dependencies:
idb: ^7.0.1 idb: ^7.0.1
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: b100b9c512754bc3e1a9c7c7d20d215d72c601a7b956333ca7753704a771a9f00e1732e9b774da4549bae390dd3cd138c6392f6a25fd67f7dcd84f89b0df7e9c checksum: 3d7cce573111bfb32f35d97ea95d5016ac42bdc0f3ab5096e5c0fd799dd466ccc3cbfdbdeab4e7158923ae3e406f2002add01e5c9369f9c3e2623e41bc04b324
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-google-analytics@npm:6.6.0": "workbox-google-analytics@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-google-analytics@npm:6.6.0" resolution: "workbox-google-analytics@npm:7.0.0"
dependencies: dependencies:
workbox-background-sync: 6.6.0 workbox-background-sync: 7.0.0
workbox-core: 6.6.0 workbox-core: 7.0.0
workbox-routing: 6.6.0 workbox-routing: 7.0.0
workbox-strategies: 6.6.0 workbox-strategies: 7.0.0
checksum: 7b287da7517ae416aae8ea1494830bb517a29ab9786b2a8b8bf98971377b83715070e784399065ab101d4bba381ab0abbb8bd0962b3010bc01f54fdafb0b6702 checksum: defb12c3f4cf924aef8c647724c32d1100042447aed20128702815eba0f6d55ba6dde6557036dc13d68c0ab0570188757136bd453823fe25f2fa541cb18b8e0c
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-navigation-preload@npm:6.6.0": "workbox-navigation-preload@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-navigation-preload@npm:6.6.0" resolution: "workbox-navigation-preload@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: d254465648e45ec6b6d7c3471354336501901d3872622ea9ba1aa1f935d4d52941d0f92fa6c06e7363e10dbac4874d5d4bff7d99cbe094925046f562a37e88cc checksum: 329018003ce44812d37f1e168960abe34c7ac4b8cd1c8f86da172e73919fb51ba94a63db3b4024614066bf1ea38e1a89839eafd46eed9a13015dd4cf6fcd056c
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-precaching@npm:6.6.0": "workbox-precaching@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-precaching@npm:6.6.0" resolution: "workbox-precaching@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
workbox-routing: 6.6.0 workbox-routing: 7.0.0
workbox-strategies: 6.6.0 workbox-strategies: 7.0.0
checksum: 62e5ee2e40568a56d4131bba461623579f56b9bd273aa7d2805e43151057f413c2ef32fb3d007aff0a5ac3ad84d5feae87408284249a487a5d51c3775c46c816 checksum: 311b1c4a162e976e0a41e36e6a96eb64fea381eda538d8a9ae962d4f39c5ba420617753aac44e19105de19aef5242c9c68a09226d144ca3cf62738fc9f491f5d
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-range-requests@npm:6.6.0": "workbox-range-requests@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-range-requests@npm:6.6.0" resolution: "workbox-range-requests@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: a55d1a364b2155548695dc8f6f85baade196d7d1bec980bcdbda80236803b14167995a81b944cffe932a94c4d556466773121afe3661a6f0a13403cbe96d8d9f checksum: 04f6d7921a8a4a024b0bf0049a592ebedcdd285a52d1b8714e0a53efc936339dac39c3a5b5b6db9a3356b9f3ed1876024403260ec426cf9dc65e3b7ba5464914
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-recipes@npm:6.6.0": "workbox-recipes@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-recipes@npm:6.6.0" resolution: "workbox-recipes@npm:7.0.0"
dependencies: dependencies:
workbox-cacheable-response: 6.6.0 workbox-cacheable-response: 7.0.0
workbox-core: 6.6.0 workbox-core: 7.0.0
workbox-expiration: 6.6.0 workbox-expiration: 7.0.0
workbox-precaching: 6.6.0 workbox-precaching: 7.0.0
workbox-routing: 6.6.0 workbox-routing: 7.0.0
workbox-strategies: 6.6.0 workbox-strategies: 7.0.0
checksum: f2ecf38502260703e4b0dcef67e3ac26d615f2c90f6d863ca7308db52454f67934ba842fd577ee807d9f510f1a277fd66af7caf57d39e50a181d05dbb3e550a7 checksum: 253d50a315855917ca6683d6a3e910ac3c6f8915a8bcc80a7f15f277db7f48dc288c0ec2d9cdc64390bdd50446e66910246f384ce19f46688db97c715b323123
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-routing@npm:6.6.0": "workbox-routing@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-routing@npm:6.6.0" resolution: "workbox-routing@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: 7a70b836196eb67332d33a94c0b57859781fe869e81a9c95452d3f4f368d3199f8c3da632dbc10425fde902a1930cf8cfd83f6434ad2b586904ce68cd9f35c6d checksum: 9ea5b00fde5d90819e29ebf6d4aec3b84abec97854eb333c71b83548f1ba12b7f92d764a159f23cfa9e8164940e7b7136536fc0477784560cf2108d8dfe7f83b
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-strategies@npm:6.6.0": "workbox-strategies@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-strategies@npm:6.6.0" resolution: "workbox-strategies@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: 236232a77fb4a4847d1e9ae6c7c9bd9c6b9449209baab9d8d90f78240326a9c0f69551b408ebf9e76610d86da15563bf27439b7e885a7bac01dfd08047c0dd7b checksum: 4f20604e762fb43b32a16d60e014d14c0933300083c109a95251c06c65c25c9d78ab16bbe638b64435911d4a01ae5f7c28c7e78d611a122ee6453be2c42a87dc
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-streams@npm:6.6.0": "workbox-streams@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-streams@npm:6.6.0" resolution: "workbox-streams@npm:7.0.0"
dependencies: dependencies:
workbox-core: 6.6.0 workbox-core: 7.0.0
workbox-routing: 6.6.0 workbox-routing: 7.0.0
checksum: 64a295e48e44e3fa4743b5baec646fc9117428e7592033475e38c461e45c294910712f322c32417d354b22999902ef8035119e070e61e159e531d878d991fc33 checksum: e2975eb773bcf765c9cc8166936a9a2aaec2609fcddc178cbf6b2da54a113c4e2e62cbd257104861ea21b80c2a051936d62249f06d2414072405147f5181c0ef
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-sw@npm:6.6.0": "workbox-sw@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-sw@npm:6.6.0" resolution: "workbox-sw@npm:7.0.0"
checksum: bb5f8695de02f89c7955465dcbd568299915565008dc8a068c5d19c1347f75d417640b9f61590e16b169b703e77d02f8b1e10c4b241f74f43cfe76175bfa5fed checksum: f2673bc3f73ef5a54349eb7c4c63aefb7dfe6b6492947851ffa44079efdbfff07a26e68a0f7ea3801e03ab3fdc29acdc36cd315b9fbdb8a60963c7cb95f2de43
languageName: node languageName: node
linkType: hard linkType: hard
"workbox-window@npm:6.6.0": "workbox-window@npm:7.0.0":
version: 6.6.0 version: 7.0.0
resolution: "workbox-window@npm:6.6.0" resolution: "workbox-window@npm:7.0.0"
dependencies: dependencies:
"@types/trusted-types": ^2.0.2 "@types/trusted-types": ^2.0.2
workbox-core: 6.6.0 workbox-core: 7.0.0
checksum: bb1dd031c1525317ceffbdc3e4f502a70dce461fd6355146e1050c1090f3c640bf65edf42a5d2a3b91b4d0c313df32c1405d88bf701d44c0e3ebc492cd77fe14 checksum: 486ceaf2c04953cd73fe04760929a9c42818b57fffbbaca3fc9065cfd6bf3f5a571d2ea78db177e548a98041c8752faa360dda8eaf0f10b8638ef3eb1b696b13
languageName: node languageName: node
linkType: hard linkType: hard