Area strategy fixes (#24700)

* Add missing water heater domain and change lights icon

* Rename areas view to areas overview view

* Use same max columns for area view and overview

* Use large section when only one section
This commit is contained in:
Paul Bottein 2025-03-20 19:09:51 +01:00 committed by GitHub
parent 888b2472df
commit fe17bb89eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 60 additions and 50 deletions

View File

@ -10,7 +10,7 @@ import {
AREA_STRATEGY_GROUP_LABELS, AREA_STRATEGY_GROUP_LABELS,
computeAreaTileCardConfig, computeAreaTileCardConfig,
getAreaGroupedEntities, getAreaGroupedEntities,
} from "./helpers/area-strategy-helper"; } from "./helpers/areas-strategy-helper";
export interface EntitiesDisplay { export interface EntitiesDisplay {
hidden?: string[]; hidden?: string[];
@ -144,6 +144,11 @@ export class AreaViewStrategy extends ReactiveElement {
}); });
} }
// Take the full width if there is only one section to avoid misalignment between cards and header
if (sections.length === 1) {
sections[0].column_span = 2;
}
return { return {
type: "sections", type: "sections",
header: { header: {

View File

@ -8,8 +8,8 @@ import type {
EntitiesDisplay, EntitiesDisplay,
} from "./area-view-strategy"; } from "./area-view-strategy";
import type { LovelaceStrategyEditor } from "../types"; import type { LovelaceStrategyEditor } from "../types";
import type { AreasViewStrategyConfig } from "./areas-view-strategy"; import type { AreasViewStrategyConfig } from "./areas-overview-view-strategy";
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers"; import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helper";
interface AreaOptions { interface AreaOptions {
groups_options?: Record<string, EntitiesDisplay>; groups_options?: Record<string, EntitiesDisplay>;
@ -58,7 +58,7 @@ export class AreasDashboardStrategy extends ReactiveElement {
icon: "mdi:home", icon: "mdi:home",
path: "home", path: "home",
strategy: { strategy: {
type: "areas", type: "areas-overview",
areas_display: config.areas_display, areas_display: config.areas_display,
areas_options: config.areas_options, areas_options: config.areas_options,
} satisfies AreasViewStrategyConfig, } satisfies AreasViewStrategyConfig,

View File

@ -5,17 +5,18 @@ import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import type { EntitiesDisplay } from "./area-view-strategy"; import type { EntitiesDisplay } from "./area-view-strategy";
import { import {
computeAreaPath,
computeAreaTileCardConfig, computeAreaTileCardConfig,
getAreaGroupedEntities, getAreaGroupedEntities,
} from "./helpers/area-strategy-helper"; getAreas,
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helpers"; } from "./helpers/areas-strategy-helper";
interface AreaOptions { interface AreaOptions {
groups_options?: Record<string, EntitiesDisplay>; groups_options?: Record<string, EntitiesDisplay>;
} }
export interface AreasViewStrategyConfig { export interface AreasViewStrategyConfig {
type: "areas"; type: "areas-overview";
areas_display?: { areas_display?: {
hidden?: string[]; hidden?: string[];
order?: string[]; order?: string[];
@ -23,8 +24,8 @@ export interface AreasViewStrategyConfig {
areas_options?: Record<string, AreaOptions>; areas_options?: Record<string, AreaOptions>;
} }
@customElement("areas-view-strategy") @customElement("areas-overview-view-strategy")
export class AreasViewStrategy extends ReactiveElement { export class AreasOverviewViewStrategy extends ReactiveElement {
static async generate( static async generate(
config: AreasViewStrategyConfig, config: AreasViewStrategyConfig,
hass: HomeAssistant hass: HomeAssistant
@ -94,7 +95,7 @@ export class AreasViewStrategy extends ReactiveElement {
return { return {
type: "sections", type: "sections",
max_columns: 3, max_columns: 2,
sections: areaSections, sections: areaSections,
}; };
} }
@ -102,6 +103,6 @@ export class AreasViewStrategy extends ReactiveElement {
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
"areas-view-strategy": AreasViewStrategy; "areas-overview-view-strategy": AreasOverviewViewStrategy;
} }
} }

View File

@ -8,13 +8,13 @@ import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-icon-button-prev"; import "../../../../../components/ha-icon-button-prev";
import "../../../../../components/ha-icon"; import "../../../../../components/ha-icon";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { AreaStrategyGroup } from "../helpers/area-strategy-helper"; import type { AreaStrategyGroup } from "../helpers/areas-strategy-helper";
import { import {
AREA_STRATEGY_GROUP_ICONS, AREA_STRATEGY_GROUP_ICONS,
AREA_STRATEGY_GROUPS, AREA_STRATEGY_GROUPS,
AREA_STRATEGY_GROUP_LABELS, AREA_STRATEGY_GROUP_LABELS,
getAreaGroupedEntities, getAreaGroupedEntities,
} from "../helpers/area-strategy-helper"; } from "../helpers/areas-strategy-helper";
import type { LovelaceStrategyEditor } from "../../types"; import type { LovelaceStrategyEditor } from "../../types";
import type { AreasDashboardStrategyConfig } from "../areas-dashboard-strategy"; import type { AreasDashboardStrategyConfig } from "../areas-dashboard-strategy";

View File

@ -4,6 +4,8 @@ import type { EntityFilterFunc } from "../../../../../common/entity/entity_filte
import { generateEntityFilter } from "../../../../../common/entity/entity_filter"; import { generateEntityFilter } from "../../../../../common/entity/entity_filter";
import { stripPrefixFromEntityName } from "../../../../../common/entity/strip_prefix_from_entity_name"; import { stripPrefixFromEntityName } from "../../../../../common/entity/strip_prefix_from_entity_name";
import { orderCompare } from "../../../../../common/string/compare"; import { orderCompare } from "../../../../../common/string/compare";
import type { AreaRegistryEntry } from "../../../../../data/area_registry";
import { areaCompare } from "../../../../../data/area_registry";
import type { LovelaceCardConfig } from "../../../../../data/lovelace/config/card"; import type { LovelaceCardConfig } from "../../../../../data/lovelace/config/card";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature"; import { supportsAlarmModesCardFeature } from "../../../card-features/hui-alarm-modes-card-feature";
@ -23,7 +25,7 @@ export const AREA_STRATEGY_GROUPS = [
] as const; ] as const;
export const AREA_STRATEGY_GROUP_ICONS = { export const AREA_STRATEGY_GROUP_ICONS = {
lights: "mdi:lightbulb", lights: "mdi:lamps",
climate: "mdi:home-thermometer", climate: "mdi:home-thermometer",
media_players: "mdi:multimedia", media_players: "mdi:multimedia",
security: "mdi:security", security: "mdi:security",
@ -68,16 +70,6 @@ export const getAreaGroupedEntities = (
}), }),
], ],
climate: [ climate: [
generateEntityFilter(hass, {
domain: "climate",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "humidifier",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, { generateEntityFilter(hass, {
domain: "cover", domain: "cover",
area: area, area: area,
@ -93,6 +85,21 @@ export const getAreaGroupedEntities = (
], ],
entity_category: "none", entity_category: "none",
}), }),
generateEntityFilter(hass, {
domain: "climate",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "humidifier",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, {
domain: "water_heater",
area: area,
entity_category: "none",
}),
generateEntityFilter(hass, { generateEntityFilter(hass, {
domain: "fan", domain: "fan",
area: area, area: area,
@ -246,3 +253,25 @@ export const computeAreaTileCardConfig =
...additionalCardConfig, ...additionalCardConfig,
}; };
}; };
export const getAreas = (
entries: HomeAssistant["areas"],
hiddenAreas?: string[],
areasOrder?: string[]
): AreaRegistryEntry[] => {
const areas = Object.values(entries);
const filteredAreas = hiddenAreas
? areas.filter((area) => !hiddenAreas!.includes(area.area_id))
: areas.concat();
const compare = areaCompare(entries, areasOrder);
const sortedAreas = filteredAreas.sort((areaA, areaB) =>
compare(areaA.area_id, areaB.area_id)
);
return sortedAreas;
};
export const computeAreaPath = (areaId: string): string => `areas-${areaId}`;

View File

@ -1,25 +0,0 @@
import type { AreaRegistryEntry } from "../../../../../data/area_registry";
import { areaCompare } from "../../../../../data/area_registry";
import type { HomeAssistant } from "../../../../../types";
export const getAreas = (
entries: HomeAssistant["areas"],
hiddenAreas?: string[],
areasOrder?: string[]
): AreaRegistryEntry[] => {
const areas = Object.values(entries);
const filteredAreas = hiddenAreas
? areas.filter((area) => !hiddenAreas!.includes(area.area_id))
: areas.concat();
const compare = areaCompare(entries, areasOrder);
const sortedAreas = filteredAreas.sort((areaA, areaB) =>
compare(areaA.area_id, areaB.area_id)
);
return sortedAreas;
};
export const computeAreaPath = (areaId: string): string => `areas-${areaId}`;

View File

@ -33,7 +33,7 @@ const STRATEGIES: Record<LovelaceStrategyConfigType, Record<string, any>> = {
map: () => import("./map/map-view-strategy"), map: () => import("./map/map-view-strategy"),
iframe: () => import("./iframe/iframe-view-strategy"), iframe: () => import("./iframe/iframe-view-strategy"),
area: () => import("./areas/area-view-strategy"), area: () => import("./areas/area-view-strategy"),
areas: () => import("./areas/areas-view-strategy"), "areas-overview": () => import("./areas/areas-overview-view-strategy"),
}, },
section: {}, section: {},
}; };