diff --git a/gallery/src/pages/components/ha-form.ts b/gallery/src/pages/components/ha-form.ts index ccc287fd85..e33b7f8780 100644 --- a/gallery/src/pages/components/ha-form.ts +++ b/gallery/src/pages/components/ha-form.ts @@ -64,6 +64,7 @@ const DEVICES: DeviceRegistryEntry[] = [ labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, { area_id: "backyard", @@ -86,6 +87,7 @@ const DEVICES: DeviceRegistryEntry[] = [ labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, { area_id: null, @@ -108,6 +110,7 @@ const DEVICES: DeviceRegistryEntry[] = [ labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, ]; diff --git a/gallery/src/pages/components/ha-selector.ts b/gallery/src/pages/components/ha-selector.ts index cb3a1f2f49..8230fceccf 100644 --- a/gallery/src/pages/components/ha-selector.ts +++ b/gallery/src/pages/components/ha-selector.ts @@ -64,6 +64,7 @@ const DEVICES: DeviceRegistryEntry[] = [ labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, { area_id: "backyard", @@ -86,6 +87,7 @@ const DEVICES: DeviceRegistryEntry[] = [ labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, { area_id: null, @@ -108,6 +110,7 @@ const DEVICES: DeviceRegistryEntry[] = [ labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, ]; diff --git a/gallery/src/pages/misc/integration-card.ts b/gallery/src/pages/misc/integration-card.ts index cab686e210..ac89788440 100644 --- a/gallery/src/pages/misc/integration-card.ts +++ b/gallery/src/pages/misc/integration-card.ts @@ -232,6 +232,7 @@ const createDeviceRegistryEntries = ( labels: [], created_at: 0, modified_at: 0, + primary_config_entry: null, }, ]; diff --git a/package.json b/package.json index 7d0cd25dbe..f9f5892a33 100644 --- a/package.json +++ b/package.json @@ -216,7 +216,7 @@ "husky": "9.1.5", "instant-mocha": "1.5.2", "jszip": "3.10.1", - "lint-staged": "15.2.9", + "lint-staged": "15.2.10", "lit-analyzer": "2.0.3", "lodash.merge": "4.6.2", "lodash.template": "4.5.0", diff --git a/pyproject.toml b/pyproject.toml index 8fc228d388..758245b668 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20240904.0" +version = "20240906.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" diff --git a/src/components/ha-selector/ha-selector-number.ts b/src/components/ha-selector/ha-selector-number.ts index 418432ef27..8949082cfb 100644 --- a/src/components/ha-selector/ha-selector-number.ts +++ b/src/components/ha-selector/ha-selector-number.ts @@ -67,7 +67,9 @@ export class HaNumberSelector extends LitElement { } return html` - ${this.label ? html`${this.label}${this.required ? "*" : ""}` : nothing} + ${this.label && !isBox + ? html`${this.label}${this.required ? "*" : ""}` + : nothing}
${!isBox ? html` diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts index 37af47885d..3558d6e109 100644 --- a/src/data/config_entries.ts +++ b/src/data/config_entries.ts @@ -1,6 +1,6 @@ import type { UnsubscribeFunc } from "home-assistant-js-websocket"; import type { HomeAssistant } from "../types"; -import type { IntegrationManifest, IntegrationType } from "./integration"; +import type { IntegrationType } from "./integration"; export interface ConfigEntry { entry_id: string; @@ -149,20 +149,19 @@ export const enableConfigEntry = (hass: HomeAssistant, configEntryId: string) => export const sortConfigEntries = ( configEntries: ConfigEntry[], - manifestLookup: { [domain: string]: IntegrationManifest } + primaryConfigEntry: string | null ): ConfigEntry[] => { - const sortedConfigEntries = [...configEntries]; - - const getScore = (entry: ConfigEntry) => { - const manifest = manifestLookup[entry.domain] as - | IntegrationManifest - | undefined; - const isHelper = manifest?.integration_type === "helper"; - return isHelper ? -1 : 1; - }; - - const configEntriesCompare = (a: ConfigEntry, b: ConfigEntry) => - getScore(b) - getScore(a); - - return sortedConfigEntries.sort(configEntriesCompare); + if (!primaryConfigEntry) { + return configEntries; + } + const primaryEntry = configEntries.find( + (e) => e.entry_id === primaryConfigEntry + ); + if (!primaryEntry) { + return configEntries; + } + const otherEntries = configEntries.filter( + (e) => e.entry_id !== primaryConfigEntry + ); + return [primaryEntry, ...otherEntries]; }; diff --git a/src/data/device_registry.ts b/src/data/device_registry.ts index f758f19b8d..2a1a334b2a 100644 --- a/src/data/device_registry.ts +++ b/src/data/device_registry.ts @@ -33,6 +33,7 @@ export interface DeviceRegistryEntry extends RegistryEntry { entry_type: "service" | null; disabled_by: "user" | "integration" | "config_entry" | null; configuration_url: string | null; + primary_config_entry: string | null; } export interface DeviceEntityDisplayLookup { diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index fb691cc7e0..7d54a6596b 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -153,7 +153,7 @@ export class HaConfigDevicePage extends LitElement { .filter((entId) => entId in entryLookup) .map((entry) => entryLookup[entry]); - return sortConfigEntries(deviceEntries, manifestLookup); + return sortConfigEntries(deviceEntries, device.primary_config_entry); } ); diff --git a/src/panels/config/devices/ha-config-devices-dashboard.ts b/src/panels/config/devices/ha-config-devices-dashboard.ts index d7cfd5498b..a4744166fd 100644 --- a/src/panels/config/devices/ha-config-devices-dashboard.ts +++ b/src/panels/config/devices/ha-config-devices-dashboard.ts @@ -388,7 +388,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) { device.config_entries .filter((entId) => entId in entryLookup) .map((entId) => entryLookup[entId]), - manifestLookup + device.primary_config_entry ); const labels = labelReg && device?.labels; diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts index 90b440dcff..7d5b1e46d5 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts @@ -6,19 +6,18 @@ import { mdiCloseCircle, mdiProgressClock, } from "@mdi/js"; -import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, TemplateResult, + css, + html, + nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; -import memoizeOne from "memoize-one"; +import { groupBy } from "../../../../../common/util/group-by"; import "../../../../../components/ha-alert"; import "../../../../../components/ha-card"; import "../../../../../components/ha-icon-next"; @@ -27,25 +26,19 @@ import "../../../../../components/ha-settings-row"; import "../../../../../components/ha-svg-icon"; import "../../../../../components/ha-switch"; import "../../../../../components/ha-textfield"; -import { groupBy } from "../../../../../common/util/group-by"; -import { - computeDeviceName, - DeviceRegistryEntry, - subscribeDeviceRegistry, -} from "../../../../../data/device_registry"; +import { computeDeviceName } from "../../../../../data/device_registry"; import { + ZWaveJSNodeConfigParam, + ZWaveJSNodeConfigParams, + ZWaveJSSetConfigParamResult, + ZwaveJSNodeMetadata, fetchZwaveNodeConfigParameters, fetchZwaveNodeMetadata, setZwaveNodeConfigParameter, - ZWaveJSNodeConfigParam, - ZWaveJSNodeConfigParams, - ZwaveJSNodeMetadata, - ZWaveJSSetConfigParamResult, } from "../../../../../data/zwave_js"; import "../../../../../layouts/hass-error-screen"; import "../../../../../layouts/hass-loading-screen"; import "../../../../../layouts/hass-tabs-subpage"; -import { SubscribeMixin } from "../../../../../mixins/subscribe-mixin"; import { haStyle } from "../../../../../resources/styles"; import type { HomeAssistant, Route } from "../../../../../types"; import "../../../ha-config-section"; @@ -57,16 +50,8 @@ const icons = { error: mdiCloseCircle, }; -const getDevice = memoizeOne( - ( - deviceId: string, - entries?: DeviceRegistryEntry[] - ): DeviceRegistryEntry | undefined => - entries?.find((device) => device.id === deviceId) -); - @customElement("zwave_js-node-config") -class ZWaveJSNodeConfig extends SubscribeMixin(LitElement) { +class ZWaveJSNodeConfig extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public route!: Route; @@ -79,8 +64,6 @@ class ZWaveJSNodeConfig extends SubscribeMixin(LitElement) { @property() public deviceId!: string; - @state() private _deviceRegistryEntries?: DeviceRegistryEntry[]; - @state() private _nodeMetadata?: ZwaveJSNodeMetadata; @state() private _config?: ZWaveJSNodeConfigParams; @@ -94,19 +77,8 @@ class ZWaveJSNodeConfig extends SubscribeMixin(LitElement) { this.deviceId = this.route.path.substr(1); } - public hassSubscribe(): UnsubscribeFunc[] { - return [ - subscribeDeviceRegistry(this.hass.connection, (entries) => { - this._deviceRegistryEntries = entries; - }), - ]; - } - protected updated(changedProps: PropertyValues): void { - if ( - (!this._config || changedProps.has("deviceId")) && - changedProps.has("_deviceRegistryEntries") - ) { + if (!this._config || changedProps.has("deviceId")) { this._fetchData(); } } @@ -125,7 +97,7 @@ class ZWaveJSNodeConfig extends SubscribeMixin(LitElement) { return html``; } - const device = this._device!; + const device = this.hass.devices[this.deviceId]; return html`