${data.map(
(trace, idx) => html`
- ${idx > 0
+ ${data.length > 1
? html`
${this.hass!.localize(
"ui.panel.config.automation.trace.path.iteration",
From 3c2fed504123cad2df38976d3b341f1e0b68ab89 Mon Sep 17 00:00:00 2001
From: Erik Montnemery
Date: Sat, 30 Dec 2023 18:08:24 +0100
Subject: [PATCH 007/361] Improve message when an automation step was not
executed (#19185)
* Improve message when an automation step was not executed
* Use step instead of node
---
src/components/trace/ha-trace-path-details.ts | 4 ++--
src/translations/en.json | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/components/trace/ha-trace-path-details.ts b/src/components/trace/ha-trace-path-details.ts
index bd827283728b..33a73af3ed45 100644
--- a/src/components/trace/ha-trace-path-details.ts
+++ b/src/components/trace/ha-trace-path-details.ts
@@ -133,7 +133,7 @@ export class HaTracePathDetails extends LitElement {
if (result?.enabled === false) {
return html`${this.hass!.localize(
- "ui.panel.config.automation.trace.path.disabled_node"
+ "ui.panel.config.automation.trace.path.disabled_step"
)}`;
}
@@ -240,7 +240,7 @@ export class HaTracePathDetails extends LitElement {
if (index === -1) {
return html`
${this.hass!.localize(
- "ui.panel.config.automation.trace.path.node_not_tracked"
+ "ui.panel.config.automation.trace.path.step_not_executed"
)}
`;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 76eab13fdbe3..b78aebb34507 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -3114,15 +3114,15 @@
"blueprint_config": "Blueprint Config"
},
"path": {
- "choose": "Select a node on the left for more information.",
+ "choose": "Select a step on the left for more information.",
"default_action_executed": "The default action was executed because no options matched.",
- "no_further_execution": "This node was not executed and so no further trace information is available.",
- "disabled_node": "This node was disabled and skipped during execution so no further trace information is available.",
+ "no_further_execution": "This step was not executed and so no further trace information is available.",
+ "disabled_step": "This step was disabled and skipped during execution so no further trace information is available.",
"iteration": "Iteration {number}",
"executed": "Executed: {time}",
"error": "Error: {error}",
"result": "Result:",
- "node_not_tracked": "Node not tracked.",
+ "step_not_executed": "This step was not executed.",
"no_logbook_entries": "No Logbook entries found for this step.",
"no_variables_changed": "No variables changed",
"unable_to_find_config": "Unable to find config"
From c584f830719b0d081f3672bb75200d4cee2cdeba Mon Sep 17 00:00:00 2001
From: Erik Montnemery
Date: Sat, 30 Dec 2023 18:16:54 +0100
Subject: [PATCH 008/361] Fix display of variables tab when automation step not
executed (#19186)
Co-authored-by: Bram Kragten
---
src/components/trace/ha-trace-path-details.ts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/components/trace/ha-trace-path-details.ts b/src/components/trace/ha-trace-path-details.ts
index 33a73af3ed45..514377e61f4f 100644
--- a/src/components/trace/ha-trace-path-details.ts
+++ b/src/components/trace/ha-trace-path-details.ts
@@ -208,6 +208,14 @@ export class HaTracePathDetails extends LitElement {
const paths = this.trace.trace;
const data: ActionTraceStep[] = paths[this.selected.path];
+ if (data === undefined) {
+ return html`
+ ${this.hass!.localize(
+ "ui.panel.config.automation.trace.path.step_not_executed"
+ )}
+
`;
+ }
+
return html`
${data.map(
From 721ec8e559c5c35d4d78470367dc4afb86e110aa Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Sat, 30 Dec 2023 09:37:50 -0800
Subject: [PATCH 009/361] Localize some strings in integration panel (#19200)
---
.../config/integrations/dialog-add-integration.ts | 10 +++++++---
src/translations/en.json | 3 +++
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/panels/config/integrations/dialog-add-integration.ts b/src/panels/config/integrations/dialog-add-integration.ts
index 757f23160276..65edfbfccf67 100644
--- a/src/panels/config/integrations/dialog-add-integration.ts
+++ b/src/panels/config/integrations/dialog-add-integration.ts
@@ -340,7 +340,9 @@ class AddIntegrationDialog extends LitElement {
!("integrations" in integration) &&
!this._flowsInProgress?.length
) {
- return "What type of device is it?";
+ return this.hass.localize(
+ "ui.panel.config.integrations.what_device_type"
+ );
}
if (
integration &&
@@ -348,9 +350,11 @@ class AddIntegrationDialog extends LitElement {
!("integrations" in integration) &&
this._flowsInProgress?.length
) {
- return "Want to add these discovered devices?";
+ return this.hass.localize(
+ "ui.panel.config.integrations.confirm_add_discovered"
+ );
}
- return "What do you want to add?";
+ return this.hass.localize("ui.panel.config.integrations.what_to_add");
}
private _renderIntegration(
diff --git a/src/translations/en.json b/src/translations/en.json
index b78aebb34507..be18b476ad29 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -3799,6 +3799,9 @@
"add_zwave_js_device": "Add Z-Wave device",
"add_zha_device": "Add Zigbee device",
"add_matter_device": "Add Matter device",
+ "what_device_type": "What type of device is it?",
+ "what_to_add": "What do you want to add?",
+ "confirm_add_discovered": "Want to add these discovered devices?",
"disable": {
"show_disabled": "Show disabled integrations",
"disabled_integrations": "{number} disabled",
From ee57f26415d087bbffbb61321335d1778df262d8 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Sat, 30 Dec 2023 18:39:21 +0100
Subject: [PATCH 010/361] Sort domains correctly, scroll to top on back
(#19197)
---
.../add-automation-element-dialog.ts | 49 +++++++++----------
1 file changed, 24 insertions(+), 25 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index f05d9ef3fe3c..b96283a61dd8 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -254,31 +254,29 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
return [];
}
const result: ListItem[] = [];
- Object.keys(services)
- .sort()
- .forEach((domain) => {
- const manifest = manifests[domain];
- if (
- (type === undefined &&
- manifest?.integration_type === "entity" &&
- !ENTITY_DOMAINS_OTHER.has(domain)) ||
- (type === "helper" && manifest?.integration_type === "helper") ||
- (type === "other" &&
- (ENTITY_DOMAINS_OTHER.has(domain) ||
- !["helper", "entity"].includes(
- manifest?.integration_type || ""
- )))
- ) {
- result.push({
- group: true,
- icon: domainIcon(domain),
- key: `${SERVICE_PREFIX}${domain}`,
- name: domainToName(localize, domain, manifest),
- description: "",
- });
- }
- });
- return result;
+ Object.keys(services).forEach((domain) => {
+ const manifest = manifests[domain];
+ if (
+ (type === undefined &&
+ manifest?.integration_type === "entity" &&
+ !ENTITY_DOMAINS_OTHER.has(domain)) ||
+ (type === "helper" && manifest?.integration_type === "helper") ||
+ (type === "other" &&
+ (ENTITY_DOMAINS_OTHER.has(domain) ||
+ !["helper", "entity"].includes(manifest?.integration_type || "")))
+ ) {
+ result.push({
+ group: true,
+ icon: domainIcon(domain),
+ key: `${SERVICE_PREFIX}${domain}`,
+ name: domainToName(localize, domain, manifest),
+ description: "",
+ });
+ }
+ });
+ return result.sort((a, b) =>
+ stringCompare(a.name, b.name, this.hass.locale.language)
+ );
}
);
@@ -515,6 +513,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
}
private _back() {
+ this._dialog!.scrollToPos(0, 0);
if (this._filter) {
this._filter = "";
return;
From fe18f70e51c76b7da0a67d6ffd2696eb9f408e0c Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Sat, 30 Dec 2023 18:40:01 +0100
Subject: [PATCH 011/361] Only make count field template (#19198)
---
.../types/ha-automation-action-repeat.ts | 34 ++++++++-----------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/src/panels/config/automation/action/types/ha-automation-action-repeat.ts b/src/panels/config/automation/action/types/ha-automation-action-repeat.ts
index becc0f6f75b0..7a1ad36e8156 100644
--- a/src/panels/config/automation/action/types/ha-automation-action-repeat.ts
+++ b/src/panels/config/automation/action/types/ha-automation-action-repeat.ts
@@ -1,4 +1,4 @@
-import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
+import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event";
@@ -9,10 +9,10 @@ import type { HomeAssistant } from "../../../../../types";
import "../ha-automation-action";
import type { ActionElement } from "../ha-automation-action-row";
+import { isTemplate } from "../../../../../common/string/has-template";
import type { LocalizeFunc } from "../../../../../common/translations/localize";
import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types";
-import { hasTemplate } from "../../../../../common/string/has-template";
const OPTIONS = ["count", "while", "until", "for_each"] as const;
@@ -32,22 +32,13 @@ export class HaRepeatAction extends LitElement implements ActionElement {
return { repeat: { count: 2, sequence: [] } };
}
- public willUpdate(changedProperties: PropertyValues) {
- if (!changedProperties.has("action")) {
- return;
- }
- // Check for templates in action. If found, revert to YAML mode.
- if (this.action && hasTemplate(this.action)) {
- fireEvent(
- this,
- "ui-mode-not-available",
- Error(this.hass.localize("ui.errors.config.no_template_editor_support"))
- );
- }
- }
-
private _schema = memoizeOne(
- (localize: LocalizeFunc, type: string, reOrderMode: boolean) =>
+ (
+ localize: LocalizeFunc,
+ type: string,
+ reOrderMode: boolean,
+ template: boolean
+ ) =>
[
{
name: "type",
@@ -68,7 +59,9 @@ export class HaRepeatAction extends LitElement implements ActionElement {
{
name: "count",
required: true,
- selector: { number: { mode: "box", min: 1 } },
+ selector: template
+ ? ({ template: {} } as const)
+ : ({ number: { mode: "box", min: 1 } } as const),
},
] as const)
: []),
@@ -104,7 +97,10 @@ export class HaRepeatAction extends LitElement implements ActionElement {
const schema = this._schema(
this.hass.localize,
type ?? "count",
- this.reOrderMode
+ this.reOrderMode,
+ "count" in action && typeof action.count === "string"
+ ? isTemplate(action.count)
+ : false
);
const data = { ...action, type };
return html`
Date: Sat, 30 Dec 2023 20:21:33 +0100
Subject: [PATCH 012/361] Allow to clear due date (#19201)
---
src/components/ha-date-input.ts | 18 ++++++++++++++++--
src/components/ha-dialog-date-picker.ts | 14 ++++++++++++++
src/data/todo.ts | 8 ++++----
src/panels/todo/dialog-todo-item-editor.ts | 17 +++++++++++------
src/translations/en.json | 3 ++-
5 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/src/components/ha-date-input.ts b/src/components/ha-date-input.ts
index d3b5a0607eb3..d4d9922639d9 100644
--- a/src/components/ha-date-input.ts
+++ b/src/components/ha-date-input.ts
@@ -18,7 +18,8 @@ export interface datePickerDialogParams {
max?: string;
locale?: string;
firstWeekday?: number;
- onChange: (value: string) => void;
+ canClear?: boolean;
+ onChange: (value: string | undefined) => void;
}
const showDatePickerDialog = (
@@ -49,6 +50,8 @@ export class HaDateInput extends LitElement {
@property() public helper?: string;
+ @property({ type: Boolean }) public canClear?: boolean;
+
render() {
return html` this._valueChanged(value),
locale: this.locale.language,
firstWeekday: firstWeekdayIndex(this.locale),
});
}
- private _valueChanged(value: string) {
+ private _keyDown(ev: KeyboardEvent) {
+ if (!this.canClear) {
+ return;
+ }
+ if (["Backspace", "Delete"].includes(ev.key)) {
+ this._valueChanged(undefined);
+ }
+ }
+
+ private _valueChanged(value: string | undefined) {
if (this.value !== value) {
this.value = value;
fireEvent(this, "change");
diff --git a/src/components/ha-dialog-date-picker.ts b/src/components/ha-dialog-date-picker.ts
index 2422754cfb15..b71e063ae410 100644
--- a/src/components/ha-dialog-date-picker.ts
+++ b/src/components/ha-dialog-date-picker.ts
@@ -50,6 +50,15 @@ export class HaDialogDatePicker extends LitElement {
@datepicker-value-updated=${this._valueChanged}
.firstDayOfWeek=${this._params.firstWeekday}
>
+ ${this._params.canClear
+ ? html`
+ ${this.hass.localize("ui.dialogs.date-picker.clear")}
+ `
+ : nothing}
${this.hass.localize("ui.dialogs.date-picker.today")}
@@ -66,6 +75,11 @@ export class HaDialogDatePicker extends LitElement {
this._value = ev.detail.value;
}
+ private _clear() {
+ this._params?.onChange(undefined);
+ this.closeDialog();
+ }
+
private _setToday() {
const today = new Date();
this._value = format(today, "yyyy-MM-dd");
diff --git a/src/data/todo.ts b/src/data/todo.ts
index e4f99090776b..9af8ef0f4cc6 100644
--- a/src/data/todo.ts
+++ b/src/data/todo.ts
@@ -18,8 +18,8 @@ export interface TodoItem {
uid: string;
summary: string;
status: TodoItemStatus;
- description?: string;
- due?: string;
+ description?: string | null;
+ due?: string | null;
}
export const enum TodoListEntityFeature {
@@ -83,9 +83,9 @@ export const updateItem = (
item: item.uid,
rename: item.summary,
status: item.status,
- description: item.description || undefined,
+ description: item.description || null,
due_datetime: item.due?.includes("T") ? item.due : undefined,
- due_date: item.due?.includes("T") ? undefined : item.due || undefined,
+ due_date: item.due?.includes("T") ? undefined : item.due || null,
},
{ entity_id }
);
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index 5206bfe8a877..c81b9e4dbec3 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -161,7 +161,8 @@ class DialogTodoItemEditor extends LitElement {
.value=${dueDate}
.locale=${this.hass.locale}
.disabled=${!canUpdate}
- @value-changed=${this._endDateChanged}
+ @value-changed=${this._dueDateChanged}
+ canClear
>
${this._todoListSupportsFeature(
TodoListEntityFeature.SET_DUE_DATETIME_ON_ITEM
@@ -170,7 +171,7 @@ class DialogTodoItemEditor extends LitElement {
.value=${dueTime}
.locale=${this.hass.locale}
.disabled=${!canUpdate}
- @value-changed=${this._endTimeChanged}
+ @value-changed=${this._dueTimeChanged}
>`
: nothing}
@@ -259,12 +260,16 @@ class DialogTodoItemEditor extends LitElement {
this._description = ev.target.value;
}
- private _endDateChanged(ev: CustomEvent) {
+ private _dueDateChanged(ev: CustomEvent) {
+ if (!ev.detail.value) {
+ this._due = undefined;
+ return;
+ }
const time = this._due ? this._formatTime(this._due) : undefined;
this._due = this._parseDate(`${ev.detail.value}${time ? `T${time}` : ""}`);
}
- private _endTimeChanged(ev: CustomEvent) {
+ private _dueTimeChanged(ev: CustomEvent) {
this._hasTime = true;
this._due = this._parseDate(
`${this._formatDate(this._due || new Date())}T${ev.detail.value}`
@@ -320,13 +325,13 @@ class DialogTodoItemEditor extends LitElement {
TodoListEntityFeature.SET_DESCRIPTION_ON_ITEM
)
? // backend should accept null to clear the field, but it doesn't now
- " "
+ null
: undefined),
due: this._due
? this._hasTime
? this._due.toISOString()
: this._formatDate(this._due)
- : undefined,
+ : null,
status: this._checked
? TodoItemStatus.Completed
: TodoItemStatus.NeedsAction,
diff --git a/src/translations/en.json b/src/translations/en.json
index be18b476ad29..0039d9926f56 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -1009,7 +1009,8 @@
"crop_image": "Picture to crop"
},
"date-picker": {
- "today": "Today"
+ "today": "Today",
+ "clear": "Clear"
},
"more_info_control": {
"dismiss": "Dismiss dialog",
From e7cc842be46a734f44bbeb560449adefc3a709f7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 30 Dec 2023 21:05:23 -0500
Subject: [PATCH 013/361] Update dependency rollup-plugin-visualizer to v5.12.0
(#19204)
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 339896248684..232e4b0beaf5 100644
--- a/package.json
+++ b/package.json
@@ -229,7 +229,7 @@
"rollup": "2.79.1",
"rollup-plugin-string": "3.0.0",
"rollup-plugin-terser": "7.0.2",
- "rollup-plugin-visualizer": "5.11.0",
+ "rollup-plugin-visualizer": "5.12.0",
"serve-handler": "6.1.5",
"sinon": "17.0.1",
"source-map-url": "0.4.1",
diff --git a/yarn.lock b/yarn.lock
index e3f41249e572..08117eab574a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9701,7 +9701,7 @@ __metadata:
rollup: "npm:2.79.1"
rollup-plugin-string: "npm:3.0.0"
rollup-plugin-terser: "npm:7.0.2"
- rollup-plugin-visualizer: "npm:5.11.0"
+ rollup-plugin-visualizer: "npm:5.12.0"
rrule: "npm:2.8.1"
serve-handler: "npm:6.1.5"
sinon: "npm:17.0.1"
@@ -13846,9 +13846,9 @@ __metadata:
languageName: node
linkType: hard
-"rollup-plugin-visualizer@npm:5.11.0":
- version: 5.11.0
- resolution: "rollup-plugin-visualizer@npm:5.11.0"
+"rollup-plugin-visualizer@npm:5.12.0":
+ version: 5.12.0
+ resolution: "rollup-plugin-visualizer@npm:5.12.0"
dependencies:
open: "npm:^8.4.0"
picomatch: "npm:^2.3.1"
@@ -13861,7 +13861,7 @@ __metadata:
optional: true
bin:
rollup-plugin-visualizer: dist/bin/cli.js
- checksum: 947238aa22706a47a4d3e8ce616855f0e5cb969ed9f61b9a268eaede0a86f461ecb38e27b4e6bf00f4b5e3f63677667f65e0d4af89a659a5160f74add1f192bb
+ checksum: 47358feb672291d6edcfd94197577c192a84c24cb644119425dae8241fb6f5a52556efd0c501f38b276c07534642a80c0885ef681babb474e83c7b5a3b475b84
languageName: node
linkType: hard
From bf5c5bc46fa79f6f20127dab55a26bef19b34e97 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 30 Dec 2023 21:06:30 -0500
Subject: [PATCH 014/361] Update dependency open to v10.0.2 (#19206)
---
package.json | 2 +-
yarn.lock | 20 ++++++++++----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/package.json b/package.json
index 232e4b0beaf5..be8b0f961a1c 100644
--- a/package.json
+++ b/package.json
@@ -223,7 +223,7 @@
"map-stream": "0.0.7",
"mocha": "10.2.0",
"object-hash": "3.0.0",
- "open": "10.0.1",
+ "open": "10.0.2",
"pinst": "3.0.0",
"prettier": "3.1.1",
"rollup": "2.79.1",
diff --git a/yarn.lock b/yarn.lock
index 08117eab574a..812ddda50de9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7228,13 +7228,13 @@ __metadata:
languageName: node
linkType: hard
-"default-browser@npm:^5.2.0":
- version: 5.2.0
- resolution: "default-browser@npm:5.2.0"
+"default-browser@npm:^5.2.1":
+ version: 5.2.1
+ resolution: "default-browser@npm:5.2.1"
dependencies:
bundle-name: "npm:^4.1.0"
default-browser-id: "npm:^5.0.0"
- checksum: 95530de0dca75892b4382d086f42bd798f54a1e25eab748e84e1b64566568b1a02cf1eccfb60a8fbab303d72c09938c2d34e0b38e57d85efd24f13a60d2de802
+ checksum: afab7eff7b7f5f7a94d9114d1ec67273d3fbc539edf8c0f80019879d53aa71e867303c6f6d7cffeb10a6f3cfb59d4f963dba3f9c96830b4540cc7339a1bf9840
languageName: node
linkType: hard
@@ -9690,7 +9690,7 @@ __metadata:
mocha: "npm:10.2.0"
node-vibrant: "npm:3.2.1-alpha.1"
object-hash: "npm:3.0.0"
- open: "npm:10.0.1"
+ open: "npm:10.0.2"
pinst: "npm:3.0.0"
prettier: "npm:3.1.1"
proxy-polyfill: "npm:0.3.2"
@@ -12530,15 +12530,15 @@ __metadata:
languageName: node
linkType: hard
-"open@npm:10.0.1":
- version: 10.0.1
- resolution: "open@npm:10.0.1"
+"open@npm:10.0.2":
+ version: 10.0.2
+ resolution: "open@npm:10.0.2"
dependencies:
- default-browser: "npm:^5.2.0"
+ default-browser: "npm:^5.2.1"
define-lazy-prop: "npm:^3.0.0"
is-inside-container: "npm:^1.0.0"
is-wsl: "npm:^3.1.0"
- checksum: 7ce545e2e68775f06ab800c2a2ef20369bce2738e1219fd31179e1a1773f2c33fcc6b7f816a4f5e9214821cb58ae9c50f2e3f7dd8f5b02e418fbcafabf481f03
+ checksum: 6f7f9e08204af00930f2998690293df1a919a61c98b225ff9e3aa09a765254b8a98bec101644ffe991452c6aabea0c6f9e49670b559d48a44bfc5238f6b58351
languageName: node
linkType: hard
From b92d25e28af9159c82cff6ad9532bddf55f5a503 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 30 Dec 2023 21:08:13 -0500
Subject: [PATCH 015/361] Update Material Design Icons to v7.4.47 (#19192)
---
package.json | 4 ++--
yarn.lock | 20 ++++++++++----------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/package.json b/package.json
index be8b0f961a1c..a66ec2870b52 100644
--- a/package.json
+++ b/package.json
@@ -81,8 +81,8 @@
"@material/mwc-top-app-bar-fixed": "0.27.0",
"@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0",
"@material/web": "=1.1.1",
- "@mdi/js": "7.3.67",
- "@mdi/svg": "7.3.67",
+ "@mdi/js": "7.4.47",
+ "@mdi/svg": "7.4.47",
"@polymer/paper-input": "3.2.1",
"@polymer/paper-item": "3.0.1",
"@polymer/paper-listbox": "3.0.1",
diff --git a/yarn.lock b/yarn.lock
index 812ddda50de9..313883fac92f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3146,17 +3146,17 @@ __metadata:
languageName: node
linkType: hard
-"@mdi/js@npm:7.3.67":
- version: 7.3.67
- resolution: "@mdi/js@npm:7.3.67"
- checksum: 0f54a632d4ab3213931cc348d524f0f5e6b492ea74f8f1babe00298a8e7ae07b2fec88cfaf0cf7be0f1e427026a8da23fb8bed55b22892ad3b40b482e01cfb17
+"@mdi/js@npm:7.4.47":
+ version: 7.4.47
+ resolution: "@mdi/js@npm:7.4.47"
+ checksum: c1a8fc82f23030bccc0cf324b13b73a0034d06140e79f8bc7b0e4e59275624c470e5ca6524d6141ad8c4fe3ad0f314c7af99afb3e38df163eb50d3b13b9eab17
languageName: node
linkType: hard
-"@mdi/svg@npm:7.3.67":
- version: 7.3.67
- resolution: "@mdi/svg@npm:7.3.67"
- checksum: bd9593e6cc16d140b681dedacd2a164da7884186d496c89809a9389c980c295d16edf4ba8744338d28bb6e627b1801f47c4c0cbf7b8faf7084ee87cd5d7b4250
+"@mdi/svg@npm:7.4.47":
+ version: 7.4.47
+ resolution: "@mdi/svg@npm:7.4.47"
+ checksum: e5a6b80bb82cc7b7c98e9a018883aee1eaa0e98edfb62192e7ec5798fa573f30b9226629361d747de6e0a81fe6657fb37e9bc2fd89c68e9b094a07e863be4fba
languageName: node
linkType: hard
@@ -9585,8 +9585,8 @@ __metadata:
"@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.1.1"
- "@mdi/js": "npm:7.3.67"
- "@mdi/svg": "npm:7.3.67"
+ "@mdi/js": "npm:7.4.47"
+ "@mdi/svg": "npm:7.4.47"
"@octokit/auth-oauth-device": "npm:6.0.1"
"@octokit/plugin-retry": "npm:6.0.1"
"@octokit/rest": "npm:20.0.2"
From d25f49b694265d4b5db3f060a041e59c369ede9e Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sun, 31 Dec 2023 13:46:23 -0500
Subject: [PATCH 016/361] Update dependency chai to v5 (#19208)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
package.json | 2 +-
yarn.lock | 70 ++++++++++++++++++++++++----------------------------
2 files changed, 33 insertions(+), 39 deletions(-)
diff --git a/package.json b/package.json
index a66ec2870b52..3288ca8cd62f 100644
--- a/package.json
+++ b/package.json
@@ -190,7 +190,7 @@
"@web/dev-server-rollup": "0.4.1",
"babel-loader": "9.1.3",
"babel-plugin-template-html-minifier": "4.1.0",
- "chai": "4.3.10",
+ "chai": "5.0.0",
"del": "7.1.0",
"eslint": "8.56.0",
"eslint-config-airbnb-base": "15.0.0",
diff --git a/yarn.lock b/yarn.lock
index 313883fac92f..d2f7e2f24c12 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5895,10 +5895,10 @@ __metadata:
languageName: node
linkType: hard
-"assertion-error@npm:^1.1.0":
- version: 1.1.0
- resolution: "assertion-error@npm:1.1.0"
- checksum: fd9429d3a3d4fd61782eb3962ae76b6d08aa7383123fca0596020013b3ebd6647891a85b05ce821c47d1471ed1271f00b0545cf6a4326cf2fc91efcc3b0fbecf
+"assertion-error@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "assertion-error@npm:2.0.1"
+ checksum: a0789dd882211b87116e81e2648ccb7f60340b34f19877dd020b39ebb4714e475eb943e14ba3e22201c221ef6645b7bfe10297e76b6ac95b48a9898c1211ce66
languageName: node
linkType: hard
@@ -6434,18 +6434,16 @@ __metadata:
languageName: node
linkType: hard
-"chai@npm:4.3.10":
- version: 4.3.10
- resolution: "chai@npm:4.3.10"
+"chai@npm:5.0.0":
+ version: 5.0.0
+ resolution: "chai@npm:5.0.0"
dependencies:
- assertion-error: "npm:^1.1.0"
- check-error: "npm:^1.0.3"
- deep-eql: "npm:^4.1.3"
- get-func-name: "npm:^2.0.2"
- loupe: "npm:^2.3.6"
- pathval: "npm:^1.1.1"
- type-detect: "npm:^4.0.8"
- checksum: 9e545fd60f5efee4f06f7ad62f7b1b142932b08fbb3454db69defd511e7c58771ce51843764212da1e129b2c9d1b029fbf5f98da030fe67a95a0853e8679524f
+ assertion-error: "npm:^2.0.1"
+ check-error: "npm:^2.0.0"
+ deep-eql: "npm:^5.0.1"
+ loupe: "npm:^3.0.0"
+ pathval: "npm:^2.0.0"
+ checksum: c23d1bb3912cc36d12861d7e4010bb992aabf923a8d393bc71e776218c39f5f40778ab9f398ff962dd26857edee07ce732c9ad28a678feb1b76f99384d2e4a90
languageName: node
linkType: hard
@@ -6495,12 +6493,10 @@ __metadata:
languageName: node
linkType: hard
-"check-error@npm:^1.0.3":
- version: 1.0.3
- resolution: "check-error@npm:1.0.3"
- dependencies:
- get-func-name: "npm:^2.0.2"
- checksum: e2131025cf059b21080f4813e55b3c480419256914601750b0fee3bd9b2b8315b531e551ef12560419b8b6d92a3636511322752b1ce905703239e7cc451b6399
+"check-error@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "check-error@npm:2.0.0"
+ checksum: 120f252c2e1ad82ef82a616662805345c6c361347bfd6203f8a28c53a158811dd0ea21278f29c8136cc9df12fc7f077d1a07124569d98fb396b3072d08f2f092
languageName: node
linkType: hard
@@ -7184,12 +7180,10 @@ __metadata:
languageName: node
linkType: hard
-"deep-eql@npm:^4.1.3":
- version: 4.1.3
- resolution: "deep-eql@npm:4.1.3"
- dependencies:
- type-detect: "npm:^4.0.0"
- checksum: 12ce93ae63de187e77b076d3d51bfc28b11f98910a22c18714cce112791195e86a94f97788180994614b14562a86c9763f67c69f785e4586f806b5df39bf9301
+"deep-eql@npm:^5.0.1":
+ version: 5.0.1
+ resolution: "deep-eql@npm:5.0.1"
+ checksum: f8846820213462cdca23700873810c8bc01263dcc6a1e0f8694964b64f48a6dcb1f323ef7bb8678b15553f4b82420eda19092d4ae2e2709c56af7ea77bd8e6ab
languageName: node
linkType: hard
@@ -8966,7 +8960,7 @@ __metadata:
languageName: node
linkType: hard
-"get-func-name@npm:^2.0.1, get-func-name@npm:^2.0.2":
+"get-func-name@npm:^2.0.1":
version: 2.0.2
resolution: "get-func-name@npm:2.0.2"
checksum: 3f62f4c23647de9d46e6f76d2b3eafe58933a9b3830c60669e4180d6c601ce1b4aa310ba8366143f55e52b139f992087a9f0647274e8745621fa2af7e0acf13b
@@ -9634,7 +9628,7 @@ __metadata:
app-datepicker: "npm:5.1.1"
babel-loader: "npm:9.1.3"
babel-plugin-template-html-minifier: "npm:4.1.0"
- chai: "npm:4.3.10"
+ chai: "npm:5.0.0"
chart.js: "npm:4.4.1"
comlink: "npm:4.4.1"
core-js: "npm:3.34.0"
@@ -11533,12 +11527,12 @@ __metadata:
languageName: node
linkType: hard
-"loupe@npm:^2.3.6":
- version: 2.3.7
- resolution: "loupe@npm:2.3.7"
+"loupe@npm:^3.0.0":
+ version: 3.0.2
+ resolution: "loupe@npm:3.0.2"
dependencies:
get-func-name: "npm:^2.0.1"
- checksum: 635c8f0914c2ce7ecfe4e239fbaf0ce1d2c00e4246fafcc4ed000bfdb1b8f89d05db1a220054175cca631ebf3894872a26fffba0124477fcb562f78762848fb1
+ checksum: 256467bf10afaca4a5dd79b32e36fcd042bc2a247232e940c62bcc07cb114c2d7a549218eb103598e7cdb8bd32c6601fe230d80e03b8d49782973d4da11c08ed
languageName: node
linkType: hard
@@ -12960,10 +12954,10 @@ __metadata:
languageName: node
linkType: hard
-"pathval@npm:^1.1.1":
- version: 1.1.1
- resolution: "pathval@npm:1.1.1"
- checksum: b50a4751068aa3a5428f5a0b480deecedc6f537666a3630a0c2ae2d5e7c0f4bf0ee77b48404441ec1220bef0c91625e6030b3d3cf5a32ab0d9764018d1d9dbb6
+"pathval@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "pathval@npm:2.0.0"
+ checksum: b91575bf9cdf01757afd7b5e521eb8a0b874a49bc972d08e0047cfea0cd3c019f5614521d4bc83d2855e3fcc331db6817dfd533dd8f3d90b16bc76fad2450fc1
languageName: node
linkType: hard
@@ -15406,7 +15400,7 @@ __metadata:
languageName: node
linkType: hard
-"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.8":
+"type-detect@npm:4.0.8, type-detect@npm:^4.0.8":
version: 4.0.8
resolution: "type-detect@npm:4.0.8"
checksum: 5179e3b8ebc51fce1b13efb75fdea4595484433f9683bbc2dca6d99789dba4e602ab7922d2656f2ce8383987467f7770131d4a7f06a26287db0615d2f4c4ce7d
From 6cc9a99b770c98220d08d9da7dab4008bf6d5c20 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sun, 31 Dec 2023 13:47:55 -0500
Subject: [PATCH 017/361] Update dependency terser-webpack-plugin to v5.3.10
(#19211)
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 3288ca8cd62f..3f4e61c24329 100644
--- a/package.json
+++ b/package.json
@@ -235,7 +235,7 @@
"source-map-url": "0.4.1",
"systemjs": "6.14.2",
"tar": "6.2.0",
- "terser-webpack-plugin": "5.3.9",
+ "terser-webpack-plugin": "5.3.10",
"ts-lit-plugin": "2.0.1",
"typescript": "5.3.3",
"vinyl-buffer": "1.0.1",
diff --git a/yarn.lock b/yarn.lock
index d2f7e2f24c12..510c103b2e84 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2043,7 +2043,7 @@ __metadata:
languageName: node
linkType: hard
-"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9":
+"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.20, @jridgewell/trace-mapping@npm:^0.3.9":
version: 0.3.20
resolution: "@jridgewell/trace-mapping@npm:0.3.20"
dependencies:
@@ -9705,7 +9705,7 @@ __metadata:
superstruct: "npm:1.0.3"
systemjs: "npm:6.14.2"
tar: "npm:6.2.0"
- terser-webpack-plugin: "npm:5.3.9"
+ terser-webpack-plugin: "npm:5.3.10"
tinykeys: "npm:2.1.0"
ts-lit-plugin: "npm:2.0.1"
tsparticles-engine: "npm:2.12.0"
@@ -15005,15 +15005,15 @@ __metadata:
languageName: node
linkType: hard
-"terser-webpack-plugin@npm:5.3.9, terser-webpack-plugin@npm:^5.3.7":
- version: 5.3.9
- resolution: "terser-webpack-plugin@npm:5.3.9"
+"terser-webpack-plugin@npm:5.3.10, terser-webpack-plugin@npm:^5.3.7":
+ version: 5.3.10
+ resolution: "terser-webpack-plugin@npm:5.3.10"
dependencies:
- "@jridgewell/trace-mapping": "npm:^0.3.17"
+ "@jridgewell/trace-mapping": "npm:^0.3.20"
jest-worker: "npm:^27.4.5"
schema-utils: "npm:^3.1.1"
serialize-javascript: "npm:^6.0.1"
- terser: "npm:^5.16.8"
+ terser: "npm:^5.26.0"
peerDependencies:
webpack: ^5.1.0
peerDependenciesMeta:
@@ -15023,7 +15023,7 @@ __metadata:
optional: true
uglify-js:
optional: true
- checksum: 339737a407e034b7a9d4a66e31d84d81c10433e41b8eae2ca776f0e47c2048879be482a9aa08e8c27565a2a949bc68f6e07f451bf4d9aa347dd61b3d000f5353
+ checksum: fb1c2436ae1b4e983be043fa0a3d355c047b16b68f102437d08c736d7960c001e7420e2f722b9d99ce0dc70ca26a68cc63c0b82bc45f5b48671142b352a9d938
languageName: node
linkType: hard
@@ -15040,7 +15040,7 @@ __metadata:
languageName: node
linkType: hard
-"terser@npm:^5.0.0, terser@npm:^5.15.1, terser@npm:^5.16.8":
+"terser@npm:^5.0.0, terser@npm:^5.15.1, terser@npm:^5.26.0":
version: 5.26.0
resolution: "terser@npm:5.26.0"
dependencies:
From d0c1481f76688a4fe836330e0972b04299b251bf Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Mon, 1 Jan 2024 13:58:47 +0100
Subject: [PATCH 018/361] Bumped version to 20240101.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 4617d88e3cd2..d1e5abd3d1c4 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20231228.0"
+version = "20240101.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 428604d91d2885e71b9ba23e559e9c036fea9cd5 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 1 Jan 2024 20:15:34 -0500
Subject: [PATCH 019/361] Update babel monorepo to v7.23.7 (#19220)
---
package.json | 10 ++---
yarn.lock | 123 +++++++++++++++++++++++++--------------------------
2 files changed, 65 insertions(+), 68 deletions(-)
diff --git a/package.json b/package.json
index 3f4e61c24329..7b3ad9c6a114 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
"license": "Apache-2.0",
"type": "module",
"dependencies": {
- "@babel/runtime": "7.23.6",
+ "@babel/runtime": "7.23.7",
"@braintree/sanitize-url": "7.0.0",
"@codemirror/autocomplete": "6.11.1",
"@codemirror/commands": "6.3.2",
@@ -150,11 +150,11 @@
"xss": "1.0.14"
},
"devDependencies": {
- "@babel/core": "7.23.6",
+ "@babel/core": "7.23.7",
"@babel/helper-define-polyfill-provider": "0.4.4",
- "@babel/plugin-proposal-decorators": "7.23.6",
- "@babel/plugin-transform-runtime": "7.23.6",
- "@babel/preset-env": "7.23.6",
+ "@babel/plugin-proposal-decorators": "7.23.7",
+ "@babel/plugin-transform-runtime": "7.23.7",
+ "@babel/preset-env": "7.23.7",
"@babel/preset-typescript": "7.23.3",
"@bundle-stats/plugin-webpack-filter": "4.8.3",
"@koa/cors": "5.0.0",
diff --git a/yarn.lock b/yarn.lock
index 510c103b2e84..dd2a90537271 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -62,26 +62,26 @@ __metadata:
languageName: node
linkType: hard
-"@babel/core@npm:7.23.6, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3":
- version: 7.23.6
- resolution: "@babel/core@npm:7.23.6"
+"@babel/core@npm:7.23.7, @babel/core@npm:^7.11.1, @babel/core@npm:^7.12.3":
+ version: 7.23.7
+ resolution: "@babel/core@npm:7.23.7"
dependencies:
"@ampproject/remapping": "npm:^2.2.0"
"@babel/code-frame": "npm:^7.23.5"
"@babel/generator": "npm:^7.23.6"
"@babel/helper-compilation-targets": "npm:^7.23.6"
"@babel/helper-module-transforms": "npm:^7.23.3"
- "@babel/helpers": "npm:^7.23.6"
+ "@babel/helpers": "npm:^7.23.7"
"@babel/parser": "npm:^7.23.6"
"@babel/template": "npm:^7.22.15"
- "@babel/traverse": "npm:^7.23.6"
+ "@babel/traverse": "npm:^7.23.7"
"@babel/types": "npm:^7.23.6"
convert-source-map: "npm:^2.0.0"
debug: "npm:^4.1.0"
gensync: "npm:^1.0.0-beta.2"
json5: "npm:^2.2.3"
semver: "npm:^6.3.1"
- checksum: a72ba71d2f557d09ff58a5f0846344b9cea9dfcbd7418729a3a74d5b0f37a5ca024942fef4d19f248de751928a1be3d5cb0488746dd8896009dd55b974bb552e
+ checksum: 956841695ea801c8b4196d01072e6c1062335960715a6fcfd4009831003b526b00627c78b373ed49b1658c3622c71142f7ff04235fe839cac4a1a25ed51b90aa
languageName: node
linkType: hard
@@ -128,9 +128,9 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.23.6":
- version: 7.23.6
- resolution: "@babel/helper-create-class-features-plugin@npm:7.23.6"
+"@babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.23.6, @babel/helper-create-class-features-plugin@npm:^7.23.7":
+ version: 7.23.7
+ resolution: "@babel/helper-create-class-features-plugin@npm:7.23.7"
dependencies:
"@babel/helper-annotate-as-pure": "npm:^7.22.5"
"@babel/helper-environment-visitor": "npm:^7.22.20"
@@ -143,7 +143,7 @@ __metadata:
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 5e0cff67a6809d2285215057be45de9dd8900b91e3526fad5eac79023c1d6bee32aed1a04fcdf0e4d99ee4bd49ea5459cb98260c13222edf3bb983621bb452f4
+ checksum: c8b3ef58fca399a25f00d703b0fb2ac1d86642d9e3bd7af04df77857641ed08aaca042ffb271ef93771f9272481fd1cf102a9bddfcee407fb126c927deeef6a7
languageName: node
linkType: hard
@@ -335,14 +335,14 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helpers@npm:^7.23.6":
- version: 7.23.6
- resolution: "@babel/helpers@npm:7.23.6"
+"@babel/helpers@npm:^7.23.7":
+ version: 7.23.7
+ resolution: "@babel/helpers@npm:7.23.7"
dependencies:
"@babel/template": "npm:^7.22.15"
- "@babel/traverse": "npm:^7.23.6"
+ "@babel/traverse": "npm:^7.23.7"
"@babel/types": "npm:^7.23.6"
- checksum: 2a85fd2bcbc15a6c94dbe7b9e94d8920f9de76d164179d6895fee89c4339079d9e3e56f572bf19b5e7d1e6f1997d7fbaeaa686b47d35136852631dfd09e85c2f
+ checksum: ec07061dc871d406ed82c8757c4d7a510aaf15145799fb0a2c3bd3c72ca101fe82a02dd5f83ca604fbbba5de5408dd731bb1452150562bed4f3b0a2846f81f61
languageName: node
linkType: hard
@@ -390,31 +390,28 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.3":
- version: 7.23.3
- resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.3"
+"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.23.7":
+ version: 7.23.7
+ resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.23.7"
dependencies:
"@babel/helper-environment-visitor": "npm:^7.22.20"
"@babel/helper-plugin-utils": "npm:^7.22.5"
peerDependencies:
"@babel/core": ^7.0.0
- checksum: 6e13f14949eb943d33cf4d3775a7195fa93c92851dfb648931038e9eb92a9b1709fdaa5a0ff6cf063cfcd68b3e52d280f3ebc0f3085b3e006e64dd6196ecb72a
+ checksum: 3b0c9554cd0048e6e7341d7b92f29d400dbc6a5a4fc2f86dbed881d32e02ece9b55bc520387bae2eac22a5ab38a0b205c29b52b181294d99b4dd75e27309b548
languageName: node
linkType: hard
-"@babel/plugin-proposal-decorators@npm:7.23.6":
- version: 7.23.6
- resolution: "@babel/plugin-proposal-decorators@npm:7.23.6"
+"@babel/plugin-proposal-decorators@npm:7.23.7":
+ version: 7.23.7
+ resolution: "@babel/plugin-proposal-decorators@npm:7.23.7"
dependencies:
- "@babel/helper-create-class-features-plugin": "npm:^7.23.6"
+ "@babel/helper-create-class-features-plugin": "npm:^7.23.7"
"@babel/helper-plugin-utils": "npm:^7.22.5"
- "@babel/helper-replace-supers": "npm:^7.22.20"
- "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5"
- "@babel/helper-split-export-declaration": "npm:^7.22.6"
"@babel/plugin-syntax-decorators": "npm:^7.23.3"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 091796967ad728c7a00ae60c978d20f17cea08fa37bf977568880324b2619f8ce11b4a3797ef1b3137085fcb890639c49462f6be19f7cc3707e17e057df11c75
+ checksum: 1fc506b113fa204323537b3299686641c29b7626f05aa098c68a818da65ce657d2398c49aea69af91c45bbdfca6086424e28d283729dba401eb93c8a16826c95
languageName: node
linkType: hard
@@ -670,9 +667,9 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-async-generator-functions@npm:^7.23.4":
- version: 7.23.4
- resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.4"
+"@babel/plugin-transform-async-generator-functions@npm:^7.23.7":
+ version: 7.23.7
+ resolution: "@babel/plugin-transform-async-generator-functions@npm:7.23.7"
dependencies:
"@babel/helper-environment-visitor": "npm:^7.22.20"
"@babel/helper-plugin-utils": "npm:^7.22.5"
@@ -680,7 +677,7 @@ __metadata:
"@babel/plugin-syntax-async-generators": "npm:^7.8.4"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: e2fc132c9033711d55209f4781e1fc73f0f4da5e0ca80a2da73dec805166b73c92a6e83571a8994cd2c893a28302e24107e90856202b24781bab734f800102bb
+ checksum: b1f66b23423933c27336b1161ac92efef46683321caea97e2255a666f992979376f47a5559f64188d3831fa66a4b24c2a7a40838cc0e9737e90eebe20e8e6372
languageName: node
linkType: hard
@@ -1137,19 +1134,19 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-transform-runtime@npm:7.23.6":
- version: 7.23.6
- resolution: "@babel/plugin-transform-runtime@npm:7.23.6"
+"@babel/plugin-transform-runtime@npm:7.23.7":
+ version: 7.23.7
+ resolution: "@babel/plugin-transform-runtime@npm:7.23.7"
dependencies:
"@babel/helper-module-imports": "npm:^7.22.15"
"@babel/helper-plugin-utils": "npm:^7.22.5"
- babel-plugin-polyfill-corejs2: "npm:^0.4.6"
- babel-plugin-polyfill-corejs3: "npm:^0.8.5"
- babel-plugin-polyfill-regenerator: "npm:^0.5.3"
+ babel-plugin-polyfill-corejs2: "npm:^0.4.7"
+ babel-plugin-polyfill-corejs3: "npm:^0.8.7"
+ babel-plugin-polyfill-regenerator: "npm:^0.5.4"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: 54e540ec04f05f664c69db36a78b5db56b0d3e25bbe34d7f11cfe21cc5aad5240661f5ada630c7b2abcae99d229851aafbb6b2218cf285771379e0844a3f24a9
+ checksum: 1e0b21c943e565e6a2a859991059f5b5a8b917689aab9b3beb172babece1843b42f9ae9ff9913f01134fb201fd67ac2831559578949c7287e7c782e6d6740de8
languageName: node
linkType: hard
@@ -1270,9 +1267,9 @@ __metadata:
languageName: node
linkType: hard
-"@babel/preset-env@npm:7.23.6, @babel/preset-env@npm:^7.11.0":
- version: 7.23.6
- resolution: "@babel/preset-env@npm:7.23.6"
+"@babel/preset-env@npm:7.23.7, @babel/preset-env@npm:^7.11.0":
+ version: 7.23.7
+ resolution: "@babel/preset-env@npm:7.23.7"
dependencies:
"@babel/compat-data": "npm:^7.23.5"
"@babel/helper-compilation-targets": "npm:^7.23.6"
@@ -1280,7 +1277,7 @@ __metadata:
"@babel/helper-validator-option": "npm:^7.23.5"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.23.3"
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.23.3"
- "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.23.3"
+ "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.23.7"
"@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2"
"@babel/plugin-syntax-async-generators": "npm:^7.8.4"
"@babel/plugin-syntax-class-properties": "npm:^7.12.13"
@@ -1301,7 +1298,7 @@ __metadata:
"@babel/plugin-syntax-top-level-await": "npm:^7.14.5"
"@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6"
"@babel/plugin-transform-arrow-functions": "npm:^7.23.3"
- "@babel/plugin-transform-async-generator-functions": "npm:^7.23.4"
+ "@babel/plugin-transform-async-generator-functions": "npm:^7.23.7"
"@babel/plugin-transform-async-to-generator": "npm:^7.23.3"
"@babel/plugin-transform-block-scoped-functions": "npm:^7.23.3"
"@babel/plugin-transform-block-scoping": "npm:^7.23.4"
@@ -1349,14 +1346,14 @@ __metadata:
"@babel/plugin-transform-unicode-regex": "npm:^7.23.3"
"@babel/plugin-transform-unicode-sets-regex": "npm:^7.23.3"
"@babel/preset-modules": "npm:0.1.6-no-external-plugins"
- babel-plugin-polyfill-corejs2: "npm:^0.4.6"
- babel-plugin-polyfill-corejs3: "npm:^0.8.5"
- babel-plugin-polyfill-regenerator: "npm:^0.5.3"
+ babel-plugin-polyfill-corejs2: "npm:^0.4.7"
+ babel-plugin-polyfill-corejs3: "npm:^0.8.7"
+ babel-plugin-polyfill-regenerator: "npm:^0.5.4"
core-js-compat: "npm:^3.31.0"
semver: "npm:^6.3.1"
peerDependencies:
"@babel/core": ^7.0.0-0
- checksum: b47e9e7cdb0d31b2a6919ffb1b767f8159a69b000e257c1dad1121dea8c42d7ec12a892a691d1a8e90cde86edd41b017254574ec6b82a984013bb3c9e3df2b36
+ checksum: 2059dee350c39aba0a1f128d00ccfd7abf97f92a9b661f4db07a96c11d91c928a9f1df39477583f068090627bff571b4415f1a4f94008d29f6ad8b124e69804e
languageName: node
linkType: hard
@@ -1395,12 +1392,12 @@ __metadata:
languageName: node
linkType: hard
-"@babel/runtime@npm:7.23.6, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4":
- version: 7.23.6
- resolution: "@babel/runtime@npm:7.23.6"
+"@babel/runtime@npm:7.23.7, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4":
+ version: 7.23.7
+ resolution: "@babel/runtime@npm:7.23.7"
dependencies:
regenerator-runtime: "npm:^0.14.0"
- checksum: 4c4ab16f0361c59fb23956e4d0a29935f1f8a64aa8dd37876ce38355b6f4d8f0e54237aacb89c73b1532def60539ddde2d651523c8fa887b30b19a8cf0c465b0
+ checksum: b29cf3ca6277aea8c5c823d9b86e7f7153757f07eaaa81d726f125de00ac0e7451c90845770f919826a94ade8f71a6bda9c0421410dfcc285ee17a40f8f8ca00
languageName: node
linkType: hard
@@ -1415,9 +1412,9 @@ __metadata:
languageName: node
linkType: hard
-"@babel/traverse@npm:^7.23.6":
- version: 7.23.6
- resolution: "@babel/traverse@npm:7.23.6"
+"@babel/traverse@npm:^7.23.7":
+ version: 7.23.7
+ resolution: "@babel/traverse@npm:7.23.7"
dependencies:
"@babel/code-frame": "npm:^7.23.5"
"@babel/generator": "npm:^7.23.6"
@@ -1429,7 +1426,7 @@ __metadata:
"@babel/types": "npm:^7.23.6"
debug: "npm:^4.3.1"
globals: "npm:^11.1.0"
- checksum: ee4434a3ce792ee8956b64d76843caa1dda4779bb621ed9f951dd3551965bf1f292f097011c9730ecbc0b57f02434b1fa5a771610a2ef570726b0df0fc3332d9
+ checksum: 3215e59429963c8dac85c26933372cdd322952aa9930e4bc5ef2d0e4bd7a1510d1ecf8f8fd860ace5d4d9fe496d23805a1ea019a86410aee4111de5f63ee84f9
languageName: node
linkType: hard
@@ -6003,7 +6000,7 @@ __metadata:
languageName: node
linkType: hard
-"babel-plugin-polyfill-corejs2@npm:^0.4.6":
+"babel-plugin-polyfill-corejs2@npm:^0.4.7":
version: 0.4.7
resolution: "babel-plugin-polyfill-corejs2@npm:0.4.7"
dependencies:
@@ -6016,7 +6013,7 @@ __metadata:
languageName: node
linkType: hard
-"babel-plugin-polyfill-corejs3@npm:^0.8.5":
+"babel-plugin-polyfill-corejs3@npm:^0.8.7":
version: 0.8.7
resolution: "babel-plugin-polyfill-corejs3@npm:0.8.7"
dependencies:
@@ -6028,7 +6025,7 @@ __metadata:
languageName: node
linkType: hard
-"babel-plugin-polyfill-regenerator@npm:^0.5.3":
+"babel-plugin-polyfill-regenerator@npm:^0.5.4":
version: 0.5.4
resolution: "babel-plugin-polyfill-regenerator@npm:0.5.4"
dependencies:
@@ -9514,13 +9511,13 @@ __metadata:
version: 0.0.0-use.local
resolution: "home-assistant-frontend@workspace:."
dependencies:
- "@babel/core": "npm:7.23.6"
+ "@babel/core": "npm:7.23.7"
"@babel/helper-define-polyfill-provider": "npm:0.4.4"
- "@babel/plugin-proposal-decorators": "npm:7.23.6"
- "@babel/plugin-transform-runtime": "npm:7.23.6"
- "@babel/preset-env": "npm:7.23.6"
+ "@babel/plugin-proposal-decorators": "npm:7.23.7"
+ "@babel/plugin-transform-runtime": "npm:7.23.7"
+ "@babel/preset-env": "npm:7.23.7"
"@babel/preset-typescript": "npm:7.23.3"
- "@babel/runtime": "npm:7.23.6"
+ "@babel/runtime": "npm:7.23.7"
"@braintree/sanitize-url": "npm:7.0.0"
"@bundle-stats/plugin-webpack-filter": "npm:4.8.3"
"@codemirror/autocomplete": "npm:6.11.1"
From c650e23432d9f0d1a875c258f5cffc5d6f0bed55 Mon Sep 17 00:00:00 2001
From: JLo
Date: Tue, 2 Jan 2024 12:08:05 +0100
Subject: [PATCH 020/361] Review on automation editor text (#19223)
- Added `.` to bloc descriptions
- Changed "Other" into "OTher triggers" "Other conditions" and "Other actions"
- Adapted a few descriptions
---
src/translations/en.json | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/translations/en.json b/src/translations/en.json
index 0039d9926f56..0ea3cf853f2e 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2492,13 +2492,13 @@
"groups": {
"entity": {
"label": "Entity",
- "description": "When something happens to an entity"
+ "description": "When something happens to an entity."
},
"time_location": {
"label": "Time and location",
"description": "When someone enters or leaves a zone, or at a specific time."
},
- "other": { "label": "Other" }
+ "other": { "label": "Other triggers" }
},
"type": {
"calendar": {
@@ -2534,7 +2534,7 @@
"context_user_picked": "User firing event",
"context_user_pick": "Select user",
"description": {
- "picker": "When an event is being received (event is an advanced concept in Home Assistant)",
+ "picker": "When an event is being received (event is an advanced concept in Home Assistant).",
"full": "When {eventTypes} event is fired"
}
},
@@ -2546,7 +2546,7 @@
"enter": "Enter",
"leave": "Leave",
"description": {
- "picker": "When an entity created by a geolocation platform appears in or disappears from a zone",
+ "picker": "When an entity created by a geolocation platform appears in or disappears from a zone.",
"full": "When {source} {event, select, \n enter {enters}\n leave {leaves} other {} \n} {zone} {numberOfZones, plural,\n one {zone}\n other {zones}\n}"
}
},
@@ -2608,7 +2608,7 @@
"updated": "updated"
},
"description": {
- "picker": "When a persistent notification is added or removed",
+ "picker": "When a persistent notification is added or removed.",
"full": "When a persistent notification is updated"
}
},
@@ -2619,7 +2619,7 @@
"sunset": "Sunset",
"offset": "Offset (optional)",
"description": {
- "picker": "When the sun sets or rises",
+ "picker": "When the sun sets or rises.",
"sets": "When the sun sets{hasDuration, select, \n true { offset by {duration}} \n other {}\n }",
"rises": "When the sun rises{hasDuration, select, \n true { offset by {duration}} \n other {}\n }"
}
@@ -2648,7 +2648,7 @@
"value_template": "Value template",
"for": "For",
"description": {
- "picker": "When a template is evaluated to true.",
+ "picker": "When a template evaluates to true.",
"full": "When a template changes from false to true{hasDuration, select, \n true { for {duration}} \n other {}\n }"
}
},
@@ -2669,7 +2669,7 @@
"minutes": "Minutes",
"seconds": "Seconds",
"description": {
- "picker": "Periodically, every defined interval of time."
+ "picker": "Periodically, at a defined interval."
}
},
"webhook": {
@@ -2692,7 +2692,7 @@
"enter": "Enter",
"leave": "Leave",
"description": {
- "picker": "When someone (or something) enters or leaves a zone",
+ "picker": "When someone (or something) enters or leaves a zone.",
"full": "When {entity} {event, select, \n enter {enters}\n leave {leaves} other {} \n} {zone} {numberOfZones, plural,\n one {zone} \n other {zones}\n}"
}
}
@@ -2734,7 +2734,7 @@
"label": "Time and location",
"description": "If someone is in a zone or if the current time is before or after a specified time."
},
- "other": { "label": "Other" },
+ "other": { "label": "Other conditions" },
"building_blocks": {
"label": "Building blocks",
"description": "Build more complex conditions."
@@ -2766,7 +2766,7 @@
"not": {
"label": "Not",
"description": {
- "picker": "Test if a condition is not true",
+ "picker": "Test if a condition is not true.",
"no_conditions": "Test if no condition matches",
"one_condition": "Test if 1 condition does not match",
"full": "Test if none of {count} conditions match"
@@ -2800,7 +2800,7 @@
"label": "[%key:ui::panel::config::automation::editor::triggers::type::state::label%]",
"state": "[%key:ui::panel::config::automation::editor::triggers::type::state::label%]",
"description": {
- "picker": "If an entity (or attribute) is in a specific state",
+ "picker": "If an entity (or attribute) is in a specific state.",
"no_entity": "Confirm state",
"full": "Confirm{hasAttribute, select, \n true { {attribute} of}\n other {}\n} {numberOfEntities, plural,\n zero {an entity is}\n one {{entities} is}\n other {{entities} are}\n} {numberOfStates, plural,\n zero {a state}\n other {{states}}\n}{hasDuration, select, \n true { for {duration}} \n other {}\n }"
}
@@ -2821,7 +2821,7 @@
"label": "[%key:ui::panel::config::automation::editor::triggers::type::template::label%]",
"value_template": "[%key:ui::panel::config::automation::editor::triggers::type::template::value_template%]",
"description": {
- "picker": "If a template is evaluated to true.",
+ "picker": "If a template evaluates to true.",
"full": "Test if template renders a value equal to true"
}
},
@@ -2844,7 +2844,7 @@
"sun": "Sunday"
},
"description": {
- "picker": "If the current time is before or after a specified time",
+ "picker": "If the current time is before or after a specified time.",
"full": "Confirm the {hasTime, select, \n after {time is after {time_after}}\n before {time is before {time_before}}\n after_before {time is after {time_after} and before {time_before}} \n other {}\n }{hasTimeAndDay, select, \n true { and the }\n other {}\n}{hasDay, select, \n true { day is {day}}\n other {}\n}"
}
},
@@ -2862,7 +2862,7 @@
"entity": "[%key:ui::panel::config::automation::editor::triggers::type::zone::entity%]",
"zone": "[%key:ui::panel::config::automation::editor::triggers::type::zone::label%]",
"description": {
- "picker": "If someone (or something) is in a zone",
+ "picker": "If someone (or something) is in a zone.",
"full": "Confirm {entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} in {zone} {numberOfZones, plural,\n one {zone} \n other {zones}\n} "
}
}
@@ -2899,7 +2899,7 @@
"continue_on_error": "Continue on error",
"groups": {
"helpers": { "label": "Helpers" },
- "other": { "label": "Other" },
+ "other": { "label": "Other actions" },
"building_blocks": {
"label": "Building blocks",
"description": "Build more complex sequences of actions."
@@ -3069,14 +3069,14 @@
"response_variable": "The name of the variable to use as response",
"error": "Stop because of an unexpected error",
"description": {
- "picker": "Stop the sequence of actions",
+ "picker": "Stop the sequence of actions.",
"full": "Stop {hasReason, select, \n true { because: {reason}} \n other {}\n }"
}
},
"parallel": {
"label": "Run in parallel",
"description": {
- "picker": "perform a sequence of actions in parallel.",
+ "picker": "Perform a sequence of actions in parallel.",
"full": "Run {number} {number, plural,\n one {action}\n other {actions}\n} in parallel"
}
},
From 52fcf64cfdb86e3958af9beca9e069a0a734f8eb Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 13:36:06 +0100
Subject: [PATCH 021/361] Automation editor tweaks (#19225)
* Automation editor tweaks
* fix styling
---
src/data/condition.ts | 1 -
.../add-automation-element-dialog.ts | 145 +++++++++++++-----
.../condition/ha-automation-condition.ts | 1 +
.../types/ha-automation-condition-device.ts | 1 +
.../show-add-automation-element-dialog.ts | 1 +
.../types/ha-automation-trigger-device.ts | 1 +
6 files changed, 108 insertions(+), 42 deletions(-)
diff --git a/src/data/condition.ts b/src/data/condition.ts
index 44a0e218609c..d8c7af44fecc 100644
--- a/src/data/condition.ts
+++ b/src/data/condition.ts
@@ -46,7 +46,6 @@ export const CONDITION_GROUPS: AutomationElementGroup = {
icon: mdiDotsHorizontal,
members: {
template: {},
- trigger: {},
},
},
} as const;
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index b96283a61dd8..31760dca1bc1 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -1,7 +1,14 @@
import "@material/mwc-list/mwc-list";
import { mdiClose, mdiContentPaste, mdiPlus } from "@mdi/js";
import Fuse, { IFuseOptions } from "fuse.js";
-import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
+import {
+ CSSResultGroup,
+ LitElement,
+ PropertyValues,
+ css,
+ html,
+ nothing,
+} from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { repeat } from "lit/directives/repeat";
@@ -42,6 +49,8 @@ import {
AddAutomationElementDialogParams,
PASTE_VALUE,
} from "./show-add-automation-element-dialog";
+import { computeDomain } from "../../../common/entity/compute_domain";
+import { deepEqual } from "../../../common/util/deep-equal";
const TYPES = {
trigger: { groups: TRIGGER_GROUPS, icons: TRIGGER_ICONS },
@@ -93,13 +102,15 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
@state() private _manifests?: DomainManifestLookup;
+ @state() private _domains?: Set;
+
@query("ha-dialog") private _dialog?: HaDialog;
private _fullScreen = false;
- private _width?: number;
+ @state() private _width?: number;
- private _height?: number;
+ @state() private _height?: number;
public showDialog(params): void {
this._params = params;
@@ -124,6 +135,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._prev = undefined;
this._filter = "";
this._manifests = undefined;
+ this._domains = undefined;
}
private _convertToItem = (
@@ -152,6 +164,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getFilteredItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
+ root: AddAutomationElementDialogParams["root"],
group: string | undefined,
filter: string,
localize: LocalizeFunc,
@@ -164,6 +177,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
: TYPES[type].groups[group].members!
: TYPES[type].groups;
+ if (type === "condition" && group === "other" && !root) {
+ groups.trigger = {};
+ }
+
const flattenGroups = (grp: AutomationElementGroup) =>
Object.entries(grp).map(([key, options]) =>
options.members
@@ -191,7 +208,9 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getGroupItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
+ root: AddAutomationElementDialogParams["root"],
group: string | undefined,
+ domains: Set | undefined,
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests?: DomainManifestLookup
@@ -208,6 +227,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
? TYPES[type].groups[group].members!
: TYPES[type].groups;
+ if (type === "condition" && group === "other" && !root) {
+ groups.trigger = {};
+ }
+
const result = Object.entries(groups).map(([key, options]) =>
this._convertToItem(key, options, type, localize)
);
@@ -215,15 +238,33 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
if (type === "action") {
if (!this._group) {
result.unshift(
- ...this._serviceGroups(localize, services, manifests, undefined)
+ ...this._serviceGroups(
+ localize,
+ services,
+ manifests,
+ domains,
+ undefined
+ )
);
} else if (this._group === "helpers") {
result.unshift(
- ...this._serviceGroups(localize, services, manifests, "helper")
+ ...this._serviceGroups(
+ localize,
+ services,
+ manifests,
+ domains,
+ "helper"
+ )
);
} else if (this._group === "other") {
result.unshift(
- ...this._serviceGroups(localize, services, manifests, "other")
+ ...this._serviceGroups(
+ localize,
+ services,
+ manifests,
+ domains,
+ "other"
+ )
);
}
}
@@ -243,42 +284,44 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
}
);
- private _serviceGroups = memoizeOne(
- (
- localize: LocalizeFunc,
- services: HomeAssistant["services"],
- manifests: DomainManifestLookup | undefined,
- type: "helper" | "other" | undefined
- ): ListItem[] => {
- if (!services || !manifests) {
- return [];
- }
- const result: ListItem[] = [];
- Object.keys(services).forEach((domain) => {
- const manifest = manifests[domain];
- if (
- (type === undefined &&
- manifest?.integration_type === "entity" &&
- !ENTITY_DOMAINS_OTHER.has(domain)) ||
- (type === "helper" && manifest?.integration_type === "helper") ||
- (type === "other" &&
- (ENTITY_DOMAINS_OTHER.has(domain) ||
- !["helper", "entity"].includes(manifest?.integration_type || "")))
- ) {
- result.push({
- group: true,
- icon: domainIcon(domain),
- key: `${SERVICE_PREFIX}${domain}`,
- name: domainToName(localize, domain, manifest),
- description: "",
- });
- }
- });
- return result.sort((a, b) =>
- stringCompare(a.name, b.name, this.hass.locale.language)
- );
+ private _serviceGroups = (
+ localize: LocalizeFunc,
+ services: HomeAssistant["services"],
+ manifests: DomainManifestLookup | undefined,
+ domains: Set | undefined,
+ type: "helper" | "other" | undefined
+ ): ListItem[] => {
+ if (!services || !manifests) {
+ return [];
}
- );
+ const result: ListItem[] = [];
+ Object.keys(services).forEach((domain) => {
+ const manifest = manifests[domain];
+ const domainUsed = !domains ? true : domains.has(domain);
+ if (
+ (type === undefined &&
+ manifest?.integration_type === "entity" &&
+ domainUsed &&
+ !ENTITY_DOMAINS_OTHER.has(domain)) ||
+ (type === "helper" && manifest?.integration_type === "helper") ||
+ (type === "other" &&
+ (ENTITY_DOMAINS_OTHER.has(domain) ||
+ (!domainUsed && manifest?.integration_type === "entity") ||
+ !["helper", "entity"].includes(manifest?.integration_type || "")))
+ ) {
+ result.push({
+ group: true,
+ icon: domainIcon(domain),
+ key: `${SERVICE_PREFIX}${domain}`,
+ name: domainToName(localize, domain, manifest),
+ description: "",
+ });
+ }
+ });
+ return result.sort((a, b) =>
+ stringCompare(a.name, b.name, this.hass.locale.language)
+ );
+ };
private _services = memoizeOne(
(
@@ -368,6 +411,19 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._height = boundingRect?.height;
}
+ protected willUpdate(changedProperties: PropertyValues): void {
+ if (
+ this._params?.type === "action" &&
+ changedProperties.has("hass") &&
+ changedProperties.get("hass")?.states !== this.hass.states
+ ) {
+ const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
+ if (!deepEqual(domains, this._domains)) {
+ this._domains = domains;
+ }
+ }
+ }
+
protected render() {
if (!this._params) {
return nothing;
@@ -376,6 +432,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const items = this._filter
? this._getFilteredItems(
this._params.type,
+ this._params.root,
this._group,
this._filter,
this.hass.localize,
@@ -384,7 +441,9 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
)
: this._getGroupItems(
this._params.type,
+ this._params.root,
this._group,
+ this._domains,
this.hass.localize,
this.hass.services,
this._manifests
@@ -562,6 +621,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
ha-icon-next {
width: 24px;
}
+ mwc-list {
+ max-height: 468px;
+ max-width: 100vw;
+ }
search-input {
display: block;
margin: 0 16px;
diff --git a/src/panels/config/automation/condition/ha-automation-condition.ts b/src/panels/config/automation/condition/ha-automation-condition.ts
index 27364b92a3ed..ecf4f8823770 100644
--- a/src/panels/config/automation/condition/ha-automation-condition.ts
+++ b/src/panels/config/automation/condition/ha-automation-condition.ts
@@ -203,6 +203,7 @@ export default class HaAutomationCondition extends LitElement {
showAddAutomationElementDialog(this, {
type: "condition",
add: this._addCondition,
+ root: !this.nested,
clipboardItem: this._clipboard?.condition?.condition,
});
}
diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-device.ts b/src/panels/config/automation/condition/types/ha-automation-condition-device.ts
index 71568fe02c10..4593a5f70123 100644
--- a/src/panels/config/automation/condition/types/ha-automation-condition-device.ts
+++ b/src/panels/config/automation/condition/types/ha-automation-condition-device.ts
@@ -168,6 +168,7 @@ export class HaDeviceCondition extends LitElement {
}
ha-form {
+ display: block;
margin-top: 24px;
}
`;
diff --git a/src/panels/config/automation/show-add-automation-element-dialog.ts b/src/panels/config/automation/show-add-automation-element-dialog.ts
index c497ca85c620..55453505121d 100644
--- a/src/panels/config/automation/show-add-automation-element-dialog.ts
+++ b/src/panels/config/automation/show-add-automation-element-dialog.ts
@@ -6,6 +6,7 @@ export interface AddAutomationElementDialogParams {
type: "trigger" | "condition" | "action";
add: (key: string) => void;
clipboardItem: string | undefined;
+ root?: boolean;
group?: string;
}
const loadDialog = () => import("./add-automation-element-dialog");
diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts
index 8b3a63575220..1b94ff6138b2 100644
--- a/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts
+++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts
@@ -174,6 +174,7 @@ export class HaDeviceTrigger extends LitElement {
}
ha-form {
+ display: block;
margin-top: 24px;
}
`;
From 1b6def487550eeb6b97e4edcd6fcf901ed306e6c Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Tue, 2 Jan 2024 05:07:34 -0800
Subject: [PATCH 022/361] Localize a device action string (#19203)
---
src/data/script_i18n.ts | 4 +++-
src/translations/en.json | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 1ba30198bd3e..4b07b84f0ed5 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -404,7 +404,9 @@ const tryDescribeAction = (
if (actionType === "device_action") {
const config = action as DeviceAction;
if (!config.device_id) {
- return "Device action";
+ return hass.localize(
+ `${actionTranslationBaseKey}.device_id.description.no_device`
+ );
}
const localized = localizeDeviceAutomationAction(
hass,
diff --git a/src/translations/en.json b/src/translations/en.json
index 0ea3cf853f2e..c176cf65c96a 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2990,7 +2990,8 @@
"flash": "Flash"
},
"description": {
- "picker": "Do something on a device. Great way to start."
+ "picker": "Do something on a device. Great way to start.",
+ "no_device": "Device action"
}
},
"activate_scene": {
From 5ac03604949cf8bf3ab616d9d22ff472f428ede4 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 16:08:26 +0100
Subject: [PATCH 023/361] Remove references to "service call" from actions
(#19226)
---
src/components/ha-service-control.ts | 28 ++++++++++++++-----
src/data/script.ts | 2 ++
src/data/script_i18n.ts | 5 +++-
.../action/ha-automation-action-row.ts | 10 ++++++-
.../automation/action/ha-automation-action.ts | 1 +
src/translations/en.json | 1 +
6 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/src/components/ha-service-control.ts b/src/components/ha-service-control.ts
index f1ae8ee54bac..119418355c64 100644
--- a/src/components/ha-service-control.ts
+++ b/src/components/ha-service-control.ts
@@ -4,7 +4,14 @@ import {
HassServices,
HassServiceTarget,
} from "home-assistant-js-websocket";
-import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
+import {
+ css,
+ CSSResultGroup,
+ html,
+ LitElement,
+ PropertyValues,
+ nothing,
+} from "lit";
import { customElement, property, query, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { ensureArray } from "../common/array/ensure-array";
@@ -83,6 +90,8 @@ export class HaServiceControl extends LitElement {
@property({ type: Boolean }) public showAdvanced?: boolean;
+ @property({ type: Boolean, reflect: true }) public hidePicker?: boolean;
+
@state() private _value!: this["value"];
@state() private _checkedKeys = new Set();
@@ -363,12 +372,14 @@ export class HaServiceControl extends LitElement {
)) ||
serviceData?.description;
- return html`
+ return html`${this.hidePicker
+ ? nothing
+ : html``}
${description ? html`
${description}
` : ""}
${this._manifest
@@ -735,6 +746,9 @@ export class HaServiceControl extends LitElement {
margin: var(--service-control-padding, 0 16px);
padding: 16px 0;
}
+ :host([hidePicker]) p {
+ padding-top: 0;
+ }
.checkbox-spacer {
width: 32px;
}
diff --git a/src/data/script.ts b/src/data/script.ts
index f0b5e7151b51..08910dc88fcb 100644
--- a/src/data/script.ts
+++ b/src/data/script.ts
@@ -52,6 +52,7 @@ export const serviceActionStruct: Describe
= assign(
target: optional(targetStruct),
data: optional(object()),
response_variable: optional(string()),
+ metadata: optional(object()),
})
);
@@ -133,6 +134,7 @@ export interface ServiceAction extends BaseAction {
target?: HassServiceTarget;
data?: Record;
response_variable?: string;
+ metadata?: Record;
}
export interface DeviceAction extends BaseAction {
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 4b07b84f0ed5..3d7d8c5a1da4 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -168,8 +168,11 @@ const tryDescribeAction = (
const service =
hass.localize(`component.${domain}.services.${serviceName}.name`) ||
hass.services[domain][serviceName]?.name;
+
return hass.localize(
- `${actionTranslationBaseKey}.service.description.service_based_on_name`,
+ `${actionTranslationBaseKey}.service.description.${
+ config.metadata ? "service_name" : "service_based_on_name"
+ }`,
{
name: service
? `${domainToName(hass.localize, domain)}: ${service}`
diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts
index f09c901c8e1a..0e58c0e8b2b5 100644
--- a/src/panels/config/automation/action/ha-automation-action-row.ts
+++ b/src/panels/config/automation/action/ha-automation-action-row.ts
@@ -29,6 +29,8 @@ import { classMap } from "lit/directives/class-map";
import { storage } from "../../../../common/decorators/storage";
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
import { fireEvent } from "../../../../common/dom/fire_event";
+import { computeDomain } from "../../../../common/entity/compute_domain";
+import { domainIconWithoutDefault } from "../../../../common/entity/domain_icon";
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
import { handleStructError } from "../../../../common/structs/handle-errors";
import "../../../../components/ha-alert";
@@ -190,7 +192,13 @@ export default class HaAutomationActionRow extends LitElement {
${capitalizeFirstLetter(
describeAction(this.hass, this._entityReg, this.action)
diff --git a/src/panels/config/automation/action/ha-automation-action.ts b/src/panels/config/automation/action/ha-automation-action.ts
index dca4bab6acde..ce312a7bd399 100644
--- a/src/panels/config/automation/action/ha-automation-action.ts
+++ b/src/panels/config/automation/action/ha-automation-action.ts
@@ -191,6 +191,7 @@ export default class HaAutomationAction extends LitElement {
} else if (isService(action)) {
actions = this.actions.concat({
service: getService(action),
+ metadata: {},
});
} else {
const elClass = customElements.get(
diff --git a/src/translations/en.json b/src/translations/en.json
index c176cf65c96a..e771c8fe1910 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2914,6 +2914,7 @@
"description": {
"service_based_on_template": "Call a service based on a template on {targets}",
"service_based_on_name": "Call a service ''{name}'' on {targets}",
+ "service_name": "''{name}'' on {targets}",
"service": "Call a service",
"target_template": "templated {name}",
"target_unknown_entity": "unknown entity",
From 6f7da16d1d367a354073d5b3d804cfb6103b36e9 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:11:34 +0100
Subject: [PATCH 024/361] Use brand icons in actions (#19227)
---
src/common/const.ts | 4 ++
.../add-automation-element-dialog.ts | 39 ++++++++++++++++---
2 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/src/common/const.ts b/src/common/const.ts
index 66c14e64e140..68f4fa97b1c1 100644
--- a/src/common/const.ts
+++ b/src/common/const.ts
@@ -29,6 +29,7 @@ import {
mdiFlash,
mdiFlower,
mdiFormatListBulleted,
+ mdiFormatListCheckbox,
mdiFormTextbox,
mdiGauge,
mdiGoogleAssistant,
@@ -64,6 +65,7 @@ import {
mdiTransmissionTower,
mdiWater,
mdiWaterPercent,
+ mdiWeatherPartlyCloudy,
mdiWeatherPouring,
mdiWeatherRainy,
mdiWeatherWindy,
@@ -128,6 +130,7 @@ export const FIXED_DOMAIN_ICONS = {
updater: mdiCloudUpload,
vacuum: mdiRobotVacuum,
wake_word: mdiChatSleep,
+ weather: mdiWeatherPartlyCloudy,
zone: mdiMapMarkerRadius,
};
@@ -166,6 +169,7 @@ export const FIXED_DEVICE_CLASS_ICONS = {
precipitation_intensity: mdiWeatherPouring,
pressure: mdiGauge,
reactive_power: mdiFlash,
+ shopping_List: mdiFormatListCheckbox,
signal_strength: mdiWifi,
sound_pressure: mdiEarHearing,
speed: mdiSpeedometer,
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 31760dca1bc1..0e930b7c9916 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -15,7 +15,7 @@ import { repeat } from "lit/directives/repeat";
import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../common/dom/fire_event";
-import { domainIcon } from "../../../common/entity/domain_icon";
+import { domainIconWithoutDefault } from "../../../common/entity/domain_icon";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import { stringCompare } from "../../../common/string/compare";
import { LocalizeFunc } from "../../../common/translations/localize";
@@ -45,6 +45,7 @@ import { TRIGGER_GROUPS, TRIGGER_ICONS } from "../../../data/trigger";
import { HassDialog } from "../../../dialogs/make-dialog-manager";
import { haStyle, haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
+import { brandsUrl } from "../../../util/brands-url";
import {
AddAutomationElementDialogParams,
PASTE_VALUE,
@@ -68,7 +69,8 @@ interface ListItem {
key: string;
name: string;
description: string;
- icon: string;
+ icon?: string;
+ image?: string;
group: boolean;
}
@@ -309,9 +311,17 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
(!domainUsed && manifest?.integration_type === "entity") ||
!["helper", "entity"].includes(manifest?.integration_type || "")))
) {
+ const icon = domainIconWithoutDefault(domain);
result.push({
group: true,
- icon: domainIcon(domain),
+ icon,
+ image: !icon
+ ? brandsUrl({
+ domain,
+ type: "icon",
+ darkOptimized: this.hass.themes?.darkMode,
+ })
+ : undefined,
key: `${SERVICE_PREFIX}${domain}`,
name: domainToName(localize, domain, manifest),
description: "",
@@ -345,9 +355,17 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const services_keys = Object.keys(services[dmn]);
for (const service of services_keys) {
+ const icon = domainIconWithoutDefault(dmn);
result.push({
group: false,
- icon: domainIcon(dmn),
+ icon,
+ image: !icon
+ ? brandsUrl({
+ domain: dmn,
+ type: "icon",
+ darkOptimized: this.hass.themes?.darkMode,
+ })
+ : undefined,
key: `${SERVICE_PREFIX}${dmn}.${service}`,
name: `${domain ? "" : `${domainToName(localize, dmn)}: `}${
this.hass.localize(`component.${dmn}.services.${service}.name`) ||
@@ -556,7 +574,18 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
>
${item.name}
${item.description}
-
+ ${item.icon
+ ? html``
+ : html``}
${item.group
? html``
: html`
Date: Tue, 2 Jan 2024 18:31:18 +0100
Subject: [PATCH 025/361] Change format of service description (#19229)
---
src/data/script_i18n.ts | 15 ++++++++++++---
src/translations/en.json | 2 +-
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 3d7d8c5a1da4..40c823bc862f 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -169,10 +169,19 @@ const tryDescribeAction = (
hass.localize(`component.${domain}.services.${serviceName}.name`) ||
hass.services[domain][serviceName]?.name;
+ if (config.metadata) {
+ return hass.localize(
+ `${actionTranslationBaseKey}.service.description.service_name`,
+ {
+ domain: domainToName(hass.localize, domain),
+ name: service || config.service,
+ targets: formatListWithAnds(hass.locale, targets),
+ }
+ );
+ }
+
return hass.localize(
- `${actionTranslationBaseKey}.service.description.${
- config.metadata ? "service_name" : "service_based_on_name"
- }`,
+ `${actionTranslationBaseKey}.service.description.service_based_on_name`,
{
name: service
? `${domainToName(hass.localize, domain)}: ${service}`
diff --git a/src/translations/en.json b/src/translations/en.json
index e771c8fe1910..6ef41c81c129 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2914,7 +2914,7 @@
"description": {
"service_based_on_template": "Call a service based on a template on {targets}",
"service_based_on_name": "Call a service ''{name}'' on {targets}",
- "service_name": "''{name}'' on {targets}",
+ "service_name": "{domain} ''{name}'' on {targets}",
"service": "Call a service",
"target_template": "templated {name}",
"target_unknown_entity": "unknown entity",
From def2eadc24b58e4f4af9bf4bb29ef59614564427 Mon Sep 17 00:00:00 2001
From: Josh McCarty
Date: Tue, 2 Jan 2024 10:35:08 -0700
Subject: [PATCH 026/361] Add missing device classes for
entity-registry-settings-editor (#19231)
* Add connectivity device class for binary sensors
* Add update device class
* Separate connectivity and update
---
src/panels/config/entities/entity-registry-settings-editor.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/panels/config/entities/entity-registry-settings-editor.ts b/src/panels/config/entities/entity-registry-settings-editor.ts
index 14d88e12afc7..9e7213e41475 100644
--- a/src/panels/config/entities/entity-registry-settings-editor.ts
+++ b/src/panels/config/entities/entity-registry-settings-editor.ts
@@ -118,6 +118,8 @@ const OVERRIDE_DEVICE_CLASSES = {
"carbon_monoxide",
"moisture",
], // Alarm
+ ["connectivity"], // Connectivity
+ ["update"], // Update
],
};
From 7d6dfaad153d4f587a7dde3a734d282ea1cb3789 Mon Sep 17 00:00:00 2001
From: JLo
Date: Tue, 2 Jan 2024 18:39:55 +0100
Subject: [PATCH 027/361] New copy for device trigger in automation editor
(#19232)
New copy for device trigger in automation editor:
"Set of conditions provided by your device. Great way to start."
---
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 6ef41c81c129..53306cd8b77d 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2760,7 +2760,7 @@
"preset_mode": "Preset mode"
},
"description": {
- "picker": "If a device is in a certain state. Great way to start."
+ "picker": "Set of conditions provided by your device. Great way to start."
}
},
"not": {
From 2add88ccc23d87a92329b3ee07128389ef1c0ed4 Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Tue, 2 Jan 2024 05:07:34 -0800
Subject: [PATCH 028/361] Localize a device action string (#19203)
---
src/data/script_i18n.ts | 4 +++-
src/translations/en.json | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 1ba30198bd3e..4b07b84f0ed5 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -404,7 +404,9 @@ const tryDescribeAction = (
if (actionType === "device_action") {
const config = action as DeviceAction;
if (!config.device_id) {
- return "Device action";
+ return hass.localize(
+ `${actionTranslationBaseKey}.device_id.description.no_device`
+ );
}
const localized = localizeDeviceAutomationAction(
hass,
diff --git a/src/translations/en.json b/src/translations/en.json
index 0039d9926f56..a3070c0787b1 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2990,7 +2990,8 @@
"flash": "Flash"
},
"description": {
- "picker": "Do something on a device. Great way to start."
+ "picker": "Do something on a device. Great way to start.",
+ "no_device": "Device action"
}
},
"activate_scene": {
From 4fcf99faa7b6735aee1550b785a76df8e633dcca Mon Sep 17 00:00:00 2001
From: JLo
Date: Tue, 2 Jan 2024 12:08:05 +0100
Subject: [PATCH 029/361] Review on automation editor text (#19223)
- Added `.` to bloc descriptions
- Changed "Other" into "OTher triggers" "Other conditions" and "Other actions"
- Adapted a few descriptions
---
src/translations/en.json | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/src/translations/en.json b/src/translations/en.json
index a3070c0787b1..c176cf65c96a 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2492,13 +2492,13 @@
"groups": {
"entity": {
"label": "Entity",
- "description": "When something happens to an entity"
+ "description": "When something happens to an entity."
},
"time_location": {
"label": "Time and location",
"description": "When someone enters or leaves a zone, or at a specific time."
},
- "other": { "label": "Other" }
+ "other": { "label": "Other triggers" }
},
"type": {
"calendar": {
@@ -2534,7 +2534,7 @@
"context_user_picked": "User firing event",
"context_user_pick": "Select user",
"description": {
- "picker": "When an event is being received (event is an advanced concept in Home Assistant)",
+ "picker": "When an event is being received (event is an advanced concept in Home Assistant).",
"full": "When {eventTypes} event is fired"
}
},
@@ -2546,7 +2546,7 @@
"enter": "Enter",
"leave": "Leave",
"description": {
- "picker": "When an entity created by a geolocation platform appears in or disappears from a zone",
+ "picker": "When an entity created by a geolocation platform appears in or disappears from a zone.",
"full": "When {source} {event, select, \n enter {enters}\n leave {leaves} other {} \n} {zone} {numberOfZones, plural,\n one {zone}\n other {zones}\n}"
}
},
@@ -2608,7 +2608,7 @@
"updated": "updated"
},
"description": {
- "picker": "When a persistent notification is added or removed",
+ "picker": "When a persistent notification is added or removed.",
"full": "When a persistent notification is updated"
}
},
@@ -2619,7 +2619,7 @@
"sunset": "Sunset",
"offset": "Offset (optional)",
"description": {
- "picker": "When the sun sets or rises",
+ "picker": "When the sun sets or rises.",
"sets": "When the sun sets{hasDuration, select, \n true { offset by {duration}} \n other {}\n }",
"rises": "When the sun rises{hasDuration, select, \n true { offset by {duration}} \n other {}\n }"
}
@@ -2648,7 +2648,7 @@
"value_template": "Value template",
"for": "For",
"description": {
- "picker": "When a template is evaluated to true.",
+ "picker": "When a template evaluates to true.",
"full": "When a template changes from false to true{hasDuration, select, \n true { for {duration}} \n other {}\n }"
}
},
@@ -2669,7 +2669,7 @@
"minutes": "Minutes",
"seconds": "Seconds",
"description": {
- "picker": "Periodically, every defined interval of time."
+ "picker": "Periodically, at a defined interval."
}
},
"webhook": {
@@ -2692,7 +2692,7 @@
"enter": "Enter",
"leave": "Leave",
"description": {
- "picker": "When someone (or something) enters or leaves a zone",
+ "picker": "When someone (or something) enters or leaves a zone.",
"full": "When {entity} {event, select, \n enter {enters}\n leave {leaves} other {} \n} {zone} {numberOfZones, plural,\n one {zone} \n other {zones}\n}"
}
}
@@ -2734,7 +2734,7 @@
"label": "Time and location",
"description": "If someone is in a zone or if the current time is before or after a specified time."
},
- "other": { "label": "Other" },
+ "other": { "label": "Other conditions" },
"building_blocks": {
"label": "Building blocks",
"description": "Build more complex conditions."
@@ -2766,7 +2766,7 @@
"not": {
"label": "Not",
"description": {
- "picker": "Test if a condition is not true",
+ "picker": "Test if a condition is not true.",
"no_conditions": "Test if no condition matches",
"one_condition": "Test if 1 condition does not match",
"full": "Test if none of {count} conditions match"
@@ -2800,7 +2800,7 @@
"label": "[%key:ui::panel::config::automation::editor::triggers::type::state::label%]",
"state": "[%key:ui::panel::config::automation::editor::triggers::type::state::label%]",
"description": {
- "picker": "If an entity (or attribute) is in a specific state",
+ "picker": "If an entity (or attribute) is in a specific state.",
"no_entity": "Confirm state",
"full": "Confirm{hasAttribute, select, \n true { {attribute} of}\n other {}\n} {numberOfEntities, plural,\n zero {an entity is}\n one {{entities} is}\n other {{entities} are}\n} {numberOfStates, plural,\n zero {a state}\n other {{states}}\n}{hasDuration, select, \n true { for {duration}} \n other {}\n }"
}
@@ -2821,7 +2821,7 @@
"label": "[%key:ui::panel::config::automation::editor::triggers::type::template::label%]",
"value_template": "[%key:ui::panel::config::automation::editor::triggers::type::template::value_template%]",
"description": {
- "picker": "If a template is evaluated to true.",
+ "picker": "If a template evaluates to true.",
"full": "Test if template renders a value equal to true"
}
},
@@ -2844,7 +2844,7 @@
"sun": "Sunday"
},
"description": {
- "picker": "If the current time is before or after a specified time",
+ "picker": "If the current time is before or after a specified time.",
"full": "Confirm the {hasTime, select, \n after {time is after {time_after}}\n before {time is before {time_before}}\n after_before {time is after {time_after} and before {time_before}} \n other {}\n }{hasTimeAndDay, select, \n true { and the }\n other {}\n}{hasDay, select, \n true { day is {day}}\n other {}\n}"
}
},
@@ -2862,7 +2862,7 @@
"entity": "[%key:ui::panel::config::automation::editor::triggers::type::zone::entity%]",
"zone": "[%key:ui::panel::config::automation::editor::triggers::type::zone::label%]",
"description": {
- "picker": "If someone (or something) is in a zone",
+ "picker": "If someone (or something) is in a zone.",
"full": "Confirm {entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} in {zone} {numberOfZones, plural,\n one {zone} \n other {zones}\n} "
}
}
@@ -2899,7 +2899,7 @@
"continue_on_error": "Continue on error",
"groups": {
"helpers": { "label": "Helpers" },
- "other": { "label": "Other" },
+ "other": { "label": "Other actions" },
"building_blocks": {
"label": "Building blocks",
"description": "Build more complex sequences of actions."
@@ -3070,14 +3070,14 @@
"response_variable": "The name of the variable to use as response",
"error": "Stop because of an unexpected error",
"description": {
- "picker": "Stop the sequence of actions",
+ "picker": "Stop the sequence of actions.",
"full": "Stop {hasReason, select, \n true { because: {reason}} \n other {}\n }"
}
},
"parallel": {
"label": "Run in parallel",
"description": {
- "picker": "perform a sequence of actions in parallel.",
+ "picker": "Perform a sequence of actions in parallel.",
"full": "Run {number} {number, plural,\n one {action}\n other {actions}\n} in parallel"
}
},
From f099f66065ead07852d268773eecb468523550eb Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 13:36:06 +0100
Subject: [PATCH 030/361] Automation editor tweaks (#19225)
* Automation editor tweaks
* fix styling
---
src/data/condition.ts | 1 -
.../add-automation-element-dialog.ts | 145 +++++++++++++-----
.../condition/ha-automation-condition.ts | 1 +
.../types/ha-automation-condition-device.ts | 1 +
.../show-add-automation-element-dialog.ts | 1 +
.../types/ha-automation-trigger-device.ts | 1 +
6 files changed, 108 insertions(+), 42 deletions(-)
diff --git a/src/data/condition.ts b/src/data/condition.ts
index 44a0e218609c..d8c7af44fecc 100644
--- a/src/data/condition.ts
+++ b/src/data/condition.ts
@@ -46,7 +46,6 @@ export const CONDITION_GROUPS: AutomationElementGroup = {
icon: mdiDotsHorizontal,
members: {
template: {},
- trigger: {},
},
},
} as const;
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index b96283a61dd8..31760dca1bc1 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -1,7 +1,14 @@
import "@material/mwc-list/mwc-list";
import { mdiClose, mdiContentPaste, mdiPlus } from "@mdi/js";
import Fuse, { IFuseOptions } from "fuse.js";
-import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
+import {
+ CSSResultGroup,
+ LitElement,
+ PropertyValues,
+ css,
+ html,
+ nothing,
+} from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { repeat } from "lit/directives/repeat";
@@ -42,6 +49,8 @@ import {
AddAutomationElementDialogParams,
PASTE_VALUE,
} from "./show-add-automation-element-dialog";
+import { computeDomain } from "../../../common/entity/compute_domain";
+import { deepEqual } from "../../../common/util/deep-equal";
const TYPES = {
trigger: { groups: TRIGGER_GROUPS, icons: TRIGGER_ICONS },
@@ -93,13 +102,15 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
@state() private _manifests?: DomainManifestLookup;
+ @state() private _domains?: Set;
+
@query("ha-dialog") private _dialog?: HaDialog;
private _fullScreen = false;
- private _width?: number;
+ @state() private _width?: number;
- private _height?: number;
+ @state() private _height?: number;
public showDialog(params): void {
this._params = params;
@@ -124,6 +135,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._prev = undefined;
this._filter = "";
this._manifests = undefined;
+ this._domains = undefined;
}
private _convertToItem = (
@@ -152,6 +164,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getFilteredItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
+ root: AddAutomationElementDialogParams["root"],
group: string | undefined,
filter: string,
localize: LocalizeFunc,
@@ -164,6 +177,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
: TYPES[type].groups[group].members!
: TYPES[type].groups;
+ if (type === "condition" && group === "other" && !root) {
+ groups.trigger = {};
+ }
+
const flattenGroups = (grp: AutomationElementGroup) =>
Object.entries(grp).map(([key, options]) =>
options.members
@@ -191,7 +208,9 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getGroupItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
+ root: AddAutomationElementDialogParams["root"],
group: string | undefined,
+ domains: Set | undefined,
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests?: DomainManifestLookup
@@ -208,6 +227,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
? TYPES[type].groups[group].members!
: TYPES[type].groups;
+ if (type === "condition" && group === "other" && !root) {
+ groups.trigger = {};
+ }
+
const result = Object.entries(groups).map(([key, options]) =>
this._convertToItem(key, options, type, localize)
);
@@ -215,15 +238,33 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
if (type === "action") {
if (!this._group) {
result.unshift(
- ...this._serviceGroups(localize, services, manifests, undefined)
+ ...this._serviceGroups(
+ localize,
+ services,
+ manifests,
+ domains,
+ undefined
+ )
);
} else if (this._group === "helpers") {
result.unshift(
- ...this._serviceGroups(localize, services, manifests, "helper")
+ ...this._serviceGroups(
+ localize,
+ services,
+ manifests,
+ domains,
+ "helper"
+ )
);
} else if (this._group === "other") {
result.unshift(
- ...this._serviceGroups(localize, services, manifests, "other")
+ ...this._serviceGroups(
+ localize,
+ services,
+ manifests,
+ domains,
+ "other"
+ )
);
}
}
@@ -243,42 +284,44 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
}
);
- private _serviceGroups = memoizeOne(
- (
- localize: LocalizeFunc,
- services: HomeAssistant["services"],
- manifests: DomainManifestLookup | undefined,
- type: "helper" | "other" | undefined
- ): ListItem[] => {
- if (!services || !manifests) {
- return [];
- }
- const result: ListItem[] = [];
- Object.keys(services).forEach((domain) => {
- const manifest = manifests[domain];
- if (
- (type === undefined &&
- manifest?.integration_type === "entity" &&
- !ENTITY_DOMAINS_OTHER.has(domain)) ||
- (type === "helper" && manifest?.integration_type === "helper") ||
- (type === "other" &&
- (ENTITY_DOMAINS_OTHER.has(domain) ||
- !["helper", "entity"].includes(manifest?.integration_type || "")))
- ) {
- result.push({
- group: true,
- icon: domainIcon(domain),
- key: `${SERVICE_PREFIX}${domain}`,
- name: domainToName(localize, domain, manifest),
- description: "",
- });
- }
- });
- return result.sort((a, b) =>
- stringCompare(a.name, b.name, this.hass.locale.language)
- );
+ private _serviceGroups = (
+ localize: LocalizeFunc,
+ services: HomeAssistant["services"],
+ manifests: DomainManifestLookup | undefined,
+ domains: Set | undefined,
+ type: "helper" | "other" | undefined
+ ): ListItem[] => {
+ if (!services || !manifests) {
+ return [];
}
- );
+ const result: ListItem[] = [];
+ Object.keys(services).forEach((domain) => {
+ const manifest = manifests[domain];
+ const domainUsed = !domains ? true : domains.has(domain);
+ if (
+ (type === undefined &&
+ manifest?.integration_type === "entity" &&
+ domainUsed &&
+ !ENTITY_DOMAINS_OTHER.has(domain)) ||
+ (type === "helper" && manifest?.integration_type === "helper") ||
+ (type === "other" &&
+ (ENTITY_DOMAINS_OTHER.has(domain) ||
+ (!domainUsed && manifest?.integration_type === "entity") ||
+ !["helper", "entity"].includes(manifest?.integration_type || "")))
+ ) {
+ result.push({
+ group: true,
+ icon: domainIcon(domain),
+ key: `${SERVICE_PREFIX}${domain}`,
+ name: domainToName(localize, domain, manifest),
+ description: "",
+ });
+ }
+ });
+ return result.sort((a, b) =>
+ stringCompare(a.name, b.name, this.hass.locale.language)
+ );
+ };
private _services = memoizeOne(
(
@@ -368,6 +411,19 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._height = boundingRect?.height;
}
+ protected willUpdate(changedProperties: PropertyValues): void {
+ if (
+ this._params?.type === "action" &&
+ changedProperties.has("hass") &&
+ changedProperties.get("hass")?.states !== this.hass.states
+ ) {
+ const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
+ if (!deepEqual(domains, this._domains)) {
+ this._domains = domains;
+ }
+ }
+ }
+
protected render() {
if (!this._params) {
return nothing;
@@ -376,6 +432,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const items = this._filter
? this._getFilteredItems(
this._params.type,
+ this._params.root,
this._group,
this._filter,
this.hass.localize,
@@ -384,7 +441,9 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
)
: this._getGroupItems(
this._params.type,
+ this._params.root,
this._group,
+ this._domains,
this.hass.localize,
this.hass.services,
this._manifests
@@ -562,6 +621,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
ha-icon-next {
width: 24px;
}
+ mwc-list {
+ max-height: 468px;
+ max-width: 100vw;
+ }
search-input {
display: block;
margin: 0 16px;
diff --git a/src/panels/config/automation/condition/ha-automation-condition.ts b/src/panels/config/automation/condition/ha-automation-condition.ts
index 27364b92a3ed..ecf4f8823770 100644
--- a/src/panels/config/automation/condition/ha-automation-condition.ts
+++ b/src/panels/config/automation/condition/ha-automation-condition.ts
@@ -203,6 +203,7 @@ export default class HaAutomationCondition extends LitElement {
showAddAutomationElementDialog(this, {
type: "condition",
add: this._addCondition,
+ root: !this.nested,
clipboardItem: this._clipboard?.condition?.condition,
});
}
diff --git a/src/panels/config/automation/condition/types/ha-automation-condition-device.ts b/src/panels/config/automation/condition/types/ha-automation-condition-device.ts
index 71568fe02c10..4593a5f70123 100644
--- a/src/panels/config/automation/condition/types/ha-automation-condition-device.ts
+++ b/src/panels/config/automation/condition/types/ha-automation-condition-device.ts
@@ -168,6 +168,7 @@ export class HaDeviceCondition extends LitElement {
}
ha-form {
+ display: block;
margin-top: 24px;
}
`;
diff --git a/src/panels/config/automation/show-add-automation-element-dialog.ts b/src/panels/config/automation/show-add-automation-element-dialog.ts
index c497ca85c620..55453505121d 100644
--- a/src/panels/config/automation/show-add-automation-element-dialog.ts
+++ b/src/panels/config/automation/show-add-automation-element-dialog.ts
@@ -6,6 +6,7 @@ export interface AddAutomationElementDialogParams {
type: "trigger" | "condition" | "action";
add: (key: string) => void;
clipboardItem: string | undefined;
+ root?: boolean;
group?: string;
}
const loadDialog = () => import("./add-automation-element-dialog");
diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts
index 8b3a63575220..1b94ff6138b2 100644
--- a/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts
+++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-device.ts
@@ -174,6 +174,7 @@ export class HaDeviceTrigger extends LitElement {
}
ha-form {
+ display: block;
margin-top: 24px;
}
`;
From c125ec087a11c0b584a85b10b6907cae764c9e73 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 16:08:26 +0100
Subject: [PATCH 031/361] Remove references to "service call" from actions
(#19226)
---
src/components/ha-service-control.ts | 28 ++++++++++++++-----
src/data/script.ts | 2 ++
src/data/script_i18n.ts | 5 +++-
.../action/ha-automation-action-row.ts | 10 ++++++-
.../automation/action/ha-automation-action.ts | 1 +
src/translations/en.json | 1 +
6 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/src/components/ha-service-control.ts b/src/components/ha-service-control.ts
index f1ae8ee54bac..119418355c64 100644
--- a/src/components/ha-service-control.ts
+++ b/src/components/ha-service-control.ts
@@ -4,7 +4,14 @@ import {
HassServices,
HassServiceTarget,
} from "home-assistant-js-websocket";
-import { css, CSSResultGroup, html, LitElement, PropertyValues } from "lit";
+import {
+ css,
+ CSSResultGroup,
+ html,
+ LitElement,
+ PropertyValues,
+ nothing,
+} from "lit";
import { customElement, property, query, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { ensureArray } from "../common/array/ensure-array";
@@ -83,6 +90,8 @@ export class HaServiceControl extends LitElement {
@property({ type: Boolean }) public showAdvanced?: boolean;
+ @property({ type: Boolean, reflect: true }) public hidePicker?: boolean;
+
@state() private _value!: this["value"];
@state() private _checkedKeys = new Set();
@@ -363,12 +372,14 @@ export class HaServiceControl extends LitElement {
)) ||
serviceData?.description;
- return html`
+ return html`${this.hidePicker
+ ? nothing
+ : html``}
${description ? html`
${description}
` : ""}
${this._manifest
@@ -735,6 +746,9 @@ export class HaServiceControl extends LitElement {
margin: var(--service-control-padding, 0 16px);
padding: 16px 0;
}
+ :host([hidePicker]) p {
+ padding-top: 0;
+ }
.checkbox-spacer {
width: 32px;
}
diff --git a/src/data/script.ts b/src/data/script.ts
index f0b5e7151b51..08910dc88fcb 100644
--- a/src/data/script.ts
+++ b/src/data/script.ts
@@ -52,6 +52,7 @@ export const serviceActionStruct: Describe
= assign(
target: optional(targetStruct),
data: optional(object()),
response_variable: optional(string()),
+ metadata: optional(object()),
})
);
@@ -133,6 +134,7 @@ export interface ServiceAction extends BaseAction {
target?: HassServiceTarget;
data?: Record;
response_variable?: string;
+ metadata?: Record;
}
export interface DeviceAction extends BaseAction {
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 4b07b84f0ed5..3d7d8c5a1da4 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -168,8 +168,11 @@ const tryDescribeAction = (
const service =
hass.localize(`component.${domain}.services.${serviceName}.name`) ||
hass.services[domain][serviceName]?.name;
+
return hass.localize(
- `${actionTranslationBaseKey}.service.description.service_based_on_name`,
+ `${actionTranslationBaseKey}.service.description.${
+ config.metadata ? "service_name" : "service_based_on_name"
+ }`,
{
name: service
? `${domainToName(hass.localize, domain)}: ${service}`
diff --git a/src/panels/config/automation/action/ha-automation-action-row.ts b/src/panels/config/automation/action/ha-automation-action-row.ts
index f09c901c8e1a..0e58c0e8b2b5 100644
--- a/src/panels/config/automation/action/ha-automation-action-row.ts
+++ b/src/panels/config/automation/action/ha-automation-action-row.ts
@@ -29,6 +29,8 @@ import { classMap } from "lit/directives/class-map";
import { storage } from "../../../../common/decorators/storage";
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
import { fireEvent } from "../../../../common/dom/fire_event";
+import { computeDomain } from "../../../../common/entity/compute_domain";
+import { domainIconWithoutDefault } from "../../../../common/entity/domain_icon";
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
import { handleStructError } from "../../../../common/structs/handle-errors";
import "../../../../components/ha-alert";
@@ -190,7 +192,13 @@ export default class HaAutomationActionRow extends LitElement {
${capitalizeFirstLetter(
describeAction(this.hass, this._entityReg, this.action)
diff --git a/src/panels/config/automation/action/ha-automation-action.ts b/src/panels/config/automation/action/ha-automation-action.ts
index dca4bab6acde..ce312a7bd399 100644
--- a/src/panels/config/automation/action/ha-automation-action.ts
+++ b/src/panels/config/automation/action/ha-automation-action.ts
@@ -191,6 +191,7 @@ export default class HaAutomationAction extends LitElement {
} else if (isService(action)) {
actions = this.actions.concat({
service: getService(action),
+ metadata: {},
});
} else {
const elClass = customElements.get(
diff --git a/src/translations/en.json b/src/translations/en.json
index c176cf65c96a..e771c8fe1910 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2914,6 +2914,7 @@
"description": {
"service_based_on_template": "Call a service based on a template on {targets}",
"service_based_on_name": "Call a service ''{name}'' on {targets}",
+ "service_name": "''{name}'' on {targets}",
"service": "Call a service",
"target_template": "templated {name}",
"target_unknown_entity": "unknown entity",
From f2226cdec24760fce2172978f97a07b609675372 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:11:34 +0100
Subject: [PATCH 032/361] Use brand icons in actions (#19227)
---
src/common/const.ts | 4 ++
.../add-automation-element-dialog.ts | 39 ++++++++++++++++---
2 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/src/common/const.ts b/src/common/const.ts
index 66c14e64e140..68f4fa97b1c1 100644
--- a/src/common/const.ts
+++ b/src/common/const.ts
@@ -29,6 +29,7 @@ import {
mdiFlash,
mdiFlower,
mdiFormatListBulleted,
+ mdiFormatListCheckbox,
mdiFormTextbox,
mdiGauge,
mdiGoogleAssistant,
@@ -64,6 +65,7 @@ import {
mdiTransmissionTower,
mdiWater,
mdiWaterPercent,
+ mdiWeatherPartlyCloudy,
mdiWeatherPouring,
mdiWeatherRainy,
mdiWeatherWindy,
@@ -128,6 +130,7 @@ export const FIXED_DOMAIN_ICONS = {
updater: mdiCloudUpload,
vacuum: mdiRobotVacuum,
wake_word: mdiChatSleep,
+ weather: mdiWeatherPartlyCloudy,
zone: mdiMapMarkerRadius,
};
@@ -166,6 +169,7 @@ export const FIXED_DEVICE_CLASS_ICONS = {
precipitation_intensity: mdiWeatherPouring,
pressure: mdiGauge,
reactive_power: mdiFlash,
+ shopping_List: mdiFormatListCheckbox,
signal_strength: mdiWifi,
sound_pressure: mdiEarHearing,
speed: mdiSpeedometer,
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 31760dca1bc1..0e930b7c9916 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -15,7 +15,7 @@ import { repeat } from "lit/directives/repeat";
import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../common/dom/fire_event";
-import { domainIcon } from "../../../common/entity/domain_icon";
+import { domainIconWithoutDefault } from "../../../common/entity/domain_icon";
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
import { stringCompare } from "../../../common/string/compare";
import { LocalizeFunc } from "../../../common/translations/localize";
@@ -45,6 +45,7 @@ import { TRIGGER_GROUPS, TRIGGER_ICONS } from "../../../data/trigger";
import { HassDialog } from "../../../dialogs/make-dialog-manager";
import { haStyle, haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
+import { brandsUrl } from "../../../util/brands-url";
import {
AddAutomationElementDialogParams,
PASTE_VALUE,
@@ -68,7 +69,8 @@ interface ListItem {
key: string;
name: string;
description: string;
- icon: string;
+ icon?: string;
+ image?: string;
group: boolean;
}
@@ -309,9 +311,17 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
(!domainUsed && manifest?.integration_type === "entity") ||
!["helper", "entity"].includes(manifest?.integration_type || "")))
) {
+ const icon = domainIconWithoutDefault(domain);
result.push({
group: true,
- icon: domainIcon(domain),
+ icon,
+ image: !icon
+ ? brandsUrl({
+ domain,
+ type: "icon",
+ darkOptimized: this.hass.themes?.darkMode,
+ })
+ : undefined,
key: `${SERVICE_PREFIX}${domain}`,
name: domainToName(localize, domain, manifest),
description: "",
@@ -345,9 +355,17 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const services_keys = Object.keys(services[dmn]);
for (const service of services_keys) {
+ const icon = domainIconWithoutDefault(dmn);
result.push({
group: false,
- icon: domainIcon(dmn),
+ icon,
+ image: !icon
+ ? brandsUrl({
+ domain: dmn,
+ type: "icon",
+ darkOptimized: this.hass.themes?.darkMode,
+ })
+ : undefined,
key: `${SERVICE_PREFIX}${dmn}.${service}`,
name: `${domain ? "" : `${domainToName(localize, dmn)}: `}${
this.hass.localize(`component.${dmn}.services.${service}.name`) ||
@@ -556,7 +574,18 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
>
${item.name}
${item.description}
-
+ ${item.icon
+ ? html``
+ : html``}
${item.group
? html``
: html`
Date: Tue, 2 Jan 2024 18:31:18 +0100
Subject: [PATCH 033/361] Change format of service description (#19229)
---
src/data/script_i18n.ts | 15 ++++++++++++---
src/translations/en.json | 2 +-
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/src/data/script_i18n.ts b/src/data/script_i18n.ts
index 3d7d8c5a1da4..40c823bc862f 100644
--- a/src/data/script_i18n.ts
+++ b/src/data/script_i18n.ts
@@ -169,10 +169,19 @@ const tryDescribeAction = (
hass.localize(`component.${domain}.services.${serviceName}.name`) ||
hass.services[domain][serviceName]?.name;
+ if (config.metadata) {
+ return hass.localize(
+ `${actionTranslationBaseKey}.service.description.service_name`,
+ {
+ domain: domainToName(hass.localize, domain),
+ name: service || config.service,
+ targets: formatListWithAnds(hass.locale, targets),
+ }
+ );
+ }
+
return hass.localize(
- `${actionTranslationBaseKey}.service.description.${
- config.metadata ? "service_name" : "service_based_on_name"
- }`,
+ `${actionTranslationBaseKey}.service.description.service_based_on_name`,
{
name: service
? `${domainToName(hass.localize, domain)}: ${service}`
diff --git a/src/translations/en.json b/src/translations/en.json
index e771c8fe1910..6ef41c81c129 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2914,7 +2914,7 @@
"description": {
"service_based_on_template": "Call a service based on a template on {targets}",
"service_based_on_name": "Call a service ''{name}'' on {targets}",
- "service_name": "''{name}'' on {targets}",
+ "service_name": "{domain} ''{name}'' on {targets}",
"service": "Call a service",
"target_template": "templated {name}",
"target_unknown_entity": "unknown entity",
From 18b5fd59a629268bce2d5d7aa6e7fd390e1d6ab1 Mon Sep 17 00:00:00 2001
From: Josh McCarty
Date: Tue, 2 Jan 2024 10:35:08 -0700
Subject: [PATCH 034/361] Add missing device classes for
entity-registry-settings-editor (#19231)
* Add connectivity device class for binary sensors
* Add update device class
* Separate connectivity and update
---
src/panels/config/entities/entity-registry-settings-editor.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/panels/config/entities/entity-registry-settings-editor.ts b/src/panels/config/entities/entity-registry-settings-editor.ts
index 14d88e12afc7..9e7213e41475 100644
--- a/src/panels/config/entities/entity-registry-settings-editor.ts
+++ b/src/panels/config/entities/entity-registry-settings-editor.ts
@@ -118,6 +118,8 @@ const OVERRIDE_DEVICE_CLASSES = {
"carbon_monoxide",
"moisture",
], // Alarm
+ ["connectivity"], // Connectivity
+ ["update"], // Update
],
};
From 01bd88ce101c1c0909c093d55afdaab1cd24073d Mon Sep 17 00:00:00 2001
From: JLo
Date: Tue, 2 Jan 2024 18:39:55 +0100
Subject: [PATCH 035/361] New copy for device trigger in automation editor
(#19232)
New copy for device trigger in automation editor:
"Set of conditions provided by your device. Great way to start."
---
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 6ef41c81c129..53306cd8b77d 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2760,7 +2760,7 @@
"preset_mode": "Preset mode"
},
"description": {
- "picker": "If a device is in a certain state. Great way to start."
+ "picker": "Set of conditions provided by your device. Great way to start."
}
},
"not": {
From f994b378f1be438ae46730412b1cc6109ee71490 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:47:39 +0100
Subject: [PATCH 036/361] Update add-automation-element-dialog.ts
---
src/panels/config/automation/add-automation-element-dialog.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 0e930b7c9916..d498e8375cd8 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -528,7 +528,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
rootTabbable
style=${styleMap({
width: this._width ? `${this._width}px` : "auto",
- height: this._height ? `${Math.min(468, this._height)}px` : "auto",
+ height: this._height ? `${Math.min(670, this._height)}px` : "auto",
})}
>
${this._params.clipboardItem &&
@@ -651,7 +651,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
width: 24px;
}
mwc-list {
- max-height: 468px;
+ max-height: 670px;
max-width: 100vw;
}
search-input {
From 8d496e1511c0ed56116da4829141239ef92e0423 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:47:39 +0100
Subject: [PATCH 037/361] Update add-automation-element-dialog.ts
---
src/panels/config/automation/add-automation-element-dialog.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 0e930b7c9916..d498e8375cd8 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -528,7 +528,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
rootTabbable
style=${styleMap({
width: this._width ? `${this._width}px` : "auto",
- height: this._height ? `${Math.min(468, this._height)}px` : "auto",
+ height: this._height ? `${Math.min(670, this._height)}px` : "auto",
})}
>
${this._params.clipboardItem &&
@@ -651,7 +651,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
width: 24px;
}
mwc-list {
- max-height: 468px;
+ max-height: 670px;
max-width: 100vw;
}
search-input {
From 5eaa6dafd902b2abdce044bb67fe772ad36cd573 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:48:34 +0100
Subject: [PATCH 038/361] Give todo and calendar edit static header (#19233)
---
src/panels/calendar/dialog-calendar-event-editor.ts | 6 +++---
src/panels/todo/dialog-todo-item-editor.ts | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/panels/calendar/dialog-calendar-event-editor.ts b/src/panels/calendar/dialog-calendar-event-editor.ts
index 7c06cac92cf1..e5925b1243e2 100644
--- a/src/panels/calendar/dialog-calendar-event-editor.ts
+++ b/src/panels/calendar/dialog-calendar-event-editor.ts
@@ -144,9 +144,9 @@ class DialogCalendarEventEditor extends LitElement {
escapeKeyAction
.heading=${createCloseHeading(
this.hass,
- isCreate
- ? this.hass.localize("ui.components.calendar.event.add")
- : this._summary
+ this.hass.localize(
+ `ui.components.calendar.event.${isCreate ? "add" : "edit"}`
+ )
)}
>
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index c81b9e4dbec3..cd26ad35fc28 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -101,9 +101,9 @@ class DialogTodoItemEditor extends LitElement {
scrimClickAction
.heading=${createCloseHeading(
this.hass,
- isCreate
- ? this.hass.localize("ui.components.todo.item.add")
- : this._summary
+ this.hass.localize(
+ `ui.components.todo.item.${isCreate ? "add" : "edit"}`
+ )
)}
>
From de3b9a5bb2a847cc7353ec9e960a83363b57ba25 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:48:34 +0100
Subject: [PATCH 039/361] Give todo and calendar edit static header (#19233)
---
src/panels/calendar/dialog-calendar-event-editor.ts | 6 +++---
src/panels/todo/dialog-todo-item-editor.ts | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/panels/calendar/dialog-calendar-event-editor.ts b/src/panels/calendar/dialog-calendar-event-editor.ts
index 7c06cac92cf1..e5925b1243e2 100644
--- a/src/panels/calendar/dialog-calendar-event-editor.ts
+++ b/src/panels/calendar/dialog-calendar-event-editor.ts
@@ -144,9 +144,9 @@ class DialogCalendarEventEditor extends LitElement {
escapeKeyAction
.heading=${createCloseHeading(
this.hass,
- isCreate
- ? this.hass.localize("ui.components.calendar.event.add")
- : this._summary
+ this.hass.localize(
+ `ui.components.calendar.event.${isCreate ? "add" : "edit"}`
+ )
)}
>
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index c81b9e4dbec3..cd26ad35fc28 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -101,9 +101,9 @@ class DialogTodoItemEditor extends LitElement {
scrimClickAction
.heading=${createCloseHeading(
this.hass,
- isCreate
- ? this.hass.localize("ui.components.todo.item.add")
- : this._summary
+ this.hass.localize(
+ `ui.components.todo.item.${isCreate ? "add" : "edit"}`
+ )
)}
>
From 7d412a9913defcf67b59d04ea49c7eebf497d745 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:49:31 +0100
Subject: [PATCH 040/361] Bumped version to 20240102.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index d1e5abd3d1c4..7d09a1121ede 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240101.0"
+version = "20240102.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 53dedc6c6587b2eeb9f76b53f55ccb5129e99612 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 18:49:31 +0100
Subject: [PATCH 041/361] Bumped version to 20240102.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index d1e5abd3d1c4..7d09a1121ede 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240101.0"
+version = "20240102.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 2933d642edfb5250b140e8154d6ff15eccf4f902 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 2 Jan 2024 13:55:44 -0500
Subject: [PATCH 042/361] Update dependency @bundle-stats/plugin-webpack-filter
to v4.8.4 (#19230)
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 7b3ad9c6a114..663a412014d2 100644
--- a/package.json
+++ b/package.json
@@ -156,7 +156,7 @@
"@babel/plugin-transform-runtime": "7.23.7",
"@babel/preset-env": "7.23.7",
"@babel/preset-typescript": "7.23.3",
- "@bundle-stats/plugin-webpack-filter": "4.8.3",
+ "@bundle-stats/plugin-webpack-filter": "4.8.4",
"@koa/cors": "5.0.0",
"@lokalise/node-api": "12.1.0",
"@octokit/auth-oauth-device": "6.0.1",
diff --git a/yarn.lock b/yarn.lock
index dd2a90537271..2f9b96e6b6ef 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1448,12 +1448,12 @@ __metadata:
languageName: node
linkType: hard
-"@bundle-stats/plugin-webpack-filter@npm:4.8.3":
- version: 4.8.3
- resolution: "@bundle-stats/plugin-webpack-filter@npm:4.8.3"
+"@bundle-stats/plugin-webpack-filter@npm:4.8.4":
+ version: 4.8.4
+ resolution: "@bundle-stats/plugin-webpack-filter@npm:4.8.4"
peerDependencies:
core-js: ^3.0.0
- checksum: a832be786197b0cd534e4ccb35cd7230f322b2b77697f5f4ac0b098e51f7867bff0364020f6015d31f2963619e1408933454841baac035452a9fec37d921f841
+ checksum: 7a33a19094fb32579ca215cfee7c536a7e524558e6a17bee0376377691b4957bd1346531dfe3b01e8daf364acef75e1926f3d1aed76d986be79ba374157782fb
languageName: node
linkType: hard
@@ -9519,7 +9519,7 @@ __metadata:
"@babel/preset-typescript": "npm:7.23.3"
"@babel/runtime": "npm:7.23.7"
"@braintree/sanitize-url": "npm:7.0.0"
- "@bundle-stats/plugin-webpack-filter": "npm:4.8.3"
+ "@bundle-stats/plugin-webpack-filter": "npm:4.8.4"
"@codemirror/autocomplete": "npm:6.11.1"
"@codemirror/commands": "npm:6.3.2"
"@codemirror/language": "npm:6.9.3"
From e72148175725b29a28dc216fd3eeb4d28c11729b Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 19:58:37 +0100
Subject: [PATCH 043/361] Move notification services to main list (#19235)
---
.../config/automation/add-automation-element-dialog.ts | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index d498e8375cd8..06a77884f1c6 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -90,6 +90,8 @@ const ENTITY_DOMAINS_OTHER = new Set([
"image_processing",
]);
+const ENTITY_DOMAINS_MAIN = new Set(["notify"]);
+
@customElement("add-automation-element-dialog")
class DialogAddAutomationElement extends LitElement implements HassDialog {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -302,11 +304,13 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const domainUsed = !domains ? true : domains.has(domain);
if (
(type === undefined &&
- manifest?.integration_type === "entity" &&
- domainUsed &&
- !ENTITY_DOMAINS_OTHER.has(domain)) ||
+ (ENTITY_DOMAINS_MAIN.has(domain) ||
+ (manifest?.integration_type === "entity" &&
+ domainUsed &&
+ !ENTITY_DOMAINS_OTHER.has(domain)))) ||
(type === "helper" && manifest?.integration_type === "helper") ||
(type === "other" &&
+ !ENTITY_DOMAINS_MAIN.has(domain) &&
(ENTITY_DOMAINS_OTHER.has(domain) ||
(!domainUsed && manifest?.integration_type === "entity") ||
!["helper", "entity"].includes(manifest?.integration_type || "")))
From 8a8b04ed004a3927ead29d5b80e7689d8f73951f Mon Sep 17 00:00:00 2001
From: Simon Lamon <32477463+silamon@users.noreply.github.com>
Date: Tue, 2 Jan 2024 20:00:19 +0100
Subject: [PATCH 044/361] Set default values for required and disabled for
labeled slider (#19246)
Set default values
---
src/components/ha-labeled-slider.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/ha-labeled-slider.ts b/src/components/ha-labeled-slider.ts
index 366eb4f5555c..5faf7a8b96b2 100644
--- a/src/components/ha-labeled-slider.ts
+++ b/src/components/ha-labeled-slider.ts
@@ -10,9 +10,9 @@ class HaLabeledSlider extends LitElement {
@property() public caption?: string;
- @property() public disabled?: boolean;
+ @property({ type: Boolean }) public disabled = false;
- @property() public required?: boolean;
+ @property({ type: Boolean }) public required = true;
@property() public min: number = 0;
From 7354988ec96e1abf1e96dc4df755cf4ea0c4e599 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Tue, 2 Jan 2024 19:58:37 +0100
Subject: [PATCH 045/361] Move notification services to main list (#19235)
---
.../config/automation/add-automation-element-dialog.ts | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index d498e8375cd8..06a77884f1c6 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -90,6 +90,8 @@ const ENTITY_DOMAINS_OTHER = new Set([
"image_processing",
]);
+const ENTITY_DOMAINS_MAIN = new Set(["notify"]);
+
@customElement("add-automation-element-dialog")
class DialogAddAutomationElement extends LitElement implements HassDialog {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -302,11 +304,13 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const domainUsed = !domains ? true : domains.has(domain);
if (
(type === undefined &&
- manifest?.integration_type === "entity" &&
- domainUsed &&
- !ENTITY_DOMAINS_OTHER.has(domain)) ||
+ (ENTITY_DOMAINS_MAIN.has(domain) ||
+ (manifest?.integration_type === "entity" &&
+ domainUsed &&
+ !ENTITY_DOMAINS_OTHER.has(domain)))) ||
(type === "helper" && manifest?.integration_type === "helper") ||
(type === "other" &&
+ !ENTITY_DOMAINS_MAIN.has(domain) &&
(ENTITY_DOMAINS_OTHER.has(domain) ||
(!domainUsed && manifest?.integration_type === "entity") ||
!["helper", "entity"].includes(manifest?.integration_type || "")))
From c2f3e43ee50fcabd26254ebd3412217b6f49a045 Mon Sep 17 00:00:00 2001
From: Simon Lamon <32477463+silamon@users.noreply.github.com>
Date: Tue, 2 Jan 2024 20:00:19 +0100
Subject: [PATCH 046/361] Set default values for required and disabled for
labeled slider (#19246)
Set default values
---
src/components/ha-labeled-slider.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/ha-labeled-slider.ts b/src/components/ha-labeled-slider.ts
index 366eb4f5555c..5faf7a8b96b2 100644
--- a/src/components/ha-labeled-slider.ts
+++ b/src/components/ha-labeled-slider.ts
@@ -10,9 +10,9 @@ class HaLabeledSlider extends LitElement {
@property() public caption?: string;
- @property() public disabled?: boolean;
+ @property({ type: Boolean }) public disabled = false;
- @property() public required?: boolean;
+ @property({ type: Boolean }) public required = true;
@property() public min: number = 0;
From 46565715c9fb46273d22292c7cc245b0b69dd12e Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 10:37:30 +0100
Subject: [PATCH 047/361] Calculate used domains on open of action dialog
(#19255)
---
.../automation/add-automation-element-dialog.ts | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 06a77884f1c6..f8be65baf183 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -122,6 +122,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
if (this._params?.type === "action") {
this.hass.loadBackendTranslation("services");
this._fetchManifests();
+ this._calculateUsedDomains();
}
this._fullScreen = matchMedia(
"all and (max-width: 450px), all and (max-height: 500px)"
@@ -425,6 +426,13 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._manifests = manifests;
}
+ private _calculateUsedDomains() {
+ const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
+ if (!deepEqual(domains, this._domains)) {
+ this._domains = domains;
+ }
+ }
+
protected _opened(): void {
// Store the width and height so that when we search, box doesn't jump
const boundingRect =
@@ -439,10 +447,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
changedProperties.has("hass") &&
changedProperties.get("hass")?.states !== this.hass.states
) {
- const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
- if (!deepEqual(domains, this._domains)) {
- this._domains = domains;
- }
+ this._calculateUsedDomains();
}
}
From c7a98fa5a1f25b283dfcff91ef4efb4a697372e9 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 10:37:59 +0100
Subject: [PATCH 048/361] Bumped version to 20240103.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 7d09a1121ede..f43e4cf0dc55 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240102.0"
+version = "20240103.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 8ee4aa9e634a2f391b4aa51f2a9cfeb116ce77d8 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 10:37:59 +0100
Subject: [PATCH 049/361] Bumped version to 20240103.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 7d09a1121ede..f43e4cf0dc55 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240102.0"
+version = "20240103.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 6e7366bf690f500f9cfa4f81aefd002c822dc9ed Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 10:37:30 +0100
Subject: [PATCH 050/361] Calculate used domains on open of action dialog
(#19255)
---
.../automation/add-automation-element-dialog.ts | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index 06a77884f1c6..f8be65baf183 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -122,6 +122,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
if (this._params?.type === "action") {
this.hass.loadBackendTranslation("services");
this._fetchManifests();
+ this._calculateUsedDomains();
}
this._fullScreen = matchMedia(
"all and (max-width: 450px), all and (max-height: 500px)"
@@ -425,6 +426,13 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._manifests = manifests;
}
+ private _calculateUsedDomains() {
+ const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
+ if (!deepEqual(domains, this._domains)) {
+ this._domains = domains;
+ }
+ }
+
protected _opened(): void {
// Store the width and height so that when we search, box doesn't jump
const boundingRect =
@@ -439,10 +447,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
changedProperties.has("hass") &&
changedProperties.get("hass")?.states !== this.hass.states
) {
- const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
- if (!deepEqual(domains, this._domains)) {
- this._domains = domains;
- }
+ this._calculateUsedDomains();
}
}
From 29fefa1d602c2c1912a2e02afbaed9f80010cca9 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 12:20:11 +0100
Subject: [PATCH 051/361] Revert conditional rendering of condition (#19257)
* Fix conditionally showing `triggered by`
* revert conditional rendering
* Update add-automation-element-dialog.ts
* Update add-automation-element-dialog.ts
---
src/data/condition.ts | 1 +
.../add-automation-element-dialog.ts | 43 ++++++++-----------
.../condition/ha-automation-condition.ts | 1 -
.../show-add-automation-element-dialog.ts | 1 -
4 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/src/data/condition.ts b/src/data/condition.ts
index d8c7af44fecc..44a0e218609c 100644
--- a/src/data/condition.ts
+++ b/src/data/condition.ts
@@ -46,6 +46,7 @@ export const CONDITION_GROUPS: AutomationElementGroup = {
icon: mdiDotsHorizontal,
members: {
template: {},
+ trigger: {},
},
},
} as const;
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index f8be65baf183..cf5874f80cd8 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -143,6 +143,16 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._domains = undefined;
}
+ private _getGroups = (
+ type: AddAutomationElementDialogParams["type"],
+ group: string | undefined
+ ): AutomationElementGroup =>
+ group
+ ? isService(group)
+ ? {}
+ : TYPES[type].groups[group].members!
+ : TYPES[type].groups;
+
private _convertToItem = (
key: string,
options,
@@ -169,22 +179,13 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getFilteredItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
- root: AddAutomationElementDialogParams["root"],
group: string | undefined,
filter: string,
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests?: DomainManifestLookup
): ListItem[] => {
- const groups: AutomationElementGroup = group
- ? isService(group)
- ? {}
- : TYPES[type].groups[group].members!
- : TYPES[type].groups;
-
- if (type === "condition" && group === "other" && !root) {
- groups.trigger = {};
- }
+ const groups = this._getGroups(type, group);
const flattenGroups = (grp: AutomationElementGroup) =>
Object.entries(grp).map(([key, options]) =>
@@ -213,7 +214,6 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getGroupItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
- root: AddAutomationElementDialogParams["root"],
group: string | undefined,
domains: Set | undefined,
localize: LocalizeFunc,
@@ -221,20 +221,17 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
manifests?: DomainManifestLookup
): ListItem[] => {
if (type === "action" && isService(group)) {
- const result = this._services(localize, services, manifests, group);
+ let result = this._services(localize, services, manifests, group);
if (group === `${SERVICE_PREFIX}media_player`) {
- result.unshift(this._convertToItem("play_media", {}, type, localize));
+ result = [
+ this._convertToItem("play_media", {}, type, localize),
+ ...result,
+ ];
}
return result;
}
- const groups: AutomationElementGroup = group
- ? TYPES[type].groups[group].members!
- : TYPES[type].groups;
-
- if (type === "condition" && group === "other" && !root) {
- groups.trigger = {};
- }
+ const groups = this._getGroups(type, group);
const result = Object.entries(groups).map(([key, options]) =>
this._convertToItem(key, options, type, localize)
@@ -459,7 +456,6 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const items = this._filter
? this._getFilteredItems(
this._params.type,
- this._params.root,
this._group,
this._filter,
this.hass.localize,
@@ -468,7 +464,6 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
)
: this._getGroupItems(
this._params.type,
- this._params.root,
this._group,
this._domains,
this.hass.localize,
@@ -537,7 +532,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
rootTabbable
style=${styleMap({
width: this._width ? `${this._width}px` : "auto",
- height: this._height ? `${Math.min(670, this._height)}px` : "auto",
+ height: this._height ? `${Math.min(468, this._height)}px` : "auto",
})}
>
${this._params.clipboardItem &&
@@ -660,7 +655,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
width: 24px;
}
mwc-list {
- max-height: 670px;
+ max-height: 468px;
max-width: 100vw;
}
search-input {
diff --git a/src/panels/config/automation/condition/ha-automation-condition.ts b/src/panels/config/automation/condition/ha-automation-condition.ts
index ecf4f8823770..27364b92a3ed 100644
--- a/src/panels/config/automation/condition/ha-automation-condition.ts
+++ b/src/panels/config/automation/condition/ha-automation-condition.ts
@@ -203,7 +203,6 @@ export default class HaAutomationCondition extends LitElement {
showAddAutomationElementDialog(this, {
type: "condition",
add: this._addCondition,
- root: !this.nested,
clipboardItem: this._clipboard?.condition?.condition,
});
}
diff --git a/src/panels/config/automation/show-add-automation-element-dialog.ts b/src/panels/config/automation/show-add-automation-element-dialog.ts
index 55453505121d..c497ca85c620 100644
--- a/src/panels/config/automation/show-add-automation-element-dialog.ts
+++ b/src/panels/config/automation/show-add-automation-element-dialog.ts
@@ -6,7 +6,6 @@ export interface AddAutomationElementDialogParams {
type: "trigger" | "condition" | "action";
add: (key: string) => void;
clipboardItem: string | undefined;
- root?: boolean;
group?: string;
}
const loadDialog = () => import("./add-automation-element-dialog");
From 6224cb69941b22c3b14ee6b622d338460cd85623 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 12:28:46 +0100
Subject: [PATCH 052/361] Bumped version to 20240103.1
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index f43e4cf0dc55..570bc96eaf74 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.0"
+version = "20240103.1"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From c9a0ae6e2d35488304c5ad0a62b528e4c64fe615 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 12:28:46 +0100
Subject: [PATCH 053/361] Bumped version to 20240103.1
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index f43e4cf0dc55..570bc96eaf74 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.0"
+version = "20240103.1"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 336214d97f3715a866988a257edf939ec37b25d5 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 12:20:11 +0100
Subject: [PATCH 054/361] Revert conditional rendering of condition (#19257)
* Fix conditionally showing `triggered by`
* revert conditional rendering
* Update add-automation-element-dialog.ts
* Update add-automation-element-dialog.ts
---
src/data/condition.ts | 1 +
.../add-automation-element-dialog.ts | 43 ++++++++-----------
.../condition/ha-automation-condition.ts | 1 -
.../show-add-automation-element-dialog.ts | 1 -
4 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/src/data/condition.ts b/src/data/condition.ts
index d8c7af44fecc..44a0e218609c 100644
--- a/src/data/condition.ts
+++ b/src/data/condition.ts
@@ -46,6 +46,7 @@ export const CONDITION_GROUPS: AutomationElementGroup = {
icon: mdiDotsHorizontal,
members: {
template: {},
+ trigger: {},
},
},
} as const;
diff --git a/src/panels/config/automation/add-automation-element-dialog.ts b/src/panels/config/automation/add-automation-element-dialog.ts
index f8be65baf183..cf5874f80cd8 100644
--- a/src/panels/config/automation/add-automation-element-dialog.ts
+++ b/src/panels/config/automation/add-automation-element-dialog.ts
@@ -143,6 +143,16 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._domains = undefined;
}
+ private _getGroups = (
+ type: AddAutomationElementDialogParams["type"],
+ group: string | undefined
+ ): AutomationElementGroup =>
+ group
+ ? isService(group)
+ ? {}
+ : TYPES[type].groups[group].members!
+ : TYPES[type].groups;
+
private _convertToItem = (
key: string,
options,
@@ -169,22 +179,13 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getFilteredItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
- root: AddAutomationElementDialogParams["root"],
group: string | undefined,
filter: string,
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests?: DomainManifestLookup
): ListItem[] => {
- const groups: AutomationElementGroup = group
- ? isService(group)
- ? {}
- : TYPES[type].groups[group].members!
- : TYPES[type].groups;
-
- if (type === "condition" && group === "other" && !root) {
- groups.trigger = {};
- }
+ const groups = this._getGroups(type, group);
const flattenGroups = (grp: AutomationElementGroup) =>
Object.entries(grp).map(([key, options]) =>
@@ -213,7 +214,6 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getGroupItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
- root: AddAutomationElementDialogParams["root"],
group: string | undefined,
domains: Set | undefined,
localize: LocalizeFunc,
@@ -221,20 +221,17 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
manifests?: DomainManifestLookup
): ListItem[] => {
if (type === "action" && isService(group)) {
- const result = this._services(localize, services, manifests, group);
+ let result = this._services(localize, services, manifests, group);
if (group === `${SERVICE_PREFIX}media_player`) {
- result.unshift(this._convertToItem("play_media", {}, type, localize));
+ result = [
+ this._convertToItem("play_media", {}, type, localize),
+ ...result,
+ ];
}
return result;
}
- const groups: AutomationElementGroup = group
- ? TYPES[type].groups[group].members!
- : TYPES[type].groups;
-
- if (type === "condition" && group === "other" && !root) {
- groups.trigger = {};
- }
+ const groups = this._getGroups(type, group);
const result = Object.entries(groups).map(([key, options]) =>
this._convertToItem(key, options, type, localize)
@@ -459,7 +456,6 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const items = this._filter
? this._getFilteredItems(
this._params.type,
- this._params.root,
this._group,
this._filter,
this.hass.localize,
@@ -468,7 +464,6 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
)
: this._getGroupItems(
this._params.type,
- this._params.root,
this._group,
this._domains,
this.hass.localize,
@@ -537,7 +532,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
rootTabbable
style=${styleMap({
width: this._width ? `${this._width}px` : "auto",
- height: this._height ? `${Math.min(670, this._height)}px` : "auto",
+ height: this._height ? `${Math.min(468, this._height)}px` : "auto",
})}
>
${this._params.clipboardItem &&
@@ -660,7 +655,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
width: 24px;
}
mwc-list {
- max-height: 670px;
+ max-height: 468px;
max-width: 100vw;
}
search-input {
diff --git a/src/panels/config/automation/condition/ha-automation-condition.ts b/src/panels/config/automation/condition/ha-automation-condition.ts
index ecf4f8823770..27364b92a3ed 100644
--- a/src/panels/config/automation/condition/ha-automation-condition.ts
+++ b/src/panels/config/automation/condition/ha-automation-condition.ts
@@ -203,7 +203,6 @@ export default class HaAutomationCondition extends LitElement {
showAddAutomationElementDialog(this, {
type: "condition",
add: this._addCondition,
- root: !this.nested,
clipboardItem: this._clipboard?.condition?.condition,
});
}
diff --git a/src/panels/config/automation/show-add-automation-element-dialog.ts b/src/panels/config/automation/show-add-automation-element-dialog.ts
index 55453505121d..c497ca85c620 100644
--- a/src/panels/config/automation/show-add-automation-element-dialog.ts
+++ b/src/panels/config/automation/show-add-automation-element-dialog.ts
@@ -6,7 +6,6 @@ export interface AddAutomationElementDialogParams {
type: "trigger" | "condition" | "action";
add: (key: string) => void;
clipboardItem: string | undefined;
- root?: boolean;
group?: string;
}
const loadDialog = () => import("./add-automation-element-dialog");
From acbb7e0453e20da93e536aa5c5d8d122cdfdb46e Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Wed, 3 Jan 2024 14:26:40 +0100
Subject: [PATCH 055/361] Display edit button for climate fan mode feature
(#19259)
---
.../lovelace/editor/config-elements/hui-card-features-editor.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts b/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts
index 49290ba57102..8693be890d8d 100644
--- a/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts
@@ -81,6 +81,7 @@ const EDITABLES_FEATURE_TYPES = new Set([
"humidifier-modes",
"water-heater-operation-modes",
"lawn-mower-commands",
+ "climate-fan-modes",
"climate-preset-modes",
"numeric-input",
"update-actions",
From 8368fb44081a20a78f01ce76b770bdbb0bb1a826 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 14:58:36 +0100
Subject: [PATCH 056/361] Fix checking todo item that dont support due date
(#19262)
* Fix checking todo item that dont support due date
* make cleaner
* Revert "make cleaner"
This reverts commit fa33b3361451dd334d9f69142f9754a1ea2c1ca4.
* Update dialog-todo-item-editor.ts
* do check in 1 place
---
src/data/todo.ts | 12 +++++++++---
src/panels/lovelace/cards/hui-todo-list-card.ts | 3 ++-
src/panels/todo/dialog-todo-item-editor.ts | 12 +++++++++---
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/src/data/todo.ts b/src/data/todo.ts
index 9af8ef0f4cc6..659c8d0c3c24 100644
--- a/src/data/todo.ts
+++ b/src/data/todo.ts
@@ -83,9 +83,12 @@ export const updateItem = (
item: item.uid,
rename: item.summary,
status: item.status,
- description: item.description || null,
+ description: item.description,
due_datetime: item.due?.includes("T") ? item.due : undefined,
- due_date: item.due?.includes("T") ? undefined : item.due || null,
+ due_date:
+ item.due === undefined || item.due?.includes("T")
+ ? undefined
+ : item.due,
},
{ entity_id }
);
@@ -102,7 +105,10 @@ export const createItem = (
item: item.summary,
description: item.description || undefined,
due_datetime: item.due?.includes("T") ? item.due : undefined,
- due_date: item.due?.includes("T") ? undefined : item.due,
+ due_date:
+ item.due === undefined || item.due?.includes("T")
+ ? undefined
+ : item.due,
},
{ entity_id }
);
diff --git a/src/panels/lovelace/cards/hui-todo-list-card.ts b/src/panels/lovelace/cards/hui-todo-list-card.ts
index 3352f7a42b43..d1d62880f8ed 100644
--- a/src/panels/lovelace/cards/hui-todo-list-card.ts
+++ b/src/panels/lovelace/cards/hui-todo-list-card.ts
@@ -476,7 +476,8 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
return;
}
await updateItem(this.hass!, this._entityId!, {
- ...item,
+ uid: item.uid,
+ summary: item.summary,
status:
item.status === TodoItemStatus.NeedsAction
? TodoItemStatus.Completed
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index cd26ad35fc28..daa5eff68627 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -324,14 +324,20 @@ class DialogTodoItemEditor extends LitElement {
(this._todoListSupportsFeature(
TodoListEntityFeature.SET_DESCRIPTION_ON_ITEM
)
- ? // backend should accept null to clear the field, but it doesn't now
- null
+ ? null
: undefined),
due: this._due
? this._hasTime
? this._due.toISOString()
: this._formatDate(this._due)
- : null,
+ : this._todoListSupportsFeature(
+ TodoListEntityFeature.SET_DUE_DATETIME_ON_ITEM
+ ) ||
+ this._todoListSupportsFeature(
+ TodoListEntityFeature.SET_DUE_DATE_ON_ITEM
+ )
+ ? null
+ : undefined,
status: this._checked
? TodoItemStatus.Completed
: TodoItemStatus.NeedsAction,
From 41bb677ebe86531e76b4aca5610bc56727c477fc Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Wed, 3 Jan 2024 05:58:59 -0800
Subject: [PATCH 057/361] Remove tile pointer/ripple/index when it has no
action (#19137)
* Remove tile pointer/ripple/index when it has no action
* update
* Apply suggestions from code review
Co-authored-by: Paul Bottein
---------
Co-authored-by: Paul Bottein
---
src/panels/lovelace/cards/hui-tile-card.ts | 27 ++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts
index 1c06426d1acb..b3470aeed569 100644
--- a/src/panels/lovelace/cards/hui-tile-card.ts
+++ b/src/panels/lovelace/cards/hui-tile-card.ts
@@ -287,21 +287,40 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
@eventOptions({ passive: true })
private handleRippleActivate(evt?: Event) {
+ if (!this.hasCardAction) return;
this._rippleHandlers.startPress(evt);
}
private handleRippleDeactivate() {
+ if (!this.hasCardAction) return;
this._rippleHandlers.endPress();
}
private handleRippleMouseEnter() {
+ if (!this.hasCardAction) return;
this._rippleHandlers.startHover();
}
private handleRippleMouseLeave() {
+ if (!this.hasCardAction) return;
this._rippleHandlers.endHover();
}
+ get hasCardAction() {
+ return (
+ !this._config?.tap_action ||
+ hasAction(this._config?.tap_action) ||
+ hasAction(this._config?.hold_action) ||
+ hasAction(this._config?.double_tap_action)
+ );
+ }
+
+ get hasIconAction() {
+ return (
+ !this._config?.icon_tap_action || hasAction(this._config?.icon_tap_action)
+ );
+ }
+
protected render() {
if (!this._config || !this.hass) {
return nothing;
@@ -368,8 +387,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
hasHold: hasAction(this._config!.hold_action),
hasDoubleClick: hasAction(this._config!.double_tap_action),
})}
- role="button"
- tabindex="0"
+ role=${ifDefined(this.hasCardAction ? "button" : undefined)}
+ tabindex=${ifDefined(this.hasCardAction ? "0" : undefined)}
aria-labelledby="info"
@mousedown=${this.handleRippleActivate}
@mouseup=${this.handleRippleDeactivate}
@@ -386,8 +405,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
From 6929a9c6037b987a1ede770625ad4ef290b47fb2 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 14:59:45 +0100
Subject: [PATCH 058/361] Bumped version to 20240103.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 570bc96eaf74..f43e4cf0dc55 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.1"
+version = "20240103.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From ae0eac3415f9df2cbab002c1f09742f0ee70c573 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 14:59:45 +0100
Subject: [PATCH 059/361] Bumped version to 20240103.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index 570bc96eaf74..f43e4cf0dc55 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.1"
+version = "20240103.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 22929672a069db25a0a94f230c8c9f57ac0afdd7 Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Wed, 3 Jan 2024 05:58:59 -0800
Subject: [PATCH 060/361] Remove tile pointer/ripple/index when it has no
action (#19137)
* Remove tile pointer/ripple/index when it has no action
* update
* Apply suggestions from code review
Co-authored-by: Paul Bottein
---------
Co-authored-by: Paul Bottein
---
src/panels/lovelace/cards/hui-tile-card.ts | 27 ++++++++++++++++++----
1 file changed, 23 insertions(+), 4 deletions(-)
diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts
index 1c06426d1acb..b3470aeed569 100644
--- a/src/panels/lovelace/cards/hui-tile-card.ts
+++ b/src/panels/lovelace/cards/hui-tile-card.ts
@@ -287,21 +287,40 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
@eventOptions({ passive: true })
private handleRippleActivate(evt?: Event) {
+ if (!this.hasCardAction) return;
this._rippleHandlers.startPress(evt);
}
private handleRippleDeactivate() {
+ if (!this.hasCardAction) return;
this._rippleHandlers.endPress();
}
private handleRippleMouseEnter() {
+ if (!this.hasCardAction) return;
this._rippleHandlers.startHover();
}
private handleRippleMouseLeave() {
+ if (!this.hasCardAction) return;
this._rippleHandlers.endHover();
}
+ get hasCardAction() {
+ return (
+ !this._config?.tap_action ||
+ hasAction(this._config?.tap_action) ||
+ hasAction(this._config?.hold_action) ||
+ hasAction(this._config?.double_tap_action)
+ );
+ }
+
+ get hasIconAction() {
+ return (
+ !this._config?.icon_tap_action || hasAction(this._config?.icon_tap_action)
+ );
+ }
+
protected render() {
if (!this._config || !this.hass) {
return nothing;
@@ -368,8 +387,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
hasHold: hasAction(this._config!.hold_action),
hasDoubleClick: hasAction(this._config!.double_tap_action),
})}
- role="button"
- tabindex="0"
+ role=${ifDefined(this.hasCardAction ? "button" : undefined)}
+ tabindex=${ifDefined(this.hasCardAction ? "0" : undefined)}
aria-labelledby="info"
@mousedown=${this.handleRippleActivate}
@mouseup=${this.handleRippleDeactivate}
@@ -386,8 +405,8 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
From 62dafac72b2c4fcc3975122aaa2c390dc1abcc80 Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Wed, 3 Jan 2024 14:26:40 +0100
Subject: [PATCH 061/361] Display edit button for climate fan mode feature
(#19259)
---
.../lovelace/editor/config-elements/hui-card-features-editor.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts b/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts
index 49290ba57102..8693be890d8d 100644
--- a/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts
@@ -81,6 +81,7 @@ const EDITABLES_FEATURE_TYPES = new Set([
"humidifier-modes",
"water-heater-operation-modes",
"lawn-mower-commands",
+ "climate-fan-modes",
"climate-preset-modes",
"numeric-input",
"update-actions",
From 2c69fe8c53cca9b1d3a1cda718b16cb06f8d23d4 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 14:58:36 +0100
Subject: [PATCH 062/361] Fix checking todo item that dont support due date
(#19262)
* Fix checking todo item that dont support due date
* make cleaner
* Revert "make cleaner"
This reverts commit fa33b3361451dd334d9f69142f9754a1ea2c1ca4.
* Update dialog-todo-item-editor.ts
* do check in 1 place
---
src/data/todo.ts | 12 +++++++++---
src/panels/lovelace/cards/hui-todo-list-card.ts | 3 ++-
src/panels/todo/dialog-todo-item-editor.ts | 12 +++++++++---
3 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/src/data/todo.ts b/src/data/todo.ts
index 9af8ef0f4cc6..659c8d0c3c24 100644
--- a/src/data/todo.ts
+++ b/src/data/todo.ts
@@ -83,9 +83,12 @@ export const updateItem = (
item: item.uid,
rename: item.summary,
status: item.status,
- description: item.description || null,
+ description: item.description,
due_datetime: item.due?.includes("T") ? item.due : undefined,
- due_date: item.due?.includes("T") ? undefined : item.due || null,
+ due_date:
+ item.due === undefined || item.due?.includes("T")
+ ? undefined
+ : item.due,
},
{ entity_id }
);
@@ -102,7 +105,10 @@ export const createItem = (
item: item.summary,
description: item.description || undefined,
due_datetime: item.due?.includes("T") ? item.due : undefined,
- due_date: item.due?.includes("T") ? undefined : item.due,
+ due_date:
+ item.due === undefined || item.due?.includes("T")
+ ? undefined
+ : item.due,
},
{ entity_id }
);
diff --git a/src/panels/lovelace/cards/hui-todo-list-card.ts b/src/panels/lovelace/cards/hui-todo-list-card.ts
index 3352f7a42b43..d1d62880f8ed 100644
--- a/src/panels/lovelace/cards/hui-todo-list-card.ts
+++ b/src/panels/lovelace/cards/hui-todo-list-card.ts
@@ -476,7 +476,8 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
return;
}
await updateItem(this.hass!, this._entityId!, {
- ...item,
+ uid: item.uid,
+ summary: item.summary,
status:
item.status === TodoItemStatus.NeedsAction
? TodoItemStatus.Completed
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index cd26ad35fc28..daa5eff68627 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -324,14 +324,20 @@ class DialogTodoItemEditor extends LitElement {
(this._todoListSupportsFeature(
TodoListEntityFeature.SET_DESCRIPTION_ON_ITEM
)
- ? // backend should accept null to clear the field, but it doesn't now
- null
+ ? null
: undefined),
due: this._due
? this._hasTime
? this._due.toISOString()
: this._formatDate(this._due)
- : null,
+ : this._todoListSupportsFeature(
+ TodoListEntityFeature.SET_DUE_DATETIME_ON_ITEM
+ ) ||
+ this._todoListSupportsFeature(
+ TodoListEntityFeature.SET_DUE_DATE_ON_ITEM
+ )
+ ? null
+ : undefined,
status: this._checked
? TodoItemStatus.Completed
: TodoItemStatus.NeedsAction,
From 288d173a4d2fcf4ec665e4fffee4015550dafa67 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 15:02:14 +0100
Subject: [PATCH 063/361] Bumped version to 20240103.3
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index f43e4cf0dc55..b1f2ee8ea705 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.0"
+version = "20240103.3"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 7a6fc573c206d096ef61b8fe59e9170d5b52daaf Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 15:19:30 +0100
Subject: [PATCH 064/361] Fix version bump script (#19264)
---
script/{version_bump.cjs => version_bump.js} | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
rename script/{version_bump.cjs => version_bump.js} (83%)
diff --git a/script/version_bump.cjs b/script/version_bump.js
similarity index 83%
rename from script/version_bump.cjs
rename to script/version_bump.js
index a1c8f9c9be6f..fbba50b6a7ab 100755
--- a/script/version_bump.cjs
+++ b/script/version_bump.js
@@ -1,7 +1,10 @@
#!/usr/bin/env node
-const fs = require("fs");
-const util = require("util");
-const exec = util.promisify(require("child_process").exec);
+/* eslint-disable no-console */
+import fs from "fs";
+import util from "util";
+import child_process from "child_process";
+
+const exec = util.promisify(child_process.exec);
function patch(version) {
const parts = version.split(".");
@@ -18,7 +21,7 @@ function today() {
function auto(version) {
const todayVersion = today();
- if (todayVersion !== version) {
+ if (todayVersion.split(".")[0] !== version.split(".")[0]) {
return todayVersion;
}
return patch(version);
@@ -44,7 +47,7 @@ async function main(args) {
commit = true;
} else {
method = args.length > 0 && methods[args[0]];
- commit = args.length > 1 && args[1] == "--commit";
+ commit = args.length > 1 && args[1] === "--commit";
}
if (!method) {
From 979085a9defd27e6b8936aa6be2d0d45843921df Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Wed, 3 Jan 2024 20:35:54 +0100
Subject: [PATCH 065/361] Fix supervisor dev build (#19266)
---
build-scripts/gulp/translations.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/build-scripts/gulp/translations.js b/build-scripts/gulp/translations.js
index 967da71efdfc..fd4cccc013a8 100755
--- a/build-scripts/gulp/translations.js
+++ b/build-scripts/gulp/translations.js
@@ -426,6 +426,7 @@ gulp.task(
"fetch-nightly-translations",
gulp.series("clean-translations", "ensure-translations-build-dir")
),
+ gulp.parallel("create-test-metadata", "create-test-translation"),
"build-master-translation",
"build-merged-translations",
"build-translation-fragment-supervisor",
From 3984702d3eba9fde82c405fcea2a60cedc75a961 Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Wed, 3 Jan 2024 11:36:59 -0800
Subject: [PATCH 066/361] Fix select view dialog (#19267)
* Fix select view dialog
* add import
---
.../select-view/hui-dialog-select-view.ts | 21 ++++++++++++++-----
src/translations/en.json | 4 +++-
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
index 6a9c8eb04fdc..5f3e073f3a4f 100644
--- a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
+++ b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
@@ -8,6 +8,7 @@ import { stopPropagation } from "../../../../common/dom/stop_propagation";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-icon";
import "../../../../components/ha-select";
+import "../../../../components/ha-alert";
import {
fetchConfig,
LovelaceConfig,
@@ -104,8 +105,15 @@ export class HuiDialogSelectView extends LitElement {
})}
`
: ""}
- ${this._config
- ? this._config.views.length > 1
+ ${!this._config || (this._config.views || []).length < 1
+ ? html`${this.hass.localize(
+ this._config
+ ? "ui.panel.lovelace.editor.select_view.no_views"
+ : "ui.panel.lovelace.editor.select_view.no_config"
+ )}`
+ : this._config.views.length > 1
? html`
${this._config.views.map(
@@ -125,8 +133,7 @@ export class HuiDialogSelectView extends LitElement {
)}
`
- : ""
- : html`No config found.
`}
+ : ""}
${this.hass!.localize("ui.common.cancel")}
-
+
${this._params.actionLabel || this.hass!.localize("ui.common.move")}
diff --git a/src/translations/en.json b/src/translations/en.json
index 53306cd8b77d..74467bcbf1ab 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -5020,7 +5020,9 @@
"select_view": {
"header": "Choose a view",
"dashboard_label": "Dashboard",
- "views_label": "View"
+ "views_label": "View",
+ "no_config": "No config found.",
+ "no_views": "No views in this dashboard."
},
"suggest_card": {
"header": "We created a suggestion for you",
From 0d8c0ac1a0c84cee9d1e14f1bc306b8424294c7d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 3 Jan 2024 17:45:46 -0500
Subject: [PATCH 067/361] Update dependency marked to v11.1.1 (#19254)
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 663a412014d2..8f2a790e78e0 100644
--- a/package.json
+++ b/package.json
@@ -119,7 +119,7 @@
"leaflet-draw": "1.0.4",
"lit": "2.8.0",
"luxon": "3.4.4",
- "marked": "11.1.0",
+ "marked": "11.1.1",
"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 2f9b96e6b6ef..59d16bf0e735 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9676,7 +9676,7 @@ __metadata:
luxon: "npm:3.4.4"
magic-string: "npm:0.30.5"
map-stream: "npm:0.0.7"
- marked: "npm:11.1.0"
+ marked: "npm:11.1.1"
memoize-one: "npm:6.0.0"
mocha: "npm:10.2.0"
node-vibrant: "npm:3.2.1-alpha.1"
@@ -11652,12 +11652,12 @@ __metadata:
languageName: node
linkType: hard
-"marked@npm:11.1.0":
- version: 11.1.0
- resolution: "marked@npm:11.1.0"
+"marked@npm:11.1.1":
+ version: 11.1.1
+ resolution: "marked@npm:11.1.1"
bin:
marked: bin/marked.js
- checksum: 4636b16283c1963a715e97578d9fd91588b11949276e633a4de53dc408bcdab7b846d2b5c2cf3239f6d2dc8affe5294a0895954b5e3d9562d77301d8847a8915
+ checksum: c2e15a330ac75cca2e12e25aae09985a78ad7e96a84418964dcdd3ee776764a38812dc0e94e9fcbacac43113d1650ca7946f9dc0bab800d72181e56a37e7631e
languageName: node
linkType: hard
From 4f05bd9e22f8cd91f288e4af88ddcb5dd8ab6c15 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 03:21:42 +0100
Subject: [PATCH 068/361] Fix circular progress size + fix bug in assist
pipeline debug (#19268)
---
src/auth/ha-auth-textfield.ts | 2 +-
src/components/media-player/ha-media-upload-button.ts | 2 +-
src/panels/config/repairs/dialog-system-information.ts | 2 +-
.../voice-assistants/debug/assist-pipeline-run-debug.ts | 7 +++++--
.../voice-assistants/debug/assist-render-pipeline-run.ts | 2 +-
5 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/auth/ha-auth-textfield.ts b/src/auth/ha-auth-textfield.ts
index 123deef03fe9..20d5e66174c8 100644
--- a/src/auth/ha-auth-textfield.ts
+++ b/src/auth/ha-auth-textfield.ts
@@ -47,7 +47,7 @@ export class HaAuthTextField extends HaTextField {
// TODO: live() directive needs casting for lit-analyzer
// https://github.com/runem/lit-analyzer/pull/91/files
// TODO: lit-analyzer labels min/max as (number|string) instead of string
- return html` 0
? html`
`;
} else if (info.type === "failed") {
diff --git a/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts b/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
index 67b902ba6581..f7df3507fa4e 100644
--- a/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
+++ b/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
@@ -247,7 +247,7 @@ export class AssistPipelineRunDebug extends LitElement {
}
// Play audio when we're done.
- if (updatedRun.stage === "done") {
+ if (updatedRun.stage === "done" && !updatedRun.error) {
const url = updatedRun.tts!.tts_output!.url;
const audio = new Audio(url);
audio.addEventListener("ended", () => {
@@ -261,7 +261,10 @@ export class AssistPipelineRunDebug extends LitElement {
}
});
audio.play();
- } else if (updatedRun.stage === "error") {
+ } else if (
+ (updatedRun.stage === "done" && updatedRun.error) ||
+ updatedRun.stage === "error"
+ ) {
this._finished = true;
}
},
diff --git a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
index 05da128692af..ae455152beb0 100644
--- a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
+++ b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
@@ -90,7 +90,7 @@ const renderProgress = (
return html`❌`;
}
return html`
-
+
`;
}
From e427ffca5fc136d5c16a4503a6fe8b68ac449606 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 03:27:30 +0100
Subject: [PATCH 069/361] Fix turning valve on/off (#19269)
---
src/common/const.ts | 1 +
src/panels/lovelace/common/entity/turn-on-off-entity.ts | 3 +++
2 files changed, 4 insertions(+)
diff --git a/src/common/const.ts b/src/common/const.ts
index 68f4fa97b1c1..bc114f2f1703 100644
--- a/src/common/const.ts
+++ b/src/common/const.ts
@@ -272,6 +272,7 @@ export const DOMAINS_TOGGLE = new Set([
"group",
"automation",
"humidifier",
+ "valve",
]);
/** Domains that have a dynamic entity image / picture. */
diff --git a/src/panels/lovelace/common/entity/turn-on-off-entity.ts b/src/panels/lovelace/common/entity/turn-on-off-entity.ts
index 701c2c4996ab..5be6beaea844 100644
--- a/src/panels/lovelace/common/entity/turn-on-off-entity.ts
+++ b/src/panels/lovelace/common/entity/turn-on-off-entity.ts
@@ -24,6 +24,9 @@ export const turnOnOffEntity = (
case "scene":
service = "turn_on";
break;
+ case "valve":
+ service = turnOn ? "open_valve" : "close_valve";
+ break;
default:
service = turnOn ? "turn_on" : "turn_off";
}
From e5d31d85dd91c1387fbddd5b8ad2a0fbfeef04d0 Mon Sep 17 00:00:00 2001
From: Franck Nijhof
Date: Thu, 4 Jan 2024 10:54:20 +0100
Subject: [PATCH 070/361] Update getStates to support valves (#19277)
---
src/common/entity/get_states.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/common/entity/get_states.ts b/src/common/entity/get_states.ts
index 29c11ca48c42..456ce27bcea5 100644
--- a/src/common/entity/get_states.ts
+++ b/src/common/entity/get_states.ts
@@ -50,6 +50,7 @@ export const FIXED_DOMAIN_STATES = {
timer: ["active", "idle", "paused"],
update: ["on", "off"],
vacuum: ["cleaning", "docked", "error", "idle", "paused", "returning"],
+ valve: ["closed", "closing", "open", "opening"],
weather: [
"clear-night",
"cloudy",
From ecadc06b452c180d97c8fa9d8f776fb3a690712f Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 11:52:38 +0100
Subject: [PATCH 071/361] fix valve entities row (#19278)
---
src/common/const.ts | 1 +
src/data/valve.ts | 10 ++++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/common/const.ts b/src/common/const.ts
index bc114f2f1703..2e7d2f7c77d7 100644
--- a/src/common/const.ts
+++ b/src/common/const.ts
@@ -254,6 +254,7 @@ export const DOMAINS_INPUT_ROW = [
"text",
"time",
"vacuum",
+ "valve",
];
/** States that we consider "off". */
diff --git a/src/data/valve.ts b/src/data/valve.ts
index 73f5d428ae18..645ca82e4954 100644
--- a/src/data/valve.ts
+++ b/src/data/valve.ts
@@ -14,14 +14,20 @@ export const enum ValveEntityFeature {
}
export function isFullyOpen(stateObj: ValveEntity) {
- if (stateObj.attributes.current_position !== undefined) {
+ if (
+ stateObj.attributes.current_position !== undefined &&
+ stateObj.attributes.current_position !== null
+ ) {
return stateObj.attributes.current_position === 100;
}
return stateObj.state === "open";
}
export function isFullyClosed(stateObj: ValveEntity) {
- if (stateObj.attributes.current_position !== undefined) {
+ if (
+ stateObj.attributes.current_position !== undefined &&
+ stateObj.attributes.current_position !== null
+ ) {
return stateObj.attributes.current_position === 0;
}
return stateObj.state === "closed";
From fd6cae48b7e2940356589881d4b0d0f3f34b0a31 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 13:20:35 +0100
Subject: [PATCH 072/361] Remove overflow hidden from profile (#19279)
---
src/panels/profile/ha-panel-profile.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/panels/profile/ha-panel-profile.ts b/src/panels/profile/ha-panel-profile.ts
index 1756af4d9333..9e82e842df5f 100644
--- a/src/panels/profile/ha-panel-profile.ts
+++ b/src/panels/profile/ha-panel-profile.ts
@@ -250,7 +250,6 @@ class HaPanelProfile extends LitElement {
max-width: 600px;
margin: 0 auto;
padding-bottom: env(safe-area-inset-bottom);
- overflow: hidden;
}
.content > * {
From 8615b799c6ede94aabca3a8a0ae54d8fdbf5b8fe Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 14:24:33 +0100
Subject: [PATCH 073/361] Fix due date when no time in certain timezones
(#19280)
* Fix due date when no time in certain timezones
* Update dialog-todo-item-editor.ts
---
src/panels/lovelace/cards/hui-todo-list-card.ts | 2 +-
src/panels/todo/dialog-todo-item-editor.ts | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/panels/lovelace/cards/hui-todo-list-card.ts b/src/panels/lovelace/cards/hui-todo-list-card.ts
index d1d62880f8ed..1d1c6b6c8243 100644
--- a/src/panels/lovelace/cards/hui-todo-list-card.ts
+++ b/src/panels/lovelace/cards/hui-todo-list-card.ts
@@ -335,7 +335,7 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
const due = item.due
? item.due.includes("T")
? new Date(item.due)
- : endOfDay(new Date(item.due))
+ : endOfDay(new Date(`${item.due}T00:00:00`))
: undefined;
const today =
due && !item.due!.includes("T") && isSameDay(new Date(), due);
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index daa5eff68627..be03e260eccf 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -60,8 +60,10 @@ class DialogTodoItemEditor extends LitElement {
this._checked = entry.status === TodoItemStatus.Completed;
this._summary = entry.summary;
this._description = entry.description || "";
- this._due = entry.due ? new Date(entry.due) : undefined;
this._hasTime = entry.due?.includes("T") || false;
+ this._due = entry.due
+ ? new Date(this._hasTime ? entry.due : `${entry.due}T00:00:00`)
+ : undefined;
} else {
this._hasTime = false;
this._checked = false;
From 72dedc7596a0626f858848afebf71ed77cf21ddd Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Thu, 4 Jan 2024 16:18:16 +0100
Subject: [PATCH 074/361] Fix thermostat and humidifier card rendering when off
(#19281)
* Fix thermostat and humidifier card rendering when off
* Fix action color
---
.../ha-state-control-climate-temperature.ts | 43 +++++++++++++------
.../ha-state-control-humidifier-humidity.ts | 37 ++++++++++++----
.../state-control-circular-slider-style.ts | 13 +++++-
3 files changed, 71 insertions(+), 22 deletions(-)
diff --git a/src/state-control/climate/ha-state-control-climate-temperature.ts b/src/state-control/climate/ha-state-control-climate-temperature.ts
index 7634fd2f2d18..0264af5ec7b3 100644
--- a/src/state-control/climate/ha-state-control-climate-temperature.ts
+++ b/src/state-control/climate/ha-state-control-climate-temperature.ts
@@ -177,11 +177,20 @@ export class HaStateControlClimateTemperature extends LitElement {
const action = this.stateObj.attributes.hvac_action;
+ const isTemperatureDisplayed =
+ (this.stateObj.attributes.current_temperature != null &&
+ this.showCurrentAsPrimary) ||
+ ((this._supportsTargetTemperature ||
+ this._supportsTargetTemperatureRange) &&
+ !this.showCurrentAsPrimary);
+
return html`
- ${action
+ ${action && action !== "off"
? this.hass.formatEntityAttributeValue(this.stateObj, "hvac_action")
- : this.hass.formatEntityState(this.stateObj)}
+ : isTemperatureDisplayed
+ ? this.hass.formatEntityState(this.stateObj)
+ : nothing}
`;
}
@@ -315,6 +324,14 @@ export class HaStateControlClimateTemperature extends LitElement {
`;
}
+ if (this.stateObj.state !== UNAVAILABLE) {
+ return html`
+
+ ${this.hass.formatEntityState(this.stateObj)}
+
+ `;
+ }
+
return nothing;
}
@@ -373,6 +390,14 @@ export class HaStateControlClimateTemperature extends LitElement {
return html``;
}
+ private _renderInfo() {
+ return html`
+
+ ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
+
+ `;
+ }
+
get _supportsTargetTemperature() {
return (
supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE) &&
@@ -447,10 +472,7 @@ export class HaStateControlClimateTemperature extends LitElement {
@value-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
- ${this._renderTemperatureButtons("value")}
+ ${this._renderInfo()} ${this._renderTemperatureButtons("value")}
`;
}
@@ -484,9 +506,7 @@ export class HaStateControlClimateTemperature extends LitElement {
@high-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
+ ${this._renderInfo()}
${this._renderTemperatureButtons(this._selectTargetTemperature, true)}
`;
@@ -497,6 +517,7 @@ export class HaStateControlClimateTemperature extends LitElement {
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
+ "--action-color": actionColor,
})}
>
-
- ${this._renderLabel()} ${this._renderSecondary()}
-
+ ${this._renderInfo()}
`;
}
diff --git a/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts b/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
index 6078180cd849..459e8d611730 100644
--- a/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
+++ b/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
@@ -105,11 +105,18 @@ export class HaStateControlHumidifierHumidity extends LitElement {
const action = this.stateObj.attributes.action;
+ const isHumidityDisplayed =
+ (this.stateObj.attributes.current_humidity != null &&
+ this.showCurrentAsPrimary) ||
+ (this._targetHumidity != null && !this.showCurrentAsPrimary);
+
return html`
- ${action
+ ${action && action !== "off"
? this.hass.formatEntityAttributeValue(this.stateObj, "action")
- : this.hass.formatEntityState(this.stateObj)}
+ : isHumidityDisplayed
+ ? this.hass.formatEntityState(this.stateObj)
+ : nothing}
`;
}
@@ -144,6 +151,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
return this._renderTarget(this._targetHumidity!, "big");
}
+ if (this.stateObj.state !== UNAVAILABLE) {
+ return html`
+
+ ${this.hass.formatEntityState(this.stateObj)}
+
+ `;
+ }
+
return nothing;
}
@@ -225,6 +240,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
`;
}
+ private _renderInfo() {
+ return html`
+
+ ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
+
+ `;
+ }
+
protected render() {
const stateColor = stateColorCss(this.stateObj);
const active = stateActive(this.stateObj);
@@ -272,10 +295,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@value-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
- ${this._renderButtons()}
+ ${this._renderInfo()} ${this._renderButtons()}
`;
}
@@ -284,6 +304,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@@ -296,9 +317,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
disabled
>
-
- ${this._renderLabel()} ${this._renderSecondary()}
-
+ ${this._renderInfo()}
`;
}
diff --git a/src/state-control/state-control-circular-slider-style.ts b/src/state-control/state-control-circular-slider-style.ts
index cc1c9366d7e9..b5d4d5281a03 100644
--- a/src/state-control/state-control-circular-slider-style.ts
+++ b/src/state-control/state-control-circular-slider-style.ts
@@ -54,7 +54,6 @@ export const stateControlCircularSliderStyle = css`
.label.disabled {
color: var(--secondary-text-color);
}
-
.buttons {
position: absolute;
bottom: 10px;
@@ -67,6 +66,9 @@ export const stateControlCircularSliderStyle = css`
align-items: center;
justify-content: center;
}
+ .primary-state {
+ font-size: 36px;
+ }
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-width: 48px;
@@ -77,6 +79,9 @@ export const stateControlCircularSliderStyle = css`
.container.md ha-big-number {
font-size: 44px;
}
+ .container.md .state {
+ font-size: 30px;
+ }
.container.md .info {
margin-top: 12px;
gap: 6px;
@@ -91,6 +96,9 @@ export const stateControlCircularSliderStyle = css`
.container.sm ha-big-number {
font-size: 32px;
}
+ .container.sm .state {
+ font-size: 26px;
+ }
.container.sm .info {
margin-top: 12px;
font-size: 14px;
@@ -107,6 +115,9 @@ export const stateControlCircularSliderStyle = css`
.container.xs ha-big-number {
font-size: 32px;
}
+ .container.xs .state {
+ font-size: 16px;
+ }
.container.xs .info {
margin-top: 12px;
}
From fe5431976d5c8c4a77e525f60a95ddbebb907baf Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 17:43:37 +0100
Subject: [PATCH 075/361] Bumped version to 20240104.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index f43e4cf0dc55..d9414825fabf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.0"
+version = "20240104.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From fef2c44cb8ffe4ff3b0827365da3ba068e193ad3 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 17:43:37 +0100
Subject: [PATCH 076/361] Bumped version to 20240104.0
---
pyproject.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pyproject.toml b/pyproject.toml
index b1f2ee8ea705..d9414825fabf 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20240103.3"
+version = "20240104.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
From 030566c1e849997c3ec39ec82c6b86ac9c2048fc Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 3 Jan 2024 17:45:46 -0500
Subject: [PATCH 077/361] Update dependency marked to v11.1.1 (#19254)
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 3f4e61c24329..0d2a855179f1 100644
--- a/package.json
+++ b/package.json
@@ -119,7 +119,7 @@
"leaflet-draw": "1.0.4",
"lit": "2.8.0",
"luxon": "3.4.4",
- "marked": "11.1.0",
+ "marked": "11.1.1",
"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 510c103b2e84..3997cc2fa300 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9679,7 +9679,7 @@ __metadata:
luxon: "npm:3.4.4"
magic-string: "npm:0.30.5"
map-stream: "npm:0.0.7"
- marked: "npm:11.1.0"
+ marked: "npm:11.1.1"
memoize-one: "npm:6.0.0"
mocha: "npm:10.2.0"
node-vibrant: "npm:3.2.1-alpha.1"
@@ -11655,12 +11655,12 @@ __metadata:
languageName: node
linkType: hard
-"marked@npm:11.1.0":
- version: 11.1.0
- resolution: "marked@npm:11.1.0"
+"marked@npm:11.1.1":
+ version: 11.1.1
+ resolution: "marked@npm:11.1.1"
bin:
marked: bin/marked.js
- checksum: 4636b16283c1963a715e97578d9fd91588b11949276e633a4de53dc408bcdab7b846d2b5c2cf3239f6d2dc8affe5294a0895954b5e3d9562d77301d8847a8915
+ checksum: c2e15a330ac75cca2e12e25aae09985a78ad7e96a84418964dcdd3ee776764a38812dc0e94e9fcbacac43113d1650ca7946f9dc0bab800d72181e56a37e7631e
languageName: node
linkType: hard
From 0b20725f5f42824d67168714f50632fd11e013bc Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Wed, 3 Jan 2024 11:36:59 -0800
Subject: [PATCH 078/361] Fix select view dialog (#19267)
* Fix select view dialog
* add import
---
.../select-view/hui-dialog-select-view.ts | 21 ++++++++++++++-----
src/translations/en.json | 4 +++-
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
index 6a9c8eb04fdc..5f3e073f3a4f 100644
--- a/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
+++ b/src/panels/lovelace/editor/select-view/hui-dialog-select-view.ts
@@ -8,6 +8,7 @@ import { stopPropagation } from "../../../../common/dom/stop_propagation";
import { createCloseHeading } from "../../../../components/ha-dialog";
import "../../../../components/ha-icon";
import "../../../../components/ha-select";
+import "../../../../components/ha-alert";
import {
fetchConfig,
LovelaceConfig,
@@ -104,8 +105,15 @@ export class HuiDialogSelectView extends LitElement {
})}
`
: ""}
- ${this._config
- ? this._config.views.length > 1
+ ${!this._config || (this._config.views || []).length < 1
+ ? html`${this.hass.localize(
+ this._config
+ ? "ui.panel.lovelace.editor.select_view.no_views"
+ : "ui.panel.lovelace.editor.select_view.no_config"
+ )}`
+ : this._config.views.length > 1
? html`
${this._config.views.map(
@@ -125,8 +133,7 @@ export class HuiDialogSelectView extends LitElement {
)}
`
- : ""
- : html`No config found.
`}
+ : ""}
${this.hass!.localize("ui.common.cancel")}
-
+
${this._params.actionLabel || this.hass!.localize("ui.common.move")}
diff --git a/src/translations/en.json b/src/translations/en.json
index 53306cd8b77d..74467bcbf1ab 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -5020,7 +5020,9 @@
"select_view": {
"header": "Choose a view",
"dashboard_label": "Dashboard",
- "views_label": "View"
+ "views_label": "View",
+ "no_config": "No config found.",
+ "no_views": "No views in this dashboard."
},
"suggest_card": {
"header": "We created a suggestion for you",
From efddbfcfa0941eccce4565a30c12dd689c7d6624 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 03:21:42 +0100
Subject: [PATCH 079/361] Fix circular progress size + fix bug in assist
pipeline debug (#19268)
---
src/auth/ha-auth-textfield.ts | 2 +-
src/components/media-player/ha-media-upload-button.ts | 2 +-
src/panels/config/repairs/dialog-system-information.ts | 2 +-
.../voice-assistants/debug/assist-pipeline-run-debug.ts | 7 +++++--
.../voice-assistants/debug/assist-render-pipeline-run.ts | 2 +-
5 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/auth/ha-auth-textfield.ts b/src/auth/ha-auth-textfield.ts
index 123deef03fe9..20d5e66174c8 100644
--- a/src/auth/ha-auth-textfield.ts
+++ b/src/auth/ha-auth-textfield.ts
@@ -47,7 +47,7 @@ export class HaAuthTextField extends HaTextField {
// TODO: live() directive needs casting for lit-analyzer
// https://github.com/runem/lit-analyzer/pull/91/files
// TODO: lit-analyzer labels min/max as (number|string) instead of string
- return html` 0
? html`
`;
} else if (info.type === "failed") {
diff --git a/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts b/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
index 67b902ba6581..f7df3507fa4e 100644
--- a/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
+++ b/src/panels/config/voice-assistants/debug/assist-pipeline-run-debug.ts
@@ -247,7 +247,7 @@ export class AssistPipelineRunDebug extends LitElement {
}
// Play audio when we're done.
- if (updatedRun.stage === "done") {
+ if (updatedRun.stage === "done" && !updatedRun.error) {
const url = updatedRun.tts!.tts_output!.url;
const audio = new Audio(url);
audio.addEventListener("ended", () => {
@@ -261,7 +261,10 @@ export class AssistPipelineRunDebug extends LitElement {
}
});
audio.play();
- } else if (updatedRun.stage === "error") {
+ } else if (
+ (updatedRun.stage === "done" && updatedRun.error) ||
+ updatedRun.stage === "error"
+ ) {
this._finished = true;
}
},
diff --git a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
index 05da128692af..ae455152beb0 100644
--- a/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
+++ b/src/panels/config/voice-assistants/debug/assist-render-pipeline-run.ts
@@ -90,7 +90,7 @@ const renderProgress = (
return html`❌`;
}
return html`
-
+
`;
}
From 32fd8270d77ce80be6944d40807bcf6a6dcf1a07 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 03:27:30 +0100
Subject: [PATCH 080/361] Fix turning valve on/off (#19269)
---
src/common/const.ts | 1 +
src/panels/lovelace/common/entity/turn-on-off-entity.ts | 3 +++
2 files changed, 4 insertions(+)
diff --git a/src/common/const.ts b/src/common/const.ts
index 68f4fa97b1c1..bc114f2f1703 100644
--- a/src/common/const.ts
+++ b/src/common/const.ts
@@ -272,6 +272,7 @@ export const DOMAINS_TOGGLE = new Set([
"group",
"automation",
"humidifier",
+ "valve",
]);
/** Domains that have a dynamic entity image / picture. */
diff --git a/src/panels/lovelace/common/entity/turn-on-off-entity.ts b/src/panels/lovelace/common/entity/turn-on-off-entity.ts
index 701c2c4996ab..5be6beaea844 100644
--- a/src/panels/lovelace/common/entity/turn-on-off-entity.ts
+++ b/src/panels/lovelace/common/entity/turn-on-off-entity.ts
@@ -24,6 +24,9 @@ export const turnOnOffEntity = (
case "scene":
service = "turn_on";
break;
+ case "valve":
+ service = turnOn ? "open_valve" : "close_valve";
+ break;
default:
service = turnOn ? "turn_on" : "turn_off";
}
From 8d541595b80638dc9ff5f4762bb243a8d77cce87 Mon Sep 17 00:00:00 2001
From: Franck Nijhof
Date: Thu, 4 Jan 2024 10:54:20 +0100
Subject: [PATCH 081/361] Update getStates to support valves (#19277)
---
src/common/entity/get_states.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/common/entity/get_states.ts b/src/common/entity/get_states.ts
index 29c11ca48c42..456ce27bcea5 100644
--- a/src/common/entity/get_states.ts
+++ b/src/common/entity/get_states.ts
@@ -50,6 +50,7 @@ export const FIXED_DOMAIN_STATES = {
timer: ["active", "idle", "paused"],
update: ["on", "off"],
vacuum: ["cleaning", "docked", "error", "idle", "paused", "returning"],
+ valve: ["closed", "closing", "open", "opening"],
weather: [
"clear-night",
"cloudy",
From f147a5e909bc94e6bc1ed5364d9ac8791e2002a2 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 11:52:38 +0100
Subject: [PATCH 082/361] fix valve entities row (#19278)
---
src/common/const.ts | 1 +
src/data/valve.ts | 10 ++++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/common/const.ts b/src/common/const.ts
index bc114f2f1703..2e7d2f7c77d7 100644
--- a/src/common/const.ts
+++ b/src/common/const.ts
@@ -254,6 +254,7 @@ export const DOMAINS_INPUT_ROW = [
"text",
"time",
"vacuum",
+ "valve",
];
/** States that we consider "off". */
diff --git a/src/data/valve.ts b/src/data/valve.ts
index 73f5d428ae18..645ca82e4954 100644
--- a/src/data/valve.ts
+++ b/src/data/valve.ts
@@ -14,14 +14,20 @@ export const enum ValveEntityFeature {
}
export function isFullyOpen(stateObj: ValveEntity) {
- if (stateObj.attributes.current_position !== undefined) {
+ if (
+ stateObj.attributes.current_position !== undefined &&
+ stateObj.attributes.current_position !== null
+ ) {
return stateObj.attributes.current_position === 100;
}
return stateObj.state === "open";
}
export function isFullyClosed(stateObj: ValveEntity) {
- if (stateObj.attributes.current_position !== undefined) {
+ if (
+ stateObj.attributes.current_position !== undefined &&
+ stateObj.attributes.current_position !== null
+ ) {
return stateObj.attributes.current_position === 0;
}
return stateObj.state === "closed";
From a1cf18468b2bafade0bbb4f4e0552bdc1fd955b3 Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 13:20:35 +0100
Subject: [PATCH 083/361] Remove overflow hidden from profile (#19279)
---
src/panels/profile/ha-panel-profile.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/panels/profile/ha-panel-profile.ts b/src/panels/profile/ha-panel-profile.ts
index 1756af4d9333..9e82e842df5f 100644
--- a/src/panels/profile/ha-panel-profile.ts
+++ b/src/panels/profile/ha-panel-profile.ts
@@ -250,7 +250,6 @@ class HaPanelProfile extends LitElement {
max-width: 600px;
margin: 0 auto;
padding-bottom: env(safe-area-inset-bottom);
- overflow: hidden;
}
.content > * {
From a31b9f1b4d952353a3f61b5905fdf6ee1eeec8ef Mon Sep 17 00:00:00 2001
From: Bram Kragten
Date: Thu, 4 Jan 2024 14:24:33 +0100
Subject: [PATCH 084/361] Fix due date when no time in certain timezones
(#19280)
* Fix due date when no time in certain timezones
* Update dialog-todo-item-editor.ts
---
src/panels/lovelace/cards/hui-todo-list-card.ts | 2 +-
src/panels/todo/dialog-todo-item-editor.ts | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/panels/lovelace/cards/hui-todo-list-card.ts b/src/panels/lovelace/cards/hui-todo-list-card.ts
index d1d62880f8ed..1d1c6b6c8243 100644
--- a/src/panels/lovelace/cards/hui-todo-list-card.ts
+++ b/src/panels/lovelace/cards/hui-todo-list-card.ts
@@ -335,7 +335,7 @@ export class HuiTodoListCard extends LitElement implements LovelaceCard {
const due = item.due
? item.due.includes("T")
? new Date(item.due)
- : endOfDay(new Date(item.due))
+ : endOfDay(new Date(`${item.due}T00:00:00`))
: undefined;
const today =
due && !item.due!.includes("T") && isSameDay(new Date(), due);
diff --git a/src/panels/todo/dialog-todo-item-editor.ts b/src/panels/todo/dialog-todo-item-editor.ts
index daa5eff68627..be03e260eccf 100644
--- a/src/panels/todo/dialog-todo-item-editor.ts
+++ b/src/panels/todo/dialog-todo-item-editor.ts
@@ -60,8 +60,10 @@ class DialogTodoItemEditor extends LitElement {
this._checked = entry.status === TodoItemStatus.Completed;
this._summary = entry.summary;
this._description = entry.description || "";
- this._due = entry.due ? new Date(entry.due) : undefined;
this._hasTime = entry.due?.includes("T") || false;
+ this._due = entry.due
+ ? new Date(this._hasTime ? entry.due : `${entry.due}T00:00:00`)
+ : undefined;
} else {
this._hasTime = false;
this._checked = false;
From 456c011f3edc0e31e3c49434dfaf37f3f715d485 Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Thu, 4 Jan 2024 16:18:16 +0100
Subject: [PATCH 085/361] Fix thermostat and humidifier card rendering when off
(#19281)
* Fix thermostat and humidifier card rendering when off
* Fix action color
---
.../ha-state-control-climate-temperature.ts | 43 +++++++++++++------
.../ha-state-control-humidifier-humidity.ts | 37 ++++++++++++----
.../state-control-circular-slider-style.ts | 13 +++++-
3 files changed, 71 insertions(+), 22 deletions(-)
diff --git a/src/state-control/climate/ha-state-control-climate-temperature.ts b/src/state-control/climate/ha-state-control-climate-temperature.ts
index 7634fd2f2d18..0264af5ec7b3 100644
--- a/src/state-control/climate/ha-state-control-climate-temperature.ts
+++ b/src/state-control/climate/ha-state-control-climate-temperature.ts
@@ -177,11 +177,20 @@ export class HaStateControlClimateTemperature extends LitElement {
const action = this.stateObj.attributes.hvac_action;
+ const isTemperatureDisplayed =
+ (this.stateObj.attributes.current_temperature != null &&
+ this.showCurrentAsPrimary) ||
+ ((this._supportsTargetTemperature ||
+ this._supportsTargetTemperatureRange) &&
+ !this.showCurrentAsPrimary);
+
return html`
- ${action
+ ${action && action !== "off"
? this.hass.formatEntityAttributeValue(this.stateObj, "hvac_action")
- : this.hass.formatEntityState(this.stateObj)}
+ : isTemperatureDisplayed
+ ? this.hass.formatEntityState(this.stateObj)
+ : nothing}
`;
}
@@ -315,6 +324,14 @@ export class HaStateControlClimateTemperature extends LitElement {
`;
}
+ if (this.stateObj.state !== UNAVAILABLE) {
+ return html`
+
+ ${this.hass.formatEntityState(this.stateObj)}
+
+ `;
+ }
+
return nothing;
}
@@ -373,6 +390,14 @@ export class HaStateControlClimateTemperature extends LitElement {
return html``;
}
+ private _renderInfo() {
+ return html`
+
+ ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
+
+ `;
+ }
+
get _supportsTargetTemperature() {
return (
supportsFeature(this.stateObj, ClimateEntityFeature.TARGET_TEMPERATURE) &&
@@ -447,10 +472,7 @@ export class HaStateControlClimateTemperature extends LitElement {
@value-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
- ${this._renderTemperatureButtons("value")}
+ ${this._renderInfo()} ${this._renderTemperatureButtons("value")}
`;
}
@@ -484,9 +506,7 @@ export class HaStateControlClimateTemperature extends LitElement {
@high-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
+ ${this._renderInfo()}
${this._renderTemperatureButtons(this._selectTargetTemperature, true)}
`;
@@ -497,6 +517,7 @@ export class HaStateControlClimateTemperature extends LitElement {
class="container${containerSizeClass}"
style=${styleMap({
"--state-color": stateColor,
+ "--action-color": actionColor,
})}
>
-
- ${this._renderLabel()} ${this._renderSecondary()}
-
+ ${this._renderInfo()}
`;
}
diff --git a/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts b/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
index 6078180cd849..459e8d611730 100644
--- a/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
+++ b/src/state-control/humidifier/ha-state-control-humidifier-humidity.ts
@@ -105,11 +105,18 @@ export class HaStateControlHumidifierHumidity extends LitElement {
const action = this.stateObj.attributes.action;
+ const isHumidityDisplayed =
+ (this.stateObj.attributes.current_humidity != null &&
+ this.showCurrentAsPrimary) ||
+ (this._targetHumidity != null && !this.showCurrentAsPrimary);
+
return html`
- ${action
+ ${action && action !== "off"
? this.hass.formatEntityAttributeValue(this.stateObj, "action")
- : this.hass.formatEntityState(this.stateObj)}
+ : isHumidityDisplayed
+ ? this.hass.formatEntityState(this.stateObj)
+ : nothing}
`;
}
@@ -144,6 +151,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
return this._renderTarget(this._targetHumidity!, "big");
}
+ if (this.stateObj.state !== UNAVAILABLE) {
+ return html`
+
+ ${this.hass.formatEntityState(this.stateObj)}
+
+ `;
+ }
+
return nothing;
}
@@ -225,6 +240,14 @@ export class HaStateControlHumidifierHumidity extends LitElement {
`;
}
+ private _renderInfo() {
+ return html`
+
+ ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
+
+ `;
+ }
+
protected render() {
const stateColor = stateColorCss(this.stateObj);
const active = stateActive(this.stateObj);
@@ -272,10 +295,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@value-changing=${this._valueChanging}
>
-
- ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
-
- ${this._renderButtons()}
+ ${this._renderInfo()} ${this._renderButtons()}
`;
}
@@ -284,6 +304,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@@ -296,9 +317,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
disabled
>
-
- ${this._renderLabel()} ${this._renderSecondary()}
-
+ ${this._renderInfo()}
`;
}
diff --git a/src/state-control/state-control-circular-slider-style.ts b/src/state-control/state-control-circular-slider-style.ts
index cc1c9366d7e9..b5d4d5281a03 100644
--- a/src/state-control/state-control-circular-slider-style.ts
+++ b/src/state-control/state-control-circular-slider-style.ts
@@ -54,7 +54,6 @@ export const stateControlCircularSliderStyle = css`
.label.disabled {
color: var(--secondary-text-color);
}
-
.buttons {
position: absolute;
bottom: 10px;
@@ -67,6 +66,9 @@ export const stateControlCircularSliderStyle = css`
align-items: center;
justify-content: center;
}
+ .primary-state {
+ font-size: 36px;
+ }
.buttons ha-outlined-icon-button {
--md-outlined-icon-button-container-width: 48px;
@@ -77,6 +79,9 @@ export const stateControlCircularSliderStyle = css`
.container.md ha-big-number {
font-size: 44px;
}
+ .container.md .state {
+ font-size: 30px;
+ }
.container.md .info {
margin-top: 12px;
gap: 6px;
@@ -91,6 +96,9 @@ export const stateControlCircularSliderStyle = css`
.container.sm ha-big-number {
font-size: 32px;
}
+ .container.sm .state {
+ font-size: 26px;
+ }
.container.sm .info {
margin-top: 12px;
font-size: 14px;
@@ -107,6 +115,9 @@ export const stateControlCircularSliderStyle = css`
.container.xs ha-big-number {
font-size: 32px;
}
+ .container.xs .state {
+ font-size: 16px;
+ }
.container.xs .info {
margin-top: 12px;
}
From 249c89669e67d420918609df807aa5aa47d5b2cb Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 4 Jan 2024 13:11:06 -0500
Subject: [PATCH 086/361] Update dependency systemjs to v6.14.3 (#19282)
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 8f2a790e78e0..c512c677b083 100644
--- a/package.json
+++ b/package.json
@@ -233,7 +233,7 @@
"serve-handler": "6.1.5",
"sinon": "17.0.1",
"source-map-url": "0.4.1",
- "systemjs": "6.14.2",
+ "systemjs": "6.14.3",
"tar": "6.2.0",
"terser-webpack-plugin": "5.3.10",
"ts-lit-plugin": "2.0.1",
diff --git a/yarn.lock b/yarn.lock
index 59d16bf0e735..7f38d4b8e0d3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9700,7 +9700,7 @@ __metadata:
source-map-url: "npm:0.4.1"
stacktrace-js: "npm:2.0.2"
superstruct: "npm:1.0.3"
- systemjs: "npm:6.14.2"
+ systemjs: "npm:6.14.3"
tar: "npm:6.2.0"
terser-webpack-plugin: "npm:5.3.10"
tinykeys: "npm:2.1.0"
@@ -14931,10 +14931,10 @@ __metadata:
languageName: node
linkType: hard
-"systemjs@npm:6.14.2":
- version: 6.14.2
- resolution: "systemjs@npm:6.14.2"
- checksum: 5e126987ab10c3a19c3134d1ca82ab18cbf05018b396b0cc64c31c9cd561e5129f134cd0985d1987d7f82bd115a9b03182658ea76d612c58e8acfd446cda550f
+"systemjs@npm:6.14.3":
+ version: 6.14.3
+ resolution: "systemjs@npm:6.14.3"
+ checksum: 5d79c3b7dbd68b246fba6a9fe2372b88765c61cb1dbbd550beaaae0a4b38a1f19de302e203f2106845f959d00c1e7f9976bccf9b0527e907d5f3d8b5c6c5f61a
languageName: node
linkType: hard
From 554e5b7be55f2898fd3a251a9a657a2da30d780b Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 4 Jan 2024 19:48:57 -0500
Subject: [PATCH 087/361] Update typescript-eslint monorepo to v6.17.0 (#19286)
---
package.json | 4 +-
yarn.lock | 104 +++++++++++++++++++++++++--------------------------
2 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/package.json b/package.json
index c512c677b083..492548711772 100644
--- a/package.json
+++ b/package.json
@@ -184,8 +184,8 @@
"@types/tar": "6.1.10",
"@types/ua-parser-js": "0.7.39",
"@types/webspeechapi": "0.0.29",
- "@typescript-eslint/eslint-plugin": "6.16.0",
- "@typescript-eslint/parser": "6.16.0",
+ "@typescript-eslint/eslint-plugin": "6.17.0",
+ "@typescript-eslint/parser": "6.17.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 7f38d4b8e0d3..d96a28098a86 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4563,15 +4563,15 @@ __metadata:
languageName: node
linkType: hard
-"@typescript-eslint/eslint-plugin@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/eslint-plugin@npm:6.16.0"
+"@typescript-eslint/eslint-plugin@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/eslint-plugin@npm:6.17.0"
dependencies:
"@eslint-community/regexpp": "npm:^4.5.1"
- "@typescript-eslint/scope-manager": "npm:6.16.0"
- "@typescript-eslint/type-utils": "npm:6.16.0"
- "@typescript-eslint/utils": "npm:6.16.0"
- "@typescript-eslint/visitor-keys": "npm:6.16.0"
+ "@typescript-eslint/scope-manager": "npm:6.17.0"
+ "@typescript-eslint/type-utils": "npm:6.17.0"
+ "@typescript-eslint/utils": "npm:6.17.0"
+ "@typescript-eslint/visitor-keys": "npm:6.17.0"
debug: "npm:^4.3.4"
graphemer: "npm:^1.4.0"
ignore: "npm:^5.2.4"
@@ -4584,44 +4584,44 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 4bedce948ac3c20492a59813ee5d4f1f2306310857864dfaac2736f6c38e18785002c36844fd64c9fbdf3059fc390b29412be105fd7a118177f1eeeb1eb533f7
+ checksum: f2a5774e9cc03e491a5a488501e5622c7eebd766f5a4fc2c30642864a3b89b0807946bde33a678f326ba7032f3f6a51aa0bf9c2d10adc823804fc9fb47db55a6
languageName: node
linkType: hard
-"@typescript-eslint/parser@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/parser@npm:6.16.0"
+"@typescript-eslint/parser@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/parser@npm:6.17.0"
dependencies:
- "@typescript-eslint/scope-manager": "npm:6.16.0"
- "@typescript-eslint/types": "npm:6.16.0"
- "@typescript-eslint/typescript-estree": "npm:6.16.0"
- "@typescript-eslint/visitor-keys": "npm:6.16.0"
+ "@typescript-eslint/scope-manager": "npm:6.17.0"
+ "@typescript-eslint/types": "npm:6.17.0"
+ "@typescript-eslint/typescript-estree": "npm:6.17.0"
+ "@typescript-eslint/visitor-keys": "npm:6.17.0"
debug: "npm:^4.3.4"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
- checksum: 3d941ce345dc2ce29957e2110957662873d514b094b8939923c3281d858c11cd1f9058db862644afe14f68d087770f39a0a1f9e523a2013ed5d2fdf3421b34d0
+ checksum: 2ed0ed4a5b30e953430ce3279df3655af09fa1caed2abf11804d239717daefc32a22864f6620ef57bb9c684c74a99a13241384fea5096e961385e3678fc2e920
languageName: node
linkType: hard
-"@typescript-eslint/scope-manager@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/scope-manager@npm:6.16.0"
+"@typescript-eslint/scope-manager@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/scope-manager@npm:6.17.0"
dependencies:
- "@typescript-eslint/types": "npm:6.16.0"
- "@typescript-eslint/visitor-keys": "npm:6.16.0"
- checksum: 3360aae4b85f5c31d20ad48d771cc09a6f8f6b1811b00d94f06e55b5a09c610ac75631b1c4edecb3bec682d41351b87e7d14d42bee84aa032064d0e13463035b
+ "@typescript-eslint/types": "npm:6.17.0"
+ "@typescript-eslint/visitor-keys": "npm:6.17.0"
+ checksum: fe09c628553c9336e6a36d32c1d34e78ebd20aa02130a6bf535329621ba5a98aaac171f607bc6e4d17b3478c42e7de6476376636897ce3f227c754eb99acd07e
languageName: node
linkType: hard
-"@typescript-eslint/type-utils@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/type-utils@npm:6.16.0"
+"@typescript-eslint/type-utils@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/type-utils@npm:6.17.0"
dependencies:
- "@typescript-eslint/typescript-estree": "npm:6.16.0"
- "@typescript-eslint/utils": "npm:6.16.0"
+ "@typescript-eslint/typescript-estree": "npm:6.17.0"
+ "@typescript-eslint/utils": "npm:6.17.0"
debug: "npm:^4.3.4"
ts-api-utils: "npm:^1.0.1"
peerDependencies:
@@ -4629,23 +4629,23 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 5964b87a87252bed278a248eb568902babd7c34defd3af8c3df371926d96aec716f33f1dc14bde170e93f73ed1b0af6e591e647853d0f33f378e2c7b3b73fc5b
+ checksum: dc7938429193acfda61b7282197ec046039e2c4da41cdcddf4daaf300d10229e4e23bb0fcf0503b19c0b99a874849c8a9f5bb35ce106260f56a14106d2b41d8c
languageName: node
linkType: hard
-"@typescript-eslint/types@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/types@npm:6.16.0"
- checksum: 236ca318c2440c95068e5d4d147e2bfed62447775e18695e21c8ca04a341a74d01c37ed2b417629b7bf2fb91ad4fd5e2a6570215d16fc24dd1507ce6973b4e22
+"@typescript-eslint/types@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/types@npm:6.17.0"
+ checksum: 87ab1b5a3270ab34b917c22a2fb90a9ad7d9f3b19d73a337bc9efbe65f924da13482c97e8ccbe3bd3d081aa96039eeff50de41c1da2a2128066429b931cdb21d
languageName: node
linkType: hard
-"@typescript-eslint/typescript-estree@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/typescript-estree@npm:6.16.0"
+"@typescript-eslint/typescript-estree@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/typescript-estree@npm:6.17.0"
dependencies:
- "@typescript-eslint/types": "npm:6.16.0"
- "@typescript-eslint/visitor-keys": "npm:6.16.0"
+ "@typescript-eslint/types": "npm:6.17.0"
+ "@typescript-eslint/visitor-keys": "npm:6.17.0"
debug: "npm:^4.3.4"
globby: "npm:^11.1.0"
is-glob: "npm:^4.0.3"
@@ -4655,34 +4655,34 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
- checksum: 8e1ef03ecabaf3791b11240a51217836dbb74850e458258db77ac5eab5508cd9c63fb671924993d1e7654718c0c857c3550d51ecba0845fe489d143bb858e1b1
+ checksum: 1671b0d2f2fdf07074fb1e2524d61935cec173bd8db6e482cc5b2dcc77aed3ffa831396736ffa0ee2fdbddd8585ae9ca8d6c97bcaea1385b23907a1ec0508f83
languageName: node
linkType: hard
-"@typescript-eslint/utils@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/utils@npm:6.16.0"
+"@typescript-eslint/utils@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/utils@npm:6.17.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.4.0"
"@types/json-schema": "npm:^7.0.12"
"@types/semver": "npm:^7.5.0"
- "@typescript-eslint/scope-manager": "npm:6.16.0"
- "@typescript-eslint/types": "npm:6.16.0"
- "@typescript-eslint/typescript-estree": "npm:6.16.0"
+ "@typescript-eslint/scope-manager": "npm:6.17.0"
+ "@typescript-eslint/types": "npm:6.17.0"
+ "@typescript-eslint/typescript-estree": "npm:6.17.0"
semver: "npm:^7.5.4"
peerDependencies:
eslint: ^7.0.0 || ^8.0.0
- checksum: 84dd02f7c8e47fae699cc222da5cbea08b28c6e1cc7827860430bc86c2a17ee3f86e198a4356902b95930f85785aa662266ea9c476f69bf80c6a5f648e55f9f4
+ checksum: 37c63afcf66124bf84808699997953b8c84a378aa2c490a771b611d82cdac8499c58fac8eeb8378528e97660b59563d99297bfec4b982cd68760b0ffe54aa714
languageName: node
linkType: hard
-"@typescript-eslint/visitor-keys@npm:6.16.0":
- version: 6.16.0
- resolution: "@typescript-eslint/visitor-keys@npm:6.16.0"
+"@typescript-eslint/visitor-keys@npm:6.17.0":
+ version: 6.17.0
+ resolution: "@typescript-eslint/visitor-keys@npm:6.17.0"
dependencies:
- "@typescript-eslint/types": "npm:6.16.0"
+ "@typescript-eslint/types": "npm:6.17.0"
eslint-visitor-keys: "npm:^3.4.1"
- checksum: 19e559f14ea0092585a374b8c5f1aca9b6b271fc23909d9857de9cf71a1e1d3abc0afd237e9c02d7a5fbdfe8e3be7853cf9fedf40a6f16bac3495cb7f4e67982
+ checksum: a2aed0e1437fdab8858ab9c7c8e355f8b72a5fa4b0adc54f28b8a2bbc29d4bb93214968ee940f83d013d0a4b83d00cd4eeeb05fb4c2c7d0ead324c6793f7d6d4
languageName: node
linkType: hard
@@ -9610,8 +9610,8 @@ __metadata:
"@types/tar": "npm:6.1.10"
"@types/ua-parser-js": "npm:0.7.39"
"@types/webspeechapi": "npm:0.0.29"
- "@typescript-eslint/eslint-plugin": "npm:6.16.0"
- "@typescript-eslint/parser": "npm:6.16.0"
+ "@typescript-eslint/eslint-plugin": "npm:6.17.0"
+ "@typescript-eslint/parser": "npm:6.17.0"
"@vaadin/combo-box": "npm:24.3.2"
"@vaadin/vaadin-themable-mixin": "npm:24.3.2"
"@vibrant/color": "npm:3.2.1-alpha.1"
From be7b3a56f9ca933f4869d6947310ddc2a0772f40 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 4 Jan 2024 20:36:13 -0500
Subject: [PATCH 088/361] Update dependency core-js to v3.35.0 (#19215)
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 492548711772..ce2e0a01eb14 100644
--- a/package.json
+++ b/package.json
@@ -101,7 +101,7 @@
"app-datepicker": "5.1.1",
"chart.js": "4.4.1",
"comlink": "4.4.1",
- "core-js": "3.34.0",
+ "core-js": "3.35.0",
"cropperjs": "1.6.1",
"date-fns": "2.30.0",
"date-fns-tz": "2.0.0",
diff --git a/yarn.lock b/yarn.lock
index d96a28098a86..44814ecb620e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7024,10 +7024,10 @@ __metadata:
languageName: node
linkType: hard
-"core-js@npm:3.34.0":
- version: 3.34.0
- resolution: "core-js@npm:3.34.0"
- checksum: 054474ab6a0a08a2277ca2c1c953e5789c562bbe144f6a43786b0f4167b4a76c671833bd0a112e275e1d99d84fa157e64814ff23aa01532e08e3b46403d7f7f4
+"core-js@npm:3.35.0":
+ version: 3.35.0
+ resolution: "core-js@npm:3.35.0"
+ checksum: 0815fce6bcc91d79d4b28885975453b0faa4d17fc2230635102b4f3832cd621035e4032aa3307e1dbe0ee14d5e34bcb64b507fd89bd8f567aedaf29538522e6a
languageName: node
linkType: hard
@@ -9628,7 +9628,7 @@ __metadata:
chai: "npm:5.0.0"
chart.js: "npm:4.4.1"
comlink: "npm:4.4.1"
- core-js: "npm:3.34.0"
+ core-js: "npm:3.35.0"
cropperjs: "npm:1.6.1"
date-fns: "npm:2.30.0"
date-fns-tz: "npm:2.0.0"
From 53be012b3454b4c1dd34a4bb30b20b2d96ae0008 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 4 Jan 2024 20:42:11 -0500
Subject: [PATCH 089/361] Update CodeMirror (#19214)
---
package.json | 8 ++++----
yarn.lock | 46 +++++++++++++++++++++++-----------------------
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/package.json b/package.json
index ce2e0a01eb14..a466d708db51 100644
--- a/package.json
+++ b/package.json
@@ -28,12 +28,12 @@
"@babel/runtime": "7.23.7",
"@braintree/sanitize-url": "7.0.0",
"@codemirror/autocomplete": "6.11.1",
- "@codemirror/commands": "6.3.2",
- "@codemirror/language": "6.9.3",
+ "@codemirror/commands": "6.3.3",
+ "@codemirror/language": "6.10.0",
"@codemirror/legacy-modes": "6.3.3",
"@codemirror/search": "6.5.5",
- "@codemirror/state": "6.3.3",
- "@codemirror/view": "6.22.3",
+ "@codemirror/state": "6.4.0",
+ "@codemirror/view": "6.23.0",
"@egjs/hammerjs": "2.0.17",
"@formatjs/intl-datetimeformat": "6.12.0",
"@formatjs/intl-displaynames": "6.6.4",
diff --git a/yarn.lock b/yarn.lock
index 44814ecb620e..49ff1a2017b5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1474,29 +1474,29 @@ __metadata:
languageName: node
linkType: hard
-"@codemirror/commands@npm:6.3.2":
- version: 6.3.2
- resolution: "@codemirror/commands@npm:6.3.2"
+"@codemirror/commands@npm:6.3.3":
+ version: 6.3.3
+ resolution: "@codemirror/commands@npm:6.3.3"
dependencies:
"@codemirror/language": "npm:^6.0.0"
- "@codemirror/state": "npm:^6.2.0"
+ "@codemirror/state": "npm:^6.4.0"
"@codemirror/view": "npm:^6.0.0"
"@lezer/common": "npm:^1.1.0"
- checksum: 85bf8242645e3f8c52b143883e837277795f9c50ad76f28f72d0d55ec921750f15ef5b4fa156b37e123b51e540d96c8db89b48bf0460cbe4a6f7b57271a65ba6
+ checksum: 4b398b102d6afcbf0e0018b426287a7458867497811c9155790a3cc679b880765cd756bdb96bf35abc28fecb85c0938e618d39469ce8bc0724d4dea5d88f6ac2
languageName: node
linkType: hard
-"@codemirror/language@npm:6.9.3, @codemirror/language@npm:^6.0.0":
- version: 6.9.3
- resolution: "@codemirror/language@npm:6.9.3"
+"@codemirror/language@npm:6.10.0, @codemirror/language@npm:^6.0.0":
+ version: 6.10.0
+ resolution: "@codemirror/language@npm:6.10.0"
dependencies:
"@codemirror/state": "npm:^6.0.0"
- "@codemirror/view": "npm:^6.0.0"
+ "@codemirror/view": "npm:^6.23.0"
"@lezer/common": "npm:^1.1.0"
"@lezer/highlight": "npm:^1.0.0"
"@lezer/lr": "npm:^1.0.0"
style-mod: "npm:^4.0.0"
- checksum: 331230a3876ed469cbf18dc2733040aa42a175b1a038080e4c317cf7f1fd8e929dc6838ba4749ea52992805f20be85878214cab6e0e7c7ab5fda872844611b7a
+ checksum: 674f87a5f7cae19a5e0cbdd0e06beade7f3694809cc30b31939aa04790dd43008942e3cd3b537ba5729fd14fed81c8ff62b7dcf51800db815cbf8d19d1d6a763
languageName: node
linkType: hard
@@ -1520,21 +1520,21 @@ __metadata:
languageName: node
linkType: hard
-"@codemirror/state@npm:6.3.3, @codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.4, @codemirror/state@npm:^6.2.0":
- version: 6.3.3
- resolution: "@codemirror/state@npm:6.3.3"
- checksum: c0db0fc943ed36925238242522a8f4b2a4e3ecc4489cc013ea6d32be2bc615ecd813c98ff6a4c8f8ec1179376e555ec93a07dc1f0d1751aae721b5b38f812c08
+"@codemirror/state@npm:6.4.0, @codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.4.0":
+ version: 6.4.0
+ resolution: "@codemirror/state@npm:6.4.0"
+ checksum: d9129c456d1589ca376594620bad10c51d3dcdb57950f34637cea0e2ea073a695d426dc1cfc9b909b07365c236a6312da1eaf740c384c853009742493b8c9935
languageName: node
linkType: hard
-"@codemirror/view@npm:6.22.3, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0":
- version: 6.22.3
- resolution: "@codemirror/view@npm:6.22.3"
+"@codemirror/view@npm:6.23.0, @codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0":
+ version: 6.23.0
+ resolution: "@codemirror/view@npm:6.23.0"
dependencies:
- "@codemirror/state": "npm:^6.1.4"
+ "@codemirror/state": "npm:^6.4.0"
style-mod: "npm:^4.1.0"
w3c-keyname: "npm:^2.2.4"
- checksum: c0ad3e9ab49ca9aba214cfe317e506f25d094bb3243cafd0309093279eb99084810f289a5cc019db6c35463813707bdc31557b28afb30d390f4736dd0dadc541
+ checksum: 3fc1c39e6d0b2550d3f4e207705f953956baa7ce768eed0258373260db86f65ae3c1eea050e8fdfe3266d4f365828f90f4341cea71b0f0e4f19515a5341e5706
languageName: node
linkType: hard
@@ -9521,12 +9521,12 @@ __metadata:
"@braintree/sanitize-url": "npm:7.0.0"
"@bundle-stats/plugin-webpack-filter": "npm:4.8.4"
"@codemirror/autocomplete": "npm:6.11.1"
- "@codemirror/commands": "npm:6.3.2"
- "@codemirror/language": "npm:6.9.3"
+ "@codemirror/commands": "npm:6.3.3"
+ "@codemirror/language": "npm:6.10.0"
"@codemirror/legacy-modes": "npm:6.3.3"
"@codemirror/search": "npm:6.5.5"
- "@codemirror/state": "npm:6.3.3"
- "@codemirror/view": "npm:6.22.3"
+ "@codemirror/state": "npm:6.4.0"
+ "@codemirror/view": "npm:6.23.0"
"@egjs/hammerjs": "npm:2.0.17"
"@formatjs/intl-datetimeformat": "npm:6.12.0"
"@formatjs/intl-displaynames": "npm:6.6.4"
From 7a8f5c0cc93722334cf20ff9012508ab691d1719 Mon Sep 17 00:00:00 2001
From: Simon Lamon <32477463+silamon@users.noreply.github.com>
Date: Fri, 5 Jan 2024 14:31:58 +0100
Subject: [PATCH 090/361] Replace remaining paper inputs (#19292)
---
.../components/supervisor-backup-content.ts | 36 +++++++--------
.../dialogs/network/dialog-hassio-network.ts | 46 +++++++++----------
.../dialog-hassio-repositories.ts | 10 ++--
package.json | 1 -
yarn.lock | 39 ----------------
5 files changed, 44 insertions(+), 88 deletions(-)
diff --git a/hassio/src/components/supervisor-backup-content.ts b/hassio/src/components/supervisor-backup-content.ts
index 8174debcefc5..ff67b511c023 100644
--- a/hassio/src/components/supervisor-backup-content.ts
+++ b/hassio/src/components/supervisor-backup-content.ts
@@ -1,6 +1,4 @@
import { mdiFolder, mdiPuzzle } from "@mdi/js";
-import "@polymer/paper-input/paper-input";
-import type { PaperInputElement } from "@polymer/paper-input/paper-input";
import {
CSSResultGroup,
LitElement,
@@ -16,6 +14,7 @@ import { formatDateTime } from "../../../src/common/datetime/format_date_time";
import { LocalizeFunc } from "../../../src/common/translations/localize";
import "../../../src/components/ha-checkbox";
import "../../../src/components/ha-formfield";
+import "../../../src/components/ha-textfield";
import "../../../src/components/ha-radio";
import type { HaRadio } from "../../../src/components/ha-radio";
import {
@@ -25,12 +24,9 @@ import {
} from "../../../src/data/hassio/backup";
import { Supervisor } from "../../../src/data/supervisor/supervisor";
import { mdiHomeAssistant } from "../../../src/resources/home-assistant-logo-svg";
-import {
- HomeAssistant,
- TranslationDict,
- ValueChangedEvent,
-} from "../../../src/types";
+import { HomeAssistant, TranslationDict } from "../../../src/types";
import "./supervisor-formfield-label";
+import type { HaTextField } from "../../../src/components/ha-textfield";
type BackupOrRestoreKey = keyof TranslationDict["supervisor"]["backup"] &
keyof TranslationDict["ui"]["panel"]["page-onboarding"]["restore"];
@@ -100,7 +96,7 @@ export class SupervisorBackupContent extends LitElement {
@property() public confirmBackupPassword = "";
- @query("paper-input, ha-radio, ha-checkbox", true) private _focusTarget;
+ @query("ha-textfield, ha-radio, ha-checkbox", true) private _focusTarget;
public willUpdate(changedProps) {
super.willUpdate(changedProps);
@@ -151,13 +147,13 @@ export class SupervisorBackupContent extends LitElement {
)
: this.backup.date}
`
- : html`
- `}
+ `}
${!this.backup || this.backup.type === "full"
? html`
${this._interface![version].method === "static"
? html`
-
-
-
+
-
-
+
-
+
`
: ""}
@@ -517,11 +517,11 @@ export class DialogHassioNetwork
this.requestUpdate("_wifiConfiguration");
}
- private _handleInputValueChanged(ev: CustomEvent): void {
- const value: string | null | undefined = (ev.target as PaperInputElement)
- .value;
+ private _handleInputValueChanged(ev: Event): void {
+ const source = ev.target as HaTextField;
+ const value = source.value;
const version = (ev.target as any).version as "ipv4" | "ipv6";
- const id = (ev.target as PaperInputElement).id;
+ const id = source.id;
if (
!value ||
@@ -535,10 +535,10 @@ export class DialogHassioNetwork
this._interface[version]![id] = value;
}
- private _handleInputValueChangedWifi(ev: CustomEvent): void {
- const value: string | null | undefined = (ev.target as PaperInputElement)
- .value;
- const id = (ev.target as PaperInputElement).id;
+ private _handleInputValueChangedWifi(ev: Event): void {
+ const source = ev.target as HaTextField;
+ const value = source.value;
+ const id = source.id;
if (
!value ||
@@ -630,7 +630,7 @@ export class DialogHassioNetwork
--expansion-panel-summary-padding: 0 16px;
margin: 4px 0;
}
- paper-input {
+ ha-textfield {
padding: 0 14px;
}
mwc-list-item {
diff --git a/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts b/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts
index 98dfc32b2417..5443d7ed44c1 100644
--- a/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts
+++ b/hassio/src/dialogs/repositories/dialog-hassio-repositories.ts
@@ -1,7 +1,5 @@
import "@material/mwc-button/mwc-button";
import { mdiDelete, mdiDeleteOff } from "@mdi/js";
-import "@polymer/paper-input/paper-input";
-import type { PaperInputElement } from "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
@@ -27,12 +25,14 @@ import {
import { haStyle, haStyleDialog } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../../src/types";
import { HassioRepositoryDialogParams } from "./show-dialog-repositories";
+import type { HaTextField } from "../../../../src/components/ha-textfield";
+import "../../../../src/components/ha-textfield";
@customElement("dialog-hassio-repositories")
class HassioRepositoriesDialog extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
- @query("#repository_input", true) private _optionInput?: PaperInputElement;
+ @query("#repository_input", true) private _optionInput?: HaTextField;
@state() private _repositories?: HassioAddonRepository[];
@@ -145,7 +145,7 @@ class HassioRepositoriesDialog extends LitElement {
)
: html` No repositories `}
-
+ >
${this._processing
? html`
Date: Fri, 5 Jan 2024 15:56:15 +0200
Subject: [PATCH 091/361] Fix for RTL in Supervisor dashboards (#19290)
---
hassio/src/dashboard/hassio-addons.ts | 1 +
hassio/src/dashboard/hassio-dashboard.ts | 2 ++
hassio/src/supervisor-base-element.ts | 10 ++++++++++
3 files changed, 13 insertions(+)
diff --git a/hassio/src/dashboard/hassio-addons.ts b/hassio/src/dashboard/hassio-addons.ts
index 7b3c9d166f0e..daeb867ef66d 100644
--- a/hassio/src/dashboard/hassio-addons.ts
+++ b/hassio/src/dashboard/hassio-addons.ts
@@ -128,6 +128,7 @@ class HassioAddons extends LitElement {
ha-card {
cursor: pointer;
overflow: hidden;
+ direction: ltr;
}
.search {
position: sticky;
diff --git a/hassio/src/dashboard/hassio-dashboard.ts b/hassio/src/dashboard/hassio-dashboard.ts
index d60819861c15..a38c37b8a822 100644
--- a/hassio/src/dashboard/hassio-dashboard.ts
+++ b/hassio/src/dashboard/hassio-dashboard.ts
@@ -133,6 +133,8 @@ class HassioDashboard extends LitElement {
position: fixed;
right: calc(16px + env(safe-area-inset-right));
bottom: calc(16px + env(safe-area-inset-bottom));
+ inset-inline-end: calc(16px + env(safe-area-inset-right));
+ inset-inline-start: initial;
z-index: 1;
}
`,
diff --git a/hassio/src/supervisor-base-element.ts b/hassio/src/supervisor-base-element.ts
index 9402728160de..86dc81998887 100644
--- a/hassio/src/supervisor-base-element.ts
+++ b/hassio/src/supervisor-base-element.ts
@@ -29,6 +29,10 @@ import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
import { HomeAssistant, Route } from "../../src/types";
import { getTranslation } from "../../src/util/common-translation";
+import {
+ computeRTLDirection,
+ setDirectionStyles,
+} from "../../src/common/util/compute_rtl";
declare global {
interface HASSDomEvents {
@@ -95,6 +99,7 @@ export class SupervisorBaseElement extends urlSyncMixin(
if (changedProperties.has("_language") || !this.hasUpdated) {
this._initializeLocalize();
+ this._applyDirection(this.hass);
}
}
@@ -215,4 +220,9 @@ export class SupervisorBaseElement extends urlSyncMixin(
);
}
}
+
+ private _applyDirection(hass: HomeAssistant) {
+ const direction = computeRTLDirection(hass);
+ setDirectionStyles(direction, this);
+ }
}
From 8960f5fef9b32a1b4c11949783b26bec5f3dd087 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Sat, 6 Jan 2024 20:50:10 -0500
Subject: [PATCH 092/361] Update dependency @types/luxon to v3.3.8 (#19308)
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index b7a0cba7a7ca..0c7a6998ca19 100644
--- a/package.json
+++ b/package.json
@@ -175,7 +175,7 @@
"@types/js-yaml": "4.0.9",
"@types/leaflet": "1.9.8",
"@types/leaflet-draw": "1.0.11",
- "@types/luxon": "3.3.7",
+ "@types/luxon": "3.3.8",
"@types/mocha": "10.0.6",
"@types/qrcode": "1.5.5",
"@types/serve-handler": "6.1.4",
diff --git a/yarn.lock b/yarn.lock
index c43ac1d4b56f..ef48030ab766 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4271,10 +4271,10 @@ __metadata:
languageName: node
linkType: hard
-"@types/luxon@npm:3.3.7":
- version: 3.3.7
- resolution: "@types/luxon@npm:3.3.7"
- checksum: 282ac72fd55da0c9d57f376ba9061ce83506cf6239c32259dacde0800964089f6183d2e449ef2ddd89b079fb8bfdffd7e5dbf187eb5c9f106aeaeca2aa60ed09
+"@types/luxon@npm:3.3.8":
+ version: 3.3.8
+ resolution: "@types/luxon@npm:3.3.8"
+ checksum: 2176c394e7ee3b8580e9f30bedac29048fabe32589c6561a9654b242b9c2c08ff9b93206f0eca07e495f900a352ac1446236c310eacda574b3c2d6238a9173a7
languageName: node
linkType: hard
@@ -9563,7 +9563,7 @@ __metadata:
"@types/js-yaml": "npm:4.0.9"
"@types/leaflet": "npm:1.9.8"
"@types/leaflet-draw": "npm:1.0.11"
- "@types/luxon": "npm:3.3.7"
+ "@types/luxon": "npm:3.3.8"
"@types/mocha": "npm:10.0.6"
"@types/qrcode": "npm:1.5.5"
"@types/serve-handler": "npm:6.1.4"
From 90965a4f4db29fdb03647c16c9000c6bcdc99244 Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Sat, 6 Jan 2024 20:19:44 -0800
Subject: [PATCH 093/361] Localize statistics datatable string (#19289)
---
.../developer-tools/statistics/developer-tools-statistics.ts | 4 +++-
src/translations/en.json | 3 ++-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/panels/developer-tools/statistics/developer-tools-statistics.ts b/src/panels/developer-tools/statistics/developer-tools-statistics.ts
index 878a4fa73978..25339a91e27c 100644
--- a/src/panels/developer-tools/statistics/developer-tools-statistics.ts
+++ b/src/panels/developer-tools/statistics/developer-tools-statistics.ts
@@ -177,7 +177,9 @@ class HaPanelDevStatistics extends SubscribeMixin(LitElement) {
.hass=${this.hass}
.columns=${this._columns(this.hass.localize)}
.data=${this._displayData(this._data, this.hass.localize)}
- noDataText="No statistics"
+ .noDataText=${this.hass.localize(
+ "ui.panel.developer-tools.tabs.statistics.data_table.no_statistics"
+ )}
id="statistic_id"
clickable
@row-click=${this._rowClicked}
diff --git a/src/translations/en.json b/src/translations/en.json
index 74467bcbf1ab..01cd81a568e1 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -6190,7 +6190,8 @@
"statistic_id": "Statistic id",
"statistics_unit": "Statistics unit",
"source": "Source",
- "issue": "Issue"
+ "issue": "Issue",
+ "no_statistics": "[%key:ui::components::statistics_charts::no_statistics_found%]"
}
},
"yaml": {
From 17e62c10d49d1823cab2874deae88232ca92e6f1 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 8 Jan 2024 08:17:13 +0100
Subject: [PATCH 094/361] Bump home-assistant/wheels from 2023.10.5 to
2024.01.0 (#19321)
---
.github/workflows/release.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 8bded3fcc5e2..dc843252dd02 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -74,7 +74,7 @@ jobs:
echo "home-assistant-frontend==$version" > ./requirements.txt
- name: Build wheels
- uses: home-assistant/wheels@2023.10.5
+ uses: home-assistant/wheels@2024.01.0
with:
abi: cp311
tag: musllinux_1_2
From 104aef3dec2e8856d5323aecad9fea9666301776 Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Mon, 8 Jan 2024 14:02:41 +0100
Subject: [PATCH 095/361] Add ha-sortable component (#19294)
---
.../ha-selector/ha-selector-select.ts | 175 ++++----
src/components/ha-sidebar.ts | 111 ++---
src/components/ha-sortable.ts | 153 +++++++
src/dialogs/area-filter/area-filter-dialog.ts | 144 +++----
.../ha-more-info-light-favorite-colors.ts | 182 ++++----
.../automation/action/ha-automation-action.ts | 221 +++++-----
.../types/ha-automation-action-choose.ts | 387 ++++++++----------
.../condition/ha-automation-condition.ts | 228 +++++------
.../trigger/ha-automation-trigger.ts | 233 +++++------
.../helpers/forms/ha-input_select-form.ts | 122 ++----
src/panels/config/script/ha-script-fields.ts | 24 +-
.../lovelace/cards/hui-todo-list-card.ts | 320 +++++++--------
.../lovelace/components/hui-entity-editor.ts | 160 +++-----
.../hui-card-features-editor.ts | 310 ++++++--------
.../editor/hui-entities-card-row-editor.ts | 279 ++++++-------
...able-style.ts => ha-sidebar-edit-style.ts} | 30 +-
16 files changed, 1371 insertions(+), 1708 deletions(-)
create mode 100644 src/components/ha-sortable.ts
rename src/resources/{ha-sortable-style.ts => ha-sidebar-edit-style.ts} (74%)
diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts
index a20559f91bfe..0f1301d28680 100644
--- a/src/components/ha-selector/ha-selector-select.ts
+++ b/src/components/ha-selector/ha-selector-select.ts
@@ -1,16 +1,13 @@
import "@material/mwc-list/mwc-list-item";
import { mdiDrag } from "@mdi/js";
-import { LitElement, PropertyValues, css, html, nothing } from "lit";
+import { LitElement, css, html, nothing } from "lit";
import { customElement, property, query } from "lit/decorators";
import { repeat } from "lit/directives/repeat";
-import { SortableEvent } from "sortablejs";
import { ensureArray } from "../../common/array/ensure-array";
import { fireEvent } from "../../common/dom/fire_event";
import { stopPropagation } from "../../common/dom/stop_propagation";
import { caseInsensitiveStringCompare } from "../../common/string/compare";
import type { SelectOption, SelectSelector } from "../../data/selector";
-import { sortableStyles } from "../../resources/ha-sortable-style";
-import { SortableInstance } from "../../resources/sortable";
import type { HomeAssistant } from "../../types";
import "../chips/ha-chip-set";
import "../chips/ha-input-chip";
@@ -21,6 +18,7 @@ import "../ha-formfield";
import "../ha-input-helper-text";
import "../ha-radio";
import "../ha-select";
+import "../ha-sortable";
@customElement("ha-selector-select")
export class HaSelectSelector extends LitElement {
@@ -42,50 +40,10 @@ export class HaSelectSelector extends LitElement {
@query("ha-combo-box", true) private comboBox!: HaComboBox;
- private _sortable?: SortableInstance;
-
- protected updated(changedProps: PropertyValues): void {
- if (changedProps.has("value") || changedProps.has("selector")) {
- const sortableNeeded =
- this.selector.select?.multiple &&
- this.selector.select.reorder &&
- this.value?.length;
- if (!this._sortable && sortableNeeded) {
- this._createSortable();
- } else if (this._sortable && !sortableNeeded) {
- this._destroySortable();
- }
- }
- }
-
- private async _createSortable() {
- const Sortable = (await import("../../resources/sortable")).default;
- this._sortable = new Sortable(
- this.shadowRoot!.querySelector("ha-chip-set")!,
- {
- animation: 150,
- fallbackClass: "sortable-fallback",
- draggable: "ha-input-chip",
- onChoose: (evt: SortableEvent) => {
- (evt.item as any).placeholder =
- document.createComment("sort-placeholder");
- evt.item.after((evt.item as any).placeholder);
- },
- onEnd: (evt: SortableEvent) => {
- // put back in original location
- if ((evt.item as any).placeholder) {
- (evt.item as any).placeholder.replaceWith(evt.item);
- delete (evt.item as any).placeholder;
- }
- this._dragged(evt);
- },
- }
- );
- }
-
- private _dragged(ev: SortableEvent): void {
- if (ev.oldIndex === ev.newIndex) return;
- this._move(ev.oldIndex!, ev.newIndex!);
+ private _itemMoved(ev: CustomEvent): void {
+ ev.stopPropagation();
+ const { oldIndex, newIndex } = ev.detail;
+ this._move(oldIndex!, newIndex);
}
private _move(index: number, newIndex: number) {
@@ -99,11 +57,6 @@ export class HaSelectSelector extends LitElement {
});
}
- private _destroySortable() {
- this._sortable?.destroy();
- this._sortable = undefined;
- }
-
private _filter = "";
protected render() {
@@ -195,37 +148,43 @@ export class HaSelectSelector extends LitElement {
return html`
${value?.length
? html`
-
- ${repeat(
- value,
- (item) => item,
- (item, idx) => {
- const label =
- options.find((option) => option.value === item)?.label ||
- item;
- return html`
-
- ${this.selector.select?.reorder
- ? html`
-
- `
- : nothing}
- ${options.find((option) => option.value === item)
- ?.label || item}
-
- `;
- }
- )}
-
+
+
+ ${repeat(
+ value,
+ (item) => item,
+ (item, idx) => {
+ const label =
+ options.find((option) => option.value === item)
+ ?.label || item;
+ return html`
+
+ ${this.selector.select?.reorder
+ ? html`
+
+ `
+ : nothing}
+ ${options.find((option) => option.value === item)
+ ?.label || item}
+
+ `;
+ }
+ )}
+
+
`
: nothing}
@@ -419,25 +378,35 @@ export class HaSelectSelector extends LitElement {
this.comboBox.filteredItems = filteredItems;
}
- static styles = [
- sortableStyles,
- css`
- :host {
- position: relative;
- }
- ha-select,
- mwc-formfield,
- ha-formfield {
- display: block;
- }
- mwc-list-item[disabled] {
- --mdc-theme-text-primary-on-background: var(--disabled-text-color);
- }
- ha-chip-set {
- padding: 8px 0;
- }
- `,
- ];
+ static styles = css`
+ :host {
+ position: relative;
+ }
+ ha-select,
+ mwc-formfield,
+ ha-formfield {
+ display: block;
+ }
+ mwc-list-item[disabled] {
+ --mdc-theme-text-primary-on-background: var(--disabled-text-color);
+ }
+ ha-chip-set {
+ padding: 8px 0;
+ }
+
+ .sortable-fallback {
+ display: none;
+ opacity: 0;
+ }
+
+ .sortable-ghost {
+ opacity: 0.4;
+ }
+
+ .sortable-drag {
+ cursor: grabbing;
+ }
+ `;
}
declare global {
diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts
index 50b5e1cba96c..352f0130f98c 100644
--- a/src/components/ha-sidebar.ts
+++ b/src/components/ha-sidebar.ts
@@ -33,7 +33,6 @@ import {
} from "lit";
import { customElement, eventOptions, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
-import { guard } from "lit/directives/guard";
import memoizeOne from "memoize-one";
import { storage } from "../common/decorators/storage";
import { fireEvent } from "../common/dom/fire_event";
@@ -50,12 +49,12 @@ import { subscribeRepairsIssueRegistry } from "../data/repairs";
import { UpdateEntity, updateCanInstall } from "../data/update";
import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
-import type { SortableInstance } from "../resources/sortable";
import { haStyleScrollbar } from "../resources/styles";
import type { HomeAssistant, PanelInfo, Route } from "../types";
import "./ha-icon";
import "./ha-icon-button";
import "./ha-menu-button";
+import "./ha-sortable";
import "./ha-svg-icon";
import "./user/ha-user-badge";
@@ -204,15 +203,13 @@ class HaSidebar extends SubscribeMixin(LitElement) {
@state() private _issuesCount = 0;
- @state() private _renderEmptySortable = false;
-
private _mouseLeaveTimeout?: number;
private _tooltipHideTimeout?: number;
private _recentKeydownActiveUntil = 0;
- private sortableStyleLoaded = false;
+ private _editStyleLoaded = false;
@storage({
key: "sidebarPanelOrder",
@@ -228,8 +225,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
})
private _hiddenPanels: string[] = [];
- private _sortable?: SortableInstance;
-
public hassSubscribe(): UnsubscribeFunc[] {
return this.hass.user?.is_admin
? [
@@ -264,14 +259,13 @@ class HaSidebar extends SubscribeMixin(LitElement) {
changedProps.has("expanded") ||
changedProps.has("narrow") ||
changedProps.has("alwaysExpand") ||
+ changedProps.has("editMode") ||
changedProps.has("_externalConfig") ||
changedProps.has("_updatesCount") ||
changedProps.has("_issuesCount") ||
changedProps.has("_notifications") ||
- changedProps.has("editMode") ||
- changedProps.has("_renderEmptySortable") ||
changedProps.has("_hiddenPanels") ||
- (changedProps.has("_panelOrder") && !this.editMode)
+ changedProps.has("_panelOrder")
) {
return true;
}
@@ -306,12 +300,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
if (changedProps.has("alwaysExpand")) {
toggleAttribute(this, "expanded", this.alwaysExpand);
}
- if (changedProps.has("editMode")) {
- if (this.editMode) {
- this._activateEditMode();
- } else {
- this._deactivateEditMode();
- }
+ if (changedProps.has("editMode") && this.editMode) {
+ this._editModeActivated();
}
if (!changedProps.has("hass")) {
return;
@@ -470,15 +460,36 @@ class HaSidebar extends SubscribeMixin(LitElement) {
`;
}
+ private _panelMoved(ev: CustomEvent) {
+ ev.stopPropagation();
+ const { oldIndex, newIndex } = ev.detail;
+
+ const [beforeSpacer] = computePanels(
+ this.hass.panels,
+ this.hass.defaultPanel,
+ this._panelOrder,
+ this._hiddenPanels,
+ this.hass.locale
+ );
+
+ const panelOrder = beforeSpacer.map((panel) => panel.url_path);
+ const panel = panelOrder.splice(oldIndex, 1)[0];
+ panelOrder.splice(newIndex, 0, panel);
+
+ this._panelOrder = panelOrder;
+ }
+
private _renderPanelsEdit(beforeSpacer: PanelInfo[]) {
- // prettier-ignore
- return html`
- ${guard([this._hiddenPanels, this._renderEmptySortable], () =>
- this._renderEmptySortable ? "" : this._renderPanels(beforeSpacer)
- )}
-
- ${this._renderSpacer()}
- ${this._renderHiddenPanels()} `;
+ return html`
+
+ ${this._renderPanels(beforeSpacer)}
+
+ ${this._renderSpacer()}${this._renderHiddenPanels()}
+ `;
}
private _renderHiddenPanels() {
@@ -674,44 +685,22 @@ class HaSidebar extends SubscribeMixin(LitElement) {
fireEvent(this, "hass-edit-sidebar", { editMode: true });
}
- private async _activateEditMode() {
- await Promise.all([this._loadSortableStyle(), this._createSortable()]);
+ private async _editModeActivated() {
+ await this._loadEditStyle();
}
- private async _loadSortableStyle() {
- if (this.sortableStyleLoaded) return;
+ private async _loadEditStyle() {
+ if (this._editStyleLoaded) return;
- const sortStylesImport = await import("../resources/ha-sortable-style");
+ const editStylesImport = await import("../resources/ha-sidebar-edit-style");
const style = document.createElement("style");
- style.innerHTML = (sortStylesImport.sortableStyles as CSSResult).cssText;
+ style.innerHTML = (editStylesImport.sidebarEditStyle as CSSResult).cssText;
this.shadowRoot!.appendChild(style);
- this.sortableStyleLoaded = true;
await this.updateComplete;
}
- private async _createSortable() {
- const Sortable = (await import("../resources/sortable")).default;
- this._sortable = new Sortable(
- this.shadowRoot!.getElementById("sortable")!,
- {
- animation: 150,
- fallbackClass: "sortable-fallback",
- dataIdAttr: "data-panel",
- handle: "paper-icon-item",
- onSort: async () => {
- this._panelOrder = this._sortable!.toArray();
- },
- }
- );
- }
-
- private _deactivateEditMode() {
- this._sortable?.destroy();
- this._sortable = undefined;
- }
-
private _closeEditMode() {
fireEvent(this, "hass-edit-sidebar", { editMode: false });
}
@@ -724,13 +713,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
}
// Make a copy for Memoize
this._hiddenPanels = [...this._hiddenPanels, panel];
- this._renderEmptySortable = true;
- await this.updateComplete;
- const container = this.shadowRoot!.getElementById("sortable")!;
- while (container.lastElementChild) {
- container.removeChild(container.lastElementChild);
- }
- this._renderEmptySortable = false;
+ // Remove it from the panel order
+ this._panelOrder = this._panelOrder.filter((order) => order !== panel);
}
private async _unhidePanel(ev: Event) {
@@ -739,13 +723,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
this._hiddenPanels = this._hiddenPanels.filter(
(hidden) => hidden !== panel
);
- this._renderEmptySortable = true;
- await this.updateComplete;
- const container = this.shadowRoot!.getElementById("sortable")!;
- while (container.lastElementChild) {
- container.removeChild(container.lastElementChild);
- }
- this._renderEmptySortable = false;
}
private _itemMouseEnter(ev: MouseEvent) {
@@ -910,7 +887,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
.menu mwc-button {
width: 100%;
}
- #sortable,
+ .reorder-list,
.hidden-panel {
display: none;
}
diff --git a/src/components/ha-sortable.ts b/src/components/ha-sortable.ts
new file mode 100644
index 000000000000..aed068a83af7
--- /dev/null
+++ b/src/components/ha-sortable.ts
@@ -0,0 +1,153 @@
+/* eslint-disable lit/prefer-static-styles */
+import { html, LitElement, nothing, PropertyValues } from "lit";
+import { customElement, property } from "lit/decorators";
+import type { SortableEvent } from "sortablejs";
+import { fireEvent } from "../common/dom/fire_event";
+import type { SortableInstance } from "../resources/sortable";
+
+declare global {
+ interface HASSDomEvents {
+ "item-moved": {
+ oldIndex: number;
+ newIndex: number;
+ };
+ }
+}
+
+@customElement("ha-sortable")
+export class HaSortable extends LitElement {
+ private _sortable?: SortableInstance;
+
+ @property({ type: Boolean })
+ public disabled = false;
+
+ @property({ type: Boolean, attribute: "no-style" })
+ public noStyle: boolean = false;
+
+ @property({ type: String, attribute: "draggable-selector" })
+ public draggableSelector?: string;
+
+ @property({ type: String, attribute: "handle-selector" })
+ public handleSelector?: string;
+
+ protected updated(changedProperties: PropertyValues) {
+ if (changedProperties.has("disabled")) {
+ if (this.disabled) {
+ this._destroySortable();
+ } else {
+ this._createSortable();
+ }
+ }
+ }
+
+ // Workaround for connectedCallback just after disconnectedCallback (when dragging sortable with sortable children)
+ private _shouldBeDestroy = false;
+
+ public disconnectedCallback() {
+ super.disconnectedCallback();
+ this._shouldBeDestroy = true;
+ setTimeout(() => {
+ if (this._shouldBeDestroy) {
+ this._destroySortable();
+ this._shouldBeDestroy = false;
+ }
+ }, 1);
+ }
+
+ public connectedCallback() {
+ super.connectedCallback();
+ this._shouldBeDestroy = false;
+ }
+
+ protected createRenderRoot() {
+ return this;
+ }
+
+ protected render() {
+ if (this.noStyle) return nothing;
+ return html`
+
+ `;
+ }
+
+ private async _createSortable() {
+ if (this._sortable) return;
+ const container = this.children[0] as HTMLElement | undefined;
+
+ if (!container) return;
+
+ const Sortable = (await import("../resources/sortable")).default;
+
+ const options: SortableInstance.Options = {
+ animation: 150,
+ onChoose: this._handleChoose,
+ onEnd: this._handleEnd,
+ };
+
+ if (this.draggableSelector) {
+ options.draggable = this.draggableSelector;
+ }
+ if (this.handleSelector) {
+ options.handle = this.handleSelector;
+ }
+ this._sortable = new Sortable(container, options);
+ }
+
+ private _handleEnd = (evt: SortableEvent) => {
+ // put back in original location
+ if ((evt.item as any).placeholder) {
+ (evt.item as any).placeholder.replaceWith(evt.item);
+ delete (evt.item as any).placeholder;
+ }
+ // if item was not moved, ignore
+ if (
+ evt.oldIndex === undefined ||
+ evt.newIndex === undefined ||
+ evt.oldIndex === evt.newIndex
+ ) {
+ return;
+ }
+
+ fireEvent(this, "item-moved", {
+ oldIndex: evt.oldIndex!,
+ newIndex: evt.newIndex!,
+ });
+ };
+
+ private _handleChoose = (evt: SortableEvent) => {
+ (evt.item as any).placeholder = document.createComment("sort-placeholder");
+ evt.item.after((evt.item as any).placeholder);
+ };
+
+ private _destroySortable() {
+ if (!this._sortable) return;
+ this._sortable.destroy();
+ this._sortable = undefined;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-sortable": HaSortable;
+ }
+}
diff --git a/src/dialogs/area-filter/area-filter-dialog.ts b/src/dialogs/area-filter/area-filter-dialog.ts
index 2dc7cacadcb2..d82a515c0929 100644
--- a/src/dialogs/area-filter/area-filter-dialog.ts
+++ b/src/dialogs/area-filter/area-filter-dialog.ts
@@ -4,15 +4,13 @@ import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { repeat } from "lit/directives/repeat";
-import type { SortableEvent } from "sortablejs";
import { fireEvent } from "../../common/dom/fire_event";
import type { AreaFilterValue } from "../../components/ha-area-filter";
import "../../components/ha-button";
import "../../components/ha-icon-button";
import "../../components/ha-list-item";
+import "../../components/ha-sortable";
import { areaCompare } from "../../data/area_registry";
-import { sortableStyles } from "../../resources/ha-sortable-style";
-import type { SortableInstance } from "../../resources/sortable";
import { haStyleDialog } from "../../resources/styles";
import { HomeAssistant } from "../../types";
import { HassDialog } from "../make-dialog-manager";
@@ -31,23 +29,18 @@ export class DialogAreaFilter
@state() private _areas: string[] = [];
- private _sortable?: SortableInstance;
-
- public async showDialog(dialogParams: AreaFilterDialogParams): Promise {
+ public showDialog(dialogParams: AreaFilterDialogParams): void {
this._dialogParams = dialogParams;
this._hidden = dialogParams.initialValue?.hidden ?? [];
const order = dialogParams.initialValue?.order ?? [];
const allAreas = Object.keys(this.hass!.areas);
this._areas = allAreas.concat().sort(areaCompare(this.hass!.areas, order));
- await this.updateComplete;
- this._createSortable();
}
public closeDialog(): void {
this._dialogParams = undefined;
this._hidden = [];
this._areas = [];
- this._destroySortable();
fireEvent(this, "dialog-closed", { dialog: this.localName });
}
@@ -66,42 +59,14 @@ export class DialogAreaFilter
this.closeDialog();
}
- private async _createSortable() {
- const Sortable = (await import("../../resources/sortable")).default;
- if (this._sortable) return;
- this._sortable = new Sortable(this.shadowRoot!.querySelector(".areas")!, {
- animation: 150,
- fallbackClass: "sortable-fallback",
- handle: ".handle",
- draggable: ".draggable",
- onChoose: (evt: SortableEvent) => {
- (evt.item as any).placeholder =
- document.createComment("sort-placeholder");
- evt.item.after((evt.item as any).placeholder);
- },
- onEnd: (evt: SortableEvent) => {
- // put back in original location
- if ((evt.item as any).placeholder) {
- (evt.item as any).placeholder.replaceWith(evt.item);
- delete (evt.item as any).placeholder;
- }
- this._dragged(evt);
- },
- });
- }
-
- private _destroySortable() {
- this._sortable?.destroy();
- this._sortable = undefined;
- }
-
- private _dragged(ev: SortableEvent): void {
- if (ev.oldIndex === ev.newIndex) return;
+ private _areaMoved(ev: CustomEvent): void {
+ ev.stopPropagation();
+ const { oldIndex, newIndex } = ev.detail;
const areas = this._areas.concat();
- const option = areas.splice(ev.oldIndex!, 1)[0];
- areas.splice(ev.newIndex!, 0, option);
+ const option = areas.splice(oldIndex, 1)[0];
+ areas.splice(newIndex, 0, option);
this._areas = areas;
}
@@ -120,50 +85,56 @@ export class DialogAreaFilter
.heading=${this._dialogParams.title ??
this.hass.localize("ui.components.area-filter.title")}
>
-
- ${repeat(
- allAreas,
- (area) => area,
- (area, _idx) => {
- const isVisible = !this._hidden.includes(area);
- const name = this.hass!.areas[area]?.name || area;
- return html`
-
- ${isVisible
- ? html``
- : nothing}
- ${name}
-
-
- `;
- }
- )}
-
+
+
+ ${repeat(
+ allAreas,
+ (area) => area,
+ (area, _idx) => {
+ const isVisible = !this._hidden.includes(area);
+ const name = this.hass!.areas[area]?.name || area;
+ return html`
+
+ ${isVisible
+ ? html``
+ : nothing}
+ ${name}
+
+
+ `;
+ }
+ )}
+
+
${this.hass.localize("ui.common.cancel")}
@@ -192,7 +163,6 @@ export class DialogAreaFilter
static get styles(): CSSResultGroup {
return [
- sortableStyles,
haStyleDialog,
css`
ha-dialog {
diff --git a/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts b/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts
index 9a2cbd6caf31..93a6b1528fd5 100644
--- a/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts
+++ b/src/dialogs/more-info/components/lights/ha-more-info-light-favorite-colors.ts
@@ -10,9 +10,9 @@ import {
} from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
-import type { SortableEvent } from "sortablejs";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-control-slider";
+import "../../../../components/ha-sortable";
import { UNAVAILABLE } from "../../../../data/entity";
import {
ExtEntityRegistryEntry,
@@ -24,7 +24,6 @@ import {
computeDefaultFavoriteColors,
} from "../../../../data/light";
import { actionHandler } from "../../../../panels/lovelace/common/directives/action-handler-directive";
-import type { SortableInstance } from "../../../../resources/sortable";
import { HomeAssistant } from "../../../../types";
import { showConfirmationDialog } from "../../../generic/show-dialog-box";
import "./ha-favorite-color-button";
@@ -48,16 +47,7 @@ export class HaMoreInfoLightFavoriteColors extends LitElement {
@state() private _favoriteColors: LightColor[] = [];
- private _sortable?: SortableInstance;
-
protected updated(changedProps: PropertyValues): void {
- if (changedProps.has("editMode")) {
- if (this.editMode) {
- this._createSortable();
- } else {
- this._destroySortable();
- }
- }
if (changedProps.has("entry")) {
if (this.entry) {
if (this.entry.options?.light?.favorite_colors) {
@@ -69,34 +59,10 @@ export class HaMoreInfoLightFavoriteColors extends LitElement {
}
}
- private async _createSortable() {
- const Sortable = (await import("../../../../resources/sortable")).default;
- this._sortable = new Sortable(
- this.shadowRoot!.querySelector(".container")!,
- {
- animation: 150,
- fallbackClass: "sortable-fallback",
- draggable: ".color",
- onChoose: (evt: SortableEvent) => {
- (evt.item as any).placeholder =
- document.createComment("sort-placeholder");
- evt.item.after((evt.item as any).placeholder);
- },
- onEnd: (evt: SortableEvent) => {
- // put back in original location
- if ((evt.item as any).placeholder) {
- (evt.item as any).placeholder.replaceWith(evt.item);
- delete (evt.item as any).placeholder;
- }
- this._dragged(evt);
- },
- }
- );
- }
-
- private _dragged(ev: SortableEvent): void {
- if (ev.oldIndex === ev.newIndex) return;
- this._move(ev.oldIndex!, ev.newIndex!);
+ private _colorMoved(ev: CustomEvent): void {
+ ev.stopPropagation();
+ const { oldIndex, newIndex } = ev.detail;
+ this._move(oldIndex, newIndex);
}
private _move(index: number, newIndex: number) {
@@ -107,11 +73,6 @@ export class HaMoreInfoLightFavoriteColors extends LitElement {
this._save(favoriteColors);
}
- private _destroySortable() {
- this._sortable?.destroy();
- this._sortable = undefined;
- }
-
private _apply = (index: number) => {
const favorite = this._favoriteColors[index];
this.hass.callService("light", "turn_on", {
@@ -223,72 +184,79 @@ export class HaMoreInfoLightFavoriteColors extends LitElement {
protected render(): TemplateResult {
return html`
-
- ${this._favoriteColors.map(
- (color, index) => html`
-
-
-
+
+ ${this._favoriteColors.map(
+ (color, index) => html`
+
+
-
- ${this.editMode
- ? html`
-
- `
- : nothing}
+
+
+ ${this.editMode
+ ? html`
+
+ `
+ : nothing}
+
-
- `
- )}
- ${this.editMode
- ? html`
-
-
-
-
-
-
`
- : nothing}
-
+ )}
+ ${this.editMode
+ ? html`
+
+
+
+
+
+
+ `
+ : nothing}
+
+
`;
}
diff --git a/src/panels/config/automation/action/ha-automation-action.ts b/src/panels/config/automation/action/ha-automation-action.ts
index ce312a7bd399..ba1208930788 100644
--- a/src/panels/config/automation/action/ha-automation-action.ts
+++ b/src/panels/config/automation/action/ha-automation-action.ts
@@ -1,19 +1,16 @@
-import "@material/mwc-button";
import { mdiArrowDown, mdiArrowUp, mdiDrag, mdiPlus } from "@mdi/js";
import deepClone from "deep-clone-simple";
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
import { customElement, property } from "lit/decorators";
import { repeat } from "lit/directives/repeat";
-import type { SortableEvent } from "sortablejs";
import { storage } from "../../../../common/decorators/storage";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/ha-button";
import "../../../../components/ha-svg-icon";
+import "../../../../components/ha-sortable";
import { getService, isService } from "../../../../data/action";
import type { AutomationClipboard } from "../../../../data/automation";
import { Action } from "../../../../data/script";
-import { sortableStyles } from "../../../../resources/ha-sortable-style";
-import type { SortableInstance } from "../../../../resources/sortable";
import { HomeAssistant } from "../../../../types";
import {
PASTE_VALUE,
@@ -48,8 +45,6 @@ export default class HaAutomationAction extends LitElement {
private _actionKeys = new WeakMap
();
- private _sortable?: SortableInstance;
-
protected render() {
return html`
${this.reOrderMode && !this.nested
@@ -63,62 +58,68 @@ export default class HaAutomationAction extends LitElement {
${this.hass.localize(
"ui.panel.config.automation.editor.re_order_mode.description_actions"
)}
-
+
${this.hass.localize(
"ui.panel.config.automation.editor.re_order_mode.exit"
)}
-
+
`
: null}
-
- ${repeat(
- this.actions,
- (action) => this._getKey(action),
- (action, idx) => html`
-
- ${this.reOrderMode
- ? html`
-
-
-
-
-
- `
- : ""}
-
- `
- )}
-
+
+
+ ${repeat(
+ this.actions,
+ (action) => this._getKey(action),
+ (action, idx) => html`
+
+ ${this.reOrderMode
+ ? html`
+
+
+
+
+
+ `
+ : ""}
+
+ `
+ )}
+
+