mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 05:47:20 +00:00
Add friendly name to quick bar list and filter (#7306)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
0d741b6275
commit
63f60019d1
@ -7,7 +7,16 @@
|
||||
*
|
||||
* 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 === "") {
|
||||
return true;
|
||||
}
|
||||
@ -22,7 +31,7 @@ export const fuzzySequentialMatch = (filter: string, word: string) => {
|
||||
const newWord = word.substring(pos + 1);
|
||||
const newFilter = filter.substring(1);
|
||||
|
||||
return fuzzySequentialMatch(newFilter, newWord);
|
||||
return _fuzzySequentialMatch(newFilter, newWord);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -36,6 +36,8 @@ export class QuickBar extends LitElement {
|
||||
|
||||
@internalProperty() private _commandItems: CommandItem[] = [];
|
||||
|
||||
@internalProperty() private _entities: HassEntity[] = [];
|
||||
|
||||
@internalProperty() private _itemFilter = "";
|
||||
|
||||
@internalProperty() private _opened = false;
|
||||
@ -46,6 +48,9 @@ export class QuickBar extends LitElement {
|
||||
this._commandMode = params.commandMode || false;
|
||||
this._opened = true;
|
||||
this._commandItems = this._generateCommandItems();
|
||||
this._entities = Object.keys(this.hass.states).map<HassEntity>(
|
||||
(entity_id) => this.hass.states[entity_id]
|
||||
);
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
@ -101,19 +106,31 @@ export class QuickBar extends LitElement {
|
||||
});
|
||||
|
||||
protected renderEntityList = memoizeOne((filter) => {
|
||||
const entities = this._filterEntityItems(
|
||||
Object.keys(this.hass.states),
|
||||
filter
|
||||
);
|
||||
const entities = this._filterEntityItems(filter);
|
||||
|
||||
return html`
|
||||
<mwc-list activatable @selected=${this._entityMoreInfo}>
|
||||
${entities.map((entityId) => {
|
||||
const domain = computeDomain(entityId);
|
||||
${entities.map((entity) => {
|
||||
const domain = computeDomain(entity.entity_id);
|
||||
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>
|
||||
${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>
|
||||
`;
|
||||
})}
|
||||
@ -155,25 +172,28 @@ export class QuickBar extends LitElement {
|
||||
): CommandItem[] {
|
||||
return items
|
||||
.filter(({ text }) =>
|
||||
fuzzySequentialMatch(filter.toLowerCase(), text.toLowerCase())
|
||||
fuzzySequentialMatch(filter.toLowerCase(), [text.toLowerCase()])
|
||||
)
|
||||
.sort((itemA, itemB) => compare(itemA.text, itemB.text));
|
||||
}
|
||||
|
||||
private _filterEntityItems(
|
||||
entityIds: HassEntity["entity_id"][],
|
||||
filter: string
|
||||
): HassEntity["entity_id"][] {
|
||||
return entityIds
|
||||
.filter((entityId) =>
|
||||
fuzzySequentialMatch(filter.toLowerCase(), entityId)
|
||||
private _filterEntityItems(filter: string): HassEntity[] {
|
||||
return this._entities
|
||||
.filter(({ entity_id, attributes: { friendly_name } }) => {
|
||||
const values = [entity_id];
|
||||
if (friendly_name) {
|
||||
values.push(friendly_name);
|
||||
}
|
||||
return fuzzySequentialMatch(filter.toLowerCase(), values);}
|
||||
)
|
||||
.sort();
|
||||
.sort((entityA, entityB) =>
|
||||
compare(entityA.entity_id, entityB.entity_id)
|
||||
);
|
||||
}
|
||||
|
||||
private async _processItemAndCloseDialog(ev: SingleSelectedEvent) {
|
||||
const index = ev.detail.index;
|
||||
const item = (ev.target as any).items[index].item;
|
||||
const _index = ev.detail.index;
|
||||
const item = (ev.target as any).items[_index].item;
|
||||
|
||||
await this.hass.callService(item.domain, item.service, item.serviceData);
|
||||
|
||||
@ -181,10 +201,11 @@ export class QuickBar extends LitElement {
|
||||
}
|
||||
|
||||
private _entityMoreInfo(ev: SingleSelectedEvent) {
|
||||
const index = ev.detail.index;
|
||||
const entityId = (ev.target as any).items[index].entityId;
|
||||
const _index = ev.detail.index;
|
||||
const entityId = (ev.target as any).items[_index].entityId;
|
||||
|
||||
fireEvent(this, "hass-more-info", { entityId });
|
||||
|
||||
this.closeDialog();
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ import { assert } from "chai";
|
||||
import { fuzzySequentialMatch } from "../../../src/common/string/sequence_matching";
|
||||
|
||||
describe("fuzzySequentialMatch", () => {
|
||||
const entityId = "automation.ticker";
|
||||
const entity = { entity_id: "automation.ticker", friendly_name: "Stocks" };
|
||||
|
||||
const shouldMatchEntity = [
|
||||
"",
|
||||
@ -23,6 +23,9 @@ describe("fuzzySequentialMatch", () => {
|
||||
"uoaintce",
|
||||
"au.tce",
|
||||
"tomaontkr",
|
||||
"s",
|
||||
"stocks",
|
||||
"sks",
|
||||
];
|
||||
|
||||
const shouldNotMatchEntity = [
|
||||
@ -32,19 +35,27 @@ describe("fuzzySequentialMatch", () => {
|
||||
"automation. ticke",
|
||||
"1",
|
||||
"noitamotua",
|
||||
"autostocks",
|
||||
"stox",
|
||||
];
|
||||
|
||||
describe(`Entity '${entityId}'`, () => {
|
||||
describe(`Entity '${entity.entity_id}'`, () => {
|
||||
for (const goodFilter of shouldMatchEntity) {
|
||||
it(`matches with '${goodFilter}'`, () => {
|
||||
const res = fuzzySequentialMatch(goodFilter, entityId);
|
||||
const res = fuzzySequentialMatch(goodFilter, [
|
||||
entity.entity_id,
|
||||
entity.friendly_name.toLowerCase(),
|
||||
]);
|
||||
assert.equal(res, true);
|
||||
});
|
||||
}
|
||||
|
||||
for (const badFilter of shouldNotMatchEntity) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user