mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add floors to hass (#21960)
This commit is contained in:
parent
68a0d04f04
commit
32feab6a70
@ -1,6 +1,6 @@
|
|||||||
import { mdiTextureBox } from "@mdi/js";
|
import { mdiTextureBox } from "@mdi/js";
|
||||||
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
|
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
|
||||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { LitElement, PropertyValues, TemplateResult, html, nothing } from "lit";
|
import { LitElement, PropertyValues, TemplateResult, html, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
@ -20,12 +20,7 @@ import {
|
|||||||
getDeviceEntityDisplayLookup,
|
getDeviceEntityDisplayLookup,
|
||||||
} from "../data/device_registry";
|
} from "../data/device_registry";
|
||||||
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
||||||
import {
|
import { FloorRegistryEntry, getFloorAreaLookup } from "../data/floor_registry";
|
||||||
FloorRegistryEntry,
|
|
||||||
getFloorAreaLookup,
|
|
||||||
subscribeFloorRegistry,
|
|
||||||
} from "../data/floor_registry";
|
|
||||||
import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
|
||||||
import { HomeAssistant, ValueChangedEvent } from "../types";
|
import { HomeAssistant, ValueChangedEvent } from "../types";
|
||||||
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
|
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
|
||||||
import "./ha-combo-box";
|
import "./ha-combo-box";
|
||||||
@ -50,7 +45,7 @@ interface FloorAreaEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@customElement("ha-area-floor-picker")
|
@customElement("ha-area-floor-picker")
|
||||||
export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
|
export class HaAreaFloorPicker extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public label?: string;
|
@property() public label?: string;
|
||||||
@ -111,22 +106,12 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public required = false;
|
@property({ type: Boolean }) public required = false;
|
||||||
|
|
||||||
@state() private _floors?: FloorRegistryEntry[];
|
|
||||||
|
|
||||||
@state() private _opened?: boolean;
|
@state() private _opened?: boolean;
|
||||||
|
|
||||||
@query("ha-combo-box", true) public comboBox!: HaComboBox;
|
@query("ha-combo-box", true) public comboBox!: HaComboBox;
|
||||||
|
|
||||||
private _init = false;
|
private _init = false;
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
|
||||||
return [
|
|
||||||
subscribeFloorRegistry(this.hass.connection, (floors) => {
|
|
||||||
this._floors = floors;
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
public async open() {
|
public async open() {
|
||||||
await this.updateComplete;
|
await this.updateComplete;
|
||||||
await this.comboBox?.open();
|
await this.comboBox?.open();
|
||||||
@ -431,12 +416,12 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
if (
|
if (
|
||||||
(!this._init && this.hass && this._floors) ||
|
(!this._init && this.hass) ||
|
||||||
(this._init && changedProps.has("_opened") && this._opened)
|
(this._init && changedProps.has("_opened") && this._opened)
|
||||||
) {
|
) {
|
||||||
this._init = true;
|
this._init = true;
|
||||||
const areas = this._getAreas(
|
const areas = this._getAreas(
|
||||||
this._floors!,
|
Object.values(this.hass.floors),
|
||||||
Object.values(this.hass.areas),
|
Object.values(this.hass.areas),
|
||||||
Object.values(this.hass.devices),
|
Object.values(this.hass.devices),
|
||||||
Object.values(this.hass.entities),
|
Object.values(this.hass.entities),
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import "@material/mwc-menu/mwc-menu-surface";
|
import "@material/mwc-menu/mwc-menu-surface";
|
||||||
import { mdiFilterVariantRemove, mdiTextureBox } from "@mdi/js";
|
import { mdiFilterVariantRemove, mdiTextureBox } from "@mdi/js";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
@ -15,13 +14,8 @@ import { repeat } from "lit/directives/repeat";
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { computeRTL } from "../common/util/compute_rtl";
|
import { computeRTL } from "../common/util/compute_rtl";
|
||||||
import {
|
import { getFloorAreaLookup } from "../data/floor_registry";
|
||||||
FloorRegistryEntry,
|
|
||||||
getFloorAreaLookup,
|
|
||||||
subscribeFloorRegistry,
|
|
||||||
} from "../data/floor_registry";
|
|
||||||
import { RelatedResult, findRelated } from "../data/search";
|
import { RelatedResult, findRelated } from "../data/search";
|
||||||
import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
|
||||||
import { haStyleScrollbar } from "../resources/styles";
|
import { haStyleScrollbar } from "../resources/styles";
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import "./ha-check-list-item";
|
import "./ha-check-list-item";
|
||||||
@ -31,7 +25,7 @@ import "./ha-svg-icon";
|
|||||||
import "./ha-tree-indicator";
|
import "./ha-tree-indicator";
|
||||||
|
|
||||||
@customElement("ha-filter-floor-areas")
|
@customElement("ha-filter-floor-areas")
|
||||||
export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
export class HaFilterFloorAreas extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public value?: {
|
@property({ attribute: false }) public value?: {
|
||||||
@ -47,8 +41,6 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _shouldRender = false;
|
@state() private _shouldRender = false;
|
||||||
|
|
||||||
@state() private _floors?: FloorRegistryEntry[];
|
|
||||||
|
|
||||||
public willUpdate(properties: PropertyValues) {
|
public willUpdate(properties: PropertyValues) {
|
||||||
super.willUpdate(properties);
|
super.willUpdate(properties);
|
||||||
|
|
||||||
@ -60,7 +52,7 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const areas = this._areas(this.hass.areas, this._floors);
|
const areas = this._areas(this.hass.areas, this.hass.floors);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-expansion-panel
|
<ha-expansion-panel
|
||||||
@ -189,14 +181,6 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||||||
this._findRelated();
|
this._findRelated();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
|
||||||
return [
|
|
||||||
subscribeFloorRegistry(this.hass.connection, (floors) => {
|
|
||||||
this._floors = floors;
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected updated(changed) {
|
protected updated(changed) {
|
||||||
if (changed.has("expanded") && this.expanded) {
|
if (changed.has("expanded") && this.expanded) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -220,9 +204,9 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _areas = memoizeOne(
|
private _areas = memoizeOne(
|
||||||
(areaReg: HomeAssistant["areas"], floors?: FloorRegistryEntry[]) => {
|
(areaReg: HomeAssistant["areas"], floorReg: HomeAssistant["floors"]) => {
|
||||||
const areas = Object.values(areaReg);
|
const areas = Object.values(areaReg);
|
||||||
|
const floors = Object.values(floorReg);
|
||||||
const floorAreaLookup = getFloorAreaLookup(areas);
|
const floorAreaLookup = getFloorAreaLookup(areas);
|
||||||
|
|
||||||
const unassisgnedAreas = areas.filter(
|
const unassisgnedAreas = areas.filter(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
|
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
|
||||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
import { LitElement, PropertyValues, TemplateResult, html } from "lit";
|
import { LitElement, PropertyValues, TemplateResult, html } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
@ -24,10 +24,8 @@ import {
|
|||||||
FloorRegistryEntry,
|
FloorRegistryEntry,
|
||||||
createFloorRegistryEntry,
|
createFloorRegistryEntry,
|
||||||
getFloorAreaLookup,
|
getFloorAreaLookup,
|
||||||
subscribeFloorRegistry,
|
|
||||||
} from "../data/floor_registry";
|
} from "../data/floor_registry";
|
||||||
import { showAlertDialog } from "../dialogs/generic/show-dialog-box";
|
import { showAlertDialog } from "../dialogs/generic/show-dialog-box";
|
||||||
import { SubscribeMixin } from "../mixins/subscribe-mixin";
|
|
||||||
import { showFloorRegistryDetailDialog } from "../panels/config/areas/show-dialog-floor-registry-detail";
|
import { showFloorRegistryDetailDialog } from "../panels/config/areas/show-dialog-floor-registry-detail";
|
||||||
import { HomeAssistant, ValueChangedEvent } from "../types";
|
import { HomeAssistant, ValueChangedEvent } from "../types";
|
||||||
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
|
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
|
||||||
@ -53,7 +51,7 @@ const rowRenderer: ComboBoxLitRenderer<FloorRegistryEntry> = (item) =>
|
|||||||
</ha-list-item>`;
|
</ha-list-item>`;
|
||||||
|
|
||||||
@customElement("ha-floor-picker")
|
@customElement("ha-floor-picker")
|
||||||
export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
export class HaFloorPicker extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public label?: string;
|
@property() public label?: string;
|
||||||
@ -111,8 +109,6 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _opened?: boolean;
|
@state() private _opened?: boolean;
|
||||||
|
|
||||||
@state() private _floors?: FloorRegistryEntry[];
|
|
||||||
|
|
||||||
@query("ha-combo-box", true) public comboBox!: HaComboBox;
|
@query("ha-combo-box", true) public comboBox!: HaComboBox;
|
||||||
|
|
||||||
private _suggestion?: string;
|
private _suggestion?: string;
|
||||||
@ -129,14 +125,6 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
await this.comboBox?.focus();
|
await this.comboBox?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
|
||||||
return [
|
|
||||||
subscribeFloorRegistry(this.hass.connection, (floors) => {
|
|
||||||
this._floors = floors;
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getFloors = memoizeOne(
|
private _getFloors = memoizeOne(
|
||||||
(
|
(
|
||||||
floors: FloorRegistryEntry[],
|
floors: FloorRegistryEntry[],
|
||||||
@ -320,12 +308,12 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
if (
|
if (
|
||||||
(!this._init && this.hass && this._floors) ||
|
(!this._init && this.hass) ||
|
||||||
(this._init && changedProps.has("_opened") && this._opened)
|
(this._init && changedProps.has("_opened") && this._opened)
|
||||||
) {
|
) {
|
||||||
this._init = true;
|
this._init = true;
|
||||||
const floors = this._getFloors(
|
const floors = this._getFloors(
|
||||||
this._floors!,
|
Object.values(this.hass.floors),
|
||||||
Object.values(this.hass.areas),
|
Object.values(this.hass.areas),
|
||||||
Object.values(this.hass.devices),
|
Object.values(this.hass.devices),
|
||||||
Object.values(this.hass.entities),
|
Object.values(this.hass.entities),
|
||||||
@ -360,8 +348,7 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
? this.hass.localize("ui.components.floor-picker.floor")
|
? this.hass.localize("ui.components.floor-picker.floor")
|
||||||
: this.label}
|
: this.label}
|
||||||
.placeholder=${this.placeholder
|
.placeholder=${this.placeholder
|
||||||
? this._floors?.find((floor) => floor.floor_id === this.placeholder)
|
? this.hass.floors[this.placeholder]?.name
|
||||||
?.name
|
|
||||||
: undefined}
|
: undefined}
|
||||||
.renderer=${rowRenderer}
|
.renderer=${rowRenderer}
|
||||||
@filter-changed=${this._filterChanged}
|
@filter-changed=${this._filterChanged}
|
||||||
@ -460,7 +447,7 @@ export class HaFloorPicker extends SubscribeMixin(LitElement) {
|
|||||||
floor_id: floor.floor_id,
|
floor_id: floor.floor_id,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const floors = [...this._floors!, floor];
|
const floors = [...Object.values(this.hass.floors), floor];
|
||||||
this.comboBox.filteredItems = this._getFloors(
|
this.comboBox.filteredItems = this._getFloors(
|
||||||
floors,
|
floors,
|
||||||
Object.values(this.hass.areas)!,
|
Object.values(this.hass.areas)!,
|
||||||
|
@ -35,10 +35,6 @@ import {
|
|||||||
computeDeviceName,
|
computeDeviceName,
|
||||||
} from "../data/device_registry";
|
} from "../data/device_registry";
|
||||||
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
import { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
||||||
import {
|
|
||||||
FloorRegistryEntry,
|
|
||||||
subscribeFloorRegistry,
|
|
||||||
} from "../data/floor_registry";
|
|
||||||
import {
|
import {
|
||||||
LabelRegistryEntry,
|
LabelRegistryEntry,
|
||||||
subscribeLabelRegistry,
|
subscribeLabelRegistry,
|
||||||
@ -103,17 +99,12 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@query(".add-container", true) private _addContainer?: HTMLDivElement;
|
@query(".add-container", true) private _addContainer?: HTMLDivElement;
|
||||||
|
|
||||||
@state() private _floors?: FloorRegistryEntry[];
|
|
||||||
|
|
||||||
@state() private _labels?: LabelRegistryEntry[];
|
@state() private _labels?: LabelRegistryEntry[];
|
||||||
|
|
||||||
private _opened = false;
|
private _opened = false;
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
||||||
return [
|
return [
|
||||||
subscribeFloorRegistry(this.hass.connection, (floors) => {
|
|
||||||
this._floors = floors;
|
|
||||||
}),
|
|
||||||
subscribeLabelRegistry(this.hass.connection, (labels) => {
|
subscribeLabelRegistry(this.hass.connection, (labels) => {
|
||||||
this._labels = labels;
|
this._labels = labels;
|
||||||
}),
|
}),
|
||||||
@ -132,9 +123,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
|||||||
<div class="mdc-chip-set items">
|
<div class="mdc-chip-set items">
|
||||||
${this.value?.floor_id
|
${this.value?.floor_id
|
||||||
? ensureArray(this.value.floor_id).map((floor_id) => {
|
? ensureArray(this.value.floor_id).map((floor_id) => {
|
||||||
const floor = this._floors?.find(
|
const floor = this.hass.floors[floor_id];
|
||||||
(flr) => flr.floor_id === floor_id
|
|
||||||
);
|
|
||||||
return this._renderChip(
|
return this._renderChip(
|
||||||
"floor_id",
|
"floor_id",
|
||||||
floor_id,
|
floor_id,
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import { Connection, createCollection } from "home-assistant-js-websocket";
|
|
||||||
import { Store } from "home-assistant-js-websocket/dist/store";
|
|
||||||
import { stringCompare } from "../common/string/compare";
|
import { stringCompare } from "../common/string/compare";
|
||||||
import { debounce } from "../common/util/debounce";
|
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { AreaRegistryEntry } from "./area_registry";
|
import { AreaRegistryEntry } from "./area_registry";
|
||||||
import { RegistryEntry } from "./registry";
|
import { RegistryEntry } from "./registry";
|
||||||
@ -27,48 +24,6 @@ export interface FloorRegistryEntryMutableParams {
|
|||||||
aliases?: string[];
|
aliases?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchFloorRegistry = (conn: Connection) =>
|
|
||||||
conn
|
|
||||||
.sendMessagePromise({
|
|
||||||
type: "config/floor_registry/list",
|
|
||||||
})
|
|
||||||
.then((floors) =>
|
|
||||||
(floors as FloorRegistryEntry[]).sort((ent1, ent2) => {
|
|
||||||
if (ent1.level !== ent2.level) {
|
|
||||||
return (ent1.level ?? 9999) - (ent2.level ?? 9999);
|
|
||||||
}
|
|
||||||
return stringCompare(ent1.name, ent2.name);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
const subscribeFloorRegistryUpdates = (
|
|
||||||
conn: Connection,
|
|
||||||
store: Store<FloorRegistryEntry[]>
|
|
||||||
) =>
|
|
||||||
conn.subscribeEvents(
|
|
||||||
debounce(
|
|
||||||
() =>
|
|
||||||
fetchFloorRegistry(conn).then((areas: FloorRegistryEntry[]) =>
|
|
||||||
store.setState(areas, true)
|
|
||||||
),
|
|
||||||
500,
|
|
||||||
true
|
|
||||||
),
|
|
||||||
"floor_registry_updated"
|
|
||||||
);
|
|
||||||
|
|
||||||
export const subscribeFloorRegistry = (
|
|
||||||
conn: Connection,
|
|
||||||
onChange: (floors: FloorRegistryEntry[]) => void
|
|
||||||
) =>
|
|
||||||
createCollection<FloorRegistryEntry[]>(
|
|
||||||
"_floorRegistry",
|
|
||||||
fetchFloorRegistry,
|
|
||||||
subscribeFloorRegistryUpdates,
|
|
||||||
conn,
|
|
||||||
onChange
|
|
||||||
);
|
|
||||||
|
|
||||||
export const createFloorRegistryEntry = (
|
export const createFloorRegistryEntry = (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
values: FloorRegistryEntryMutableParams
|
values: FloorRegistryEntryMutableParams
|
||||||
|
47
src/data/ws-floor_registry.ts
Normal file
47
src/data/ws-floor_registry.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { Connection, createCollection } from "home-assistant-js-websocket";
|
||||||
|
import { Store } from "home-assistant-js-websocket/dist/store";
|
||||||
|
import { stringCompare } from "../common/string/compare";
|
||||||
|
import { debounce } from "../common/util/debounce";
|
||||||
|
import { FloorRegistryEntry } from "./floor_registry";
|
||||||
|
|
||||||
|
const fetchFloorRegistry = (conn: Connection) =>
|
||||||
|
conn
|
||||||
|
.sendMessagePromise({
|
||||||
|
type: "config/floor_registry/list",
|
||||||
|
})
|
||||||
|
.then((floors) =>
|
||||||
|
(floors as FloorRegistryEntry[]).sort((ent1, ent2) => {
|
||||||
|
if (ent1.level !== ent2.level) {
|
||||||
|
return (ent1.level ?? 9999) - (ent2.level ?? 9999);
|
||||||
|
}
|
||||||
|
return stringCompare(ent1.name, ent2.name);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const subscribeFloorRegistryUpdates = (
|
||||||
|
conn: Connection,
|
||||||
|
store: Store<FloorRegistryEntry[]>
|
||||||
|
) =>
|
||||||
|
conn.subscribeEvents(
|
||||||
|
debounce(
|
||||||
|
() =>
|
||||||
|
fetchFloorRegistry(conn).then((areas: FloorRegistryEntry[]) =>
|
||||||
|
store.setState(areas, true)
|
||||||
|
),
|
||||||
|
500,
|
||||||
|
true
|
||||||
|
),
|
||||||
|
"floor_registry_updated"
|
||||||
|
);
|
||||||
|
|
||||||
|
export const subscribeFloorRegistry = (
|
||||||
|
conn: Connection,
|
||||||
|
onChange: (floors: FloorRegistryEntry[]) => void
|
||||||
|
) =>
|
||||||
|
createCollection<FloorRegistryEntry[]>(
|
||||||
|
"_floorRegistry",
|
||||||
|
fetchFloorRegistry,
|
||||||
|
subscribeFloorRegistryUpdates,
|
||||||
|
conn,
|
||||||
|
onChange
|
||||||
|
);
|
@ -21,6 +21,7 @@ import { subscribeRepairsIssueRegistry } from "../data/repairs";
|
|||||||
import { subscribeAreaRegistry } from "../data/ws-area_registry";
|
import { subscribeAreaRegistry } from "../data/ws-area_registry";
|
||||||
import { subscribeDeviceRegistry } from "../data/ws-device_registry";
|
import { subscribeDeviceRegistry } from "../data/ws-device_registry";
|
||||||
import { subscribeEntityRegistryDisplay } from "../data/ws-entity_registry_display";
|
import { subscribeEntityRegistryDisplay } from "../data/ws-entity_registry_display";
|
||||||
|
import { subscribeFloorRegistry } from "../data/ws-floor_registry";
|
||||||
import { subscribePanels } from "../data/ws-panels";
|
import { subscribePanels } from "../data/ws-panels";
|
||||||
import { subscribeThemes } from "../data/ws-themes";
|
import { subscribeThemes } from "../data/ws-themes";
|
||||||
import { subscribeUser } from "../data/ws-user";
|
import { subscribeUser } from "../data/ws-user";
|
||||||
@ -117,6 +118,7 @@ window.hassConnection.then(({ conn }) => {
|
|||||||
subscribeEntityRegistryDisplay(conn, noop);
|
subscribeEntityRegistryDisplay(conn, noop);
|
||||||
subscribeDeviceRegistry(conn, noop);
|
subscribeDeviceRegistry(conn, noop);
|
||||||
subscribeAreaRegistry(conn, noop);
|
subscribeAreaRegistry(conn, noop);
|
||||||
|
subscribeFloorRegistry(conn, noop);
|
||||||
subscribeConfig(conn, noop);
|
subscribeConfig(conn, noop);
|
||||||
subscribeServices(conn, noop);
|
subscribeServices(conn, noop);
|
||||||
subscribePanels(conn, noop);
|
subscribePanels(conn, noop);
|
||||||
|
@ -6,7 +6,6 @@ import {
|
|||||||
mdiPencil,
|
mdiPencil,
|
||||||
mdiPlus,
|
mdiPlus,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
@ -15,15 +14,15 @@ import {
|
|||||||
html,
|
html,
|
||||||
nothing,
|
nothing,
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { formatListWithAnds } from "../../../common/string/format-list";
|
import { formatListWithAnds } from "../../../common/string/format-list";
|
||||||
import "../../../components/ha-fab";
|
import "../../../components/ha-fab";
|
||||||
import "../../../components/ha-floor-icon";
|
import "../../../components/ha-floor-icon";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-svg-icon";
|
|
||||||
import "../../../components/ha-sortable";
|
import "../../../components/ha-sortable";
|
||||||
|
import "../../../components/ha-svg-icon";
|
||||||
import {
|
import {
|
||||||
AreaRegistryEntry,
|
AreaRegistryEntry,
|
||||||
createAreaRegistryEntry,
|
createAreaRegistryEntry,
|
||||||
@ -34,7 +33,6 @@ import {
|
|||||||
createFloorRegistryEntry,
|
createFloorRegistryEntry,
|
||||||
deleteFloorRegistryEntry,
|
deleteFloorRegistryEntry,
|
||||||
getFloorAreaLookup,
|
getFloorAreaLookup,
|
||||||
subscribeFloorRegistry,
|
|
||||||
updateFloorRegistryEntry,
|
updateFloorRegistryEntry,
|
||||||
} from "../../../data/floor_registry";
|
} from "../../../data/floor_registry";
|
||||||
import {
|
import {
|
||||||
@ -42,7 +40,6 @@ import {
|
|||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
} from "../../../dialogs/generic/show-dialog-box";
|
} from "../../../dialogs/generic/show-dialog-box";
|
||||||
import "../../../layouts/hass-tabs-subpage";
|
import "../../../layouts/hass-tabs-subpage";
|
||||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
|
||||||
import { HomeAssistant, Route } from "../../../types";
|
import { HomeAssistant, Route } from "../../../types";
|
||||||
import "../ha-config-section";
|
import "../ha-config-section";
|
||||||
import { configSections } from "../ha-panel-config";
|
import { configSections } from "../ha-panel-config";
|
||||||
@ -57,7 +54,7 @@ const UNASSIGNED_PATH = ["__unassigned__"];
|
|||||||
const SORT_OPTIONS = { sort: false, delay: 500, delayOnTouchOnly: true };
|
const SORT_OPTIONS = { sort: false, delay: 500, delayOnTouchOnly: true };
|
||||||
|
|
||||||
@customElement("ha-config-areas-dashboard")
|
@customElement("ha-config-areas-dashboard")
|
||||||
export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
|
export class HaConfigAreasDashboard extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ type: Boolean }) public isWide = false;
|
@property({ type: Boolean }) public isWide = false;
|
||||||
@ -66,14 +63,12 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@property({ attribute: false }) public route!: Route;
|
@property({ attribute: false }) public route!: Route;
|
||||||
|
|
||||||
@state() private _floors?: FloorRegistryEntry[];
|
|
||||||
|
|
||||||
private _processAreas = memoizeOne(
|
private _processAreas = memoizeOne(
|
||||||
(
|
(
|
||||||
areas: HomeAssistant["areas"],
|
areas: HomeAssistant["areas"],
|
||||||
devices: HomeAssistant["devices"],
|
devices: HomeAssistant["devices"],
|
||||||
entities: HomeAssistant["entities"],
|
entities: HomeAssistant["entities"],
|
||||||
floors: FloorRegistryEntry[]
|
floors: HomeAssistant["floors"]
|
||||||
) => {
|
) => {
|
||||||
const processArea = (area: AreaRegistryEntry) => {
|
const processArea = (area: AreaRegistryEntry) => {
|
||||||
let noDevicesInArea = 0;
|
let noDevicesInArea = 0;
|
||||||
@ -109,7 +104,7 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
|
|||||||
(area) => !area.floor_id || !floorAreaLookup[area.floor_id]
|
(area) => !area.floor_id || !floorAreaLookup[area.floor_id]
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
floors: floors.map((floor) => ({
|
floors: Object.values(floors).map((floor) => ({
|
||||||
...floor,
|
...floor,
|
||||||
areas: (floorAreaLookup[floor.floor_id] || []).map(processArea),
|
areas: (floorAreaLookup[floor.floor_id] || []).map(processArea),
|
||||||
})),
|
})),
|
||||||
@ -118,26 +113,18 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
|
|
||||||
return [
|
|
||||||
subscribeFloorRegistry(this.hass.connection, (floors) => {
|
|
||||||
this._floors = floors;
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const areasAndFloors =
|
const areasAndFloors =
|
||||||
!this.hass.areas ||
|
!this.hass.areas ||
|
||||||
!this.hass.devices ||
|
!this.hass.devices ||
|
||||||
!this.hass.entities ||
|
!this.hass.entities ||
|
||||||
!this._floors
|
!this.hass.floors
|
||||||
? undefined
|
? undefined
|
||||||
: this._processAreas(
|
: this._processAreas(
|
||||||
this.hass.areas,
|
this.hass.areas,
|
||||||
this.hass.devices,
|
this.hass.devices,
|
||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
this._floors
|
this.hass.floors
|
||||||
);
|
);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
@ -327,7 +314,7 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
|
|||||||
this.hass.areas,
|
this.hass.areas,
|
||||||
this.hass.devices,
|
this.hass.devices,
|
||||||
this.hass.entities,
|
this.hass.entities,
|
||||||
this._floors!
|
this.hass.floors
|
||||||
);
|
);
|
||||||
let area: AreaRegistryEntry;
|
let area: AreaRegistryEntry;
|
||||||
if (ev.detail.oldPath === UNASSIGNED_PATH) {
|
if (ev.detail.oldPath === UNASSIGNED_PATH) {
|
||||||
|
@ -35,22 +35,17 @@ import { customElement, property, state } from "lit/decorators";
|
|||||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||||
import { listenMediaQuery } from "../../common/dom/media_query";
|
import { listenMediaQuery } from "../../common/dom/media_query";
|
||||||
import { CloudStatus, fetchCloudStatus } from "../../data/cloud";
|
import { CloudStatus, fetchCloudStatus } from "../../data/cloud";
|
||||||
import {
|
import { fullEntitiesContext, labelsContext } from "../../data/context";
|
||||||
floorsContext,
|
|
||||||
fullEntitiesContext,
|
|
||||||
labelsContext,
|
|
||||||
} from "../../data/context";
|
|
||||||
import {
|
import {
|
||||||
entityRegistryByEntityId,
|
entityRegistryByEntityId,
|
||||||
entityRegistryById,
|
entityRegistryById,
|
||||||
subscribeEntityRegistry,
|
subscribeEntityRegistry,
|
||||||
} from "../../data/entity_registry";
|
} from "../../data/entity_registry";
|
||||||
|
import { subscribeLabelRegistry } from "../../data/label_registry";
|
||||||
import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page";
|
import { HassRouterPage, RouterOptions } from "../../layouts/hass-router-page";
|
||||||
import { PageNavigation } from "../../layouts/hass-tabs-subpage";
|
import { PageNavigation } from "../../layouts/hass-tabs-subpage";
|
||||||
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
|
||||||
import { HomeAssistant, Route } from "../../types";
|
import { HomeAssistant, Route } from "../../types";
|
||||||
import { subscribeLabelRegistry } from "../../data/label_registry";
|
|
||||||
import { subscribeFloorRegistry } from "../../data/floor_registry";
|
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
// for fire event
|
// for fire event
|
||||||
@ -390,11 +385,6 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
|
|||||||
initialValue: [],
|
initialValue: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
private _floorsContext = new ContextProvider(this, {
|
|
||||||
context: floorsContext,
|
|
||||||
initialValue: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
public hassSubscribe(): UnsubscribeFunc[] {
|
public hassSubscribe(): UnsubscribeFunc[] {
|
||||||
return [
|
return [
|
||||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
||||||
@ -403,9 +393,6 @@ class HaPanelConfig extends SubscribeMixin(HassRouterPage) {
|
|||||||
subscribeLabelRegistry(this.hass.connection!, (labels) => {
|
subscribeLabelRegistry(this.hass.connection!, (labels) => {
|
||||||
this._labelsContext.setValue(labels);
|
this._labelsContext.setValue(labels);
|
||||||
}),
|
}),
|
||||||
subscribeFloorRegistry(this.hass.connection!, (floors) => {
|
|
||||||
this._floorsContext.setValue(floors);
|
|
||||||
}),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import { getState } from "../util/ha-pref-storage";
|
|||||||
import hassCallApi from "../util/hass-call-api";
|
import hassCallApi from "../util/hass-call-api";
|
||||||
import { HassBaseEl } from "./hass-base-mixin";
|
import { HassBaseEl } from "./hass-base-mixin";
|
||||||
import { promiseTimeout } from "../common/util/promise-timeout";
|
import { promiseTimeout } from "../common/util/promise-timeout";
|
||||||
|
import { subscribeFloorRegistry } from "../data/ws-floor_registry";
|
||||||
|
|
||||||
export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||||
superClass: T
|
superClass: T
|
||||||
@ -52,6 +53,7 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
entities: null as any,
|
entities: null as any,
|
||||||
devices: null as any,
|
devices: null as any,
|
||||||
areas: null as any,
|
areas: null as any,
|
||||||
|
floors: null as any,
|
||||||
config: null as any,
|
config: null as any,
|
||||||
themes: null as any,
|
themes: null as any,
|
||||||
selectedTheme: null,
|
selectedTheme: null,
|
||||||
@ -266,6 +268,13 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
|||||||
}
|
}
|
||||||
this._updateHass({ areas });
|
this._updateHass({ areas });
|
||||||
});
|
});
|
||||||
|
subscribeFloorRegistry(conn, (floorReg) => {
|
||||||
|
const floors: HomeAssistant["floors"] = {};
|
||||||
|
for (const floor of floorReg) {
|
||||||
|
floors[floor.floor_id] = floor;
|
||||||
|
}
|
||||||
|
this._updateHass({ floors });
|
||||||
|
});
|
||||||
subscribeConfig(conn, (config) => this._updateHass({ config }));
|
subscribeConfig(conn, (config) => this._updateHass({ config }));
|
||||||
subscribeServices(conn, (services) => this._updateHass({ services }));
|
subscribeServices(conn, (services) => this._updateHass({ services }));
|
||||||
subscribePanels(conn, (panels) => this._updateHass({ panels }));
|
subscribePanels(conn, (panels) => this._updateHass({ panels }));
|
||||||
|
@ -12,6 +12,7 @@ import { LocalizeFunc } from "./common/translations/localize";
|
|||||||
import { AreaRegistryEntry } from "./data/area_registry";
|
import { AreaRegistryEntry } from "./data/area_registry";
|
||||||
import { DeviceRegistryEntry } from "./data/device_registry";
|
import { DeviceRegistryEntry } from "./data/device_registry";
|
||||||
import { EntityRegistryDisplayEntry } from "./data/entity_registry";
|
import { EntityRegistryDisplayEntry } from "./data/entity_registry";
|
||||||
|
import { FloorRegistryEntry } from "./data/floor_registry";
|
||||||
import { CoreFrontendUserData } from "./data/frontend";
|
import { CoreFrontendUserData } from "./data/frontend";
|
||||||
import { FrontendLocaleData, getHassTranslations } from "./data/translation";
|
import { FrontendLocaleData, getHassTranslations } from "./data/translation";
|
||||||
import { Themes } from "./data/ws-themes";
|
import { Themes } from "./data/ws-themes";
|
||||||
@ -210,6 +211,7 @@ export interface HomeAssistant {
|
|||||||
entities: { [id: string]: EntityRegistryDisplayEntry };
|
entities: { [id: string]: EntityRegistryDisplayEntry };
|
||||||
devices: { [id: string]: DeviceRegistryEntry };
|
devices: { [id: string]: DeviceRegistryEntry };
|
||||||
areas: { [id: string]: AreaRegistryEntry };
|
areas: { [id: string]: AreaRegistryEntry };
|
||||||
|
floors: { [id: string]: FloorRegistryEntry };
|
||||||
services: HassServices;
|
services: HassServices;
|
||||||
config: HassConfig;
|
config: HassConfig;
|
||||||
themes: Themes;
|
themes: Themes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user