Optimise config entities panel + clarify not being able to dele… (#5079)

This commit is contained in:
Paulus Schoutsen 2020-03-05 09:09:29 -08:00 committed by GitHub
parent b17ea09b8b
commit 4f98524258
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 36 deletions

View File

@ -3,7 +3,7 @@ import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-listbox/paper-listbox"; import "@polymer/paper-listbox/paper-listbox";
import "@polymer/paper-tooltip/paper-tooltip"; import "@polymer/paper-tooltip/paper-tooltip";
import { UnsubscribeFunc, HassEntities } from "home-assistant-js-websocket"; import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { import {
css, css,
CSSResult, CSSResult,
@ -58,6 +58,7 @@ export interface StateEntity extends EntityRegistryEntry {
export interface EntityRow extends StateEntity { export interface EntityRow extends StateEntity {
icon: string; icon: string;
unavailable: boolean; unavailable: boolean;
restored: boolean;
status: string; status: string;
} }
@ -68,6 +69,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
@property() public narrow!: boolean; @property() public narrow!: boolean;
@property() public route!: Route; @property() public route!: Route;
@property() private _entities?: EntityRegistryEntry[]; @property() private _entities?: EntityRegistryEntry[];
@property() private _stateEntities: StateEntity[] = [];
@property() private _showDisabled = false; @property() private _showDisabled = false;
@property() private _showUnavailable = true; @property() private _showUnavailable = true;
@property() private _showReadOnly = true; @property() private _showReadOnly = true;
@ -115,14 +117,20 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
style=${styleMap({ style=${styleMap({
color: entity.unavailable ? "var(--google-red-500)" : "", color: entity.unavailable ? "var(--google-red-500)" : "",
})} })}
.icon=${entity.unavailable .icon=${entity.restored
? "hass:restore-alert"
: entity.unavailable
? "hass:alert-circle" ? "hass:alert-circle"
: entity.disabled_by : entity.disabled_by
? "hass:cancel" ? "hass:cancel"
: "hass:pencil-off"} : "hass:pencil-off"}
></ha-icon> ></ha-icon>
<paper-tooltip position="left"> <paper-tooltip position="left">
${entity.unavailable ${entity.restored
? this.hass.localize(
"ui.panel.config.entities.picker.status.restored"
)
: entity.unavailable
? this.hass.localize( ? this.hass.localize(
"ui.panel.config.entities.picker.status.unavailable" "ui.panel.config.entities.picker.status.unavailable"
) )
@ -177,40 +185,23 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
private _filteredEntities = memoize( private _filteredEntities = memoize(
( (
entities: EntityRegistryEntry[], entities: EntityRegistryEntry[],
states: HassEntities, stateEntities: StateEntity[],
showDisabled: boolean, showDisabled: boolean,
showUnavailable: boolean, showUnavailable: boolean,
showReadOnly: boolean showReadOnly: boolean
): EntityRow[] => { ): EntityRow[] => {
const stateEntities: StateEntity[] = [];
if (showReadOnly) {
const regEntityIds = new Set(
entities.map((entity) => entity.entity_id)
);
for (const entityId of Object.keys(states)) {
if (regEntityIds.has(entityId)) {
continue;
}
stateEntities.push({
name: computeStateName(states[entityId]),
entity_id: entityId,
platform: computeDomain(entityId),
disabled_by: null,
readonly: true,
selectable: false,
});
}
}
if (!showDisabled) { if (!showDisabled) {
entities = entities.filter((entity) => !Boolean(entity.disabled_by)); entities = entities.filter((entity) => !Boolean(entity.disabled_by));
} }
const result: EntityRow[] = []; const result: EntityRow[] = [];
for (const entry of entities.concat(stateEntities)) { for (const entry of showReadOnly
const state = states[entry.entity_id]; ? entities.concat(stateEntities)
const unavailable = state?.state === "unavailable"; : entities) {
const entity = this.hass.states[entry.entity_id];
const unavailable = entity?.state === "unavailable";
const restored = entity?.attributes.restored;
if (!showUnavailable && unavailable) { if (!showUnavailable && unavailable) {
continue; continue;
@ -218,14 +209,19 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
result.push({ result.push({
...entry, ...entry,
icon: state icon: entity
? stateIcon(state) ? stateIcon(entity)
: domainIcon(computeDomain(entry.entity_id)), : domainIcon(computeDomain(entry.entity_id)),
name: name:
computeEntityRegistryName(this.hass!, entry) || computeEntityRegistryName(this.hass!, entry) ||
this.hass.localize("state.default.unavailable"), this.hass.localize("state.default.unavailable"),
unavailable, unavailable,
status: unavailable restored,
status: restored
? this.hass.localize(
"ui.panel.config.entities.picker.status.restored"
)
: unavailable
? this.hass.localize( ? this.hass.localize(
"ui.panel.config.entities.picker.status.unavailable" "ui.panel.config.entities.picker.status.unavailable"
) )
@ -389,7 +385,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
.columns=${this._columns(this.narrow, this.hass.language)} .columns=${this._columns(this.narrow, this.hass.language)}
.data=${this._filteredEntities( .data=${this._filteredEntities(
this._entities, this._entities,
this.hass.states, this._stateEntities,
this._showDisabled, this._showDisabled,
this._showUnavailable, this._showUnavailable,
this._showReadOnly this._showReadOnly
@ -418,6 +414,43 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
loadEntityEditorDialog(); loadEntityEditorDialog();
} }
protected updated(changedProps): void {
super.updated(changedProps);
const oldHass = changedProps.get("hass");
let changed = false;
if (!this.hass || !this._entities) {
return;
}
if (changedProps.has("hass") || changedProps.has("_entities")) {
const stateEntities: StateEntity[] = [];
const regEntityIds = new Set(
this._entities.map((entity) => entity.entity_id)
);
for (const entityId of Object.keys(this.hass.states)) {
if (regEntityIds.has(entityId)) {
continue;
}
if (
!oldHass ||
this.hass.states[entityId] !== oldHass.states[entityId]
) {
changed = true;
}
stateEntities.push({
name: computeStateName(this.hass.states[entityId]),
entity_id: entityId,
platform: computeDomain(entityId),
disabled_by: null,
readonly: true,
selectable: false,
});
}
if (changed) {
this._stateEntities = stateEntities;
}
}
}
private _showDisabledChanged() { private _showDisabledChanged() {
this._showDisabled = !this._showDisabled; this._showDisabled = !this._showDisabled;
} }
@ -499,12 +532,25 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
}); });
showConfirmationDialog(this, { showConfirmationDialog(this, {
title: this.hass.localize( title: this.hass.localize(
"ui.panel.config.entities.picker.remove_selected.confirm_title", `ui.panel.config.entities.picker.remove_selected.confirm_${
removeableEntities.length !== this._selectedEntities.length
? "partly_"
: ""
}title`,
"number", "number",
removeableEntities.length removeableEntities.length
), ),
text: this.hass.localize( text:
removeableEntities.length === this._selectedEntities.length
? this.hass.localize(
"ui.panel.config.entities.picker.remove_selected.confirm_text" "ui.panel.config.entities.picker.remove_selected.confirm_text"
)
: this.hass.localize(
"ui.panel.config.entities.picker.remove_selected.confirm_partly_text",
"removable",
removeableEntities.length,
"selected",
this._selectedEntities.length
), ),
confirmText: this.hass.localize("ui.common.yes"), confirmText: this.hass.localize("ui.common.yes"),
dismissText: this.hass.localize("ui.common.no"), dismissText: this.hass.localize("ui.common.no"),

View File

@ -1488,6 +1488,7 @@
"show_readonly": "Show read-only entities" "show_readonly": "Show read-only entities"
}, },
"status": { "status": {
"restored": "Restored",
"unavailable": "Unavailable", "unavailable": "Unavailable",
"disabled": "Disabled", "disabled": "Disabled",
"readonly": "Read-only", "readonly": "Read-only",
@ -1513,7 +1514,9 @@
"remove_selected": { "remove_selected": {
"button": "Remove selected", "button": "Remove selected",
"confirm_title": "Do you want to remove {number} entities?", "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." "confirm_partly_title": "Only {number} selected entities can be removed.",
"confirm_text": "You should remove them from your Lovelace config and automations if they contain these entities.",
"confirm_partly_text": "You can only remove {removable} of the selected {selected} entities. Entities can only be removed when the integration is no longer providing the entities. Sometimes you have to restart Home Assistant before you can remove the entities of a removed integration. Are you sure you want to remove the removable entities?"
} }
} }
}, },