From b2a55dd737da01501878c2aae9a12a8e5894f1e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 06:34:34 +0200 Subject: [PATCH 01/86] Update dependency @types/chromecast-caf-receiver to v6.0.16 (#21183) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 48258f74c1a2..d67d582af2a9 100644 --- a/package.json +++ b/package.json @@ -168,7 +168,7 @@ "@rollup/plugin-node-resolve": "15.2.3", "@rollup/plugin-replace": "5.0.7", "@types/babel__plugin-transform-runtime": "7.9.5", - "@types/chromecast-caf-receiver": "6.0.15", + "@types/chromecast-caf-receiver": "6.0.16", "@types/chromecast-caf-sender": "1.0.10", "@types/color-name": "1.1.4", "@types/glob": "8.1.0", diff --git a/yarn.lock b/yarn.lock index 97db273ab73c..88dd85f65445 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4036,10 +4036,10 @@ __metadata: languageName: node linkType: hard -"@types/chromecast-caf-receiver@npm:6.0.15": - version: 6.0.15 - resolution: "@types/chromecast-caf-receiver@npm:6.0.15" - checksum: 10/532c926d01b8173013c0aa96fad3b4e3e8b8f02c993b52cbc654b4263c7e396cc7a1497e00561428cccdbe6bb2014824577e7fdf44f1ebd63e68a3815500fd86 +"@types/chromecast-caf-receiver@npm:6.0.16": + version: 6.0.16 + resolution: "@types/chromecast-caf-receiver@npm:6.0.16" + checksum: 10/8d60a8fb0a7c4c90d8d8bb7fd55007ef0b2367f0a2129b83895bd857dfdc21296934cb57829248806093d92f66a2fc05475c616b7656ebc27c9498011e2f1f01 languageName: node linkType: hard @@ -8986,7 +8986,7 @@ __metadata: "@rollup/plugin-replace": "npm:5.0.7" "@thomasloven/round-slider": "npm:0.6.0" "@types/babel__plugin-transform-runtime": "npm:7.9.5" - "@types/chromecast-caf-receiver": "npm:6.0.15" + "@types/chromecast-caf-receiver": "npm:6.0.16" "@types/chromecast-caf-sender": "npm:1.0.10" "@types/color-name": "npm:1.1.4" "@types/glob": "npm:8.1.0" From 7aa005e0ce08419c55efd084aca367fc85163d5b Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Thu, 27 Jun 2024 03:40:09 -0700 Subject: [PATCH 02/86] Fix device integration filter for entityless devices (#21136) * Fix device integration filter for entityless devices * code review --- .../ha-selector/ha-selector-area.ts | 13 ++++++++- .../ha-selector/ha-selector-device.ts | 13 ++++++++- .../ha-selector/ha-selector-floor.ts | 13 ++++++++- src/data/device_registry.ts | 27 ++++++++++++++----- src/data/selector.ts | 4 +-- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/src/components/ha-selector/ha-selector-area.ts b/src/components/ha-selector/ha-selector-area.ts index 7690c387adfd..47230ff88d11 100644 --- a/src/components/ha-selector/ha-selector-area.ts +++ b/src/components/ha-selector/ha-selector-area.ts @@ -11,6 +11,7 @@ import { fetchEntitySourcesWithCache, } from "../../data/entity_sources"; import type { AreaSelector } from "../../data/selector"; +import { ConfigEntry, getConfigEntries } from "../../data/config_entries"; import { filterSelectorDevices, filterSelectorEntities, @@ -37,6 +38,8 @@ export class HaAreaSelector extends LitElement { @state() private _entitySources?: EntitySources; + @state() private _configEntries?: ConfigEntry[]; + private _deviceIntegrationLookup = memoizeOne(getDeviceIntegrationLookup); private _hasIntegration(selector: AreaSelector) { @@ -72,6 +75,12 @@ export class HaAreaSelector extends LitElement { this._entitySources = sources; }); } + if (!this._configEntries && this._hasIntegration(this.selector)) { + this._configEntries = []; + getConfigEntries(this.hass).then((entries) => { + this._configEntries = entries; + }); + } } protected render() { @@ -136,7 +145,9 @@ export class HaAreaSelector extends LitElement { const deviceIntegrations = this._entitySources ? this._deviceIntegrationLookup( this._entitySources, - Object.values(this.hass.entities) + Object.values(this.hass.entities), + Object.values(this.hass.devices), + this._configEntries ) : undefined; diff --git a/src/components/ha-selector/ha-selector-device.ts b/src/components/ha-selector/ha-selector-device.ts index b3ffebd4b667..0131b9b69854 100644 --- a/src/components/ha-selector/ha-selector-device.ts +++ b/src/components/ha-selector/ha-selector-device.ts @@ -11,6 +11,7 @@ import { fetchEntitySourcesWithCache, } from "../../data/entity_sources"; import type { DeviceSelector } from "../../data/selector"; +import { ConfigEntry, getConfigEntries } from "../../data/config_entries"; import { filterSelectorDevices, filterSelectorEntities, @@ -27,6 +28,8 @@ export class HaDeviceSelector extends LitElement { @state() private _entitySources?: EntitySources; + @state() private _configEntries?: ConfigEntry[]; + @property() public value?: any; @property() public label?: string; @@ -75,6 +78,12 @@ export class HaDeviceSelector extends LitElement { this._entitySources = sources; }); } + if (!this._configEntries && this._hasIntegration(this.selector)) { + this._configEntries = []; + getConfigEntries(this.hass).then((entries) => { + this._configEntries = entries; + }); + } } protected render() { @@ -123,7 +132,9 @@ export class HaDeviceSelector extends LitElement { const deviceIntegrations = this._entitySources ? this._deviceIntegrationLookup( this._entitySources, - Object.values(this.hass.entities) + Object.values(this.hass.entities), + Object.values(this.hass.devices), + this._configEntries ) : undefined; diff --git a/src/components/ha-selector/ha-selector-floor.ts b/src/components/ha-selector/ha-selector-floor.ts index eac63f414edb..6d4d0d29c834 100644 --- a/src/components/ha-selector/ha-selector-floor.ts +++ b/src/components/ha-selector/ha-selector-floor.ts @@ -11,6 +11,7 @@ import { fetchEntitySourcesWithCache, } from "../../data/entity_sources"; import type { FloorSelector } from "../../data/selector"; +import { ConfigEntry, getConfigEntries } from "../../data/config_entries"; import { filterSelectorDevices, filterSelectorEntities, @@ -37,6 +38,8 @@ export class HaFloorSelector extends LitElement { @state() private _entitySources?: EntitySources; + @state() private _configEntries?: ConfigEntry[]; + private _deviceIntegrationLookup = memoizeOne(getDeviceIntegrationLookup); private _hasIntegration(selector: FloorSelector) { @@ -72,6 +75,12 @@ export class HaFloorSelector extends LitElement { this._entitySources = sources; }); } + if (!this._configEntries && this._hasIntegration(this.selector)) { + this._configEntries = []; + getConfigEntries(this.hass).then((entries) => { + this._configEntries = entries; + }); + } } protected render() { @@ -136,7 +145,9 @@ export class HaFloorSelector extends LitElement { const deviceIntegrations = this._entitySources ? this._deviceIntegrationLookup( this._entitySources, - Object.values(this.hass.entities) + Object.values(this.hass.entities), + Object.values(this.hass.devices), + this._configEntries ) : undefined; diff --git a/src/data/device_registry.ts b/src/data/device_registry.ts index 80e9a5b05373..90bd894e8a62 100644 --- a/src/data/device_registry.ts +++ b/src/data/device_registry.ts @@ -5,6 +5,7 @@ import type { EntityRegistryDisplayEntry, EntityRegistryEntry, } from "./entity_registry"; +import { ConfigEntry } from "./config_entries"; import type { EntitySources } from "./entity_sources"; export { @@ -142,9 +143,11 @@ export const getDeviceEntityDisplayLookup = ( export const getDeviceIntegrationLookup = ( entitySources: EntitySources, - entities: EntityRegistryDisplayEntry[] | EntityRegistryEntry[] -): Record => { - const deviceIntegrations: Record = {}; + entities: EntityRegistryDisplayEntry[] | EntityRegistryEntry[], + devices?: DeviceRegistryEntry[], + configEntries?: ConfigEntry[] +): Record> => { + const deviceIntegrations: Record> = {}; for (const entity of entities) { const source = entitySources[entity.entity_id]; @@ -152,10 +155,22 @@ export const getDeviceIntegrationLookup = ( continue; } - if (!deviceIntegrations[entity.device_id!]) { - deviceIntegrations[entity.device_id!] = []; + deviceIntegrations[entity.device_id!] = + deviceIntegrations[entity.device_id!] || new Set(); + deviceIntegrations[entity.device_id!].add(source.domain); + } + // Lookup devices that have no entities + if (devices && configEntries) { + for (const device of devices) { + for (const config_entry_id of device.config_entries) { + const entry = configEntries.find((e) => e.entry_id === config_entry_id); + if (entry?.domain) { + deviceIntegrations[device.id] = + deviceIntegrations[device.id] || new Set(); + deviceIntegrations[device.id].add(entry.domain); + } + } } - deviceIntegrations[entity.device_id!].push(source.domain); } return deviceIntegrations; }; diff --git a/src/data/selector.ts b/src/data/selector.ts index bb90c792f48b..60b9e4973b1c 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -696,7 +696,7 @@ export const entityMeetsTargetSelector = ( export const filterSelectorDevices = ( filterDevice: DeviceSelectorFilter, device: DeviceRegistryEntry, - deviceIntegrationLookup?: Record | undefined + deviceIntegrationLookup?: Record> | undefined ): boolean => { const { manufacturer: filterManufacturer, @@ -713,7 +713,7 @@ export const filterSelectorDevices = ( } if (filterIntegration && deviceIntegrationLookup) { - if (!deviceIntegrationLookup?.[device.id]?.includes(filterIntegration)) { + if (!deviceIntegrationLookup?.[device.id]?.has(filterIntegration)) { return false; } } From 7603fa3aa86ea0c97655764606ba60f058c93bbe Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 27 Jun 2024 16:49:10 +0200 Subject: [PATCH 03/86] Don't set hass to undefined in lovelace cards. (#21189) * Wait for hass and config before building the card * Don't use setter * Improve code readability * Use hasupdated * Rename build to load --- src/panels/lovelace/cards/hui-card.ts | 90 ++++++++++--------- .../lovelace/cards/hui-conditional-card.ts | 1 + .../lovelace/cards/hui-entity-filter-card.ts | 1 + src/panels/lovelace/cards/hui-stack-card.ts | 3 +- .../card-editor/hui-card-layout-editor.ts | 1 + src/panels/lovelace/sections/hui-section.ts | 1 + src/panels/lovelace/views/hui-view.ts | 1 + 7 files changed, 55 insertions(+), 43 deletions(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index a892d4764dcf..6249acaba095 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -1,4 +1,4 @@ -import { PropertyValueMap, PropertyValues, ReactiveElement } from "lit"; +import { PropertyValues, ReactiveElement } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; import { MediaQueriesListener } from "../../../common/dom/media_query"; @@ -23,29 +23,20 @@ declare global { @customElement("hui-card") export class HuiCard extends ReactiveElement { - @property({ attribute: false }) public hass?: HomeAssistant; - @property({ type: Boolean }) public preview = false; @property({ type: Boolean }) public isPanel = false; - set config(config: LovelaceCardConfig | undefined) { - if (!config) return; - if (config.type !== this._config?.type) { - this._buildElement(config); - } else if (config !== this.config) { - this._element?.setConfig(config); - fireEvent(this, "card-updated"); - } - this._config = config; - } + @property({ attribute: false }) public config?: LovelaceCardConfig; - @property({ attribute: false }) - public get config() { - return this._config; - } + @property({ attribute: false }) public hass?: HomeAssistant; - private _config?: LovelaceCardConfig; + public load() { + if (!this.config) { + throw new Error("Cannot build card without config"); + } + this._loadElement(this.config); + } private _element?: LovelaceCard; @@ -90,57 +81,76 @@ export class HuiCard extends ReactiveElement { return this._element?.getLayoutOptions?.() ?? {}; } - private _createElement(config: LovelaceCardConfig) { - const element = createCardElement(config); - element.hass = this.hass; - element.preview = this.preview; + private _loadElement(config: LovelaceCardConfig) { + this._element = createCardElement(config); + if (this.hass) { + this._element.hass = this.hass; + } + this._element.preview = this.preview; // For backwards compatibility - (element as any).editMode = this.preview; + (this._element as any).editMode = this.preview; // Update element when the visibility of the card changes (e.g. conditional card or filter card) - element.addEventListener("card-visibility-changed", (ev: Event) => { + this._element.addEventListener("card-visibility-changed", (ev: Event) => { ev.stopPropagation(); this._updateVisibility(); }); - element.addEventListener( + this._element.addEventListener( "ll-upgrade", (ev: Event) => { ev.stopPropagation(); - element.hass = this.hass; - element.preview = this.preview; + if (this.hass) { + this._element!.hass = this.hass; + } fireEvent(this, "card-updated"); }, { once: true } ); - element.addEventListener( + this._element.addEventListener( "ll-rebuild", (ev: Event) => { ev.stopPropagation(); - this._buildElement(config); + this._loadElement(config); fireEvent(this, "card-updated"); }, { once: true } ); - return element; - } - - private _buildElement(config: LovelaceCardConfig) { - this._element = this._createElement(config); - while (this.lastChild) { this.removeChild(this.lastChild); } this._updateVisibility(); } + protected willUpdate(changedProps: PropertyValues): void { + super.willUpdate(changedProps); + + if (!this._element) { + this.load(); + } + } + protected update(changedProps: PropertyValues) { super.update(changedProps); if (this._element) { + if (changedProps.has("config") && this.hasUpdated) { + const oldConfig = changedProps.get("config"); + if (this.config !== oldConfig && this.config) { + const typeChanged = this.config?.type !== oldConfig?.type; + if (typeChanged) { + this._loadElement(this.config); + } else { + this._element?.setConfig(this.config); + fireEvent(this, "card-updated"); + } + } + } if (changedProps.has("hass")) { try { - this._element.hass = this.hass; + if (this.hass) { + this._element.hass = this.hass; + } } catch (e: any) { - this._buildElement(createErrorCardConfig(e.message, null)); + this._loadElement(createErrorCardConfig(e.message, null)); } } if (changedProps.has("preview")) { @@ -149,18 +159,14 @@ export class HuiCard extends ReactiveElement { // For backwards compatibility (this._element as any).editMode = this.preview; } catch (e: any) { - this._buildElement(createErrorCardConfig(e.message, null)); + this._loadElement(createErrorCardConfig(e.message, null)); } } if (changedProps.has("isPanel")) { this._element.isPanel = this.isPanel; } } - } - protected willUpdate( - changedProps: PropertyValueMap | Map - ): void { if (changedProps.has("hass") || changedProps.has("preview")) { this._updateVisibility(); } diff --git a/src/panels/lovelace/cards/hui-conditional-card.ts b/src/panels/lovelace/cards/hui-conditional-card.ts index 9a57b3e5a343..630a7494c9b0 100644 --- a/src/panels/lovelace/cards/hui-conditional-card.ts +++ b/src/panels/lovelace/cards/hui-conditional-card.ts @@ -41,6 +41,7 @@ class HuiConditionalCard extends HuiConditionalBase implements LovelaceCard { element.hass = this.hass; element.preview = this.preview; element.config = cardConfig; + element.load(); return element; } diff --git a/src/panels/lovelace/cards/hui-entity-filter-card.ts b/src/panels/lovelace/cards/hui-entity-filter-card.ts index ca8372b4a7c0..d79e88ad0daf 100644 --- a/src/panels/lovelace/cards/hui-entity-filter-card.ts +++ b/src/panels/lovelace/cards/hui-entity-filter-card.ts @@ -249,6 +249,7 @@ export class HuiEntityFilterCard element.hass = this.hass; element.preview = this.preview; element.config = cardConfig; + element.load(); return element; } } diff --git a/src/panels/lovelace/cards/hui-stack-card.ts b/src/panels/lovelace/cards/hui-stack-card.ts index a308e368eb59..93bc5c4931f9 100644 --- a/src/panels/lovelace/cards/hui-stack-card.ts +++ b/src/panels/lovelace/cards/hui-stack-card.ts @@ -56,7 +56,7 @@ export abstract class HuiStackCard card.hass = this.hass; }); } - if (changedProperties.has("editMode")) { + if (changedProperties.has("preview")) { this._cards.forEach((card) => { card.preview = this.preview; }); @@ -69,6 +69,7 @@ export abstract class HuiStackCard element.hass = this.hass; element.preview = this.preview; element.config = cardConfig; + element.load(); return element; } diff --git a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts index f9cda6e38bac..68c0487beee4 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts @@ -146,6 +146,7 @@ export class HuiCardLayoutEditor extends LitElement { this._defaultLayoutOptions = this._cardElement?.getElementLayoutOptions(); }); + this._cardElement.load(); this._defaultLayoutOptions = this._cardElement.getElementLayoutOptions(); } catch (err) { // eslint-disable-next-line no-console diff --git a/src/panels/lovelace/sections/hui-section.ts b/src/panels/lovelace/sections/hui-section.ts index b662072a13e4..07dc7a78f8af 100644 --- a/src/panels/lovelace/sections/hui-section.ts +++ b/src/panels/lovelace/sections/hui-section.ts @@ -64,6 +64,7 @@ export class HuiSection extends ReactiveElement { ev.stopPropagation(); this._cards = [...this._cards]; }); + element.load(); return element; } diff --git a/src/panels/lovelace/views/hui-view.ts b/src/panels/lovelace/views/hui-view.ts index 06df93b7465b..ea0bb5a89512 100644 --- a/src/panels/lovelace/views/hui-view.ts +++ b/src/panels/lovelace/views/hui-view.ts @@ -82,6 +82,7 @@ export class HUIView extends ReactiveElement { ev.stopPropagation(); this._cards = [...this._cards]; }); + element.load(); return element; } From 49c42fc757122a7a65a9b25a7f44f204460daac4 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 27 Jun 2024 17:15:33 +0200 Subject: [PATCH 04/86] Add support for native QR code scanner (#21187) --- src/components/ha-qr-scanner.ts | 161 ++++++++++++++---- .../zwave_js/dialog-zwave_js-add-node.ts | 21 +-- 2 files changed, 138 insertions(+), 44 deletions(-) diff --git a/src/components/ha-qr-scanner.ts b/src/components/ha-qr-scanner.ts index b65f9ba07aa1..b6fdef9e8984 100644 --- a/src/components/ha-qr-scanner.ts +++ b/src/components/ha-qr-scanner.ts @@ -1,72 +1,92 @@ import "@material/mwc-button/mwc-button"; -import "@material/mwc-list/mwc-list-item"; import { mdiCamera } from "@mdi/js"; -import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { css, html, LitElement, nothing, PropertyValues } from "lit"; import { customElement, property, query, state } from "lit/decorators"; import type QrScanner from "qr-scanner"; import { fireEvent } from "../common/dom/fire_event"; import { stopPropagation } from "../common/dom/stop_propagation"; import { LocalizeFunc } from "../common/translations/localize"; +import { addExternalBarCodeListener } from "../external_app/external_app_entrypoint"; +import { HomeAssistant } from "../types"; import "./ha-alert"; import "./ha-button-menu"; +import "./ha-list-item"; import "./ha-textfield"; import type { HaTextField } from "./ha-textfield"; @customElement("ha-qr-scanner") class HaQrScanner extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + @property({ attribute: false }) public localize!: LocalizeFunc; + @property() public description?: string; + + @property({ attribute: "alternative_option_label" }) + public alternativeOptionLabel?: string; + + @property() public error?: string; + @state() private _cameras?: QrScanner.Camera[]; - @state() private _error?: string; + @state() private _manual = false; private _qrScanner?: QrScanner; private _qrNotFoundCount = 0; - @query("video", true) private _video!: HTMLVideoElement; + private _removeListener?: UnsubscribeFunc; - @query("#canvas-container", true) private _canvasContainer!: HTMLDivElement; + @query("video", true) private _video?: HTMLVideoElement; + + @query("#canvas-container", true) private _canvasContainer?: HTMLDivElement; @query("ha-textfield") private _manualInput?: HaTextField; public disconnectedCallback(): void { super.disconnectedCallback(); this._qrNotFoundCount = 0; + if (this._nativeBarcodeScanner) { + this._closeExternalScanner(); + } if (this._qrScanner) { this._qrScanner.stop(); this._qrScanner.destroy(); this._qrScanner = undefined; } - while (this._canvasContainer.lastChild) { + while (this._canvasContainer?.lastChild) { this._canvasContainer.removeChild(this._canvasContainer.lastChild); } } public connectedCallback(): void { super.connectedCallback(); - if (this.hasUpdated && navigator.mediaDevices) { + if (this.hasUpdated) { this._loadQrScanner(); } } protected firstUpdated() { - if (navigator.mediaDevices) { - this._loadQrScanner(); - } + this._loadQrScanner(); } protected updated(changedProps: PropertyValues) { - if (changedProps.has("_error") && this._error) { - fireEvent(this, "qr-code-error", { message: this._error }); + if (changedProps.has("error") && this.error) { + alert(`error: ${this.error}`); + this._notifyExternalScanner(this.error); } } - protected render(): TemplateResult { - return html`${this._error - ? html`${this._error}` + protected render() { + if (this._nativeBarcodeScanner && !this._manual) { + return nothing; + } + + return html`${this.error + ? html`${this.error}` : ""} - ${navigator.mediaDevices + ${navigator.mediaDevices && !this._manual ? html`
${this._cameras && this._cameras.length > 1 @@ -80,21 +100,26 @@ class HaQrScanner extends LitElement { > ${this._cameras!.map( (camera) => html` - ${camera.label} + ${camera.label} + ` )} ` - : ""} + : nothing}
` - : html` - ${!window.isSecureContext - ? this.localize("ui.components.qr-scanner.only_https_supported") - : this.localize("ui.components.qr-scanner.not_supported")} - + : html`${this._manual + ? nothing + : html` + ${!window.isSecureContext + ? this.localize( + "ui.components.qr-scanner.only_https_supported" + ) + : this.localize("ui.components.qr-scanner.not_supported")} + `}

${this.localize("ui.components.qr-scanner.manual_input")}

- ${this.localize("ui.common.submit")} + + ${this.localize("ui.common.submit")} +
`}`; } + private get _nativeBarcodeScanner(): boolean { + return Boolean(this.hass.auth.external?.config.hasBarCodeScanner); + } + private async _loadQrScanner() { + if (this._nativeBarcodeScanner) { + this._openExternalScanner(); + return; + } + if (!navigator.mediaDevices) { + return; + } const QrScanner = (await import("qr-scanner")).default; if (!(await QrScanner.hasCamera())) { - this._error = "No camera found"; + this._reportError("No camera found"); return; } QrScanner.WORKER_PATH = "/static/js/qr-scanner-worker.min.js"; this._listCameras(QrScanner); this._qrScanner = new QrScanner( - this._video, + this._video!, this._qrCodeScanned, this._qrCodeError ); // @ts-ignore const canvas = this._qrScanner.$canvas; - this._canvasContainer.appendChild(canvas); + this._canvasContainer!.appendChild(canvas); canvas.style.display = "block"; try { await this._qrScanner.start(); } catch (err: any) { - this._error = err; + this._reportError(err); } } @@ -140,16 +176,16 @@ class HaQrScanner extends LitElement { if (err === "No QR code found") { this._qrNotFoundCount++; if (this._qrNotFoundCount === 250) { - this._error = err; + this._reportError(err); } return; } - this._error = err.message || err; + this._reportError(err.message || err); // eslint-disable-next-line no-console console.log(err); }; - private _qrCodeScanned = async (qrCodeString: string): Promise => { + private _qrCodeScanned = (qrCodeString: string): void => { this._qrNotFoundCount = 0; fireEvent(this, "qr-code-scanned", { value: qrCodeString }); }; @@ -175,6 +211,62 @@ class HaQrScanner extends LitElement { this._qrScanner?.setCamera((ev.target as any).value); } + private _openExternalScanner() { + this._removeListener = addExternalBarCodeListener((msg) => { + if (msg.command === "bar_code/scan_result") { + if (msg.payload.format !== "qr_code") { + this._notifyExternalScanner( + `Wrong barcode scanned! ${msg.payload.format}: ${msg.payload.rawValue}, we need a QR code.` + ); + } else { + this._qrCodeScanned(msg.payload.rawValue); + } + } else if (msg.command === "bar_code/aborted") { + this._closeExternalScanner(); + if (msg.payload.reason === "canceled") { + fireEvent(this, "qr-code-closed"); + } else { + this._manual = true; + } + } + return true; + }); + this.hass.auth.external!.fireMessage({ + type: "bar_code/scan", + payload: { + title: this.title || "Scan QR code", + description: this.description || "Scan a barcode.", + alternative_option_label: + this.alternativeOptionLabel || "Click to manually enter the barcode", + }, + }); + } + + private _closeExternalScanner() { + this._removeListener?.(); + this._removeListener = undefined; + this.hass.auth.external!.fireMessage({ + type: "bar_code/close", + }); + } + + private _notifyExternalScanner(message: string) { + if (!this.hass.auth.external) { + return; + } + this.hass.auth.external.fireMessage({ + type: "bar_code/notify", + payload: { + message, + }, + }); + this.error = undefined; + } + + private _reportError(message: string) { + fireEvent(this, "qr-code-error", { message }); + } + static styles = css` canvas { width: 100%; @@ -210,6 +302,7 @@ declare global { interface HASSDomEvents { "qr-code-scanned": { value: string }; "qr-code-error": { message: string }; + "qr-code-closed": undefined; } interface HTMLElementTagNameMap { diff --git a/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts b/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts index 29c982bbfe7f..530073bb44b2 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-add-node.ts @@ -205,14 +205,13 @@ class DialogZWaveJSAddNode extends LitElement { Search device ` : this._status === "qr_scan" - ? html`${this._error - ? html`${this._error}` - : ""} - ${this._supportsSmartStart - ? html`
+ ? html`

${this.hass.localize( "ui.panel.config.zwave_js.add_node.qr_code" @@ -498,9 +497,7 @@ class DialogZWaveJSAddNode extends LitElement { ` : ""} ${this.hass.localize( @@ -599,6 +596,10 @@ class DialogZWaveJSAddNode extends LitElement { this._handleQrCodeScanned(ev.detail.value); } + private _qrCodeError(ev: CustomEvent): void { + this._error = ev.detail.message; + } + private async _handleQrCodeScanned(qrCodeString: string): Promise { this._error = undefined; if (this._status !== "qr_scan" || this._qrProcessing) { From 5273293cd6203ab839d22298cdb7d0c9d9982d6f Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 27 Jun 2024 18:46:39 +0200 Subject: [PATCH 05/86] Add last updated property to tile card state content (#21191) --- src/panels/lovelace/cards/hui-tile-card.ts | 8 ++++++++ .../editor/config-elements/hui-tile-card-editor.ts | 6 ++++++ src/translations/en.json | 3 ++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 634b52ca1478..fa8c2cc6d067 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -238,6 +238,14 @@ export class HuiTileCard extends LitElement implements LovelaceCard { > `; } + if (content === "last-updated") { + return html` + + `; + } if (content === "last_triggered") { return html` !HIDDEN_ATTRIBUTES.includes(a)) .map((attribute) => ({ diff --git a/src/translations/en.json b/src/translations/en.json index 822152b2214e..ffd25ca6bba2 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5987,7 +5987,8 @@ "state_content": "State content", "state_content_options": { "state": "State", - "last-changed": "Last changed" + "last-changed": "Last changed", + "last-updated": "Last updated" } }, "vertical-stack": { From fd64d17d88ae34283ce97113527ca2a8a90a0cc7 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 27 Jun 2024 19:30:48 +0200 Subject: [PATCH 06/86] Bumped version to 20240627.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 28a3be951139..48b7f8fcea7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240626.2" +version = "20240627.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From da2865d8bf0083282ff7f92caff822283032b81c Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 27 Jun 2024 19:31:55 +0200 Subject: [PATCH 07/86] Fix size of cards inside stack cards (#21190) * Fix size of cards inside stack cards * Apply style everywhere * Fix stack * Fix grid stack * Set block only for square --- src/panels/lovelace/cards/hui-card.ts | 3 +++ src/panels/lovelace/cards/hui-grid-card.ts | 1 + src/panels/lovelace/cards/hui-horizontal-stack-card.ts | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index 6249acaba095..b4ca36b94e86 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -43,6 +43,9 @@ export class HuiCard extends ReactiveElement { private _listeners: MediaQueriesListener[] = []; protected createRenderRoot() { + const style = document.createElement("style"); + style.textContent = `hui-card { display: contents }`; + this.append(style); return this; } diff --git a/src/panels/lovelace/cards/hui-grid-card.ts b/src/panels/lovelace/cards/hui-grid-card.ts index 97b336c529cb..0838db77d9ba 100644 --- a/src/panels/lovelace/cards/hui-grid-card.ts +++ b/src/panels/lovelace/cards/hui-grid-card.ts @@ -92,6 +92,7 @@ class HuiGridCard extends HuiStackCard { } :host([square]) #root > *:not([hidden]) { + display: block; grid-row: 1 / 1; grid-column: 1 / 1; } diff --git a/src/panels/lovelace/cards/hui-horizontal-stack-card.ts b/src/panels/lovelace/cards/hui-horizontal-stack-card.ts index 502e54db4dd7..4e867e5b0e2f 100644 --- a/src/panels/lovelace/cards/hui-horizontal-stack-card.ts +++ b/src/panels/lovelace/cards/hui-horizontal-stack-card.ts @@ -30,7 +30,7 @@ export class HuiHorizontalStackCard extends HuiStackCard { height: 100%; gap: var(--horizontal-stack-card-gap, var(--stack-card-gap, 8px)); } - #root > * { + #root > hui-card > * { flex: 1 1 0; min-width: 0; } From df650383412563670bbd56efac0337017a6dea59 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:55:43 -0400 Subject: [PATCH 08/86] Update dependency mocha to v10.5.0 (#21194) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 31 ++++++------------------------- 2 files changed, 7 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index d67d582af2a9..afb8f552d6b5 100644 --- a/package.json +++ b/package.json @@ -220,7 +220,7 @@ "lodash.template": "4.5.0", "magic-string": "0.30.10", "map-stream": "0.0.7", - "mocha": "10.4.0", + "mocha": "10.5.0", "object-hash": "3.0.0", "open": "10.1.0", "pinst": "3.0.0", diff --git a/yarn.lock b/yarn.lock index 88dd85f65445..55b78f9b5d12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6274,25 +6274,6 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:3.5.3": - version: 3.5.3 - resolution: "chokidar@npm:3.5.3" - dependencies: - anymatch: "npm:~3.1.2" - braces: "npm:~3.0.2" - fsevents: "npm:~2.3.2" - glob-parent: "npm:~5.1.2" - is-binary-path: "npm:~2.1.0" - is-glob: "npm:~4.0.1" - normalize-path: "npm:~3.0.0" - readdirp: "npm:~3.6.0" - dependenciesMeta: - fsevents: - optional: true - checksum: 10/863e3ff78ee7a4a24513d2a416856e84c8e4f5e60efbe03e8ab791af1a183f569b62fc6f6b8044e2804966cb81277ddbbc1dc374fba3265bd609ea8efd62f5b3 - languageName: node - linkType: hard - "chokidar@npm:^3.4.3, chokidar@npm:^3.5.3, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" @@ -9070,7 +9051,7 @@ __metadata: map-stream: "npm:0.0.7" marked: "npm:12.0.2" memoize-one: "npm:6.0.0" - mocha: "npm:10.4.0" + mocha: "npm:10.5.0" node-vibrant: "npm:3.2.1-alpha.1" object-hash: "npm:3.0.0" open: "npm:10.1.0" @@ -11169,13 +11150,13 @@ __metadata: languageName: node linkType: hard -"mocha@npm:10.4.0": - version: 10.4.0 - resolution: "mocha@npm:10.4.0" +"mocha@npm:10.5.0": + version: 10.5.0 + resolution: "mocha@npm:10.5.0" dependencies: ansi-colors: "npm:4.1.1" browser-stdout: "npm:1.3.1" - chokidar: "npm:3.5.3" + chokidar: "npm:^3.5.3" debug: "npm:4.3.4" diff: "npm:5.0.0" escape-string-regexp: "npm:4.0.0" @@ -11196,7 +11177,7 @@ __metadata: bin: _mocha: bin/_mocha mocha: bin/mocha.js - checksum: 10/0147b2a86c8a3b134b3bda949006aa5f2b08db606b9394e38eb3fa0d97dd2f54f06eb4afb270d4ae08aa6fb7674282737ed556b9a8bc407f9b8488380852eca4 + checksum: 10/64f5aace4a5b7eed23d8bcfaf1eacdaafbffdc5e3ee977ecb32ace8f91733b1520b8342ce02d7101e8d7b8bd4008e055e4f4f63a0e4a3da81baf0e41566a07ab languageName: node linkType: hard From 3b15d2650001ac8ad0d49de77d636cb988f0c5d4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 21:57:31 +0200 Subject: [PATCH 09/86] Update typescript-eslint monorepo to v7.14.1 (#21195) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index afb8f552d6b5..0bd3b356f63f 100644 --- a/package.json +++ b/package.json @@ -185,8 +185,8 @@ "@types/tar": "6.1.13", "@types/ua-parser-js": "0.7.39", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", + "@typescript-eslint/eslint-plugin": "7.14.1", + "@typescript-eslint/parser": "7.14.1", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.3", diff --git a/yarn.lock b/yarn.lock index 55b78f9b5d12..766c2e0fd17a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4575,15 +4575,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.13.1" +"@typescript-eslint/eslint-plugin@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/eslint-plugin@npm:7.14.1" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/type-utils": "npm:7.13.1" - "@typescript-eslint/utils": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" + "@typescript-eslint/scope-manager": "npm:7.14.1" + "@typescript-eslint/type-utils": "npm:7.14.1" + "@typescript-eslint/utils": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -4594,44 +4594,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/37fff8c302f93f5f88fc8d6e6c9151a7d1873a3c8af6e15547d737bdc066a6b8887fa54bcd8eb4e4ca6a11494051801c8e957eea8d8b4d4b078a477df6f10692 + checksum: 10/48c815dbb92399965483c93b27816fad576c3b3227b59eebfe5525e24d07b39ec8b0c7459de83865c8d61c818696519f50b229714dd3ed705d5b35973bfcc781 languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/parser@npm:7.13.1" +"@typescript-eslint/parser@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/parser@npm:7.14.1" dependencies: - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/typescript-estree": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" + "@typescript-eslint/scope-manager": "npm:7.14.1" + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/typescript-estree": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/a76cfcf97c289110403b50a377e925f29cda74340de0526f68b0c34199ce643d9c31803e492217e0f3df28361d3019ced4806f974ea70529c559b26b70cec7ef + checksum: 10/f521462a7005cab5e4923937dcf36713d9438ded175b53332ae469d91cc9eb18cb3a23768b3c52063464280baae83f6b66db28cebb2e262d6d869d1a898b23f3 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/scope-manager@npm:7.13.1" +"@typescript-eslint/scope-manager@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/scope-manager@npm:7.14.1" dependencies: - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" - checksum: 10/fea9ab8f72ace1dd55d835037efe038c70021275581855820cdb7fc4b01e8afb51723856537adff1fdb0ea3899c1f8b593fd75c34b5087ca2ef2f7c72e610050 + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" + checksum: 10/600a7beb96f5b96f675125285137339c2438b5b26db203a66eef52dd409e8c0db0dafb22c94547dfb963f8efdf63b0fb59e05655e2dcf84d54624863365a59e7 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/type-utils@npm:7.13.1" +"@typescript-eslint/type-utils@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/type-utils@npm:7.14.1" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.13.1" - "@typescript-eslint/utils": "npm:7.13.1" + "@typescript-eslint/typescript-estree": "npm:7.14.1" + "@typescript-eslint/utils": "npm:7.14.1" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -4639,23 +4639,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/cc03cd44e125933511ea657e386c5cf427eb6a386fdb110cba0858598195fb4f8c71173b00b187f388a6713e16b919a2037a86e0be10f4c40c18bcbdbe06d5de + checksum: 10/75c279948a7e7e546d692e85a0b48fc3b648ffee1773feb7ff199aba1b0847a9a16c432b133aa72d26e645627403852b7dd24829f9b3badd6d4711c4cc38e9e4 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/types@npm:7.13.1" - checksum: 10/006a5518608184c1d017b27fb4f66ce28bc75f89e2380ac42969ebdf0dc726af1cfcdf4ba36ce2858e9f6907d6f4295d3453859d7e9a35bc7855d4ebc900955d +"@typescript-eslint/types@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/types@npm:7.14.1" + checksum: 10/608057582bb195bd746a7bfb7c04dac4be1d4602b8fa681b2d1d50b564362b681dc2ca293b13cc4c7acc454f3a09f1ea2580415347efb7853e5df8ba34b7acdb languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.13.1" +"@typescript-eslint/typescript-estree@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/typescript-estree@npm:7.14.1" dependencies: - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/visitor-keys": "npm:7.13.1" + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/visitor-keys": "npm:7.14.1" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -4665,31 +4665,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/5c68b5faa962e5f984067aa91770486af817858d2fa35b54a44fa4d5c0c612ba23b52b191d8051d9e4439e5425251e32861c81239e9400a29de057f8360537fb + checksum: 10/f75b956f7981712d3f85498f9d9fcc2243d79d6fe71b24bc688a7c43d2a4248f73ecfb78f9d58501fde87fc44b02e26c46f9ea2ae51eb8450db79ca169f91ef9 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/utils@npm:7.13.1" +"@typescript-eslint/utils@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/utils@npm:7.14.1" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.13.1" - "@typescript-eslint/types": "npm:7.13.1" - "@typescript-eslint/typescript-estree": "npm:7.13.1" + "@typescript-eslint/scope-manager": "npm:7.14.1" + "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/typescript-estree": "npm:7.14.1" peerDependencies: eslint: ^8.56.0 - checksum: 10/e1bc916dcb567c6b35819f635a84561e015f40b28d650b987f74c79b013ec43fb4f5b61199d4039fcdf9480281f945f622650cba2e68739600822da05808a706 + checksum: 10/1ef74214ca84e32f151364512a51e82b7da5590dee03d0de0e1abcf18009e569f9a0638506cf03bd4a844af634b4935458e334b7b2459e9a50a67aba7d6228c7 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.13.1": - version: 7.13.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.13.1" +"@typescript-eslint/visitor-keys@npm:7.14.1": + version: 7.14.1 + resolution: "@typescript-eslint/visitor-keys@npm:7.14.1" dependencies: - "@typescript-eslint/types": "npm:7.13.1" + "@typescript-eslint/types": "npm:7.14.1" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/811e9642851359b5197d45a9878143c4c608aaef887a20c26f57f8b012ce9e316d232b82a311bdd52a2af0c8b8da5d4bd9401ce565fc7bdb43cd44556e76d225 + checksum: 10/42246f33cb3f9185c0b467c9a534e34a674e4fc08ba982a03aaa77dc1e569e916f1fca9ce9cd14c4df91f416e6e917bff51f98b8d8ca26ec5f67c253e8646bde languageName: node linkType: hard @@ -8984,8 +8984,8 @@ __metadata: "@types/tar": "npm:6.1.13" "@types/ua-parser-js": "npm:0.7.39" "@types/webspeechapi": "npm:0.0.29" - "@typescript-eslint/eslint-plugin": "npm:7.13.1" - "@typescript-eslint/parser": "npm:7.13.1" + "@typescript-eslint/eslint-plugin": "npm:7.14.1" + "@typescript-eslint/parser": "npm:7.14.1" "@vaadin/combo-box": "npm:24.4.0" "@vaadin/vaadin-themable-mixin": "npm:24.4.0" "@vibrant/color": "npm:3.2.1-alpha.1" From 11d832c2ea2e20c4f997c5b09109f42e186cf370 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 23:00:52 -0400 Subject: [PATCH 10/86] Update dependency @bundle-stats/plugin-webpack-filter to v4.13.3 (#21197) --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0bd3b356f63f..2f1c2b10a773 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "@babel/plugin-transform-runtime": "7.24.7", "@babel/preset-env": "7.24.7", "@babel/preset-typescript": "7.24.7", - "@bundle-stats/plugin-webpack-filter": "4.13.2", + "@bundle-stats/plugin-webpack-filter": "4.13.3", "@koa/cors": "5.0.0", "@lokalise/node-api": "12.5.0", "@octokit/auth-oauth-device": "7.1.1", diff --git a/yarn.lock b/yarn.lock index 766c2e0fd17a..f26b8a6153bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1460,12 +1460,12 @@ __metadata: languageName: node linkType: hard -"@bundle-stats/plugin-webpack-filter@npm:4.13.2": - version: 4.13.2 - resolution: "@bundle-stats/plugin-webpack-filter@npm:4.13.2" +"@bundle-stats/plugin-webpack-filter@npm:4.13.3": + version: 4.13.3 + resolution: "@bundle-stats/plugin-webpack-filter@npm:4.13.3" peerDependencies: core-js: ^3.0.0 - checksum: 10/92c2e3c05998762613e3fbed465bceb133c94b4182db502c42e6cbfc2016867101f72adcecb5d1791f73ebcb44039e0c8046737dfb1f49bbad7b1b617599184c + checksum: 10/5de079362fe592d29a32598646164aeea329e81697b51356d2f760932bf95f0ca2e5ac8c45324e2850f8450c12e8a8ec95d851fd15ab25522832ebd3e64aacfe languageName: node linkType: hard @@ -8893,7 +8893,7 @@ __metadata: "@babel/preset-typescript": "npm:7.24.7" "@babel/runtime": "npm:7.24.7" "@braintree/sanitize-url": "npm:7.0.3" - "@bundle-stats/plugin-webpack-filter": "npm:4.13.2" + "@bundle-stats/plugin-webpack-filter": "npm:4.13.3" "@codemirror/autocomplete": "npm:6.16.3" "@codemirror/commands": "npm:6.6.0" "@codemirror/language": "npm:6.10.2" From dcd4c39978083f01cab474a0a13107d2e157b116 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:44:30 +0200 Subject: [PATCH 11/86] Fix add application credential keyboard handling (#21205) double primaryAction --- .../dialog-add-application-credential.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/panels/config/application_credentials/dialog-add-application-credential.ts b/src/panels/config/application_credentials/dialog-add-application-credential.ts index d620f499c1a4..e30e494b4730 100644 --- a/src/panels/config/application_credentials/dialog-add-application-credential.ts +++ b/src/panels/config/application_credentials/dialog-add-application-credential.ts @@ -1,4 +1,3 @@ -import "@material/mwc-button"; import "@material/mwc-list/mwc-list-item"; import { mdiOpenInNew } from "@mdi/js"; import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; @@ -11,6 +10,7 @@ import "../../../components/ha-combo-box"; import { createCloseHeading } from "../../../components/ha-dialog"; import "../../../components/ha-markdown"; import "../../../components/ha-textfield"; +import "../../../components/ha-button"; import { ApplicationCredential, ApplicationCredentialsConfig, @@ -231,10 +231,10 @@ export class DialogAddApplicationCredential extends LitElement {

` : html` - + ${this.hass.localize("ui.common.cancel")} - - + + `} `; From cbc95a5e2d1a2c0ce5b3a5626e6ecbfebf91c6c6 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:44:57 +0200 Subject: [PATCH 12/86] Fix icon header labels in Automations, Scene and Script tables (#21214) Change icon header labels --- src/panels/config/automation/ha-automation-picker.ts | 2 +- src/panels/config/scene/ha-scene-dashboard.ts | 2 +- src/panels/config/script/ha-script-picker.ts | 2 +- src/translations/en.json | 9 ++++++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index 67da2d580dc6..3c0f0d10df8c 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -265,7 +265,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { const columns: DataTableColumnContainer = { icon: { title: "", - label: localize("ui.panel.config.automation.picker.headers.state"), + label: localize("ui.panel.config.automation.picker.headers.icon"), type: "icon", moveable: false, showNarrow: true, diff --git a/src/panels/config/scene/ha-scene-dashboard.ts b/src/panels/config/scene/ha-scene-dashboard.ts index 0f47b0644c07..b889dc1094de 100644 --- a/src/panels/config/scene/ha-scene-dashboard.ts +++ b/src/panels/config/scene/ha-scene-dashboard.ts @@ -243,7 +243,7 @@ class HaSceneDashboard extends SubscribeMixin(LitElement) { const columns: DataTableColumnContainer = { icon: { title: "", - label: localize("ui.panel.config.scene.picker.headers.state"), + label: localize("ui.panel.config.scene.picker.headers.icon"), moveable: false, showNarrow: true, type: "icon", diff --git a/src/panels/config/script/ha-script-picker.ts b/src/panels/config/script/ha-script-picker.ts index f89790c886ce..d35aed5f90d6 100644 --- a/src/panels/config/script/ha-script-picker.ts +++ b/src/panels/config/script/ha-script-picker.ts @@ -252,7 +252,7 @@ class HaScriptPicker extends SubscribeMixin(LitElement) { title: "", showNarrow: true, moveable: false, - label: localize("ui.panel.config.script.picker.headers.state"), + label: localize("ui.panel.config.script.picker.headers.icon"), type: "icon", template: (script) => html` Date: Fri, 28 Jun 2024 14:45:33 +0200 Subject: [PATCH 13/86] Add storage variables for application credentials config table (#21215) Implement storage variables --- .../ha-config-application-credentials.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/panels/config/application_credentials/ha-config-application-credentials.ts b/src/panels/config/application_credentials/ha-config-application-credentials.ts index 644759e148da..7c5fa5ae93dc 100644 --- a/src/panels/config/application_credentials/ha-config-application-credentials.ts +++ b/src/panels/config/application_credentials/ha-config-application-credentials.ts @@ -7,6 +7,7 @@ import { LocalizeFunc } from "../../../common/translations/localize"; import { DataTableColumnContainer, SelectionChangedEvent, + SortingChangedEvent, } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-fab"; import "../../../components/ha-help-tooltip"; @@ -27,6 +28,7 @@ import type { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage- import { HomeAssistant, Route } from "../../../types"; import { configSections } from "../ha-panel-config"; import { showAddApplicationCredentialDialog } from "./show-dialog-add-application-credential"; +import { storage } from "../../../common/decorators/storage"; @customElement("ha-config-application-credentials") export class HaConfigApplicationCredentials extends LitElement { @@ -45,6 +47,27 @@ export class HaConfigApplicationCredentials extends LitElement { @query("hass-tabs-subpage-data-table", true) private _dataTable!: HaTabsSubpageDataTable; + @storage({ + key: "application-credentials-table-sort", + state: false, + subscribe: false, + }) + private _activeSorting?: SortingChangedEvent; + + @storage({ + key: "application-credentials-table-column-order", + state: false, + subscribe: false, + }) + private _activeColumnOrder?: string[]; + + @storage({ + key: "application-credentials-table-hidden-columns", + state: false, + subscribe: false, + }) + private _activeHiddenColumns?: string[]; + private _columns = memoizeOne( (narrow: boolean, localize: LocalizeFunc): DataTableColumnContainer => { const columns: DataTableColumnContainer = { @@ -128,6 +151,11 @@ export class HaConfigApplicationCredentials extends LitElement { selectable .selected=${this._selected.length} @selection-changed=${this._handleSelectionChanged} + .initialSorting=${this._activeSorting} + .columnOrder=${this._activeColumnOrder} + .hiddenColumns=${this._activeHiddenColumns} + @columns-changed=${this._handleColumnsChanged} + @sorting-changed=${this._handleSortingChanged} >
${!this.narrow @@ -252,6 +280,15 @@ export class HaConfigApplicationCredentials extends LitElement { }); } + private _handleSortingChanged(ev: CustomEvent) { + this._activeSorting = ev.detail; + } + + private _handleColumnsChanged(ev: CustomEvent) { + this._activeColumnOrder = ev.detail.columnOrder; + this._activeHiddenColumns = ev.detail.hiddenColumns; + } + static get styles(): CSSResultGroup { return css` .table-header { From d33cf4f199d53daf8793bad665edc6ad505b3be0 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:46:27 +0200 Subject: [PATCH 14/86] Reload application credentials after single delete (#21216) Reload application credentials after delete --- .../ha-config-application-credentials.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/panels/config/application_credentials/ha-config-application-credentials.ts b/src/panels/config/application_credentials/ha-config-application-credentials.ts index 7c5fa5ae93dc..ad12b59791f4 100644 --- a/src/panels/config/application_credentials/ha-config-application-credentials.ts +++ b/src/panels/config/application_credentials/ha-config-application-credentials.ts @@ -107,7 +107,7 @@ export class HaConfigApplicationCredentials extends LitElement { path: mdiDelete, warning: true, label: this.hass.localize("ui.common.delete"), - action: () => this._removeCredential(credential), + action: () => this._deleteCredential(credential), }, ]} > @@ -160,7 +160,7 @@ export class HaConfigApplicationCredentials extends LitElement {
${!this.narrow ? html` - ${this.hass.localize( "ui.panel.config.application_credentials.picker.remove_selected.button" )} @@ -202,7 +202,7 @@ export class HaConfigApplicationCredentials extends LitElement { this._selected = ev.detail.value; } - private _removeCredential = async (credential) => { + private _deleteCredential = async (credential) => { const confirm = await showConfirmationDialog(this, { title: this.hass.localize( `ui.panel.config.application_credentials.picker.remove.confirm_title` @@ -218,9 +218,10 @@ export class HaConfigApplicationCredentials extends LitElement { return; } await deleteApplicationCredential(this.hass, credential.id); + await this._fetchApplicationCredentials(); }; - private _removeSelected() { + private _deleteSelected() { showConfirmationDialog(this, { title: this.hass.localize( `ui.panel.config.application_credentials.picker.remove_selected.confirm_title`, @@ -252,7 +253,7 @@ export class HaConfigApplicationCredentials extends LitElement { return; } this._dataTable.clearSelection(); - this._fetchApplicationCredentials(); + await this._fetchApplicationCredentials(); }, }); } From 85865af0c31cc6d41637424b2ace203dab9db127 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 28 Jun 2024 20:17:57 +0200 Subject: [PATCH 15/86] Fix update config mecanism in hui-card (#21218) --- src/panels/lovelace/cards/hui-card.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index b4ca36b94e86..d47bffc1f5a5 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -31,6 +31,8 @@ export class HuiCard extends ReactiveElement { @property({ attribute: false }) public hass?: HomeAssistant; + private _elementConfig?: LovelaceCardConfig; + public load() { if (!this.config) { throw new Error("Cannot build card without config"); @@ -84,8 +86,18 @@ export class HuiCard extends ReactiveElement { return this._element?.getLayoutOptions?.() ?? {}; } + private _updateElement(config: LovelaceCardConfig) { + if (!this._element) { + return; + } + this._element.setConfig(config); + this._elementConfig = config; + fireEvent(this, "card-updated"); + } + private _loadElement(config: LovelaceCardConfig) { this._element = createCardElement(config); + this._elementConfig = config; if (this.hass) { this._element.hass = this.hass; } @@ -135,15 +147,14 @@ export class HuiCard extends ReactiveElement { super.update(changedProps); if (this._element) { - if (changedProps.has("config") && this.hasUpdated) { - const oldConfig = changedProps.get("config"); - if (this.config !== oldConfig && this.config) { - const typeChanged = this.config?.type !== oldConfig?.type; + if (changedProps.has("config")) { + const elementConfig = this._elementConfig; + if (this.config !== elementConfig && this.config) { + const typeChanged = this.config?.type !== elementConfig?.type; if (typeChanged) { this._loadElement(this.config); } else { - this._element?.setConfig(this.config); - fireEvent(this, "card-updated"); + this._updateElement(this.config); } } } From beec720b9bba693f14896f94baac18c921506dab Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 28 Jun 2024 20:56:01 +0200 Subject: [PATCH 16/86] Use display contents in horizontal stack only (#21217) --- src/panels/lovelace/cards/hui-card.ts | 3 --- src/panels/lovelace/cards/hui-horizontal-stack-card.ts | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index d47bffc1f5a5..54b079d1b7fb 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -45,9 +45,6 @@ export class HuiCard extends ReactiveElement { private _listeners: MediaQueriesListener[] = []; protected createRenderRoot() { - const style = document.createElement("style"); - style.textContent = `hui-card { display: contents }`; - this.append(style); return this; } diff --git a/src/panels/lovelace/cards/hui-horizontal-stack-card.ts b/src/panels/lovelace/cards/hui-horizontal-stack-card.ts index 4e867e5b0e2f..e224953ade0f 100644 --- a/src/panels/lovelace/cards/hui-horizontal-stack-card.ts +++ b/src/panels/lovelace/cards/hui-horizontal-stack-card.ts @@ -30,6 +30,9 @@ export class HuiHorizontalStackCard extends HuiStackCard { height: 100%; gap: var(--horizontal-stack-card-gap, var(--stack-card-gap, 8px)); } + #root > hui-card { + display: contents; + } #root > hui-card > * { flex: 1 1 0; min-width: 0; From 18a6f8d64db32dafbe8500079c09d431d6a5dc09 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 28 Jun 2024 21:08:51 +0200 Subject: [PATCH 17/86] Add credential to user after creation (#21221) --- src/panels/config/users/dialog-add-user.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/panels/config/users/dialog-add-user.ts b/src/panels/config/users/dialog-add-user.ts index 04b336c69768..640f1aa1047d 100644 --- a/src/panels/config/users/dialog-add-user.ts +++ b/src/panels/config/users/dialog-add-user.ts @@ -290,6 +290,11 @@ export class DialogAddUser extends LitElement { } user.username = this._username; + user.credentials = [ + { + type: "homeassistant", + }, + ]; this._params!.userAddedCallback(user); this._close(); } From 9beb4c39ffcc7487a9ac70851f34fe18bbfe6b02 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 28 Jun 2024 21:10:24 +0200 Subject: [PATCH 18/86] Implement search in application credentials table (#21219) Implement search functions --- .../ha-config-application-credentials.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/panels/config/application_credentials/ha-config-application-credentials.ts b/src/panels/config/application_credentials/ha-config-application-credentials.ts index ad12b59791f4..e11f0515f431 100644 --- a/src/panels/config/application_credentials/ha-config-application-credentials.ts +++ b/src/panels/config/application_credentials/ha-config-application-credentials.ts @@ -68,6 +68,14 @@ export class HaConfigApplicationCredentials extends LitElement { }) private _activeHiddenColumns?: string[]; + @storage({ + storage: "sessionStorage", + key: "application-credentials-table-search", + state: true, + subscribe: false, + }) + private _filter = ""; + private _columns = memoizeOne( (narrow: boolean, localize: LocalizeFunc): DataTableColumnContainer => { const columns: DataTableColumnContainer = { @@ -76,6 +84,7 @@ export class HaConfigApplicationCredentials extends LitElement { "ui.panel.config.application_credentials.picker.headers.name" ), sortable: true, + filterable: true, direction: "asc", grows: true, }, @@ -83,6 +92,7 @@ export class HaConfigApplicationCredentials extends LitElement { title: localize( "ui.panel.config.application_credentials.picker.headers.client_id" ), + filterable: true, width: "30%", hidden: narrow, }, @@ -91,6 +101,7 @@ export class HaConfigApplicationCredentials extends LitElement { "ui.panel.config.application_credentials.picker.headers.application" ), sortable: true, + filterable: true, width: "30%", direction: "asc", }, @@ -156,6 +167,8 @@ export class HaConfigApplicationCredentials extends LitElement { .hiddenColumns=${this._activeHiddenColumns} @columns-changed=${this._handleColumnsChanged} @sorting-changed=${this._handleSortingChanged} + .filter=${this._filter} + @search-changed=${this._handleSearchChange} >
${!this.narrow @@ -290,6 +303,10 @@ export class HaConfigApplicationCredentials extends LitElement { this._activeHiddenColumns = ev.detail.hiddenColumns; } + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value; + } + static get styles(): CSSResultGroup { return css` .table-header { From b81314fc1f054c3b6020bd342799f0256b30a14c Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 28 Jun 2024 21:11:07 +0200 Subject: [PATCH 19/86] Bumped version to 20240628.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 48b7f8fcea7c..4d2f4be0602b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240627.0" +version = "20240628.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From 93445ced7487c6a6d6fd8ede46019045986a2f47 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 13:30:05 -0400 Subject: [PATCH 20/86] Update dependency eslint-plugin-lit-a11y to v4.1.3 (#21227) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 2f1c2b10a773..1937552669a6 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ "eslint-import-resolver-webpack": "0.13.8", "eslint-plugin-import": "2.29.1", "eslint-plugin-lit": "1.14.0", - "eslint-plugin-lit-a11y": "4.1.2", + "eslint-plugin-lit-a11y": "4.1.3", "eslint-plugin-unused-imports": "4.0.0", "eslint-plugin-wc": "2.1.0", "fancy-log": "2.0.0", diff --git a/yarn.lock b/yarn.lock index f26b8a6153bc..405534461284 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3974,6 +3974,15 @@ __metadata: languageName: node linkType: hard +"@thepassle/axobject-query@npm:^4.0.0": + version: 4.0.0 + resolution: "@thepassle/axobject-query@npm:4.0.0" + dependencies: + dequal: "npm:^2.0.3" + checksum: 10/919cb6ed90259cd0398b7e485dfbacae42423ff4202d5753c6545d3dfa9dc3d63e7f34941d6b94608c2730ec1539d30805411d9501c86951966e0d4aa0c4ae44 + languageName: node + linkType: hard + "@thomasloven/round-slider@npm:0.6.0": version: 0.6.0 resolution: "@thomasloven/round-slider@npm:0.6.0" @@ -5825,13 +5834,6 @@ __metadata: languageName: node linkType: hard -"axobject-query@npm:^2.2.0": - version: 2.2.0 - resolution: "axobject-query@npm:2.2.0" - checksum: 10/25de4b5ba6b28f5856fab60d86ea20fea941586bc38f33c81b78d66cd7e9c5792a9b9a9e60a38407aa634e01fee6a34133fbbd1d1d3d24cc686de83c6bb1e634 - languageName: node - linkType: hard - "b4a@npm:^1.6.4": version: 1.6.6 resolution: "b4a@npm:1.6.6" @@ -7579,13 +7581,13 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-lit-a11y@npm:4.1.2": - version: 4.1.2 - resolution: "eslint-plugin-lit-a11y@npm:4.1.2" +"eslint-plugin-lit-a11y@npm:4.1.3": + version: 4.1.3 + resolution: "eslint-plugin-lit-a11y@npm:4.1.3" dependencies: + "@thepassle/axobject-query": "npm:^4.0.0" aria-query: "npm:^5.1.3" axe-core: "npm:^4.3.3" - axobject-query: "npm:^2.2.0" dom5: "npm:^3.0.1" emoji-regex: "npm:^10.2.1" eslint-plugin-lit: "npm:^1.10.1" @@ -7596,7 +7598,7 @@ __metadata: requireindex: "npm:~1.2.0" peerDependencies: eslint: ">= 5" - checksum: 10/2d70f0b9fa6afc7f259877acd7e69c14f0104a69a019efb594d5de603e12b982e4a96fec5b169005fab244655951f85bff77f469d9aeadb885974f963a7d9996 + checksum: 10/730a82cfefbeba87e604172db8c29fc18d3361b5c913531c05e83af26edbe612df955d5f124daf6066c3703b0e25f2352a8ea9cae8b2f8a3e6121937c297d3a9 languageName: node linkType: hard @@ -9018,7 +9020,7 @@ __metadata: eslint-import-resolver-webpack: "npm:0.13.8" eslint-plugin-import: "npm:2.29.1" eslint-plugin-lit: "npm:1.14.0" - eslint-plugin-lit-a11y: "npm:4.1.2" + eslint-plugin-lit-a11y: "npm:4.1.3" eslint-plugin-unused-imports: "npm:4.0.0" eslint-plugin-wc: "npm:2.1.0" fancy-log: "npm:2.0.0" From bda61da6660495ba8ad65240baa022911bd74de5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 09:34:43 +0200 Subject: [PATCH 21/86] Update dependency @material/web to v1.5.1 (#21224) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 1937552669a6..292983f4ad45 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "@material/mwc-top-app-bar": "0.27.0", "@material/mwc-top-app-bar-fixed": "0.27.0", "@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0", - "@material/web": "1.5.0", + "@material/web": "1.5.1", "@mdi/js": "7.4.47", "@mdi/svg": "7.4.47", "@polymer/paper-item": "3.0.1", diff --git a/yarn.lock b/yarn.lock index 405534461284..255077cb166b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3235,13 +3235,13 @@ __metadata: languageName: node linkType: hard -"@material/web@npm:1.5.0": - version: 1.5.0 - resolution: "@material/web@npm:1.5.0" +"@material/web@npm:1.5.1": + version: 1.5.1 + resolution: "@material/web@npm:1.5.1" dependencies: lit: "npm:^2.7.4 || ^3.0.0" tslib: "npm:^2.4.0" - checksum: 10/6bf651e8eaf33332b7f83aa04d473f6844a1f8280d5a2025a30583fbe03aa718de348260c5b9466d587f166772759aba0d100137e3e13d4d7c6fba6ffb79efa4 + checksum: 10/9be6019068fbc4ed6873837ad549fd672c24beaacd9123bc9f3d72b7dfd67a1acdafab43bd484b50d40300e27e3742314915f4d6e6723b38be223b4547ae206f languageName: node linkType: hard @@ -8951,7 +8951,7 @@ __metadata: "@material/mwc-top-app-bar": "npm:0.27.0" "@material/mwc-top-app-bar-fixed": "npm:0.27.0" "@material/top-app-bar": "npm:=14.0.0-canary.53b3cad2f.0" - "@material/web": "npm:1.5.0" + "@material/web": "npm:1.5.1" "@mdi/js": "npm:7.4.47" "@mdi/svg": "npm:7.4.47" "@octokit/auth-oauth-device": "npm:7.1.1" From f41fab69680f4bbe20aaadf7042ea7159fa0c197 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 1 Jul 2024 11:12:15 +0200 Subject: [PATCH 22/86] Improve take control of automation/script wording (#21241) --- src/translations/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/translations/en.json b/src/translations/en.json index 4ee62dc063c6..75271fe1a472 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2773,7 +2773,7 @@ "take_control": "Take control", "take_control_confirmation": { "title": "Take control of automation?", - "text": "This automation is using a blueprint. By taking control, your automation will be converted into a regular automation using triggers, conditions and actions. You will be able to edit it directly and you won't be able to convert it back to a blueprint.", + "text": "This automation is based on a blueprint. You are about to take control, which will separate it from the blueprint and give you the ability to fully edit the automation. Would you like to proceed?", "action": "Take control" }, "run": "[%key:ui::panel::config::automation::editor::actions::run%]", @@ -3650,7 +3650,7 @@ "take_control": "[%key:ui::panel::config::automation::editor::take_control%]", "take_control_confirmation": { "title": "Take control of script?", - "text": "This script is using a blueprint. By taking control, your script will be converted into a regular automation using actions. You will be able to edit it directly and you won't be able to convert it back to a blueprint.", + "text": "This script is based on a blueprint. You are about to take control, which will separate it from the blueprint and give you the ability to fully edit the script. Would you like to proceed?", "action": "[%key:ui::panel::config::automation::editor::take_control_confirmation::action%]" }, "read_only": "This script cannot be edited from the UI, because it is not stored in the ''scripts.yaml'' file.", From c71a051b6dedb2ff273a58a45331b713d9933090 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 1 Jul 2024 12:11:26 +0200 Subject: [PATCH 23/86] Remove ga.js (#21242) --- cast/src/html/faq.html.template | 12 ------------ cast/src/html/media.html.template | 6 ------ cast/src/html/receiver.html.template | 6 ------ demo/src/html/index.html.template | 11 ----------- 4 files changed, 35 deletions(-) diff --git a/cast/src/html/faq.html.template b/cast/src/html/faq.html.template index c67a5b477a95..80fc487bef21 100644 --- a/cast/src/html/faq.html.template +++ b/cast/src/html/faq.html.template @@ -232,17 +232,5 @@ http:

- - diff --git a/cast/src/html/media.html.template b/cast/src/html/media.html.template index e91fbb881cbe..49633e084021 100644 --- a/cast/src/html/media.html.template +++ b/cast/src/html/media.html.template @@ -14,12 +14,6 @@ --background-color: #41bdf5; } - <%= renderTemplate("../../../src/html/_js_base.html.template") %> diff --git a/cast/src/html/receiver.html.template b/cast/src/html/receiver.html.template index 582e9ca865d4..d326ce55ff13 100644 --- a/cast/src/html/receiver.html.template +++ b/cast/src/html/receiver.html.template @@ -11,10 +11,4 @@ font-size: initial; } - diff --git a/demo/src/html/index.html.template b/demo/src/html/index.html.template index c2be4e7cc39c..6b044e44a355 100644 --- a/demo/src/html/index.html.template +++ b/demo/src/html/index.html.template @@ -93,16 +93,5 @@ } <%= renderTemplate("../../../src/html/_script_load_es5.html.template") %> - From e97be57e3b8ca22daf096294b0c2d46d97bfe6bb Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:11:52 +0200 Subject: [PATCH 24/86] Application credentials: small improvements (#21233) * small improvements * Update ha-config-application-credentials.ts * Update ha-config-application-credentials.ts --------- Co-authored-by: Bram Kragten --- .../ha-config-application-credentials.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/panels/config/application_credentials/ha-config-application-credentials.ts b/src/panels/config/application_credentials/ha-config-application-credentials.ts index e11f0515f431..d31c8b274d18 100644 --- a/src/panels/config/application_credentials/ha-config-application-credentials.ts +++ b/src/panels/config/application_credentials/ha-config-application-credentials.ts @@ -77,12 +77,13 @@ export class HaConfigApplicationCredentials extends LitElement { private _filter = ""; private _columns = memoizeOne( - (narrow: boolean, localize: LocalizeFunc): DataTableColumnContainer => { + (localize: LocalizeFunc): DataTableColumnContainer => { const columns: DataTableColumnContainer = { name: { title: localize( "ui.panel.config.application_credentials.picker.headers.name" ), + main: true, sortable: true, filterable: true, direction: "asc", @@ -94,7 +95,6 @@ export class HaConfigApplicationCredentials extends LitElement { ), filterable: true, width: "30%", - hidden: narrow, }, localizedDomain: { title: localize( @@ -109,6 +109,9 @@ export class HaConfigApplicationCredentials extends LitElement { title: "", width: "64px", type: "overflow-menu", + showNarrow: true, + hideable: false, + moveable: false, template: (credential) => html` Date: Mon, 1 Jul 2024 10:31:22 -0400 Subject: [PATCH 25/86] Fix Webpack bundling of recorder worklet (#21239) * Fix Webpack bundling of recorder worklet --- build-scripts/webpack.cjs | 17 ++++++++++++----- src/util/audio-recorder.ts | 17 +++++++++-------- ...{recorder.worklet.js => recorder-worklet.js} | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) rename src/util/{recorder.worklet.js => recorder-worklet.js} (89%) diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs index 0679e3e2baec..5ba0f35d2383 100644 --- a/build-scripts/webpack.cjs +++ b/build-scripts/webpack.cjs @@ -74,6 +74,9 @@ const createWebpackConfig = ({ resolve: { fullySpecified: false, }, + parser: { + worker: ["*context.audioWorklet.addModule()", "..."], + }, }, { test: /\.css$/, @@ -92,11 +95,15 @@ const createWebpackConfig = ({ moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", splitChunks: { - // Disable splitting for web workers with ESM output - // Imports of external chunks are broken - chunks: latestBuild - ? (chunk) => !chunk.canBeInitial() && !/^.+-worker$/.test(chunk.name) - : undefined, + // Disable splitting for web workers and worklets because imports of + // external chunks are broken for: + // - ESM output: https://github.com/webpack/webpack/issues/17014 + // - Worklets use `importScripts`: https://github.com/webpack/webpack/issues/11543 + chunks: (chunk) => + !chunk.canBeInitial() && + !new RegExp(`^.+-work${latestBuild ? "(?:let|er)" : "let"}$`).test( + chunk.name + ), }, }, plugins: [ diff --git a/src/util/audio-recorder.ts b/src/util/audio-recorder.ts index b26f0f49229c..30bf78793709 100644 --- a/src/util/audio-recorder.ts +++ b/src/util/audio-recorder.ts @@ -70,17 +70,18 @@ export class AudioRecorder { } private async _createContext() { - // @ts-ignore-next-line - this._context = new (window.AudioContext || window.webkitAudioContext)(); + // @ts-expect-error webkitAudioContext is not recognized + const context = new (AudioContext || webkitAudioContext)(); this._stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - - await this._context.audioWorklet.addModule( - new URL("./recorder.worklet.js", import.meta.url) + // Syntax here must match an item of `parser.worker` in Webpack config in + // order for module to be parsed and a chunk to be properly created. + await context.audioWorklet.addModule( + /* webpackChunkName: "recorder-worklet" */ + new URL("./recorder-worklet.js", import.meta.url) ); - + this._context = context; this._source = this._context.createMediaStreamSource(this._stream); - this._recorder = new AudioWorkletNode(this._context, "recorder.worklet"); - + this._recorder = new AudioWorkletNode(this._context, "recorder-worklet"); this._recorder.port.onmessage = (e) => { if (!this._active) { return; diff --git a/src/util/recorder.worklet.js b/src/util/recorder-worklet.js similarity index 89% rename from src/util/recorder.worklet.js rename to src/util/recorder-worklet.js index b8fef662e727..0d54b3a607c9 100644 --- a/src/util/recorder.worklet.js +++ b/src/util/recorder-worklet.js @@ -18,4 +18,4 @@ class RecorderProcessor extends AudioWorkletProcessor { } } -registerProcessor("recorder.worklet", RecorderProcessor); +registerProcessor("recorder-worklet", RecorderProcessor); From 76abfea6edc41fb4ed22f543b177db099914d5c8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 2 Jul 2024 14:59:52 +0200 Subject: [PATCH 26/86] Hide demo card when showing demo from frontpage (#21243) * Hide demo card when showing demo from frontpage * Store in constant on load * reverse * Remove filter * move constnat * Make Home Assistant title --- demo/src/configs/sections/lovelace.ts | 15 ++++++++++----- demo/src/entrypoint.ts | 1 + demo/src/util/is_frontpage.ts | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 demo/src/util/is_frontpage.ts diff --git a/demo/src/configs/sections/lovelace.ts b/demo/src/configs/sections/lovelace.ts index 70146c0bdb39..ccea806c61ee 100644 --- a/demo/src/configs/sections/lovelace.ts +++ b/demo/src/configs/sections/lovelace.ts @@ -1,3 +1,4 @@ +import { isFrontpageEmbed } from "../../util/is_frontpage"; import { DemoConfig } from "../types"; export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ @@ -5,14 +6,18 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ views: [ { type: "sections", - title: "Demo", + title: isFrontpageEmbed ? "Home Assistant" : "Demo", path: "home", icon: "mdi:home-assistant", sections: [ - { - title: "Welcome 👋", - cards: [{ type: "custom:ha-demo-card" }], - }, + ...(isFrontpageEmbed + ? [] + : [ + { + title: "Welcome 👋", + cards: [{ type: "custom:ha-demo-card" }], + }, + ]), { cards: [ { diff --git a/demo/src/entrypoint.ts b/demo/src/entrypoint.ts index ca58e546e357..e02049326436 100644 --- a/demo/src/entrypoint.ts +++ b/demo/src/entrypoint.ts @@ -1,4 +1,5 @@ import "../../src/resources/safari-14-attachshadow-patch"; +import "./util/is_frontpage"; import "./ha-demo"; import("../../src/resources/ha-style"); diff --git a/demo/src/util/is_frontpage.ts b/demo/src/util/is_frontpage.ts new file mode 100644 index 000000000000..4de52935ba6a --- /dev/null +++ b/demo/src/util/is_frontpage.ts @@ -0,0 +1 @@ +export const isFrontpageEmbed = document.location.search === "?frontpage"; From 5707ca0016e832d99dd0b9a1a2242eb3abd7da6f Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Tue, 2 Jul 2024 09:13:04 -0400 Subject: [PATCH 27/86] Fix English only translations build (#21245) --- build-scripts/gulp/translations.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build-scripts/gulp/translations.js b/build-scripts/gulp/translations.js index dde4dd89f4c8..1127a5d3f5eb 100755 --- a/build-scripts/gulp/translations.js +++ b/build-scripts/gulp/translations.js @@ -244,11 +244,11 @@ const createTranslations = async () => { // TODO: This is a naive interpretation of BCP47 that should be improved. // Will be OK for now as long as we don't have anything more complicated // than a base translation + region. - gulp + const masterStream = gulp .src(`${workDir}/en.json`) - .pipe(new PassThrough({ objectMode: true })) - .pipe(hashStream, { end: false }); - const mergesFinished = []; + .pipe(new PassThrough({ objectMode: true })); + masterStream.pipe(hashStream, { end: false }); + const mergesFinished = [finished(masterStream)]; for (const translationFile of translationFiles) { const locale = basename(translationFile, ".json"); const subtags = locale.split("-"); From 7258e31348d6fa8fc98271990d99e1c252210062 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 2 Jul 2024 17:11:16 +0200 Subject: [PATCH 28/86] Tweak first section in section demo (#21249) * Tweak first section in section demo * Allow automation entities be toggled --- demo/src/configs/sections/lovelace.ts | 25 +++++-------------------- src/fake_data/entity.ts | 1 + 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/demo/src/configs/sections/lovelace.ts b/demo/src/configs/sections/lovelace.ts index ccea806c61ee..36b4abb2fe9c 100644 --- a/demo/src/configs/sections/lovelace.ts +++ b/demo/src/configs/sections/lovelace.ts @@ -20,26 +20,6 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ ]), { cards: [ - { - type: "tile", - entity: "cover.living_room_garden_shutter", - name: "Garden", - }, - { - type: "tile", - entity: "cover.living_room_graveyard_shutter", - name: "Rear", - }, - { - type: "tile", - entity: "cover.living_room_left_shutter", - name: "Left", - }, - { - type: "tile", - entity: "cover.living_room_right_shutter", - name: "Right", - }, { type: "tile", entity: "light.floor_lamp", @@ -65,6 +45,11 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ detail: 1, name: "Temperature", }, + { + type: "tile", + entity: "cover.living_room_garden_shutter", + name: "Blinds", + }, { type: "tile", entity: "media_player.living_room_nest_mini", diff --git a/src/fake_data/entity.ts b/src/fake_data/entity.ts index b001b4b7fcd0..2ea81b3feacf 100644 --- a/src/fake_data/entity.ts +++ b/src/fake_data/entity.ts @@ -394,6 +394,7 @@ class GroupEntity extends Entity { } const TYPES = { + automation: ToggleEntity, alarm_control_panel: AlarmControlPanelEntity, climate: ClimateEntity, cover: CoverEntity, From 7d432cd11ab6504595667e6bf53b754addc09417 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 2 Jul 2024 18:44:36 +0200 Subject: [PATCH 29/86] Fix logbook card display/reloading issues (#21253) remove await logic --- src/panels/logbook/ha-logbook.ts | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/panels/logbook/ha-logbook.ts b/src/panels/logbook/ha-logbook.ts index ea25e307b3d4..38ef5ee2a62f 100644 --- a/src/panels/logbook/ha-logbook.ts +++ b/src/panels/logbook/ha-logbook.ts @@ -139,7 +139,7 @@ export class HaLogbook extends LitElement { this._throttleGetLogbookEntries.cancel(); this._updateTraceContexts.cancel(); this._updateUsers.cancel(); - await this._unsubscribeSetLoading(); + this._unsubscribeSetLoading(); if (force) { this._getLogBookData(); @@ -206,18 +206,9 @@ export class HaLogbook extends LitElement { ); } - private async _unsubscribe(): Promise { + private _unsubscribe() { if (this._subscribed) { - const unsub = await this._subscribed; - if (unsub) { - try { - await unsub(); - } catch (e) { - // The backend will cancel the subscription if - // we subscribe to entities that will all be - // filtered away - } - } + this._subscribed.then((unsub) => unsub?.()); this._subscribed = undefined; } } @@ -239,8 +230,8 @@ export class HaLogbook extends LitElement { * Setting this._logbookEntries to undefined * will put the page in a loading state. */ - private async _unsubscribeSetLoading() { - await this._unsubscribe(); + private _unsubscribeSetLoading() { + this._unsubscribe(); this._logbookEntries = undefined; this._pendingStreamMessages = []; } @@ -249,8 +240,8 @@ export class HaLogbook extends LitElement { * Setting this._logbookEntries to an empty * list will show a no results message. */ - private async _unsubscribeNoResults() { - await this._unsubscribe(); + private _unsubscribeNoResults() { + this._unsubscribe(); this._logbookEntries = []; this._pendingStreamMessages = []; } From 09accb3071eefb62e28bbf688d054aee9e05ec8c Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 2 Jul 2024 18:50:42 +0200 Subject: [PATCH 30/86] Ignore aspect ratio in grid section (#21248) * Ignore aspect ratio in grid section * Feedback --- src/panels/lovelace/cards/hui-area-card.ts | 23 +++++++++- src/panels/lovelace/cards/hui-card.ts | 10 ++++- src/panels/lovelace/cards/hui-iframe-card.ts | 43 ++++++++++++------- src/panels/lovelace/cards/hui-map-card.ts | 16 ++++++- .../lovelace/sections/hui-grid-section.ts | 1 + src/panels/lovelace/types.ts | 1 + 6 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src/panels/lovelace/cards/hui-area-card.ts b/src/panels/lovelace/cards/hui-area-card.ts index 5bd7e44e317b..5ebf4b4eae05 100644 --- a/src/panels/lovelace/cards/hui-area-card.ts +++ b/src/panels/lovelace/cards/hui-area-card.ts @@ -55,7 +55,11 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import { HomeAssistant } from "../../../types"; import "../components/hui-image"; import "../components/hui-warning"; -import { LovelaceCard, LovelaceCardEditor } from "../types"; +import { + LovelaceCard, + LovelaceCardEditor, + LovelaceLayoutOptions, +} from "../types"; import { AreaCardConfig } from "./types"; export const DEFAULT_ASPECT_RATIO = "16:9"; @@ -102,6 +106,9 @@ export class HuiAreaCard @property({ attribute: false }) public hass!: HomeAssistant; + @property({ attribute: false }) + public layout?: string; + @state() private _config?: AreaCardConfig; @state() private _entities?: EntityRegistryEntry[]; @@ -405,13 +412,17 @@ export class HuiAreaCard if (this._config.show_camera && "camera" in entitiesByDomain) { cameraEntityId = entitiesByDomain.camera[0].entity_id; } + cameraEntityId = "camera.demo_camera"; const imageClass = area.picture || cameraEntityId; + + const ignoreAspectRatio = imageClass || this.layout === "grid"; + return html` 0 && ratio.h > 0) { - padding = `${((100 * ratio.h) / ratio.w).toFixed(2)}%`; + const ignoreAspectRatio = this.isPanel || this.layout === "grid"; + if (!ignoreAspectRatio) { + if (this._config.aspect_ratio) { + const ratio = parseAspectRatio(this._config.aspect_ratio); + if (ratio && ratio.w > 0 && ratio.h > 0) { + padding = `${((100 * ratio.h) / ratio.w).toFixed(2)}%`; + } + } else { + padding = "50%"; } - } else if (!this.isPanel) { - padding = "50%"; } const target_protocol = new URL(this._config.url, location.toString()) @@ -105,24 +115,25 @@ export class HuiIframeCard extends LitElement implements LovelaceCard { `; } + public getLayoutOptions(): LovelaceLayoutOptions { + return { + grid_columns: 4, + grid_rows: 4, + }; + } + static get styles(): CSSResultGroup { return css` - :host([ispanel]) ha-card { - width: 100%; - height: 100%; - } - ha-card { overflow: hidden; + width: 100%; + height: 100%; } #root { width: 100%; - position: relative; - } - - :host([ispanel]) #root { height: 100%; + position: relative; } iframe { diff --git a/src/panels/lovelace/cards/hui-map-card.ts b/src/panels/lovelace/cards/hui-map-card.ts index 65189e351360..ef0d25be529e 100644 --- a/src/panels/lovelace/cards/hui-map-card.ts +++ b/src/panels/lovelace/cards/hui-map-card.ts @@ -39,7 +39,7 @@ import { HomeAssistant } from "../../../types"; import { findEntities } from "../common/find-entities"; import { processConfigEntities } from "../common/process-config-entities"; import { EntityConfig } from "../entity-rows/types"; -import { LovelaceCard } from "../types"; +import { LovelaceCard, LovelaceLayoutOptions } from "../types"; import { MapCardConfig } from "./types"; export const DEFAULT_HOURS_TO_SHOW = 0; @@ -57,6 +57,9 @@ class HuiMapCard extends LitElement implements LovelaceCard { @property({ type: Boolean, reflect: true }) public isPanel = false; + @property({ attribute: false }) + public layout?: string; + @state() private _stateHistory?: HistoryStates; @state() @@ -297,7 +300,9 @@ class HuiMapCard extends LitElement implements LovelaceCard { private _computePadding(): void { const root = this.shadowRoot!.getElementById("root"); - if (!this._config || this.isPanel || !root) { + + const ignoreAspectRatio = this.isPanel || this.layout === "grid"; + if (!this._config || ignoreAspectRatio || !root) { return; } @@ -423,6 +428,13 @@ class HuiMapCard extends LitElement implements LovelaceCard { } ); + public getLayoutOptions(): LovelaceLayoutOptions { + return { + grid_columns: 4, + grid_rows: 4, + }; + } + static get styles(): CSSResultGroup { return css` ha-card { diff --git a/src/panels/lovelace/sections/hui-grid-section.ts b/src/panels/lovelace/sections/hui-grid-section.ts index 11fd8aa0afd3..8b5b8d9bb16c 100644 --- a/src/panels/lovelace/sections/hui-grid-section.ts +++ b/src/panels/lovelace/sections/hui-grid-section.ts @@ -98,6 +98,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement { (cardConfig) => this._getKey(cardConfig), (_cardConfig, idx) => { const card = this.cards![idx]; + card.layout = "grid"; const layoutOptions = card.getLayoutOptions(); const columnSize = diff --git a/src/panels/lovelace/types.ts b/src/panels/lovelace/types.ts index eaf582057322..9eadc1fd017e 100644 --- a/src/panels/lovelace/types.ts +++ b/src/panels/lovelace/types.ts @@ -49,6 +49,7 @@ export interface LovelaceCard extends HTMLElement { hass?: HomeAssistant; isPanel?: boolean; preview?: boolean; + layout?: string; getCardSize(): number | Promise; getLayoutOptions?(): LovelaceLayoutOptions; setConfig(config: LovelaceCardConfig): void; From 9a2051a6797ba3c6688dddbb4e8b763ef26315b1 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 2 Jul 2024 21:18:58 +0200 Subject: [PATCH 31/86] Change take control of blueprint UX (#21254) * Change take control of blueprint UX * Add margin to ha-alert --------- Co-authored-by: Paul Bottein --- .../automation/blueprint-automation-editor.ts | 8 -- .../config/automation/ha-automation-editor.ts | 97 ++++++++++------- .../automation/manual-automation-editor.ts | 18 ---- .../blueprint/blueprint-generic-editor.ts | 21 ++-- .../config/script/blueprint-script-editor.ts | 9 -- src/panels/config/script/ha-script-editor.ts | 100 +++++++++++------- .../config/script/manual-script-editor.ts | 18 ---- src/translations/en.json | 12 +-- 8 files changed, 130 insertions(+), 153 deletions(-) diff --git a/src/panels/config/automation/blueprint-automation-editor.ts b/src/panels/config/automation/blueprint-automation-editor.ts index 959230be5f97..78b4a2375bfe 100644 --- a/src/panels/config/automation/blueprint-automation-editor.ts +++ b/src/panels/config/automation/blueprint-automation-editor.ts @@ -20,14 +20,6 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor { protected render() { return html` - ${this.disabled - ? html` - ${this.hass.localize("ui.panel.config.automation.editor.read_only")} - - ${this.hass.localize("ui.panel.config.automation.editor.migrate")} - - ` - : nothing} ${this.stateObj?.state === "off" ? html` diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 939c00af531c..cd7ab59477a7 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -81,9 +81,9 @@ declare global { unsub?: UnsubscribeFunc; }; "ui-mode-not-available": Error; - duplicate: undefined; "move-down": undefined; "move-up": undefined; + duplicate: undefined; } } @@ -116,6 +116,8 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { @state() private _validationErrors?: (string | TemplateResult)[]; + @state() private _blueprintConfig?: BlueprintAutomationConfig; + private _configSubscriptions: Record< string, (config?: AutomationConfig) => void @@ -200,7 +202,9 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ${this.hass.localize("ui.panel.config.automation.editor.rename")} @@ -224,7 +228,8 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { : nothing} @@ -244,7 +249,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ${this.hass.localize( "ui.panel.config.automation.editor.take_control" @@ -337,6 +342,32 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { : nothing} ` : ""} + ${this._blueprintConfig + ? html` + ${this.hass.localize( + "ui.panel.config.automation.editor.confirm_take_control" + )} +
+ ${this.hass.localize("ui.common.yes")} + ${this.hass.localize("ui.common.no")} +
+
` + : this._readOnly + ? html`${this.hass.localize( + "ui.panel.config.automation.editor.read_only" + )} + + ${this.hass.localize( + "ui.panel.config.automation.editor.migrate" + )} + + ` + : nothing} ${this._mode === "gui" ? html`
` : html` @@ -366,25 +396,12 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { .config=${this._config} .disabled=${Boolean(this._readOnly)} @value-changed=${this._valueChanged} - @duplicate=${this._duplicate} > `}
` : this._mode === "yaml" - ? html` ${this._readOnly - ? html` - ${this.hass.localize( - "ui.panel.config.automation.editor.read_only" - )} - - ${this.hass.localize( - "ui.panel.config.automation.editor.migrate" - )} - - ` - : nothing} - ${stateObj?.state === "off" + ? html`${stateObj?.state === "off" ? html` ${this.hass.localize( @@ -409,7 +426,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
ha-alert { margin: 0 auto; max-width: 1040px; padding: 28px 20px 0; + display: block; } ha-yaml-editor { flex-grow: 1; diff --git a/src/panels/config/automation/manual-automation-editor.ts b/src/panels/config/automation/manual-automation-editor.ts index ceb4da52e033..3e7a23c2f948 100644 --- a/src/panels/config/automation/manual-automation-editor.ts +++ b/src/panels/config/automation/manual-automation-editor.ts @@ -38,14 +38,6 @@ export class HaManualAutomationEditor extends LitElement { protected render() { return html` - ${this.disabled - ? html` - ${this.hass.localize("ui.panel.config.automation.editor.read_only")} - - ${this.hass.localize("ui.panel.config.automation.editor.migrate")} - - ` - : nothing} ${this.stateObj?.state === "off" ? html` @@ -238,10 +230,6 @@ export class HaManualAutomationEditor extends LitElement { }); } - private _duplicate() { - fireEvent(this, "duplicate"); - } - static get styles(): CSSResultGroup { return [ haStyle, @@ -280,12 +268,6 @@ export class HaManualAutomationEditor extends LitElement { font-weight: normal; line-height: 0; } - ha-alert.re-order { - display: block; - margin-bottom: 16px; - border-radius: var(--ha-card-border-radius, 12px); - overflow: hidden; - } `, ]; } diff --git a/src/panels/config/blueprint/blueprint-generic-editor.ts b/src/panels/config/blueprint/blueprint-generic-editor.ts index bae63f6dc7e3..85d7083a8a8e 100644 --- a/src/panels/config/blueprint/blueprint-generic-editor.ts +++ b/src/panels/config/blueprint/blueprint-generic-editor.ts @@ -3,7 +3,6 @@ import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; import { nestedArrayMove } from "../../../common/util/array-move"; -import "../../../components/ha-alert"; import "../../../components/ha-blueprint-picker"; import "../../../components/ha-card"; import "../../../components/ha-circular-progress"; @@ -126,14 +125,14 @@ export abstract class HaBlueprintGenericEditor extends LitElement { ); const expanded = !section.collapsed || anyRequired; - return html`
${section?.icon - ? html` ` @@ -261,10 +260,6 @@ export abstract class HaBlueprintGenericEditor extends LitElement { }); } - protected _duplicate() { - fireEvent(this, "duplicate"); - } - static get styles(): CSSResultGroup { return [ haStyle, @@ -318,14 +313,6 @@ export abstract class HaBlueprintGenericEditor extends LitElement { margin-left: 8px; margin-right: 8px; } - ha-alert { - margin-bottom: 16px; - display: block; - } - ha-alert.re-order { - border-radius: var(--ha-card-border-radius, 12px); - overflow: hidden; - } div.section-header { display: flex; vertical-align: middle; @@ -333,6 +320,10 @@ export abstract class HaBlueprintGenericEditor extends LitElement { ha-icon.section-header { padding-right: 10px; } + ha-alert { + display: block; + margin-bottom: 16px; + } `, ]; } diff --git a/src/panels/config/script/blueprint-script-editor.ts b/src/panels/config/script/blueprint-script-editor.ts index bc7b624a0cb3..dbe96677de50 100644 --- a/src/panels/config/script/blueprint-script-editor.ts +++ b/src/panels/config/script/blueprint-script-editor.ts @@ -1,7 +1,6 @@ import "@material/mwc-button/mwc-button"; import { html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; -import "../../../components/ha-alert"; import "../../../components/ha-markdown"; import { fetchBlueprints } from "../../../data/blueprint"; import { BlueprintScriptConfig } from "../../../data/script"; @@ -17,14 +16,6 @@ export class HaBlueprintScriptEditor extends HaBlueprintGenericEditor { protected render() { return html` - ${this.disabled - ? html` - ${this.hass.localize("ui.panel.config.script.editor.read_only")} - - ${this.hass.localize("ui.panel.config.script.editor.migrate")} - - ` - : nothing} ${this.config.description ? html` @@ -236,7 +239,7 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ${this.hass.localize( "ui.panel.config.script.editor.take_control" @@ -312,6 +315,32 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { : nothing} ` : ""} + ${this._blueprintConfig + ? html` + ${this.hass.localize( + "ui.panel.config.script.editor.confirm_take_control" + )} +
+ ${this.hass.localize("ui.common.yes")} + ${this.hass.localize("ui.common.no")} +
+
` + : this._readOnly + ? html`${this.hass.localize( + "ui.panel.config.script.editor.read_only" + )} + + ${this.hass.localize( + "ui.panel.config.script.editor.migrate" + )} + + ` + : nothing} ${this._mode === "gui" ? html`
` : html` @@ -339,31 +367,18 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { .config=${this._config} .disabled=${this._readOnly} @value-changed=${this._valueChanged} - @duplicate=${this._duplicate} > `}
` : this._mode === "yaml" - ? html` ${this._readOnly - ? html` - ${this.hass.localize( - "ui.panel.config.script.editor.read_only" - )} - - ${this.hass.localize( - "ui.panel.config.script.editor.migrate" - )} - - ` - : nothing} - ` + ? html`` : nothing}
ha-alert { margin: 0 auto; max-width: 1040px; padding: 28px 20px 0; + display: block; } .config-container ha-alert { margin-bottom: 16px; diff --git a/src/panels/config/script/manual-script-editor.ts b/src/panels/config/script/manual-script-editor.ts index f5f946229dd7..63f0b555e4f5 100644 --- a/src/panels/config/script/manual-script-editor.ts +++ b/src/panels/config/script/manual-script-editor.ts @@ -60,14 +60,6 @@ export class HaManualScriptEditor extends LitElement { protected render() { return html` - ${this.disabled - ? html` - ${this.hass.localize("ui.panel.config.script.editor.read_only")} - - ${this.hass.localize("ui.panel.config.script.editor.migrate")} - - ` - : nothing} ${this.config.description ? html` Date: Tue, 2 Jul 2024 21:19:29 +0200 Subject: [PATCH 32/86] Add min/max row/columns to resize card editor (#21244) * Add min/max row/columns to resize card editor * Add humidifier and thermostat card * Removed unused condition * Don't set max rows * Add media card * Add button card * Use same rule if there is footer * Don't show disabled cell * Add min rows to sensor card * Update sizes * Update sizes * Update sizes * Add min rows to weather forecast card --- src/components/ha-grid-size-picker.ts | 22 +++++---- src/panels/lovelace/cards/hui-button-card.ts | 11 ++++- src/panels/lovelace/cards/hui-entity-card.ts | 15 ++++++- .../lovelace/cards/hui-humidifier-card.ts | 24 +++++++++- src/panels/lovelace/cards/hui-iframe-card.ts | 1 + src/panels/lovelace/cards/hui-map-card.ts | 2 + .../lovelace/cards/hui-media-control-card.ts | 15 ++++++- src/panels/lovelace/cards/hui-sensor-card.ts | 2 + .../lovelace/cards/hui-statistic-card.ts | 16 +++++-- .../lovelace/cards/hui-thermostat-card.ts | 24 +++++++++- src/panels/lovelace/cards/hui-tile-card.ts | 18 +++++--- .../cards/hui-weather-forecast-card.ts | 26 ++++++++++- .../card-editor/ha-grid-layout-slider.ts | 23 +++++----- .../card-editor/hui-card-layout-editor.ts | 30 +++++++------ .../lovelace/sections/hui-grid-section.ts | 45 ++++++++++++++++--- src/panels/lovelace/types.ts | 4 ++ 16 files changed, 222 insertions(+), 56 deletions(-) diff --git a/src/components/ha-grid-size-picker.ts b/src/components/ha-grid-size-picker.ts index dca2cbd2fbe1..453a24cb8d30 100644 --- a/src/components/ha-grid-size-picker.ts +++ b/src/components/ha-grid-size-picker.ts @@ -7,6 +7,7 @@ import { mdiRestore } from "@mdi/js"; import { styleMap } from "lit/directives/style-map"; import { fireEvent } from "../common/dom/fire_event"; import { HomeAssistant } from "../types"; +import { conditionalClamp } from "../common/number/clamp"; type GridSizeValue = { rows?: number; @@ -42,6 +43,10 @@ export class HaGridSizeEditor extends LitElement { } protected render() { + const disabledColumns = + this.columnMin !== undefined && this.columnMin === this.columnMax; + const disabledRows = + this.rowMin !== undefined && this.rowMin === this.rowMax; return html`
${!this.isDefault ? html` @@ -100,17 +107,11 @@ export class HaGridSizeEditor extends LitElement { .map((_, index) => { const row = Math.floor(index / this.columns) + 1; const column = (index % this.columns) + 1; - const disabled = - (this.rowMin !== undefined && row < this.rowMin) || - (this.rowMax !== undefined && row > this.rowMax) || - (this.columnMin !== undefined && column < this.columnMin) || - (this.columnMax !== undefined && column > this.columnMax); return html`
`; @@ -126,11 +127,16 @@ export class HaGridSizeEditor extends LitElement { _cellClick(ev) { const cell = ev.currentTarget as HTMLElement; - if (cell.getAttribute("disabled") !== null) return; const rows = Number(cell.getAttribute("data-row")); const columns = Number(cell.getAttribute("data-column")); + const clampedRow = conditionalClamp(rows, this.rowMin, this.rowMax); + const clampedColumn = conditionalClamp( + columns, + this.columnMin, + this.columnMax + ); fireEvent(this, "value-changed", { - value: { rows, columns }, + value: { rows: clampedRow, columns: clampedColumn }, }); } diff --git a/src/panels/lovelace/cards/hui-button-card.ts b/src/panels/lovelace/cards/hui-button-card.ts index 160e5c427747..f7492d0f65a1 100644 --- a/src/panels/lovelace/cards/hui-button-card.ts +++ b/src/panels/lovelace/cards/hui-button-card.ts @@ -145,9 +145,16 @@ export class HuiButtonCard extends LitElement implements LovelaceCard { this._config?.show_icon && (this._config?.show_name || this._config?.show_state) ) { - return { grid_rows: 2, grid_columns: 2 }; + return { + grid_rows: 2, + grid_columns: 2, + grid_min_rows: 2, + }; } - return { grid_rows: 1, grid_columns: 1 }; + return { + grid_rows: 1, + grid_columns: 1, + }; } public setConfig(config: ButtonCardConfig): void { diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index e6366cd28b6c..42861e70fe4e 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -36,7 +36,11 @@ import { findEntities } from "../common/find-entities"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { createHeaderFooterElement } from "../create-element/create-header-footer-element"; -import { LovelaceCard, LovelaceHeaderFooter } from "../types"; +import { + LovelaceCard, + LovelaceHeaderFooter, + LovelaceLayoutOptions, +} from "../types"; import { HuiErrorCard } from "./hui-error-card"; import { EntityCardConfig } from "./types"; @@ -241,6 +245,15 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { fireEvent(this, "hass-more-info", { entityId: this._config!.entity }); } + public getLayoutOptions(): LovelaceLayoutOptions { + return { + grid_columns: 2, + grid_rows: 2, + grid_min_columns: 2, + grid_min_rows: 2, + }; + } + static get styles(): CSSResultGroup { return [ iconColorCSS, diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index f964148c0a64..405158847a09 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -22,7 +22,11 @@ import { HomeAssistant } from "../../../types"; import "../card-features/hui-card-features"; import { findEntities } from "../common/find-entities"; import { createEntityNotFoundWarning } from "../components/hui-warning"; -import { LovelaceCard, LovelaceCardEditor } from "../types"; +import { + LovelaceCard, + LovelaceCardEditor, + LovelaceLayoutOptions, +} from "../types"; import { HumidifierCardConfig } from "./types"; @customElement("hui-humidifier-card") @@ -173,6 +177,24 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { `; } + public getLayoutOptions(): LovelaceLayoutOptions { + const grid_columns = 4; + let grid_rows = 5; + let grid_min_rows = 2; + const grid_min_columns = 2; + if (this._config?.features?.length) { + const featureHeight = Math.ceil((this._config.features.length * 2) / 3); + grid_rows += featureHeight; + grid_min_rows += featureHeight; + } + return { + grid_columns, + grid_rows, + grid_min_rows, + grid_min_columns, + }; + } + static get styles(): CSSResultGroup { return css` :host { diff --git a/src/panels/lovelace/cards/hui-iframe-card.ts b/src/panels/lovelace/cards/hui-iframe-card.ts index c87766cbae64..36cdea605ec3 100644 --- a/src/panels/lovelace/cards/hui-iframe-card.ts +++ b/src/panels/lovelace/cards/hui-iframe-card.ts @@ -119,6 +119,7 @@ export class HuiIframeCard extends LitElement implements LovelaceCard { return { grid_columns: 4, grid_rows: 4, + grid_min_rows: 2, }; } diff --git a/src/panels/lovelace/cards/hui-map-card.ts b/src/panels/lovelace/cards/hui-map-card.ts index ef0d25be529e..0c810280c29c 100644 --- a/src/panels/lovelace/cards/hui-map-card.ts +++ b/src/panels/lovelace/cards/hui-map-card.ts @@ -432,6 +432,8 @@ class HuiMapCard extends LitElement implements LovelaceCard { return { grid_columns: 4, grid_rows: 4, + grid_min_columns: 2, + grid_min_rows: 2, }; } diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index ffdfe2c34a2f..4cd3e0f1058d 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -40,7 +40,11 @@ import { findEntities } from "../common/find-entities"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-marquee"; import { createEntityNotFoundWarning } from "../components/hui-warning"; -import type { LovelaceCard, LovelaceCardEditor } from "../types"; +import type { + LovelaceCard, + LovelaceCardEditor, + LovelaceLayoutOptions, +} from "../types"; import { MediaControlCardConfig } from "./types"; @customElement("hui-media-control-card") @@ -582,6 +586,15 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { } } + public getLayoutOptions(): LovelaceLayoutOptions { + return { + grid_columns: 4, + grid_min_columns: 2, + grid_rows: 3, + grid_min_rows: 3, + }; + } + static get styles(): CSSResultGroup { return css` ha-card { diff --git a/src/panels/lovelace/cards/hui-sensor-card.ts b/src/panels/lovelace/cards/hui-sensor-card.ts index 76ba0fa63626..c456d427b6ab 100644 --- a/src/panels/lovelace/cards/hui-sensor-card.ts +++ b/src/panels/lovelace/cards/hui-sensor-card.ts @@ -76,6 +76,8 @@ class HuiSensorCard extends HuiEntityCard { return { grid_columns: 2, grid_rows: 2, + grid_min_columns: 2, + grid_min_rows: 2, }; } diff --git a/src/panels/lovelace/cards/hui-statistic-card.ts b/src/panels/lovelace/cards/hui-statistic-card.ts index e5beb4a209cc..62338e7a65f3 100644 --- a/src/panels/lovelace/cards/hui-statistic-card.ts +++ b/src/panels/lovelace/cards/hui-statistic-card.ts @@ -1,10 +1,10 @@ import { HassEntity } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -16,12 +16,12 @@ import "../../../components/ha-alert"; import "../../../components/ha-card"; import "../../../components/ha-state-icon"; import { + StatisticsMetaData, fetchStatistic, getDisplayUnit, getStatisticLabel, getStatisticMetadata, isExternalStatistic, - StatisticsMetaData, } from "../../../data/recorder"; import { HomeAssistant } from "../../../types"; import { computeCardSize } from "../common/compute-card-size"; @@ -32,6 +32,7 @@ import { LovelaceCard, LovelaceCardEditor, LovelaceHeaderFooter, + LovelaceLayoutOptions, } from "../types"; import { HuiErrorCard } from "./hui-error-card"; import { EntityCardConfig, StatisticCardConfig } from "./types"; @@ -254,6 +255,15 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard { fireEvent(this, "hass-more-info", { entityId: this._config!.entity }); } + public getLayoutOptions(): LovelaceLayoutOptions { + return { + grid_columns: 2, + grid_rows: 2, + grid_min_columns: 2, + grid_min_rows: 2, + }; + } + static get styles(): CSSResultGroup { return [ css` diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index d8d58ee9c776..620f17a20562 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -22,7 +22,11 @@ import { HomeAssistant } from "../../../types"; import "../card-features/hui-card-features"; import { findEntities } from "../common/find-entities"; import { createEntityNotFoundWarning } from "../components/hui-warning"; -import { LovelaceCard, LovelaceCardEditor } from "../types"; +import { + LovelaceCard, + LovelaceCardEditor, + LovelaceLayoutOptions, +} from "../types"; import { ThermostatCardConfig } from "./types"; @customElement("hui-thermostat-card") @@ -165,6 +169,24 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { `; } + public getLayoutOptions(): LovelaceLayoutOptions { + const grid_columns = 4; + let grid_rows = 5; + let grid_min_rows = 2; + const grid_min_columns = 2; + if (this._config?.features?.length) { + const featureHeight = Math.ceil((this._config.features.length * 2) / 3); + grid_rows += featureHeight; + grid_min_rows += featureHeight; + } + return { + grid_columns, + grid_rows, + grid_min_rows, + grid_min_columns, + }; + } + static get styles(): CSSResultGroup { return css` :host { diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index fa8c2cc6d067..19a05e3bb4ab 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -122,17 +122,21 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } public getLayoutOptions(): LovelaceLayoutOptions { - const options = { - grid_columns: 2, - grid_rows: 1, - }; + const grid_columns = 2; + let grid_rows = 1; if (this._config?.features?.length) { - options.grid_rows += Math.ceil((this._config.features.length * 2) / 3); + const featureHeight = Math.ceil((this._config.features.length * 2) / 3); + grid_rows += featureHeight; } if (this._config?.vertical) { - options.grid_rows++; + grid_rows!++; } - return options; + return { + grid_columns, + grid_rows, + grid_min_rows: grid_rows, + grid_min_columns: grid_columns, + }; } private _handleAction(ev: ActionHandlerEvent) { diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index 40649ed32ae2..fadca1dd5aef 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -38,7 +38,11 @@ import { handleAction } from "../common/handle-action"; import { hasAction } from "../common/has-action"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import { createEntityNotFoundWarning } from "../components/hui-warning"; -import type { LovelaceCard, LovelaceCardEditor } from "../types"; +import type { + LovelaceCard, + LovelaceCardEditor, + LovelaceLayoutOptions, +} from "../types"; import type { WeatherForecastCardConfig } from "./types"; @customElement("hui-weather-forecast-card") @@ -421,6 +425,26 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { return typeof item !== "undefined" && item !== null; } + public getLayoutOptions(): LovelaceLayoutOptions { + if ( + this._config?.show_current !== false && + this._config?.show_forecast !== false + ) { + return { + grid_columns: 4, + grid_min_columns: 2, + grid_rows: 3, + grid_min_rows: 3, + }; + } + return { + grid_columns: 4, + grid_min_columns: 2, + grid_rows: 2, + grid_min_rows: 1, + }; + } + static get styles(): CSSResultGroup { return [ weatherSVGStyles, diff --git a/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts b/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts index 2ef6a61f0c40..ab1bebf00fcc 100644 --- a/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts +++ b/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts @@ -255,15 +255,14 @@ export class HaGridLayoutSlider extends LitElement { >
-
-
-
+
+
${this.value !== undefined ? html`
` @@ -323,11 +322,12 @@ export class HaGridLayoutSlider extends LitElement { position: absolute; inset: 0; background: var(--disabled-color); - opacity: 0.5; + opacity: 0.2; } .active { position: absolute; background: grey; + opacity: 0.7; top: 0; right: calc(var(--max) * 100%); bottom: 0; @@ -375,6 +375,9 @@ export class HaGridLayoutSlider extends LitElement { :host(:disabled) .slider { cursor: not-allowed; } + :host(:disabled) .handle:after { + background: var(--disabled-color); + } .pressed .handle { transition: none; } diff --git a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts index 68c0487beee4..5a5690727ce6 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts @@ -19,7 +19,7 @@ import { LovelaceCardConfig } from "../../../../data/lovelace/config/card"; import { haStyle } from "../../../../resources/styles"; import { HomeAssistant } from "../../../../types"; import { HuiCard } from "../../cards/hui-card"; -import { DEFAULT_GRID_OPTIONS } from "../../sections/hui-grid-section"; +import { computeSizeOnGrid } from "../../sections/hui-grid-section"; import { LovelaceLayoutOptions } from "../../types"; @customElement("hui-card-layout-editor") @@ -38,28 +38,29 @@ export class HuiCardLayoutEditor extends LitElement { private _cardElement?: HuiCard; - private _gridSizeValue = memoizeOne( + private _mergedOptions = memoizeOne( ( options?: LovelaceLayoutOptions, defaultOptions?: LovelaceLayoutOptions ) => ({ - rows: - options?.grid_rows ?? - defaultOptions?.grid_rows ?? - DEFAULT_GRID_OPTIONS.grid_rows, - columns: - options?.grid_columns ?? - defaultOptions?.grid_columns ?? - DEFAULT_GRID_OPTIONS.grid_columns, + ...defaultOptions, + ...options, }) ); + private _gridSizeValue = memoizeOne(computeSizeOnGrid); + private _isDefault = memoizeOne( (options?: LovelaceLayoutOptions) => options?.grid_columns === undefined && options?.grid_rows === undefined ); render() { + const options = this._mergedOptions( + this.config.layout_options, + this._defaultLayoutOptions + ); + return html`

@@ -123,12 +124,13 @@ export class HuiCardLayoutEditor extends LitElement { : html` `} `; diff --git a/src/panels/lovelace/sections/hui-grid-section.ts b/src/panels/lovelace/sections/hui-grid-section.ts index 8b5b8d9bb16c..0cc5c74824c0 100644 --- a/src/panels/lovelace/sections/hui-grid-section.ts +++ b/src/panels/lovelace/sections/hui-grid-section.ts @@ -15,6 +15,7 @@ import { HuiCard } from "../cards/hui-card"; import "../components/hui-card-edit-mode"; import { moveCard } from "../editor/config-util"; import type { Lovelace, LovelaceLayoutOptions } from "../types"; +import { conditionalClamp } from "../../../common/number/clamp"; const CARD_SORTABLE_OPTIONS: HaSortableOptions = { delay: 100, @@ -23,9 +24,41 @@ const CARD_SORTABLE_OPTIONS: HaSortableOptions = { invertedSwapThreshold: 0.7, } as HaSortableOptions; -export const DEFAULT_GRID_OPTIONS: LovelaceLayoutOptions = { +export const DEFAULT_GRID_OPTIONS = { grid_columns: 4, grid_rows: 1, +} as const satisfies LovelaceLayoutOptions; + +type GridSizeValue = { + rows?: number; + columns?: number; +}; + +export const computeSizeOnGrid = ( + options: LovelaceLayoutOptions +): GridSizeValue => { + const rows = + typeof options.grid_rows === "number" + ? conditionalClamp( + options.grid_rows, + options.grid_min_rows, + options.grid_max_rows + ) + : DEFAULT_GRID_OPTIONS.grid_rows; + + const columns = + typeof options.grid_columns === "number" + ? conditionalClamp( + options.grid_columns, + options.grid_min_columns, + options.grid_max_columns + ) + : DEFAULT_GRID_OPTIONS.grid_columns; + + return { + rows, + columns, + }; }; export class GridSection extends LitElement implements LovelaceSectionElement { @@ -101,15 +134,13 @@ export class GridSection extends LitElement implements LovelaceSectionElement { card.layout = "grid"; const layoutOptions = card.getLayoutOptions(); - const columnSize = - layoutOptions.grid_columns ?? DEFAULT_GRID_OPTIONS.grid_columns; - const rowSize = - layoutOptions.grid_rows ?? DEFAULT_GRID_OPTIONS.grid_rows; + const { rows, columns } = computeSizeOnGrid(layoutOptions); + return html`

Date: Tue, 2 Jul 2024 21:21:25 +0200 Subject: [PATCH 33/86] Bumped version to 20240702.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4d2f4be0602b..a045f384a64a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240628.0" +version = "20240702.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From 82329833f5f01c47021e42cc78a47381d32128ec Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Wed, 3 Jul 2024 00:28:57 -0400 Subject: [PATCH 34/86] Remove Safari 14.0 patch for delegatesFocus (#21247) --- cast/src/launcher/entrypoint.ts | 1 - demo/src/entrypoint.ts | 1 - hassio/src/entrypoint.ts | 1 - src/entrypoints/authorize.ts | 1 - src/entrypoints/core.ts | 1 - src/entrypoints/custom-panel.ts | 1 - src/entrypoints/onboarding.ts | 1 - src/resources/safari-14-attachshadow-patch.ts | 17 ----------------- 8 files changed, 24 deletions(-) delete mode 100644 src/resources/safari-14-attachshadow-patch.ts diff --git a/cast/src/launcher/entrypoint.ts b/cast/src/launcher/entrypoint.ts index 423e3165e771..f7d615d45857 100644 --- a/cast/src/launcher/entrypoint.ts +++ b/cast/src/launcher/entrypoint.ts @@ -1,4 +1,3 @@ -import "../../../src/resources/safari-14-attachshadow-patch"; import "./layout/hc-connect"; import("../../../src/resources/ha-style"); diff --git a/demo/src/entrypoint.ts b/demo/src/entrypoint.ts index e02049326436..e153eabb128c 100644 --- a/demo/src/entrypoint.ts +++ b/demo/src/entrypoint.ts @@ -1,4 +1,3 @@ -import "../../src/resources/safari-14-attachshadow-patch"; import "./util/is_frontpage"; import "./ha-demo"; diff --git a/hassio/src/entrypoint.ts b/hassio/src/entrypoint.ts index 35a7e8647b13..eabfb7e5e590 100644 --- a/hassio/src/entrypoint.ts +++ b/hassio/src/entrypoint.ts @@ -1,6 +1,5 @@ // Compat needs to be first import import "../../src/resources/compatibility"; -import "../../src/resources/safari-14-attachshadow-patch"; import "./hassio-main"; import("../../src/resources/ha-style"); diff --git a/src/entrypoints/authorize.ts b/src/entrypoints/authorize.ts index cc3e208d8194..047e80be1890 100644 --- a/src/entrypoints/authorize.ts +++ b/src/entrypoints/authorize.ts @@ -1,7 +1,6 @@ // Compat needs to be first import import "../resources/compatibility"; import "../auth/ha-authorize"; -import "../resources/safari-14-attachshadow-patch"; import("../resources/ha-style"); import("@polymer/polymer/lib/utils/settings").then( diff --git a/src/entrypoints/core.ts b/src/entrypoints/core.ts index bcd6138a0dc2..c0b83b90cc7a 100644 --- a/src/entrypoints/core.ts +++ b/src/entrypoints/core.ts @@ -25,7 +25,6 @@ import { subscribePanels } from "../data/ws-panels"; import { subscribeThemes } from "../data/ws-themes"; import { subscribeUser } from "../data/ws-user"; import type { ExternalAuth } from "../external_app/external_auth"; -import "../resources/safari-14-attachshadow-patch"; window.name = MAIN_WINDOW_NAME; (window as any).frontendVersion = __VERSION__; diff --git a/src/entrypoints/custom-panel.ts b/src/entrypoints/custom-panel.ts index b0b759ba775b..c12674a98e0a 100644 --- a/src/entrypoints/custom-panel.ts +++ b/src/entrypoints/custom-panel.ts @@ -1,6 +1,5 @@ // Compat needs to be first import import "../resources/compatibility"; -import "../resources/safari-14-attachshadow-patch"; import { CSSResult } from "lit"; import { fireEvent } from "../common/dom/fire_event"; diff --git a/src/entrypoints/onboarding.ts b/src/entrypoints/onboarding.ts index 9deb7359271c..87539e965a9b 100644 --- a/src/entrypoints/onboarding.ts +++ b/src/entrypoints/onboarding.ts @@ -1,7 +1,6 @@ // Compat needs to be first import import "../resources/compatibility"; import "../onboarding/ha-onboarding"; -import "../resources/safari-14-attachshadow-patch"; import("../resources/ha-style"); import("@polymer/polymer/lib/utils/settings").then( diff --git a/src/resources/safari-14-attachshadow-patch.ts b/src/resources/safari-14-attachshadow-patch.ts deleted file mode 100644 index a3a41ce4bdab..000000000000 --- a/src/resources/safari-14-attachshadow-patch.ts +++ /dev/null @@ -1,17 +0,0 @@ -// https://github.com/home-assistant/frontend/pull/7031 - -export {}; // for Babel to treat as a module - -const isSafari14 = /^((?!chrome|android).)*version\/14\.0\s.*safari/i.test( - navigator.userAgent -); - -if (isSafari14) { - const origAttachShadow = window.Element.prototype.attachShadow; - window.Element.prototype.attachShadow = function (init) { - if (init && init.delegatesFocus) { - delete init.delegatesFocus; - } - return origAttachShadow.apply(this, [init]); - }; -} From 19ee1503950197de6a2123d0d795d38d8b82f5e8 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 3 Jul 2024 11:54:11 +0200 Subject: [PATCH 35/86] Remove layout options for media player (#21258) --- .../lovelace/cards/hui-media-control-card.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index 4cd3e0f1058d..ffdfe2c34a2f 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -40,11 +40,7 @@ import { findEntities } from "../common/find-entities"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-marquee"; import { createEntityNotFoundWarning } from "../components/hui-warning"; -import type { - LovelaceCard, - LovelaceCardEditor, - LovelaceLayoutOptions, -} from "../types"; +import type { LovelaceCard, LovelaceCardEditor } from "../types"; import { MediaControlCardConfig } from "./types"; @customElement("hui-media-control-card") @@ -586,15 +582,6 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { } } - public getLayoutOptions(): LovelaceLayoutOptions { - return { - grid_columns: 4, - grid_min_columns: 2, - grid_rows: 3, - grid_min_rows: 3, - }; - } - static get styles(): CSSResultGroup { return css` ha-card { From 81c796beb43b03f3e28a41a8aa298b9da8398de3 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 3 Jul 2024 13:16:55 +0200 Subject: [PATCH 36/86] Fix area card background and improve grid support (#21259) --- src/panels/lovelace/cards/hui-area-card.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/panels/lovelace/cards/hui-area-card.ts b/src/panels/lovelace/cards/hui-area-card.ts index 5ebf4b4eae05..387110d9ae19 100644 --- a/src/panels/lovelace/cards/hui-area-card.ts +++ b/src/panels/lovelace/cards/hui-area-card.ts @@ -412,19 +412,19 @@ export class HuiAreaCard if (this._config.show_camera && "camera" in entitiesByDomain) { cameraEntityId = entitiesByDomain.camera[0].entity_id; } - cameraEntityId = "camera.demo_camera"; const imageClass = area.picture || cameraEntityId; - const ignoreAspectRatio = imageClass || this.layout === "grid"; + const ignoreAspectRatio = this.layout === "grid"; return html` ${area.picture || cameraEntityId @@ -435,8 +435,10 @@ export class HuiAreaCard .image=${area.picture ? area.picture : undefined} .cameraImage=${cameraEntityId} .cameraView=${this._config.camera_view} - .aspectRatio=${this._config.aspect_ratio || - DEFAULT_ASPECT_RATIO} + .aspectRatio=${ignoreAspectRatio + ? undefined + : this._config.aspect_ratio || DEFAULT_ASPECT_RATIO} + fitMode="cover" > ` : area.icon @@ -586,6 +588,10 @@ export class HuiAreaCard opacity: 0.12; } + .image hui-image { + height: 100%; + } + .icon-container { position: absolute; top: 0; From d833910796917d779ec3f66dd2c95948ebe0e8fc Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 3 Jul 2024 13:52:53 +0200 Subject: [PATCH 37/86] Fix demo development inside a dev container (#21261) --- .devcontainer/devcontainer.json | 1 + build-scripts/env.cjs | 3 +++ build-scripts/gulp/webpack.js | 6 +++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d6033abcd080..7f8ab1df13e7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,6 +8,7 @@ "postCreateCommand": "sudo apt update && sudo apt upgrade -y && sudo apt install -y libpcap-dev", "postStartCommand": "script/bootstrap", "containerEnv": { + "DEV_CONTAINER": "1", "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" }, "customizations": { diff --git a/build-scripts/env.cjs b/build-scripts/env.cjs index bb0d6b3d0028..6f208b779b33 100644 --- a/build-scripts/env.cjs +++ b/build-scripts/env.cjs @@ -32,4 +32,7 @@ module.exports = { } return version[1]; }, + isDevContainer() { + return process.env.DEV_CONTAINER === "1"; + }, }; diff --git a/build-scripts/gulp/webpack.js b/build-scripts/gulp/webpack.js index 51f062f316e1..a7eb3be20d8e 100644 --- a/build-scripts/gulp/webpack.js +++ b/build-scripts/gulp/webpack.js @@ -40,8 +40,12 @@ const runDevServer = async ({ compiler, contentBase, port, - listenHost = "localhost", + listenHost = undefined, }) => { + if (listenHost === undefined) { + // For dev container, we need to listen on all hosts + listenHost = env.isDevContainer() ? "0.0.0.0" : "localhost"; + } const server = new WebpackDevServer( { hot: false, From 2b5fba4a30c99df2cb686ffc3b1e2bdb70c53080 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 3 Jul 2024 14:08:38 +0200 Subject: [PATCH 38/86] Add support for capability attributes in demo (#21263) --- src/fake_data/entity.ts | 75 ++++++++++++++++++++++++++++++++--- src/fake_data/provide_hass.ts | 2 + 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/fake_data/entity.ts b/src/fake_data/entity.ts index 2ea81b3feacf..232b75de1ff5 100644 --- a/src/fake_data/entity.ts +++ b/src/fake_data/entity.ts @@ -10,6 +10,18 @@ const now = () => new Date().toISOString(); const randomTime = () => new Date(new Date().getTime() - Math.random() * 80 * 60 * 1000).toISOString(); +const CAPABILITY_ATTRIBUTES = [ + "friendly_name", + "unit_of_measurement", + "icon", + "entity_picture", + "supported_features", + "hidden", + "assumed_state", + "device_class", + "state_class", + "restored", +]; export class Entity { public domain: string; @@ -29,16 +41,28 @@ export class Entity { public hass?: any; - constructor(domain, objectId, state, baseAttributes) { + static CAPABILITY_ATTRIBUTES = new Set(CAPABILITY_ATTRIBUTES); + + constructor(domain, objectId, state, attributes) { this.domain = domain; this.objectId = objectId; this.entityId = `${domain}.${objectId}`; this.lastChanged = randomTime(); this.lastUpdated = randomTime(); this.state = String(state); + // These are the attributes that we always write to the state machine + const baseAttributes = {}; + const capabilityAttributes = + TYPES[domain]?.CAPABILITY_ATTRIBUTES || Entity.CAPABILITY_ATTRIBUTES; + for (const key of Object.keys(attributes)) { + if (capabilityAttributes.has(key)) { + baseAttributes[key] = attributes[key]; + } + } + this.baseAttributes = baseAttributes; - this.attributes = baseAttributes; + this.attributes = attributes; } public async handleService(domain, service, data: Record) { @@ -54,7 +78,7 @@ export class Entity { this.lastUpdated = now(); this.lastChanged = state === this.state ? this.lastChanged : this.lastUpdated; - this.attributes = { ...this.baseAttributes, ...attributes }; + this.attributes = { ...this.attributes, ...attributes }; // eslint-disable-next-line console.log("update", this.entityId, this); @@ -68,7 +92,7 @@ export class Entity { return { entity_id: this.entityId, state: this.state, - attributes: this.attributes, + attributes: this.state === "off" ? this.baseAttributes : this.attributes, last_changed: this.lastChanged, last_updated: this.lastUpdated, }; @@ -76,6 +100,16 @@ export class Entity { } class LightEntity extends Entity { + static CAPABILITY_ATTRIBUTES = new Set([ + ...CAPABILITY_ATTRIBUTES, + "min_color_temp_kelvin", + "max_color_temp_kelvin", + "min_mireds", + "max_mireds", + "effect_list", + "supported_color_modes", + ]); + public async handleService(domain, service, data) { if (!["homeassistant", this.domain].includes(domain)) { return; @@ -188,6 +222,12 @@ class AlarmControlPanelEntity extends Entity { } class MediaPlayerEntity extends Entity { + static CAPABILITY_ATTRIBUTES = new Set([ + ...CAPABILITY_ATTRIBUTES, + "source_list", + "sound_mode_list", + ]); + public async handleService( domain, service, @@ -223,7 +263,11 @@ class CoverEntity extends Entity { if (service === "open_cover") { this.update("open"); } else if (service === "close_cover") { - this.update("closing"); + this.update("closed"); + } else if (service === "set_cover_position") { + this.update(data.position > 0 ? "open" : "closed", { + current_position: data.position, + }); } else { super.handleService(domain, service, data); } @@ -288,6 +332,19 @@ class InputSelectEntity extends Entity { } class ClimateEntity extends Entity { + static CAPABILITY_ATTRIBUTES = new Set([ + ...CAPABILITY_ATTRIBUTES, + "hvac_modes", + "min_temp", + "max_temp", + "target_temp_step", + "fan_modes", + "preset_modes", + "swing_modes", + "min_humidity", + "max_humidity", + ]); + public async handleService(domain, service, data) { if (domain !== this.domain) { return; @@ -357,6 +414,14 @@ class ClimateEntity extends Entity { } class WaterHeaterEntity extends Entity { + static CAPABILITY_ATTRIBUTES = new Set([ + ...CAPABILITY_ATTRIBUTES, + "current_temperature", + "min_temp", + "max_temp", + "operation_list", + ]); + public async handleService(domain, service, data) { if (domain !== this.domain) { return; diff --git a/src/fake_data/provide_hass.ts b/src/fake_data/provide_hass.ts index 3723fa7321ec..62787c4fef93 100644 --- a/src/fake_data/provide_hass.ts +++ b/src/fake_data/provide_hass.ts @@ -278,6 +278,8 @@ export const provideHass = ( // @ts-ignore async callService(domain, service, data) { if (data && "entity_id" in data) { + // eslint-disable-next-line + console.log("Entity service call", domain, service, data); await Promise.all( ensureArray(data.entity_id).map((ent) => entities[ent].handleService(domain, service, data) From 37af77dabef0989c937dac27a7b2eb6c831d4617 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 3 Jul 2024 14:23:05 +0200 Subject: [PATCH 39/86] Make sure unhidden columns are put at the correct place (#21262) --- .../data-table/dialog-data-table-settings.ts | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/components/data-table/dialog-data-table-settings.ts b/src/components/data-table/dialog-data-table-settings.ts index 265abe0da0c5..1dfe8bbabf49 100644 --- a/src/components/data-table/dialog-data-table-settings.ts +++ b/src/components/data-table/dialog-data-table-settings.ts @@ -202,20 +202,53 @@ export class DialogDataTableSettings extends LitElement { const columns = this._sortedColumns( this._params.columns, this._columnOrder, - this._hiddenColumns + hidden ); if (!this._columnOrder) { this._columnOrder = columns.map((col) => col.key); } else { + const newOrder = this._columnOrder.filter((col) => col !== column); + + // Array.findLastIndex when supported or core-js polyfill + const findLastIndex = ( + arr: Array, + fn: (item: any, index: number, arr: Array) => boolean + ) => { + for (let i = arr.length - 1; i >= 0; i--) { + if (fn(arr[i], i, arr)) return i; + } + return -1; + }; + + let lastMoveable = findLastIndex( + newOrder, + (col) => + col !== column && + !hidden.includes(col) && + !this._params!.columns[col].main && + this._params!.columns[col].moveable !== false + ); + + if (lastMoveable === -1) { + lastMoveable = newOrder.length - 1; + } + columns.forEach((col) => { - if (!this._columnOrder!.includes(col.key)) { - this._columnOrder!.push(col.key); + if (!newOrder.includes(col.key)) { + if (col.moveable === false) { + newOrder.unshift(col.key); + } else { + newOrder.splice(lastMoveable + 1, 0, col.key); + } + if (col.defaultHidden) { hidden.push(col.key); } } }); + + this._columnOrder = newOrder; } this._hiddenColumns = hidden; From 57e48e2561c1c1087349bbe35590e668f8fce2ed Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 3 Jul 2024 14:23:31 +0200 Subject: [PATCH 40/86] Bumped version to 20240703.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a045f384a64a..6aa93e24f7a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240702.0" +version = "20240703.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From 522f66423bdcab7482cd46b7fda85028383ec879 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 3 Jul 2024 15:26:19 +0200 Subject: [PATCH 41/86] Fix demo map panel (#21265) --- demo/src/stubs/entities.ts | 50 ++++++++++++++++++++++++++++++++++++ demo/src/stubs/lovelace.ts | 17 +++++++++--- src/fake_data/demo_panels.ts | 4 +-- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/demo/src/stubs/entities.ts b/demo/src/stubs/entities.ts index 132515a014ad..8c863f9a3bb6 100644 --- a/demo/src/stubs/entities.ts +++ b/demo/src/stubs/entities.ts @@ -1,5 +1,55 @@ import { convertEntities } from "../../../src/fake_data/entity"; +export const mapEntities = () => + convertEntities({ + "zone.home": { + entity_id: "zone.home", + state: "zoning", + attributes: { + hidden: true, + latitude: 52.3631339, + longitude: 4.8903147, + radius: 200, + friendly_name: "Home", + icon: "hademo:home", + }, + }, + "zone.uva": { + entity_id: "zone.buckhead", + state: "zoning", + attributes: { + hidden: true, + radius: 400, + friendly_name: "UvA", + icon: "hademo:school", + latitude: 52.3558182, + longitude: 4.9535376, + }, + }, + "person.arsaboo": { + entity_id: "person.arsaboo", + state: "not_home", + attributes: { + radius: 50, + friendly_name: "Arsaboo", + latitude: 52.3579946, + longitude: 4.8664597, + entity_picture: "/assets/arsaboo/images/arsaboo.jpg", + }, + }, + "person.melody": { + entity_id: "person.melody", + state: "not_home", + attributes: { + radius: 50, + friendly_name: "Melody", + latitude: 52.3408927, + longitude: 4.8711073, + entity_picture: "/assets/arsaboo/images/melody.jpg", + }, + }, + }); + export const energyEntities = () => convertEntities({ "sensor.grid_fossil_fuel_percentage": { diff --git a/demo/src/stubs/lovelace.ts b/demo/src/stubs/lovelace.ts index 6896de37ef09..8712f51a66a2 100644 --- a/demo/src/stubs/lovelace.ts +++ b/demo/src/stubs/lovelace.ts @@ -7,16 +7,25 @@ import { } from "../configs/demo-configs"; import "../custom-cards/cast-demo-row"; import "../custom-cards/ha-demo-card"; +import { mapEntities } from "./entities"; export const mockLovelace = ( hass: MockHomeAssistant, localizePromise: Promise ) => { - hass.mockWS("lovelace/config", () => - Promise.all([selectedDemoConfig, localizePromise]).then( + hass.mockWS("lovelace/config", ({ url_path }) => { + if (url_path === "map") { + hass.addEntities(mapEntities()); + return { + strategy: { + type: "map", + }, + }; + } + return Promise.all([selectedDemoConfig, localizePromise]).then( ([config, localize]) => config.lovelace(localize) - ) - ); + ); + }); hass.mockWS("lovelace/config/save", () => Promise.resolve()); hass.mockWS("lovelace/resources", () => Promise.resolve([])); diff --git a/src/fake_data/demo_panels.ts b/src/fake_data/demo_panels.ts index 319aa4997827..dbf70b4b1df8 100644 --- a/src/fake_data/demo_panels.ts +++ b/src/fake_data/demo_panels.ts @@ -66,10 +66,10 @@ export const demoPanels: Panels = { // url_path: "history", // }, map: { - component_name: "map", + component_name: "lovelace", icon: "hass:tooltip-account", title: "map", - config: null, + config: { mode: "storage" }, url_path: "map", }, energy: { From 97c4cf9391955fc1a066546575aeb3f6b082e9b0 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 3 Jul 2024 15:33:00 +0200 Subject: [PATCH 42/86] Hide some things in demo (#21268) --- .../more-info/controls/more-info-media_player.ts | 3 ++- src/dialogs/more-info/ha-more-info-dialog.ts | 2 +- src/dialogs/more-info/ha-more-info-history.ts | 12 +++++++----- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts index 1cd8c228120d..34971e593ba0 100644 --- a/src/dialogs/more-info/controls/more-info-media_player.ts +++ b/src/dialogs/more-info/controls/more-info-media_player.ts @@ -63,7 +63,8 @@ class MoreInfoMediaPlayer extends LitElement { ` )}
- ${!isUnavailableState(stateObj.state) && + ${!__DEMO__ && + !isUnavailableState(stateObj.state) && supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA) ? html` ` : nothing} - ${isAdmin + ${!__DEMO__ && isAdmin ? html` ${this.hass.localize("ui.dialogs.more_info_control.history")}
-
${this.hass.localize( - "ui.dialogs.more_info_control.show_more" - )} + ${__DEMO__ + ? nothing + : html`${this.hass.localize( + "ui.dialogs.more_info_control.show_more" + )}`}
${this._error ? html`
${this._error}
` From e332364ec0f445ade3b73f4de3388460a69093cb Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Wed, 3 Jul 2024 08:56:44 -0700 Subject: [PATCH 43/86] Fix automation picker overflow menu for keyboard (#21048) * Fix automation picker overflow menu for keyboard * some updates from review * typing * no removeEventListener * updates from review --- src/components/ha-menu-item.ts | 4 +- src/components/ha-menu.ts | 25 +++++++ .../config/automation/ha-automation-picker.ts | 73 +++++++++++-------- 3 files changed, 69 insertions(+), 33 deletions(-) diff --git a/src/components/ha-menu-item.ts b/src/components/ha-menu-item.ts index b6b133c68115..2f2914859640 100644 --- a/src/components/ha-menu-item.ts +++ b/src/components/ha-menu-item.ts @@ -1,9 +1,11 @@ import { MdMenuItem } from "@material/web/menu/menu-item"; import { css } from "lit"; -import { customElement } from "lit/decorators"; +import { customElement, property } from "lit/decorators"; @customElement("ha-menu-item") export class HaMenuItem extends MdMenuItem { + @property({ attribute: false }) clickAction?: (item?: HTMLElement) => void; + static override styles = [ ...super.styles, css` diff --git a/src/components/ha-menu.ts b/src/components/ha-menu.ts index 06c2d5f91def..06e1de186329 100644 --- a/src/components/ha-menu.ts +++ b/src/components/ha-menu.ts @@ -1,9 +1,30 @@ import { MdMenu } from "@material/web/menu/menu"; +import type { CloseMenuEvent } from "@material/web/menu/menu"; +import { + CloseReason, + KeydownCloseKey, +} from "@material/web/menu/internal/controllers/shared"; import { css } from "lit"; import { customElement } from "lit/decorators"; +import type { HaMenuItem } from "./ha-menu-item"; @customElement("ha-menu") export class HaMenu extends MdMenu { + connectedCallback(): void { + super.connectedCallback(); + this.addEventListener("close-menu", this._handleCloseMenu); + } + + private _handleCloseMenu(ev: CloseMenuEvent) { + if ( + ev.detail.reason.kind === CloseReason.KEYDOWN && + ev.detail.reason.key === KeydownCloseKey.ESCAPE + ) { + return; + } + (ev.detail.initiator as HaMenuItem).clickAction?.(ev.detail.initiator); + } + static override styles = [ ...super.styles, css` @@ -18,4 +39,8 @@ declare global { interface HTMLElementTagNameMap { "ha-menu": HaMenu; } + + interface HTMLElementEventMap { + "close-menu": CloseMenuEvent; + } } diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts index 3c0f0d10df8c..7bef54309e4b 100644 --- a/src/panels/config/automation/ha-automation-picker.ts +++ b/src/panels/config/automation/ha-automation-picker.ts @@ -68,6 +68,7 @@ import "../../../components/ha-icon-overflow-menu"; import "../../../components/ha-menu"; import type { HaMenu } from "../../../components/ha-menu"; import "../../../components/ha-menu-item"; +import type { HaMenuItem } from "../../../components/ha-menu-item"; import "../../../components/ha-sub-menu"; import "../../../components/ha-svg-icon"; import { createAreaRegistryEntry } from "../../../data/area_registry"; @@ -826,7 +827,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { - + - +
${this.hass.localize( @@ -844,7 +845,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { )}
- +
${this.hass.localize( @@ -852,13 +853,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { )}
- +
${this.hass.localize("ui.panel.config.automation.editor.run")}
- +
${this.hass.localize( @@ -867,13 +868,13 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) {
- +
${this.hass.localize("ui.panel.config.automation.picker.duplicate")}
- + - +
${this.hass.localize("ui.panel.config.automation.picker.delete")} @@ -1055,28 +1056,32 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { this._applyFilters(); } - private _showInfo(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _showInfo = (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; fireEvent(this, "hass-more-info", { entityId: automation.entity_id }); - } + }; - private _showSettings(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _showSettings = (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; fireEvent(this, "hass-more-info", { entityId: automation.entity_id, view: "settings", }); - } + }; - private _runActions(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _runActions = (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; triggerAutomationActions(this.hass, automation.entity_id); - } + }; - private _editCategory(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _editCategory = (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; const entityReg = this._entityReg.find( (reg) => reg.entity_id === automation.entity_id @@ -1096,10 +1101,11 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { scope: "automation", entityReg, }); - } + }; - private _showTrace(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _showTrace = (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; if (!automation.attributes.id) { showAlertDialog(this, { @@ -1112,19 +1118,21 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { navigate( `/config/automation/trace/${encodeURIComponent(automation.attributes.id)}` ); - } + }; - private async _toggle(ev): Promise { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _toggle = async (item: HaMenuItem): Promise => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; const service = automation.state === "off" ? "turn_on" : "turn_off"; await this.hass.callService("automation", service, { entity_id: automation.entity_id, }); - } + }; - private async _deleteConfirm(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _deleteConfirm = async (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; showConfirmationDialog(this, { title: this.hass.localize( @@ -1139,7 +1147,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { confirm: () => this._delete(automation), destructive: true, }); - } + }; private async _delete(automation) { try { @@ -1159,8 +1167,9 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { } } - private async _duplicate(ev) { - const automation = ev.currentTarget.parentElement.anchorElement.automation; + private _duplicate = async (item: HaMenuItem) => { + const automation = ((item.parentElement as HaMenu)!.anchorElement as any)! + .automation; try { const config = await fetchAutomationFileConfig( @@ -1184,7 +1193,7 @@ class HaAutomationPicker extends SubscribeMixin(LitElement) { ), }); } - } + }; private _showHelp() { showAlertDialog(this, { From 1ceef7c3d33547ef4805f7f40d3e324d37c17192 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 3 Jul 2024 22:32:56 +0200 Subject: [PATCH 44/86] Set min column size to 1 for vertical tile card (#21275) --- src/panels/lovelace/cards/hui-tile-card.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 19a05e3bb4ab..ae8c8a99c0b8 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -123,19 +123,21 @@ export class HuiTileCard extends LitElement implements LovelaceCard { public getLayoutOptions(): LovelaceLayoutOptions { const grid_columns = 2; + let grid_min_columns = 2; let grid_rows = 1; if (this._config?.features?.length) { const featureHeight = Math.ceil((this._config.features.length * 2) / 3); grid_rows += featureHeight; } if (this._config?.vertical) { - grid_rows!++; + grid_rows++; + grid_min_columns = 1; } return { grid_columns, grid_rows, grid_min_rows: grid_rows, - grid_min_columns: grid_columns, + grid_min_columns, }; } From c07e1122e156ee72a5bf2ed0267feb7863058f60 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 4 Jul 2024 08:11:39 +0200 Subject: [PATCH 45/86] Tweak demo, add some translations, tweak media players (#21271) Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../images/media_player_family_room.jpg | Bin 0 -> 30519 bytes demo/src/configs/sections/entities.ts | 74 ++++++++++++++++-- demo/src/configs/sections/lovelace.ts | 21 +++-- .../controls/more-info-media_player.ts | 3 +- src/translations/en.json | 19 ++++- 5 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 demo/public/assets/sections/images/media_player_family_room.jpg diff --git a/demo/public/assets/sections/images/media_player_family_room.jpg b/demo/public/assets/sections/images/media_player_family_room.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e73833aa305179403ee04bfd0c4762195740ae80 GIT binary patch literal 30519 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 literal 0 HcmV?d00001 diff --git a/demo/src/configs/sections/entities.ts b/demo/src/configs/sections/entities.ts index 1900624b8304..1bdb06f8a9ad 100644 --- a/demo/src/configs/sections/entities.ts +++ b/demo/src/configs/sections/entities.ts @@ -1,7 +1,7 @@ import { convertEntities } from "../../../../src/fake_data/entity"; import { DemoConfig } from "../types"; -export const demoEntitiesSections: DemoConfig["entities"] = () => +export const demoEntitiesSections: DemoConfig["entities"] = (localize) => convertEntities({ "cover.living_room_garden_shutter": { entity_id: "cover.living_room_garden_shutter", @@ -113,11 +113,30 @@ export const demoEntitiesSections: DemoConfig["entities"] = () => }, "media_player.living_room_nest_mini": { entity_id: "media_player.living_room_nest_mini", - state: "off", + state: "on", attributes: { device_class: "speaker", - friendly_name: "Living room Nest Mini", - supported_features: 152461, + volume_level: 0.18, + is_volume_muted: false, + media_content_type: "music", + media_duration: 300, + media_position: 0, + media_position_updated_at: new Date( + // 23 seconds in + new Date().getTime() - 23000 + ).toISOString(), + media_title: "I Wasn't Born To Follow", + media_artist: "The Byrds", + media_album_name: "The Notorious Byrd Brothers", + source_list: ["It's A Party", "Radio HSL", "Retro 70s and 80s"], + shuffle: false, + night_sound: false, + speech_enhance: false, + friendly_name: localize( + "ui.panel.page-demo.config.sections.entities.media_player.living_room_nest_mini" + ), + entity_picture: "/assets/sections/images/media_player_family_room.jpg", + supported_features: 64063, }, }, "cover.kitchen_shutter": { @@ -168,8 +187,27 @@ export const demoEntitiesSections: DemoConfig["entities"] = () => state: "on", attributes: { device_class: "speaker", - friendly_name: "Kitchen Nest Audio", - supported_features: 152461, + volume_level: 0.18, + is_volume_muted: false, + media_content_type: "music", + media_duration: 300, + media_position: 0, + media_position_updated_at: new Date( + // 23 seconds in + new Date().getTime() - 23000 + ).toISOString(), + media_title: "I Wasn't Born To Follow", + media_artist: "The Byrds", + media_album_name: "The Notorious Byrd Brothers", + source_list: ["It's A Party", "Radio HSL", "Retro 70s and 80s"], + shuffle: false, + night_sound: false, + speech_enhance: false, + friendly_name: localize( + "ui.panel.page-demo.config.sections.entities.media_player.kitchen_nest_audio" + ), + entity_picture: "/assets/sections/images/media_player_family_room.jpg", + supported_features: 64063, }, }, "binary_sensor.tesla_wall_connector_vehicle_connected": { @@ -333,8 +371,28 @@ export const demoEntitiesSections: DemoConfig["entities"] = () => entity_id: "media_player.study_nest_hub", state: "off", attributes: { - friendly_name: "Study Nest Hub", - supported_features: 152461, + device_class: "speaker", + volume_level: 0.18, + is_volume_muted: false, + media_content_type: "music", + media_duration: 300, + media_position: 0, + media_position_updated_at: new Date( + // 23 seconds in + new Date().getTime() - 23000 + ).toISOString(), + media_title: "I Wasn't Born To Follow", + media_artist: "The Byrds", + media_album_name: "The Notorious Byrd Brothers", + source_list: ["It's A Party", "Radio HSL", "Retro 70s and 80s"], + shuffle: false, + night_sound: false, + speech_enhance: false, + friendly_name: localize( + "ui.panel.page-demo.config.sections.entities.media_player.study_nest_hub" + ), + entity_picture: "/assets/sections/images/media_player_family_room.jpg", + supported_features: 64063, }, }, "sensor.standing_desk_height": { diff --git a/demo/src/configs/sections/lovelace.ts b/demo/src/configs/sections/lovelace.ts index 36b4abb2fe9c..f09c0595c6da 100644 --- a/demo/src/configs/sections/lovelace.ts +++ b/demo/src/configs/sections/lovelace.ts @@ -1,7 +1,7 @@ import { isFrontpageEmbed } from "../../util/is_frontpage"; import { DemoConfig } from "../types"; -export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ +export const demoLovelaceSections: DemoConfig["lovelace"] = (localize) => ({ title: "Home Assistant Demo", views: [ { @@ -14,7 +14,7 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ ? [] : [ { - title: "Welcome 👋", + title: `${localize("ui.panel.page-demo.config.sections.titles.welcome")} 👋`, cards: [{ type: "custom:ha-demo-card" }], }, ]), @@ -53,10 +53,9 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ { type: "tile", entity: "media_player.living_room_nest_mini", - name: "Nest Mini", }, ], - title: "🛋️ Living room ", + title: `🛋️ ${localize("ui.panel.page-demo.config.sections.titles.living_room")} `, }, { type: "grid", @@ -89,10 +88,9 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ { type: "tile", entity: "media_player.kitchen_nest_audio", - name: "Nest Audio", }, ], - title: "👩‍🍳 Kitchen", + title: `👩‍🍳 ${localize("ui.panel.page-demo.config.sections.titles.kitchen")}`, }, { type: "grid", @@ -134,7 +132,7 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ color: "dark-grey", }, ], - title: "⚡️ Energy", + title: `⚡️ ${localize("ui.panel.page-demo.config.sections.titles.energy")}`, }, { type: "grid", @@ -171,7 +169,7 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ state_content: ["preset_mode", "current_temperature"], }, ], - title: "🌤️ Climate", + title: `🌤️ ${localize("ui.panel.page-demo.config.sections.titles.climate")}`, }, { type: "grid", @@ -189,7 +187,6 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ { type: "tile", entity: "media_player.study_nest_hub", - name: "Nest Hub", }, { type: "tile", @@ -199,7 +196,7 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ icon: "mdi:desk", }, ], - title: "🧑‍💻 Study", + title: `🧑‍💻 ${localize("ui.panel.page-demo.config.sections.titles.study")}`, }, { type: "grid", @@ -233,7 +230,7 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ name: "Illuminance", }, ], - title: "🌳 Outdoor", + title: `🌳 ${localize("ui.panel.page-demo.config.sections.titles.outdoor")}`, }, { type: "grid", @@ -263,7 +260,7 @@ export const demoLovelaceSections: DemoConfig["lovelace"] = () => ({ icon: "mdi:home-assistant", }, ], - title: "🎉 Updates", + title: `🎉 ${localize("ui.panel.page-demo.config.sections.titles.updates")}`, }, ], }, diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts index 34971e593ba0..1cd8c228120d 100644 --- a/src/dialogs/more-info/controls/more-info-media_player.ts +++ b/src/dialogs/more-info/controls/more-info-media_player.ts @@ -63,8 +63,7 @@ class MoreInfoMediaPlayer extends LitElement { ` )}
- ${!__DEMO__ && - !isUnavailableState(stateObj.state) && + ${!isUnavailableState(stateObj.state) && supportsFeature(stateObj, MediaPlayerEntityFeature.BROWSE_MEDIA) ? html` Date: Thu, 4 Jul 2024 04:01:01 -0400 Subject: [PATCH 46/86] Clean up imports and unopened tag on device config page (#21274) --- .../config/devices/ha-config-device-page.ts | 462 ++++++++---------- 1 file changed, 212 insertions(+), 250 deletions(-) diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 7b3849ec665a..1a9809b9b68a 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -1,6 +1,5 @@ import { consume } from "@lit-labs/context"; import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; -import "@material/mwc-list/mwc-list-item"; import { mdiCog, mdiDelete, @@ -10,8 +9,6 @@ import { mdiPencil, mdiPlusCircle, } from "@mdi/js"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-item/paper-item-body"; import { CSSResultGroup, LitElement, @@ -24,7 +21,7 @@ import { customElement, property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; import memoizeOne from "memoize-one"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; -import { SENSOR_ENTITIES, ASSIST_ENTITIES } from "../../../common/const"; +import { ASSIST_ENTITIES, SENSOR_ENTITIES } from "../../../common/const"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; @@ -77,7 +74,6 @@ import type { HomeAssistant } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; import { fileDownload } from "../../../util/file_download"; import "../../logbook/ha-logbook"; -import "../ha-config-section"; import "./device-detail/ha-device-entities-card"; import "./device-detail/ha-device-info-card"; import "./device-detail/ha-device-via-devices-card"; @@ -665,269 +661,235 @@ export class HaConfigDevicePage extends LitElement { ` : ""; - return html` - - - + +
+
+ ${area + ? html`` + : ""} +
+ ${battery && + (batteryDomain === "binary_sensor" || !isNaN(battery.state as any)) + ? html` +
+ ${batteryDomain === "sensor" + ? this.hass.formatEntityState(battery) + : nothing} + +
+ ` + : ""} + ${integrations.length + ? html` + ${domainToName( + ` + : ""} +
+
+
+ ${this._deviceAlerts?.length + ? html` +
+ ${this._deviceAlerts.map( + (alert) => html` + + ${alert.text} + + ` )} - > -
-
- ${ - area - ? html`` - : "" - } -
- ${ - battery && - (batteryDomain === "binary_sensor" || - !isNaN(battery.state as any)) - ? html` -
- ${batteryDomain === "sensor" - ? this.hass.formatEntityState(battery) - : nothing} - -
- ` - : "" - } - ${ - integrations.length - ? html` - ${domainToName( - ` - : "" - } -
-
-
- ${ - this._deviceAlerts?.length - ? html` -
- ${this._deviceAlerts.map( - (alert) => html` - - ${alert.text} - - ` + ` + : ""} + + ${deviceInfo} + ${firstDeviceAction || actions.length + ? html` +
+
+ - ` - : "" - } - - ${deviceInfo} - ${ - firstDeviceAction || actions.length - ? html` -
- + + ${actions.length + ? html` + + + ${actions.map((deviceAction) => { + const listItem = html` - ${firstDeviceAction!.label} - ${firstDeviceAction!.icon + ${deviceAction.label} + ${deviceAction.icon ? html` ` : ""} - ${firstDeviceAction!.trailingIcon + ${deviceAction.trailingIcon ? html` ` : ""} - - -
- - ${actions.length - ? html` - - `; + return deviceAction.href + ? html` - ${actions.map((deviceAction) => { - const listItem = html` - ${deviceAction.label} - ${deviceAction.icon - ? html` - - ` - : ""} - ${deviceAction.trailingIcon - ? html` - - ` - : ""} - `; - return deviceAction.href - ? html`${listItem} - ` - : listItem; - })} - - ` - : ""} -
- ` - : "" - } - - ${!this.narrow ? [automationCard, sceneCard, scriptCard] : ""} -
-
- ${( - [ - "control", - "sensor", - "notify", - "event", - "assist", - "config", - "diagnostic", - ] as const - ).map((category) => - // Make sure we render controls if no other cards will be rendered - entitiesByCategory[category].length > 0 || - (entities.length === 0 && category === "control") - ? html` - - - ` - : "" - )} - -
-
- ${this.narrow ? [automationCard, sceneCard, scriptCard] : ""} - ${ - isComponentLoaded(this.hass, "logbook") - ? html` - -

- ${this.hass.localize("panel.logbook")} -

- -
- ` - : "" - } -
-
- - `; + >${listItem} + ` + : listItem; + })} + + ` + : ""} +
+ ` + : ""} + + ${!this.narrow ? [automationCard, sceneCard, scriptCard] : ""} +
+
+ ${( + [ + "control", + "sensor", + "notify", + "event", + "assist", + "config", + "diagnostic", + ] as const + ).map((category) => + // Make sure we render controls if no other cards will be rendered + entitiesByCategory[category].length > 0 || + (entities.length === 0 && category === "control") + ? html` + + + ` + : "" + )} + +
+
+ ${this.narrow ? [automationCard, sceneCard, scriptCard] : ""} + ${isComponentLoaded(this.hass, "logbook") + ? html` + +

+ ${this.hass.localize("panel.logbook")} +

+ +
+ ` + : ""} +
+
+ `; } private async _getDiagnosticButtons(requestId: number): Promise { From df7b5b08cf25f86beb013661a3ebd1648358a830 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 4 Jul 2024 11:46:10 +0200 Subject: [PATCH 47/86] Allow custom localize function for datatable (#21270) --- src/components/data-table/ha-data-table.ts | 11 +++++++++-- src/layouts/hass-tabs-subpage-data-table.ts | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index bd1507e2eee0..1819256bab0c 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -34,6 +34,7 @@ import type { HaCheckbox } from "../ha-checkbox"; import "../ha-svg-icon"; import "../search-input"; import { filterData, sortData } from "./sort-filter"; +import { LocalizeFunc } from "../../common/translations/localize"; export interface RowClickedEvent { id: string; @@ -110,6 +111,8 @@ const UNDEFINED_GROUP_KEY = "zzzzz_undefined"; export class HaDataTable extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; + @property({ attribute: false }) public localizeFunc?: LocalizeFunc; + @property({ type: Boolean }) public narrow = false; @property({ type: Object }) public columns: DataTableColumnContainer = {}; @@ -317,6 +320,8 @@ export class HaDataTable extends LitElement { ); protected render() { + const localize = this.localizeFunc || this.hass.localize; + const columns = this._sortedColumns(this.columns, this.columnOrder); const renderRow = (row: DataTableRowData, index: number) => @@ -436,7 +441,7 @@ export class HaDataTable extends LitElement {
${this.noDataText || - this.hass.localize("ui.components.data-table.no-data")} + localize("ui.components.data-table.no-data")}
@@ -619,6 +624,8 @@ export class HaDataTable extends LitElement { return; } + const localize = this.localizeFunc || this.hass.localize; + if (this.appendRow || this.hasFab || this.groupColumn) { let items = [...data]; @@ -672,7 +679,7 @@ export class HaDataTable extends LitElement { > ${groupName === UNDEFINED_GROUP_KEY - ? this.hass.localize("ui.components.data-table.ungrouped") + ? localize("ui.components.data-table.ungrouped") : groupName || ""}
`, }); diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index 4f062182a2dc..615fb2d5d056 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -430,6 +430,7 @@ export class HaTabsSubpageDataTable extends LitElement { : ""}
- ${this.hass.localize( - "ui.components.subpage-data-table.show_results", - { number: this.data.length } - )} + ${localize("ui.components.subpage-data-table.show_results", { + number: this.data.length, + })}
` From 15589927c8b93e640b74dacda4e9c6d1c88567ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:46:55 +0200 Subject: [PATCH 48/86] Update dependency @codemirror/view to v6.28.3 (#21277) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 292983f4ad45..24d847dcce6a 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@codemirror/legacy-modes": "6.4.0", "@codemirror/search": "6.5.6", "@codemirror/state": "6.4.1", - "@codemirror/view": "6.28.2", + "@codemirror/view": "6.28.3", "@egjs/hammerjs": "2.0.17", "@formatjs/intl-datetimeformat": "6.12.5", "@formatjs/intl-displaynames": "6.6.8", diff --git a/yarn.lock b/yarn.lock index 255077cb166b..16d13741a67e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1539,14 +1539,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:6.28.2, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0": - version: 6.28.2 - resolution: "@codemirror/view@npm:6.28.2" +"@codemirror/view@npm:6.28.3, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0": + version: 6.28.3 + resolution: "@codemirror/view@npm:6.28.3" dependencies: "@codemirror/state": "npm:^6.4.0" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: 10/c4221d6e47112ec3ec20c954deecab4565a8023dfeefabff8ba1801fb67d2965d49c27853310618fd723077ca86564b4bbefa36f0839d9430518f7d0a1cc3e84 + checksum: 10/4732786b1afa3730a2c08b3711b335b8da2cb76318c9c4b2aeafd868bb36bfaeec826a18669b3d2d0f408e8012734689085633e4b6c3609cd2385838d79e5bc6 languageName: node linkType: hard @@ -8902,7 +8902,7 @@ __metadata: "@codemirror/legacy-modes": "npm:6.4.0" "@codemirror/search": "npm:6.5.6" "@codemirror/state": "npm:6.4.1" - "@codemirror/view": "npm:6.28.2" + "@codemirror/view": "npm:6.28.3" "@egjs/hammerjs": "npm:2.0.17" "@formatjs/intl-datetimeformat": "npm:6.12.5" "@formatjs/intl-displaynames": "npm:6.6.8" From 202bd148efa0141eb65fd1347f16b145e2b54e2a Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 4 Jul 2024 12:29:17 +0200 Subject: [PATCH 49/86] Fix iframe card overflow in vertical stack (#21282) --- src/panels/lovelace/cards/hui-iframe-card.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/panels/lovelace/cards/hui-iframe-card.ts b/src/panels/lovelace/cards/hui-iframe-card.ts index 36cdea605ec3..48113e02d6d8 100644 --- a/src/panels/lovelace/cards/hui-iframe-card.ts +++ b/src/panels/lovelace/cards/hui-iframe-card.ts @@ -129,6 +129,8 @@ export class HuiIframeCard extends LitElement implements LovelaceCard { overflow: hidden; width: 100%; height: 100%; + display: flex; + flex-direction: column; } #root { From b411ae028689f695be4735ed070d20f35368f896 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:18:37 +0200 Subject: [PATCH 50/86] Update dependency @lokalise/node-api to v12.6.0 (#21291) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 24d847dcce6a..b5cba2ab3737 100644 --- a/package.json +++ b/package.json @@ -157,7 +157,7 @@ "@babel/preset-typescript": "7.24.7", "@bundle-stats/plugin-webpack-filter": "4.13.3", "@koa/cors": "5.0.0", - "@lokalise/node-api": "12.5.0", + "@lokalise/node-api": "12.6.0", "@octokit/auth-oauth-device": "7.1.1", "@octokit/plugin-retry": "7.1.1", "@octokit/rest": "21.0.0", diff --git a/yarn.lock b/yarn.lock index 16d13741a67e..16ff05d601e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2221,10 +2221,10 @@ __metadata: languageName: node linkType: hard -"@lokalise/node-api@npm:12.5.0": - version: 12.5.0 - resolution: "@lokalise/node-api@npm:12.5.0" - checksum: 10/f070847c5dcf450e060c5cc8a92e1b731c9509c85492ac8864a7e49c16e6532d6aaae76cb3f374c356dbf84d72d548a61d40f89afd6d8090cc16a700b069299a +"@lokalise/node-api@npm:12.6.0": + version: 12.6.0 + resolution: "@lokalise/node-api@npm:12.6.0" + checksum: 10/966f4d014c12ef91745925cd6e21698ca35db6483ee50b938e1029509d7c37d0a881bdc673f18debd2fedcafade8c2ce22aa39bea53e0861ba5243a2c646921b languageName: node linkType: hard @@ -8924,7 +8924,7 @@ __metadata: "@lit-labs/motion": "npm:1.0.7" "@lit-labs/observers": "npm:2.0.2" "@lit-labs/virtualizer": "npm:2.0.13" - "@lokalise/node-api": "npm:12.5.0" + "@lokalise/node-api": "npm:12.6.0" "@lrnwebcomponents/simple-tooltip": "npm:8.0.2" "@material/chips": "npm:=14.0.0-canary.53b3cad2f.0" "@material/data-table": "npm:=14.0.0-canary.53b3cad2f.0" From 1abebdae21b9011af9f19442ee148b6c7310b74f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 20:07:42 +0200 Subject: [PATCH 51/86] Update typescript-eslint monorepo to v7.15.0 (#21296) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index b5cba2ab3737..aac30ded713c 100644 --- a/package.json +++ b/package.json @@ -185,8 +185,8 @@ "@types/tar": "6.1.13", "@types/ua-parser-js": "0.7.39", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "7.14.1", - "@typescript-eslint/parser": "7.14.1", + "@typescript-eslint/eslint-plugin": "7.15.0", + "@typescript-eslint/parser": "7.15.0", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.3", diff --git a/yarn.lock b/yarn.lock index 16ff05d601e9..02e62368d9c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4584,15 +4584,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/eslint-plugin@npm:7.14.1" +"@typescript-eslint/eslint-plugin@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.15.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.14.1" - "@typescript-eslint/type-utils": "npm:7.14.1" - "@typescript-eslint/utils": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" + "@typescript-eslint/scope-manager": "npm:7.15.0" + "@typescript-eslint/type-utils": "npm:7.15.0" + "@typescript-eslint/utils": "npm:7.15.0" + "@typescript-eslint/visitor-keys": "npm:7.15.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -4603,44 +4603,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/48c815dbb92399965483c93b27816fad576c3b3227b59eebfe5525e24d07b39ec8b0c7459de83865c8d61c818696519f50b229714dd3ed705d5b35973bfcc781 + checksum: 10/e6b21687ab9e9dc38eb1b1d90a3ac483f3f5e5e9c49aa8a434a24de016822d65c82b926cda2ae79bac2225bd9495fb04f7aa6afcaad2b09f6129fd8014fbcedd languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/parser@npm:7.14.1" +"@typescript-eslint/parser@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/parser@npm:7.15.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.14.1" - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/typescript-estree": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" + "@typescript-eslint/scope-manager": "npm:7.15.0" + "@typescript-eslint/types": "npm:7.15.0" + "@typescript-eslint/typescript-estree": "npm:7.15.0" + "@typescript-eslint/visitor-keys": "npm:7.15.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/f521462a7005cab5e4923937dcf36713d9438ded175b53332ae469d91cc9eb18cb3a23768b3c52063464280baae83f6b66db28cebb2e262d6d869d1a898b23f3 + checksum: 10/0b5e7a14fa5d0680efb17e750a095729a7fb7c785d7a0fea2f9e6cbfef9e65caab2b751654b348b9ab813d222c1c3f8189ebf48561b81224d1821cee5c99d658 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/scope-manager@npm:7.14.1" +"@typescript-eslint/scope-manager@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/scope-manager@npm:7.15.0" dependencies: - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" - checksum: 10/600a7beb96f5b96f675125285137339c2438b5b26db203a66eef52dd409e8c0db0dafb22c94547dfb963f8efdf63b0fb59e05655e2dcf84d54624863365a59e7 + "@typescript-eslint/types": "npm:7.15.0" + "@typescript-eslint/visitor-keys": "npm:7.15.0" + checksum: 10/45bfdbae2d080691a34f5b37679b4a4067981baa3b82922268abdd21f6917a8dd1c4ccb12133f6c9cce81cfd640040913b223e8125235b92f42fdb57db358a3e languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/type-utils@npm:7.14.1" +"@typescript-eslint/type-utils@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/type-utils@npm:7.15.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.14.1" - "@typescript-eslint/utils": "npm:7.14.1" + "@typescript-eslint/typescript-estree": "npm:7.15.0" + "@typescript-eslint/utils": "npm:7.15.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -4648,23 +4648,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/75c279948a7e7e546d692e85a0b48fc3b648ffee1773feb7ff199aba1b0847a9a16c432b133aa72d26e645627403852b7dd24829f9b3badd6d4711c4cc38e9e4 + checksum: 10/64fa589b413567df3689a19ef88f3dbaed66d965e39cc548a58626eb5bd8fc4e2338496eb632f3472de9ae9800cb14d0e48ef3508efe80bdb91af8f3f1e56ad7 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/types@npm:7.14.1" - checksum: 10/608057582bb195bd746a7bfb7c04dac4be1d4602b8fa681b2d1d50b564362b681dc2ca293b13cc4c7acc454f3a09f1ea2580415347efb7853e5df8ba34b7acdb +"@typescript-eslint/types@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/types@npm:7.15.0" + checksum: 10/b36c98344469f4bc54a5199733ea4f6d4d0f2da1070605e60d4031e2da2946b84b91a90108516c8e6e83a21030ba4e935053a0906041c920156de40683297d0b languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/typescript-estree@npm:7.14.1" +"@typescript-eslint/typescript-estree@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.15.0" dependencies: - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/visitor-keys": "npm:7.14.1" + "@typescript-eslint/types": "npm:7.15.0" + "@typescript-eslint/visitor-keys": "npm:7.15.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -4674,31 +4674,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/f75b956f7981712d3f85498f9d9fcc2243d79d6fe71b24bc688a7c43d2a4248f73ecfb78f9d58501fde87fc44b02e26c46f9ea2ae51eb8450db79ca169f91ef9 + checksum: 10/c5fb15108fbbc1bc976e827218ff7bfbc78930c5906292325ee42ba03514623e7b861497b3e3087f71ede9a757b16441286b4d234450450b0dd70ff753782736 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/utils@npm:7.14.1" +"@typescript-eslint/utils@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/utils@npm:7.15.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.14.1" - "@typescript-eslint/types": "npm:7.14.1" - "@typescript-eslint/typescript-estree": "npm:7.14.1" + "@typescript-eslint/scope-manager": "npm:7.15.0" + "@typescript-eslint/types": "npm:7.15.0" + "@typescript-eslint/typescript-estree": "npm:7.15.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/1ef74214ca84e32f151364512a51e82b7da5590dee03d0de0e1abcf18009e569f9a0638506cf03bd4a844af634b4935458e334b7b2459e9a50a67aba7d6228c7 + checksum: 10/f6de1849dee610a8110638be98ab2ec09e7cdf2f756b538b0544df2dfad86a8e66d5326a765302fe31553e8d9d3170938c0d5d38bd9c7d36e3ee0beb1bdc8172 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.14.1": - version: 7.14.1 - resolution: "@typescript-eslint/visitor-keys@npm:7.14.1" +"@typescript-eslint/visitor-keys@npm:7.15.0": + version: 7.15.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.15.0" dependencies: - "@typescript-eslint/types": "npm:7.14.1" + "@typescript-eslint/types": "npm:7.15.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/42246f33cb3f9185c0b467c9a534e34a674e4fc08ba982a03aaa77dc1e569e916f1fca9ce9cd14c4df91f416e6e917bff51f98b8d8ca26ec5f67c253e8646bde + checksum: 10/0e17d7f5de767da7f98170c2efc905cdb0ceeaf04a667e12ca1a92eae64479a07f4f8e2a9b5023b055b01250916c3bcac86908cd06552610baff734fafae4464 languageName: node linkType: hard @@ -8986,8 +8986,8 @@ __metadata: "@types/tar": "npm:6.1.13" "@types/ua-parser-js": "npm:0.7.39" "@types/webspeechapi": "npm:0.0.29" - "@typescript-eslint/eslint-plugin": "npm:7.14.1" - "@typescript-eslint/parser": "npm:7.14.1" + "@typescript-eslint/eslint-plugin": "npm:7.15.0" + "@typescript-eslint/parser": "npm:7.15.0" "@vaadin/combo-box": "npm:24.4.0" "@vaadin/vaadin-themable-mixin": "npm:24.4.0" "@vibrant/color": "npm:3.2.1-alpha.1" From 050bef056431b98f1d398c87740070250f66e421 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 4 Jul 2024 21:09:10 +0200 Subject: [PATCH 52/86] Better handle auto height in card resize editor (#21260) * Add auto-height option to resize editor * Use min instead of max * Remove auto height --- src/components/ha-grid-size-picker.ts | 33 +++++++++++-------- .../card-editor/ha-grid-layout-slider.ts | 3 ++ .../card-editor/hui-card-layout-editor.ts | 8 +++-- .../lovelace/sections/hui-grid-section.ts | 4 +-- src/panels/lovelace/types.ts | 2 +- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/components/ha-grid-size-picker.ts b/src/components/ha-grid-size-picker.ts index 453a24cb8d30..6ae6b7b37d75 100644 --- a/src/components/ha-grid-size-picker.ts +++ b/src/components/ha-grid-size-picker.ts @@ -10,7 +10,7 @@ import { HomeAssistant } from "../types"; import { conditionalClamp } from "../common/number/clamp"; type GridSizeValue = { - rows?: number; + rows?: number | "auto"; columns?: number; }; @@ -47,6 +47,16 @@ export class HaGridSizeEditor extends LitElement { this.columnMin !== undefined && this.columnMin === this.columnMax; const disabledRows = this.rowMin !== undefined && this.rowMin === this.rowMax; + + const autoHeight = this._localValue?.rows === "auto"; + + const rowMin = this.rowMin ?? 1; + const rowMax = this.rowMax ?? this.rows; + const columnMin = this.columnMin ?? 1; + const columnMax = this.columnMax ?? this.columns; + const rowValue = autoHeight ? rowMin : this._localValue?.rows; + const columnValue = this._localValue?.columns; + return html`
+
@@ -215,10 +226,6 @@ export class HaGridSizeEditor extends LitElement { opacity: 0.2; cursor: pointer; } - .preview .cell[disabled] { - opacity: 0.05; - cursor: initial; - } .selected { pointer-events: none; } diff --git a/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts b/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts index ab1bebf00fcc..cfbbd31c3aec 100644 --- a/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts +++ b/src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts @@ -378,6 +378,9 @@ export class HaGridLayoutSlider extends LitElement { :host(:disabled) .handle:after { background: var(--disabled-color); } + :host(:disabled) .active { + background: var(--disabled-color); + } .pressed .handle { transition: none; } diff --git a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts index 5a5690727ce6..ac32343f75e9 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts @@ -11,8 +11,10 @@ import "../../../../components/ha-button-menu"; import "../../../../components/ha-grid-size-picker"; import "../../../../components/ha-icon-button"; import "../../../../components/ha-list-item"; +import "../../../../components/ha-settings-row"; import "../../../../components/ha-slider"; import "../../../../components/ha-svg-icon"; +import "../../../../components/ha-switch"; import "../../../../components/ha-yaml-editor"; import type { HaYamlEditor } from "../../../../components/ha-yaml-editor"; import { LovelaceCardConfig } from "../../../../data/lovelace/config/card"; @@ -61,11 +63,13 @@ export class HuiCardLayoutEditor extends LitElement { this._defaultLayoutOptions ); + const sizeValue = this._gridSizeValue(options); + return html`

${this.hass.localize( - `ui.panel.lovelace.editor.edit_card.layout.explanation` + "ui.panel.lovelace.editor.edit_card.layout.explanation" )}

Date: Thu, 4 Jul 2024 21:09:34 +0200 Subject: [PATCH 53/86] Change delete/remove wording in tag area to be consistent (#21299) delete tags --- src/panels/config/tags/ha-config-tags.ts | 7 ++++--- src/translations/en.json | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/panels/config/tags/ha-config-tags.ts b/src/panels/config/tags/ha-config-tags.ts index 98ae4252f802..933490adfe3c 100644 --- a/src/panels/config/tags/ha-config-tags.ts +++ b/src/panels/config/tags/ha-config-tags.ts @@ -301,12 +301,13 @@ export class HaConfigTags extends SubscribeMixin(LitElement) { private async _removeTag(selectedTag: Tag) { if ( !(await showConfirmationDialog(this, { - title: this.hass!.localize("ui.panel.config.tag.confirm_remove_title"), - text: this.hass.localize("ui.panel.config.tag.confirm_remove", { + title: this.hass!.localize("ui.panel.config.tag.confirm_delete_title"), + text: this.hass.localize("ui.panel.config.tag.confirm_delete", { tag: selectedTag.name || selectedTag.id, }), dismissText: this.hass!.localize("ui.common.cancel"), - confirmText: this.hass!.localize("ui.common.remove"), + confirmText: this.hass!.localize("ui.common.delete"), + destructive: true, })) ) { return false; diff --git a/src/translations/en.json b/src/translations/en.json index 541d0fcc92c4..f73378c16bf4 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2107,8 +2107,8 @@ "edit": "Edit", "never_scanned": "Never scanned", "create_automation": "Create automation with tag", - "confirm_remove_title": "Remove tag?", - "confirm_remove": "Are you sure you want to remove tag {tag}?", + "confirm_delete_title": "Delete tag?", + "confirm_delete": "Are you sure you want to delete tag {tag}?", "automation_title": "Tag {name} is scanned", "qr_code_image": "QR code for tag {name}", "headers": { From dc93a0ce54b6001a13c90832960eac30944877bf Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 4 Jul 2024 21:18:50 +0200 Subject: [PATCH 54/86] Fix energy selection date card in grid layout (#21293) Fix energy selection card in grid layout --- .../energy/hui-energy-date-selection-card.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts b/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts index d6ab8eb4929a..0b2ff5fa817b 100644 --- a/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts +++ b/src/panels/lovelace/cards/energy/hui-energy-date-selection-card.ts @@ -1,17 +1,17 @@ import { - html, - LitElement, - nothing, - css, CSSResultGroup, + LitElement, PropertyValues, + css, + html, + nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { HomeAssistant } from "../../../../types"; +import { hasConfigChanged } from "../../common/has-changed"; import "../../components/hui-energy-period-selector"; -import { LovelaceCard } from "../../types"; +import { LovelaceCard, LovelaceLayoutOptions } from "../../types"; import { EnergyCardBaseConfig } from "../types"; -import { hasConfigChanged } from "../../common/has-changed"; @customElement("hui-energy-date-selection-card") export class HuiEnergyDateSelectionCard @@ -26,6 +26,13 @@ export class HuiEnergyDateSelectionCard return 1; } + public getLayoutOptions(): LovelaceLayoutOptions { + return { + grid_rows: 1, + grid_columns: 4, + }; + } + public setConfig(config: EnergyCardBaseConfig): void { this._config = config; } @@ -57,6 +64,13 @@ export class HuiEnergyDateSelectionCard static get styles(): CSSResultGroup { return css` + :host { + ha-card { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + } .padded { padding-left: 16px !important; padding-inline-start: 16px !important; From 7f50504908d414308df04f276ec8933e9892f52d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 19:21:19 +0000 Subject: [PATCH 55/86] Update dependency typescript to v5.5.3 (#21300) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index aac30ded713c..baf9e0afd94f 100644 --- a/package.json +++ b/package.json @@ -237,7 +237,7 @@ "terser-webpack-plugin": "5.3.10", "transform-async-modules-webpack-plugin": "1.1.1", "ts-lit-plugin": "2.0.2", - "typescript": "5.5.2", + "typescript": "5.5.3", "webpack": "5.92.1", "webpack-cli": "5.1.4", "webpack-dev-server": "5.0.4", diff --git a/yarn.lock b/yarn.lock index 02e62368d9c3..e43e25715610 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9083,7 +9083,7 @@ __metadata: ts-lit-plugin: "npm:2.0.2" tsparticles-engine: "npm:2.12.0" tsparticles-preset-links: "npm:2.12.0" - typescript: "npm:5.5.2" + typescript: "npm:5.5.3" ua-parser-js: "npm:1.0.38" unfetch: "npm:5.0.0" vis-data: "npm:7.1.9" @@ -14209,13 +14209,13 @@ __metadata: languageName: node linkType: hard -"typescript@npm:5.5.2": - version: 5.5.2 - resolution: "typescript@npm:5.5.2" +"typescript@npm:5.5.3": + version: 5.5.3 + resolution: "typescript@npm:5.5.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/9118b20f248e76b0dbff8737fef65dfa89d02668d4e633d2c5ceac99033a0ca5e8a1c1a53bc94da68e8f67677a88f318663dde859c9e9a09c1e116415daec2ba + checksum: 10/11a867312419ed497929aafd2f1d28b2cd41810a5eb6c6e9e169559112e9ea073d681c121a29102e67cd4478d0a4ae37a306a5800f3717f59c4337e6a9bd5e8d languageName: node linkType: hard @@ -14229,13 +14229,13 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A5.5.2#optional!builtin": - version: 5.5.2 - resolution: "typescript@patch:typescript@npm%3A5.5.2#optional!builtin::version=5.5.2&hash=379a07" +"typescript@patch:typescript@npm%3A5.5.3#optional!builtin": + version: 5.5.3 + resolution: "typescript@patch:typescript@npm%3A5.5.3#optional!builtin::version=5.5.3&hash=379a07" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10/ac3145f65cf9e72ab29f2196e05d5816b355dc1a9195b9f010d285182a12457cfacd068be2dd22c877f88ebc966ac6e0e83f51c8586412b16499a27e3670ff4b + checksum: 10/7cf7acb78a80f749b82842f2ffe01e90e7b3e709a6f4268588e0b7599c41dca1059be217f47778fe1a380bfaf60933021ef20d002c426d4d7745e1b36c11467b languageName: node linkType: hard From f995f19f061be75279551eead79732758a3f3064 Mon Sep 17 00:00:00 2001 From: Matthias de Baat Date: Fri, 5 Jul 2024 09:00:19 +0200 Subject: [PATCH 56/86] Clarify remove vs. delete (#21297) Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com> Co-authored-by: Franck Nijhof --- .../src/pages/Text/remove-delete-add-create.markdown | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gallery/src/pages/Text/remove-delete-add-create.markdown b/gallery/src/pages/Text/remove-delete-add-create.markdown index 89c61db6383a..3b0bb85c3676 100644 --- a/gallery/src/pages/Text/remove-delete-add-create.markdown +++ b/gallery/src/pages/Text/remove-delete-add-create.markdown @@ -3,13 +3,16 @@ title: When to use remove, delete, add and create subtitle: The difference between remove/delete and add/create. --- -# Remove vs Delete +# Removing or deleting content -Remove and Delete are quite similar, but can be frustrating if used inconsistently. +_Remove_ and _Delete_ are quite similar, but can be frustrating if used inconsistently. + +- Remove refers to an action that can be restored or reapplied. +- Delete refers to a permanent, non-recoverable action. ## Remove -Take away and set aside, but kept in existence. +The term _Remove_ should always be used when an item/setting or content is to be removed or disassociated, but the action can be reversed or reapplied. For example: @@ -22,7 +25,7 @@ For example: ## Delete -Erase, rendered nonexistent or nonrecoverable. +The term _Delete_ should always be used to refer to any action that will cause the permanent deletion of an item/setting or content. For example: From f7072c247e8ea13ff9b894871e6f27341389b3f2 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 5 Jul 2024 12:17:31 +0200 Subject: [PATCH 57/86] Improve sensor card graph inside section grid (#21289) --- src/panels/lovelace/cards/hui-entity-card.ts | 24 ++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index 42861e70fe4e..3e06cf7bf197 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -8,6 +8,7 @@ import { PropertyValues, } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { classMap } from "lit/directives/class-map"; import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; @@ -73,6 +74,8 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { @property({ attribute: false }) public hass?: HomeAssistant; + @property() public layout?: string; + @state() private _config?: EntityCardConfig; private _footerElement?: HuiErrorCard | LovelaceHeaderFooter; @@ -132,8 +135,15 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { const colored = stateObj && this.getStateColor(stateObj, this._config); + const fixedFooter = + this.layout === "grid" || this._footerElement !== undefined; + return html` - +
${name}
@@ -188,7 +198,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { ` : ""}
- ${this._footerElement} + `; } @@ -309,6 +319,16 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { font-size: 18px; color: var(--secondary-text-color); } + + .with-fixed-footer { + justify-content: flex-start; + } + .with-fixed-footer .footer { + position: absolute; + right: 0; + left: 0; + bottom: 0; + } `, ]; } From 42b5fbec9bd0c4dd7a871d80b9b3082da1dade2f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 5 Jul 2024 13:22:23 +0200 Subject: [PATCH 58/86] Bumped version to 20240705.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6aa93e24f7a8..402d7c3b98b9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240703.0" +version = "20240705.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From b7473b58fb9e19553b1ddc8b04b69fe10f59a735 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 5 Jul 2024 21:01:19 +0200 Subject: [PATCH 59/86] Fix sensor card display (#21313) --- src/panels/lovelace/cards/hui-entity-card.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index 3e06cf7bf197..b042d7e7c354 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -136,7 +136,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { const colored = stateObj && this.getStateColor(stateObj, this._config); const fixedFooter = - this.layout === "grid" || this._footerElement !== undefined; + this.layout === "grid" && this._footerElement !== undefined; return html` Date: Fri, 5 Jul 2024 21:19:50 +0200 Subject: [PATCH 60/86] Update dependency @braintree/sanitize-url to v7.0.4 (#21314) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index baf9e0afd94f..245b16777fa6 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "type": "module", "dependencies": { "@babel/runtime": "7.24.7", - "@braintree/sanitize-url": "7.0.3", + "@braintree/sanitize-url": "7.0.4", "@codemirror/autocomplete": "6.16.3", "@codemirror/commands": "6.6.0", "@codemirror/language": "6.10.2", diff --git a/yarn.lock b/yarn.lock index e43e25715610..b22363996cc6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1453,10 +1453,10 @@ __metadata: languageName: node linkType: hard -"@braintree/sanitize-url@npm:7.0.3": - version: 7.0.3 - resolution: "@braintree/sanitize-url@npm:7.0.3" - checksum: 10/86c0613d795340f555554511df1a3e64f0b5da7774707a8435a9a0b22cd62e38fb4ab5d3ac1b0862ef13106e2513af074d37c29e3184e1323e8c2fef031f181f +"@braintree/sanitize-url@npm:7.0.4": + version: 7.0.4 + resolution: "@braintree/sanitize-url@npm:7.0.4" + checksum: 10/80ea0080776a0305d697d12042acac287675e88a2abd9d294464f70ec57c1b00242d8d02a110c98ef8ea1731e512d67273ff5532c4bf01a78ab8b046fabb53d9 languageName: node linkType: hard @@ -8894,7 +8894,7 @@ __metadata: "@babel/preset-env": "npm:7.24.7" "@babel/preset-typescript": "npm:7.24.7" "@babel/runtime": "npm:7.24.7" - "@braintree/sanitize-url": "npm:7.0.3" + "@braintree/sanitize-url": "npm:7.0.4" "@bundle-stats/plugin-webpack-filter": "npm:4.13.3" "@codemirror/autocomplete": "npm:6.16.3" "@codemirror/commands": "npm:6.6.0" From d6e6844f236e922c02b869ad8a85aec2287d6472 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:23:49 +0200 Subject: [PATCH 61/86] Update dependency @codemirror/autocomplete to v6.17.0 (#21320) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 245b16777fa6..5259e7f35f2a 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "dependencies": { "@babel/runtime": "7.24.7", "@braintree/sanitize-url": "7.0.4", - "@codemirror/autocomplete": "6.16.3", + "@codemirror/autocomplete": "6.17.0", "@codemirror/commands": "6.6.0", "@codemirror/language": "6.10.2", "@codemirror/legacy-modes": "6.4.0", diff --git a/yarn.lock b/yarn.lock index b22363996cc6..2a57c9bce9e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1469,9 +1469,9 @@ __metadata: languageName: node linkType: hard -"@codemirror/autocomplete@npm:6.16.3": - version: 6.16.3 - resolution: "@codemirror/autocomplete@npm:6.16.3" +"@codemirror/autocomplete@npm:6.17.0": + version: 6.17.0 + resolution: "@codemirror/autocomplete@npm:6.17.0" dependencies: "@codemirror/language": "npm:^6.0.0" "@codemirror/state": "npm:^6.0.0" @@ -1482,7 +1482,7 @@ __metadata: "@codemirror/state": ^6.0.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.0.0 - checksum: 10/2455039375dc62ec007bafcd19978d2ea105a766760a02142f3bd27f2ecba76298386084051d727c21e763cd35422f0936b00352547de674c225fb24bf882f7a + checksum: 10/b38ef7ad392a88470c5e545b016bf1c443f50840ca4c7af9e19348fe27229aa9118dabc3cff8a0831143a307ab6ba948d7e126c0add7932a7f8044ab5902cda8 languageName: node linkType: hard @@ -8896,7 +8896,7 @@ __metadata: "@babel/runtime": "npm:7.24.7" "@braintree/sanitize-url": "npm:7.0.4" "@bundle-stats/plugin-webpack-filter": "npm:4.13.3" - "@codemirror/autocomplete": "npm:6.16.3" + "@codemirror/autocomplete": "npm:6.17.0" "@codemirror/commands": "npm:6.6.0" "@codemirror/language": "npm:6.10.2" "@codemirror/legacy-modes": "npm:6.4.0" From d646ce49953846c3bf518a1d8f90a1f3af3643b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:42:38 +0200 Subject: [PATCH 62/86] Update dependency @codemirror/view to v6.28.4 (#21321) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 5259e7f35f2a..2329fe4d8844 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@codemirror/legacy-modes": "6.4.0", "@codemirror/search": "6.5.6", "@codemirror/state": "6.4.1", - "@codemirror/view": "6.28.3", + "@codemirror/view": "6.28.4", "@egjs/hammerjs": "2.0.17", "@formatjs/intl-datetimeformat": "6.12.5", "@formatjs/intl-displaynames": "6.6.8", diff --git a/yarn.lock b/yarn.lock index 2a57c9bce9e7..be3e1bfc4b20 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1539,14 +1539,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:6.28.3, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0": - version: 6.28.3 - resolution: "@codemirror/view@npm:6.28.3" +"@codemirror/view@npm:6.28.4, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.27.0": + version: 6.28.4 + resolution: "@codemirror/view@npm:6.28.4" dependencies: "@codemirror/state": "npm:^6.4.0" style-mod: "npm:^4.1.0" w3c-keyname: "npm:^2.2.4" - checksum: 10/4732786b1afa3730a2c08b3711b335b8da2cb76318c9c4b2aeafd868bb36bfaeec826a18669b3d2d0f408e8012734689085633e4b6c3609cd2385838d79e5bc6 + checksum: 10/3effc92732e9fb25f32fe04a8e651202dbf453c3694adda4ff9666bd2b65d5ec4aef5288ab94932a26c03f5b27a6f5873b0d5fe6eb71051c912bb9ba1f1ae931 languageName: node linkType: hard @@ -8902,7 +8902,7 @@ __metadata: "@codemirror/legacy-modes": "npm:6.4.0" "@codemirror/search": "npm:6.5.6" "@codemirror/state": "npm:6.4.1" - "@codemirror/view": "npm:6.28.3" + "@codemirror/view": "npm:6.28.4" "@egjs/hammerjs": "npm:2.0.17" "@formatjs/intl-datetimeformat": "npm:6.12.5" "@formatjs/intl-displaynames": "npm:6.6.8" From aa49d6ef6b94853ccc49de6b52333cc9fa3f508b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Jul 2024 13:32:07 +0200 Subject: [PATCH 63/86] Update dependency marked to v13 (#21094) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 2329fe4d8844..8de6254a084a 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "leaflet-draw": "1.0.4", "lit": "2.8.0", "luxon": "3.4.4", - "marked": "12.0.2", + "marked": "13.0.2", "memoize-one": "6.0.0", "node-vibrant": "3.2.1-alpha.1", "proxy-polyfill": "0.3.2", diff --git a/yarn.lock b/yarn.lock index be3e1bfc4b20..699700c3b7a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9051,7 +9051,7 @@ __metadata: luxon: "npm:3.4.4" magic-string: "npm:0.30.10" map-stream: "npm:0.0.7" - marked: "npm:12.0.2" + marked: "npm:13.0.2" memoize-one: "npm:6.0.0" mocha: "npm:10.5.0" node-vibrant: "npm:3.2.1-alpha.1" @@ -10819,12 +10819,12 @@ __metadata: languageName: node linkType: hard -"marked@npm:12.0.2": - version: 12.0.2 - resolution: "marked@npm:12.0.2" +"marked@npm:13.0.2": + version: 13.0.2 + resolution: "marked@npm:13.0.2" bin: marked: bin/marked.js - checksum: 10/24d4fc58d37c1779197fa7f93c504d8c71d4df54eb69cbbc14a55ba2a8e2ad83d723801fc25452c21ce74b38a483c5863c53449f130253a597be9e9c1d3e7e2b + checksum: 10/73696e2d9d77995011f7a75acaa82a8d3b68cbe7072ad06cfdaddef9cb716022f07c3e51f91710db25338dda7736815d0aa9673950bf27c0ed325e6e3549db38 languageName: node linkType: hard From 877d0db1bb6f85bee59ff00a23e113db011793cd Mon Sep 17 00:00:00 2001 From: G Johansson Date: Sun, 7 Jul 2024 18:54:58 +0200 Subject: [PATCH 64/86] Add defrosting to HVAC actions for ClimateEntity (#21330) --- gallery/src/pages/misc/entity-state.ts | 3 +++ src/common/entity/get_states.ts | 1 + src/data/climate.ts | 12 +++++++----- src/fake_data/entity_component_icons.ts | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/gallery/src/pages/misc/entity-state.ts b/gallery/src/pages/misc/entity-state.ts index ab395b71a111..8d38fe9413d6 100644 --- a/gallery/src/pages/misc/entity-state.ts +++ b/gallery/src/pages/misc/entity-state.ts @@ -140,6 +140,9 @@ const ENTITIES: HassEntity[] = [ createEntity("climate.auto_preheating", "auto", undefined, { hvac_action: "preheating", }), + createEntity("climate.auto_defrosting", "auto", undefined, { + hvac_action: "defrosting", + }), createEntity("climate.auto_heating", "auto", undefined, { hvac_action: "heating", }), diff --git a/src/common/entity/get_states.ts b/src/common/entity/get_states.ts index 24e9fa4a7eef..901cf95a8c52 100644 --- a/src/common/entity/get_states.ts +++ b/src/common/entity/get_states.ts @@ -125,6 +125,7 @@ const FIXED_DOMAIN_ATTRIBUTE_STATES = { "off", "idle", "preheating", + "defrosting", "heating", "cooling", "drying", diff --git a/src/data/climate.ts b/src/data/climate.ts index 97a2557c71f7..30ee11d2b909 100644 --- a/src/data/climate.ts +++ b/src/data/climate.ts @@ -28,13 +28,14 @@ export type HvacMode = (typeof HVAC_MODES)[number]; export const CLIMATE_PRESET_NONE = "none"; export type HvacAction = - | "off" - | "preheating" - | "heating" | "cooling" + | "defrosting" | "drying" + | "fan" + | "heating" | "idle" - | "fan"; + | "off" + | "preheating"; export type ClimateEntity = HassEntityBase & { attributes: HassEntityAttributeBase & { @@ -89,12 +90,13 @@ export const compareClimateHvacModes = (mode1: HvacMode, mode2: HvacMode) => export const CLIMATE_HVAC_ACTION_TO_MODE: Record = { cooling: "cool", + defrosting: "heat", drying: "dry", fan: "fan_only", - preheating: "heat", heating: "heat", idle: "off", off: "off", + preheating: "heat", }; export const CLIMATE_HVAC_MODE_ICONS: Record = { diff --git a/src/fake_data/entity_component_icons.ts b/src/fake_data/entity_component_icons.ts index 90b580f977e7..242f301516a6 100644 --- a/src/fake_data/entity_component_icons.ts +++ b/src/fake_data/entity_component_icons.ts @@ -907,6 +907,7 @@ export const ENTITY_COMPONENT_ICONS: Record = { idle: "mdi:clock-outline", off: "mdi:power", preheating: "mdi:heat-wave", + defrosting: "mdi:snowflake-melt", }, }, preset_mode: { From bef53aef576d2eb3982fbfa4bfcf146396697039 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 08:42:44 +0200 Subject: [PATCH 65/86] Bump actions/upload-artifact from 4.3.3 to 4.3.4 (#21332) --- .github/workflows/ci.yaml | 4 ++-- .github/workflows/nightly.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 881d9ded40f0..42d7d54e6517 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -89,7 +89,7 @@ jobs: env: IS_TEST: "true" - name: Upload bundle stats - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.4 with: name: frontend-bundle-stats path: build/stats/*.json @@ -113,7 +113,7 @@ jobs: env: IS_TEST: "true" - name: Upload bundle stats - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.4 with: name: supervisor-bundle-stats path: build/stats/*.json diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 46d2063361ac..c095b89c2455 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -57,14 +57,14 @@ jobs: run: tar -czvf translations.tar.gz translations - name: Upload build artifacts - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.4 with: name: wheels path: dist/home_assistant_frontend*.whl if-no-files-found: error - name: Upload translations - uses: actions/upload-artifact@v4.3.3 + uses: actions/upload-artifact@v4.3.4 with: name: translations path: translations.tar.gz From e7a749ef7db5a0449c41411ff2886602e0fd7715 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 8 Jul 2024 05:13:29 -0700 Subject: [PATCH 66/86] Add `title` to stack editor UI (#21328) Add title to stack editor UI --- .../config-elements/hui-grid-card-editor.ts | 34 +++++-------------- .../config-elements/hui-stack-card-editor.ts | 33 ++++++++++++++++++ src/translations/en.json | 2 ++ 3 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts index 6105a3fa167e..52122938183d 100644 --- a/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-grid-card-editor.ts @@ -1,4 +1,3 @@ -import { html, nothing } from "lit"; import { customElement } from "lit/decorators"; import { any, @@ -11,8 +10,10 @@ import { optional, string, } from "superstruct"; -import { fireEvent } from "../../../../common/dom/fire_event"; -import type { SchemaUnion } from "../../../../components/ha-form/types"; +import type { + HaFormSchema, + SchemaUnion, +} from "../../../../components/ha-form/types"; import type { GridCardConfig } from "../../cards/types"; import { baseLovelaceCardConfig } from "../structs/base-card-struct"; import { HuiStackCardEditor } from "./hui-stack-card-editor"; @@ -49,35 +50,18 @@ const SCHEMA = [ @customElement("hui-grid-card-editor") export class HuiGridCardEditor extends HuiStackCardEditor { + protected _schema: readonly HaFormSchema[] = SCHEMA; + public setConfig(config: Readonly): void { assert(config, cardConfigStruct); this._config = config; } - protected render() { - if (!this.hass || !this._config) { - return nothing; - } - - const data = { square: true, ...this._config }; - - return html` - - ${super.render()} - `; - } - - private _valueChanged(ev: CustomEvent): void { - fireEvent(this, "config-changed", { config: ev.detail.value }); + protected formData(): object { + return { square: true, ...this._config }; } - private _computeLabelCallback = (schema: SchemaUnion) => + protected _computeLabelCallback = (schema: SchemaUnion) => this.hass!.localize(`ui.panel.lovelace.editor.card.grid.${schema.name}`); } diff --git a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts index 0655f6dddb8b..c5e81164e134 100644 --- a/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-stack-card-editor.ts @@ -20,6 +20,10 @@ import { optional, string, } from "superstruct"; +import type { + HaFormSchema, + SchemaUnion, +} from "../../../../components/ha-form/types"; import { storage } from "../../../../common/decorators/storage"; import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-icon-button"; @@ -46,6 +50,13 @@ const cardConfigStruct = assign( }) ); +const SCHEMA = [ + { + name: "title", + selector: { text: {} }, + }, +] as const; + @customElement("hui-stack-card-editor") export class HuiStackCardEditor extends LitElement @@ -71,6 +82,8 @@ export class HuiStackCardEditor @state() protected _guiModeAvailable? = true; + protected _schema: readonly HaFormSchema[] = SCHEMA; + @query("hui-card-element-editor") protected _cardEditorEl?: HuiCardElementEditor; @@ -83,6 +96,10 @@ export class HuiStackCardEditor this._cardEditorEl?.focusYamlEditor(); } + protected formData(): object { + return this._config!; + } + protected render() { if (!this.hass || !this._config) { return nothing; @@ -93,6 +110,13 @@ export class HuiStackCardEditor const isGuiMode = !this._cardEditorEl || this._GUImode; return html` +
) => + this.hass!.localize( + `ui.panel.lovelace.editor.card.${this._config!.type}.${schema.name}` + ); + static get styles(): CSSResultGroup { return [ configElementStyle, diff --git a/src/translations/en.json b/src/translations/en.json index f73378c16bf4..eb7e855219cc 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5852,6 +5852,7 @@ }, "horizontal-stack": { "name": "Horizontal stack", + "title": "[%key:ui::panel::lovelace::editor::card::grid::title%]", "description": "The Horizontal stack card allows you to stack together multiple cards, so they always sit next to each other in the space of one column." }, "humidifier": { @@ -5988,6 +5989,7 @@ }, "vertical-stack": { "name": "Vertical stack", + "title": "[%key:ui::panel::lovelace::editor::card::grid::title%]", "description": "The Vertical stack card allows you to group multiple cards so they always sit in the same column." }, "weather-forecast": { From c85e29f2bb8c113981ba0f2ed925f37e6e4b796e Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 8 Jul 2024 17:41:59 +0200 Subject: [PATCH 67/86] Use localize func in table settings dialog (#21335) --- .../data-table/dialog-data-table-settings.ts | 10 +++++----- .../data-table/show-dialog-data-table-settings.ts | 2 ++ src/layouts/hass-tabs-subpage-data-table.ts | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/data-table/dialog-data-table-settings.ts b/src/components/data-table/dialog-data-table-settings.ts index 1dfe8bbabf49..dd8a6f28888c 100644 --- a/src/components/data-table/dialog-data-table-settings.ts +++ b/src/components/data-table/dialog-data-table-settings.ts @@ -78,6 +78,8 @@ export class DialogDataTableSettings extends LitElement { return nothing; } + const localize = this._params.localizeFunc || this.hass.localize; + const columns = this._sortedColumns( this._params.columns, this._columnOrder, @@ -90,7 +92,7 @@ export class DialogDataTableSettings extends LitElement { @closed=${this.closeDialog} .heading=${createCloseHeading( this.hass, - this.hass.localize("ui.components.data-table.settings.header") + localize("ui.components.data-table.settings.header") )} > ${this.hass.localize( - "ui.components.data-table.settings.restore" - )}${localize("ui.components.data-table.settings.restore")} - ${this.hass.localize("ui.components.data-table.settings.done")} + ${localize("ui.components.data-table.settings.done")} `; diff --git a/src/components/data-table/show-dialog-data-table-settings.ts b/src/components/data-table/show-dialog-data-table-settings.ts index b31e801acb11..954dd871bb26 100644 --- a/src/components/data-table/show-dialog-data-table-settings.ts +++ b/src/components/data-table/show-dialog-data-table-settings.ts @@ -1,4 +1,5 @@ import { fireEvent } from "../../common/dom/fire_event"; +import { LocalizeFunc } from "../../common/translations/localize"; import { DataTableColumnContainer } from "./ha-data-table"; export interface DataTableSettingsDialogParams { @@ -9,6 +10,7 @@ export interface DataTableSettingsDialogParams { ) => void; hiddenColumns?: string[]; columnOrder?: string[]; + localizeFunc?: LocalizeFunc; } export const loadDataTableSettingsDialog = () => diff --git a/src/layouts/hass-tabs-subpage-data-table.ts b/src/layouts/hass-tabs-subpage-data-table.ts index 615fb2d5d056..79db1674e59a 100644 --- a/src/layouts/hass-tabs-subpage-data-table.ts +++ b/src/layouts/hass-tabs-subpage-data-table.ts @@ -638,6 +638,7 @@ export class HaTabsSubpageDataTable extends LitElement { this.hiddenColumns = hiddenColumns; fireEvent(this, "columns-changed", { columnOrder, hiddenColumns }); }, + localizeFunc: this.localizeFunc, }); } From 8ff2396a53a3fa5a624cfd53c9a438a97b84d35a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:42:39 +0200 Subject: [PATCH 68/86] Update vaadinWebComponents monorepo to v24.4.1 (#21334) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 170 +++++++++++++++++++++++++-------------------------- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/package.json b/package.json index 8de6254a084a..144e157f11fa 100644 --- a/package.json +++ b/package.json @@ -88,8 +88,8 @@ "@polymer/paper-tabs": "3.1.0", "@polymer/polymer": "3.5.1", "@thomasloven/round-slider": "0.6.0", - "@vaadin/combo-box": "24.4.0", - "@vaadin/vaadin-themable-mixin": "24.4.0", + "@vaadin/combo-box": "24.4.1", + "@vaadin/vaadin-themable-mixin": "24.4.1", "@vibrant/color": "3.2.1-alpha.1", "@vibrant/core": "3.2.1-alpha.1", "@vibrant/quantizer-mmcq": "3.2.1-alpha.1", diff --git a/yarn.lock b/yarn.lock index 699700c3b7a3..345b11c15dca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4709,129 +4709,129 @@ __metadata: languageName: node linkType: hard -"@vaadin/a11y-base@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/a11y-base@npm:24.4.0" +"@vaadin/a11y-base@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/a11y-base@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.0" + "@vaadin/component-base": "npm:~24.4.1" lit: "npm:^3.0.0" - checksum: 10/d601527b93f3e3e7561ea67da6183be1a192ebe8a8f09dc6de8a59a8bec104d95d945e201b6c3faeb2870fa7f1739fe2087e6d5a228e173385744f079e385c7a + checksum: 10/b59f6b8ecab3b359ce3f4e0362674b45800bb6a61343895cecab7956eb64de4ed94f7ed34e943cb27865bc5fcdf980d9012533a1cbd11ed5f10ed14f6282cf9e languageName: node linkType: hard -"@vaadin/combo-box@npm:24.4.0": - version: 24.4.0 - resolution: "@vaadin/combo-box@npm:24.4.0" +"@vaadin/combo-box@npm:24.4.1": + version: 24.4.1 + resolution: "@vaadin/combo-box@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/field-base": "npm:~24.4.0" - "@vaadin/input-container": "npm:~24.4.0" - "@vaadin/item": "npm:~24.4.0" - "@vaadin/lit-renderer": "npm:~24.4.0" - "@vaadin/overlay": "npm:~24.4.0" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.0" - "@vaadin/vaadin-material-styles": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" - checksum: 10/84c9eff3020f3d991b2c69f7510d98952512bed29835b98a3328d75ec066187e7202ea3cbf79c2bfbf52b743bc3208a71dd1077d83aa8ccf2b1ea64209db995b + "@vaadin/a11y-base": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/field-base": "npm:~24.4.1" + "@vaadin/input-container": "npm:~24.4.1" + "@vaadin/item": "npm:~24.4.1" + "@vaadin/lit-renderer": "npm:~24.4.1" + "@vaadin/overlay": "npm:~24.4.1" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" + "@vaadin/vaadin-material-styles": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + checksum: 10/5caca3660fa91f8ae913a2159e7533aa545e21593574a80ca317a13cc2a5ddf8754beb852d6d3ff4b31e8171bf581d784de8925af17d57096a2f5842a4c699d3 languageName: node linkType: hard -"@vaadin/component-base@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/component-base@npm:24.4.0" +"@vaadin/component-base@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/component-base@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" "@vaadin/vaadin-development-mode-detector": "npm:^2.0.0" "@vaadin/vaadin-usage-statistics": "npm:^2.1.0" lit: "npm:^3.0.0" - checksum: 10/6df7a2372099e4efb9b8307aaf51300fd530cc4ed967532bfaa9250fea45b2c78a0b946093021a7da622dedadae4386f1388b667840b577f74f5b0db55f91ea3 + checksum: 10/5717aaa2b418930ceb9a77b8641e5e103ae2ac2b47dcb4dd16cf245edc51c4c79d9573338520d4c412d4dd39daa132606d5f3474bf217390e866b60a6291e7dd languageName: node linkType: hard -"@vaadin/field-base@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/field-base@npm:24.4.0" +"@vaadin/field-base@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/field-base@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.0" - "@vaadin/component-base": "npm:~24.4.0" + "@vaadin/a11y-base": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.1" lit: "npm:^3.0.0" - checksum: 10/b74c9e8758672e818fc69dbb438938745588232e58d3c3fc0157c3719ef2382d736d7634d34ae4b8047f32fa481eeb768938f91073f8b3e1e6894c8106ab7c61 + checksum: 10/8feed52803b9078b62fd0124a90f70cdb69d1620e507b605ec57a5a4523af0cf087d0b5864bb4fdd4676b9b96a5182b0e69b53dc36d4f791fcfcd4a372869883 languageName: node linkType: hard -"@vaadin/icon@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/icon@npm:24.4.0" +"@vaadin/icon@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/icon@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" lit: "npm:^3.0.0" - checksum: 10/f9560f330a2e361f3e55257dfa77b6c26abec7d8b6b7c4c73ddf496f3a1dde64c708902780b4eb3ad6640d2779b728f28bf22a59e286a765b99e6ebe6e1f9861 + checksum: 10/0097ddeff4e705bae69dbd6e6fb6b2c55a969ef2b3dfefd794e6e7b9e70f987d31e4952d84cbf582d8f76b93f204fe92760eb68ef12d037c9d54f77bad7ace02 languageName: node linkType: hard -"@vaadin/input-container@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/input-container@npm:24.4.0" +"@vaadin/input-container@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/input-container@npm:24.4.1" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.0" - "@vaadin/vaadin-material-styles": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" + "@vaadin/vaadin-material-styles": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" lit: "npm:^3.0.0" - checksum: 10/c4a59f5d27bc336d8dcd996f306e0108e666ff3dc0124ef07773e517f509f67249d737d1b62a9d82d31cfd2ee461a26f6e71d86f0a354b5f831d7d2088843ba3 + checksum: 10/b6c4d448182cd7f55e671ed4ed06e8076c320ff9659a2e19e7e80181b2a338cd4e2a2de328ff7839c965a81e32c2609f825c9df2da55d99af081951e568c9457 languageName: node linkType: hard -"@vaadin/item@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/item@npm:24.4.0" +"@vaadin/item@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/item@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.0" - "@vaadin/vaadin-material-styles": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" - checksum: 10/ae25b2ed91cefcfbde6a61d832be8d6549a690fc37854324f149097e60a5fafae9cbaeebf5f5a363c5bce1f027bd59a0e84362dd6189208e11517bfb50d5f58e + "@vaadin/a11y-base": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" + "@vaadin/vaadin-material-styles": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + checksum: 10/81d4560461ea13818a3c5604cf3c4e3acd6de9e8cac51e1ab41d7b2d0d14d09519790c8cfbab5b391f88461cde662915e4093e95491dc83942c460d11bb698e4 languageName: node linkType: hard -"@vaadin/lit-renderer@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/lit-renderer@npm:24.4.0" +"@vaadin/lit-renderer@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/lit-renderer@npm:24.4.1" dependencies: lit: "npm:^3.0.0" - checksum: 10/b50f2d7c5ee9eb7577fbfc33f104279654a962a06159225258e38baa132230328d9d114047ce6a873046b1c2e3ec799996ab1eb5f68467a6f11a54929c67a549 + checksum: 10/9a2ebf90ca4f3a08152058a5e431a4019bac78fb94a38b382550e85ca2993b35bb09a94a47e573529cd94a1b99bcbcdd89d71e1ec9c12a3a796e2e41cc79221f languageName: node linkType: hard -"@vaadin/overlay@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/overlay@npm:24.4.0" +"@vaadin/overlay@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/overlay@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.0" - "@vaadin/vaadin-material-styles": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" + "@vaadin/a11y-base": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" + "@vaadin/vaadin-material-styles": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" lit: "npm:^3.0.0" - checksum: 10/528e006f08ac2e9d98eacc8af44fbecc37c0cb36bb7e42263ffdfd8c91d5eacb7575e60279978adaa89f478cf37c907689455a689ec4acfa6a0edba1e38c7f0a + checksum: 10/4b899ffe4bd22104e7c038f9669d18d3ba482875cbe7425ac9e98da6fec397c4419580e2f0f6dcd1411acd42cd4cc6dc5267393e7deedd1701195ddcd99e9d2d languageName: node linkType: hard @@ -4842,36 +4842,36 @@ __metadata: languageName: node linkType: hard -"@vaadin/vaadin-lumo-styles@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/vaadin-lumo-styles@npm:24.4.0" +"@vaadin/vaadin-lumo-styles@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/vaadin-lumo-styles@npm:24.4.1" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/icon": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" - checksum: 10/10621a61a60244faff663856c9dd315fb5df21373cab9b519661a60e8b51484b7db4a17cc7084f0774c6c68c9bacb93fbfd1fb4144a8a912480a579ca3dbfdf3 + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/icon": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + checksum: 10/cec42991f1bdab3a1da179f77593735dbc6b6ec677195cd1558eeb79fc1c5707badad3818103f57cf0a68d141e7cc2860ab634e2b99b00d71e289c6dd884b375 languageName: node linkType: hard -"@vaadin/vaadin-material-styles@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/vaadin-material-styles@npm:24.4.0" +"@vaadin/vaadin-material-styles@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/vaadin-material-styles@npm:24.4.1" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.0" - checksum: 10/6b97a48dcd043f14652afc47a2280678187407af1501f5c241aedd49fdcadef4e2ce944641047206247419d9d8d3cfa727c3442050fd0e77c3ea6468a089f298 + "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + checksum: 10/d128217dbd0333ecf6c935dfe09a60bf9e67ad1c65430d4a052a9f5a3691677854f60c45faa40b33889380feac0f29b2a6376accb928dd6c3114cd167cbbcc9f languageName: node linkType: hard -"@vaadin/vaadin-themable-mixin@npm:24.4.0, @vaadin/vaadin-themable-mixin@npm:~24.4.0": - version: 24.4.0 - resolution: "@vaadin/vaadin-themable-mixin@npm:24.4.0" +"@vaadin/vaadin-themable-mixin@npm:24.4.1, @vaadin/vaadin-themable-mixin@npm:~24.4.1": + version: 24.4.1 + resolution: "@vaadin/vaadin-themable-mixin@npm:24.4.1" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" lit: "npm:^3.0.0" - checksum: 10/d9d72241811d35c1fb3c104576e3d391dad6cddebd89ab33c8345177b0afda70c23b1a2c14a79b1d373cad0670be9ccc95b90a629f978cab08653a9c33137bf2 + checksum: 10/576f39795fa7112f1f872449d97690814dc0dd982125a8ceeee7a8e7d3aa66b18ea6288f38a95b40a7d9e3008fd5cd9bbb73af9a7cb16cae84f75206f76327b4 languageName: node linkType: hard @@ -8988,8 +8988,8 @@ __metadata: "@types/webspeechapi": "npm:0.0.29" "@typescript-eslint/eslint-plugin": "npm:7.15.0" "@typescript-eslint/parser": "npm:7.15.0" - "@vaadin/combo-box": "npm:24.4.0" - "@vaadin/vaadin-themable-mixin": "npm:24.4.0" + "@vaadin/combo-box": "npm:24.4.1" + "@vaadin/vaadin-themable-mixin": "npm:24.4.1" "@vibrant/color": "npm:3.2.1-alpha.1" "@vibrant/core": "npm:3.2.1-alpha.1" "@vibrant/quantizer-mmcq": "npm:3.2.1-alpha.1" From bd54eb40a74db0daf5195617d38b4cf8ec1c8a8a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:59:36 +0200 Subject: [PATCH 69/86] Update dependency glob to v10.4.3 (#21343) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 144e157f11fa..747e69769992 100644 --- a/package.json +++ b/package.json @@ -205,7 +205,7 @@ "eslint-plugin-wc": "2.1.0", "fancy-log": "2.0.0", "fs-extra": "11.2.0", - "glob": "10.4.2", + "glob": "10.4.3", "gulp": "5.0.0", "gulp-json-transform": "0.5.0", "gulp-rename": "2.0.0", diff --git a/yarn.lock b/yarn.lock index 345b11c15dca..8b5ee67ad15a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8542,9 +8542,9 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.4.2, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": - version: 10.4.2 - resolution: "glob@npm:10.4.2" +"glob@npm:10.4.3, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": + version: 10.4.3 + resolution: "glob@npm:10.4.3" dependencies: foreground-child: "npm:^3.1.0" jackspeak: "npm:^3.1.2" @@ -8554,7 +8554,7 @@ __metadata: path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10/e412776b5952a818eba790c830bea161c9a56813fd767d8c4c49f855603b1fb962b3e73f1f627a47298a57d2992b9f0f2fe15cf93e74ecaaa63fb45d63fdd090 + checksum: 10/7670e257bc7cf62a5649e79a71fc3b74806516eabfbfef0a949e11c5530c215d0f6d75c8c0c35266ff44ef6cb29b6c0e59be63906909be946d4c65df5d336be8 languageName: node linkType: hard @@ -9026,7 +9026,7 @@ __metadata: fancy-log: "npm:2.0.0" fs-extra: "npm:11.2.0" fuse.js: "npm:7.0.0" - glob: "npm:10.4.2" + glob: "npm:10.4.3" google-timezones-json: "npm:1.2.0" gulp: "npm:5.0.0" gulp-json-transform: "npm:0.5.0" From ca53af5c41f241e7affff29de754e575ec4d98d8 Mon Sep 17 00:00:00 2001 From: G Johansson Date: Tue, 9 Jul 2024 10:26:42 +0200 Subject: [PATCH 70/86] Add turn_on/off to FanEntity (#21339) --- src/data/fan.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/data/fan.ts b/src/data/fan.ts index 5bcf32e75890..3320ff5353d8 100644 --- a/src/data/fan.ts +++ b/src/data/fan.ts @@ -17,6 +17,8 @@ export const enum FanEntityFeature { OSCILLATE = 2, DIRECTION = 4, PRESET_MODE = 8, + TURN_OFF = 16, + TURN_ON = 32, } interface FanEntityAttributes extends HassEntityAttributeBase { From 541453c24599d36da61d04c619d8e393714a90ec Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 9 Jul 2024 15:37:05 +0200 Subject: [PATCH 71/86] Fix hidden conditional card in editor preview (#21344) --- src/panels/lovelace/cards/hui-card.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index ecc34ee4ca3d..34c47a691e93 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -23,7 +23,7 @@ declare global { @customElement("hui-card") export class HuiCard extends ReactiveElement { - @property({ attribute: false }) public preview = false; + @property({ type: Boolean }) public preview = false; @property({ attribute: false }) public isPanel = false; From 144d278e4a3f36fc8cf1733ab8d113d5d7ee338c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 9 Jul 2024 17:03:40 +0200 Subject: [PATCH 72/86] Don't block interaction on disabled automation selector (#21347) --- src/components/ha-selector/ha-selector-action.ts | 4 ---- src/components/ha-selector/ha-selector-condition.ts | 4 ---- src/components/ha-selector/ha-selector-trigger.ts | 4 ---- 3 files changed, 12 deletions(-) diff --git a/src/components/ha-selector/ha-selector-action.ts b/src/components/ha-selector/ha-selector-action.ts index 2e203a62da4b..6ee30b5e675d 100644 --- a/src/components/ha-selector/ha-selector-action.ts +++ b/src/components/ha-selector/ha-selector-action.ts @@ -35,10 +35,6 @@ export class HaActionSelector extends LitElement { display: block; margin-bottom: 16px; } - :host([disabled]) ha-automation-action { - opacity: var(--light-disabled-opacity); - pointer-events: none; - } label { display: block; margin-bottom: 4px; diff --git a/src/components/ha-selector/ha-selector-condition.ts b/src/components/ha-selector/ha-selector-condition.ts index 756d43b1e4e3..721cf265ade0 100644 --- a/src/components/ha-selector/ha-selector-condition.ts +++ b/src/components/ha-selector/ha-selector-condition.ts @@ -35,10 +35,6 @@ export class HaConditionSelector extends LitElement { display: block; margin-bottom: 16px; } - :host([disabled]) ha-automation-condition { - opacity: var(--light-disabled-opacity); - pointer-events: none; - } label { display: block; margin-bottom: 4px; diff --git a/src/components/ha-selector/ha-selector-trigger.ts b/src/components/ha-selector/ha-selector-trigger.ts index 567a81c4d364..af4b814a76f9 100644 --- a/src/components/ha-selector/ha-selector-trigger.ts +++ b/src/components/ha-selector/ha-selector-trigger.ts @@ -35,10 +35,6 @@ export class HaTriggerSelector extends LitElement { display: block; margin-bottom: 16px; } - :host([disabled]) ha-automation-trigger { - opacity: var(--light-disabled-opacity); - pointer-events: none; - } label { display: block; margin-bottom: 4px; From 7edc4efc95c46e9cf6677b2cbc5ee65c4506a0a8 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 10 Jul 2024 08:21:12 +0200 Subject: [PATCH 73/86] Bumped version to 20240710.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 402d7c3b98b9..91ae7718f848 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240705.0" +version = "20240710.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From daa36788e09b0eb38506456bb1c90d7aa7e9623b Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 10 Jul 2024 12:39:50 +0200 Subject: [PATCH 74/86] Reload the card when changing the configuration in editor (#21351) --- src/panels/lovelace/cards/hui-card.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/cards/hui-card.ts b/src/panels/lovelace/cards/hui-card.ts index 34c47a691e93..5e2d832a4a95 100644 --- a/src/panels/lovelace/cards/hui-card.ts +++ b/src/panels/lovelace/cards/hui-card.ts @@ -150,8 +150,10 @@ export class HuiCard extends ReactiveElement { if (changedProps.has("config")) { const elementConfig = this._elementConfig; if (this.config !== elementConfig && this.config) { - const typeChanged = this.config?.type !== elementConfig?.type; - if (typeChanged) { + const typeChanged = + this.config?.type !== elementConfig?.type || this.preview; + // Rebuild the card if the type of the card has changed or if we are in preview mode + if (typeChanged || this.preview) { this._loadElement(this.config); } else { this._updateElement(this.config); From cd4937b53984f9215766b4cc0cb3f8a08c10903c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 10 Jul 2024 14:58:26 +0200 Subject: [PATCH 75/86] Fix unhiding default hidden columns (#21354) * Fix unhiding default hidden columns * Update dialog-data-table-settings.ts --- src/components/data-table/dialog-data-table-settings.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/data-table/dialog-data-table-settings.ts b/src/components/data-table/dialog-data-table-settings.ts index dd8a6f28888c..29c99762ee9a 100644 --- a/src/components/data-table/dialog-data-table-settings.ts +++ b/src/components/data-table/dialog-data-table-settings.ts @@ -193,6 +193,7 @@ export class DialogDataTableSettings extends LitElement { .filter(([_key, col]) => col.defaultHidden) .map(([key]) => key)), ]; + if (wasHidden && hidden.includes(column)) { hidden.splice(hidden.indexOf(column), 1); } else if (!wasHidden) { @@ -235,14 +236,14 @@ export class DialogDataTableSettings extends LitElement { } columns.forEach((col) => { - if (!newOrder.includes(col.key)) { + if (col.key !== column && !newOrder.includes(col.key)) { if (col.moveable === false) { newOrder.unshift(col.key); } else { newOrder.splice(lastMoveable + 1, 0, col.key); } - if (col.defaultHidden) { + if (col.defaultHidden && !hidden.includes(col.key)) { hidden.push(col.key); } } From 11b490d145a7dae5e386705f3033039a235cb048 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 10 Jul 2024 15:01:56 +0200 Subject: [PATCH 76/86] Dev tools events: Add a clear events button (#21353) Clear events --- .../event/developer-tools-event.ts | 101 ++++++++++-------- .../event/event-subscribe-card.ts | 79 +++++++++----- src/translations/en.json | 1 + 3 files changed, 108 insertions(+), 73 deletions(-) diff --git a/src/panels/developer-tools/event/developer-tools-event.ts b/src/panels/developer-tools/event/developer-tools-event.ts index cd29d3176d4d..a72b570e3a17 100644 --- a/src/panels/developer-tools/event/developer-tools-event.ts +++ b/src/panels/developer-tools/event/developer-tools-event.ts @@ -1,8 +1,9 @@ import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit"; import { customElement, property, state } from "lit/decorators"; -import "@material/mwc-button"; import "../../../components/ha-yaml-editor"; import "../../../components/ha-textfield"; +import "../../../components/ha-button"; +import "../../../components/ha-card"; import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; import { documentationUrl } from "../../../util/documentation-url"; import "./event-subscribe-card"; @@ -31,49 +32,61 @@ class HaPanelDevEvent extends LitElement { : "content layout horizontal"} >
-

- ${this.hass.localize( - "ui.panel.developer-tools.tabs.events.description" - )} - - ${this.hass.localize( - "ui.panel.developer-tools.tabs.events.documentation" - )} - -

-
- -

- ${this.hass.localize("ui.panel.developer-tools.tabs.events.data")} -

-
-
- -
- ${this.hass.localize( - "ui.panel.developer-tools.tabs.events.fire_event" - )} + +
+

+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.events.description" + )} + + ${this.hass.localize( + "ui.panel.developer-tools.tabs.events.documentation" + )} + +

+
+ +

+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.events.data" + )} +

+
+
+ +
+
+
+ ${this.hass.localize( + "ui.panel.developer-tools.tabs.events.fire_event" + )} +
+
+
diff --git a/src/panels/developer-tools/event/event-subscribe-card.ts b/src/panels/developer-tools/event/event-subscribe-card.ts index ada37484ce19..564af64c4b3e 100644 --- a/src/panels/developer-tools/event/event-subscribe-card.ts +++ b/src/panels/developer-tools/event/event-subscribe-card.ts @@ -1,4 +1,3 @@ -import "@material/mwc-button"; import { HassEvent } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -7,6 +6,7 @@ import { formatTime } from "../../../common/datetime/format_time"; import "../../../components/ha-card"; import "../../../components/ha-textfield"; import "../../../components/ha-yaml-editor"; +import "../../../components/ha-button"; import { HomeAssistant } from "../../../types"; @customElement("event-subscribe-card") @@ -40,33 +40,46 @@ class EventSubscribeCard extends LitElement { )} >
-
- - - ${this._subscribed - ? this.hass!.localize( - "ui.panel.developer-tools.tabs.events.stop_listening" - ) - : this.hass!.localize( - "ui.panel.developer-tools.tabs.events.start_listening" - )} - -
+ +
+
+ + ${this._subscribed + ? this.hass!.localize( + "ui.panel.developer-tools.tabs.events.stop_listening" + ) + : this.hass!.localize( + "ui.panel.developer-tools.tabs.events.start_listening" + )} + + + ${this.hass!.localize( + "ui.panel.developer-tools.tabs.events.clear_events" + )} + +
+ + +
${repeat( this._events, @@ -99,7 +112,7 @@ class EventSubscribeCard extends LitElement { this._eventType = ev.target.value; } - private async _handleSubmit(): Promise { + private async _startOrStopListening(): Promise { if (this._subscribed) { this._subscribed(); this._subscribed = undefined; @@ -121,6 +134,11 @@ class EventSubscribeCard extends LitElement { } } + private _clearEvents(): void { + this._events = []; + this._eventCount = 0; + } + static get styles(): CSSResultGroup { return css` ha-textfield { @@ -140,6 +158,9 @@ class EventSubscribeCard extends LitElement { pre { font-family: var(--code-font-family, monospace); } + ha-card { + margin-bottom: 5px; + } `; } } diff --git a/src/translations/en.json b/src/translations/en.json index eb7e855219cc..865a4f9e7560 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -6686,6 +6686,7 @@ "subscribe_to": "Event to subscribe to", "start_listening": "Start listening", "stop_listening": "Stop listening", + "clear_events": "Clear events", "alert_event_type": "Event type is a mandatory field", "notification_event_fired": "Event {type} successfully fired!" }, From f2993602f991a44d32a74fea141730b2789abca7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:09:06 +0200 Subject: [PATCH 77/86] Update dependency superstruct to v2 (#21324) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 747e69769992..25156691a324 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "rrule": "2.8.1", "sortablejs": "1.15.2", "stacktrace-js": "2.0.2", - "superstruct": "1.0.4", + "superstruct": "2.0.2", "tinykeys": "2.1.0", "tsparticles-engine": "2.12.0", "tsparticles-preset-links": "2.12.0", diff --git a/yarn.lock b/yarn.lock index 8b5ee67ad15a..1d34ef6c5c0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9074,7 +9074,7 @@ __metadata: sortablejs: "npm:1.15.2" source-map-url: "npm:0.4.1" stacktrace-js: "npm:2.0.2" - superstruct: "npm:1.0.4" + superstruct: "npm:2.0.2" systemjs: "npm:6.15.1" tar: "npm:7.4.0" terser-webpack-plugin: "npm:5.3.10" @@ -13601,10 +13601,10 @@ __metadata: languageName: node linkType: hard -"superstruct@npm:1.0.4": - version: 1.0.4 - resolution: "superstruct@npm:1.0.4" - checksum: 10/9b3fd70a08c5ad3ea78b5c6b7ab90d31dde71af10448208d296c3d29ba2e55dfd817dfef75957163ee032163d04c4b2e0cb2fddff30313516aa60f748c1a48da +"superstruct@npm:2.0.2": + version: 2.0.2 + resolution: "superstruct@npm:2.0.2" + checksum: 10/10e1944a9da4baee187fbaa6c5d97d7af266b55786dfe50bce67f0f1e7d93f1a5a42dd51e245a2e16404f8336d07c21c67f1c1fbc4ad0a252d3d2601d6c926da languageName: node linkType: hard From 5ead5ed058150336987f7a2ca300b4ecb40b1e3f Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 10 Jul 2024 18:25:57 +0200 Subject: [PATCH 78/86] Fix unhiding default hidden column (#21358) the first commit is the right commit... --- src/components/data-table/dialog-data-table-settings.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/data-table/dialog-data-table-settings.ts b/src/components/data-table/dialog-data-table-settings.ts index 29c99762ee9a..b3f8c5108759 100644 --- a/src/components/data-table/dialog-data-table-settings.ts +++ b/src/components/data-table/dialog-data-table-settings.ts @@ -236,14 +236,18 @@ export class DialogDataTableSettings extends LitElement { } columns.forEach((col) => { - if (col.key !== column && !newOrder.includes(col.key)) { + if (!newOrder.includes(col.key)) { if (col.moveable === false) { newOrder.unshift(col.key); } else { newOrder.splice(lastMoveable + 1, 0, col.key); } - if (col.defaultHidden && !hidden.includes(col.key)) { + if ( + col.key !== column && + col.defaultHidden && + !hidden.includes(col.key) + ) { hidden.push(col.key); } } From d9583582e6406f11b755dceb46cb36d3c4d19779 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 11 Jul 2024 09:00:15 +0200 Subject: [PATCH 79/86] Rename service call to action (#21362) --- src/components/ha-service-control.ts | 6 +- src/components/ha-service-picker.ts | 2 +- .../config/cloud/account/cloud-tts-pref.ts | 9 +- .../entity-registry-settings-editor.ts | 2 +- .../config/entities/ha-config-entities.ts | 2 +- .../developer-tools-action.ts} | 47 +++++----- .../developer-tools/developer-tools-router.ts | 7 +- .../ha-panel-developer-tools.ts | 6 +- src/panels/lovelace/common/compute-tooltip.ts | 2 +- src/panels/lovelace/common/handle-action.ts | 2 +- .../config-elements/hui-tile-card-editor.ts | 1 - src/state/connection-mixin.ts | 2 +- src/translations/en.json | 93 ++++++++++--------- 13 files changed, 92 insertions(+), 89 deletions(-) rename src/panels/developer-tools/{service/developer-tools-service.ts => action/developer-tools-action.ts} (91%) diff --git a/src/components/ha-service-control.ts b/src/components/ha-service-control.ts index 47ee86539306..cbf71987e0f4 100644 --- a/src/components/ha-service-control.ts +++ b/src/components/ha-service-control.ts @@ -451,7 +451,7 @@ export class HaServiceControl extends LitElement { > ${this.hass.localize( - "ui.components.service-control.target_description" + "ui.components.service-control.target_secondary" )}
- ${this.hass.localize("ui.panel.config.cloud.account.tts.info", { - service: '"tts.cloud_say"', - })} + ${this.hass.localize( + "ui.panel.config.cloud.account.tts.description", + { + service: '"tts.cloud_say"', + } + )}

${this.hass.localize( - "ui.dialogs.entity_registry.editor.hidden_description" + "ui.dialogs.entity_registry.editor.hidden_explanation" )}

${this.hass.localize( - "ui.panel.developer-tools.tabs.services.description" + "ui.panel.developer-tools.tabs.actions.description" )}

@@ -154,23 +155,23 @@ class HaPanelDevService extends LitElement { > ${this._yamlMode ? this.hass.localize( - "ui.panel.developer-tools.tabs.services.ui_mode" + "ui.panel.developer-tools.tabs.actions.ui_mode" ) : this.hass.localize( - "ui.panel.developer-tools.tabs.services.yaml_mode" + "ui.panel.developer-tools.tabs.actions.yaml_mode" )} ${!this._uiAvailable ? html`${this.hass.localize( - "ui.panel.developer-tools.tabs.services.no_template_ui_support" + "ui.panel.developer-tools.tabs.actions.no_template_ui_support" )}` : ""}
${this.hass.localize( - "ui.panel.developer-tools.tabs.services.call_service" + "ui.panel.developer-tools.tabs.actions.call_service" )}
@@ -179,7 +180,7 @@ class HaPanelDevService extends LitElement { ? html`
@@ -199,10 +200,10 @@ class HaPanelDevService extends LitElement { ${this.hass.localize( - "ui.panel.developer-tools.tabs.services.column_parameter" + "ui.panel.developer-tools.tabs.actions.column_parameter" )} ${this.hass.localize( - "ui.panel.developer-tools.tabs.services.column_description" + "ui.panel.developer-tools.tabs.actions.column_description" )} ${this.hass.localize( - "ui.panel.developer-tools.tabs.services.column_example" + "ui.panel.developer-tools.tabs.actions.column_example" )} @@ -281,7 +282,7 @@ class HaPanelDevService extends LitElement { ${this._yamlMode ? html`${this.hass.localize( - "ui.panel.developer-tools.tabs.services.fill_example_data" + "ui.panel.developer-tools.tabs.actions.fill_example_data" )}` : ""} @@ -305,14 +306,14 @@ class HaPanelDevService extends LitElement { const errorCategory = yamlMode ? "yaml" : "ui"; if (!serviceData?.service) { return localize( - `ui.panel.developer-tools.tabs.services.errors.${errorCategory}.no_service` + `ui.panel.developer-tools.tabs.actions.errors.${errorCategory}.no_service` ); } const domain = computeDomain(serviceData.service); const service = computeObjectId(serviceData.service); if (!domain || !service) { return localize( - `ui.panel.developer-tools.tabs.services.errors.${errorCategory}.invalid_service` + `ui.panel.developer-tools.tabs.actions.errors.${errorCategory}.invalid_service` ); } if ( @@ -323,7 +324,7 @@ class HaPanelDevService extends LitElement { !serviceData.data?.area_id ) { return localize( - `ui.panel.developer-tools.tabs.services.errors.${errorCategory}.no_target` + `ui.panel.developer-tools.tabs.actions.errors.${errorCategory}.no_target` ); } for (const field of fields) { @@ -332,7 +333,7 @@ class HaPanelDevService extends LitElement { (!serviceData.data || serviceData.data[field.key] === undefined) ) { return localize( - `ui.panel.developer-tools.tabs.services.errors.${errorCategory}.missing_required_field`, + `ui.panel.developer-tools.tabs.actions.errors.${errorCategory}.missing_required_field`, { key: field.key } ); } @@ -377,7 +378,7 @@ class HaPanelDevService extends LitElement { forwardHaptic("failure"); button.actionError(); this._error = this.hass.localize( - "ui.panel.developer-tools.tabs.services.errors.yaml.invalid_yaml" + "ui.panel.developer-tools.tabs.actions.errors.yaml.invalid_yaml" ); return; } @@ -439,7 +440,7 @@ class HaPanelDevService extends LitElement { } this._error = localizedErrorMessage || - this.hass.localize("ui.notification_toast.service_call_failed", { + this.hass.localize("ui.notification_toast.action_failed", { service: this._serviceData!.service!, }) + ` ${err.message}`; return; @@ -630,10 +631,8 @@ class HaPanelDevService extends LitElement { } } -customElements.define("developer-tools-service", HaPanelDevService); - declare global { interface HTMLElementTagNameMap { - "developer-tools-service": HaPanelDevService; + "developer-tools-action": HaPanelDevAction; } } diff --git a/src/panels/developer-tools/developer-tools-router.ts b/src/panels/developer-tools/developer-tools-router.ts index 6fdf6aa01080..6018861ecbf6 100644 --- a/src/panels/developer-tools/developer-tools-router.ts +++ b/src/panels/developer-tools/developer-tools-router.ts @@ -24,9 +24,10 @@ class DeveloperToolsRouter extends HassRouterPage { tag: "developer-tools-event", load: () => import("./event/developer-tools-event"), }, - service: { - tag: "developer-tools-service", - load: () => import("./service/developer-tools-service"), + service: "action", + action: { + tag: "developer-tools-action", + load: () => import("./action/developer-tools-action"), }, state: { tag: "developer-tools-state", diff --git a/src/panels/developer-tools/ha-panel-developer-tools.ts b/src/panels/developer-tools/ha-panel-developer-tools.ts index 667f016ea57c..237e08272412 100644 --- a/src/panels/developer-tools/ha-panel-developer-tools.ts +++ b/src/panels/developer-tools/ha-panel-developer-tools.ts @@ -62,10 +62,8 @@ class PanelDeveloperTools extends LitElement { ${this.hass.localize("ui.panel.developer-tools.tabs.states.title")} - - ${this.hass.localize( - "ui.panel.developer-tools.tabs.services.title" - )} + + ${this.hass.localize("ui.panel.developer-tools.tabs.actions.title")} ${this.hass.localize( diff --git a/src/panels/lovelace/common/compute-tooltip.ts b/src/panels/lovelace/common/compute-tooltip.ts index b371984b44d8..b002cd2caffa 100644 --- a/src/panels/lovelace/common/compute-tooltip.ts +++ b/src/panels/lovelace/common/compute-tooltip.ts @@ -45,7 +45,7 @@ function computeActionTooltip( break; case "call-service": tooltip += `${hass.localize( - "ui.panel.lovelace.cards.picture-elements.call_service", + "ui.panel.lovelace.cards.picture-elements.perform_action", { name: config.service } )}`; break; diff --git a/src/panels/lovelace/common/handle-action.ts b/src/panels/lovelace/common/handle-action.ts index b9b4041d5fbf..f4fdd9065336 100644 --- a/src/panels/lovelace/common/handle-action.ts +++ b/src/panels/lovelace/common/handle-action.ts @@ -148,7 +148,7 @@ export const handleAction = async ( case "call-service": { if (!actionConfig.service) { showToast(node, { - message: hass.localize("ui.panel.lovelace.cards.actions.no_service"), + message: hass.localize("ui.panel.lovelace.cards.actions.no_action"), }); forwardHaptic("failure"); return; diff --git a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts index 491bec6e31d2..ca705fafb726 100644 --- a/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-tile-card-editor.ts @@ -407,7 +407,6 @@ export class HuiTileCardEditor return this.hass!.localize( `ui.panel.lovelace.editor.card.tile.${schema.name}` ); - default: return this.hass!.localize( `ui.panel.lovelace.editor.card.generic.${schema.name}` diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index e37652950131..d4ce2419ed6c 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -135,7 +135,7 @@ export const connectionMixin = >( const message = localizedErrorMessage || (this as any).hass.localize( - "ui.notification_toast.service_call_failed", + "ui.notification_toast.action_failed", "service", `${domain}/${service}` ) + diff --git a/src/translations/en.json b/src/translations/en.json index 865a4f9e7560..424901461d4a 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -429,7 +429,7 @@ "triggered_by": "triggered by", "triggered_by_automation": "triggered by automation", "triggered_by_script": "triggered by script", - "triggered_by_service": "triggered by service", + "triggered_by_action": "triggered by action", "triggered_by_numeric_state_of": "triggered by numeric state of", "triggered_by_state_of": "triggered by state of", "triggered_by_event": "triggered by event", @@ -773,13 +773,13 @@ } }, "service-picker": { - "service": "Service" + "action": "Action" }, "service-control": { "required": "This field is required", "target": "Targets", - "target_description": "What should this service use as targeted areas, devices or entities.", - "data": "Service data", + "target_secondary": "What should this action use as targeted areas, devices or entities.", + "action_data": "Action data", "integration_doc": "Integration documentation" }, "related-items": { @@ -1352,7 +1352,7 @@ "enabled_description": "Disabled entities will not be added to Home Assistant.", "enabled_delay_confirm": "The enabled entities will be added to Home Assistant in {delay} seconds", "enabled_restart_confirm": "Restart Home Assistant to finish enabling the entities", - "hidden_description": "Hidden entities will not be shown on your dashboard or included when indirectly referenced (ie via an area or device). Their history is still tracked and you can still interact with them with services.", + "hidden_explanation": "Hidden entities will not be shown on your dashboard or included when indirectly referenced (ie via an area or device). Their history is still tracked and you can still interact with them with actions.", "delete": "Delete", "confirm_delete": "Are you sure you want to delete this entity?", "update": "Update", @@ -1603,7 +1603,7 @@ "view_network": "View network" }, "services": { - "reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this service.", + "reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this action.", "updateDeviceName": "Set a custom name for this device in the device registry.", "remove": "Remove a device from the Zigbee network.", "zigbee_information": "View the Zigbee information for the device." @@ -1732,7 +1732,7 @@ "step_3": "Tap {link_apps_services} and choose {home_assistant} from the list.", "linked_matter_apps_services": "Linked Matter apps and services", "link_apps_services": "Link apps & services", - "no_home_assistant": "I can’t find Home Assistant on the list", + "no_home_assistant": "I can''t find Home Assistant on the list", "redirect": "You are redirected to the Home Assistant app. Please follow the instructions." }, "google_home_fallback": { @@ -1807,7 +1807,7 @@ "dismiss_all": "Dismiss all" }, "notification_toast": { - "service_call_failed": "Failed to call service {service}.", + "action_failed": "Failed to perform the action {service}.", "connection_lost": "Connection lost. Reconnecting…", "started": "Home Assistant has started!", "starting": "Home Assistant is starting, not everything will be available until it is finished.", @@ -2660,7 +2660,7 @@ "run_text_pipeline": "Run text pipeline", "run_audio_pipeline": "Run audio pipeline", "run_audio_with_wake": "Run audio pipeline with wake word detection", - "response": "[%key:ui::panel::developer-tools::tabs::services::response%]", + "response": "[%key:ui::panel::developer-tools::tabs::actions::response%]", "send": "Send", "continue_listening": "Continue listening for wake word", "continue_talking": "Continue talking", @@ -3267,18 +3267,19 @@ }, "type": { "service": { - "label": "Call service", + "label": "Perform action", "response_variable": "Response variable", - "has_optional_response": "This service can return a response, if you want to use the response, enter the name of a variable the response will be saved in", - "has_response": "This service returns a response, enter the name of a variable the response will be saved in", + "has_optional_response": "This action can return a response, if you want to use the response, enter the name of a variable the response will be saved in", + "has_response": "This action returns a response, enter the name of a variable the response will be saved in", "description": { - "service_based_on_template": "Call a service based on a template on {targets}", - "service_based_on_name": "Call a service ''{name}'' on {targets}", + "picker": "Previously known as call service.", + "service_based_on_template": "Perform an action based on a template on {targets}", + "service_based_on_name": "Perform action ''{name}'' on {targets}", "service_name": "{domain} ''{name}'' on {targets}", - "service_based_on_template_no_targets": "Call a service based on a template", - "service_based_on_name_no_targets": "Call a service ''{name}''", + "service_based_on_template_no_targets": "Perform an action based on a template", + "service_based_on_name_no_targets": "Perform action ''{name}''", "service_name_no_targets": "{domain} ''{name}''", - "service": "Call a service", + "service": "Perform an action", "target_template": "templated {name}", "target_unknown_entity": "unknown entity", "target_unknown_device": "unknown device", @@ -3837,7 +3838,7 @@ "fetching_subscription": "Fetching subscription…", "tts": { "title": "Text-to-speech", - "info": "Bring personality to your home by having it speak to you by using our text-to-speech services. You can use this in automations and scripts by using the {service} service.", + "description": "Bring personality to your home by having it speak to you by using our text-to-speech services. You can use this in automations and scripts by using the {service} action.", "default_language": "Default language to use", "default_voice": "Default voice to use", "try": "Try", @@ -4122,7 +4123,7 @@ "hide_selected": { "button": "Hide selected", "confirm_title": "Do you want to hide {number} {number, plural,\n one {entity}\n other {entities}\n}?", - "confirm_text": "Hidden entities will not be shown on your dashboard. Their history is still tracked and you can still interact with them with services." + "confirm": "Hidden entities will not be shown on your dashboard. Their history is still tracked and you can still interact with them with actions." }, "unhide_selected": { "button": "Unhide selected" @@ -5280,7 +5281,7 @@ "no_entity_toggle": "No entity provided to toggle", "no_navigation_path": "No navigation path specified", "no_url": "No URL to open specified", - "no_service": "No service to run specified" + "no_action": "No action to run specified" }, "empty_state": { "title": "Welcome Home", @@ -5310,7 +5311,7 @@ "navigate_to": "Navigate to {location}", "url": "Open window to {url_path}", "toggle": "Toggle {name}", - "call_service": "Call service {name}", + "perform_action": "Perform action {name}", "more_info": "Show more info: {name}" }, "iframe": { @@ -5625,14 +5626,14 @@ "start_listening": "Start listening", "pipeline_id": "Assistant", "actions": { - "default_action": "Default action", - "call-service": "Call service", + "default_action": "Default", + "call-service": "Perform action", "more-info": "More info", "toggle": "Toggle", "navigate": "Navigate", "assist": "Assist", "url": "URL", - "none": "No action" + "none": "Nothing" } }, "condition-editor": { @@ -5740,7 +5741,7 @@ }, "entity_row": { "divider": "Divider", - "call-service": "Call service", + "call-service": "Perform action", "section": "Section", "weblink": "Web link", "attribute": "Attribute", @@ -5757,7 +5758,7 @@ "button": { "name": "Button", "description": "The Button card allows you to add buttons to perform tasks.", - "default_action_help": "The default action depends on the entity's capabilities, it will either be toggled or the more info dialog will be shown." + "default_action_help": "The default depends on the entity's capabilities, it will either be toggled or the more info dialog will be shown." }, "entity-filter": { "name": "Entity filter", @@ -5875,10 +5876,10 @@ "camera_image": "Camera entity", "image_entity": "Image entity", "camera_view": "Camera view", - "double_tap_action": "Double tap action", + "double_tap_action": "Double tap behavior", "entities": "Entities", "entity": "Entity", - "hold_action": "Hold action", + "hold_action": "Hold behavior", "hours_to_show": "Hours to show", "days_to_show": "Days to show", "icon": "Icon", @@ -5895,7 +5896,7 @@ "show_icon": "Show icon?", "show_name": "Show name?", "show_state": "Show state?", - "tap_action": "Tap action", + "tap_action": "Tap behavior", "title": "Title", "theme": "Theme", "unit": "Unit", @@ -5934,7 +5935,7 @@ }, "picture": { "name": "Picture", - "description": "The Picture card allows you to set an image to use for navigation to various paths in your interface or to call a service." + "description": "The Picture card allows you to set an image to use for navigation to various paths in your interface or to perform an action." }, "picture-elements": { "name": "Picture elements", @@ -5946,7 +5947,7 @@ }, "picture-glance": { "name": "Picture glance", - "description": "The Picture card allows you to set an image to use for navigation to various paths in your interface or to call a service.", + "description": "The Picture card allows you to set an image to use for navigation to various paths in your interface or to perform an action.", "state_entity": "State entity" }, "plant-status": { @@ -5973,7 +5974,7 @@ "name": "Tile", "description": "The tile card gives you a quick overview of your entity. The card allow you to toggle the entity, show the more info dialog or custom actions.", "color": "Color", - "icon_tap_action": "Icon tap action", + "icon_tap_action": "Icon tap behavior", "actions": "Actions", "appearance": "Appearance", "default_color": "Default color (state)", @@ -6690,10 +6691,10 @@ "alert_event_type": "Event type is a mandatory field", "notification_event_fired": "Event {type} successfully fired!" }, - "services": { - "title": "Services", - "description": "The service dev tool allows you to call any available service in Home Assistant.", - "call_service": "Call service", + "actions": { + "title": "Actions", + "description": "The actions dev tool allows you to perform any action available in Home Assistant.", + "call_service": "Perform action", "response": "Response", "column_parameter": "Parameter", "column_description": "Description", @@ -6703,21 +6704,21 @@ "ui_mode": "Go to UI mode", "yaml_parameters": "Parameters only available in YAML mode", "all_parameters": "All available parameters", - "accepts_target": "This service accepts a target, for example: `entity_id: light.bed_light`", + "accepts_target": "This action accepts a target, for example: `entity_id: light.bed_light`", "no_template_ui_support": "The UI does not support templates, you can still use the YAML editor.", "errors": { "ui": { - "no_service": "No service selected, please select a service", - "invalid_service": "Selected service is invalid, please select a valid service", - "no_target": "This service requires a target, please select a target from the picker", - "missing_required_field": "This service requires field {key}, please enter a valid value for {key}" + "no_service": "No action selected, please select an action", + "invalid_service": "Selected action is invalid, please select a valid action", + "no_target": "This action requires a target, please select a target from the picker", + "missing_required_field": "This action requires field {key}, please enter a valid value for {key}" }, "yaml": { - "invalid_yaml": "Service YAML contains syntax errors, please fix the syntax", - "no_service": "No service defined, please define a service: key", - "invalid_service": "Defined service is invalid, please provide a service in the format domain.service", - "no_target": "This service requires a target, please define a target entity_id, device_id, or area_id under target: or data:", - "missing_required_field": "This service requires field {key}, which must be provided under data:" + "invalid_yaml": "Action YAML contains syntax errors, please fix the syntax", + "no_service": "No action defined, please define an action: key", + "invalid_service": "Defined action is invalid, please provide an action in the format domain.action", + "no_target": "This action requires a target, please define a target entity_id, device_id, or area_id under target: or data:", + "missing_required_field": "This action requires field {key}, which must be provided under data:" } } }, From e59c04c68546396f95f71610983912b62cf98bab Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 11 Jul 2024 11:09:14 +0200 Subject: [PATCH 80/86] Display live remaining time for timer on tile card (#21290) Display timer by default on tile card --- src/data/timer.ts | 2 +- src/panels/lovelace/cards/hui-tile-card.ts | 17 +++- .../entity-rows/hui-timer-entity-row.ts | 87 ++----------------- src/state-display/state-display-timer.ts | 74 ++++++++++++++++ src/state-summary/state-card-timer.ts | 67 ++------------ 5 files changed, 101 insertions(+), 146 deletions(-) create mode 100644 src/state-display/state-display-timer.ts diff --git a/src/data/timer.ts b/src/data/timer.ts index 7dc4f8e41dba..4b0ab1ce2768 100644 --- a/src/data/timer.ts +++ b/src/data/timer.ts @@ -92,7 +92,7 @@ export const computeDisplayTimer = ( return hass.formatEntityState(stateObj); } - let display = secondsToDuration(timeRemaining || 0); + let display = secondsToDuration(timeRemaining || 0) || "0"; if (stateObj.state === "paused") { display = `${display} (${hass.formatEntityState(stateObj)})`; diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index ae8c8a99c0b8..3208928d0273 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -311,10 +311,19 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } if (domain === "update") { - return html`${computeUpdateStateDisplay( - stateObj as UpdateEntity, - this.hass! - )}`; + return html` + ${computeUpdateStateDisplay(stateObj as UpdateEntity, this.hass!)} + `; + } + + if (domain === "timer") { + import("../../../state-display/state-display-timer"); + return html` + + `; } return this._renderStateContent(stateObj, "state"); diff --git a/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts b/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts index bd58e41534b2..8cb3cac9a185 100644 --- a/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-timer-entity-row.ts @@ -1,7 +1,6 @@ -import { HassEntity } from "home-assistant-js-websocket"; -import { html, LitElement, PropertyValues, nothing } from "lit"; +import { LitElement, PropertyValues, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeDisplayTimer, timerTimeRemaining } from "../../../data/timer"; +import "../../../state-display/state-display-timer"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; import "../components/hui-generic-entity-row"; @@ -14,42 +13,11 @@ class HuiTimerEntityRow extends LitElement { @state() private _config?: EntityConfig; - @state() private _timeRemaining?: number; - - private _interval?: number; - public setConfig(config: EntityConfig): void { if (!config) { throw new Error("Invalid configuration"); } this._config = config; - - if (!this.hass) { - return; - } - - const stateObj = this.hass!.states[this._config.entity]; - - if (stateObj) { - this._startInterval(stateObj); - } else { - this._clearInterval(); - } - } - - public disconnectedCallback(): void { - super.disconnectedCallback(); - this._clearInterval(); - } - - public connectedCallback(): void { - super.connectedCallback(); - if (this._config && this._config.entity) { - const stateObj = this.hass?.states[this._config!.entity]; - if (stateObj) { - this._startInterval(stateObj); - } - } } protected render() { @@ -70,61 +38,18 @@ class HuiTimerEntityRow extends LitElement { return html`
- ${computeDisplayTimer(this.hass, stateObj, this._timeRemaining)} +
`; } protected shouldUpdate(changedProps: PropertyValues): boolean { - if (changedProps.has("_timeRemaining")) { - return true; - } - return hasConfigOrEntityChanged(this, changedProps); } - - protected updated(changedProps: PropertyValues) { - super.updated(changedProps); - - if (!this._config || !changedProps.has("hass")) { - return; - } - const stateObj = this.hass!.states[this._config!.entity]; - const oldHass = changedProps.get("hass") as this["hass"]; - const oldStateObj = oldHass - ? oldHass.states[this._config!.entity] - : undefined; - - if (oldStateObj !== stateObj) { - this._startInterval(stateObj); - } else if (!stateObj) { - this._clearInterval(); - } - } - - private _clearInterval(): void { - if (this._interval) { - window.clearInterval(this._interval); - this._interval = undefined; - } - } - - private _startInterval(stateObj: HassEntity): void { - this._clearInterval(); - this._calculateRemaining(stateObj); - - if (stateObj.state === "active") { - this._interval = window.setInterval( - () => this._calculateRemaining(stateObj), - 1000 - ); - } - } - - private _calculateRemaining(stateObj: HassEntity): void { - this._timeRemaining = timerTimeRemaining(stateObj); - } } declare global { diff --git a/src/state-display/state-display-timer.ts b/src/state-display/state-display-timer.ts new file mode 100644 index 000000000000..13960c088cc4 --- /dev/null +++ b/src/state-display/state-display-timer.ts @@ -0,0 +1,74 @@ +import type { HassEntity } from "home-assistant-js-websocket"; +import { PropertyValues, ReactiveElement } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { computeDisplayTimer, timerTimeRemaining } from "../data/timer"; +import type { HomeAssistant } from "../types"; + +@customElement("state-display-timer") +class StateDisplayTimer extends ReactiveElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj!: HassEntity; + + @state() private timeRemaining?: number; + + private _updateRemaining: any; + + protected createRenderRoot() { + return this; + } + + protected update(changedProps: PropertyValues) { + super.update(changedProps); + this.innerHTML = + computeDisplayTimer(this.hass, this.stateObj, this.timeRemaining) ?? "-"; + } + + connectedCallback() { + super.connectedCallback(); + if (this.stateObj) { + this._startInterval(this.stateObj); + } + } + + disconnectedCallback() { + super.disconnectedCallback(); + this._clearInterval(); + } + + protected willUpdate(changedProp: PropertyValues): void { + super.willUpdate(changedProp); + if (changedProp.has("stateObj")) { + this._startInterval(this.stateObj); + } + } + + private _clearInterval() { + if (this._updateRemaining) { + clearInterval(this._updateRemaining); + this._updateRemaining = null; + } + } + + private _startInterval(stateObj: HassEntity) { + this._clearInterval(); + this._calculateRemaining(stateObj); + + if (stateObj.state === "active") { + this._updateRemaining = setInterval( + () => this._calculateRemaining(this.stateObj), + 1000 + ); + } + } + + private _calculateRemaining(stateObj: HassEntity) { + this.timeRemaining = timerTimeRemaining(stateObj); + } +} + +declare global { + interface HTMLElementTagNameMap { + "state-display-timer": StateDisplayTimer; + } +} diff --git a/src/state-summary/state-card-timer.ts b/src/state-summary/state-card-timer.ts index 57bb83e8e7be..134ebdb89c61 100644 --- a/src/state-summary/state-card-timer.ts +++ b/src/state-summary/state-card-timer.ts @@ -1,17 +1,10 @@ import type { HassEntity } from "home-assistant-js-websocket"; -import { - css, - CSSResultGroup, - html, - LitElement, - PropertyValues, - TemplateResult, -} from "lit"; +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import "../components/entity/state-info"; -import { computeDisplayTimer, timerTimeRemaining } from "../data/timer"; -import { HomeAssistant } from "../types"; import { haStyle } from "../resources/styles"; +import "../state-display/state-display-timer"; +import { HomeAssistant } from "../types"; @customElement("state-card-timer") class StateCardTimer extends LitElement { @@ -21,10 +14,6 @@ class StateCardTimer extends LitElement { @property({ type: Boolean }) public inDialog = false; - @property({ type: Number }) public timeRemaining?: number; - - private _updateRemaining: any; - protected render(): TemplateResult { return html`
@@ -34,63 +23,21 @@ class StateCardTimer extends LitElement { .inDialog=${this.inDialog} >
- ${this._displayState(this.timeRemaining, this.stateObj)} +
`; } - connectedCallback() { - super.connectedCallback(); - this._startInterval(this.stateObj); - } - - disconnectedCallback() { - super.disconnectedCallback(); - this._clearInterval(); - } - - protected willUpdate(changedProp: PropertyValues): void { - super.willUpdate(changedProp); - if (changedProp.has("stateObj")) { - this._startInterval(this.stateObj); - } - } - - private _clearInterval() { - if (this._updateRemaining) { - clearInterval(this._updateRemaining); - this._updateRemaining = null; - } - } - - private _startInterval(stateObj) { - this._clearInterval(); - this._calculateRemaining(stateObj); - - if (stateObj.state === "active") { - this._updateRemaining = setInterval( - () => this._calculateRemaining(this.stateObj), - 1000 - ); - } - } - - private _calculateRemaining(stateObj) { - this.timeRemaining = timerTimeRemaining(stateObj); - } - - private _displayState(timeRemaining, stateObj) { - return computeDisplayTimer(this.hass, stateObj, timeRemaining); - } - static get styles(): CSSResultGroup { return [ haStyle, css` .state { color: var(--primary-text-color); - margin-left: 16px; margin-inline-start: 16px; margin-inline-end: initial; From 277650e1c15790aa2944dc2278725e8a3538e849 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 11 Jul 2024 12:26:23 +0200 Subject: [PATCH 81/86] Update en.json --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index 424901461d4a..5b9c9762909c 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1732,7 +1732,7 @@ "step_3": "Tap {link_apps_services} and choose {home_assistant} from the list.", "linked_matter_apps_services": "Linked Matter apps and services", "link_apps_services": "Link apps & services", - "no_home_assistant": "I can''t find Home Assistant on the list", + "no_home_assistant": "I can't find Home Assistant on the list", "redirect": "You are redirected to the Home Assistant app. Please follow the instructions." }, "google_home_fallback": { From 3f34dacec9185c5d41f68938bd2abda8e07b8ffa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 21:16:54 +0200 Subject: [PATCH 82/86] Update typescript-eslint monorepo to v7.16.0 (#21372) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 25156691a324..c6e8147bb3da 100644 --- a/package.json +++ b/package.json @@ -185,8 +185,8 @@ "@types/tar": "6.1.13", "@types/ua-parser-js": "0.7.39", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "7.15.0", - "@typescript-eslint/parser": "7.15.0", + "@typescript-eslint/eslint-plugin": "7.16.0", + "@typescript-eslint/parser": "7.16.0", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.3", diff --git a/yarn.lock b/yarn.lock index 1d34ef6c5c0b..15d45cdf844c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4584,15 +4584,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.15.0" +"@typescript-eslint/eslint-plugin@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/eslint-plugin@npm:7.16.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.15.0" - "@typescript-eslint/type-utils": "npm:7.15.0" - "@typescript-eslint/utils": "npm:7.15.0" - "@typescript-eslint/visitor-keys": "npm:7.15.0" + "@typescript-eslint/scope-manager": "npm:7.16.0" + "@typescript-eslint/type-utils": "npm:7.16.0" + "@typescript-eslint/utils": "npm:7.16.0" + "@typescript-eslint/visitor-keys": "npm:7.16.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -4603,44 +4603,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/e6b21687ab9e9dc38eb1b1d90a3ac483f3f5e5e9c49aa8a434a24de016822d65c82b926cda2ae79bac2225bd9495fb04f7aa6afcaad2b09f6129fd8014fbcedd + checksum: 10/beda6b586bfc953843877395b09acc0525d727dcb77e6ded5fbc645a9008b7e60360ddbaf6a9b7deaf23cd42c206412b7150d8df27f1fe2da3dc24dfab1c8d71 languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/parser@npm:7.15.0" +"@typescript-eslint/parser@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/parser@npm:7.16.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.15.0" - "@typescript-eslint/types": "npm:7.15.0" - "@typescript-eslint/typescript-estree": "npm:7.15.0" - "@typescript-eslint/visitor-keys": "npm:7.15.0" + "@typescript-eslint/scope-manager": "npm:7.16.0" + "@typescript-eslint/types": "npm:7.16.0" + "@typescript-eslint/typescript-estree": "npm:7.16.0" + "@typescript-eslint/visitor-keys": "npm:7.16.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.56.0 peerDependenciesMeta: typescript: optional: true - checksum: 10/0b5e7a14fa5d0680efb17e750a095729a7fb7c785d7a0fea2f9e6cbfef9e65caab2b751654b348b9ab813d222c1c3f8189ebf48561b81224d1821cee5c99d658 + checksum: 10/dc374e6c9e7dfcdd968828bb32ef59d3ebabd0a18671dee22d14dda2c713dade6eb493fd11b127df17035c7451898b42f4a88102da9a4bf3ca6a3baed8c20309 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/scope-manager@npm:7.15.0" +"@typescript-eslint/scope-manager@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/scope-manager@npm:7.16.0" dependencies: - "@typescript-eslint/types": "npm:7.15.0" - "@typescript-eslint/visitor-keys": "npm:7.15.0" - checksum: 10/45bfdbae2d080691a34f5b37679b4a4067981baa3b82922268abdd21f6917a8dd1c4ccb12133f6c9cce81cfd640040913b223e8125235b92f42fdb57db358a3e + "@typescript-eslint/types": "npm:7.16.0" + "@typescript-eslint/visitor-keys": "npm:7.16.0" + checksum: 10/bf39a3ab803503c33e6c33568e7b93793d53d18100cb2f2ec1a540121aeba74d291d19c9ad3933198ff15e53a46d2f92db0c54309259dc99c1e3e297becd5677 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/type-utils@npm:7.15.0" +"@typescript-eslint/type-utils@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/type-utils@npm:7.16.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.15.0" - "@typescript-eslint/utils": "npm:7.15.0" + "@typescript-eslint/typescript-estree": "npm:7.16.0" + "@typescript-eslint/utils": "npm:7.16.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: @@ -4648,23 +4648,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/64fa589b413567df3689a19ef88f3dbaed66d965e39cc548a58626eb5bd8fc4e2338496eb632f3472de9ae9800cb14d0e48ef3508efe80bdb91af8f3f1e56ad7 + checksum: 10/84925c851a515768317573984dc855ac93bf787ebaa6382379dea6b356adb936ebd38bf7ab2f95124c68de7ab1fd5c849fe6717929343a80b839757fb5bf3af0 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/types@npm:7.15.0" - checksum: 10/b36c98344469f4bc54a5199733ea4f6d4d0f2da1070605e60d4031e2da2946b84b91a90108516c8e6e83a21030ba4e935053a0906041c920156de40683297d0b +"@typescript-eslint/types@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/types@npm:7.16.0" + checksum: 10/0813d9eb158f984b9d7e9e83961533ddc1e8c8815ca9059dab820df276b1e537b183f4c83cc4fe79ab3865cde1a64f2ec3f7fffe7209872d7d404636299f630b languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.15.0" +"@typescript-eslint/typescript-estree@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/typescript-estree@npm:7.16.0" dependencies: - "@typescript-eslint/types": "npm:7.15.0" - "@typescript-eslint/visitor-keys": "npm:7.15.0" + "@typescript-eslint/types": "npm:7.16.0" + "@typescript-eslint/visitor-keys": "npm:7.16.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -4674,31 +4674,31 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10/c5fb15108fbbc1bc976e827218ff7bfbc78930c5906292325ee42ba03514623e7b861497b3e3087f71ede9a757b16441286b4d234450450b0dd70ff753782736 + checksum: 10/5719c0cb649d627a073f1c8994a6073acc211ecfce0daef61d2de4315e42a23cf79e4dacb3b3596c4792eab062fdd22080c62345e2a58d38e7268eb6103a46d4 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/utils@npm:7.15.0" +"@typescript-eslint/utils@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/utils@npm:7.16.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.15.0" - "@typescript-eslint/types": "npm:7.15.0" - "@typescript-eslint/typescript-estree": "npm:7.15.0" + "@typescript-eslint/scope-manager": "npm:7.16.0" + "@typescript-eslint/types": "npm:7.16.0" + "@typescript-eslint/typescript-estree": "npm:7.16.0" peerDependencies: eslint: ^8.56.0 - checksum: 10/f6de1849dee610a8110638be98ab2ec09e7cdf2f756b538b0544df2dfad86a8e66d5326a765302fe31553e8d9d3170938c0d5d38bd9c7d36e3ee0beb1bdc8172 + checksum: 10/325eab6705e70322d8df613cba4b018abc5d8ef857eb6c86f7a8376334eac789e6a585d30c041045c7eeede18083744faae66f48033e7811b2a23ebe8f6d3407 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.15.0": - version: 7.15.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.15.0" +"@typescript-eslint/visitor-keys@npm:7.16.0": + version: 7.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:7.16.0" dependencies: - "@typescript-eslint/types": "npm:7.15.0" + "@typescript-eslint/types": "npm:7.16.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10/0e17d7f5de767da7f98170c2efc905cdb0ceeaf04a667e12ca1a92eae64479a07f4f8e2a9b5023b055b01250916c3bcac86908cd06552610baff734fafae4464 + checksum: 10/aae065bdd6d5681d40df51af24933fc86c15f355f9d8f85c39a506f352ddc2a76fc72d4f8cf823ebb7550c84d543605a2fdd7d06979a0967cd48c1f542436714 languageName: node linkType: hard @@ -8986,8 +8986,8 @@ __metadata: "@types/tar": "npm:6.1.13" "@types/ua-parser-js": "npm:0.7.39" "@types/webspeechapi": "npm:0.0.29" - "@typescript-eslint/eslint-plugin": "npm:7.15.0" - "@typescript-eslint/parser": "npm:7.15.0" + "@typescript-eslint/eslint-plugin": "npm:7.16.0" + "@typescript-eslint/parser": "npm:7.16.0" "@vaadin/combo-box": "npm:24.4.1" "@vaadin/vaadin-themable-mixin": "npm:24.4.1" "@vibrant/color": "npm:3.2.1-alpha.1" From 7b66ee06eb7a2a90419b2fe197ba628dec1f2ec0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Jul 2024 01:15:19 +0200 Subject: [PATCH 83/86] Update vaadinWebComponents monorepo to v24.4.2 (#21376) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 170 +++++++++++++++++++++++++-------------------------- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/package.json b/package.json index c6e8147bb3da..ea7561e20a5c 100644 --- a/package.json +++ b/package.json @@ -88,8 +88,8 @@ "@polymer/paper-tabs": "3.1.0", "@polymer/polymer": "3.5.1", "@thomasloven/round-slider": "0.6.0", - "@vaadin/combo-box": "24.4.1", - "@vaadin/vaadin-themable-mixin": "24.4.1", + "@vaadin/combo-box": "24.4.2", + "@vaadin/vaadin-themable-mixin": "24.4.2", "@vibrant/color": "3.2.1-alpha.1", "@vibrant/core": "3.2.1-alpha.1", "@vibrant/quantizer-mmcq": "3.2.1-alpha.1", diff --git a/yarn.lock b/yarn.lock index 15d45cdf844c..a1d302b789fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4709,129 +4709,129 @@ __metadata: languageName: node linkType: hard -"@vaadin/a11y-base@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/a11y-base@npm:24.4.1" +"@vaadin/a11y-base@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/a11y-base@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.2" lit: "npm:^3.0.0" - checksum: 10/b59f6b8ecab3b359ce3f4e0362674b45800bb6a61343895cecab7956eb64de4ed94f7ed34e943cb27865bc5fcdf980d9012533a1cbd11ed5f10ed14f6282cf9e + checksum: 10/6b3bd35507168e1524dd26e5b18c5e1f4e6d8db2ec576fdeb9928282257d47c5b6984395286786b11aeb6aeacdade42a495cb75517cb4fa2cb450cad88d9916a languageName: node linkType: hard -"@vaadin/combo-box@npm:24.4.1": - version: 24.4.1 - resolution: "@vaadin/combo-box@npm:24.4.1" +"@vaadin/combo-box@npm:24.4.2": + version: 24.4.2 + resolution: "@vaadin/combo-box@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.1" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/field-base": "npm:~24.4.1" - "@vaadin/input-container": "npm:~24.4.1" - "@vaadin/item": "npm:~24.4.1" - "@vaadin/lit-renderer": "npm:~24.4.1" - "@vaadin/overlay": "npm:~24.4.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" - "@vaadin/vaadin-material-styles": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" - checksum: 10/5caca3660fa91f8ae913a2159e7533aa545e21593574a80ca317a13cc2a5ddf8754beb852d6d3ff4b31e8171bf581d784de8925af17d57096a2f5842a4c699d3 + "@vaadin/a11y-base": "npm:~24.4.2" + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/field-base": "npm:~24.4.2" + "@vaadin/input-container": "npm:~24.4.2" + "@vaadin/item": "npm:~24.4.2" + "@vaadin/lit-renderer": "npm:~24.4.2" + "@vaadin/overlay": "npm:~24.4.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.2" + "@vaadin/vaadin-material-styles": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" + checksum: 10/6d75c4ce8eeffbb4015436115afec8f6d429c2840dc300eaa6c737ae262b41fe3bb3548c5bc948c55b41a30a66b7df47eabdb526c3805bd38dae99ee3bc63d0e languageName: node linkType: hard -"@vaadin/component-base@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/component-base@npm:24.4.1" +"@vaadin/component-base@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/component-base@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" "@vaadin/vaadin-development-mode-detector": "npm:^2.0.0" "@vaadin/vaadin-usage-statistics": "npm:^2.1.0" lit: "npm:^3.0.0" - checksum: 10/5717aaa2b418930ceb9a77b8641e5e103ae2ac2b47dcb4dd16cf245edc51c4c79d9573338520d4c412d4dd39daa132606d5f3474bf217390e866b60a6291e7dd + checksum: 10/7e233c68da0ea673c6bcacc13488059a063d69734b222be663fb85542932cbbc4031e2855fbebc8e8aeec42d9ce1c05713890a8be3a642050921fb0b743e2eb7 languageName: node linkType: hard -"@vaadin/field-base@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/field-base@npm:24.4.1" +"@vaadin/field-base@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/field-base@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.1" - "@vaadin/component-base": "npm:~24.4.1" + "@vaadin/a11y-base": "npm:~24.4.2" + "@vaadin/component-base": "npm:~24.4.2" lit: "npm:^3.0.0" - checksum: 10/8feed52803b9078b62fd0124a90f70cdb69d1620e507b605ec57a5a4523af0cf087d0b5864bb4fdd4676b9b96a5182b0e69b53dc36d4f791fcfcd4a372869883 + checksum: 10/98e680fa02b1dbd636df3244fb2b08add4a214613034de2b3bdfd1e66bad407788c3f192ded98d348d3ab2f3ac7992d7819413d46958c371f8ff9b08f66d80f1 languageName: node linkType: hard -"@vaadin/icon@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/icon@npm:24.4.1" +"@vaadin/icon@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/icon@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" lit: "npm:^3.0.0" - checksum: 10/0097ddeff4e705bae69dbd6e6fb6b2c55a969ef2b3dfefd794e6e7b9e70f987d31e4952d84cbf582d8f76b93f204fe92760eb68ef12d037c9d54f77bad7ace02 + checksum: 10/e8168ed771681688dc3fab96296cb6bf0568eab2788ecdb08b4b4f744873fb99a0b3c849283460356b2f05355d0ea03c801b4cf42b881e020b060bf4c0525b49 languageName: node linkType: hard -"@vaadin/input-container@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/input-container@npm:24.4.1" +"@vaadin/input-container@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/input-container@npm:24.4.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" - "@vaadin/vaadin-material-styles": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.2" + "@vaadin/vaadin-material-styles": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" lit: "npm:^3.0.0" - checksum: 10/b6c4d448182cd7f55e671ed4ed06e8076c320ff9659a2e19e7e80181b2a338cd4e2a2de328ff7839c965a81e32c2609f825c9df2da55d99af081951e568c9457 + checksum: 10/1519819566d5afef998d155be96a6acf2ffceef9980bf34b60ee1d0c1048a2e5282fd7658d043f130114f08cac5662c8bc3d4337c8aa7cd0ba1b6048cbb62f46 languageName: node linkType: hard -"@vaadin/item@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/item@npm:24.4.1" +"@vaadin/item@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/item@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.1" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" - "@vaadin/vaadin-material-styles": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" - checksum: 10/81d4560461ea13818a3c5604cf3c4e3acd6de9e8cac51e1ab41d7b2d0d14d09519790c8cfbab5b391f88461cde662915e4093e95491dc83942c460d11bb698e4 + "@vaadin/a11y-base": "npm:~24.4.2" + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.2" + "@vaadin/vaadin-material-styles": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" + checksum: 10/871711a437429a32583c73ee55d9c0734bd6c5a82a04b39be89082190aef91fd1690784902e0d7951c5c03c701af2ba9a390e7eef13800363302df41896586ca languageName: node linkType: hard -"@vaadin/lit-renderer@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/lit-renderer@npm:24.4.1" +"@vaadin/lit-renderer@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/lit-renderer@npm:24.4.2" dependencies: lit: "npm:^3.0.0" - checksum: 10/9a2ebf90ca4f3a08152058a5e431a4019bac78fb94a38b382550e85ca2993b35bb09a94a47e573529cd94a1b99bcbcdd89d71e1ec9c12a3a796e2e41cc79221f + checksum: 10/668fac55b69999e682c23f24ce3fdbf8ee13aa926b1b5f6ae7fb11111244bf50fbb46c3d673c2d650c8f55202ec529bfe0fb940cf6117ed12b8067d591bbbdc3 languageName: node linkType: hard -"@vaadin/overlay@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/overlay@npm:24.4.1" +"@vaadin/overlay@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/overlay@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" "@polymer/polymer": "npm:^3.0.0" - "@vaadin/a11y-base": "npm:~24.4.1" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/vaadin-lumo-styles": "npm:~24.4.1" - "@vaadin/vaadin-material-styles": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" + "@vaadin/a11y-base": "npm:~24.4.2" + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/vaadin-lumo-styles": "npm:~24.4.2" + "@vaadin/vaadin-material-styles": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" lit: "npm:^3.0.0" - checksum: 10/4b899ffe4bd22104e7c038f9669d18d3ba482875cbe7425ac9e98da6fec397c4419580e2f0f6dcd1411acd42cd4cc6dc5267393e7deedd1701195ddcd99e9d2d + checksum: 10/7a0b1a32d61a5a17961e57c95a62cb7a666d2a78c67f115d405011a5271f78239eb8e776db80c27428f97626dd1ec1a2371eeb0991d17581fc672524572c4247 languageName: node linkType: hard @@ -4842,36 +4842,36 @@ __metadata: languageName: node linkType: hard -"@vaadin/vaadin-lumo-styles@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/vaadin-lumo-styles@npm:24.4.1" +"@vaadin/vaadin-lumo-styles@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/vaadin-lumo-styles@npm:24.4.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/icon": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" - checksum: 10/cec42991f1bdab3a1da179f77593735dbc6b6ec677195cd1558eeb79fc1c5707badad3818103f57cf0a68d141e7cc2860ab634e2b99b00d71e289c6dd884b375 + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/icon": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" + checksum: 10/dfb95f3c4ab998022c51f816cfb9a39c2ddec8fb340e5c99c3617cfefc8d4915bd7d06be9a878930594afa70c5ed1f6dab9daa02515033d26fdae3570274ae04 languageName: node linkType: hard -"@vaadin/vaadin-material-styles@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/vaadin-material-styles@npm:24.4.1" +"@vaadin/vaadin-material-styles@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/vaadin-material-styles@npm:24.4.2" dependencies: "@polymer/polymer": "npm:^3.0.0" - "@vaadin/component-base": "npm:~24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:~24.4.1" - checksum: 10/d128217dbd0333ecf6c935dfe09a60bf9e67ad1c65430d4a052a9f5a3691677854f60c45faa40b33889380feac0f29b2a6376accb928dd6c3114cd167cbbcc9f + "@vaadin/component-base": "npm:~24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:~24.4.2" + checksum: 10/f94c531be9da3cd9a70caffd2925f348e0a06043ae512209ca0926599bff77ba0b70643fc375fb71b9debc0c0d8204618ccf5e986642bbb3335f733650f2b58b languageName: node linkType: hard -"@vaadin/vaadin-themable-mixin@npm:24.4.1, @vaadin/vaadin-themable-mixin@npm:~24.4.1": - version: 24.4.1 - resolution: "@vaadin/vaadin-themable-mixin@npm:24.4.1" +"@vaadin/vaadin-themable-mixin@npm:24.4.2, @vaadin/vaadin-themable-mixin@npm:~24.4.2": + version: 24.4.2 + resolution: "@vaadin/vaadin-themable-mixin@npm:24.4.2" dependencies: "@open-wc/dedupe-mixin": "npm:^1.3.0" lit: "npm:^3.0.0" - checksum: 10/576f39795fa7112f1f872449d97690814dc0dd982125a8ceeee7a8e7d3aa66b18ea6288f38a95b40a7d9e3008fd5cd9bbb73af9a7cb16cae84f75206f76327b4 + checksum: 10/d86979fb9eb6e214685a01c9d596f905eac5444af7bfadf3422c0bdbf80ea0f7cd8dae8b286cd95c422560426c3321c62d69b58c7f72473240c7a824df61644c languageName: node linkType: hard @@ -8988,8 +8988,8 @@ __metadata: "@types/webspeechapi": "npm:0.0.29" "@typescript-eslint/eslint-plugin": "npm:7.16.0" "@typescript-eslint/parser": "npm:7.16.0" - "@vaadin/combo-box": "npm:24.4.1" - "@vaadin/vaadin-themable-mixin": "npm:24.4.1" + "@vaadin/combo-box": "npm:24.4.2" + "@vaadin/vaadin-themable-mixin": "npm:24.4.2" "@vibrant/color": "npm:3.2.1-alpha.1" "@vibrant/core": "npm:3.2.1-alpha.1" "@vibrant/quantizer-mmcq": "npm:3.2.1-alpha.1" From db314522d78d3eb2277a0e22ad7abc7e816b02e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Jul 2024 01:18:34 +0200 Subject: [PATCH 84/86] Update dependency glob to v10.4.5 (#21374) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index ea7561e20a5c..e6f719e00765 100644 --- a/package.json +++ b/package.json @@ -205,7 +205,7 @@ "eslint-plugin-wc": "2.1.0", "fancy-log": "2.0.0", "fs-extra": "11.2.0", - "glob": "10.4.3", + "glob": "10.4.5", "gulp": "5.0.0", "gulp-json-transform": "0.5.0", "gulp-rename": "2.0.0", diff --git a/yarn.lock b/yarn.lock index a1d302b789fc..dd0e51c705ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8542,9 +8542,9 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.4.3, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": - version: 10.4.3 - resolution: "glob@npm:10.4.3" +"glob@npm:10.4.5, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": + version: 10.4.5 + resolution: "glob@npm:10.4.5" dependencies: foreground-child: "npm:^3.1.0" jackspeak: "npm:^3.1.2" @@ -8554,7 +8554,7 @@ __metadata: path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10/7670e257bc7cf62a5649e79a71fc3b74806516eabfbfef0a949e11c5530c215d0f6d75c8c0c35266ff44ef6cb29b6c0e59be63906909be946d4c65df5d336be8 + checksum: 10/698dfe11828b7efd0514cd11e573eaed26b2dff611f0400907281ce3eab0c1e56143ef9b35adc7c77ecc71fba74717b510c7c223d34ca8a98ec81777b293d4ac languageName: node linkType: hard @@ -9026,7 +9026,7 @@ __metadata: fancy-log: "npm:2.0.0" fs-extra: "npm:11.2.0" fuse.js: "npm:7.0.0" - glob: "npm:10.4.3" + glob: "npm:10.4.5" google-timezones-json: "npm:1.2.0" gulp: "npm:5.0.0" gulp-json-transform: "npm:0.5.0" From a60242f0424a4bedf3d0e2456fad46eb520546a2 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Sat, 13 Jul 2024 11:35:03 +0200 Subject: [PATCH 85/86] Fix state color for locking and unlocking state (#21369) --- src/resources/ha-style.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/resources/ha-style.ts b/src/resources/ha-style.ts index 1fa724ac0af8..2fbabcfbba8d 100644 --- a/src/resources/ha-style.ts +++ b/src/resources/ha-style.ts @@ -163,10 +163,11 @@ const mainStyles = css` --state-light-active-color: var(--amber-color); --state-lock-jammed-color: var(--red-color); --state-lock-locked-color: var(--green-color); - --state-lock-pending-color: var(--orange-color); + --state-lock-locking-color: var(--orange-color); --state-lock-unlocked-color: var(--red-color); - --state-lock-opening-color: var(--orange-color); + --state-lock-unlocking-color: var(--orange-color); --state-lock-open-color: var(--red-color); + --state-lock-opening-color: var(--orange-color); --state-media_player-active-color: var(--light-blue-color); --state-person-active-color: var(--blue-color); --state-person-home-color: var(--green-color); From 8d74174be197c0f5757da581278965c37b2cf510 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Jul 2024 11:39:17 +0200 Subject: [PATCH 86/86] Update dependency glob to v11 (#21375) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 71 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index e6f719e00765..3f53739f5a8f 100644 --- a/package.json +++ b/package.json @@ -205,7 +205,7 @@ "eslint-plugin-wc": "2.1.0", "fancy-log": "2.0.0", "fs-extra": "11.2.0", - "glob": "10.4.5", + "glob": "11.0.0", "gulp": "5.0.0", "gulp-json-transform": "0.5.0", "gulp-rename": "2.0.0", diff --git a/yarn.lock b/yarn.lock index dd0e51c705ab..4db921d9d794 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8542,19 +8542,19 @@ __metadata: languageName: node linkType: hard -"glob@npm:10.4.5, glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": - version: 10.4.5 - resolution: "glob@npm:10.4.5" +"glob@npm:11.0.0": + version: 11.0.0 + resolution: "glob@npm:11.0.0" dependencies: foreground-child: "npm:^3.1.0" - jackspeak: "npm:^3.1.2" - minimatch: "npm:^9.0.4" + jackspeak: "npm:^4.0.1" + minimatch: "npm:^10.0.0" minipass: "npm:^7.1.2" package-json-from-dist: "npm:^1.0.0" - path-scurry: "npm:^1.11.1" + path-scurry: "npm:^2.0.0" bin: glob: dist/esm/bin.mjs - checksum: 10/698dfe11828b7efd0514cd11e573eaed26b2dff611f0400907281ce3eab0c1e56143ef9b35adc7c77ecc71fba74717b510c7c223d34ca8a98ec81777b293d4ac + checksum: 10/e66939201d11ae30fe97e3364ac2be5c59d6c9bfce18ac633edfad473eb6b46a7553f6f73658f67caaf6cccc1df1ae336298a45e9021fa5695fd78754cc1603e languageName: node linkType: hard @@ -8571,6 +8571,22 @@ __metadata: languageName: node linkType: hard +"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.7, glob@npm:^10.4.1": + version: 10.4.5 + resolution: "glob@npm:10.4.5" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10/698dfe11828b7efd0514cd11e573eaed26b2dff611f0400907281ce3eab0c1e56143ef9b35adc7c77ecc71fba74717b510c7c223d34ca8a98ec81777b293d4ac + languageName: node + linkType: hard + "glob@npm:^7.1.3, glob@npm:^7.1.6": version: 7.2.3 resolution: "glob@npm:7.2.3" @@ -9026,7 +9042,7 @@ __metadata: fancy-log: "npm:2.0.0" fs-extra: "npm:11.2.0" fuse.js: "npm:7.0.0" - glob: "npm:10.4.5" + glob: "npm:11.0.0" google-timezones-json: "npm:1.2.0" gulp: "npm:5.0.0" gulp-json-transform: "npm:0.5.0" @@ -10052,6 +10068,19 @@ __metadata: languageName: node linkType: hard +"jackspeak@npm:^4.0.1": + version: 4.0.1 + resolution: "jackspeak@npm:4.0.1" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10/b20dc0df0dbb2903e4d540ae68308ec7d1dd60944b130e867e218c98b5d77481d65ea734b6c81c812d481500076e8b3fdfccfb38fc81cb1acf165e853da3e26c + languageName: node + linkType: hard + "jake@npm:^10.8.5": version: 10.9.1 resolution: "jake@npm:10.9.1" @@ -10733,6 +10762,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^11.0.0": + version: 11.0.0 + resolution: "lru-cache@npm:11.0.0" + checksum: 10/41f36fbff8b6f199cce3e9cb2b625714f97a535dfd7f16d0988c2627f9ed4c38b6dc8f9ea7fdba19262a7c917ba41c89cad15ca3e3791fc9a2068af472b5bc8d + languageName: node + linkType: hard + "lru-cache@npm:^5.1.1": version: 5.1.1 resolution: "lru-cache@npm:5.1.1" @@ -10997,6 +11033,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.0.0": + version: 10.0.1 + resolution: "minimatch@npm:10.0.1" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10/082e7ccbc090d5f8c4e4e029255d5a1d1e3af37bda837da2b8b0085b1503a1210c91ac90d9ebfe741d8a5f286ece820a1abb4f61dc1f82ce602a055d461d93f3 + languageName: node + linkType: hard + "minimatch@npm:^5.0.1": version: 5.1.6 resolution: "minimatch@npm:5.1.6" @@ -11910,6 +11955,16 @@ __metadata: languageName: node linkType: hard +"path-scurry@npm:^2.0.0": + version: 2.0.0 + resolution: "path-scurry@npm:2.0.0" + dependencies: + lru-cache: "npm:^11.0.0" + minipass: "npm:^7.1.2" + checksum: 10/285ae0c2d6c34ae91dc1d5378ede21981c9a2f6de1ea9ca5a88b5a270ce9763b83dbadc7a324d512211d8d36b0c540427d3d0817030849d97a60fa840a2c59ec + languageName: node + linkType: hard + "path-to-regexp@npm:0.1.7": version: 0.1.7 resolution: "path-to-regexp@npm:0.1.7"