mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
Move exclude entities config to area card (#25909)
This commit is contained in:
parent
3ab6a02994
commit
af149dcfab
@ -18,6 +18,7 @@ import type { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { forwardHaptic } from "../../../data/haptics";
|
||||
import { computeCssVariable } from "../../../resources/css-variables";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { AreaCardFeatureContext } from "../cards/hui-area-card";
|
||||
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||
import { cardFeatureStyles } from "./common/card-feature-styles";
|
||||
import type {
|
||||
@ -86,8 +87,8 @@ export const supportsAreaControlsCardFeature = (
|
||||
export const getAreaControlEntities = (
|
||||
controls: AreaControl[],
|
||||
areaId: string,
|
||||
hass: HomeAssistant,
|
||||
excludeEntities: string[] = []
|
||||
excludeEntities: string[] | undefined,
|
||||
hass: HomeAssistant
|
||||
): Record<AreaControl, string[]> =>
|
||||
controls.reduce(
|
||||
(acc, control) => {
|
||||
@ -99,7 +100,7 @@ export const getAreaControlEntities = (
|
||||
});
|
||||
|
||||
acc[control] = Object.keys(hass.entities).filter(
|
||||
(entityId) => filter(entityId) && !excludeEntities.includes(entityId)
|
||||
(entityId) => filter(entityId) && !excludeEntities?.includes(entityId)
|
||||
);
|
||||
return acc;
|
||||
},
|
||||
@ -115,7 +116,7 @@ class HuiAreaControlsCardFeature
|
||||
{
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
|
||||
@property({ attribute: false }) public context?: AreaCardFeatureContext;
|
||||
|
||||
@property({ attribute: false })
|
||||
public position?: LovelaceCardFeaturePosition;
|
||||
@ -168,7 +169,7 @@ class HuiAreaControlsCardFeature
|
||||
const controlEntities = this._controlEntities(
|
||||
this._controls,
|
||||
this.context.area_id,
|
||||
this._config.exclude_entities,
|
||||
this.context.exclude_entities,
|
||||
this.hass!.entities,
|
||||
this.hass!.devices,
|
||||
this.hass!.areas
|
||||
@ -192,7 +193,7 @@ class HuiAreaControlsCardFeature
|
||||
_entities: HomeAssistant["entities"],
|
||||
_devices: HomeAssistant["devices"],
|
||||
_areas: HomeAssistant["areas"]
|
||||
) => getAreaControlEntities(controls, areaId, this.hass!, excludeEntities)
|
||||
) => getAreaControlEntities(controls, areaId, excludeEntities, this.hass!)
|
||||
);
|
||||
|
||||
protected render() {
|
||||
@ -209,7 +210,7 @@ class HuiAreaControlsCardFeature
|
||||
const controlEntities = this._controlEntities(
|
||||
this._controls,
|
||||
this.context.area_id!,
|
||||
this._config.exclude_entities,
|
||||
this.context.exclude_entities,
|
||||
this.hass!.entities,
|
||||
this.hass!.devices,
|
||||
this.hass!.areas
|
||||
|
@ -179,7 +179,6 @@ export type AreaControl = (typeof AREA_CONTROLS)[number];
|
||||
export interface AreaControlsCardFeatureConfig {
|
||||
type: "area-controls";
|
||||
controls?: AreaControl[];
|
||||
exclude_entities?: string[];
|
||||
}
|
||||
|
||||
export type LovelaceCardFeaturePosition = "bottom" | "inline";
|
||||
|
@ -53,6 +53,10 @@ export const DEVICE_CLASSES = {
|
||||
binary_sensor: ["motion", "moisture"],
|
||||
};
|
||||
|
||||
export interface AreaCardFeatureContext extends LovelaceCardFeatureContext {
|
||||
exclude_entities?: string[];
|
||||
}
|
||||
|
||||
@customElement("hui-area-card")
|
||||
export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -61,7 +65,7 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
|
||||
@state() private _config?: AreaCardConfig;
|
||||
|
||||
@state() private _featureContext: LovelaceCardFeatureContext = {};
|
||||
@state() private _featureContext: AreaCardFeatureContext = {};
|
||||
|
||||
private _ratio: {
|
||||
w: number;
|
||||
@ -87,6 +91,7 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
|
||||
this._featureContext = {
|
||||
area_id: config.area,
|
||||
exclude_entities: config.exclude_entities,
|
||||
};
|
||||
}
|
||||
|
||||
@ -166,7 +171,8 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
(
|
||||
entities: HomeAssistant["entities"],
|
||||
areaId: string,
|
||||
sensorClasses: string[]
|
||||
sensorClasses: string[],
|
||||
excludeEntities?: string[]
|
||||
): Map<string, string[]> => {
|
||||
const sensorFilter = generateEntityFilter(this.hass, {
|
||||
area: areaId,
|
||||
@ -174,7 +180,10 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
domain: "sensor",
|
||||
device_class: sensorClasses,
|
||||
});
|
||||
const entityIds = Object.keys(entities).filter(sensorFilter);
|
||||
const entityIds = Object.keys(entities).filter(
|
||||
(id) => sensorFilter(id) && !excludeEntities?.includes(id)
|
||||
);
|
||||
|
||||
return this._groupEntitiesByDeviceClass(entityIds);
|
||||
}
|
||||
);
|
||||
@ -183,7 +192,8 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
(
|
||||
entities: HomeAssistant["entities"],
|
||||
areaId: string,
|
||||
binarySensorClasses: string[]
|
||||
binarySensorClasses: string[],
|
||||
excludeEntities?: string[]
|
||||
): Map<string, string[]> => {
|
||||
const binarySensorFilter = generateEntityFilter(this.hass, {
|
||||
area: areaId,
|
||||
@ -191,7 +201,11 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
domain: "binary_sensor",
|
||||
device_class: binarySensorClasses,
|
||||
});
|
||||
const entityIds = Object.keys(entities).filter(binarySensorFilter);
|
||||
|
||||
const entityIds = Object.keys(entities).filter(
|
||||
(id) => binarySensorFilter(id) && !excludeEntities?.includes(id)
|
||||
);
|
||||
|
||||
return this._groupEntitiesByDeviceClass(entityIds);
|
||||
}
|
||||
);
|
||||
@ -215,13 +229,15 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
const areaId = this._config?.area;
|
||||
const area = areaId ? this.hass.areas[areaId] : undefined;
|
||||
const alertClasses = this._config?.alert_classes;
|
||||
const excludeEntities = this._config?.exclude_entities;
|
||||
if (!area || !alertClasses) {
|
||||
return [];
|
||||
}
|
||||
const groupedEntities = this._groupedBinarySensorEntityIds(
|
||||
this.hass.entities,
|
||||
area.area_id,
|
||||
alertClasses
|
||||
alertClasses,
|
||||
excludeEntities
|
||||
);
|
||||
|
||||
return (
|
||||
@ -286,6 +302,7 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
const areaId = this._config?.area;
|
||||
const area = areaId ? this.hass.areas[areaId] : undefined;
|
||||
const sensorClasses = this._config?.sensor_classes;
|
||||
const excludeEntities = this._config?.exclude_entities;
|
||||
if (!area || !sensorClasses) {
|
||||
return undefined;
|
||||
}
|
||||
@ -293,7 +310,8 @@ export class HuiAreaCard extends LitElement implements LovelaceCard {
|
||||
const groupedEntities = this._groupedSensorEntityIds(
|
||||
this.hass.entities,
|
||||
area.area_id,
|
||||
sensorClasses
|
||||
sensorClasses,
|
||||
excludeEntities
|
||||
);
|
||||
|
||||
const sensorStates = sensorClasses
|
||||
|
@ -117,6 +117,7 @@ export interface AreaCardConfig extends LovelaceCardConfig {
|
||||
alert_classes?: string[];
|
||||
features?: LovelaceCardFeatureConfig[];
|
||||
features_position?: LovelaceCardFeaturePosition;
|
||||
exclude_entities?: string[];
|
||||
}
|
||||
|
||||
export interface ButtonCardConfig extends LovelaceCardConfig {
|
||||
|
@ -32,7 +32,10 @@ import type {
|
||||
LovelaceCardFeatureConfig,
|
||||
LovelaceCardFeatureContext,
|
||||
} from "../../card-features/types";
|
||||
import { DEVICE_CLASSES } from "../../cards/hui-area-card";
|
||||
import {
|
||||
DEVICE_CLASSES,
|
||||
type AreaCardFeatureContext,
|
||||
} from "../../cards/hui-area-card";
|
||||
import type { AreaCardConfig } from "../../cards/types";
|
||||
import type { LovelaceCardEditor } from "../../types";
|
||||
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||
@ -55,6 +58,7 @@ const cardConfigStruct = assign(
|
||||
features: optional(array(any())),
|
||||
features_position: optional(enums(["bottom", "inline"])),
|
||||
aspect_ratio: optional(string()),
|
||||
exclude_entities: optional(array(string())),
|
||||
})
|
||||
);
|
||||
|
||||
@ -69,11 +73,7 @@ export class HuiAreaCardEditor
|
||||
|
||||
@state() private _numericDeviceClasses?: string[];
|
||||
|
||||
private _featureContext = memoizeOne(
|
||||
(areaId?: string): LovelaceCardFeatureContext => ({
|
||||
area_id: areaId,
|
||||
})
|
||||
);
|
||||
@state() private _featureContext: AreaCardFeatureContext = {};
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(
|
||||
@ -174,7 +174,10 @@ export class HuiAreaCardEditor
|
||||
);
|
||||
|
||||
private _binaryClassesForArea = memoizeOne(
|
||||
(area: string | undefined): string[] => {
|
||||
(
|
||||
area: string | undefined,
|
||||
excludeEntities: string[] | undefined
|
||||
): string[] => {
|
||||
if (!area) {
|
||||
return [];
|
||||
}
|
||||
@ -186,7 +189,9 @@ export class HuiAreaCardEditor
|
||||
});
|
||||
|
||||
const classes = Object.keys(this.hass!.entities)
|
||||
.filter(binarySensorFilter)
|
||||
.filter(
|
||||
(id) => binarySensorFilter(id) && !excludeEntities?.includes(id)
|
||||
)
|
||||
.map((id) => this.hass!.states[id]?.attributes.device_class)
|
||||
.filter((c): c is string => Boolean(c));
|
||||
|
||||
@ -195,7 +200,11 @@ export class HuiAreaCardEditor
|
||||
);
|
||||
|
||||
private _sensorClassesForArea = memoizeOne(
|
||||
(area: string | undefined, numericDeviceClasses?: string[]): string[] => {
|
||||
(
|
||||
area: string | undefined,
|
||||
excludeEntities: string[] | undefined,
|
||||
numericDeviceClasses: string[] | undefined
|
||||
): string[] => {
|
||||
if (!area) {
|
||||
return [];
|
||||
}
|
||||
@ -208,7 +217,7 @@ export class HuiAreaCardEditor
|
||||
});
|
||||
|
||||
const classes = Object.keys(this.hass!.entities)
|
||||
.filter(sensorFilter)
|
||||
.filter((id) => sensorFilter(id) && !excludeEntities?.includes(id))
|
||||
.map((id) => this.hass!.states[id]?.attributes.device_class)
|
||||
.filter((c): c is string => Boolean(c));
|
||||
|
||||
@ -257,6 +266,11 @@ export class HuiAreaCardEditor
|
||||
display_type: displayType,
|
||||
};
|
||||
delete this._config.show_camera;
|
||||
|
||||
this._featureContext = {
|
||||
area_id: config.area,
|
||||
exclude_entities: config.exclude_entities,
|
||||
};
|
||||
}
|
||||
|
||||
protected async updated() {
|
||||
@ -306,11 +320,13 @@ export class HuiAreaCardEditor
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const areaId = this._config!.area;
|
||||
|
||||
const possibleBinaryClasses = this._binaryClassesForArea(this._config.area);
|
||||
const possibleBinaryClasses = this._binaryClassesForArea(
|
||||
this._config.area,
|
||||
this._config.exclude_entities
|
||||
);
|
||||
const possibleSensorClasses = this._sensorClassesForArea(
|
||||
this._config.area,
|
||||
this._config.exclude_entities,
|
||||
this._numericDeviceClasses
|
||||
);
|
||||
const binarySelectOptions = this._buildBinaryOptions(
|
||||
@ -347,8 +363,9 @@ export class HuiAreaCardEditor
|
||||
...this._config,
|
||||
};
|
||||
|
||||
const featureContext = this._featureContext(areaId);
|
||||
const hasCompatibleFeatures = this._hasCompatibleFeatures(featureContext);
|
||||
const hasCompatibleFeatures = this._hasCompatibleFeatures(
|
||||
this._featureContext
|
||||
);
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
@ -381,7 +398,7 @@ export class HuiAreaCardEditor
|
||||
: nothing}
|
||||
<hui-card-features-editor
|
||||
.hass=${this.hass}
|
||||
.context=${featureContext}
|
||||
.context=${this._featureContext}
|
||||
.features=${this._config!.features ?? []}
|
||||
@features-changed=${this._featuresChanged}
|
||||
@edit-detail-element=${this._editDetailElement}
|
||||
@ -428,12 +445,11 @@ export class HuiAreaCardEditor
|
||||
private _editDetailElement(ev: HASSDomEvent<EditDetailElementEvent>): void {
|
||||
const index = ev.detail.subElementConfig.index;
|
||||
const config = this._config!.features![index!];
|
||||
const featureContext = this._featureContext(this._config!.area);
|
||||
|
||||
fireEvent(this, "edit-sub-element", {
|
||||
config: config,
|
||||
saveConfig: (newConfig) => this._updateFeature(index!, newConfig),
|
||||
context: featureContext,
|
||||
context: this._featureContext,
|
||||
type: "feature",
|
||||
} as EditSubElementEvent<
|
||||
LovelaceCardFeatureConfig,
|
||||
|
@ -17,8 +17,8 @@ import {
|
||||
AREA_CONTROLS,
|
||||
type AreaControl,
|
||||
type AreaControlsCardFeatureConfig,
|
||||
type LovelaceCardFeatureContext,
|
||||
} from "../../card-features/types";
|
||||
import type { AreaCardFeatureContext } from "../../cards/hui-area-card";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
|
||||
type AreaControlsCardFeatureData = AreaControlsCardFeatureConfig & {
|
||||
@ -32,7 +32,7 @@ export class HuiAreaControlsCardFeatureEditor
|
||||
{
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
|
||||
@property({ attribute: false }) public context?: AreaCardFeatureContext;
|
||||
|
||||
@state() private _config?: AreaControlsCardFeatureConfig;
|
||||
|
||||
@ -78,6 +78,7 @@ export class HuiAreaControlsCardFeatureEditor
|
||||
private _supportedControls = memoizeOne(
|
||||
(
|
||||
areaId: string,
|
||||
excludeEntities: string[] | undefined,
|
||||
// needed to update memoized function when entities, devices or areas change
|
||||
_entities: HomeAssistant["entities"],
|
||||
_devices: HomeAssistant["devices"],
|
||||
@ -89,6 +90,7 @@ export class HuiAreaControlsCardFeatureEditor
|
||||
const controlEntities = getAreaControlEntities(
|
||||
AREA_CONTROLS as unknown as AreaControl[],
|
||||
areaId,
|
||||
excludeEntities,
|
||||
this.hass!
|
||||
);
|
||||
return (
|
||||
@ -104,6 +106,7 @@ export class HuiAreaControlsCardFeatureEditor
|
||||
|
||||
const supportedControls = this._supportedControls(
|
||||
this.context.area_id,
|
||||
this.context.exclude_entities,
|
||||
this.hass.entities,
|
||||
this.hass.devices,
|
||||
this.hass.areas
|
||||
@ -148,6 +151,7 @@ export class HuiAreaControlsCardFeatureEditor
|
||||
if (customize_controls && !config.controls) {
|
||||
config.controls = this._supportedControls(
|
||||
this.context!.area_id!,
|
||||
this.context!.exclude_entities,
|
||||
this.hass!.entities,
|
||||
this.hass!.devices,
|
||||
this.hass!.areas
|
||||
|
@ -83,8 +83,8 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
|
||||
const controlEntities = getAreaControlEntities(
|
||||
controls,
|
||||
area.area_id,
|
||||
hass,
|
||||
hiddenEntities
|
||||
hiddenEntities,
|
||||
hass
|
||||
);
|
||||
|
||||
const filteredControls = controls.filter(
|
||||
@ -105,12 +105,12 @@ export class AreasOverviewViewStrategy extends ReactiveElement {
|
||||
"occupancy",
|
||||
"presence",
|
||||
],
|
||||
exclude_entities: hiddenEntities,
|
||||
features: filteredControls.length
|
||||
? [
|
||||
{
|
||||
type: "area-controls",
|
||||
controls: filteredControls,
|
||||
exclude_entities: hiddenEntities,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
|
Loading…
x
Reference in New Issue
Block a user