mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 13:37:47 +00:00
Allow editting entity registry (#2630)
* Allow editting entity registry * Slight simplify * Style fixes * Correctly set submitting * Apply suggestions from code review Co-Authored-By: balloob <paulus@home-assistant.io> * Fix invalid type * Add config section to entity registry * Trim * Fix trimming
This commit is contained in:
parent
e42e59871e
commit
175693ba4e
52
src/data/entity_registry.ts
Normal file
52
src/data/entity_registry.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
import computeStateName from "../common/entity/compute_state_name";
|
||||
|
||||
export interface EntityRegistryEntry {
|
||||
entity_id: string;
|
||||
name: string;
|
||||
platform: string;
|
||||
config_entry_id?: string;
|
||||
device_id?: string;
|
||||
disabled_by?: string;
|
||||
}
|
||||
|
||||
export interface EntityRegistryEntryUpdateParams {
|
||||
name: string | null;
|
||||
new_entity_id: string;
|
||||
}
|
||||
|
||||
export const computeEntityRegistryName = (
|
||||
hass: HomeAssistant,
|
||||
entry: EntityRegistryEntry
|
||||
): string | null => {
|
||||
if (entry.name) {
|
||||
return entry.name;
|
||||
}
|
||||
const state = hass.states[entry.entity_id];
|
||||
return state ? computeStateName(state) : null;
|
||||
};
|
||||
|
||||
export const fetchEntityRegistry = (
|
||||
hass: HomeAssistant
|
||||
): Promise<EntityRegistryEntry[]> =>
|
||||
hass.callWS<EntityRegistryEntry[]>({ type: "config/entity_registry/list" });
|
||||
|
||||
export const updateEntityRegistryEntry = (
|
||||
hass: HomeAssistant,
|
||||
entityId: string,
|
||||
updates: Partial<EntityRegistryEntryUpdateParams>
|
||||
): Promise<EntityRegistryEntry> =>
|
||||
hass.callWS<EntityRegistryEntry>({
|
||||
type: "config/entity_registry/update",
|
||||
entity_id: entityId,
|
||||
...updates,
|
||||
});
|
||||
|
||||
export const removeEntityRegistryEntry = (
|
||||
hass: HomeAssistant,
|
||||
entityId: string
|
||||
): Promise<void> =>
|
||||
hass.callWS({
|
||||
type: "config/entity_registry/remove",
|
||||
entity_id: entityId,
|
||||
});
|
@ -11,6 +11,7 @@ import LocalizeMixin from "../../mixins/localize-mixin";
|
||||
import computeStateName from "../../common/entity/compute_state_name";
|
||||
import computeDomain from "../../common/entity/compute_domain";
|
||||
import isComponentLoaded from "../../common/config/is_component_loaded";
|
||||
import { updateEntityRegistryEntry } from "../../data/entity_registry";
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
@ -122,12 +123,14 @@ class MoreInfoSettings extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
|
||||
async _save() {
|
||||
try {
|
||||
const info = await this.hass.callWS({
|
||||
type: "config/entity_registry/update",
|
||||
entity_id: this.stateObj.entity_id,
|
||||
name: this._name,
|
||||
new_entity_id: this._entityId,
|
||||
});
|
||||
const info = await updateEntityRegistryEntry(
|
||||
this.hass,
|
||||
this.stateObj.entity_id,
|
||||
{
|
||||
name: this._name,
|
||||
new_entity_id: this._entityId,
|
||||
}
|
||||
);
|
||||
|
||||
this.registryInfo = info;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Constructor, LitElement } from "lit-element";
|
||||
import { HASSDomEvent, ValidHassDomEvent } from "../../common/dom/fire_event";
|
||||
import { HassBaseEl } from "./hass-base-mixin";
|
||||
|
||||
interface RegisterDialogParams {
|
||||
dialogShowEvent: keyof HASSDomEvents;
|
||||
@ -7,6 +8,12 @@ interface RegisterDialogParams {
|
||||
dialogImport: () => Promise<unknown>;
|
||||
}
|
||||
|
||||
interface ShowDialogParams<T> {
|
||||
dialogTag: keyof HTMLElementTagNameMap;
|
||||
dialogImport: () => Promise<unknown>;
|
||||
dialogParams: T;
|
||||
}
|
||||
|
||||
interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]> extends HTMLElement {
|
||||
showDialog(params: T);
|
||||
}
|
||||
@ -15,20 +22,34 @@ declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"register-dialog": RegisterDialogParams;
|
||||
"show-dialog": ShowDialogParams<unknown>;
|
||||
}
|
||||
// for add event listener
|
||||
interface HTMLElementEventMap {
|
||||
"register-dialog": HASSDomEvent<RegisterDialogParams>;
|
||||
"show-dialog": HASSDomEvent<ShowDialogParams<unknown>>;
|
||||
}
|
||||
}
|
||||
|
||||
export const dialogManagerMixin = (superClass: Constructor<LitElement>) =>
|
||||
const LOADED = {};
|
||||
|
||||
export const dialogManagerMixin = (
|
||||
superClass: Constructor<LitElement & HassBaseEl>
|
||||
) =>
|
||||
class extends superClass {
|
||||
protected firstUpdated(changedProps) {
|
||||
super.firstUpdated(changedProps);
|
||||
// deprecated
|
||||
this.addEventListener("register-dialog", (e) =>
|
||||
this.registerDialog(e.detail)
|
||||
);
|
||||
this.addEventListener(
|
||||
"show-dialog",
|
||||
async (e: HASSDomEvent<ShowDialogParams<unknown>>) => {
|
||||
const { dialogTag, dialogImport, dialogParams } = e.detail;
|
||||
this._showDialog(dialogImport, dialogTag, dialogParams);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private registerDialog({
|
||||
@ -36,20 +57,29 @@ export const dialogManagerMixin = (superClass: Constructor<LitElement>) =>
|
||||
dialogTag,
|
||||
dialogImport,
|
||||
}: RegisterDialogParams) {
|
||||
let loaded: Promise<HassDialog<unknown>>;
|
||||
|
||||
this.addEventListener(dialogShowEvent, (showEv) => {
|
||||
if (!loaded) {
|
||||
loaded = dialogImport().then(() => {
|
||||
const dialogEl = document.createElement(dialogTag) as HassDialog;
|
||||
this.shadowRoot!.appendChild(dialogEl);
|
||||
(this as any).provideHass(dialogEl);
|
||||
return dialogEl;
|
||||
});
|
||||
}
|
||||
loaded.then((dialogEl) =>
|
||||
dialogEl.showDialog((showEv as HASSDomEvent<unknown>).detail)
|
||||
this._showDialog(
|
||||
dialogImport,
|
||||
dialogTag,
|
||||
(showEv as HASSDomEvent<unknown>).detail
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private async _showDialog(
|
||||
dialogImport: () => Promise<unknown>,
|
||||
dialogTag: string,
|
||||
dialogParams: unknown
|
||||
) {
|
||||
if (!(dialogTag in LOADED)) {
|
||||
LOADED[dialogTag] = dialogImport().then(() => {
|
||||
const dialogEl = document.createElement(dialogTag) as HassDialog;
|
||||
this.shadowRoot!.appendChild(dialogEl);
|
||||
this.provideHass(dialogEl);
|
||||
return dialogEl;
|
||||
});
|
||||
}
|
||||
const element = await LOADED[dialogTag];
|
||||
element.showDialog(dialogParams);
|
||||
}
|
||||
};
|
||||
|
@ -8,14 +8,8 @@ import "../../../layouts/hass-subpage";
|
||||
|
||||
import EventsMixin from "../../../mixins/events-mixin";
|
||||
import LocalizeMixIn from "../../../mixins/localize-mixin";
|
||||
import computeStateName from "../../../common/entity/compute_state_name";
|
||||
import "../../../components/entity/state-badge";
|
||||
|
||||
function computeEntityName(hass, entity) {
|
||||
if (entity.name) return entity.name;
|
||||
const state = hass.states[entity.entity_id];
|
||||
return state ? computeStateName(state) : null;
|
||||
}
|
||||
import { computeEntityRegistryName } from "../../../data/entity_registry";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixIn
|
||||
@ -66,7 +60,7 @@ class HaCeEntitiesCard extends LocalizeMixIn(EventsMixin(PolymerElement)) {
|
||||
|
||||
_computeEntityName(entity, hass) {
|
||||
return (
|
||||
computeEntityName(hass, entity) ||
|
||||
computeEntityRegistryName(hass, entity) ||
|
||||
`(${this.localize(
|
||||
"ui.panel.config.integrations.config_entry.entity_unavailable"
|
||||
)})`
|
||||
|
@ -10,7 +10,7 @@ import LocalizeMixin from "../../../mixins/localize-mixin";
|
||||
|
||||
import isComponentLoaded from "../../../common/config/is_component_loaded";
|
||||
|
||||
const CORE_PAGES = ["core", "customize"];
|
||||
const CORE_PAGES = ["core", "customize", "entity_registry"];
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
* @appliesMixin NavigateMixin
|
||||
@ -50,7 +50,15 @@ class HaConfigNavigation extends LocalizeMixin(NavigateMixin(PolymerElement)) {
|
||||
|
||||
pages: {
|
||||
type: Array,
|
||||
value: ["core", "customize", "automation", "script", "zha", "zwave"],
|
||||
value: [
|
||||
"core",
|
||||
"customize",
|
||||
"entity_registry",
|
||||
"automation",
|
||||
"script",
|
||||
"zha",
|
||||
"zwave",
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -0,0 +1,191 @@
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
css,
|
||||
PropertyDeclarations,
|
||||
CSSResult,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-dialog/paper-dialog";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
|
||||
import { EntityRegistryDetailDialogParams } from "./show-dialog-entity-registry-detail";
|
||||
import { PolymerChangedEvent } from "../../../polymer-types";
|
||||
import { haStyleDialog } from "../../../resources/ha-style";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import computeDomain from "../../../common/entity/compute_domain";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import computeStateName from "../../../common/entity/compute_state_name";
|
||||
|
||||
class DialogEntityRegistryDetail extends LitElement {
|
||||
public hass!: HomeAssistant;
|
||||
private _name!: string;
|
||||
private _entityId!: string;
|
||||
private _error?: string;
|
||||
private _params?: EntityRegistryDetailDialogParams;
|
||||
private _submitting?: boolean;
|
||||
|
||||
static get properties(): PropertyDeclarations {
|
||||
return {
|
||||
_error: {},
|
||||
_name: {},
|
||||
_entityId: {},
|
||||
_params: {},
|
||||
};
|
||||
}
|
||||
|
||||
public async showDialog(
|
||||
params: EntityRegistryDetailDialogParams
|
||||
): Promise<void> {
|
||||
this._params = params;
|
||||
this._error = undefined;
|
||||
this._name = this._params.entry.name || "";
|
||||
this._entityId = this._params.entry.entity_id;
|
||||
await this.updateComplete;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this._params) {
|
||||
return html``;
|
||||
}
|
||||
const entry = this._params.entry;
|
||||
const stateObj: HassEntity | undefined = this.hass.states[entry.entity_id];
|
||||
const invalidDomainUpdate =
|
||||
computeDomain(this._entityId.trim()) !==
|
||||
computeDomain(this._params.entry.entity_id);
|
||||
|
||||
return html`
|
||||
<paper-dialog
|
||||
with-backdrop
|
||||
opened
|
||||
@opened-changed="${this._openedChanged}"
|
||||
>
|
||||
<h2>${entry.entity_id}</h2>
|
||||
<paper-dialog-scrollable>
|
||||
${!stateObj
|
||||
? html`
|
||||
<div>This entity is not currently available.</div>
|
||||
`
|
||||
: ""}
|
||||
${this._error
|
||||
? html`
|
||||
<div class="error">${this._error}</div>
|
||||
`
|
||||
: ""}
|
||||
<div class="form">
|
||||
<paper-input
|
||||
.value=${this._name}
|
||||
@value-changed=${this._nameChanged}
|
||||
.label=${this.hass.localize("ui.dialogs.more_info_settings.name")}
|
||||
.placeholder=${stateObj ? computeStateName(stateObj) : ""}
|
||||
.disabled=${this._submitting}
|
||||
></paper-input>
|
||||
<paper-input
|
||||
.value=${this._entityId}
|
||||
@value-changed=${this._entityIdChanged}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.more_info_settings.entity_id"
|
||||
)}
|
||||
error-message="Domain needs to stay the same"
|
||||
.invalid=${invalidDomainUpdate}
|
||||
.disabled=${this._submitting}
|
||||
></paper-input>
|
||||
</div>
|
||||
</paper-dialog-scrollable>
|
||||
<div class="paper-dialog-buttons">
|
||||
<paper-button
|
||||
class="danger"
|
||||
@click="${this._deleteEntry}"
|
||||
.disabled=${this._submitting}
|
||||
>
|
||||
DELETE
|
||||
</paper-button>
|
||||
<paper-button
|
||||
@click="${this._updateEntry}"
|
||||
.disabled=${invalidDomainUpdate || this._submitting}
|
||||
>
|
||||
UPDATE
|
||||
</paper-button>
|
||||
</div>
|
||||
</paper-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _nameChanged(ev: PolymerChangedEvent<string>): void {
|
||||
this._error = undefined;
|
||||
this._name = ev.detail.value;
|
||||
}
|
||||
|
||||
private _entityIdChanged(ev: PolymerChangedEvent<string>): void {
|
||||
this._error = undefined;
|
||||
this._entityId = ev.detail.value;
|
||||
}
|
||||
|
||||
private async _updateEntry(): Promise<void> {
|
||||
try {
|
||||
this._submitting = true;
|
||||
await this._params!.updateEntry({
|
||||
name: this._name.trim() || null,
|
||||
new_entity_id: this._entityId.trim(),
|
||||
});
|
||||
this._params = undefined;
|
||||
} catch (err) {
|
||||
this._submitting = false;
|
||||
this._error = err;
|
||||
}
|
||||
}
|
||||
|
||||
private async _deleteEntry(): Promise<void> {
|
||||
this._submitting = true;
|
||||
|
||||
if (await this._params!.removeEntry()) {
|
||||
this._params = undefined;
|
||||
} else {
|
||||
this._submitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
private _openedChanged(ev: PolymerChangedEvent<boolean>): void {
|
||||
if (!(ev.detail as any).value) {
|
||||
this._params = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
haStyleDialog,
|
||||
css`
|
||||
paper-dialog {
|
||||
min-width: 400px;
|
||||
}
|
||||
.form {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
paper-button {
|
||||
font-weight: 500;
|
||||
}
|
||||
paper-button.danger {
|
||||
font-weight: 500;
|
||||
color: var(--google-red-500);
|
||||
margin-left: -12px;
|
||||
margin-right: auto;
|
||||
}
|
||||
.error {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-entity-registry-detail": DialogEntityRegistryDetail;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(
|
||||
"dialog-entity-registry-detail",
|
||||
DialogEntityRegistryDetail
|
||||
);
|
165
src/panels/config/entity_registry/ha-config-entity-registry.ts
Normal file
165
src/panels/config/entity_registry/ha-config-entity-registry.ts
Normal file
@ -0,0 +1,165 @@
|
||||
import {
|
||||
LitElement,
|
||||
TemplateResult,
|
||||
html,
|
||||
css,
|
||||
CSSResult,
|
||||
PropertyDeclarations,
|
||||
} from "lit-element";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-item/paper-item-body";
|
||||
import "@polymer/paper-card/paper-card";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
fetchEntityRegistry,
|
||||
computeEntityRegistryName,
|
||||
updateEntityRegistryEntry,
|
||||
removeEntityRegistryEntry,
|
||||
} from "../../../data/entity_registry";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import "../../../components/ha-icon";
|
||||
import compare from "../../../common/string/compare";
|
||||
import domainIcon from "../../../common/entity/domain_icon";
|
||||
import stateIcon from "../../../common/entity/state_icon";
|
||||
import computeDomain from "../../../common/entity/compute_domain";
|
||||
import "../ha-config-section";
|
||||
import {
|
||||
showEntityRegistryDetailDialog,
|
||||
loadEntityRegistryDetailDialog,
|
||||
} from "./show-dialog-entity-registry-detail";
|
||||
|
||||
class HaConfigEntityRegistry extends LitElement {
|
||||
public hass?: HomeAssistant;
|
||||
public isWide?: boolean;
|
||||
private _items?: EntityRegistryEntry[];
|
||||
|
||||
static get properties(): PropertyDeclarations {
|
||||
return {
|
||||
hass: {},
|
||||
isWide: {},
|
||||
_items: {},
|
||||
};
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | void {
|
||||
if (!this.hass || this._items === undefined) {
|
||||
return html`
|
||||
<hass-loading-screen></hass-loading-screen>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<hass-subpage header="Entity Registry">
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">Entity Registry</span>
|
||||
<span slot="introduction">
|
||||
Home Assistant keeps a registry of every entity it has ever seen
|
||||
that can be uniquely identified. Each of these entities will have an
|
||||
entity ID assigned which will be reserved for just this entity.
|
||||
<p>
|
||||
Use the entity registry to override the name, change the entity ID
|
||||
or remove the entry from Home Assistant. Note, removing the entity
|
||||
registry entry won't remove the entity. To do that, remove it from
|
||||
<a href="/config/integrations">the integrations page</a>.
|
||||
</p>
|
||||
</span>
|
||||
<paper-card>
|
||||
${this._items.map((entry) => {
|
||||
const state = this.hass!.states[entry.entity_id];
|
||||
return html`
|
||||
<paper-icon-item @click=${this._openEditEntry} .entry=${entry}>
|
||||
<ha-icon
|
||||
slot="item-icon"
|
||||
.icon=${state
|
||||
? stateIcon(state)
|
||||
: domainIcon(computeDomain(entry.entity_id))}
|
||||
></ha-icon>
|
||||
<paper-item-body two-line>
|
||||
<div class="name">
|
||||
${computeEntityRegistryName(this.hass!, entry) ||
|
||||
"(unavailable)"}
|
||||
</div>
|
||||
<div class="secondary entity-id">
|
||||
${entry.entity_id}
|
||||
</div>
|
||||
</paper-item-body>
|
||||
<div class="platform">${entry.platform}</div>
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</paper-card>
|
||||
</ha-config-section>
|
||||
</hass-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps): void {
|
||||
super.firstUpdated(changedProps);
|
||||
this._fetchData();
|
||||
loadEntityRegistryDetailDialog();
|
||||
}
|
||||
|
||||
private async _fetchData(): Promise<void> {
|
||||
this._items = (await fetchEntityRegistry(this.hass!)).sort((ent1, ent2) =>
|
||||
compare(ent1.entity_id, ent2.entity_id)
|
||||
);
|
||||
}
|
||||
|
||||
private _openEditEntry(ev: MouseEvent): void {
|
||||
const entry = (ev.currentTarget! as any).entry;
|
||||
showEntityRegistryDetailDialog(this, {
|
||||
entry,
|
||||
updateEntry: async (updates) => {
|
||||
const updated = await updateEntityRegistryEntry(
|
||||
this.hass!,
|
||||
entry.entity_id,
|
||||
updates
|
||||
);
|
||||
this._items = this._items!.map((ent) =>
|
||||
ent === entry ? updated : ent
|
||||
);
|
||||
},
|
||||
removeEntry: async () => {
|
||||
if (
|
||||
!confirm(`Are you sure you want to delete this entry?
|
||||
|
||||
Deleting an entry will not remove the entity from Home Assistant. To do this, you will need to remove the integration "${
|
||||
entry.platform
|
||||
}" from Home Assistant.`)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
await removeEntityRegistryEntry(this.hass!, entry.entity_id);
|
||||
this._items = this._items!.filter((ent) => ent !== entry);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
paper-card {
|
||||
display: block;
|
||||
background-color: white;
|
||||
}
|
||||
paper-icon-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
ha-icon {
|
||||
margin-left: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-config-entity-registry", HaConfigEntityRegistry);
|
@ -0,0 +1,27 @@
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
EntityRegistryEntryUpdateParams,
|
||||
} from "../../../data/entity_registry";
|
||||
|
||||
export interface EntityRegistryDetailDialogParams {
|
||||
entry: EntityRegistryEntry;
|
||||
updateEntry: (
|
||||
updates: Partial<EntityRegistryEntryUpdateParams>
|
||||
) => Promise<unknown>;
|
||||
removeEntry: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
export const loadEntityRegistryDetailDialog = () =>
|
||||
import(/* webpackChunkName: "entity-registry-detail-dialog" */ "./dialog-entity-registry-detail");
|
||||
|
||||
export const showEntityRegistryDetailDialog = (
|
||||
element: HTMLElement,
|
||||
systemLogDetailParams: EntityRegistryDetailDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-entity-registry-detail",
|
||||
dialogImport: loadEntityRegistryDetailDialog,
|
||||
dialogParams: systemLogDetailParams,
|
||||
});
|
||||
};
|
@ -16,6 +16,7 @@ import(/* webpackChunkName: "panel-config-core" */ "./core/ha-config-core");
|
||||
import(/* webpackChunkName: "panel-config-customize" */ "./customize/ha-config-customize");
|
||||
import(/* webpackChunkName: "panel-config-dashboard" */ "./dashboard/ha-config-dashboard");
|
||||
import(/* webpackChunkName: "panel-config-script" */ "./script/ha-config-script");
|
||||
import(/* webpackChunkName: "panel-config-entity-registry" */ "./entity_registry/ha-config-entity-registry");
|
||||
import(/* webpackChunkName: "panel-config-users" */ "./users/ha-config-users");
|
||||
import(/* webpackChunkName: "panel-config-zha" */ "./zha/ha-config-zha");
|
||||
import(/* webpackChunkName: "panel-config-zwave" */ "./zwave/ha-config-zwave");
|
||||
@ -92,6 +93,19 @@ class HaPanelConfig extends EventsMixin(NavigateMixin(PolymerElement)) {
|
||||
></ha-config-script>
|
||||
</template>
|
||||
|
||||
<template
|
||||
is="dom-if"
|
||||
if='[[_equals(_routeData.page, "entity_registry")]]'
|
||||
restamp
|
||||
>
|
||||
<ha-config-entity-registry
|
||||
page-name="entity_registry"
|
||||
route="[[route]]"
|
||||
hass="[[hass]]"
|
||||
is-wide="[[isWide]]"
|
||||
></ha-config-entity-registry>
|
||||
</template>
|
||||
|
||||
<template is="dom-if" if='[[_equals(_routeData.page, "zha")]]' restamp>
|
||||
<ha-config-zha
|
||||
page-name="zha"
|
||||
|
@ -491,7 +491,7 @@
|
||||
},
|
||||
"more_info_settings": {
|
||||
"save": "Save",
|
||||
"name": "Name",
|
||||
"name": "Name Override",
|
||||
"entity_id": "Entity ID"
|
||||
}
|
||||
},
|
||||
@ -748,6 +748,10 @@
|
||||
"description_login": "Logged in as {email}",
|
||||
"description_not_login": "Not logged in"
|
||||
},
|
||||
"entity_registry": {
|
||||
"caption": "Entity Registry",
|
||||
"description": "Overview of all known entities."
|
||||
},
|
||||
"integrations": {
|
||||
"caption": "Integrations",
|
||||
"description": "Manage connected devices and services",
|
||||
|
Loading…
x
Reference in New Issue
Block a user