Add friendly name to quick bar list and filter (#7306)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Donnie 2020-10-13 15:26:12 -07:00 committed by GitHub
parent 0d741b6275
commit 63f60019d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 27 deletions

View File

@ -7,7 +7,16 @@
* *
* return true if word contains sequence. Otherwise false. * return true if word contains sequence. Otherwise false.
*/ */
export const fuzzySequentialMatch = (filter: string, word: string) => { export const fuzzySequentialMatch = (filter: string, words: string[]) => {
for (const word of words) {
if (_fuzzySequentialMatch(filter, word)) {
return true;
}
}
return false;
};
const _fuzzySequentialMatch = (filter: string, word: string) => {
if (filter === "") { if (filter === "") {
return true; return true;
} }
@ -22,7 +31,7 @@ export const fuzzySequentialMatch = (filter: string, word: string) => {
const newWord = word.substring(pos + 1); const newWord = word.substring(pos + 1);
const newFilter = filter.substring(1); const newFilter = filter.substring(1);
return fuzzySequentialMatch(newFilter, newWord); return _fuzzySequentialMatch(newFilter, newWord);
} }
return true; return true;

View File

@ -36,6 +36,8 @@ export class QuickBar extends LitElement {
@internalProperty() private _commandItems: CommandItem[] = []; @internalProperty() private _commandItems: CommandItem[] = [];
@internalProperty() private _entities: HassEntity[] = [];
@internalProperty() private _itemFilter = ""; @internalProperty() private _itemFilter = "";
@internalProperty() private _opened = false; @internalProperty() private _opened = false;
@ -46,6 +48,9 @@ export class QuickBar extends LitElement {
this._commandMode = params.commandMode || false; this._commandMode = params.commandMode || false;
this._opened = true; this._opened = true;
this._commandItems = this._generateCommandItems(); this._commandItems = this._generateCommandItems();
this._entities = Object.keys(this.hass.states).map<HassEntity>(
(entity_id) => this.hass.states[entity_id]
);
} }
public closeDialog() { public closeDialog() {
@ -101,19 +106,31 @@ export class QuickBar extends LitElement {
}); });
protected renderEntityList = memoizeOne((filter) => { protected renderEntityList = memoizeOne((filter) => {
const entities = this._filterEntityItems( const entities = this._filterEntityItems(filter);
Object.keys(this.hass.states),
filter
);
return html` return html`
<mwc-list activatable @selected=${this._entityMoreInfo}> <mwc-list activatable @selected=${this._entityMoreInfo}>
${entities.map((entityId) => { ${entities.map((entity) => {
const domain = computeDomain(entityId); const domain = computeDomain(entity.entity_id);
return html` return html`
<mwc-list-item graphic="icon" .entityId=${entityId}> <mwc-list-item
twoline
.entityId=${entity.entity_id}
graphic="avatar"
>
<ha-icon .icon=${domainIcon(domain)} slot="graphic"></ha-icon> <ha-icon .icon=${domainIcon(domain)} slot="graphic"></ha-icon>
${entityId} ${entity.attributes?.friendly_name
? html`
<span>
${entity.attributes?.friendly_name}
</span>
<span slot="secondary">${entity.entity_id}</span>
`
: html`
<span>
${entity.entity_id}
</span>
`}
</mwc-list-item> </mwc-list-item>
`; `;
})} })}
@ -155,25 +172,28 @@ export class QuickBar extends LitElement {
): CommandItem[] { ): CommandItem[] {
return items return items
.filter(({ text }) => .filter(({ text }) =>
fuzzySequentialMatch(filter.toLowerCase(), text.toLowerCase()) fuzzySequentialMatch(filter.toLowerCase(), [text.toLowerCase()])
) )
.sort((itemA, itemB) => compare(itemA.text, itemB.text)); .sort((itemA, itemB) => compare(itemA.text, itemB.text));
} }
private _filterEntityItems( private _filterEntityItems(filter: string): HassEntity[] {
entityIds: HassEntity["entity_id"][], return this._entities
filter: string .filter(({ entity_id, attributes: { friendly_name } }) => {
): HassEntity["entity_id"][] { const values = [entity_id];
return entityIds if (friendly_name) {
.filter((entityId) => values.push(friendly_name);
fuzzySequentialMatch(filter.toLowerCase(), entityId) }
return fuzzySequentialMatch(filter.toLowerCase(), values);}
) )
.sort(); .sort((entityA, entityB) =>
compare(entityA.entity_id, entityB.entity_id)
);
} }
private async _processItemAndCloseDialog(ev: SingleSelectedEvent) { private async _processItemAndCloseDialog(ev: SingleSelectedEvent) {
const index = ev.detail.index; const _index = ev.detail.index;
const item = (ev.target as any).items[index].item; const item = (ev.target as any).items[_index].item;
await this.hass.callService(item.domain, item.service, item.serviceData); await this.hass.callService(item.domain, item.service, item.serviceData);
@ -181,10 +201,11 @@ export class QuickBar extends LitElement {
} }
private _entityMoreInfo(ev: SingleSelectedEvent) { private _entityMoreInfo(ev: SingleSelectedEvent) {
const index = ev.detail.index; const _index = ev.detail.index;
const entityId = (ev.target as any).items[index].entityId; const entityId = (ev.target as any).items[_index].entityId;
fireEvent(this, "hass-more-info", { entityId }); fireEvent(this, "hass-more-info", { entityId });
this.closeDialog(); this.closeDialog();
} }

View File

@ -3,7 +3,7 @@ import { assert } from "chai";
import { fuzzySequentialMatch } from "../../../src/common/string/sequence_matching"; import { fuzzySequentialMatch } from "../../../src/common/string/sequence_matching";
describe("fuzzySequentialMatch", () => { describe("fuzzySequentialMatch", () => {
const entityId = "automation.ticker"; const entity = { entity_id: "automation.ticker", friendly_name: "Stocks" };
const shouldMatchEntity = [ const shouldMatchEntity = [
"", "",
@ -23,6 +23,9 @@ describe("fuzzySequentialMatch", () => {
"uoaintce", "uoaintce",
"au.tce", "au.tce",
"tomaontkr", "tomaontkr",
"s",
"stocks",
"sks",
]; ];
const shouldNotMatchEntity = [ const shouldNotMatchEntity = [
@ -32,19 +35,27 @@ describe("fuzzySequentialMatch", () => {
"automation. ticke", "automation. ticke",
"1", "1",
"noitamotua", "noitamotua",
"autostocks",
"stox",
]; ];
describe(`Entity '${entityId}'`, () => { describe(`Entity '${entity.entity_id}'`, () => {
for (const goodFilter of shouldMatchEntity) { for (const goodFilter of shouldMatchEntity) {
it(`matches with '${goodFilter}'`, () => { it(`matches with '${goodFilter}'`, () => {
const res = fuzzySequentialMatch(goodFilter, entityId); const res = fuzzySequentialMatch(goodFilter, [
entity.entity_id,
entity.friendly_name.toLowerCase(),
]);
assert.equal(res, true); assert.equal(res, true);
}); });
} }
for (const badFilter of shouldNotMatchEntity) { for (const badFilter of shouldNotMatchEntity) {
it(`fails to match with '${badFilter}'`, () => { it(`fails to match with '${badFilter}'`, () => {
const res = fuzzySequentialMatch(badFilter, entityId); const res = fuzzySequentialMatch(badFilter, [
entity.entity_id,
entity.friendly_name,
]);
assert.equal(res, false); assert.equal(res, false);
}); });
} }