mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Add UI for setting an area on entity level (#7837)
This commit is contained in:
parent
7ceb6eb50d
commit
fe31d15d27
@ -137,8 +137,7 @@ export class DialogHassioNetwork extends LitElement
|
||||
)}
|
||||
${this._interface?.type === "wireless"
|
||||
? html`
|
||||
<ha-expansion-panel outlined>
|
||||
<span slot="title">Wi-Fi</span>
|
||||
<ha-expansion-panel header="Wi-Fi" outlined>
|
||||
${this._interface?.wifi?.ssid
|
||||
? html`<p>Connected to: ${this._interface?.wifi?.ssid}</p>`
|
||||
: ""}
|
||||
@ -281,8 +280,10 @@ export class DialogHassioNetwork extends LitElement
|
||||
|
||||
private _renderIPConfiguration(version: string) {
|
||||
return html`
|
||||
<ha-expansion-panel outlined>
|
||||
<span slot="title">IPv${version.charAt(version.length - 1)}</span>
|
||||
<ha-expansion-panel
|
||||
.header=${`IPv${version.charAt(version.length - 1)}`}
|
||||
outlined
|
||||
>
|
||||
<div class="radio-row">
|
||||
<ha-formfield label="DHCP">
|
||||
<ha-radio
|
||||
@ -591,6 +592,7 @@ export class DialogHassioNetwork extends LitElement
|
||||
}
|
||||
|
||||
ha-expansion-panel {
|
||||
--expansion-panel-summary-padding: 0 16px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
paper-input {
|
||||
|
@ -28,6 +28,7 @@ import {
|
||||
import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
||||
import { PolymerChangedEvent } from "../polymer-types";
|
||||
import { HomeAssistant } from "../types";
|
||||
import memoizeOne from "memoize-one";
|
||||
|
||||
const rowRenderer = (
|
||||
root: HTMLElement,
|
||||
@ -68,6 +69,8 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
|
||||
|
||||
@property() public value?: string;
|
||||
|
||||
@property() public placeholder?: string;
|
||||
|
||||
@property() public _areas?: AreaRegistryEntry[];
|
||||
|
||||
@property({ type: Boolean, attribute: "no-add" })
|
||||
@ -110,6 +113,9 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
|
||||
.label=${this.label === undefined && this.hass
|
||||
? this.hass.localize("ui.components.area-picker.area")
|
||||
: this.label}
|
||||
.placeholder=${this.placeholder
|
||||
? this._area(this.placeholder)?.name
|
||||
: undefined}
|
||||
class="input"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
@ -151,6 +157,12 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
|
||||
`;
|
||||
}
|
||||
|
||||
private _area = memoizeOne((areaId: string):
|
||||
| AreaRegistryEntry
|
||||
| undefined => {
|
||||
return this._areas?.find((area) => area.area_id === areaId);
|
||||
});
|
||||
|
||||
private _clearValue(ev: Event) {
|
||||
ev.stopPropagation();
|
||||
this._setValue("");
|
||||
|
@ -19,12 +19,14 @@ class HaExpansionPanel extends LitElement {
|
||||
|
||||
@property({ type: Boolean, reflect: true }) outlined = false;
|
||||
|
||||
@property() header?: string;
|
||||
|
||||
@query(".container") private _container!: HTMLDivElement;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div class="summary" @click=${this._toggleContainer}>
|
||||
<slot name="title"></slot>
|
||||
<slot name="header">${this.header}</slot>
|
||||
<ha-svg-icon
|
||||
.path=${mdiChevronDown}
|
||||
class="summary-icon ${classMap({ expanded: this.expanded })}"
|
||||
@ -76,7 +78,7 @@ class HaExpansionPanel extends LitElement {
|
||||
|
||||
.summary {
|
||||
display: flex;
|
||||
padding: var(--expansion-panel-summary-padding, 0px 16px);
|
||||
padding: var(--expansion-panel-summary-padding, 0);
|
||||
min-height: 48px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
@ -10,6 +10,7 @@ export interface EntityRegistryEntry {
|
||||
platform: string;
|
||||
config_entry_id?: string;
|
||||
device_id?: string;
|
||||
area_id?: string;
|
||||
disabled_by: string | null;
|
||||
}
|
||||
|
||||
@ -29,6 +30,7 @@ export interface UpdateEntityRegistryEntryResult {
|
||||
export interface EntityRegistryEntryUpdateParams {
|
||||
name?: string | null;
|
||||
icon?: string | null;
|
||||
area_id?: string | null;
|
||||
disabled_by?: string | null;
|
||||
new_entity_id?: string;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import "@polymer/paper-input/paper-input";
|
||||
import type { PaperInputElement } from "@polymer/paper-input/paper-input";
|
||||
import "../../../components/ha-circular-progress";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
@ -97,12 +96,11 @@ class DialogImportBlueprint extends LitElement {
|
||||
)}
|
||||
></paper-input>
|
||||
`}
|
||||
<ha-expansion-panel>
|
||||
<span slot="title"
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.blueprint.add.raw_blueprint"
|
||||
)}</span
|
||||
>
|
||||
<ha-expansion-panel
|
||||
.header=${this.hass.localize(
|
||||
"ui.panel.config.blueprint.add.raw_blueprint"
|
||||
)}
|
||||
>
|
||||
<pre>${this._result.raw_data}</pre>
|
||||
</ha-expansion-panel>`
|
||||
: html`${this.hass.localize(
|
||||
@ -201,15 +199,8 @@ class DialogImportBlueprint extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
ha-expansion-panel {
|
||||
--expansion-panel-summary-padding: 0;
|
||||
}
|
||||
`,
|
||||
];
|
||||
static get styles(): CSSResult {
|
||||
return haStyleDialog;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
computeDeviceName,
|
||||
DeviceRegistryEntry,
|
||||
} from "../../../../data/device_registry";
|
||||
import { loadDeviceRegistryDetailDialog } from "../../../../dialogs/device-registry-detail/show-dialog-device-registry-detail";
|
||||
import { loadDeviceRegistryDetailDialog } from "../device-registry-detail/show-dialog-device-registry-detail";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
|
||||
@customElement("ha-device-info-card")
|
||||
|
@ -3,8 +3,8 @@ import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import "../../components/ha-dialog";
|
||||
import "../../components/ha-area-picker";
|
||||
import "../../../../components/ha-dialog";
|
||||
import "../../../../components/ha-area-picker";
|
||||
|
||||
import {
|
||||
CSSResult,
|
||||
@ -18,11 +18,11 @@ import {
|
||||
} from "lit-element";
|
||||
|
||||
import { DeviceRegistryDetailDialogParams } from "./show-dialog-device-registry-detail";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
import { computeDeviceName } from "../../data/device_registry";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { PolymerChangedEvent } from "../../../../polymer-types";
|
||||
import { computeDeviceName } from "../../../../data/device_registry";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { haStyleDialog } from "../../../../resources/styles";
|
||||
|
||||
@customElement("dialog-device-registry-detail")
|
||||
class DialogDeviceRegistryDetail extends LitElement {
|
@ -1,8 +1,8 @@
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
DeviceRegistryEntryMutableParams,
|
||||
} from "../../data/device_registry";
|
||||
} from "../../../../data/device_registry";
|
||||
|
||||
export interface DeviceRegistryDetailDialogParams {
|
||||
device: DeviceRegistryEntry;
|
@ -35,7 +35,7 @@ import { findRelated, RelatedResult } from "../../../data/search";
|
||||
import {
|
||||
loadDeviceRegistryDetailDialog,
|
||||
showDeviceRegistryDetailDialog,
|
||||
} from "../../../dialogs/device-registry-detail/show-dialog-device-registry-detail";
|
||||
} from "./device-registry-detail/show-dialog-device-registry-detail";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/hass-error-screen";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
|
@ -20,9 +20,16 @@ import {
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import type { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import "../../../components/ha-area-picker";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../data/device_registry";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
|
||||
@customElement("ha-registry-basic-editor")
|
||||
export class HaEntityRegistryBasicEditor extends LitElement {
|
||||
export class HaEntityRegistryBasicEditor extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public entry!: ExtEntityRegistryEntry;
|
||||
@ -31,16 +38,26 @@ export class HaEntityRegistryBasicEditor extends LitElement {
|
||||
|
||||
@internalProperty() private _entityId!: string;
|
||||
|
||||
@internalProperty() private _areaId?: string;
|
||||
|
||||
@internalProperty() private _disabledBy!: string | null;
|
||||
|
||||
private _deviceLookup?: Record<string, DeviceRegistryEntry>;
|
||||
|
||||
@internalProperty() private _device?: DeviceRegistryEntry;
|
||||
|
||||
@internalProperty() private _submitting?: boolean;
|
||||
|
||||
public async updateEntry(): Promise<void> {
|
||||
this._submitting = true;
|
||||
const params: Partial<EntityRegistryEntryUpdateParams> = {
|
||||
new_entity_id: this._entityId.trim(),
|
||||
area_id: this._areaId || null,
|
||||
};
|
||||
if (this._disabledBy === null || this._disabledBy === "user") {
|
||||
if (
|
||||
this.entry.disabled_by !== this._disabledBy &&
|
||||
(this._disabledBy === null || this._disabledBy === "user")
|
||||
) {
|
||||
params.disabled_by = this._disabledBy;
|
||||
}
|
||||
try {
|
||||
@ -70,6 +87,20 @@ export class HaEntityRegistryBasicEditor extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
||||
this._deviceLookup = {};
|
||||
for (const device of devices) {
|
||||
this._deviceLookup[device.id] = device;
|
||||
}
|
||||
if (!this._device && this.entry.device_id) {
|
||||
this._device = this._deviceLookup[this.entry.device_id];
|
||||
}
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues) {
|
||||
super.updated(changedProperties);
|
||||
if (!changedProperties.has("entry")) {
|
||||
@ -79,6 +110,11 @@ export class HaEntityRegistryBasicEditor extends LitElement {
|
||||
this._origEntityId = this.entry.entity_id;
|
||||
this._entityId = this.entry.entity_id;
|
||||
this._disabledBy = this.entry.disabled_by;
|
||||
this._areaId = this.entry.area_id;
|
||||
this._device =
|
||||
this.entry.device_id && this._deviceLookup
|
||||
? this._deviceLookup[this.entry.device_id]
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,6 +141,12 @@ export class HaEntityRegistryBasicEditor extends LitElement {
|
||||
.invalid=${invalidDomainUpdate}
|
||||
.disabled=${this._submitting}
|
||||
></paper-input>
|
||||
<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._areaId}
|
||||
.placeholder=${this._device?.area_id}
|
||||
@value-changed=${this._areaPicked}
|
||||
></ha-area-picker>
|
||||
<div class="row">
|
||||
<ha-switch
|
||||
.checked=${!this._disabledBy}
|
||||
@ -139,6 +181,10 @@ export class HaEntityRegistryBasicEditor extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _areaPicked(ev: CustomEvent) {
|
||||
this._areaId = ev.detail.value;
|
||||
}
|
||||
|
||||
private _entityIdChanged(ev: PolymerChangedEvent<string>): void {
|
||||
this._entityId = ev.detail.value;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -31,9 +31,18 @@ import type { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
||||
import "../../../components/ha-area-picker";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
updateDeviceRegistryEntry,
|
||||
} from "../../../data/device_registry";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import "../../../components/ha-expansion-panel";
|
||||
import { showDeviceRegistryDetailDialog } from "../devices/device-registry-detail/show-dialog-device-registry-detail";
|
||||
|
||||
@customElement("entity-registry-settings")
|
||||
export class EntityRegistrySettings extends LitElement {
|
||||
export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public entry!: ExtEntityRegistryEntry;
|
||||
@ -44,14 +53,34 @@ export class EntityRegistrySettings extends LitElement {
|
||||
|
||||
@internalProperty() private _entityId!: string;
|
||||
|
||||
@internalProperty() private _areaId?: string | null;
|
||||
|
||||
@internalProperty() private _disabledBy!: string | null;
|
||||
|
||||
private _deviceLookup?: Record<string, DeviceRegistryEntry>;
|
||||
|
||||
@internalProperty() private _device?: DeviceRegistryEntry;
|
||||
|
||||
@internalProperty() private _error?: string;
|
||||
|
||||
@internalProperty() private _submitting?: boolean;
|
||||
|
||||
private _origEntityId!: string;
|
||||
|
||||
public hassSubscribe(): UnsubscribeFunc[] {
|
||||
return [
|
||||
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
||||
this._deviceLookup = {};
|
||||
for (const device of devices) {
|
||||
this._deviceLookup[device.id] = device;
|
||||
}
|
||||
if (this.entry.device_id) {
|
||||
this._device = this._deviceLookup[this.entry.device_id];
|
||||
}
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has("entry")) {
|
||||
@ -59,8 +88,13 @@ export class EntityRegistrySettings extends LitElement {
|
||||
this._name = this.entry.name || "";
|
||||
this._icon = this.entry.icon || "";
|
||||
this._origEntityId = this.entry.entity_id;
|
||||
this._areaId = this.entry.area_id;
|
||||
this._entityId = this.entry.entity_id;
|
||||
this._disabledBy = this.entry.disabled_by;
|
||||
this._device =
|
||||
this.entry.device_id && this._deviceLookup
|
||||
? this._deviceLookup[this.entry.device_id]
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +151,13 @@ export class EntityRegistrySettings extends LitElement {
|
||||
.invalid=${invalidDomainUpdate}
|
||||
.disabled=${this._submitting}
|
||||
></paper-input>
|
||||
${!this.entry.device_id
|
||||
? html`<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._areaId}
|
||||
@value-changed=${this._areaPicked}
|
||||
></ha-area-picker>`
|
||||
: ""}
|
||||
<div class="row">
|
||||
<ha-switch
|
||||
.checked=${!this._disabledBy}
|
||||
@ -148,6 +189,31 @@ export class EntityRegistrySettings extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${this.entry.device_id
|
||||
? html`<ha-expansion-panel .header=${"Advanced"}>
|
||||
<p>
|
||||
By default the entities of a device are in the same area as the
|
||||
device. If you change the area of this entity, it will no longer
|
||||
follow the area of the device.
|
||||
</p>
|
||||
${this._areaId
|
||||
? html`<mwc-button @click=${this._clearArea}
|
||||
>Follow device area</mwc-button
|
||||
>`
|
||||
: this._device
|
||||
? html`<mwc-button @click=${this._openDeviceSettings}
|
||||
>Change device area</mwc-button
|
||||
>`
|
||||
: ""}
|
||||
<ha-area-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._areaId}
|
||||
.placeholder=${this._device?.area_id}
|
||||
@value-changed=${this._areaPicked}
|
||||
></ha-area-picker
|
||||
></ha-expansion-panel>`
|
||||
: ""}
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<mwc-button
|
||||
@ -183,14 +249,37 @@ export class EntityRegistrySettings extends LitElement {
|
||||
this._entityId = ev.detail.value;
|
||||
}
|
||||
|
||||
private _areaPicked(ev: CustomEvent) {
|
||||
this._error = undefined;
|
||||
this._areaId = ev.detail.value;
|
||||
}
|
||||
|
||||
private _clearArea() {
|
||||
this._error = undefined;
|
||||
this._areaId = null;
|
||||
}
|
||||
|
||||
private _openDeviceSettings() {
|
||||
showDeviceRegistryDetailDialog(this, {
|
||||
device: this._device!,
|
||||
updateEntry: async (updates) => {
|
||||
await updateDeviceRegistryEntry(this.hass, this._device!.id, updates);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async _updateEntry(): Promise<void> {
|
||||
this._submitting = true;
|
||||
const params: Partial<EntityRegistryEntryUpdateParams> = {
|
||||
name: this._name.trim() || null,
|
||||
icon: this._icon.trim() || null,
|
||||
area_id: this._areaId || null,
|
||||
new_entity_id: this._entityId.trim(),
|
||||
};
|
||||
if (this._disabledBy === null || this._disabledBy === "user") {
|
||||
if (
|
||||
this.entry.disabled_by !== this._disabledBy &&
|
||||
(this._disabledBy === null || this._disabledBy === "user")
|
||||
) {
|
||||
params.disabled_by = this._disabledBy;
|
||||
}
|
||||
try {
|
||||
|
@ -62,6 +62,14 @@ import {
|
||||
} from "./show-dialog-entity-editor";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../data/device_registry";
|
||||
import {
|
||||
AreaRegistryEntry,
|
||||
subscribeAreaRegistry,
|
||||
} from "../../../data/area_registry";
|
||||
|
||||
export interface StateEntity extends EntityRegistryEntry {
|
||||
readonly?: boolean;
|
||||
@ -73,6 +81,7 @@ export interface EntityRow extends StateEntity {
|
||||
unavailable: boolean;
|
||||
restored: boolean;
|
||||
status: string;
|
||||
area?: string;
|
||||
}
|
||||
|
||||
@customElement("ha-config-entities")
|
||||
@ -87,6 +96,10 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
|
||||
@internalProperty() private _entities?: EntityRegistryEntry[];
|
||||
|
||||
@internalProperty() private _devices?: DeviceRegistryEntry[];
|
||||
|
||||
@internalProperty() private _areas: AreaRegistryEntry[] = [];
|
||||
|
||||
@internalProperty() private _stateEntities: StateEntity[] = [];
|
||||
|
||||
@property() public _entries?: ConfigEntry[];
|
||||
@ -201,6 +214,15 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
template: (platform) =>
|
||||
this.hass.localize(`component.${platform}.title`) || platform,
|
||||
},
|
||||
area: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.entities.picker.headers.area"
|
||||
),
|
||||
sortable: true,
|
||||
hidden: narrow,
|
||||
filterable: true,
|
||||
width: "15%",
|
||||
},
|
||||
status: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.entities.picker.headers.status"
|
||||
@ -255,6 +277,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
private _filteredEntities = memoize(
|
||||
(
|
||||
entities: EntityRegistryEntry[],
|
||||
devices: DeviceRegistryEntry[] | undefined,
|
||||
areas: AreaRegistryEntry[] | undefined,
|
||||
stateEntities: StateEntity[],
|
||||
filters: URLSearchParams,
|
||||
showDisabled: boolean,
|
||||
@ -262,21 +286,42 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
showReadOnly: boolean
|
||||
): EntityRow[] => {
|
||||
const result: EntityRow[] = [];
|
||||
|
||||
// If nothing gets filtered, this is our correct count of entities
|
||||
let startLength = entities.length + stateEntities.length;
|
||||
|
||||
entities = showReadOnly ? entities.concat(stateEntities) : entities;
|
||||
const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
|
||||
const deviceLookup: { [deviceId: string]: DeviceRegistryEntry } = {};
|
||||
|
||||
if (areas) {
|
||||
for (const area of areas) {
|
||||
areaLookup[area.area_id] = area;
|
||||
}
|
||||
if (devices) {
|
||||
for (const device of devices) {
|
||||
deviceLookup[device.id] = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entities.forEach((entity) => {
|
||||
return entity;
|
||||
});
|
||||
|
||||
let filteredEntities = showReadOnly
|
||||
? entities.concat(stateEntities)
|
||||
: entities;
|
||||
|
||||
filters.forEach((value, key) => {
|
||||
switch (key) {
|
||||
case "config_entry":
|
||||
entities = entities.filter(
|
||||
filteredEntities = filteredEntities.filter(
|
||||
(entity) => entity.config_entry_id === value
|
||||
);
|
||||
// If we have an active filter and `showReadOnly` is true, the length of `entities` is correct.
|
||||
// If however, the read-only entities were not added before, we need to check how many would
|
||||
// have matched the active filter and add that number to the count.
|
||||
startLength = entities.length;
|
||||
startLength = filteredEntities.length;
|
||||
if (!showReadOnly) {
|
||||
startLength += stateEntities.filter(
|
||||
(entity) => entity.config_entry_id === value
|
||||
@ -287,13 +332,17 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
});
|
||||
|
||||
if (!showDisabled) {
|
||||
entities = entities.filter((entity) => !entity.disabled_by);
|
||||
filteredEntities = filteredEntities.filter(
|
||||
(entity) => !entity.disabled_by
|
||||
);
|
||||
}
|
||||
|
||||
for (const entry of entities) {
|
||||
for (const entry of filteredEntities) {
|
||||
const entity = this.hass.states[entry.entity_id];
|
||||
const unavailable = entity?.state === UNAVAILABLE;
|
||||
const restored = entity?.attributes.restored;
|
||||
const areaId = entry.area_id ?? deviceLookup[entry.device_id!]?.area_id;
|
||||
const area = areaId ? areaLookup[areaId] : undefined;
|
||||
|
||||
if (!showUnavailable && unavailable) {
|
||||
continue;
|
||||
@ -309,6 +358,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
this.hass.localize("state.default.unavailable"),
|
||||
unavailable,
|
||||
restored,
|
||||
area: area ? area.name : undefined,
|
||||
status: restored
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.entities.picker.status.restored"
|
||||
@ -345,6 +395,12 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||
this._entities = entities;
|
||||
}),
|
||||
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
|
||||
this._devices = devices;
|
||||
}),
|
||||
subscribeAreaRegistry(this.hass.connection, (areas) => {
|
||||
this._areas = areas;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
@ -372,6 +428,8 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
|
||||
const entityData = this._filteredEntities(
|
||||
this._entities,
|
||||
this._devices,
|
||||
this._areas,
|
||||
this._stateEntities,
|
||||
this._searchParms,
|
||||
this._showDisabled,
|
||||
|
@ -1830,6 +1830,7 @@
|
||||
"name": "Name",
|
||||
"entity_id": "Entity ID",
|
||||
"integration": "Integration",
|
||||
"area": "Area",
|
||||
"status": "Status"
|
||||
},
|
||||
"selected": "{number} selected",
|
||||
|
Loading…
x
Reference in New Issue
Block a user