Add default icons for area and floors (#20214)

* Add default icons for area and floors

* Add default icon for floor based on level

* Allow deleting floor level

* Use texture box for area

---------

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
Bram Kragten 2024-03-28 16:35:56 +01:00 committed by GitHub
parent 6b8f4e92a7
commit d3e62454a5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 146 additions and 61 deletions

View File

@ -1,12 +1,12 @@
import { mdiSofa } from "@mdi/js"; import { mdiTextureBox } from "@mdi/js";
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit"; import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators"; import { customElement, property } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { showAreaFilterDialog } from "../dialogs/area-filter/show-area-filter-dialog"; import { showAreaFilterDialog } from "../dialogs/area-filter/show-area-filter-dialog";
import { HomeAssistant } from "../types"; import { HomeAssistant } from "../types";
import "./ha-icon-next";
import "./ha-svg-icon"; import "./ha-svg-icon";
import "./ha-textfield"; import "./ha-textfield";
import "./ha-icon-next";
export type AreaFilterValue = { export type AreaFilterValue = {
hidden?: string[]; hidden?: string[];
@ -51,7 +51,7 @@ export class HaAreaPicker extends LitElement {
@keydown=${this._edit} @keydown=${this._edit}
.disabled=${this.disabled} .disabled=${this.disabled}
> >
<ha-svg-icon slot="graphic" .path=${mdiSofa}></ha-svg-icon> <ha-svg-icon slot="graphic" .path=${mdiTextureBox}></ha-svg-icon>
<span>${this.label}</span> <span>${this.label}</span>
<span slot="secondary">${description}</span> <span slot="secondary">${description}</span>
<ha-icon-next <ha-icon-next

View File

@ -1,10 +1,12 @@
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, UnsubscribeFunc } from "home-assistant-js-websocket";
import { LitElement, PropertyValues, TemplateResult, html, nothing } 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 memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { computeDomain } from "../common/entity/compute_domain"; import { computeDomain } from "../common/entity/compute_domain";
import { stringCompare } from "../common/string/compare";
import { import {
ScorableTextItem, ScorableTextItem,
fuzzyFilterSort, fuzzyFilterSort,
@ -26,10 +28,10 @@ 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";
import type { HaComboBox } from "./ha-combo-box"; import type { HaComboBox } from "./ha-combo-box";
import "./ha-floor-icon";
import "./ha-icon-button"; import "./ha-icon-button";
import "./ha-list-item"; import "./ha-list-item";
import "./ha-svg-icon"; import "./ha-svg-icon";
import { stringCompare } from "../common/string/compare";
type ScorableAreaFloorEntry = ScorableTextItem & FloorAreaEntry; type ScorableAreaFloorEntry = ScorableTextItem & FloorAreaEntry;
@ -40,6 +42,7 @@ interface FloorAreaEntry {
strings: string[]; strings: string[];
type: "floor" | "area"; type: "floor" | "area";
hasFloor?: boolean; hasFloor?: boolean;
level: number | null;
} }
const rowRenderer: ComboBoxLitRenderer<FloorAreaEntry> = (item) => const rowRenderer: ComboBoxLitRenderer<FloorAreaEntry> = (item) =>
@ -49,9 +52,14 @@ const rowRenderer: ComboBoxLitRenderer<FloorAreaEntry> = (item) =>
? "--mdc-list-side-padding-left: 48px;" ? "--mdc-list-side-padding-left: 48px;"
: ""} : ""}
> >
${item.icon ${item.type === "floor"
? html`<ha-icon slot="graphic" .icon=${item.icon}></ha-icon>` ? html`<ha-floor-icon slot="graphic" .floor=${item}></ha-floor-icon>`
: nothing} : item.icon
? html`<ha-icon slot="graphic" .icon=${item.icon}></ha-icon>`
: html`<ha-svg-icon
slot="graphic"
.path=${mdiTextureBox}
></ha-svg-icon>`}
${item.name} ${item.name}
</ha-list-item>`; </ha-list-item>`;
@ -165,6 +173,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: this.hass.localize("ui.components.area-picker.no_areas"), name: this.hass.localize("ui.components.area-picker.no_areas"),
icon: null, icon: null,
strings: [], strings: [],
level: null,
}, },
]; ];
} }
@ -316,6 +325,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: this.hass.localize("ui.components.area-picker.no_match"), name: this.hass.localize("ui.components.area-picker.no_match"),
icon: null, icon: null,
strings: [], strings: [],
level: null,
}, },
]; ];
} }
@ -350,6 +360,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: floor.name, name: floor.name,
icon: floor.icon, icon: floor.icon,
strings: [floor.floor_id, ...floor.aliases, floor.name], strings: [floor.floor_id, ...floor.aliases, floor.name],
level: floor.level,
}); });
} }
output.push( output.push(
@ -360,6 +371,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
icon: area.icon, icon: area.icon,
strings: [area.area_id, ...area.aliases, area.name], strings: [area.area_id, ...area.aliases, area.name],
hasFloor: true, hasFloor: true,
level: null,
})) }))
); );
}); });
@ -373,6 +385,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
), ),
icon: null, icon: null,
strings: [], strings: [],
level: null,
}); });
} }
@ -383,6 +396,7 @@ export class HaAreaFloorPicker extends SubscribeMixin(LitElement) {
name: area.name, name: area.name,
icon: area.icon, icon: area.icon,
strings: [area.area_id, ...area.aliases, area.name], strings: [area.area_id, ...area.aliases, area.name],
level: null,
})) }))
); );

View File

@ -1,14 +1,15 @@
import { mdiTextureBox } from "@mdi/js";
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { HassEntity } from "home-assistant-js-websocket"; import { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, nothing, PropertyValues, TemplateResult } 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";
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 { computeDomain } from "../common/entity/compute_domain"; import { computeDomain } from "../common/entity/compute_domain";
import { import {
fuzzyFilterSort,
ScorableTextItem, ScorableTextItem,
fuzzyFilterSort,
} from "../common/string/filter/sequence-matching"; } from "../common/string/filter/sequence-matching";
import { import {
AreaRegistryEntry, AreaRegistryEntry,
@ -41,7 +42,7 @@ const rowRenderer: ComboBoxLitRenderer<AreaRegistryEntry> = (item) =>
> >
${item.icon ${item.icon
? html`<ha-icon slot="graphic" .icon=${item.icon}></ha-icon>` ? html`<ha-icon slot="graphic" .icon=${item.icon}></ha-icon>`
: nothing} : html`<ha-svg-icon slot="graphic" .path=${mdiTextureBox}></ha-svg-icon>`}
${item.name} ${item.name}
</ha-list-item>`; </ha-list-item>`;

View File

@ -1,4 +1,5 @@
import "@material/mwc-menu/mwc-menu-surface"; import "@material/mwc-menu/mwc-menu-surface";
import { mdiTextureBox } from "@mdi/js";
import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
@ -15,6 +16,9 @@ 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";
import "./ha-floor-icon";
import "./ha-icon";
import "./ha-svg-icon";
@customElement("ha-filter-floor-areas") @customElement("ha-filter-floor-areas")
export class HaFilterFloorAreas extends SubscribeMixin(LitElement) { export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
@ -70,12 +74,10 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
graphic="icon" graphic="icon"
@request-selected=${this._handleItemClick} @request-selected=${this._handleItemClick}
> >
${floor.icon <ha-floor-icon
? html`<ha-icon slot="graphic"
slot="graphic" .floor=${floor}
.icon=${floor.icon} ></ha-floor-icon>
></ha-icon>`
: nothing}
${floor.name} ${floor.name}
</ha-check-list-item> </ha-check-list-item>
${repeat( ${repeat(
@ -108,7 +110,10 @@ export class HaFilterFloorAreas extends SubscribeMixin(LitElement) {
> >
${area.icon ${area.icon
? html`<ha-icon slot="graphic" .icon=${area.icon}></ha-icon>` ? html`<ha-icon slot="graphic" .icon=${area.icon}></ha-icon>`
: nothing} : html`<ha-svg-icon
slot="graphic"
.path=${mdiTextureBox}
></ha-svg-icon>`}
${area.name} ${area.name}
</ha-check-list-item>`; </ha-check-list-item>`;
} }

View File

@ -0,0 +1,56 @@
import {
mdiHome,
mdiHomeFloor0,
mdiHomeFloor1,
mdiHomeFloor2,
mdiHomeFloor3,
mdiHomeFloorNegative1,
} from "@mdi/js";
import { LitElement, html } from "lit";
import { customElement, property } from "lit/decorators";
import { FloorRegistryEntry } from "../data/floor_registry";
import "./ha-icon";
import "./ha-svg-icon";
export const floorDefaultIconPath = (
floor: Pick<FloorRegistryEntry, "level">
) => {
switch (floor.level) {
case 0:
return mdiHomeFloor0;
case 1:
return mdiHomeFloor1;
case 2:
return mdiHomeFloor2;
case 3:
return mdiHomeFloor3;
case -1:
return mdiHomeFloorNegative1;
}
return mdiHome;
};
@customElement("ha-floor-icon")
export class HaFloorIcon extends LitElement {
@property({ attribute: false }) public floor!: Pick<
FloorRegistryEntry,
"icon" | "level"
>;
@property() public icon?: string;
protected render() {
if (this.floor.icon) {
return html`<ha-icon .icon=${this.floor.icon}></ha-icon>`;
}
const defaultPath = floorDefaultIconPath(this.floor);
return html`<ha-svg-icon .path=${defaultPath}></ha-svg-icon>`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-floor-icon": HaFloorIcon;
}
}

View File

@ -1,14 +1,14 @@
import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit"; import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
import { html, LitElement, nothing, PropertyValues, TemplateResult } 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";
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 { computeDomain } from "../common/entity/compute_domain"; import { computeDomain } from "../common/entity/compute_domain";
import { import {
fuzzyFilterSort,
ScorableTextItem, ScorableTextItem,
fuzzyFilterSort,
} from "../common/string/filter/sequence-matching"; } from "../common/string/filter/sequence-matching";
import { AreaRegistryEntry } from "../data/area_registry"; import { AreaRegistryEntry } from "../data/area_registry";
import { import {
@ -17,24 +17,24 @@ import {
getDeviceEntityDisplayLookup, getDeviceEntityDisplayLookup,
} from "../data/device_registry"; } from "../data/device_registry";
import { EntityRegistryDisplayEntry } from "../data/entity_registry"; import { EntityRegistryDisplayEntry } from "../data/entity_registry";
import {
FloorRegistryEntry,
createFloorRegistryEntry,
getFloorAreaLookup,
subscribeFloorRegistry,
} from "../data/floor_registry";
import { import {
showAlertDialog, showAlertDialog,
showPromptDialog, showPromptDialog,
} from "../dialogs/generic/show-dialog-box"; } from "../dialogs/generic/show-dialog-box";
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";
import type { HaComboBox } from "./ha-combo-box"; import type { HaComboBox } from "./ha-combo-box";
import "./ha-floor-icon";
import "./ha-icon-button"; import "./ha-icon-button";
import "./ha-list-item"; import "./ha-list-item";
import "./ha-svg-icon";
import { SubscribeMixin } from "../mixins/subscribe-mixin";
import {
createFloorRegistryEntry,
FloorRegistryEntry,
getFloorAreaLookup,
subscribeFloorRegistry,
} from "../data/floor_registry";
type ScorableFloorRegistryEntry = ScorableTextItem & FloorRegistryEntry; type ScorableFloorRegistryEntry = ScorableTextItem & FloorRegistryEntry;
@ -43,9 +43,7 @@ const rowRenderer: ComboBoxLitRenderer<FloorRegistryEntry> = (item) =>
graphic="icon" graphic="icon"
class=${classMap({ "add-new": item.floor_id === "add_new" })} class=${classMap({ "add-new": item.floor_id === "add_new" })}
> >
${item.icon <ha-floor-icon slot="graphic" .floor=${item}></ha-floor-icon>
? html`<ha-icon slot="graphic" .icon=${item.icon}></ha-icon>`
: nothing}
${item.name} ${item.name}
</ha-list-item>`; </ha-list-item>`;

View File

@ -118,7 +118,7 @@ export class HaIconPicker extends LitElement {
<ha-icon .icon=${this._value || this.placeholder} slot="icon"> <ha-icon .icon=${this._value || this.placeholder} slot="icon">
</ha-icon> </ha-icon>
` `
: html`<slot name="fallback"></slot>`} : html`<slot slot="icon" name="fallback"></slot>`}
</ha-combo-box> </ha-combo-box>
`; `;
} }

View File

@ -6,10 +6,10 @@ import "@material/mwc-menu/mwc-menu-surface";
import { import {
mdiClose, mdiClose,
mdiDevices, mdiDevices,
mdiFloorPlan, mdiHome,
mdiLabel, mdiLabel,
mdiPlus, mdiPlus,
mdiSofa, mdiTextureBox,
mdiUnfoldMoreVertical, mdiUnfoldMoreVertical,
} from "@mdi/js"; } from "@mdi/js";
import { ComboBoxLightOpenedChangedEvent } from "@vaadin/combo-box/vaadin-combo-box-light"; import { ComboBoxLightOpenedChangedEvent } from "@vaadin/combo-box/vaadin-combo-box-light";
@ -18,30 +18,23 @@ import {
HassServiceTarget, HassServiceTarget,
UnsubscribeFunc, UnsubscribeFunc,
} from "home-assistant-js-websocket"; } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing, unsafeCSS } from "lit"; import { CSSResultGroup, LitElement, css, html, nothing, unsafeCSS } 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";
import { ensureArray } from "../common/array/ensure-array"; import { ensureArray } from "../common/array/ensure-array";
import { computeCssColor } from "../common/color/compute-color";
import { hex2rgb } from "../common/color/convert-color";
import { fireEvent } from "../common/dom/fire_event"; import { fireEvent } from "../common/dom/fire_event";
import { stopPropagation } from "../common/dom/stop_propagation"; import { stopPropagation } from "../common/dom/stop_propagation";
import { computeDomain } from "../common/entity/compute_domain"; import { computeDomain } from "../common/entity/compute_domain";
import { computeStateName } from "../common/entity/compute_state_name"; import { computeStateName } from "../common/entity/compute_state_name";
import { isValidEntityId } from "../common/entity/valid_entity_id"; import { isValidEntityId } from "../common/entity/valid_entity_id";
import { AreaRegistryEntry } from "../data/area_registry";
import { import {
computeDeviceName,
DeviceRegistryEntry, DeviceRegistryEntry,
computeDeviceName,
} from "../data/device_registry"; } from "../data/device_registry";
import { EntityRegistryDisplayEntry } from "../data/entity_registry"; import { EntityRegistryDisplayEntry } from "../data/entity_registry";
import { HomeAssistant } from "../types";
import "./device/ha-device-picker";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./entity/ha-entity-picker";
import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
import "./ha-area-floor-picker";
import "./ha-icon-button";
import "./ha-input-helper-text";
import "./ha-svg-icon";
import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { import {
FloorRegistryEntry, FloorRegistryEntry,
subscribeFloorRegistry, subscribeFloorRegistry,
@ -50,9 +43,17 @@ import {
LabelRegistryEntry, LabelRegistryEntry,
subscribeLabelRegistry, subscribeLabelRegistry,
} from "../data/label_registry"; } from "../data/label_registry";
import { computeCssColor } from "../common/color/compute-color"; import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { AreaRegistryEntry } from "../data/area_registry"; import { HomeAssistant } from "../types";
import { hex2rgb } from "../common/color/convert-color"; import "./device/ha-device-picker";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./entity/ha-entity-picker";
import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
import "./ha-area-floor-picker";
import { floorDefaultIconPath } from "./ha-floor-icon";
import "./ha-icon-button";
import "./ha-input-helper-text";
import "./ha-svg-icon";
@customElement("ha-target-picker") @customElement("ha-target-picker")
export class HaTargetPicker extends SubscribeMixin(LitElement) { export class HaTargetPicker extends SubscribeMixin(LitElement) {
@ -138,7 +139,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
floor?.name || floor_id, floor?.name || floor_id,
undefined, undefined,
floor?.icon, floor?.icon,
mdiFloorPlan floor ? floorDefaultIconPath(floor) : mdiHome
); );
}) })
: ""} : ""}
@ -151,7 +152,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
area?.name || area_id, area?.name || area_id,
undefined, undefined,
area?.icon, area?.icon,
mdiSofa mdiTextureBox
); );
}) })
: nothing} : nothing}

View File

@ -1,16 +1,16 @@
import { Connection, createCollection } from "home-assistant-js-websocket"; import { Connection, createCollection } from "home-assistant-js-websocket";
import { Store } from "home-assistant-js-websocket/dist/store"; 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 { debounce } from "../common/util/debounce";
export { subscribeAreaRegistry } from "./ws-area_registry"; export { subscribeAreaRegistry } from "./ws-area_registry";
export interface FloorRegistryEntry { export interface FloorRegistryEntry {
floor_id: string; floor_id: string;
name: string; name: string;
level: number; level: number | null;
icon: string | null; icon: string | null;
aliases: string[]; aliases: string[];
} }

View File

@ -6,10 +6,11 @@ import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-alert"; import "../../../components/ha-alert";
import "../../../components/ha-aliases-editor"; import "../../../components/ha-aliases-editor";
import { createCloseHeading } from "../../../components/ha-dialog"; import { createCloseHeading } from "../../../components/ha-dialog";
import "../../../components/ha-icon-picker";
import "../../../components/ha-picture-upload"; import "../../../components/ha-picture-upload";
import "../../../components/ha-settings-row"; import "../../../components/ha-settings-row";
import "../../../components/ha-svg-icon";
import "../../../components/ha-textfield"; import "../../../components/ha-textfield";
import "../../../components/ha-icon-picker";
import { FloorRegistryEntryMutableParams } from "../../../data/floor_registry"; import { FloorRegistryEntryMutableParams } from "../../../data/floor_registry";
import { haStyleDialog } from "../../../resources/styles"; import { haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
@ -56,6 +57,7 @@ class DialogFloorDetail extends LitElement {
} }
const entry = this._params.entry; const entry = this._params.entry;
const nameInvalid = !this._isNameValid(); const nameInvalid = !this._isNameValid();
return html` return html`
<ha-dialog <ha-dialog
open open
@ -110,7 +112,16 @@ class DialogFloorDetail extends LitElement {
.value=${this._icon} .value=${this._icon}
@value-changed=${this._iconChanged} @value-changed=${this._iconChanged}
.label=${this.hass.localize("ui.panel.config.areas.editor.icon")} .label=${this.hass.localize("ui.panel.config.areas.editor.icon")}
></ha-icon-picker> >
${!this._icon
? html`
<ha-floor-icon
slot="fallback"
.floor=${{ level: this._level }}
></ha-floor-icon>
`
: nothing}
</ha-icon-picker>
<h3 class="header"> <h3 class="header">
${this.hass.localize( ${this.hass.localize(
@ -157,7 +168,7 @@ class DialogFloorDetail extends LitElement {
private _levelChanged(ev) { private _levelChanged(ev) {
this._error = undefined; this._error = undefined;
this._level = Number(ev.target.value); this._level = ev.target.value === "" ? null : Number(ev.target.value);
} }
private _iconChanged(ev) { private _iconChanged(ev) {

View File

@ -1,3 +1,4 @@
import { ActionDetail } from "@material/mwc-list";
import { import {
mdiDelete, mdiDelete,
mdiDotsVertical, mdiDotsVertical,
@ -17,9 +18,9 @@ import {
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } 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 { ActionDetail } from "@material/mwc-list";
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-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-svg-icon"; import "../../../components/ha-svg-icon";
import { import {
@ -39,6 +40,7 @@ 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";
@ -47,7 +49,6 @@ import {
showAreaRegistryDetailDialog, showAreaRegistryDetailDialog,
} from "./show-dialog-area-registry-detail"; } from "./show-dialog-area-registry-detail";
import { showFloorRegistryDetailDialog } from "./show-dialog-floor-registry-detail"; import { showFloorRegistryDetailDialog } from "./show-dialog-floor-registry-detail";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
@customElement("ha-config-areas-dashboard") @customElement("ha-config-areas-dashboard")
export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) { export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
@ -154,9 +155,7 @@ export class HaConfigAreasDashboard extends SubscribeMixin(LitElement) {
html`<div class="floor"> html`<div class="floor">
<div class="header"> <div class="header">
<h2> <h2>
${floor.icon <ha-floor-icon .floor=${floor}></ha-floor-icon>
? html`<ha-icon .icon=${floor.icon}></ha-icon>`
: nothing}
${floor.name} ${floor.name}
</h2> </h2>
<ha-button-menu <ha-button-menu