From 0c3fd8f3ad226fbc440d68ca6b450ed637324eb3 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Fri, 10 Dec 2021 14:41:09 +0100
Subject: [PATCH 01/11] typo login -> log in (#10850)
---
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 f4ac593a0c..d9e79df1f9 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2515,7 +2515,7 @@
"admin": "Administrator",
"group": "Group",
"active": "Active",
- "local_only": "Can only login from the local network",
+ "local_only": "Can only log in from the local network",
"system_generated": "System generated",
"system_generated_users_not_removable": "Unable to remove system generated users.",
"system_generated_users_not_editable": "Unable to update system generated users.",
From cea40610c097dbd0b54c2944e5dab29833a750d3 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Fri, 10 Dec 2021 14:44:40 +0100
Subject: [PATCH 02/11] Add base trigger to struct (#10851)
---
src/panels/config/automation/structs.ts | 7 ++++-
.../types/ha-automation-trigger-state.ts | 31 +++++++++++++------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/panels/config/automation/structs.ts b/src/panels/config/automation/structs.ts
index eb6baefa97..d54d9761f4 100644
--- a/src/panels/config/automation/structs.ts
+++ b/src/panels/config/automation/structs.ts
@@ -1,4 +1,9 @@
-import { object, optional, number } from "superstruct";
+import { object, optional, number, string } from "superstruct";
+
+export const baseTriggerStruct = object({
+ platform: string(),
+ id: optional(string()),
+});
export const forDictStruct = object({
days: optional(number()),
diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts
index e75f2f8b33..9e362634ea 100644
--- a/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts
+++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-state.ts
@@ -1,7 +1,15 @@
import "@polymer/paper-input/paper-input";
import { html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators";
-import { assert, literal, object, optional, string, union } from "superstruct";
+import {
+ assert,
+ assign,
+ literal,
+ object,
+ optional,
+ string,
+ union,
+} from "superstruct";
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { hasTemplate } from "../../../../../common/string/has-template";
@@ -10,20 +18,23 @@ import "../../../../../components/entity/ha-entity-picker";
import "../../../../../components/ha-duration-input";
import { StateTrigger } from "../../../../../data/automation";
import { HomeAssistant } from "../../../../../types";
-import { forDictStruct } from "../../structs";
+import { baseTriggerStruct, forDictStruct } from "../../structs";
import {
handleChangeEvent,
TriggerElement,
} from "../ha-automation-trigger-row";
-const stateTriggerStruct = object({
- platform: literal("state"),
- entity_id: string(),
- attribute: optional(string()),
- from: optional(string()),
- to: optional(string()),
- for: optional(union([string(), forDictStruct])),
-});
+const stateTriggerStruct = assign(
+ baseTriggerStruct,
+ object({
+ platform: literal("state"),
+ entity_id: string(),
+ attribute: optional(string()),
+ from: optional(string()),
+ to: optional(string()),
+ for: optional(union([string(), forDictStruct])),
+ })
+);
@customElement("ha-automation-trigger-state")
export class HaStateTrigger extends LitElement implements TriggerElement {
From 48c66e63497cea6c2817c569f8c31815ab87421b Mon Sep 17 00:00:00 2001
From: Erik Montnemery
Date: Fri, 10 Dec 2021 18:49:53 +0100
Subject: [PATCH 03/11] Tweak some energy related translation strings (#10852)
---
src/translations/en.json | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/translations/en.json b/src/translations/en.json
index d9e79df1f9..d6e784beb4 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1146,7 +1146,7 @@
"cost_number": "Use a static price",
"cost_number_input": "Price per {unit}",
"gas_usage": "Gas usage",
- "m3_or_kWh": "m³ or kWh"
+ "m3_or_kWh": "ft³, m³, Wh, kWh or MWh"
}
},
"device_consumption": {
@@ -1187,19 +1187,19 @@
},
"entity_unexpected_unit_energy": {
"title": "Unexpected unit of measurement",
- "description": "The following entities do not have the expected units of measurement 'kWh' or 'Wh':"
+ "description": "The following entities do not have the expected units of measurement 'Wh', 'kWh' or 'MWh':"
},
"entity_unexpected_unit_gas": {
"title": "Unexpected unit of measurement",
- "description": "The following entities do not have the expected units of measurement 'kWh', 'm³' or 'ft³':"
+ "description": "The following entities do not have the expected units of measurement 'Wh', 'kWh' or 'MWh' for an energy sensor or 'm³' or 'ft³' for a gas sensor:"
},
"entity_unexpected_unit_energy_price": {
"title": "Unexpected unit of measurement",
- "description": "The following entities do not have the expected units of measurement ''{currency}/kWh'' or ''{currency}/Wh'':"
+ "description": "The following entities do not have the expected units of measurement ''{currency}/kWh'', ''{currency}/Wh'' or ''{currency}/MWh'':"
},
"entity_unexpected_unit_gas_price": {
"title": "Unexpected unit of measurement",
- "description": "The following entities do not have the expected units of measurement ''{currency}/kWh'', ''{currency}/Wh'', ''{currency}/m³'' or ''{currency}/ft³'':"
+ "description": "The following entities do not have the expected units of measurement ''{currency}/kWh'', ''{currency}/Wh'', ''{currency}/MWh'', ''{currency}/m³'' or ''{currency}/ft³'':"
},
"entity_unexpected_state_class": {
"title": "Unexpected state class",
From bec5c564b62b63199dea33776127037f1d149768 Mon Sep 17 00:00:00 2001
From: Matthias de Baat
Date: Fri, 10 Dec 2021 20:18:05 +0100
Subject: [PATCH 04/11] Update blueprint description (#10854)
---
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 d6e784beb4..96ebbaa632 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -939,7 +939,7 @@
},
"blueprints": {
"title": "Blueprints",
- "description": "Manage blueprints"
+ "description": "Pre-made automations and scripts by the community"
},
"supervisor": {
"title": "Add-ons, Backups & Supervisor",
From 585648ac4cd13b901d2a7e616c7ff6c3117dc5fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joakim=20S=C3=B8rensen?=
Date: Sat, 11 Dec 2021 08:30:35 +0100
Subject: [PATCH 05/11] Revert "handle ha-radio and ha-checkbox in
ha-formfield" (#10863)
---
src/components/ha-formfield.ts | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/src/components/ha-formfield.ts b/src/components/ha-formfield.ts
index 8a1e60e480..e0452e0db7 100644
--- a/src/components/ha-formfield.ts
+++ b/src/components/ha-formfield.ts
@@ -5,22 +5,6 @@ import { customElement } from "lit/decorators";
@customElement("ha-formfield")
// @ts-expect-error
export class HaFormfield extends Formfield {
- protected _labelClick() {
- const input = this.input;
- if (input) {
- input.focus();
- switch (input.tagName) {
- case "HA-CHECKBOX":
- case "HA-RADIO":
- (input as any).checked = !(input as any).checked;
- break;
- default:
- input.click();
- break;
- }
- }
- }
-
protected static get styles(): CSSResultGroup {
return [
Formfield.styles,
From ca6fd6c77040e378b8ec7823df7ccd8d279c6ebf Mon Sep 17 00:00:00 2001
From: Philip Allgaier
Date: Sat, 11 Dec 2021 17:01:24 +0100
Subject: [PATCH 06/11] Prevent quickbar command entry duplicates (#10861)
---
src/dialogs/quick-bar/ha-quick-bar.ts | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/dialogs/quick-bar/ha-quick-bar.ts b/src/dialogs/quick-bar/ha-quick-bar.ts
index 80afe58dd7..3394c575a2 100644
--- a/src/dialogs/quick-bar/ha-quick-bar.ts
+++ b/src/dialogs/quick-bar/ha-quick-bar.ts
@@ -99,6 +99,8 @@ export class QuickBar extends LitElement {
private _focusSet = false;
+ private _focusListElement?: ListItem | null;
+
public async showDialog(params: QuickBarParams) {
this._commandMode = params.commandMode || this._toggleIfAlreadyOpened();
this._initializeItemsIfNeeded();
@@ -317,7 +319,8 @@ export class QuickBar extends LitElement {
} else if (ev.code === "ArrowDown") {
ev.preventDefault();
this._getItemAtIndex(0)?.focus();
- this._getItemAtIndex(1)?.focus();
+ this._focusSet = true;
+ this._focusListElement = this._getItemAtIndex(0);
}
}
@@ -350,6 +353,11 @@ export class QuickBar extends LitElement {
this._initializeItemsIfNeeded();
this._filter = this._search;
} else {
+ if (this._focusSet && this._focusListElement) {
+ this._focusSet = false;
+ // @ts-ignore
+ this._focusListElement.rippleHandlers.endFocus();
+ }
this._debouncedSetFilter(this._search);
}
}
@@ -366,12 +374,14 @@ export class QuickBar extends LitElement {
private _setFocusFirstListItem() {
// @ts-ignore
this._getItemAtIndex(0)?.rippleHandlers.startFocus();
+ this._focusListElement = this._getItemAtIndex(0);
}
private _handleListItemKeyDown(ev: KeyboardEvent) {
const isSingleCharacter = ev.key.length === 1;
const isFirstListItem =
(ev.target as HTMLElement).getAttribute("index") === "0";
+ this._focusListElement = ev.target as ListItem;
if (ev.key === "ArrowUp") {
if (isFirstListItem) {
this._filterInputField?.focus();
@@ -511,7 +521,13 @@ export class QuickBar extends LitElement {
if (page.component) {
const info = this._getNavigationInfoFromConfig(page);
- if (info) {
+ // Add to list, but only if we do not already have an entry for the same path and component
+ if (
+ info &&
+ !items.some(
+ (e) => e.path === info.path && e.component === info.component
+ )
+ ) {
items.push(info);
}
}
From bfb84a834fc87cc3b092e4c37d1a8bd07f8e3ea7 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Sat, 11 Dec 2021 17:12:41 +0100
Subject: [PATCH 07/11] Still have manual input if camera is not supported
(#10849)
* Still have manual input if camera is not supported
* Adjust & fix
---
src/components/ha-qr-scanner.ts | 53 ++++++++++++++++---
.../zwave_js/dialog-zwave_js-add-node.ts | 12 +++--
src/translations/en.json | 10 +++-
3 files changed, 62 insertions(+), 13 deletions(-)
diff --git a/src/components/ha-qr-scanner.ts b/src/components/ha-qr-scanner.ts
index 7ef687cafe..4b4c3d859c 100644
--- a/src/components/ha-qr-scanner.ts
+++ b/src/components/ha-qr-scanner.ts
@@ -1,5 +1,7 @@
import "@material/mwc-list/mwc-list-item";
import "@material/mwc-select/mwc-select";
+import "@material/mwc-textfield/mwc-textfield";
+import type { TextField } from "@material/mwc-textfield/mwc-textfield";
import { mdiCamera } from "@mdi/js";
import { css, html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
@@ -9,6 +11,7 @@ import { stopPropagation } from "../common/dom/stop_propagation";
import { LocalizeFunc } from "../common/translations/localize";
import "./ha-alert";
import "./ha-button-menu";
+import "@material/mwc-button/mwc-button";
@customElement("ha-qr-scanner")
class HaQrScanner extends LitElement {
@@ -26,6 +29,8 @@ class HaQrScanner extends LitElement {
@query("#canvas-container", true) private _canvasContainer!: HTMLDivElement;
+ @query("mwc-textfield") private _manualInput?: TextField;
+
public disconnectedCallback(): void {
super.disconnectedCallback();
this._qrNotFoundCount = 0;
@@ -74,7 +79,7 @@ class HaQrScanner extends LitElement {
@@ -90,11 +95,22 @@ class HaQrScanner extends LitElement {
`
: ""}
`
- : html`${!window.isSecureContext
- ? "You can only use your camera to scan a QR core when using HTTPS."
- : "Your browser doesn't support QR scanning."}`}`;
+ : 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")}
+
`}`;
}
private async _loadQrScanner() {
@@ -143,6 +159,23 @@ class HaQrScanner extends LitElement {
fireEvent(this, "qr-code-scanned", { value: qrCodeString });
};
+ private _manualKeyup(ev: KeyboardEvent) {
+ if (ev.key === "Enter") {
+ this._qrCodeScanned((ev.target as TextField).value);
+ }
+ }
+
+ private _manualPaste(ev: ClipboardEvent) {
+ this._qrCodeScanned(
+ // @ts-ignore
+ (ev.clipboardData || window.clipboardData).getData("text")
+ );
+ }
+
+ private _manualSubmit() {
+ this._qrCodeScanned(this._manualInput!.value);
+ }
+
private _cameraChanged(ev: CustomEvent): void {
this._qrScanner?.setCamera((ev.target as any).value);
}
@@ -162,6 +195,14 @@ class HaQrScanner extends LitElement {
color: white;
border-radius: 50%;
}
+ .row {
+ display: flex;
+ align-items: center;
+ }
+ mwc-textfield {
+ flex: 1;
+ margin-right: 8px;
+ }
`;
}
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 cc4cdda74e..82a7ebda77 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
@@ -178,7 +178,10 @@ class DialogZWaveJSAddNode extends LitElement {
Search device
`
: this._status === "qr_scan"
- ? html`${this._error}`
+ : ""}
+
@@ -194,9 +197,9 @@ class DialogZWaveJSAddNode extends LitElement {
${
this._error
- ? html`${this._error}`
+ ? html`
+ ${this._error}
+ `
: ""
}
@@ -614,7 +617,6 @@ class DialogZWaveJSAddNode extends LitElement {
ZWaveFeature.SmartStart
)
).supported;
- this._supportsSmartStart = true;
}
private _startOver(_ev: Event) {
diff --git a/src/translations/en.json b/src/translations/en.json
index 96ebbaa632..eec89cb39c 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -291,6 +291,7 @@
"undo": "Undo",
"move": "Move",
"save": "Save",
+ "submit": "Submit",
"rename": "Rename",
"yes": "Yes",
"no": "No",
@@ -538,6 +539,13 @@
},
"attributes": {
"expansion_header": "Attributes"
+ },
+ "qr-scanner": {
+ "select_camera": "Select camera",
+ "only_https_supported": "You can only use your camera to scan a QR code when using HTTPS.",
+ "not_supported": "Your browser doesn't support QR scanning.",
+ "manual_input": "You can scan the QR code with another QR scanner and paste the code in the input below",
+ "enter_qr_code": "Enter QR code value"
}
},
"dialogs": {
@@ -2920,8 +2928,6 @@
"qr_code": "QR Code",
"qr_code_paragraph": "If your device supports SmartStart you can scan the QR code for easy pairing.",
"scan_qr_code": "Scan QR code",
- "enter_qr_code": "Enter QR code value",
- "select_camera": "Select camera",
"inclusion_failed": "The device could not be added.",
"check_logs": "Please check the logs for more information.",
"inclusion_finished": "The device has been added.",
From 2890192c054fdb48fe5d2181d73ef94900ee7fc7 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Sat, 11 Dec 2021 17:13:24 +0100
Subject: [PATCH 08/11] Fix formfield label touch (#10867)
---
src/components/ha-formfield.ts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/components/ha-formfield.ts b/src/components/ha-formfield.ts
index e0452e0db7..7ca076e7ea 100644
--- a/src/components/ha-formfield.ts
+++ b/src/components/ha-formfield.ts
@@ -1,10 +1,28 @@
import { Formfield } from "@material/mwc-formfield";
import { css, CSSResultGroup } from "lit";
import { customElement } from "lit/decorators";
+import { fireEvent } from "../common/dom/fire_event";
@customElement("ha-formfield")
// @ts-expect-error
export class HaFormfield extends Formfield {
+ protected _labelClick() {
+ const input = this.input;
+ if (input) {
+ input.focus();
+ switch (input.tagName) {
+ case "HA-CHECKBOX":
+ case "HA-RADIO":
+ (input as any).checked = !(input as any).checked;
+ fireEvent(input, "change");
+ break;
+ default:
+ input.click();
+ break;
+ }
+ }
+ }
+
protected static get styles(): CSSResultGroup {
return [
Formfield.styles,
From b730676914a33c3b848a3f89d979e011e04c0dbf Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Sat, 11 Dec 2021 17:13:43 +0100
Subject: [PATCH 09/11] Fix translations cover controls (#10868)
---
src/components/ha-cover-controls.ts | 6 +++---
src/components/ha-cover-tilt-controls.ts | 8 +++++---
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/components/ha-cover-controls.ts b/src/components/ha-cover-controls.ts
index 9f28b010d9..73a1acbc5d 100644
--- a/src/components/ha-cover-controls.ts
+++ b/src/components/ha-cover-controls.ts
@@ -35,7 +35,7 @@ class HaCoverControls extends LitElement {
hidden: !supportsOpen(this.stateObj),
})}
.label=${this.hass.localize(
- "ui.dialogs.more_info_control.open_cover"
+ "ui.dialogs.more_info_control.cover.open_cover"
)}
@click=${this._onOpenTap}
.disabled=${this._computeOpenDisabled()}
@@ -47,7 +47,7 @@ class HaCoverControls extends LitElement {
hidden: !supportsStop(this.stateObj),
})}
.label=${this.hass.localize(
- "ui.dialogs.more_info_control.stop_cover"
+ "ui.dialogs.more_info_control.cover.stop_cover"
)}
.path=${mdiStop}
@click=${this._onStopTap}
@@ -58,7 +58,7 @@ class HaCoverControls extends LitElement {
hidden: !supportsClose(this.stateObj),
})}
.label=${this.hass.localize(
- "ui.dialogs.more_info_control.close_cover"
+ "ui.dialogs.more_info_control.cover.close_cover"
)}
@click=${this._onCloseTap}
.disabled=${this._computeClosedDisabled()}
diff --git a/src/components/ha-cover-tilt-controls.ts b/src/components/ha-cover-tilt-controls.ts
index dac778f0ad..d0ce147f89 100644
--- a/src/components/ha-cover-tilt-controls.ts
+++ b/src/components/ha-cover-tilt-controls.ts
@@ -30,7 +30,7 @@ class HaCoverTiltControls extends LitElement {
invisible: !supportsOpenTilt(this.stateObj),
})}
.label=${this.hass.localize(
- "ui.dialogs.more_info_control.open_tilt_cover"
+ "ui.dialogs.more_info_control.cover.open_tilt_cover"
)}
.path=${mdiArrowTopRight}
@click=${this._onOpenTiltTap}
@@ -40,7 +40,9 @@ class HaCoverTiltControls extends LitElement {
class=${classMap({
invisible: !supportsStopTilt(this.stateObj),
})}
- .label=${this.hass.localize("ui.dialogs.more_info_control.stop_cover")}
+ .label=${this.hass.localize(
+ "ui.dialogs.more_info_control.cover.stop_cover"
+ )}
.path=${mdiStop}
@click=${this._onStopTiltTap}
.disabled=${this.stateObj.state === UNAVAILABLE}
@@ -50,7 +52,7 @@ class HaCoverTiltControls extends LitElement {
invisible: !supportsCloseTilt(this.stateObj),
})}
.label=${this.hass.localize(
- "ui.dialogs.more_info_control.close_tilt_cover"
+ "ui.dialogs.more_info_control.cover.close_tilt_cover"
)}
.path=${mdiArrowBottomLeft}
@click=${this._onCloseTiltTap}
From 35e9687170876ddf4103c422a0099dc980566585 Mon Sep 17 00:00:00 2001
From: Philip Allgaier
Date: Sat, 11 Dec 2021 17:15:16 +0100
Subject: [PATCH 10/11] Replace `mwc-icon-button` with `ha-icon-button` in
automation picker (#10858)
---
src/components/ha-button-related-filter-menu.ts | 1 +
src/components/ha-icon-overflow-menu.ts | 12 +++++-------
src/translations/en.json | 2 ++
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/components/ha-button-related-filter-menu.ts b/src/components/ha-button-related-filter-menu.ts
index afbfff1966..fb65469e12 100644
--- a/src/components/ha-button-related-filter-menu.ts
+++ b/src/components/ha-button-related-filter-menu.ts
@@ -56,6 +56,7 @@ export class HaRelatedFilterButtonMenu extends LitElement {
return html`
+ ? html`
`
: html`
-
-
+
${this.items.map((item) =>
item.narrowOnly
? ""
@@ -70,13 +69,12 @@ export class HaIconOverflowMenu extends LitElement {
${item.tooltip}
`
: ""}
-
-
-
+ >
`
)}
`}
diff --git a/src/translations/en.json b/src/translations/en.json
index eec89cb39c..e423ddcf10 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -298,6 +298,7 @@
"not_now": "Not now",
"skip": "Skip",
"menu": "Menu",
+ "overflow_menu": "Overflow menu",
"help": "Help",
"successfully_saved": "Successfully saved",
"successfully_deleted": "Successfully deleted",
@@ -422,6 +423,7 @@
}
},
"related-filter-menu": {
+ "filter": "Filter",
"filter_by_entity": "Filter by entity",
"filter_by_device": "Filter by device",
"filter_by_area": "Filter by area",
From 2b0359edba777581e16112c11cf7c5a94dfe0b79 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Sat, 11 Dec 2021 17:15:38 +0100
Subject: [PATCH 11/11] Bumped version to 20211211.0
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index 75612bd2c5..ddadce10c4 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
- version="20211209.0",
+ version="20211211.0",
description="The Home Assistant frontend",
url="https://github.com/home-assistant/frontend",
author="The Home Assistant Authors",