Virtualize the add exposed entity list (#16333)

This commit is contained in:
Paul Bottein 2023-04-27 13:22:37 +02:00 committed by GitHub
parent 8ecdde3507
commit 37ba34cb0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -13,7 +13,7 @@ import {
ExtEntityRegistryEntry, ExtEntityRegistryEntry,
} from "../../../data/entity_registry"; } from "../../../data/entity_registry";
import { voiceAssistants } from "../../../data/voice"; import { voiceAssistants } from "../../../data/voice";
import { haStyle, haStyleDialog } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import "./entity-voice-settings"; import "./entity-voice-settings";
import { ExposeEntityDialogParams } from "./show-dialog-expose-entity"; import { ExposeEntityDialogParams } from "./show-dialog-expose-entity";
@ -48,6 +48,11 @@ class DialogExposeEntity extends LitElement {
"ui.panel.config.voice_assistants.expose.expose_dialog.header" "ui.panel.config.voice_assistants.expose.expose_dialog.header"
); );
const entities = this._filterEntities(
this._params.extendedEntities,
this._filter
);
return html` return html`
<ha-dialog open @closed=${this.closeDialog} .heading=${header}> <ha-dialog open @closed=${this.closeDialog} .heading=${header}>
<div slot="heading"> <div slot="heading">
@ -76,10 +81,14 @@ class DialogExposeEntity extends LitElement {
></search-input> ></search-input>
</div> </div>
<mwc-list multi> <mwc-list multi>
${this._filterEntities( <lit-virtualizer
this._params.extendedEntities, scroller
this._filter class="ha-scrollbar"
).map((entity) => this._renderItem(entity))} @click=${this._itemClicked}
.items=${entities}
.renderItem=${this._renderItem}
>
</lit-virtualizer>
</mwc-list> </mwc-list>
<mwc-button <mwc-button
slot="primaryAction" slot="primaryAction"
@ -95,10 +104,7 @@ class DialogExposeEntity extends LitElement {
`; `;
} }
private _handleSelected(ev) { private _handleSelected = (ev) => {
if (ev.detail.source !== "property") {
return;
}
const entityId = ev.target.value; const entityId = ev.target.value;
if (ev.detail.selected) { if (ev.detail.selected) {
if (this._selected.includes(entityId)) { if (this._selected.includes(entityId)) {
@ -108,6 +114,11 @@ class DialogExposeEntity extends LitElement {
} else { } else {
this._selected = this._selected.filter((item) => item !== entityId); this._selected = this._selected.filter((item) => item !== entityId);
} }
};
private _itemClicked(ev) {
const listItem = ev.target.closest("ha-check-list-item");
listItem.selected = !listItem.selected;
} }
private _filterChanged(e) { private _filterChanged(e) {
@ -133,21 +144,23 @@ class DialogExposeEntity extends LitElement {
private _renderItem = (entity: ExtEntityRegistryEntry) => { private _renderItem = (entity: ExtEntityRegistryEntry) => {
const entityState = this.hass.states[entity.entity_id]; const entityState = this.hass.states[entity.entity_id];
return html`<ha-check-list-item return html`
graphic="icon" <ha-check-list-item
twoLine graphic="icon"
.value=${entity.entity_id} twoLine
.selected=${this._selected.includes(entity.entity_id)} .value=${entity.entity_id}
@request-selected=${this._handleSelected} .selected=${this._selected.includes(entity.entity_id)}
> @request-selected=${this._handleSelected}
<ha-state-icon >
title=${ifDefined(entityState?.state)} <ha-state-icon
slot="graphic" title=${ifDefined(entityState?.state)}
.state=${entityState} slot="graphic"
></ha-state-icon> .state=${entityState}
${computeEntityRegistryName(this.hass!, entity)} ></ha-state-icon>
<span slot="secondary">${entity.entity_id}</span> ${computeEntityRegistryName(this.hass!, entity)}
</ha-check-list-item>`; <span slot="secondary">${entity.entity_id}</span>
</ha-check-list-item>
`;
}; };
private _expose() { private _expose() {
@ -158,21 +171,36 @@ class DialogExposeEntity extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
haStyle, haStyle,
haStyleDialog,
css` css`
ha-dialog { ha-dialog {
--dialog-content-padding: 0; --dialog-content-padding: 0;
--mdc-dialog-min-width: 500px;
--mdc-dialog-max-width: 600px;
} }
@media all and (min-width: 600px) { lit-virtualizer {
height: 500px;
}
@media all and (max-width: 500px), all and (max-height: 800px) {
ha-dialog { ha-dialog {
--mdc-dialog-min-width: 600px; --mdc-dialog-min-width: calc(
--mdc-dialog-max-height: 80%; 100vw - env(safe-area-inset-right) - env(safe-area-inset-left)
);
--mdc-dialog-max-width: calc(
100vw - env(safe-area-inset-right) - env(safe-area-inset-left)
);
--mdc-dialog-min-height: 100%;
--mdc-dialog-max-height: 100%;
--vertical-align-dialog: flex-end;
--ha-dialog-border-radius: 0px;
}
lit-virtualizer {
height: calc(100vh - 234px);
} }
} }
search-input { search-input {
width: 100%; width: 100%;
display: block; display: block;
padding: 24px 16px 0; padding: 16px 16px 0;
box-sizing: border-box; box-sizing: border-box;
} }
.header { .header {
@ -231,6 +259,20 @@ class DialogExposeEntity extends LitElement {
inset-inline-end: 16px; inset-inline-end: 16px;
direction: var(--direction); direction: var(--direction);
} }
lit-virtualizer {
width: 100%;
contain: size layout !important;
}
ha-check-list-item {
width: 100%;
height: 72px;
}
ha-check-list-item ha-state-icon {
margin-left: 24px;
margin-inline-start: 24;
margin-inline-end: initial;
direction: var(--direction);
}
`, `,
]; ];
} }