From 9155c855093143ff8f087e9db7f75a37976ee8c4 Mon Sep 17 00:00:00 2001
From: Wendelin <12148533+wendevlin@users.noreply.github.com>
Date: Mon, 5 May 2025 15:05:35 +0200
Subject: [PATCH 01/75] Fix zwave add device LR/mesh icons (#25313)
Fix zwave LR/mesh icons
---
.../images/z-wave-add-node/long-range.svg | 10 +++----
public/static/images/z-wave-add-node/mesh.svg | 30 +++++++++----------
.../images/z-wave-add-node/mesh_dark.svg | 29 +++++++++---------
3 files changed, 34 insertions(+), 35 deletions(-)
diff --git a/public/static/images/z-wave-add-node/long-range.svg b/public/static/images/z-wave-add-node/long-range.svg
index 48deddc513..32fa115cc8 100644
--- a/public/static/images/z-wave-add-node/long-range.svg
+++ b/public/static/images/z-wave-add-node/long-range.svg
@@ -1,13 +1,13 @@
`
+ : html`
+
+ ${devices.map(
+ (device) => html`
+
+
+ ${this.step.result?.domain
+ ? html`

`
+ : nothing}
+
+ ${device.model || device.manufacturer}
+ ${device.model
+ ? html`
+ ${device.manufacturer}
+ `
+ : nothing}
+
+
+
+
+
+ `
+ )}
+
+ `}
@@ -68,14 +89,15 @@ class HaConfigSectionNetwork extends LitElement {
supervisor-network,
ha-config-url-form,
ha-config-network,
- ha-config-network-dhcp,
- ha-config-network-ssdp,
- ha-config-network-zeroconf {
+ .discovery-card {
display: block;
margin: 0 auto;
margin-bottom: 24px;
max-width: 600px;
}
+ .discovery-card ha-md-list {
+ padding-top: 0;
+ }
`;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 519b6a2968..374d86b6a9 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -6401,15 +6401,14 @@
}
},
"discovery": {
+ "title": "Network discovery",
+ "description": "Explore what data Home Assistant can see on the network.",
"dhcp": "DHCP browser",
- "dhcp_info": "The DHCP browser shows devices detected by Home Assistant using methods like DHCP, ARP+PTR lookups, and router-based device trackers. DHCP (Dynamic Host Configuration Protocol) data is received when devices join the network and request an IP address, allowing Home Assistant to discover them automatically. All devices found through these methods will appear here.",
- "dhcp_browser": "View DHCP browser",
+ "dhcp_info": "Show devices detected by Home Assistant using methods like DHCP, ARP+PTR lookups, and router-based device trackers. DHCP (Dynamic Host Configuration Protocol) data is received when devices join the network and request an IP address.",
"ssdp": "SSDP browser",
- "ssdp_info": "The SSDP browser shows devices discovered by Home Assistant using SSDP/UPnP. Devices that Home Assistant has discovered will appear here.",
- "ssdp_browser": "View SSDP browser",
+ "ssdp_info": "Show devices discovered by Home Assistant using SSDP/UPnP. Devices that Home Assistant has discovered will appear here.",
"zeroconf": "Zeroconf browser",
- "zeroconf_info": "The Zeroconf browser shows devices discovered by Home Assistant using mDNS. Only devices that Home Assistant is actively searching for will appear here.",
- "zeroconf_browser": "View Zeroconf browser"
+ "zeroconf_info": "Show devices discovered by Home Assistant using mDNS. Only devices that Home Assistant is actively searching for will appear here."
},
"network_adapter": "Network adapter",
"network_adapter_info": "Configure which network adapters integrations will use. Currently this setting only affects multicast traffic. A restart is required for these settings to apply.",
From 7434b12d9f40546cc8fffd660a2cb78be8d8ffca Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Mon, 5 May 2025 19:37:47 +0200
Subject: [PATCH 08/75] Use new entity naming in card entity picker (#25316)
---
.../badge-editor/hui-dialog-create-badge.ts | 19 --
.../card-editor/hui-dialog-create-card.ts | 19 --
.../card-editor/hui-entity-picker-table.ts | 255 +++++++++++++-----
.../unused-entities/hui-unused-entities.ts | 25 +-
4 files changed, 195 insertions(+), 123 deletions(-)
diff --git a/src/panels/lovelace/editor/badge-editor/hui-dialog-create-badge.ts b/src/panels/lovelace/editor/badge-editor/hui-dialog-create-badge.ts
index d14959e4fb..9388295802 100644
--- a/src/panels/lovelace/editor/badge-editor/hui-dialog-create-badge.ts
+++ b/src/panels/lovelace/editor/badge-editor/hui-dialog-create-badge.ts
@@ -4,11 +4,7 @@ import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { cache } from "lit/directives/cache";
import { classMap } from "lit/directives/class-map";
-import memoize from "memoize-one";
import { fireEvent } from "../../../../common/dom/fire_event";
-import { computeDomain } from "../../../../common/entity/compute_domain";
-import { computeStateName } from "../../../../common/entity/compute_state_name";
-import type { DataTableRowData } from "../../../../components/data-table/ha-data-table";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/sl-tab-group";
@@ -137,7 +133,6 @@ export class HuiCreateDialogBadge
no-label-float
.hass=${this.hass}
.narrow=${true}
- .entities=${this._allEntities(this.hass.states)}
@selected-changed=${this._handleSelectedChanged}
>
`
@@ -276,20 +271,6 @@ export class HuiCreateDialogBadge
this.closeDialog();
}
-
- private _allEntities = memoize((entities) =>
- Object.keys(entities).map((entity) => {
- const stateObj = this.hass.states[entity];
- return {
- icon: "",
- entity_id: entity,
- stateObj,
- name: computeStateName(stateObj),
- domain: computeDomain(entity),
- last_changed: stateObj!.last_changed,
- } as DataTableRowData;
- })
- );
}
declare global {
diff --git a/src/panels/lovelace/editor/card-editor/hui-dialog-create-card.ts b/src/panels/lovelace/editor/card-editor/hui-dialog-create-card.ts
index 314029fa0d..46927da9c8 100644
--- a/src/panels/lovelace/editor/card-editor/hui-dialog-create-card.ts
+++ b/src/panels/lovelace/editor/card-editor/hui-dialog-create-card.ts
@@ -5,11 +5,7 @@ import { customElement, property, state } from "lit/decorators";
import { cache } from "lit/directives/cache";
import { classMap } from "lit/directives/class-map";
import { ifDefined } from "lit/directives/if-defined";
-import memoize from "memoize-one";
import { fireEvent } from "../../../../common/dom/fire_event";
-import { computeDomain } from "../../../../common/entity/compute_domain";
-import { computeStateName } from "../../../../common/entity/compute_state_name";
-import type { DataTableRowData } from "../../../../components/data-table/ha-data-table";
import "../../../../components/ha-dialog";
import "../../../../components/ha-dialog-header";
import "../../../../components/sl-tab-group";
@@ -157,7 +153,6 @@ export class HuiCreateDialogCard
no-label-float
.hass=${this.hass}
narrow
- .entities=${this._allEntities(this.hass.states)}
@selected-changed=${this._handleSelectedChanged}
>
`
@@ -340,20 +335,6 @@ export class HuiCreateDialogCard
this.closeDialog();
}
-
- private _allEntities = memoize((entities) =>
- Object.keys(entities).map((entity) => {
- const stateObj = this.hass.states[entity];
- return {
- icon: "",
- entity_id: entity,
- stateObj,
- name: computeStateName(stateObj),
- domain: computeDomain(entity),
- last_changed: stateObj!.last_changed,
- } as DataTableRowData;
- })
- );
}
declare global {
diff --git a/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts b/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts
index 5918aafef6..dd0c3a549c 100644
--- a/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts
+++ b/src/panels/lovelace/editor/card-editor/hui-entity-picker-table.ts
@@ -1,9 +1,17 @@
-import type { TemplateResult } from "lit";
-import { css, html, LitElement } from "lit";
+import type { PropertyValues, TemplateResult } from "lit";
+import { css, html, LitElement, nothing } from "lit";
import { customElement, property } from "lit/decorators";
+import { styleMap } from "lit/directives/style-map";
import memoizeOne from "memoize-one";
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
import { fireEvent } from "../../../../common/dom/fire_event";
+import { computeAreaName } from "../../../../common/entity/compute_area_name";
+import { computeDeviceName } from "../../../../common/entity/compute_device_name";
+import { computeDomain } from "../../../../common/entity/compute_domain";
+import { computeEntityName } from "../../../../common/entity/compute_entity_name";
+import { getEntityContext } from "../../../../common/entity/context/get_entity_context";
+import type { LocalizeFunc } from "../../../../common/translations/localize";
+import { computeRTL } from "../../../../common/util/compute_rtl";
import "../../../../components/data-table/ha-data-table";
import type {
DataTableColumnContainer,
@@ -12,8 +20,26 @@ import type {
} from "../../../../components/data-table/ha-data-table";
import "../../../../components/entity/state-badge";
import "../../../../components/ha-relative-time";
+import { domainToName } from "../../../../data/integration";
import type { HomeAssistant } from "../../../../types";
+const ENTITY_ID_STYLE = styleMap({
+ fontFamily: "var(--ha-font-family-code)",
+ fontSize: "var(--ha-font-size-xs)",
+});
+
+interface EntityPickerTableRowData extends DataTableRowData {
+ icon: string;
+ entity_id: string;
+ stateObj: any;
+ name: string;
+ entity_name?: string;
+ device_name?: string;
+ area_name?: string;
+ domain_name: string;
+ last_changed: string;
+}
+
@customElement("hui-entity-picker-table")
export class HuiEntityPickerTable extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -23,16 +49,69 @@ export class HuiEntityPickerTable extends LitElement {
@property({ type: Boolean, attribute: "no-label-float" })
public noLabelFloat? = false;
- @property({ type: Array }) public entities!: DataTableRowData[];
+ @property({ type: Array }) public entities?: string[];
+
+ protected firstUpdated(_changedProperties: PropertyValues): void {
+ super.firstUpdated(_changedProperties);
+ this.hass.loadBackendTranslation("title");
+ }
+
+ private _data = memoizeOne(
+ (
+ states: HomeAssistant["states"],
+ localize: LocalizeFunc,
+ entities?: string[]
+ ): EntityPickerTableRowData[] =>
+ (entities || Object.keys(states)).map(
+ (entity) => {
+ const stateObj = this.hass.states[entity];
+
+ const { area, device } = getEntityContext(stateObj, this.hass);
+
+ const entityName = computeEntityName(stateObj, this.hass);
+ const deviceName = device ? computeDeviceName(device) : undefined;
+ const areaName = area ? computeAreaName(area) : undefined;
+ const name = [deviceName, entityName].filter(Boolean).join(" ");
+ const domain = computeDomain(entity);
+
+ return {
+ icon: "",
+ entity_id: entity,
+ stateObj,
+ name: name,
+ entity_name: entityName,
+ device_name: deviceName,
+ area_name: areaName,
+ domain_name: domainToName(localize, domain),
+ last_changed: stateObj!.last_changed,
+ } satisfies EntityPickerTableRowData;
+ }
+ )
+ );
protected render(): TemplateResult {
+ const data = this._data(
+ this.hass.states,
+ this.hass.localize,
+ this.entities
+ );
+
+ const showEntityId = Boolean(this.hass.userData?.showEntityIdPicker);
+
+ const columns = this._columns(
+ this.narrow,
+ computeRTL(this.hass),
+ showEntityId
+ );
+
return html`
{
- const columns: DataTableColumnContainer = {
- icon: {
- title: "",
- label: this.hass!.localize(
- "ui.panel.lovelace.unused_entities.state_icon"
+ private _columns = memoizeOne(
+ (narrow: boolean, isRTL: boolean, showEntityId: boolean) => {
+ const columns: DataTableColumnContainer = {
+ icon: {
+ title: "",
+ label: this.hass!.localize(
+ "ui.panel.lovelace.unused_entities.state_icon"
+ ),
+ type: "icon",
+ template: (entity) => html`
+
+ `,
+ },
+ name: {
+ title: this.hass!.localize(
+ "ui.panel.lovelace.unused_entities.entity"
+ ),
+ sortable: true,
+ filterable: true,
+ flex: 2,
+ main: true,
+ direction: "asc",
+ template: (entity: any) => {
+ const primary =
+ entity.entity_name || entity.device_name || entity.entity_id;
+ const secondary = [
+ entity.area_name,
+ entity.entity_name ? entity.device_name : undefined,
+ ]
+ .filter(Boolean)
+ .join(isRTL ? " ◂ " : " ▸ ");
+ return html`
+
+ ${primary}
+ ${secondary
+ ? html`
${secondary}
`
+ : nothing}
+ ${narrow && showEntityId
+ ? html`
+
+ ${entity.entity_id}
+
+ `
+ : nothing}
+
+ `;
+ },
+ },
+ };
+
+ columns.entity_name = {
+ title: "entity_name",
+ filterable: true,
+ hidden: true,
+ };
+
+ columns.device_name = {
+ title: "device_name",
+ filterable: true,
+ hidden: true,
+ };
+
+ columns.area_name = {
+ title: "area_name",
+ filterable: true,
+ hidden: true,
+ };
+
+ columns.entity_id = {
+ title: this.hass!.localize(
+ "ui.panel.lovelace.unused_entities.entity_id"
),
- type: "icon",
- template: (entity) => html`
-
- `,
- },
- name: {
- title: this.hass!.localize("ui.panel.lovelace.unused_entities.entity"),
sortable: true,
filterable: true,
- flex: 2,
- main: true,
- direction: "asc",
- template: (entity: any) => html`
-
- ${entity.name}
- ${narrow
- ? html`
${entity.entity_id}
`
- : ""}
-
+ hidden: narrow || !showEntityId,
+ };
+
+ columns.domain_name = {
+ title: this.hass!.localize("ui.panel.lovelace.unused_entities.domain"),
+ sortable: true,
+ filterable: true,
+ hidden: narrow || showEntityId,
+ };
+
+ columns.last_changed = {
+ title: this.hass!.localize(
+ "ui.panel.lovelace.unused_entities.last_changed"
+ ),
+ type: "numeric",
+ sortable: true,
+ hidden: narrow,
+ template: (entity) => html`
+
`,
- },
- };
+ };
- columns.entity_id = {
- title: this.hass!.localize("ui.panel.lovelace.unused_entities.entity_id"),
- sortable: true,
- filterable: true,
- hidden: narrow,
- };
-
- columns.domain = {
- title: this.hass!.localize("ui.panel.lovelace.unused_entities.domain"),
- sortable: true,
- filterable: true,
- hidden: narrow,
- };
-
- columns.last_changed = {
- title: this.hass!.localize(
- "ui.panel.lovelace.unused_entities.last_changed"
- ),
- type: "numeric",
- sortable: true,
- hidden: narrow,
- template: (entity) => html`
-
- `,
- };
-
- return columns;
- });
+ return columns;
+ }
+ );
private _handleSelectionChanged(
ev: HASSDomEvent
@@ -134,6 +254,9 @@ export class HuiEntityPickerTable extends LitElement {
--data-table-border-width: 0;
height: 100%;
}
+ ha-data-table.show-entity-id {
+ --data-table-row-height: 64px;
+ }
`;
}
diff --git a/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts b/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts
index a63d3e3a50..392f439f73 100644
--- a/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts
+++ b/src/panels/lovelace/editor/unused-entities/hui-unused-entities.ts
@@ -3,22 +3,19 @@ import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
-import { computeDomain } from "../../../../common/entity/compute_domain";
-import { computeStateName } from "../../../../common/entity/compute_state_name";
-import type { DataTableRowData } from "../../../../components/data-table/ha-data-table";
import "../../../../components/ha-fab";
import "../../../../components/ha-svg-icon";
+import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
import type { HomeAssistant } from "../../../../types";
import { computeUnusedEntities } from "../../common/compute-unused-entities";
-import type { Lovelace } from "../../types";
-import "../card-editor/hui-entity-picker-table";
-import { showSuggestCardDialog } from "../card-editor/show-suggest-card-dialog";
-import { showSelectViewDialog } from "../select-view/show-select-view-dialog";
-import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
import {
computeCards,
computeSection,
} from "../../common/generate-lovelace-config";
+import type { Lovelace } from "../../types";
+import "../card-editor/hui-entity-picker-table";
+import { showSuggestCardDialog } from "../card-editor/show-suggest-card-dialog";
+import { showSelectViewDialog } from "../select-view/show-select-view-dialog";
@customElement("hui-unused-entities")
export class HuiUnusedEntities extends LitElement {
@@ -80,17 +77,7 @@ export class HuiUnusedEntities extends LitElement {
{
- const stateObj = this.hass!.states[entity];
- return {
- icon: "",
- entity_id: entity,
- stateObj,
- name: stateObj ? computeStateName(stateObj) : "Unavailable",
- domain: computeDomain(entity),
- last_changed: stateObj?.last_changed,
- };
- }) as DataTableRowData[]}
+ .entities=${this._unusedEntities}
@selected-changed=${this._handleSelectedChanged}
>
From c7882f392681fddf86da8dc4ba638cea3e5ab055 Mon Sep 17 00:00:00 2001
From: Paulus Schoutsen
Date: Mon, 5 May 2025 13:48:29 -0400
Subject: [PATCH 09/75] Populate integration domain My link (#25322)
* Populate integration domain My link
* break out of loop
* Actually just return from function
* Consolidate code
---
src/state/quick-bar-mixin.ts | 60 +++++++++++++++++-------------------
1 file changed, 28 insertions(+), 32 deletions(-)
diff --git a/src/state/quick-bar-mixin.ts b/src/state/quick-bar-mixin.ts
index 6e931a9bd7..f0effc7f03 100644
--- a/src/state/quick-bar-mixin.ts
+++ b/src/state/quick-bar-mixin.ts
@@ -16,6 +16,7 @@ import { extractSearchParamsObject } from "../common/url/search-params";
import { showVoiceCommandDialog } from "../dialogs/voice-command-dialog/show-ha-voice-command-dialog";
import { canOverrideAlphanumericInput } from "../common/dom/can-override-input";
import { showShortcutsDialog } from "../dialogs/shortcuts/show-shortcuts-dialog";
+import type { Redirects } from "../panels/my/ha-panel-my";
declare global {
interface HASSDomEvents {
@@ -143,49 +144,44 @@ export default >(superClass: T) =>
e.preventDefault();
const targetPath = mainWindow.location.pathname;
- const isHassio = isComponentLoaded(this.hass, "hassio");
const myParams = new URLSearchParams();
- if (isHassio && targetPath.startsWith("/hassio")) {
+ let redirects: Redirects;
+
+ if (targetPath.startsWith("/hassio")) {
const myPanelSupervisor = await import(
"../../hassio/src/hassio-my-redirect"
);
- for (const [slug, redirect] of Object.entries(
- myPanelSupervisor.REDIRECTS
- )) {
- if (targetPath.startsWith(redirect.redirect)) {
- myParams.append("redirect", slug);
- if (redirect.redirect === "/hassio/addon") {
- myParams.append("addon", targetPath.split("/")[3]);
- }
- window.open(
- `https://my.home-assistant.io/create-link/?${myParams.toString()}`,
- "_blank"
- );
- return;
- }
- }
+ redirects = myPanelSupervisor.REDIRECTS;
+ } else {
+ const myPanel = await import("../panels/my/ha-panel-my");
+ redirects = myPanel.getMyRedirects();
}
- const myPanel = await import("../panels/my/ha-panel-my");
+ for (const [slug, redirect] of Object.entries(redirects)) {
+ if (!targetPath.startsWith(redirect.redirect)) {
+ continue;
+ }
+ myParams.append("redirect", slug);
- for (const [slug, redirect] of Object.entries(myPanel.getMyRedirects())) {
- if (targetPath.startsWith(redirect.redirect)) {
- myParams.append("redirect", slug);
- if (redirect.params) {
- const params = extractSearchParamsObject();
- for (const key of Object.keys(redirect.params)) {
- if (key in params) {
- myParams.append(key, params[key]);
- }
+ if (redirect.params) {
+ const params = extractSearchParamsObject();
+ for (const key of Object.keys(redirect.params)) {
+ if (key in params) {
+ myParams.append(key, params[key]);
}
}
- window.open(
- `https://my.home-assistant.io/create-link/?${myParams.toString()}`,
- "_blank"
- );
- return;
}
+ if (redirect.redirect === "/config/integrations/integration") {
+ myParams.append("domain", targetPath.split("/")[4]);
+ } else if (redirect.redirect === "/hassio/addon") {
+ myParams.append("addon", targetPath.split("/")[3]);
+ }
+ window.open(
+ `https://my.home-assistant.io/create-link/?${myParams.toString()}`,
+ "_blank"
+ );
+ return;
}
showToast(this, {
message: this.hass.localize(
From 83289bdd41d8cee70fdba97d81065555d345e9d9 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 6 May 2025 09:43:21 +0200
Subject: [PATCH 10/75] Update dependency eslint to v9.26.0 (#25327)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
package.json | 2 +-
yarn.lock | 340 ++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 311 insertions(+), 31 deletions(-)
diff --git a/package.json b/package.json
index b6cd23a971..eb286c2e34 100644
--- a/package.json
+++ b/package.json
@@ -185,7 +185,7 @@
"babel-plugin-template-html-minifier": "4.1.0",
"browserslist-useragent-regexp": "4.1.3",
"del": "8.0.0",
- "eslint": "9.25.1",
+ "eslint": "9.26.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-prettier": "10.1.2",
"eslint-import-resolver-webpack": "0.13.10",
diff --git a/yarn.lock b/yarn.lock
index 5331f5b96d..eaa5ac2a2e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1559,10 +1559,10 @@ __metadata:
languageName: node
linkType: hard
-"@eslint/js@npm:9.25.1":
- version: 9.25.1
- resolution: "@eslint/js@npm:9.25.1"
- checksum: 10/ad5812889598de32d674ef60c0e61468ac5c7f3b6ecf98b0e29d1e88d7af8ba3aab255b8c0a46bbaf654047bbd2ee5aa033db9b53e330f97615093fcccde4cbb
+"@eslint/js@npm:9.26.0":
+ version: 9.26.0
+ resolution: "@eslint/js@npm:9.26.0"
+ checksum: 10/863d35df8f6675250bb5a917037e0f6833965437eba4c4649633fd0b55a93e8d727bcd36e9b5cc82047898ee9348cb40363e196f333914ae3a6bb36159495212
languageName: node
linkType: hard
@@ -3168,6 +3168,24 @@ __metadata:
languageName: node
linkType: hard
+"@modelcontextprotocol/sdk@npm:^1.8.0":
+ version: 1.11.0
+ resolution: "@modelcontextprotocol/sdk@npm:1.11.0"
+ dependencies:
+ content-type: "npm:^1.0.5"
+ cors: "npm:^2.8.5"
+ cross-spawn: "npm:^7.0.3"
+ eventsource: "npm:^3.0.2"
+ express: "npm:^5.0.1"
+ express-rate-limit: "npm:^7.5.0"
+ pkce-challenge: "npm:^5.0.0"
+ raw-body: "npm:^3.0.0"
+ zod: "npm:^3.23.8"
+ zod-to-json-schema: "npm:^3.24.1"
+ checksum: 10/527413fd2b18f75e031cda7f73a662098f3c5f1224b9c6b0b903d5a1f79e23e23a4f4b8e6971bac7eb46a74ed65ae05e8e548f7b7a3f7f6d179c3f6d10825fbc
+ languageName: node
+ linkType: hard
+
"@module-federation/error-codes@npm:0.13.0":
version: 0.13.0
resolution: "@module-federation/error-codes@npm:0.13.0"
@@ -5418,6 +5436,16 @@ __metadata:
languageName: node
linkType: hard
+"accepts@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "accepts@npm:2.0.0"
+ dependencies:
+ mime-types: "npm:^3.0.0"
+ negotiator: "npm:^1.0.0"
+ checksum: 10/ea1343992b40b2bfb3a3113fa9c3c2f918ba0f9197ae565c48d3f84d44b174f6b1d5cd9989decd7655963eb03a272abc36968cc439c2907f999bd5ef8653d5a7
+ languageName: node
+ linkType: hard
+
"accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8":
version: 1.3.8
resolution: "accepts@npm:1.3.8"
@@ -6083,6 +6111,23 @@ __metadata:
languageName: node
linkType: hard
+"body-parser@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "body-parser@npm:2.2.0"
+ dependencies:
+ bytes: "npm:^3.1.2"
+ content-type: "npm:^1.0.5"
+ debug: "npm:^4.4.0"
+ http-errors: "npm:^2.0.0"
+ iconv-lite: "npm:^0.6.3"
+ on-finished: "npm:^2.4.1"
+ qs: "npm:^6.14.0"
+ raw-body: "npm:^3.0.0"
+ type-is: "npm:^2.0.0"
+ checksum: 10/e9d844b036bd15970df00a16f373c7ed28e1ef870974a0a1d4d6ef60d70e01087cc20a0dbb2081c49a88e3c08ce1d87caf1e2898c615dffa193f63e8faa8a84e
+ languageName: node
+ linkType: hard
+
"bonjour-service@npm:^1.2.1":
version: 1.3.0
resolution: "bonjour-service@npm:1.3.0"
@@ -6771,7 +6816,16 @@ __metadata:
languageName: node
linkType: hard
-"content-type@npm:~1.0.4, content-type@npm:~1.0.5":
+"content-disposition@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "content-disposition@npm:1.0.0"
+ dependencies:
+ safe-buffer: "npm:5.2.1"
+ checksum: 10/0dcc1a2d7874526b0072df3011b134857b49d97a3bc135bb464a299525d4972de6f5f464fd64da6c4d8406d26a1ffb976f62afaffef7723b1021a44498d10e08
+ languageName: node
+ linkType: hard
+
+"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5":
version: 1.0.5
resolution: "content-type@npm:1.0.5"
checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662
@@ -6792,6 +6846,13 @@ __metadata:
languageName: node
linkType: hard
+"cookie-signature@npm:^1.2.1":
+ version: 1.2.2
+ resolution: "cookie-signature@npm:1.2.2"
+ checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708
+ languageName: node
+ linkType: hard
+
"cookie@npm:0.7.1":
version: 0.7.1
resolution: "cookie@npm:0.7.1"
@@ -6799,7 +6860,7 @@ __metadata:
languageName: node
linkType: hard
-"cookie@npm:~0.7.2":
+"cookie@npm:^0.7.1, cookie@npm:~0.7.2":
version: 0.7.2
resolution: "cookie@npm:0.7.2"
checksum: 10/24b286c556420d4ba4e9bc09120c9d3db7d28ace2bd0f8ccee82422ce42322f73c8312441271e5eefafbead725980e5996cc02766dbb89a90ac7f5636ede608f
@@ -6839,7 +6900,7 @@ __metadata:
languageName: node
linkType: hard
-"cors@npm:2.8.5, cors@npm:~2.8.5":
+"cors@npm:2.8.5, cors@npm:^2.8.5, cors@npm:~2.8.5":
version: 2.8.5
resolution: "cors@npm:2.8.5"
dependencies:
@@ -6987,7 +7048,7 @@ __metadata:
languageName: node
linkType: hard
-"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.0":
+"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.4.0":
version: 4.4.0
resolution: "debug@npm:4.4.0"
dependencies:
@@ -7168,7 +7229,7 @@ __metadata:
languageName: node
linkType: hard
-"depd@npm:2.0.0":
+"depd@npm:2.0.0, depd@npm:^2.0.0":
version: 2.0.0
resolution: "depd@npm:2.0.0"
checksum: 10/c0c8ff36079ce5ada64f46cc9d6fd47ebcf38241105b6e0c98f412e8ad91f084bcf906ff644cc3a4bd876ca27a62accb8b0fff72ea6ed1a414b89d8506f4a5ca
@@ -7437,6 +7498,13 @@ __metadata:
languageName: node
linkType: hard
+"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0":
+ version: 2.0.0
+ resolution: "encodeurl@npm:2.0.0"
+ checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe
+ languageName: node
+ linkType: hard
+
"encodeurl@npm:~1.0.2":
version: 1.0.2
resolution: "encodeurl@npm:1.0.2"
@@ -7444,13 +7512,6 @@ __metadata:
languageName: node
linkType: hard
-"encodeurl@npm:~2.0.0":
- version: 2.0.0
- resolution: "encodeurl@npm:2.0.0"
- checksum: 10/abf5cd51b78082cf8af7be6785813c33b6df2068ce5191a40ca8b1afe6a86f9230af9a9ce694a5ce4665955e5c1120871826df9c128a642e09c58d592e2807fe
- languageName: node
- linkType: hard
-
"encoding@npm:^0.1.13":
version: 0.1.13
resolution: "encoding@npm:0.1.13"
@@ -7781,7 +7842,7 @@ __metadata:
languageName: node
linkType: hard
-"escape-html@npm:~1.0.3":
+"escape-html@npm:^1.0.3, escape-html@npm:~1.0.3":
version: 1.0.3
resolution: "escape-html@npm:1.0.3"
checksum: 10/6213ca9ae00d0ab8bccb6d8d4e0a98e76237b2410302cf7df70aaa6591d509a2a37ce8998008cbecae8fc8ffaadf3fb0229535e6a145f3ce0b211d060decbb24
@@ -8003,9 +8064,9 @@ __metadata:
languageName: node
linkType: hard
-"eslint@npm:9.25.1":
- version: 9.25.1
- resolution: "eslint@npm:9.25.1"
+"eslint@npm:9.26.0":
+ version: 9.26.0
+ resolution: "eslint@npm:9.26.0"
dependencies:
"@eslint-community/eslint-utils": "npm:^4.2.0"
"@eslint-community/regexpp": "npm:^4.12.1"
@@ -8013,11 +8074,12 @@ __metadata:
"@eslint/config-helpers": "npm:^0.2.1"
"@eslint/core": "npm:^0.13.0"
"@eslint/eslintrc": "npm:^3.3.1"
- "@eslint/js": "npm:9.25.1"
+ "@eslint/js": "npm:9.26.0"
"@eslint/plugin-kit": "npm:^0.2.8"
"@humanfs/node": "npm:^0.16.6"
"@humanwhocodes/module-importer": "npm:^1.0.1"
"@humanwhocodes/retry": "npm:^0.4.2"
+ "@modelcontextprotocol/sdk": "npm:^1.8.0"
"@types/estree": "npm:^1.0.6"
"@types/json-schema": "npm:^7.0.15"
ajv: "npm:^6.12.4"
@@ -8042,6 +8104,7 @@ __metadata:
minimatch: "npm:^3.1.2"
natural-compare: "npm:^1.4.0"
optionator: "npm:^0.9.3"
+ zod: "npm:^3.24.2"
peerDependencies:
jiti: "*"
peerDependenciesMeta:
@@ -8049,7 +8112,7 @@ __metadata:
optional: true
bin:
eslint: bin/eslint.js
- checksum: 10/037bbdc5cba6f72199976dcdce115b1b479b9425ee1116c08bcaf25e0de4a74a0ffe696d48610ade79c91b04ef3e707a7215a42dfba9c7d3a0b85747d5902e67
+ checksum: 10/b87092cb7e87f1d0963475c1a1e15e551842ea122925cf13231e742fae565bf3582029a5b0b4aecf793f25c26ee0be3ee1f32190bc361e0c3f3633b9cbace948
languageName: node
linkType: hard
@@ -8119,7 +8182,7 @@ __metadata:
languageName: node
linkType: hard
-"etag@npm:~1.8.1":
+"etag@npm:^1.8.1, etag@npm:~1.8.1":
version: 1.8.1
resolution: "etag@npm:1.8.1"
checksum: 10/571aeb3dbe0f2bbd4e4fadbdb44f325fc75335cd5f6f6b6a091e6a06a9f25ed5392f0863c5442acb0646787446e816f13cbfc6edce5b07658541dff573cab1ff
@@ -8154,6 +8217,22 @@ __metadata:
languageName: node
linkType: hard
+"eventsource-parser@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "eventsource-parser@npm:3.0.1"
+ checksum: 10/2730c54c3cb47d55d2967f2ece843f9fc95d8a11c2fef6fece8d17d9080193cbe3cd9ac7b04a325977f63cbf8c1664fdd0512dec1aec601666a5c5bd8564b61f
+ languageName: node
+ linkType: hard
+
+"eventsource@npm:^3.0.2":
+ version: 3.0.6
+ resolution: "eventsource@npm:3.0.6"
+ dependencies:
+ eventsource-parser: "npm:^3.0.1"
+ checksum: 10/ac08c7d1b21e454c7685693fe4ace53fc0b84f3cf752699a556876f2a7f33b7a12972ae33d1c407fb920d6d4aed10de52fdf0dd01902ccdf45cd5da8d55e7f88
+ languageName: node
+ linkType: hard
+
"execa@npm:^5.1.1":
version: 5.1.1
resolution: "execa@npm:5.1.1"
@@ -8225,6 +8304,15 @@ __metadata:
languageName: node
linkType: hard
+"express-rate-limit@npm:^7.5.0":
+ version: 7.5.0
+ resolution: "express-rate-limit@npm:7.5.0"
+ peerDependencies:
+ express: ^4.11 || 5 || ^5.0.0-beta.1
+ checksum: 10/eff34c83bf586789933a332a339b66649e2cca95c8e977d193aa8bead577d3182ac9f0e9c26f39389287539b8038890ff023f910b54ebb506a26a2ce135b92ca
+ languageName: node
+ linkType: hard
+
"express@npm:^4.21.2":
version: 4.21.2
resolution: "express@npm:4.21.2"
@@ -8264,6 +8352,41 @@ __metadata:
languageName: node
linkType: hard
+"express@npm:^5.0.1":
+ version: 5.1.0
+ resolution: "express@npm:5.1.0"
+ dependencies:
+ accepts: "npm:^2.0.0"
+ body-parser: "npm:^2.2.0"
+ content-disposition: "npm:^1.0.0"
+ content-type: "npm:^1.0.5"
+ cookie: "npm:^0.7.1"
+ cookie-signature: "npm:^1.2.1"
+ debug: "npm:^4.4.0"
+ encodeurl: "npm:^2.0.0"
+ escape-html: "npm:^1.0.3"
+ etag: "npm:^1.8.1"
+ finalhandler: "npm:^2.1.0"
+ fresh: "npm:^2.0.0"
+ http-errors: "npm:^2.0.0"
+ merge-descriptors: "npm:^2.0.0"
+ mime-types: "npm:^3.0.0"
+ on-finished: "npm:^2.4.1"
+ once: "npm:^1.4.0"
+ parseurl: "npm:^1.3.3"
+ proxy-addr: "npm:^2.0.7"
+ qs: "npm:^6.14.0"
+ range-parser: "npm:^1.2.1"
+ router: "npm:^2.2.0"
+ send: "npm:^1.1.0"
+ serve-static: "npm:^2.2.0"
+ statuses: "npm:^2.0.1"
+ type-is: "npm:^2.0.1"
+ vary: "npm:^1.1.2"
+ checksum: 10/6dba00bbdf308f43a84ed3f07a7e9870d5208f2a0b8f60f39459dda089750379747819863fad250849d3c9163833f33f94ce69d73938df31e0c5a430800d7e56
+ languageName: node
+ linkType: hard
+
"extend-shallow@npm:^3.0.2":
version: 3.0.2
resolution: "extend-shallow@npm:3.0.2"
@@ -8478,6 +8601,20 @@ __metadata:
languageName: node
linkType: hard
+"finalhandler@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "finalhandler@npm:2.1.0"
+ dependencies:
+ debug: "npm:^4.4.0"
+ encodeurl: "npm:^2.0.0"
+ escape-html: "npm:^1.0.3"
+ on-finished: "npm:^2.4.1"
+ parseurl: "npm:^1.3.3"
+ statuses: "npm:^2.0.1"
+ checksum: 10/b2bd68c310e2c463df0ab747ab05f8defbc540b8c3f2442f86e7d084ac8acbc31f8cae079931b7f5a406521501941e3395e963de848a0aaf45dd414adeb5ff4e
+ languageName: node
+ linkType: hard
+
"find-root@npm:^1.1.0":
version: 1.1.0
resolution: "find-root@npm:1.1.0"
@@ -8625,6 +8762,13 @@ __metadata:
languageName: node
linkType: hard
+"fresh@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "fresh@npm:2.0.0"
+ checksum: 10/44e1468488363074641991c1340d2a10c5a6f6d7c353d89fd161c49d120c58ebf9890720f7584f509058385836e3ce50ddb60e9f017315a4ba8c6c3461813bfc
+ languageName: node
+ linkType: hard
+
"fs-extra@npm:11.3.0, fs-extra@npm:^11.1.1":
version: 11.3.0
resolution: "fs-extra@npm:11.3.0"
@@ -9329,7 +9473,7 @@ __metadata:
dialog-polyfill: "npm:0.5.6"
echarts: "npm:5.6.0"
element-internals-polyfill: "npm:3.0.2"
- eslint: "npm:9.25.1"
+ eslint: "npm:9.26.0"
eslint-config-airbnb-base: "npm:15.0.0"
eslint-config-prettier: "npm:10.1.2"
eslint-import-resolver-webpack: "npm:0.13.10"
@@ -9516,7 +9660,7 @@ __metadata:
languageName: node
linkType: hard
-"http-errors@npm:2.0.0":
+"http-errors@npm:2.0.0, http-errors@npm:^2.0.0":
version: 2.0.0
resolution: "http-errors@npm:2.0.0"
dependencies:
@@ -10114,6 +10258,13 @@ __metadata:
languageName: node
linkType: hard
+"is-promise@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "is-promise@npm:4.0.0"
+ checksum: 10/0b46517ad47b00b6358fd6553c83ec1f6ba9acd7ffb3d30a0bf519c5c69e7147c132430452351b8a9fc198f8dd6c4f76f8e6f5a7f100f8c77d57d9e0f4261a8a
+ languageName: node
+ linkType: hard
+
"is-regex@npm:^1.2.0, is-regex@npm:^1.2.1":
version: 1.2.1
resolution: "is-regex@npm:1.2.1"
@@ -11073,6 +11224,13 @@ __metadata:
languageName: node
linkType: hard
+"media-typer@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "media-typer@npm:1.1.0"
+ checksum: 10/a58dd60804df73c672942a7253ccc06815612326dc1c0827984b1a21704466d7cde351394f47649e56cf7415e6ee2e26e000e81b51b3eebb5a93540e8bf93cbd
+ languageName: node
+ linkType: hard
+
"memfs@npm:^4.6.0":
version: 4.17.0
resolution: "memfs@npm:4.17.0"
@@ -11106,6 +11264,13 @@ __metadata:
languageName: node
linkType: hard
+"merge-descriptors@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "merge-descriptors@npm:2.0.0"
+ checksum: 10/e383332e700a94682d0125a36c8be761142a1320fc9feeb18e6e36647c9edf064271645f5669b2c21cf352116e561914fd8aa831b651f34db15ef4038c86696a
+ languageName: node
+ linkType: hard
+
"merge-stream@npm:^2.0.0":
version: 2.0.0
resolution: "merge-stream@npm:2.0.0"
@@ -11144,7 +11309,7 @@ __metadata:
languageName: node
linkType: hard
-"mime-db@npm:>= 1.43.0 < 2":
+"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0":
version: 1.54.0
resolution: "mime-db@npm:1.54.0"
checksum: 10/9e7834be3d66ae7f10eaa69215732c6d389692b194f876198dca79b2b90cbf96688d9d5d05ef7987b20f749b769b11c01766564264ea5f919c88b32a29011311
@@ -11176,6 +11341,15 @@ __metadata:
languageName: node
linkType: hard
+"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "mime-types@npm:3.0.1"
+ dependencies:
+ mime-db: "npm:^1.54.0"
+ checksum: 10/fa1d3a928363723a8046c346d87bf85d35014dae4285ad70a3ff92bd35957992b3094f8417973cfe677330916c6ef30885109624f1fb3b1e61a78af509dba120
+ languageName: node
+ linkType: hard
+
"mime@npm:1.6.0":
version: 1.6.0
resolution: "mime@npm:1.6.0"
@@ -11972,7 +12146,7 @@ __metadata:
languageName: node
linkType: hard
-"parseurl@npm:~1.3.2, parseurl@npm:~1.3.3":
+"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3":
version: 1.3.3
resolution: "parseurl@npm:1.3.3"
checksum: 10/407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2
@@ -12088,6 +12262,13 @@ __metadata:
languageName: node
linkType: hard
+"path-to-regexp@npm:^8.0.0":
+ version: 8.2.0
+ resolution: "path-to-regexp@npm:8.2.0"
+ checksum: 10/23378276a172b8ba5f5fb824475d1818ca5ccee7bbdb4674701616470f23a14e536c1db11da9c9e6d82b82c556a817bbf4eee6e41b9ed20090ef9427cbb38e13
+ languageName: node
+ linkType: hard
+
"path-type@npm:^6.0.0":
version: 6.0.0
resolution: "path-type@npm:6.0.0"
@@ -12166,6 +12347,13 @@ __metadata:
languageName: node
linkType: hard
+"pkce-challenge@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "pkce-challenge@npm:5.0.0"
+ checksum: 10/e60c06a0e0481cb82f80072053d5c479a7490758541c4226460450285dd5d72a995c44b3c553731ca7c2f64cc34b35f1d2e5f9de08d276b59899298f9efe1ddf
+ languageName: node
+ linkType: hard
+
"plugin-error@npm:^1.0.1":
version: 1.0.1
resolution: "plugin-error@npm:1.0.1"
@@ -12303,7 +12491,7 @@ __metadata:
languageName: node
linkType: hard
-"proxy-addr@npm:~2.0.7":
+"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7":
version: 2.0.7
resolution: "proxy-addr@npm:2.0.7"
dependencies:
@@ -12365,6 +12553,15 @@ __metadata:
languageName: node
linkType: hard
+"qs@npm:^6.14.0":
+ version: 6.14.0
+ resolution: "qs@npm:6.14.0"
+ dependencies:
+ side-channel: "npm:^1.1.0"
+ checksum: 10/a60e49bbd51c935a8a4759e7505677b122e23bf392d6535b8fc31c1e447acba2c901235ecb192764013cd2781723dc1f61978b5fdd93cc31d7043d31cdc01974
+ languageName: node
+ linkType: hard
+
"queue-microtask@npm:^1.2.2":
version: 1.2.3
resolution: "queue-microtask@npm:1.2.3"
@@ -12407,6 +12604,18 @@ __metadata:
languageName: node
linkType: hard
+"raw-body@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "raw-body@npm:3.0.0"
+ dependencies:
+ bytes: "npm:3.1.2"
+ http-errors: "npm:2.0.0"
+ iconv-lite: "npm:0.6.3"
+ unpipe: "npm:1.0.0"
+ checksum: 10/2443429bbb2f9ae5c50d3d2a6c342533dfbde6b3173740b70fa0302b30914ff400c6d31a46b3ceacbe7d0925dc07d4413928278b494b04a65736fc17ca33e30c
+ languageName: node
+ linkType: hard
+
"rc@npm:^1.0.1, rc@npm:^1.1.6":
version: 1.2.8
resolution: "rc@npm:1.2.8"
@@ -12882,6 +13091,19 @@ __metadata:
languageName: node
linkType: hard
+"router@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "router@npm:2.2.0"
+ dependencies:
+ debug: "npm:^4.4.0"
+ depd: "npm:^2.0.0"
+ is-promise: "npm:^4.0.0"
+ parseurl: "npm:^1.3.3"
+ path-to-regexp: "npm:^8.0.0"
+ checksum: 10/8949bd1d3da5403cc024e2989fee58d7fda0f3ffe9f2dc5b8a192f295f400b3cde307b0b554f7d44851077640f36962ca469a766b3d57410d7d96245a7ba6c91
+ languageName: node
+ linkType: hard
+
"rrule@npm:2.8.1":
version: 2.8.1
resolution: "rrule@npm:2.8.1"
@@ -13085,6 +13307,25 @@ __metadata:
languageName: node
linkType: hard
+"send@npm:^1.1.0, send@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "send@npm:1.2.0"
+ dependencies:
+ debug: "npm:^4.3.5"
+ encodeurl: "npm:^2.0.0"
+ escape-html: "npm:^1.0.3"
+ etag: "npm:^1.8.1"
+ fresh: "npm:^2.0.0"
+ http-errors: "npm:^2.0.0"
+ mime-types: "npm:^3.0.1"
+ ms: "npm:^2.1.3"
+ on-finished: "npm:^2.4.1"
+ range-parser: "npm:^1.2.1"
+ statuses: "npm:^2.0.1"
+ checksum: 10/9fa3b1a3b9a06b7b4ab00c25e8228326d9665a9745753a34d1ffab8ac63c7c206727331d1dc5be73647f1b658d259a1aa8e275b0e0eee51349370af02e9da506
+ languageName: node
+ linkType: hard
+
"serialize-javascript@npm:^6.0.1, serialize-javascript@npm:^6.0.2":
version: 6.0.2
resolution: "serialize-javascript@npm:6.0.2"
@@ -13136,6 +13377,18 @@ __metadata:
languageName: node
linkType: hard
+"serve-static@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "serve-static@npm:2.2.0"
+ dependencies:
+ encodeurl: "npm:^2.0.0"
+ escape-html: "npm:^1.0.3"
+ parseurl: "npm:^1.3.3"
+ send: "npm:^1.2.0"
+ checksum: 10/9f1a900738c5bb02258275ce3bd1273379c4c3072b622e15d44e8f47d89a1ba2d639ec2d63b11c263ca936096b40758acb7a0d989cd6989018a65a12f9433ada
+ languageName: node
+ linkType: hard
+
"serve@npm:14.2.4":
version: 14.2.4
resolution: "serve@npm:14.2.4"
@@ -13608,7 +13861,7 @@ __metadata:
languageName: node
linkType: hard
-"statuses@npm:2.0.1":
+"statuses@npm:2.0.1, statuses@npm:^2.0.1":
version: 2.0.1
resolution: "statuses@npm:2.0.1"
checksum: 10/18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb
@@ -14382,6 +14635,17 @@ __metadata:
languageName: node
linkType: hard
+"type-is@npm:^2.0.0, type-is@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "type-is@npm:2.0.1"
+ dependencies:
+ content-type: "npm:^1.0.5"
+ media-typer: "npm:^1.1.0"
+ mime-types: "npm:^3.0.0"
+ checksum: 10/bacdb23c872dacb7bd40fbd9095e6b2fca2895eedbb689160c05534d7d4810a7f4b3fd1ae87e96133c505958f6d602967a68db5ff577b85dd6be76eaa75d58af
+ languageName: node
+ linkType: hard
+
"type-is@npm:~1.6.18":
version: 1.6.18
resolution: "type-is@npm:1.6.18"
@@ -14752,7 +15016,7 @@ __metadata:
languageName: node
linkType: hard
-"vary@npm:^1, vary@npm:~1.1.2":
+"vary@npm:^1, vary@npm:^1.1.2, vary@npm:~1.1.2":
version: 1.1.2
resolution: "vary@npm:1.1.2"
checksum: 10/31389debef15a480849b8331b220782230b9815a8e0dbb7b9a8369559aed2e9a7800cd904d4371ea74f4c3527db456dc8e7ac5befce5f0d289014dbdf47b2242
@@ -16007,6 +16271,22 @@ __metadata:
languageName: node
linkType: hard
+"zod-to-json-schema@npm:^3.24.1":
+ version: 3.24.5
+ resolution: "zod-to-json-schema@npm:3.24.5"
+ peerDependencies:
+ zod: ^3.24.1
+ checksum: 10/1af291b4c429945c9568c2e924bdb7c66ab8d139cbeb9a99b6e9fc9e1b02863f85d07759b9303714f07ceda3993dcaf0ebcb80d2c18bb2aaf5502b2c1016affd
+ languageName: node
+ linkType: hard
+
+"zod@npm:^3.23.8, zod@npm:^3.24.2":
+ version: 3.24.4
+ resolution: "zod@npm:3.24.4"
+ checksum: 10/3d545792fa54bb27ee5dbc34a5709e81f603185fcc94c8204b5d95c20dc4c81d870ff9c51f3884a30ef05cdc601449f4c4df254ac4783f0827b1faed7c1cdb48
+ languageName: node
+ linkType: hard
+
"zrender@npm:5.6.1":
version: 5.6.1
resolution: "zrender@npm:5.6.1"
From d618c25095f35a9522d974a3b861194d66370739 Mon Sep 17 00:00:00 2001
From: Paulus Schoutsen
Date: Tue, 6 May 2025 03:49:35 -0400
Subject: [PATCH 11/75] Show voice ID in TTS media browser (#25324)
* Show voice ID in TTS media browser
* Apply suggestions from code review
Co-authored-by: Paul Bottein
* Add copy button
* Now copy correct clipboard icon
* Improve styling
* GAP
---------
Co-authored-by: Paul Bottein
---
.../media-player/ha-browse-media-tts.ts | 135 ++++++++++++------
src/translations/en.json | 4 +-
2 files changed, 94 insertions(+), 45 deletions(-)
diff --git a/src/components/media-player/ha-browse-media-tts.ts b/src/components/media-player/ha-browse-media-tts.ts
index e6fbdd62d7..1924af09a4 100644
--- a/src/components/media-player/ha-browse-media-tts.ts
+++ b/src/components/media-player/ha-browse-media-tts.ts
@@ -2,6 +2,7 @@ import "@material/mwc-button/mwc-button";
import type { PropertyValues } from "lit";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
+import { mdiContentCopy } from "@mdi/js";
import { storage } from "../../common/decorators/storage";
import { fireEvent } from "../../common/dom/fire_event";
import type {
@@ -17,6 +18,8 @@ import "../ha-language-picker";
import "../ha-tts-voice-picker";
import "../ha-card";
import { fetchCloudStatus } from "../../data/cloud";
+import { copyToClipboard } from "../../common/util/copy-clipboard";
+import { showToast } from "../../util/toast";
export interface TtsMediaPickedEvent {
item: MediaPlayerItem;
@@ -51,50 +54,69 @@ class BrowseMediaTTS extends LitElement {
private _message?: string;
protected render() {
- return html`
-
-
-
- ${this._provider?.supported_languages?.length
- ? html`
-
-
-
`
- : nothing}
-
-
-
- ${this.hass.localize(
- `ui.components.media-browser.tts.action_${this.action}`
- )}
-
-
- `;
+ return html`
+
+
+
+
+ ${this._provider?.supported_languages?.length
+ ? html`
+
+
+
`
+ : nothing}
+
+
+
+ ${this.hass.localize(
+ `ui.components.media-browser.tts.action_${this.action}`
+ )}
+
+
+
+ ${this._voice
+ ? html`
+
+ `
+ : nothing}
+ `;
}
protected override willUpdate(changedProps: PropertyValues): void {
@@ -197,6 +219,14 @@ class BrowseMediaTTS extends LitElement {
fireEvent(this, "tts-picked", { item });
}
+ private async _copyVoiceId(ev) {
+ ev.preventDefault();
+ await copyToClipboard(this._voice);
+ showToast(this, {
+ message: this.hass.localize("ui.common.copied_clipboard"),
+ });
+ }
+
static override styles = [
buttonLinkStyle,
css`
@@ -218,6 +248,23 @@ class BrowseMediaTTS extends LitElement {
button.link {
color: var(--primary-color);
}
+ .footer {
+ font-size: var(--ha-font-size-s);
+ color: var(--secondary-text-color);
+ margin: 16px 0;
+ text-align: center;
+ }
+ .footer code {
+ font-weight: var(--ha-font-weight-bold);
+ }
+ .footer {
+ --mdc-icon-size: 14px;
+ --mdc-icon-button-size: 24px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 6px;
+ }
`,
];
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 374d86b6a9..d3da5cbb65 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -920,7 +920,9 @@
"action_play": "Say",
"action_pick": "Select",
"set_as_default": "Set as default options",
- "faild_to_store_defaults": "Failed to store defaults: {error}"
+ "faild_to_store_defaults": "Failed to store defaults: {error}",
+ "selected_voice_id": "Selected voice ID",
+ "copy_voice_id": "Copy voice ID"
},
"pick": "Pick",
"play": "Play",
From ad8d3dd5985590ba368c3abdadfe753b2fcc9789 Mon Sep 17 00:00:00 2001
From: Simon Lamon <32477463+silamon@users.noreply.github.com>
Date: Tue, 6 May 2025 09:52:04 +0200
Subject: [PATCH 12/75] Bump the sortable patch (#25262)
---
... => sortablejs-npm-1.15.6-3235a8f83b.patch} | 0
package.json | 2 +-
yarn.lock | 18 +++++++++---------
3 files changed, 10 insertions(+), 10 deletions(-)
rename .yarn/patches/{sortablejs-npm-1.15.3-3235a8f83b.patch => sortablejs-npm-1.15.6-3235a8f83b.patch} (100%)
diff --git a/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch b/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch
similarity index 100%
rename from .yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch
rename to .yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch
diff --git a/package.json b/package.json
index eb286c2e34..3040aec248 100644
--- a/package.json
+++ b/package.json
@@ -131,7 +131,7 @@
"qrcode": "1.5.4",
"roboto-fontface": "0.10.0",
"rrule": "2.8.1",
- "sortablejs": "patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch",
+ "sortablejs": "patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch",
"stacktrace-js": "2.0.2",
"superstruct": "2.0.2",
"tinykeys": "3.0.0",
diff --git a/yarn.lock b/yarn.lock
index eaa5ac2a2e..a593fb7e20 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9526,7 +9526,7 @@ __metadata:
rspack-manifest-plugin: "npm:5.0.3"
serve: "npm:14.2.4"
sinon: "npm:20.0.0"
- sortablejs: "patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch"
+ sortablejs: "patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch"
stacktrace-js: "npm:2.0.2"
superstruct: "npm:2.0.2"
tar: "npm:7.4.3"
@@ -13699,17 +13699,17 @@ __metadata:
languageName: node
linkType: hard
-"sortablejs@npm:1.15.3":
- version: 1.15.3
- resolution: "sortablejs@npm:1.15.3"
- checksum: 10/85d39a172ef47adedf273afa65daa8aefcbaafd43a5b5c480d8637add93033f5784da697d0d3545d9bb6e11fd71f1847f307ee26be452942f3785a683fd44bb5
+"sortablejs@npm:1.15.6":
+ version: 1.15.6
+ resolution: "sortablejs@npm:1.15.6"
+ checksum: 10/3179071352662e6cff20d7d10792a934fc892a83a01ae09c7e604d2dd51daaf07283b00a8f2b13025f27959ff68a1469959bc94ef2a7049723d4c381a368a5ac
languageName: node
linkType: hard
-"sortablejs@patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch":
- version: 1.15.3
- resolution: "sortablejs@patch:sortablejs@npm%3A1.15.3#~/.yarn/patches/sortablejs-npm-1.15.3-3235a8f83b.patch::version=1.15.3&hash=fba0ad"
- checksum: 10/249f4cfd2b4a811f4e1505b25d4d67a97521afabdabd2f5482f985da20785d995c2899d442ad79075c7ba547e477aef81f09b0028f12d1de468cbca4f2b8c043
+"sortablejs@patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch":
+ version: 1.15.6
+ resolution: "sortablejs@patch:sortablejs@npm%3A1.15.6#~/.yarn/patches/sortablejs-npm-1.15.6-3235a8f83b.patch::version=1.15.6&hash=fba0ad"
+ checksum: 10/4d7515c6490fd9d7184a758775634b72c971f1ac739f8bf19683ad973374d6afb3adeb5dcb5c604d15faac55867b401cdb0631c0baee9f73d4c1ef82ee4318f8
languageName: node
linkType: hard
From 92b8cd8f459f1d78fc3d5ec7b45b9f24156a6e13 Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Tue, 6 May 2025 10:57:47 +0200
Subject: [PATCH 13/75] Align side bar title with items (#25330)
---
src/components/ha-sidebar.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts
index e3f139b62b..3f48666754 100644
--- a/src/components/ha-sidebar.ts
+++ b/src/components/ha-sidebar.ts
@@ -896,8 +896,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
color: var(--sidebar-icon-color);
}
.title {
- margin-left: 19px;
- margin-inline-start: 19px;
+ margin-left: 3px;
+ margin-inline-start: 3px;
margin-inline-end: initial;
width: 100%;
display: none;
From 0729aaacb8f9acfe0519fe410e1c537a39574549 Mon Sep 17 00:00:00 2001
From: Wendelin <12148533+wendevlin@users.noreply.github.com>
Date: Tue, 6 May 2025 11:00:37 +0200
Subject: [PATCH 14/75] Revert "Keyboard accessible panel sorting" (#25331)
---
src/components/ha-sidebar.ts | 71 +++-----------------------
src/resources/ha-sidebar-edit-style.ts | 2 +-
src/translations/en.json | 4 +-
3 files changed, 9 insertions(+), 68 deletions(-)
diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts
index 3f48666754..19c4a8d633 100644
--- a/src/components/ha-sidebar.ts
+++ b/src/components/ha-sidebar.ts
@@ -52,7 +52,6 @@ import "./user/ha-user-badge";
import "./ha-md-list";
import "./ha-md-list-item";
import type { HaMdListItem } from "./ha-md-list-item";
-import { showPromptDialog } from "../dialogs/generic/show-dialog-box";
const SHOW_AFTER_SPACER = ["config", "developer-tools"];
@@ -425,12 +424,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
`;
}
- private _renderPanels(
- panels: PanelInfo[],
- selectedPanel: string,
- orderable = false
- ) {
- return panels.map((panel, idx) =>
+ private _renderPanels(panels: PanelInfo[], selectedPanel: string) {
+ return panels.map((panel) =>
this._renderPanel(
panel.url_path,
panel.url_path === this.hass.defaultPanel
@@ -442,8 +437,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
: panel.url_path in PANEL_ICONS
? PANEL_ICONS[panel.url_path]
: undefined,
- selectedPanel,
- orderable ? idx : null
+ selectedPanel
)
);
}
@@ -453,8 +447,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
title: string | null,
icon: string | null | undefined,
iconPath: string | null | undefined,
- selectedPanel: string,
- index: number | null
+ selectedPanel: string
) {
return urlPath === "config"
? this._renderConfiguration(title, selectedPanel)
@@ -470,20 +463,8 @@ class HaSidebar extends SubscribeMixin(LitElement) {
? html``
: html``}
${title}
- ${index != null
- ? html`
- ${index + 1}
- `
- : nothing}
${this.editMode
- ? html` ${this._renderPanels(beforeSpacer, selectedPanel, true)}
+ >${this._renderPanels(beforeSpacer, selectedPanel)}
${this._renderSpacer()}${this._renderHiddenPanels()}
`;
@@ -712,28 +690,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
fireEvent(this, "hass-edit-sidebar", { editMode: false });
}
- private async _changePosition(ev): Promise {
- ev.preventDefault();
- const oldIndex = (ev.currentTarget as any).index as number;
- const name = ((ev.currentTarget as any).title as string) || "";
-
- const positionString = await showPromptDialog(this, {
- title: this.hass!.localize("ui.sidebar.change_position"),
- text: this.hass!.localize("ui.sidebar.change_position_dialog_text", {
- name,
- }),
- inputType: "number",
- inputMin: "1",
- placeholder: String(oldIndex + 1),
- });
-
- if (!positionString) return;
- const position = parseInt(positionString);
- if (isNaN(position)) return;
- const newIndex = Math.max(0, position - 1);
- this._panelMove(oldIndex, newIndex);
- }
-
private async _hidePanel(ev: Event) {
ev.preventDefault();
const panel = (ev.currentTarget as any).panel;
@@ -984,7 +940,7 @@ class HaSidebar extends SubscribeMixin(LitElement) {
ha-md-list-item .item-text {
display: none;
- max-width: 100%;
+ max-width: calc(100% - 56px);
font-weight: 500;
font-size: 14px;
}
@@ -1015,19 +971,6 @@ class HaSidebar extends SubscribeMixin(LitElement) {
color: var(--text-accent-color, var(--text-primary-color));
}
- .position-badge {
- display: block;
- width: 24px;
- line-height: 24px;
- box-sizing: border-box;
- border-radius: 50%;
- font-weight: 500;
- text-align: center;
- font-size: 14px;
- background-color: var(--app-header-edit-background-color, #455a64);
- color: var(--app-header-edit-text-color, white);
- }
-
ha-svg-icon + .badge {
position: absolute;
top: 4px;
diff --git a/src/resources/ha-sidebar-edit-style.ts b/src/resources/ha-sidebar-edit-style.ts
index 10dc29f913..efd4ddee10 100644
--- a/src/resources/ha-sidebar-edit-style.ts
+++ b/src/resources/ha-sidebar-edit-style.ts
@@ -58,7 +58,7 @@ export const sidebarEditStyle = css`
}
:host([expanded]) .hide-panel {
- display: inline-block;
+ display: block;
}
:host([expanded]) .show-panel {
diff --git a/src/translations/en.json b/src/translations/en.json
index d3da5cbb65..6e4810e682 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2018,9 +2018,7 @@
"sidebar_toggle": "Sidebar toggle",
"done": "Done",
"hide_panel": "Hide panel",
- "show_panel": "Show panel",
- "change_position": "Change panel position",
- "change_position_dialog_text": "What position do you want to move your ''{name}'' panel to?"
+ "show_panel": "Show panel"
},
"panel": {
"my": {
From 15dcdffe55298bf9eae37c91649569645c400b7a Mon Sep 17 00:00:00 2001
From: Paul Bottein
Date: Tue, 6 May 2025 13:38:38 +0200
Subject: [PATCH 15/75] Add covers to overview view for area strategy (#25334)
---
.../lovelace/strategies/areas/areas-overview-view-strategy.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/panels/lovelace/strategies/areas/areas-overview-view-strategy.ts b/src/panels/lovelace/strategies/areas/areas-overview-view-strategy.ts
index 40a034140b..fde3545216 100644
--- a/src/panels/lovelace/strategies/areas/areas-overview-view-strategy.ts
+++ b/src/panels/lovelace/strategies/areas/areas-overview-view-strategy.ts
@@ -50,6 +50,7 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
const entities = [
...groups.lights,
+ ...groups.covers,
...groups.climate,
...groups.media_players,
...groups.security,
From 852278e8aa95588269a160666ee898782b53f564 Mon Sep 17 00:00:00 2001
From: Wendelin <12148533+wendevlin@users.noreply.github.com>
Date: Tue, 6 May 2025 13:50:23 +0200
Subject: [PATCH 16/75] Add custom retention info to backup locations (#25318)
* Add retention messages to backup locations
* Fix mobile
* Use join
---
.../config/ha-backup-config-agents.ts | 74 +++++++++++++++----
src/translations/en.json | 5 +-
2 files changed, 62 insertions(+), 17 deletions(-)
diff --git a/src/panels/config/backup/components/config/ha-backup-config-agents.ts b/src/panels/config/backup/components/config/ha-backup-config-agents.ts
index 687321f7c5..a9817dba96 100644
--- a/src/panels/config/backup/components/config/ha-backup-config-agents.ts
+++ b/src/panels/config/backup/components/config/ha-backup-config-agents.ts
@@ -1,5 +1,6 @@
import { mdiCog, mdiDelete, mdiHarddisk, mdiNas } from "@mdi/js";
-import { css, html, LitElement, nothing } from "lit";
+import { css, html, LitElement, nothing, type TemplateResult } from "lit";
+import { join } from "lit/directives/join";
import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../../common/dom/fire_event";
@@ -57,26 +58,51 @@ class HaBackupConfigAgents extends LitElement {
);
}
+ const texts: (TemplateResult | string)[] = [];
+
+ if (isNetworkMountAgent(agentId)) {
+ texts.push(
+ this.hass.localize(
+ "ui.panel.config.backup.agents.network_mount_agent_description"
+ )
+ );
+ }
+
const encryptionTurnedOff =
this.agentsConfig?.[agentId]?.protected === false;
if (encryptionTurnedOff) {
- return html`
-
-
- ${this.hass.localize(
- "ui.panel.config.backup.agents.encryption_turned_off"
- )}
-
- `;
- }
-
- if (isNetworkMountAgent(agentId)) {
- return this.hass.localize(
- "ui.panel.config.backup.agents.network_mount_agent_description"
+ texts.push(
+ html`
+
+
+ ${this.hass.localize(
+ "ui.panel.config.backup.agents.encryption_turned_off"
+ )}
+
+
`
);
}
- return "";
+
+ const retention = this.agentsConfig?.[agentId]?.retention;
+
+ if (retention) {
+ if (retention.copies === null && retention.days === null) {
+ texts.push(
+ this.hass.localize("ui.panel.config.backup.agents.retention_all")
+ );
+ } else {
+ texts.push(
+ this.hass.localize(
+ `ui.panel.config.backup.agents.retention_${retention.copies ? "backups" : "days"}`,
+ {
+ count: retention.copies || retention.days,
+ }
+ )
+ );
+ }
+ }
+ return join(texts, html` ⸱ `);
}
private _availableAgents = memoizeOne(
@@ -287,6 +313,11 @@ class HaBackupConfigAgents extends LitElement {
gap: 8px;
line-height: normal;
}
+ .unencrypted-warning {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ }
.dot {
display: block;
position: relative;
@@ -294,11 +325,22 @@ class HaBackupConfigAgents extends LitElement {
height: 8px;
background-color: var(--disabled-color);
border-radius: 50%;
- flex: none;
}
.dot.warning {
background-color: var(--warning-color);
}
+ @media all and (max-width: 500px) {
+ .separator {
+ display: none;
+ }
+ ha-md-list-item [slot="supporting-text"] {
+ display: flex;
+ align-items: flex-start;
+ flex-direction: column;
+ justify-content: flex-start;
+ gap: 4px;
+ }
+ }
`;
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 6e4810e682..aaa9a327be 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -2491,7 +2491,10 @@
"unavailable_agents": "Unavailable locations",
"no_agents": "No locations configured",
"encryption_turned_off": "Encryption turned off",
- "local_agent": "This system"
+ "local_agent": "This system",
+ "retention_all": "Keep all backups",
+ "retention_backups": "Keep {count} {count, plural,\n one {backup}\n other {backups}\n}",
+ "retention_days": "Keep {count} {count, plural,\n one {day}\n other {days}\n}"
},
"data": {
"ha_settings": "Home Assistant settings",
From 00d708fbd4b249852f3404dbf35e8942b5a9a5ae Mon Sep 17 00:00:00 2001
From: Wendelin <12148533+wendevlin@users.noreply.github.com>
Date: Tue, 6 May 2025 13:52:00 +0200
Subject: [PATCH 17/75] Fix flow form padding end (#25328)
* Fix flow form padding end
* Use more end padding if docs are present
---
.../config-flow/dialog-data-entry-flow.ts | 42 +++++++++++--------
src/dialogs/config-flow/step-flow-abort.ts | 5 ++-
.../config-flow/step-flow-create-entry.ts | 5 ++-
src/dialogs/config-flow/step-flow-external.ts | 10 ++++-
src/dialogs/config-flow/step-flow-form.ts | 7 +++-
src/dialogs/config-flow/step-flow-menu.ts | 7 +++-
src/dialogs/config-flow/step-flow-progress.ts | 5 ++-
src/dialogs/config-flow/styles.ts | 3 ++
8 files changed, 61 insertions(+), 23 deletions(-)
diff --git a/src/dialogs/config-flow/dialog-data-entry-flow.ts b/src/dialogs/config-flow/dialog-data-entry-flow.ts
index 94959185ec..726143bdb1 100644
--- a/src/dialogs/config-flow/dialog-data-entry-flow.ts
+++ b/src/dialogs/config-flow/dialog-data-entry-flow.ts
@@ -1,4 +1,3 @@
-import "@material/mwc-button";
import { mdiClose, mdiHelpCircle } from "@mdi/js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { CSSResultGroup, PropertyValues } from "lit";
@@ -177,6 +176,17 @@ class DataEntryFlowDialog extends LitElement {
return nothing;
}
+ const showDocumentationLink =
+ ([
+ "form",
+ "menu",
+ "external",
+ "progress",
+ "data_entry_flow_progressed",
+ ].includes(this._step?.type as any) &&
+ this._params.manifest?.is_built_in) ||
+ !!this._params.manifest?.documentation;
+
return html`
@@ -199,26 +209,18 @@ class DataEntryFlowDialog extends LitElement {
: this._step === undefined
? // When we are going to next step, we render 1 round of empty
// to reset the element.
- ""
+ nothing
: html`
- ${([
- "form",
- "menu",
- "external",
- "progress",
- "data_entry_flow_progressed",
- ].includes(this._step?.type as any) &&
- this._params.manifest?.is_built_in) ||
- this._params.manifest?.documentation
+ ${showDocumentationLink
? html`
@@ -229,7 +231,7 @@ class DataEntryFlowDialog extends LitElement {
`
- : ""}
+ : nothing}
`
: this._step.type === "external"
@@ -250,6 +253,7 @@ class DataEntryFlowDialog extends LitElement {
.flowConfig=${this._params.flowConfig}
.step=${this._step}
.hass=${this.hass}
+ .increasePaddingEnd=${showDocumentationLink}
>
`
: this._step.type === "abort"
@@ -261,6 +265,7 @@ class DataEntryFlowDialog extends LitElement {
.handler=${this._step.handler}
.domain=${this._params.domain ??
this._step.handler}
+ .increasePaddingEnd=${showDocumentationLink}
>
`
: this._step.type === "progress"
@@ -270,6 +275,7 @@ class DataEntryFlowDialog extends LitElement {
.step=${this._step}
.hass=${this.hass}
.progress=${this._progress}
+ .increasePaddingEnd=${showDocumentationLink}
>
`
: this._step.type === "menu"
@@ -278,6 +284,7 @@ class DataEntryFlowDialog extends LitElement {
.flowConfig=${this._params.flowConfig}
.step=${this._step}
.hass=${this.hass}
+ .increasePaddingEnd=${showDocumentationLink}
>
`
: html`
@@ -286,7 +293,8 @@ class DataEntryFlowDialog extends LitElement {
.step=${this._step}
.hass=${this.hass}
.navigateToResult=${this._params
- .navigateToResult}
+ .navigateToResult ?? false}
+ .increasePaddingEnd=${showDocumentationLink}
>
`}
`}
diff --git a/src/dialogs/config-flow/step-flow-abort.ts b/src/dialogs/config-flow/step-flow-abort.ts
index fa54d4ca57..9f0ad9abb0 100644
--- a/src/dialogs/config-flow/step-flow-abort.ts
+++ b/src/dialogs/config-flow/step-flow-abort.ts
@@ -22,6 +22,9 @@ class StepFlowAbort extends LitElement {
@property({ attribute: false }) public handler!: string;
+ @property({ type: Boolean, attribute: "increase-padding-end" })
+ public increasePaddingEnd = false;
+
protected firstUpdated(changed: PropertyValues) {
super.firstUpdated(changed);
if (this.step.reason === "missing_credentials") {
@@ -34,7 +37,7 @@ class StepFlowAbort extends LitElement {
return nothing;
}
return html`
-
+
${this.params.flowConfig.renderAbortHeader
? this.params.flowConfig.renderAbortHeader(this.hass, this.step)
: this.hass.localize(`component.${this.domain}.title`)}
diff --git a/src/dialogs/config-flow/step-flow-create-entry.ts b/src/dialogs/config-flow/step-flow-create-entry.ts
index 6f59bf593d..327b5b783a 100644
--- a/src/dialogs/config-flow/step-flow-create-entry.ts
+++ b/src/dialogs/config-flow/step-flow-create-entry.ts
@@ -36,6 +36,9 @@ class StepFlowCreateEntry extends LitElement {
@property({ attribute: false }) public step!: DataEntryFlowStepCreateEntry;
+ @property({ type: Boolean, attribute: "increase-padding-end" })
+ public increasePaddingEnd = false;
+
public navigateToResult = false;
@state() private _deviceUpdate: Record<
@@ -113,7 +116,7 @@ class StepFlowCreateEntry extends LitElement {
this.step.result?.entry_id
);
return html`
-
+
${devices.length
? localize("ui.panel.config.integrations.config_flow.assign_area", {
number: devices.length,
diff --git a/src/dialogs/config-flow/step-flow-external.ts b/src/dialogs/config-flow/step-flow-external.ts
index 4e3b10512c..98d98c61ef 100644
--- a/src/dialogs/config-flow/step-flow-external.ts
+++ b/src/dialogs/config-flow/step-flow-external.ts
@@ -15,11 +15,16 @@ class StepFlowExternal extends LitElement {
@property({ attribute: false }) public step!: DataEntryFlowStepExternal;
+ @property({ type: Boolean, attribute: "increase-padding-end" })
+ public increasePaddingEnd = false;
+
protected render(): TemplateResult {
const localize = this.hass.localize;
return html`
- ${this.flowConfig.renderExternalStepHeader(this.hass, this.step)}
+
+ ${this.flowConfig.renderExternalStepHeader(this.hass, this.step)}
+
${this.flowConfig.renderExternalStepDescription(this.hass, this.step)}