mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-29 12:16:39 +00:00
Hide empty blocks on device page (#3950)
* Hide empty blocks on device page * lint * Rename entities on device rename * check if entity_id is valid * clarify var name * Review comments * Use regex to replace not allowed chars * Align with backend
This commit is contained in:
parent
12d8a04c15
commit
9ad7f0dbac
@ -1,2 +1,12 @@
|
|||||||
const validEntityId = /^(\w+)\.(\w+)$/;
|
const validEntityId = /^(\w+)\.(\w+)$/;
|
||||||
export default (entityId: string) => validEntityId.test(entityId);
|
|
||||||
|
export const isValidEntityId = (entityId: string) =>
|
||||||
|
validEntityId.test(entityId);
|
||||||
|
|
||||||
|
export const createValidEntityId = (input: string) =>
|
||||||
|
input
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\s|\'/g, "_") // replace spaces and quotes with underscore
|
||||||
|
.replace(/\W/g, "") // remove not allowed chars
|
||||||
|
.replace(/_{2,}/g, "_") // replace multiple underscores with 1
|
||||||
|
.replace(/_$/, ""); // remove underscores at the end
|
||||||
|
@ -10,7 +10,7 @@ import "@polymer/paper-icon-button/paper-icon-button-light";
|
|||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import isValidEntityId from "../../common/entity/valid_entity_id";
|
import { isValidEntityId } from "../../common/entity/valid_entity_id";
|
||||||
|
|
||||||
import "./ha-entity-picker";
|
import "./ha-entity-picker";
|
||||||
// Not a duplicate, type import
|
// Not a duplicate, type import
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { customElement } from "lit-element";
|
import { customElement } from "lit-element";
|
||||||
import {
|
import {
|
||||||
DeviceAction,
|
DeviceAction,
|
||||||
fetchDeviceActions,
|
|
||||||
localizeDeviceAutomationAction,
|
localizeDeviceAutomationAction,
|
||||||
} from "../../../../data/device_automation";
|
} from "../../../../data/device_automation";
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ export class HaDeviceActionsCard extends HaDeviceAutomationCard<DeviceAction> {
|
|||||||
protected headerKey = "ui.panel.config.devices.automation.actions.caption";
|
protected headerKey = "ui.panel.config.devices.automation.actions.caption";
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(localizeDeviceAutomationAction, fetchDeviceActions);
|
super(localizeDeviceAutomationAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,34 +11,27 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
> extends LitElement {
|
> extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@property() public deviceId?: string;
|
@property() public deviceId?: string;
|
||||||
|
@property() public automations: T[] = [];
|
||||||
|
|
||||||
protected headerKey = "";
|
protected headerKey = "";
|
||||||
protected type = "";
|
protected type = "";
|
||||||
|
|
||||||
@property() private _automations: T[] = [];
|
|
||||||
|
|
||||||
private _localizeDeviceAutomation: (
|
private _localizeDeviceAutomation: (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
automation: T
|
automation: T
|
||||||
) => string;
|
) => string;
|
||||||
private _fetchDeviceAutomations: (
|
|
||||||
hass: HomeAssistant,
|
|
||||||
deviceId: string
|
|
||||||
) => Promise<T[]>;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
localizeDeviceAutomation: HaDeviceAutomationCard<
|
localizeDeviceAutomation: HaDeviceAutomationCard<
|
||||||
T
|
T
|
||||||
>["_localizeDeviceAutomation"],
|
>["_localizeDeviceAutomation"]
|
||||||
fetchDeviceAutomations: HaDeviceAutomationCard<T>["_fetchDeviceAutomations"]
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._localizeDeviceAutomation = localizeDeviceAutomation;
|
this._localizeDeviceAutomation = localizeDeviceAutomation;
|
||||||
this._fetchDeviceAutomations = fetchDeviceAutomations;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected shouldUpdate(changedProps): boolean {
|
protected shouldUpdate(changedProps): boolean {
|
||||||
if (changedProps.has("deviceId") || changedProps.has("_automations")) {
|
if (changedProps.has("deviceId") || changedProps.has("automations")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const oldHass = changedProps.get("hass");
|
const oldHass = changedProps.get("hass");
|
||||||
@ -48,18 +41,8 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async updated(changedProps): Promise<void> {
|
|
||||||
super.updated(changedProps);
|
|
||||||
|
|
||||||
if (changedProps.has("deviceId")) {
|
|
||||||
this._automations = this.deviceId
|
|
||||||
? await this._fetchDeviceAutomations(this.hass, this.deviceId)
|
|
||||||
: [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this._automations.length === 0) {
|
if (this.automations.length === 0) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
@ -70,7 +53,7 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<ha-chips
|
<ha-chips
|
||||||
@chip-clicked=${this._handleAutomationClicked}
|
@chip-clicked=${this._handleAutomationClicked}
|
||||||
.items=${this._automations.map((automation) =>
|
.items=${this.automations.map((automation) =>
|
||||||
this._localizeDeviceAutomation(this.hass, automation)
|
this._localizeDeviceAutomation(this.hass, automation)
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -81,7 +64,7 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleAutomationClicked(ev: CustomEvent) {
|
private _handleAutomationClicked(ev: CustomEvent) {
|
||||||
const automation = this._automations[ev.detail.index];
|
const automation = this.automations[ev.detail.index];
|
||||||
if (!automation) {
|
if (!automation) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { customElement } from "lit-element";
|
import { customElement } from "lit-element";
|
||||||
import {
|
import {
|
||||||
DeviceCondition,
|
DeviceCondition,
|
||||||
fetchDeviceConditions,
|
|
||||||
localizeDeviceAutomationCondition,
|
localizeDeviceAutomationCondition,
|
||||||
} from "../../../../data/device_automation";
|
} from "../../../../data/device_automation";
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ export class HaDeviceConditionsCard extends HaDeviceAutomationCard<
|
|||||||
protected headerKey = "ui.panel.config.devices.automation.conditions.caption";
|
protected headerKey = "ui.panel.config.devices.automation.conditions.caption";
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(localizeDeviceAutomationCondition, fetchDeviceConditions);
|
super(localizeDeviceAutomationCondition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,9 +10,7 @@ import {
|
|||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
|
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import memoizeOne from "memoize-one";
|
|
||||||
|
|
||||||
import { compare } from "../../../../common/string/compare";
|
|
||||||
import "../../../../components/entity/state-badge";
|
import "../../../../components/entity/state-badge";
|
||||||
|
|
||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
@ -22,40 +20,23 @@ import "@polymer/paper-item/paper-item-body";
|
|||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
import "../../../../components/ha-icon";
|
import "../../../../components/ha-icon";
|
||||||
import "../../../../components/ha-switch";
|
import "../../../../components/ha-switch";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import { EntityRegistryEntry } from "../../../../data/entity_registry";
|
|
||||||
import { showEntityRegistryDetailDialog } from "../../entity_registry/show-dialog-entity-registry-detail";
|
import { showEntityRegistryDetailDialog } from "../../entity_registry/show-dialog-entity-registry-detail";
|
||||||
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 { domainIcon } from "../../../../common/entity/domain_icon";
|
import { domainIcon } from "../../../../common/entity/domain_icon";
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
import { HaSwitch } from "../../../../components/ha-switch";
|
import { HaSwitch } from "../../../../components/ha-switch";
|
||||||
|
import { EntityRegistryStateEntry } from "../ha-config-device-page";
|
||||||
|
|
||||||
@customElement("ha-device-entities-card")
|
@customElement("ha-device-entities-card")
|
||||||
export class HaDeviceEntitiesCard extends LitElement {
|
export class HaDeviceEntitiesCard extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@property() public deviceId!: string;
|
@property() public deviceId!: string;
|
||||||
@property() public entities!: EntityRegistryEntry[];
|
@property() public entities!: EntityRegistryStateEntry[];
|
||||||
@property() public narrow!: boolean;
|
@property() public narrow!: boolean;
|
||||||
@property() private _showDisabled = false;
|
@property() private _showDisabled = false;
|
||||||
|
|
||||||
private _entities = memoizeOne(
|
|
||||||
(
|
|
||||||
deviceId: string,
|
|
||||||
entities: EntityRegistryEntry[]
|
|
||||||
): EntityRegistryEntry[] =>
|
|
||||||
entities
|
|
||||||
.filter((entity) => entity.device_id === deviceId)
|
|
||||||
.sort((ent1, ent2) =>
|
|
||||||
compare(
|
|
||||||
this._computeEntityName(ent1) || `zzz${ent1.entity_id}`,
|
|
||||||
this._computeEntityName(ent2) || `zzz${ent2.entity_id}`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const entities = this._entities(this.deviceId, this.entities);
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<paper-item>
|
<paper-item>
|
||||||
@ -67,8 +48,8 @@ export class HaDeviceEntitiesCard extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</ha-switch>
|
</ha-switch>
|
||||||
</paper-item>
|
</paper-item>
|
||||||
${entities.length
|
${this.entities.length
|
||||||
? entities.map((entry: EntityRegistryEntry) => {
|
? this.entities.map((entry: EntityRegistryStateEntry) => {
|
||||||
if (!this._showDisabled && entry.disabled_by) {
|
if (!this._showDisabled && entry.disabled_by) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -92,7 +73,7 @@ export class HaDeviceEntitiesCard extends LitElement {
|
|||||||
></ha-icon>
|
></ha-icon>
|
||||||
`}
|
`}
|
||||||
<paper-item-body two-line>
|
<paper-item-body two-line>
|
||||||
<div class="name">${this._computeEntityName(entry)}</div>
|
<div class="name">${entry.stateName}</div>
|
||||||
<div class="secondary entity-id">${entry.entity_id}</div>
|
<div class="secondary entity-id">${entry.entity_id}</div>
|
||||||
</paper-item-body>
|
</paper-item-body>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
@ -143,14 +124,6 @@ export class HaDeviceEntitiesCard extends LitElement {
|
|||||||
fireEvent(this, "hass-more-info", { entityId: entry.entity_id });
|
fireEvent(this, "hass-more-info", { entityId: entry.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeEntityName(entity) {
|
|
||||||
if (entity.name) {
|
|
||||||
return entity.name;
|
|
||||||
}
|
|
||||||
const state = this.hass.states[entity.entity_id];
|
|
||||||
return state ? computeStateName(state) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
ha-icon {
|
ha-icon {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { customElement } from "lit-element";
|
import { customElement } from "lit-element";
|
||||||
import {
|
import {
|
||||||
DeviceTrigger,
|
DeviceTrigger,
|
||||||
fetchDeviceTriggers,
|
|
||||||
localizeDeviceAutomationTrigger,
|
localizeDeviceAutomationTrigger,
|
||||||
} from "../../../../data/device_automation";
|
} from "../../../../data/device_automation";
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ export class HaDeviceTriggersCard extends HaDeviceAutomationCard<
|
|||||||
protected headerKey = "ui.panel.config.devices.automation.triggers.caption";
|
protected headerKey = "ui.panel.config.devices.automation.triggers.caption";
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super(localizeDeviceAutomationTrigger, fetchDeviceTriggers);
|
super(localizeDeviceAutomationTrigger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,10 @@ import "./device-detail/ha-device-actions-card";
|
|||||||
import "./device-detail/ha-device-entities-card";
|
import "./device-detail/ha-device-entities-card";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { ConfigEntry } from "../../../data/config_entries";
|
import { ConfigEntry } from "../../../data/config_entries";
|
||||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
import {
|
||||||
|
EntityRegistryEntry,
|
||||||
|
updateEntityRegistryEntry,
|
||||||
|
} from "../../../data/entity_registry";
|
||||||
import {
|
import {
|
||||||
DeviceRegistryEntry,
|
DeviceRegistryEntry,
|
||||||
updateDeviceRegistryEntry,
|
updateDeviceRegistryEntry,
|
||||||
@ -30,6 +33,22 @@ import {
|
|||||||
showDeviceRegistryDetailDialog,
|
showDeviceRegistryDetailDialog,
|
||||||
} from "../../../dialogs/device-registry-detail/show-dialog-device-registry-detail";
|
} from "../../../dialogs/device-registry-detail/show-dialog-device-registry-detail";
|
||||||
|
|
||||||
|
import {
|
||||||
|
DeviceTrigger,
|
||||||
|
DeviceAction,
|
||||||
|
DeviceCondition,
|
||||||
|
fetchDeviceTriggers,
|
||||||
|
fetchDeviceConditions,
|
||||||
|
fetchDeviceActions,
|
||||||
|
} from "../../../data/device_automation";
|
||||||
|
import { compare } from "../../../common/string/compare";
|
||||||
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
|
import { createValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
|
|
||||||
|
export interface EntityRegistryStateEntry extends EntityRegistryEntry {
|
||||||
|
stateName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("ha-config-device-page")
|
@customElement("ha-config-device-page")
|
||||||
export class HaConfigDevicePage extends LitElement {
|
export class HaConfigDevicePage extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@ -39,6 +58,10 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
@property() public areas!: AreaRegistryEntry[];
|
@property() public areas!: AreaRegistryEntry[];
|
||||||
@property() public deviceId!: string;
|
@property() public deviceId!: string;
|
||||||
@property() public narrow!: boolean;
|
@property() public narrow!: boolean;
|
||||||
|
@property() public showAdvanced!: boolean;
|
||||||
|
@property() private _triggers: DeviceTrigger[] = [];
|
||||||
|
@property() private _conditions: DeviceCondition[] = [];
|
||||||
|
@property() private _actions: DeviceAction[] = [];
|
||||||
|
|
||||||
private _device = memoizeOne(
|
private _device = memoizeOne(
|
||||||
(
|
(
|
||||||
@ -48,11 +71,51 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
devices ? devices.find((device) => device.id === deviceId) : undefined
|
devices ? devices.find((device) => device.id === deviceId) : undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private _entities = memoizeOne(
|
||||||
|
(
|
||||||
|
deviceId: string,
|
||||||
|
entities: EntityRegistryEntry[]
|
||||||
|
): EntityRegistryStateEntry[] =>
|
||||||
|
entities
|
||||||
|
.filter((entity) => entity.device_id === deviceId)
|
||||||
|
.map((entity) => {
|
||||||
|
return { ...entity, stateName: this._computeEntityName(entity) };
|
||||||
|
})
|
||||||
|
.sort((ent1, ent2) =>
|
||||||
|
compare(
|
||||||
|
ent1.stateName || `zzz${ent1.entity_id}`,
|
||||||
|
ent2.stateName || `zzz${ent2.entity_id}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
loadDeviceRegistryDetailDialog();
|
loadDeviceRegistryDetailDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps): void {
|
||||||
|
super.updated(changedProps);
|
||||||
|
|
||||||
|
if (changedProps.has("deviceId")) {
|
||||||
|
if (this.deviceId) {
|
||||||
|
fetchDeviceTriggers(this.hass, this.deviceId).then(
|
||||||
|
(triggers) => (this._triggers = triggers)
|
||||||
|
);
|
||||||
|
fetchDeviceConditions(this.hass, this.deviceId).then(
|
||||||
|
(conditions) => (this._conditions = conditions)
|
||||||
|
);
|
||||||
|
fetchDeviceActions(this.hass, this.deviceId).then(
|
||||||
|
(actions) => (this._actions = actions)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this._triggers = [];
|
||||||
|
this._conditions = [];
|
||||||
|
this._actions = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const device = this._device(this.deviceId, this.devices);
|
const device = this._device(this.deviceId, this.devices);
|
||||||
|
|
||||||
@ -62,6 +125,8 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const entities = this._entities(this.deviceId, this.entities);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-subpage .header=${device.name_by_user || device.name}>
|
<hass-subpage .header=${device.name_by_user || device.name}>
|
||||||
<paper-icon-button
|
<paper-icon-button
|
||||||
@ -84,37 +149,114 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
hide-entities
|
hide-entities
|
||||||
></ha-device-card>
|
></ha-device-card>
|
||||||
|
|
||||||
|
${entities.length
|
||||||
|
? html`
|
||||||
<div class="header">Entities</div>
|
<div class="header">Entities</div>
|
||||||
<ha-device-entities-card
|
<ha-device-entities-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.deviceId=${this.deviceId}
|
.entities=${entities}
|
||||||
.entities=${this.entities}
|
|
||||||
>
|
>
|
||||||
</ha-device-entities-card>
|
</ha-device-entities-card>
|
||||||
|
`
|
||||||
|
: html``}
|
||||||
|
${this._triggers.length ||
|
||||||
|
this._conditions.length ||
|
||||||
|
this._actions.length
|
||||||
|
? html`
|
||||||
<div class="header">Automations</div>
|
<div class="header">Automations</div>
|
||||||
|
${this._triggers.length
|
||||||
|
? html`
|
||||||
<ha-device-triggers-card
|
<ha-device-triggers-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.deviceId=${this.deviceId}
|
.automations=${this._triggers}
|
||||||
></ha-device-triggers-card>
|
></ha-device-triggers-card>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this._conditions.length
|
||||||
|
? html`
|
||||||
<ha-device-conditions-card
|
<ha-device-conditions-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.deviceId=${this.deviceId}
|
.automations=${this._conditions}
|
||||||
></ha-device-conditions-card>
|
></ha-device-conditions-card>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${this._actions.length
|
||||||
|
? html`
|
||||||
<ha-device-actions-card
|
<ha-device-actions-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.deviceId=${this.deviceId}
|
.automations=${this._actions}
|
||||||
></ha-device-actions-card>
|
></ha-device-actions-card>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
`
|
||||||
|
: html``}
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
</hass-subpage>
|
</hass-subpage>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _showSettings() {
|
private _computeEntityName(entity) {
|
||||||
|
if (entity.name) {
|
||||||
|
return entity.name;
|
||||||
|
}
|
||||||
|
const state = this.hass.states[entity.entity_id];
|
||||||
|
return state ? computeStateName(state) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _showSettings() {
|
||||||
|
const device = this._device(this.deviceId, this.devices)!;
|
||||||
showDeviceRegistryDetailDialog(this, {
|
showDeviceRegistryDetailDialog(this, {
|
||||||
device: this._device(this.deviceId, this.devices)!,
|
device,
|
||||||
updateEntry: async (updates) => {
|
updateEntry: async (updates) => {
|
||||||
|
const oldDeviceName = device.name_by_user || device.name;
|
||||||
|
const newDeviceName = updates.name_by_user;
|
||||||
await updateDeviceRegistryEntry(this.hass, this.deviceId, updates);
|
await updateDeviceRegistryEntry(this.hass, this.deviceId, updates);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!oldDeviceName ||
|
||||||
|
!newDeviceName ||
|
||||||
|
oldDeviceName === newDeviceName
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const entities = this._entities(this.deviceId, this.entities);
|
||||||
|
|
||||||
|
const renameEntityid =
|
||||||
|
this.showAdvanced &&
|
||||||
|
confirm(
|
||||||
|
"Do you also want to rename the entity id's of your entities?"
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateProms = entities.map((entity) => {
|
||||||
|
const name = entity.name || entity.stateName;
|
||||||
|
let newEntityId: string | null = null;
|
||||||
|
let newName: string | null = null;
|
||||||
|
|
||||||
|
if (name && name.includes(oldDeviceName)) {
|
||||||
|
newName = name.replace(oldDeviceName, newDeviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (renameEntityid) {
|
||||||
|
const oldSearch = createValidEntityId(oldDeviceName);
|
||||||
|
if (entity.entity_id.includes(oldSearch)) {
|
||||||
|
newEntityId = entity.entity_id.replace(
|
||||||
|
oldSearch,
|
||||||
|
createValidEntityId(newDeviceName)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newName && !newEntityId) {
|
||||||
|
return new Promise((resolve) => resolve());
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateEntityRegistryEntry(this.hass!, entity.entity_id, {
|
||||||
|
name: newName || name,
|
||||||
|
disabled_by: entity.disabled_by,
|
||||||
|
new_entity_id: newEntityId || entity.entity_id,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
await Promise.all(updateProms);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|||||||
class HaConfigDevices extends HassRouterPage {
|
class HaConfigDevices extends HassRouterPage {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@property() public narrow!: boolean;
|
@property() public narrow!: boolean;
|
||||||
|
@property() public showAdvanced!: boolean;
|
||||||
|
|
||||||
protected routerOptions: RouterOptions = {
|
protected routerOptions: RouterOptions = {
|
||||||
defaultPage: "dashboard",
|
defaultPage: "dashboard",
|
||||||
@ -96,6 +97,7 @@ class HaConfigDevices extends HassRouterPage {
|
|||||||
pageEl.devices = this._deviceRegistryEntries;
|
pageEl.devices = this._deviceRegistryEntries;
|
||||||
pageEl.areas = this._areas;
|
pageEl.areas = this._areas;
|
||||||
pageEl.narrow = this.narrow;
|
pageEl.narrow = this.narrow;
|
||||||
|
pageEl.showAdvanced = this.showAdvanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _loadData() {
|
private _loadData() {
|
||||||
|
@ -15,7 +15,7 @@ import "@material/mwc-ripple";
|
|||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
|
|
||||||
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
import { stateIcon } from "../../../common/entity/state_icon";
|
import { stateIcon } from "../../../common/entity/state_icon";
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
|
@ -13,7 +13,7 @@ import { styleMap } from "lit-html/directives/style-map";
|
|||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
|
|
||||||
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
import applyThemesOnElement from "../../../common/dom/apply_themes_on_element";
|
import applyThemesOnElement from "../../../common/dom/apply_themes_on_element";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
|
|
||||||
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
|
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Parse array of entity objects from config
|
// Parse array of entity objects from config
|
||||||
import isValidEntityId from "../../../common/entity/valid_entity_id";
|
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||||
import { EntityConfig } from "../entity-rows/types";
|
import { EntityConfig } from "../entity-rows/types";
|
||||||
|
|
||||||
export const processConfigEntities = <T extends EntityConfig>(
|
export const processConfigEntities = <T extends EntityConfig>(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user