From 6e331616734e490b71e124d9a8c152aff9fadf05 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 6 Jan 2020 16:04:03 +0100 Subject: [PATCH 1/5] Add multi select to entity registry --- src/common/search/search-input.ts | 2 +- src/components/data-table/ha-data-table.ts | 66 ++- .../dialog-entity-registry-detail.ts | 10 +- .../ha-config-entity-registry.ts | 444 +++++++++++++++--- src/translations/en.json | 32 +- 5 files changed, 444 insertions(+), 110 deletions(-) diff --git a/src/common/search/search-input.ts b/src/common/search/search-input.ts index 8bfcf399fd7e..2c3e772c42ae 100644 --- a/src/common/search/search-input.ts +++ b/src/common/search/search-input.ts @@ -14,7 +14,7 @@ import "@material/mwc-button"; @customElement("search-input") class SearchInput extends LitElement { - @property() private filter?: string; + @property() public filter?: string; public focus() { this.shadowRoot!.querySelector("paper-input")!.focus(); diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index ea7f0e59ac5b..7ca6dae14679 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -88,11 +88,11 @@ export class HaDataTable extends BaseElement { @property({ type: Array }) public data: DataTableRowData[] = []; @property({ type: Boolean }) public selectable = false; @property({ type: String }) public id = "id"; + @property({ type: String }) public filter = ""; protected mdcFoundation!: MDCDataTableFoundation; protected readonly mdcFoundationClass = MDCDataTableFoundation; @query(".mdc-data-table") protected mdcRoot!: HTMLElement; @queryAll(".mdc-data-table__row") protected rowElements!: HTMLElement[]; - @query("#header-checkbox") private _headerCheckbox!: HaCheckbox; @property({ type: Boolean }) private _filterable = false; @property({ type: Boolean }) private _headerChecked = false; @property({ type: Boolean }) private _headerIndeterminate = false; @@ -108,13 +108,19 @@ export class HaDataTable extends BaseElement { private _worker: any | undefined; private _debounceSearch = debounce( - (ev) => { - this._filter = ev.detail.value; + (value: string) => { + this._filter = value; }, 200, false ); + public clearSelection(): void { + this._headerChecked = false; + this._headerIndeterminate = false; + this.mdcFoundation.handleHeaderRowCheckboxChange(); + } + protected firstUpdated() { super.firstUpdated(); this._worker = sortFilterWorker(); @@ -146,6 +152,10 @@ export class HaDataTable extends BaseElement { this._sortColumns = clonedColumns; } + if (properties.has("filter")) { + this._debounceSearch(this.filter); + } + if ( properties.has("data") || properties.has("columns") || @@ -159,14 +169,20 @@ export class HaDataTable extends BaseElement { protected render() { return html` - ${this._filterable - ? html` - - ` - : ""}
+ + ${this._filterable + ? html` +
+ +
+ ` + : ""} +
@@ -178,7 +194,6 @@ export class HaDataTable extends BaseElement { scope="col" > ${this.hass.localize( "ui.panel.config.entity_registry.editor.delete" @@ -201,13 +202,8 @@ class DialogEntityRegistryDetail extends LitElement { private _confirmDeleteEntry(): void { showConfirmationDialog(this, { - title: this.hass.localize( - "ui.panel.config.entity_registry.editor.confirm_delete" - ), text: this.hass.localize( - "ui.panel.config.entity_registry.editor.confirm_delete2", - "platform", - this._platform + "ui.panel.config.entity_registry.editor.confirm_delete" ), confirm: () => this._deleteEntry(), }); diff --git a/src/panels/config/entity_registry/ha-config-entity-registry.ts b/src/panels/config/entity_registry/ha-config-entity-registry.ts index e7854ece8fae..7fb4081a10ad 100644 --- a/src/panels/config/entity_registry/ha-config-entity-registry.ts +++ b/src/panels/config/entity_registry/ha-config-entity-registry.ts @@ -5,19 +5,28 @@ import { css, CSSResult, property, + query, } from "lit-element"; +import { styleMap } from "lit-html/directives/style-map"; + +import "@polymer/paper-checkbox/paper-checkbox"; +import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; +import "@polymer/paper-item/paper-icon-item"; +import "@polymer/paper-listbox/paper-listbox"; +import "@polymer/paper-tooltip/paper-tooltip"; import { HomeAssistant } from "../../../types"; import { EntityRegistryEntry, computeEntityRegistryName, subscribeEntityRegistry, + removeEntityRegistryEntry, + updateEntityRegistryEntry, } from "../../../data/entity_registry"; import "../../../layouts/hass-subpage"; import "../../../layouts/hass-loading-screen"; import "../../../components/data-table/ha-data-table"; import "../../../components/ha-icon"; -import "../../../components/ha-switch"; import { domainIcon } from "../../../common/entity/domain_icon"; import { stateIcon } from "../../../common/entity/state_icon"; import { computeDomain } from "../../../common/entity/compute_domain"; @@ -26,25 +35,33 @@ import { loadEntityRegistryDetailDialog, } from "./show-dialog-entity-registry-detail"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; -// tslint:disable-next-line -import { HaSwitch } from "../../../components/ha-switch"; import memoize from "memoize-one"; // tslint:disable-next-line import { DataTableColumnContainer, RowClickedEvent, + SelectionChangedEvent, + HaDataTable, + DataTableColumnData, } from "../../../components/data-table/ha-data-table"; +import { showConfirmationDialog } from "../../../dialogs/confirmation/show-dialog-confirmation"; class HaConfigEntityRegistry extends LitElement { @property() public hass!: HomeAssistant; - @property() public isWide?: boolean; + @property() public isWide!: boolean; + @property() public narrow!: boolean; @property() private _entities?: EntityRegistryEntry[]; @property() private _showDisabled = false; + @property() private _showRestored = true; + @property() private _filter = ""; + @property() private _selectedEntities: string[] = []; + @query("ha-data-table") private _dataTable!: HaDataTable; + private _unsubEntities?: UnsubscribeFunc; private _columns = memoize( - (_language): DataTableColumnContainer => { - return { + (narrow, _language): DataTableColumnContainer => { + const columns: DataTableColumnContainer = { icon: { title: "", type: "icon", @@ -60,49 +77,104 @@ class HaConfigEntityRegistry extends LitElement { filterable: true, direction: "asc", }, - entity_id: { - title: this.hass.localize( - "ui.panel.config.entity_registry.picker.headers.entity_id" - ), - sortable: true, - filterable: true, - }, - platform: { - title: this.hass.localize( - "ui.panel.config.entity_registry.picker.headers.integration" - ), - sortable: true, - filterable: true, - template: (platform) => - html` - ${this.hass.localize(`component.${platform}.config.title`) || - platform} - `, - }, - disabled_by: { - title: this.hass.localize( - "ui.panel.config.entity_registry.picker.headers.enabled" - ), - type: "icon", - template: (disabledBy) => html` - + }; + + const statusColumn: DataTableColumnData = { + title: this.hass.localize( + "ui.panel.config.entity_registry.picker.headers.status" + ), + type: "icon", + template: (_status, entity: any) => html` + ${entity.unavailable || entity.disabled_by + ? html` +
+ + + ${entity.unavailable + ? this.hass.localize( + "ui.panel.config.entity_registry.picker.status.unavailable" + ) + : this.hass.localize( + "ui.panel.config.entity_registry.picker.status.disabled" + )} + +
+ ` + : ""} + `, + }; + + if (narrow) { + columns.name.template = (name, entity: any) => { + return html` + ${name}
+ ${entity.entity_id} | + ${this.hass.localize(`component.${entity.platform}.config.title`) || + entity.platform} + `; + }; + columns.status = statusColumn; + return columns; + } + + columns.entity_id = { + title: this.hass.localize( + "ui.panel.config.entity_registry.picker.headers.entity_id" + ), + sortable: true, + filterable: true, + }; + columns.platform = { + title: this.hass.localize( + "ui.panel.config.entity_registry.picker.headers.integration" + ), + sortable: true, + filterable: true, + template: (platform) => + html` + ${this.hass.localize(`component.${platform}.config.title`) || + platform} `, - }, }; + columns.status = statusColumn; + + return columns; } ); private _filteredEntities = memoize( - (entities: EntityRegistryEntry[], showDisabled: boolean) => - (showDisabled - ? entities - : entities.filter((entity) => !Boolean(entity.disabled_by)) - ).map((entry) => { + ( + entities: EntityRegistryEntry[], + showDisabled: boolean, + showUnavailable: boolean + ) => { + if (!showDisabled) { + entities = entities.filter((entity) => !Boolean(entity.disabled_by)); + } + + return entities.reduce((result, entry) => { const state = this.hass!.states[entry.entity_id]; - return { + + const unavailable = + state && (state.state === "unavailable" || state.attributes.restored); // if there is not state it is disabled + + if (!showUnavailable) { + if (unavailable) { + return result; + } + } + + result.push({ ...entry, icon: state ? stateIcon(state) @@ -110,8 +182,12 @@ class HaConfigEntityRegistry extends LitElement { name: computeEntityRegistryName(this.hass!, entry) || this.hass!.localize("state.default.unavailable"), - }; - }) + unavailable, + status: true, + }); + return result; + }, [] as any); + } ); public disconnectedCallback() { @@ -133,17 +209,19 @@ class HaConfigEntityRegistry extends LitElement { "ui.panel.config.entity_registry.caption" )}" > -
-
-

- ${this.hass.localize( - "ui.panel.config.entity_registry.picker.header" - )} -

-

- ${this.hass.localize( - "ui.panel.config.entity_registry.picker.introduction" - )} +

+
+

+ ${this.hass.localize( + "ui.panel.config.entity_registry.picker.header" + )} +

+

+ ${this.hass.localize( + "ui.panel.config.entity_registry.picker.introduction" + )} +

+

${this.hass.localize( "ui.panel.config.entity_registry.picker.introduction2" @@ -154,22 +232,123 @@ class HaConfigEntityRegistry extends LitElement { "ui.panel.config.entity_registry.picker.integrations_page" )} - ${this.hass.localize( - "ui.panel.config.entity_registry.picker.show_disabled" - )} -

-

- - + +
+ ${this._selectedEntities.length + ? html` +

+ ${this.hass.localize( + "ui.panel.config.entity_registry.picker.selected", + "number", + this._selectedEntities.length + )} +

+
+ ${!this.narrow + ? html` + ${this.hass.localize( + "ui.panel.config.entity_registry.picker.enable_selected.button" + )} + ${this.hass.localize( + "ui.panel.config.entity_registry.picker.disable_selected.button" + )} + ${this.hass.localize( + "ui.panel.config.entity_registry.picker.remove_selected.button" + )} + ` + : html` + + + ${this.hass.localize( + "ui.panel.config.entity_registry.picker.enable_selected.button" + )} + + + + ${this.hass.localize( + "ui.panel.config.entity_registry.picker.disable_selected.button" + )} + + + + ${this.hass.localize( + "ui.panel.config.entity_registry.picker.remove_selected.button" + )} + + `} +
+ ` + : html` + + + + + + + ${this.hass!.localize( + "ui.panel.config.entity_registry.picker.filter.show_disabled" + )} + + + + ${this.hass!.localize( + "ui.panel.config.entity_registry.picker.filter.show_unavailable" + )} + + + + `} +
+
`; @@ -192,8 +371,106 @@ class HaConfigEntityRegistry extends LitElement { } } - private _showDisabledChanged(ev: Event) { - this._showDisabled = (ev.target as HaSwitch).checked; + private _showDisabledChanged() { + this._showDisabled = !this._showDisabled; + } + + private _showRestoredChanged() { + this._showRestored = !this._showRestored; + } + + private _handleSearchChange(ev: CustomEvent) { + this._filter = ev.detail.value; + } + + private _handleSelectionChanged(ev: CustomEvent): void { + const changedSelection = ev.detail as SelectionChangedEvent; + const entity = changedSelection.id; + if (changedSelection.selected) { + this._selectedEntities.push(entity); + } else { + const index = this._selectedEntities.indexOf(entity); + if (index !== -1) { + this._selectedEntities.splice(index, 1); + } + } + this._selectedEntities = [...this._selectedEntities]; + } + + private _enableSelected() { + showConfirmationDialog(this, { + title: this.hass.localize( + "ui.panel.config.entity_registry.picker.enable_selected.confirm_title", + "number", + this._selectedEntities.length + ), + text: this.hass.localize( + "ui.panel.config.entity_registry.picker.enable_selected.confirm_text" + ), + confirmBtnText: this.hass.localize("ui.common.yes"), + cancelBtnText: this.hass.localize("ui.common.no"), + confirm: () => { + this._selectedEntities.forEach((entity) => + updateEntityRegistryEntry(this.hass, entity, { + disabled_by: null, + }) + ); + this._clearSelection(); + }, + }); + } + + private _disableSelected() { + showConfirmationDialog(this, { + title: this.hass.localize( + "ui.panel.config.entity_registry.picker.disable_selected.confirm_title", + "number", + this._selectedEntities.length + ), + text: this.hass.localize( + "ui.panel.config.entity_registry.picker.disable_selected.confirm_text" + ), + confirmBtnText: this.hass.localize("ui.common.yes"), + cancelBtnText: this.hass.localize("ui.common.no"), + confirm: () => { + this._selectedEntities.forEach((entity) => + updateEntityRegistryEntry(this.hass, entity, { + disabled_by: "user", + }) + ); + this._clearSelection(); + }, + }); + } + + private _removeSelected() { + showConfirmationDialog(this, { + title: this.hass.localize( + "ui.panel.config.entity_registry.picker.remove_selected.confirm_title", + "number", + this._selectedEntities.length + ), + text: this.hass.localize( + "ui.panel.config.entity_registry.picker.remove_selected.confirm_text" + ), + confirmBtnText: this.hass.localize("ui.common.yes"), + cancelBtnText: this.hass.localize("ui.common.no"), + confirm: () => { + this._selectedEntities.forEach((entity) => this._removeEntity(entity)); + this._clearSelection(); + }, + }); + } + + private _removeEntity(entityId: string) { + const stateObj = this.hass.states[entityId]; + if (stateObj?.attributes.restored) { + removeEntityRegistryEntry(this.hass, entityId); + } + } + + private _clearSelection() { + this._dataTable.clearSelection(); } private _openEditEntry(ev: CustomEvent): void { @@ -237,18 +514,35 @@ class HaConfigEntityRegistry extends LitElement { opacity: var(--dark-primary-opacity); } .intro { - padding: 24px 16px 0; + padding: 24px 16px; } .content { padding: 4px; } ha-data-table { - margin-bottom: 24px; - margin-top: 0px; + width: 100%; } ha-switch { margin-top: 16px; } + .table-header { + display: flex; + justify-content: space-between; + align-items: flex-end; + border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12); + } + search-input { + flex-grow: 1; + } + .selected-txt { + font-weight: bold; + margin-top: 38px; + padding-left: 16px; + } + .header-btns > mwc-button, + .header-btns > paper-icon-button { + margin: 8px; + } `; } } diff --git a/src/translations/en.json b/src/translations/en.json index 8b08f4624f0e..69c1c554cc25 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1257,14 +1257,37 @@ "picker": { "header": "Entities", "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.", - "introduction2": "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, follow the link below and remove it from the integrations page.", - "integrations_page": "Integrations page", - "show_disabled": "Show disabled entities", + "introduction2": "Use the entity registry to override the name, change the entity ID or remove the entry from Home Assistant.", + "filter": { + "filter": "Filter", + "show_disabled": "Show disabled entities", + "show_unavailable": "Show unavailable entities" + }, + "status": { + "unavailable": "Unavailable", + "disabled": "Disabled" + }, "headers": { "name": "Name", "entity_id": "Entity ID", "integration": "Integration", - "enabled": "Enabled" + "status": "Status" + }, + "selected": "{number} selected", + "enable_selected": { + "button": "Enable selected", + "confirm_title": "Do you want to enable {number} entities?", + "confirm_text": "This will make them available in Home Assistant again if they are now disabled." + }, + "disable_selected": { + "button": "Disable selected", + "confirm_title": "Do you want to disable {number} entities?", + "confirm_text": "Disabled entities will not be added to Home Assistant." + }, + "remove_selected": { + "button": "Remove selected", + "confirm_title": "Do you want to remove {number} entities?", + "confirm_text": "Entities can only be removed when the integration is no longer providing the entities." } }, "editor": { @@ -1275,7 +1298,6 @@ "enabled_description": "Disabled entities will not be added to Home Assistant.", "delete": "DELETE", "confirm_delete": "Are you sure you want to delete this entry?", - "confirm_delete2": "Deleting an entry will not remove the entity from Home Assistant. To do this, you will need to remove the integration '{platform}' from Home Assistant.", "update": "UPDATE", "note": "Note: this might not work yet with all integrations." } From 9ff301012ba6b16f9ca88f347b0f20ccffb956b1 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 6 Jan 2020 16:11:54 +0100 Subject: [PATCH 2/5] Fix filter and sort on status --- .../entity_registry/ha-config-entity-registry.ts | 16 ++++++++++++++-- src/translations/en.json | 3 ++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/panels/config/entity_registry/ha-config-entity-registry.ts b/src/panels/config/entity_registry/ha-config-entity-registry.ts index 7fb4081a10ad..a53d29882edf 100644 --- a/src/panels/config/entity_registry/ha-config-entity-registry.ts +++ b/src/panels/config/entity_registry/ha-config-entity-registry.ts @@ -84,6 +84,8 @@ class HaConfigEntityRegistry extends LitElement { "ui.panel.config.entity_registry.picker.headers.status" ), type: "icon", + sortable: true, + filterable: true, template: (_status, entity: any) => html` ${entity.unavailable || entity.disabled_by ? html` @@ -181,9 +183,19 @@ class HaConfigEntityRegistry extends LitElement { : domainIcon(computeDomain(entry.entity_id)), name: computeEntityRegistryName(this.hass!, entry) || - this.hass!.localize("state.default.unavailable"), + this.hass.localize("state.default.unavailable"), unavailable, - status: true, + status: unavailable + ? this.hass.localize( + "ui.panel.config.entity_registry.picker.status.unavailable" + ) + : entry.disabled_by + ? this.hass.localize( + "ui.panel.config.entity_registry.picker.status.disabled" + ) + : this.hass.localize( + "ui.panel.config.entity_registry.picker.status.ok" + ), }); return result; }, [] as any); diff --git a/src/translations/en.json b/src/translations/en.json index 69c1c554cc25..39d70997d640 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1265,7 +1265,8 @@ }, "status": { "unavailable": "Unavailable", - "disabled": "Disabled" + "disabled": "Disabled", + "ok": "Ok" }, "headers": { "name": "Name", From 047680a03105d7c4b6c2da8b88f3abc4ed09e5c4 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 6 Jan 2020 18:03:25 +0100 Subject: [PATCH 3/5] Remove unused prop platform --- .../config/entity_registry/dialog-entity-registry-detail.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/panels/config/entity_registry/dialog-entity-registry-detail.ts b/src/panels/config/entity_registry/dialog-entity-registry-detail.ts index 0a412bb21221..5b4a0f32ded0 100644 --- a/src/panels/config/entity_registry/dialog-entity-registry-detail.ts +++ b/src/panels/config/entity_registry/dialog-entity-registry-detail.ts @@ -31,7 +31,6 @@ import { showConfirmationDialog } from "../../../dialogs/confirmation/show-dialo class DialogEntityRegistryDetail extends LitElement { @property() public hass!: HomeAssistant; @property() private _name!: string; - @property() private _platform!: string; @property() private _entityId!: string; @property() private _disabledBy!: string | null; @property() private _error?: string; @@ -45,7 +44,6 @@ class DialogEntityRegistryDetail extends LitElement { this._params = params; this._error = undefined; this._name = this._params.entry.name || ""; - this._platform = this._params.entry.platform; this._origEntityId = this._params.entry.entity_id; this._entityId = this._params.entry.entity_id; this._disabledBy = this._params.entry.disabled_by; From 012a75e27ad62d4c9965421588001f710286c7db Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 6 Jan 2020 21:54:37 +0100 Subject: [PATCH 4/5] Review --- src/components/data-table/ha-data-table.ts | 9 ++-- .../ha-config-entity-registry.ts | 42 +++++++++---------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/components/data-table/ha-data-table.ts b/src/components/data-table/ha-data-table.ts index 7ca6dae14679..7827938381f3 100644 --- a/src/components/data-table/ha-data-table.ts +++ b/src/components/data-table/ha-data-table.ts @@ -75,7 +75,7 @@ export interface DataTableSortColumnData { export interface DataTableColumnData extends DataTableSortColumnData { title: string; type?: "numeric" | "icon"; - template?: (data: any, row: T) => TemplateResult; + template?: (data: any, row: T) => TemplateResult | string; } export interface DataTableRowData { @@ -173,9 +173,7 @@ export class HaDataTable extends BaseElement { ${this._filterable ? html` -
+
@@ -611,6 +609,9 @@ export class HaDataTable extends BaseElement { .mdc-data-table__header-cell:hover.not-sorted ha-icon { left: 0px; } + .table-header { + border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12); + } `; } } diff --git a/src/panels/config/entity_registry/ha-config-entity-registry.ts b/src/panels/config/entity_registry/ha-config-entity-registry.ts index a53d29882edf..6556a0f032b8 100644 --- a/src/panels/config/entity_registry/ha-config-entity-registry.ts +++ b/src/panels/config/entity_registry/ha-config-entity-registry.ts @@ -86,8 +86,8 @@ class HaConfigEntityRegistry extends LitElement { type: "icon", sortable: true, filterable: true, - template: (_status, entity: any) => html` - ${entity.unavailable || entity.disabled_by + template: (_status, entity: any) => + entity.unavailable || entity.disabled_by ? html`
` - : ""} - `, + : "", }; if (narrow) { @@ -143,10 +142,7 @@ class HaConfigEntityRegistry extends LitElement { sortable: true, filterable: true, template: (platform) => - html` - ${this.hass.localize(`component.${platform}.config.title`) || - platform} - `, + this.hass.localize(`component.${platform}.config.title`) || platform, }; columns.status = statusColumn; @@ -170,10 +166,8 @@ class HaConfigEntityRegistry extends LitElement { const unavailable = state && (state.state === "unavailable" || state.attributes.restored); // if there is not state it is disabled - if (!showUnavailable) { - if (unavailable) { - return result; - } + if (!showUnavailable && unavailable) { + return result; } result.push({ @@ -399,14 +393,14 @@ class HaConfigEntityRegistry extends LitElement { const changedSelection = ev.detail as SelectionChangedEvent; const entity = changedSelection.id; if (changedSelection.selected) { - this._selectedEntities.push(entity); + this._selectedEntities = [...this._selectedEntities, entity]; } else { const index = this._selectedEntities.indexOf(entity); if (index !== -1) { this._selectedEntities.splice(index, 1); + this._selectedEntities = [...this._selectedEntities]; } } - this._selectedEntities = [...this._selectedEntities]; } private _enableSelected() { @@ -456,11 +450,18 @@ class HaConfigEntityRegistry extends LitElement { } private _removeSelected() { + const removeableEntities: string[] = []; + this._selectedEntities.forEach((entity) => { + const stateObj = this.hass.states[entity]; + if (stateObj?.attributes.restored) { + removeableEntities.push(entity); + } + }); showConfirmationDialog(this, { title: this.hass.localize( "ui.panel.config.entity_registry.picker.remove_selected.confirm_title", "number", - this._selectedEntities.length + removeableEntities.length ), text: this.hass.localize( "ui.panel.config.entity_registry.picker.remove_selected.confirm_text" @@ -468,19 +469,14 @@ class HaConfigEntityRegistry extends LitElement { confirmBtnText: this.hass.localize("ui.common.yes"), cancelBtnText: this.hass.localize("ui.common.no"), confirm: () => { - this._selectedEntities.forEach((entity) => this._removeEntity(entity)); + removeableEntities.forEach((entity) => + removeEntityRegistryEntry(this.hass, entity) + ); this._clearSelection(); }, }); } - private _removeEntity(entityId: string) { - const stateObj = this.hass.states[entityId]; - if (stateObj?.attributes.restored) { - removeEntityRegistryEntry(this.hass, entityId); - } - } - private _clearSelection() { this._dataTable.clearSelection(); } From e975077906024e56fa5f5e175296ffca0e6bddb1 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 7 Jan 2020 09:00:40 +0100 Subject: [PATCH 5/5] Update ha-config-entity-registry.ts --- .../ha-config-entity-registry.ts | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/panels/config/entity_registry/ha-config-entity-registry.ts b/src/panels/config/entity_registry/ha-config-entity-registry.ts index 6556a0f032b8..3b3fec5eff0d 100644 --- a/src/panels/config/entity_registry/ha-config-entity-registry.ts +++ b/src/panels/config/entity_registry/ha-config-entity-registry.ts @@ -52,7 +52,7 @@ class HaConfigEntityRegistry extends LitElement { @property() public narrow!: boolean; @property() private _entities?: EntityRegistryEntry[]; @property() private _showDisabled = false; - @property() private _showRestored = true; + @property() private _showUnavailable = true; @property() private _filter = ""; @property() private _selectedEntities: string[] = []; @query("ha-data-table") private _dataTable!: HaDataTable; @@ -244,7 +244,7 @@ class HaConfigEntityRegistry extends LitElement { .data=${this._filteredEntities( this._entities, this._showDisabled, - this._showRestored + this._showUnavailable )} .filter=${this._filter} selectable @@ -343,7 +343,7 @@ class HaConfigEntityRegistry extends LitElement { ${this.hass!.localize( @@ -382,7 +382,7 @@ class HaConfigEntityRegistry extends LitElement { } private _showRestoredChanged() { - this._showRestored = !this._showRestored; + this._showUnavailable = !this._showUnavailable; } private _handleSearchChange(ev: CustomEvent) { @@ -395,11 +395,9 @@ class HaConfigEntityRegistry extends LitElement { if (changedSelection.selected) { this._selectedEntities = [...this._selectedEntities, entity]; } else { - const index = this._selectedEntities.indexOf(entity); - if (index !== -1) { - this._selectedEntities.splice(index, 1); - this._selectedEntities = [...this._selectedEntities]; - } + this._selectedEntities = this._selectedEntities.filter( + (entityId) => entityId !== entity + ); } } @@ -450,12 +448,9 @@ class HaConfigEntityRegistry extends LitElement { } private _removeSelected() { - const removeableEntities: string[] = []; - this._selectedEntities.forEach((entity) => { + const removeableEntities = this._selectedEntities.filter((entity) => { const stateObj = this.hass.states[entity]; - if (stateObj?.attributes.restored) { - removeableEntities.push(entity); - } + return stateObj?.attributes.restored; }); showConfirmationDialog(this, { title: this.hass.localize(