mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 03:36:44 +00:00
Use area card in area strategy (#25879)
* Bring area card to area strategy * Add device classes * Use subview
This commit is contained in:
parent
876e36b4e0
commit
641a2eb77c
@ -30,6 +30,22 @@ export const floorDefaultIconPath = (
|
|||||||
return mdiHome;
|
return mdiHome;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const floorDefaultIcon = (floor: Pick<FloorRegistryEntry, "level">) => {
|
||||||
|
switch (floor.level) {
|
||||||
|
case 0:
|
||||||
|
return "mdi:home-floor-0";
|
||||||
|
case 1:
|
||||||
|
return "mdi:home-floor-1";
|
||||||
|
case 2:
|
||||||
|
return "mdi:home-floor-2";
|
||||||
|
case 3:
|
||||||
|
return "mdi:home-floor-3";
|
||||||
|
case -1:
|
||||||
|
return "mdi:home-floor-negative-1";
|
||||||
|
}
|
||||||
|
return "mdi:home";
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("ha-floor-icon")
|
@customElement("ha-floor-icon")
|
||||||
export class HaFloorIcon extends LitElement {
|
export class HaFloorIcon extends LitElement {
|
||||||
@property({ attribute: false }) public floor!: Pick<
|
@property({ attribute: false }) public floor!: Pick<
|
||||||
|
@ -191,12 +191,6 @@ export class AreaViewStrategy extends ReactiveElement {
|
|||||||
type: "sections",
|
type: "sections",
|
||||||
header: {
|
header: {
|
||||||
badges_position: "bottom",
|
badges_position: "bottom",
|
||||||
layout: "responsive",
|
|
||||||
card: {
|
|
||||||
type: "markdown",
|
|
||||||
text_only: true,
|
|
||||||
content: `## ${area.name}`,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
max_columns: maxColumns,
|
max_columns: maxColumns,
|
||||||
sections: sections,
|
sections: sections,
|
||||||
|
@ -66,6 +66,7 @@ export class AreasDashboardStrategy extends ReactiveElement {
|
|||||||
return {
|
return {
|
||||||
title: area.name,
|
title: area.name,
|
||||||
path: path,
|
path: path,
|
||||||
|
subview: true,
|
||||||
strategy: {
|
strategy: {
|
||||||
type: "area",
|
type: "area",
|
||||||
area: area.area_id,
|
area: area.area_id,
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
import { ReactiveElement } from "lit";
|
import { ReactiveElement } from "lit";
|
||||||
import { customElement } from "lit/decorators";
|
import { customElement } from "lit/decorators";
|
||||||
|
import { stringCompare } from "../../../../common/string/compare";
|
||||||
|
import { floorDefaultIcon } from "../../../../components/ha-floor-icon";
|
||||||
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
import type { LovelaceSectionConfig } from "../../../../data/lovelace/config/section";
|
||||||
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import { getAreaControlEntities } from "../../card-features/hui-area-controls-card-feature";
|
||||||
|
import type { AreaControl } from "../../card-features/types";
|
||||||
|
import type { AreaCardConfig, HeadingCardConfig } from "../../cards/types";
|
||||||
import type { EntitiesDisplay } from "./area-view-strategy";
|
import type { EntitiesDisplay } from "./area-view-strategy";
|
||||||
import {
|
import { computeAreaPath, getAreas } from "./helpers/areas-strategy-helper";
|
||||||
computeAreaPath,
|
|
||||||
computeAreaTileCardConfig,
|
|
||||||
getAreaGroupedEntities,
|
|
||||||
getAreas,
|
|
||||||
} from "./helpers/areas-strategy-helper";
|
|
||||||
|
|
||||||
interface AreaOptions {
|
interface AreaOptions {
|
||||||
groups_options?: Record<string, EntitiesDisplay>;
|
groups_options?: Record<string, EntitiesDisplay>;
|
||||||
@ -36,71 +36,88 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
|
|||||||
config.areas_display?.order
|
config.areas_display?.order
|
||||||
);
|
);
|
||||||
|
|
||||||
const areaSections = areas
|
const floors = Object.values(hass.floors);
|
||||||
.map<LovelaceSectionConfig | undefined>((area) => {
|
floors.sort((floorA, floorB) => {
|
||||||
const path = computeAreaPath(area.area_id);
|
if (floorA.level !== floorB.level) {
|
||||||
|
return (floorA.level ?? 0) - (floorB.level ?? 0);
|
||||||
|
}
|
||||||
|
return stringCompare(floorA.name, floorB.name);
|
||||||
|
});
|
||||||
|
|
||||||
const areaConfig = config.areas_options?.[area.area_id];
|
const floorSections = [
|
||||||
|
...floors,
|
||||||
const groups = getAreaGroupedEntities(
|
{ floor_id: "default", name: "Default", level: null, icon: null },
|
||||||
area.area_id,
|
]
|
||||||
hass,
|
.map<LovelaceSectionConfig | undefined>((floor) => {
|
||||||
areaConfig?.groups_options
|
const areasInFloors = areas.filter(
|
||||||
|
(area) =>
|
||||||
|
area.floor_id === floor.floor_id ||
|
||||||
|
(!area.floor_id && floor.floor_id === "default")
|
||||||
);
|
);
|
||||||
|
|
||||||
const entities = [
|
if (areasInFloors.length === 0) {
|
||||||
...groups.lights,
|
return undefined;
|
||||||
...groups.covers,
|
}
|
||||||
...groups.climate,
|
|
||||||
...groups.media_players,
|
|
||||||
...groups.security,
|
|
||||||
...groups.actions,
|
|
||||||
...groups.others,
|
|
||||||
];
|
|
||||||
|
|
||||||
const computeTileCard = computeAreaTileCardConfig(hass, area.name);
|
const areasCards = areasInFloors.map<AreaCardConfig>((area) => {
|
||||||
|
const path = computeAreaPath(area.area_id);
|
||||||
|
|
||||||
|
const controls: AreaControl[] = ["light", "fan"];
|
||||||
|
const controlEntities = getAreaControlEntities(
|
||||||
|
controls,
|
||||||
|
area.area_id,
|
||||||
|
hass
|
||||||
|
);
|
||||||
|
|
||||||
|
const filteredControls = controls.filter(
|
||||||
|
(control) => controlEntities[control].length > 0
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "area",
|
||||||
|
area: area.area_id,
|
||||||
|
display_type: "compact",
|
||||||
|
sensor_classes: ["temperature", "humidity"],
|
||||||
|
alert_classes: [
|
||||||
|
"water_leak",
|
||||||
|
"smoke",
|
||||||
|
"gas",
|
||||||
|
"co",
|
||||||
|
"motion",
|
||||||
|
"occupancy",
|
||||||
|
"presence",
|
||||||
|
],
|
||||||
|
features: filteredControls.length
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
type: "area-controls",
|
||||||
|
controls: filteredControls,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [],
|
||||||
|
navigation_path: path,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const headingCard: HeadingCardConfig = {
|
||||||
|
type: "heading",
|
||||||
|
heading_style: "title",
|
||||||
|
heading: floor.name,
|
||||||
|
icon: floor.icon || floorDefaultIcon(floor),
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
max_columns: 3,
|
||||||
type: "grid",
|
type: "grid",
|
||||||
cards: [
|
cards: [headingCard, ...areasCards],
|
||||||
{
|
|
||||||
type: "heading",
|
|
||||||
heading: area.name,
|
|
||||||
icon: area.icon || undefined,
|
|
||||||
badges: [
|
|
||||||
...(area.temperature_entity_id
|
|
||||||
? [{ entity: area.temperature_entity_id }]
|
|
||||||
: []),
|
|
||||||
...(area.humidity_entity_id
|
|
||||||
? [{ entity: area.humidity_entity_id }]
|
|
||||||
: []),
|
|
||||||
],
|
|
||||||
tap_action: {
|
|
||||||
action: "navigate",
|
|
||||||
navigation_path: path,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
...(entities.length
|
|
||||||
? entities.map(computeTileCard)
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
type: "markdown",
|
|
||||||
content: hass.localize(
|
|
||||||
"ui.panel.lovelace.strategy.areas.no_entities"
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter(
|
?.filter((section) => section !== undefined);
|
||||||
(section): section is LovelaceSectionConfig => section !== undefined
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: "sections",
|
type: "sections",
|
||||||
max_columns: 3,
|
max_columns: 3,
|
||||||
sections: areaSections,
|
sections: floorSections || [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user