mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 11:16:35 +00:00
Put item at the top of picker result if there is an exact match with entity id (#25625)
This commit is contained in:
parent
139c8b3702
commit
48a3e1fd63
@ -23,7 +23,10 @@ import type { HomeAssistant } from "../../types";
|
|||||||
import "../ha-combo-box-item";
|
import "../ha-combo-box-item";
|
||||||
import "../ha-generic-picker";
|
import "../ha-generic-picker";
|
||||||
import type { HaGenericPicker } from "../ha-generic-picker";
|
import type { HaGenericPicker } from "../ha-generic-picker";
|
||||||
import type { PickerComboBoxItem } from "../ha-picker-combo-box";
|
import type {
|
||||||
|
PickerComboBoxItem,
|
||||||
|
PickerComboBoxSearchFn,
|
||||||
|
} from "../ha-picker-combo-box";
|
||||||
import type { PickerValueRenderer } from "../ha-picker-field";
|
import type { PickerValueRenderer } from "../ha-picker-field";
|
||||||
import "../ha-svg-icon";
|
import "../ha-svg-icon";
|
||||||
import "./state-badge";
|
import "./state-badge";
|
||||||
@ -406,6 +409,7 @@ export class HaEntityPicker extends LitElement {
|
|||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
.hideClearIcon=${this.hideClearIcon}
|
.hideClearIcon=${this.hideClearIcon}
|
||||||
|
.searchFn=${this._searchFn}
|
||||||
.valueRenderer=${this._valueRenderer}
|
.valueRenderer=${this._valueRenderer}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
>
|
>
|
||||||
@ -413,6 +417,23 @@ export class HaEntityPicker extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _searchFn: PickerComboBoxSearchFn<EntityComboBoxItem> = (
|
||||||
|
search,
|
||||||
|
filteredItems
|
||||||
|
) => {
|
||||||
|
// If there is exact match for entity id, put it first
|
||||||
|
const index = filteredItems.findIndex(
|
||||||
|
(item) => item.stateObj?.entity_id === search
|
||||||
|
);
|
||||||
|
if (index === -1) {
|
||||||
|
return filteredItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [exactMatch] = filteredItems.splice(index, 1);
|
||||||
|
filteredItems.unshift(exactMatch);
|
||||||
|
return filteredItems;
|
||||||
|
};
|
||||||
|
|
||||||
public async open() {
|
public async open() {
|
||||||
await this.updateComplete;
|
await this.updateComplete;
|
||||||
await this._picker?.open();
|
await this._picker?.open();
|
||||||
|
@ -25,7 +25,10 @@ import "../ha-generic-picker";
|
|||||||
import type { HaGenericPicker } from "../ha-generic-picker";
|
import type { HaGenericPicker } from "../ha-generic-picker";
|
||||||
import "../ha-icon-button";
|
import "../ha-icon-button";
|
||||||
import "../ha-input-helper-text";
|
import "../ha-input-helper-text";
|
||||||
import type { PickerComboBoxItem } from "../ha-picker-combo-box";
|
import type {
|
||||||
|
PickerComboBoxItem,
|
||||||
|
PickerComboBoxSearchFn,
|
||||||
|
} from "../ha-picker-combo-box";
|
||||||
import type { PickerValueRenderer } from "../ha-picker-field";
|
import type { PickerValueRenderer } from "../ha-picker-field";
|
||||||
import "../ha-svg-icon";
|
import "../ha-svg-icon";
|
||||||
import "./state-badge";
|
import "./state-badge";
|
||||||
@ -470,6 +473,7 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
.getItems=${this._getItems}
|
.getItems=${this._getItems}
|
||||||
.getAdditionalItems=${this._getAdditionalItems}
|
.getAdditionalItems=${this._getAdditionalItems}
|
||||||
.hideClearIcon=${this.hideClearIcon}
|
.hideClearIcon=${this.hideClearIcon}
|
||||||
|
.searchFn=${this._searchFn}
|
||||||
.valueRenderer=${this._valueRenderer}
|
.valueRenderer=${this._valueRenderer}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
>
|
>
|
||||||
@ -477,6 +481,24 @@ export class HaStatisticPicker extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _searchFn: PickerComboBoxSearchFn<StatisticComboBoxItem> = (
|
||||||
|
search,
|
||||||
|
filteredItems
|
||||||
|
) => {
|
||||||
|
// If there is exact match for entity id or statistic id, put it first
|
||||||
|
const index = filteredItems.findIndex(
|
||||||
|
(item) =>
|
||||||
|
item.stateObj?.entity_id === search || item.statistic_id === search
|
||||||
|
);
|
||||||
|
if (index === -1) {
|
||||||
|
return filteredItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [exactMatch] = filteredItems.splice(index, 1);
|
||||||
|
filteredItems.unshift(exactMatch);
|
||||||
|
return filteredItems;
|
||||||
|
};
|
||||||
|
|
||||||
private _valueChanged(ev: ValueChangedEvent<string>) {
|
private _valueChanged(ev: ValueChangedEvent<string>) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const value = ev.detail.value;
|
const value = ev.detail.value;
|
||||||
|
@ -12,6 +12,7 @@ import "./ha-picker-combo-box";
|
|||||||
import type {
|
import type {
|
||||||
HaPickerComboBox,
|
HaPickerComboBox,
|
||||||
PickerComboBoxItem,
|
PickerComboBoxItem,
|
||||||
|
PickerComboBoxSearchFn,
|
||||||
} from "./ha-picker-combo-box";
|
} from "./ha-picker-combo-box";
|
||||||
import "./ha-picker-field";
|
import "./ha-picker-field";
|
||||||
import type { HaPickerField, PickerValueRenderer } from "./ha-picker-field";
|
import type { HaPickerField, PickerValueRenderer } from "./ha-picker-field";
|
||||||
@ -57,6 +58,9 @@ export class HaGenericPicker extends LitElement {
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
public valueRenderer?: PickerValueRenderer;
|
public valueRenderer?: PickerValueRenderer;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public searchFn?: PickerComboBoxSearchFn<PickerComboBoxItem>;
|
||||||
|
|
||||||
@property({ attribute: "not-found-label", type: String })
|
@property({ attribute: "not-found-label", type: String })
|
||||||
public notFoundLabel?: string;
|
public notFoundLabel?: string;
|
||||||
|
|
||||||
@ -102,6 +106,7 @@ export class HaGenericPicker extends LitElement {
|
|||||||
.notFoundLabel=${this.notFoundLabel}
|
.notFoundLabel=${this.notFoundLabel}
|
||||||
.getItems=${this.getItems}
|
.getItems=${this.getItems}
|
||||||
.getAdditionalItems=${this.getAdditionalItems}
|
.getAdditionalItems=${this.getAdditionalItems}
|
||||||
|
.searchFn=${this.searchFn}
|
||||||
></ha-picker-combo-box>
|
></ha-picker-combo-box>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,6 +49,12 @@ const DEFAULT_ROW_RENDERER: ComboBoxLitRenderer<PickerComboBoxItem> = (
|
|||||||
</ha-combo-box-item>
|
</ha-combo-box-item>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export type PickerComboBoxSearchFn<T extends PickerComboBoxItem> = (
|
||||||
|
search: string,
|
||||||
|
filteredItems: T[],
|
||||||
|
allItems: T[]
|
||||||
|
) => T[];
|
||||||
|
|
||||||
@customElement("ha-picker-combo-box")
|
@customElement("ha-picker-combo-box")
|
||||||
export class HaPickerComboBox extends LitElement {
|
export class HaPickerComboBox extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -84,6 +90,9 @@ export class HaPickerComboBox extends LitElement {
|
|||||||
@property({ attribute: "not-found-label", type: String })
|
@property({ attribute: "not-found-label", type: String })
|
||||||
public notFoundLabel?: string;
|
public notFoundLabel?: string;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public searchFn?: PickerComboBoxSearchFn<PickerComboBoxItem>;
|
||||||
|
|
||||||
@state() private _opened = false;
|
@state() private _opened = false;
|
||||||
|
|
||||||
@query("ha-combo-box", true) public comboBox!: HaComboBox;
|
@query("ha-combo-box", true) public comboBox!: HaComboBox;
|
||||||
@ -237,6 +246,7 @@ export class HaPickerComboBox extends LitElement {
|
|||||||
const fuse = new HaFuse(this._items, { shouldSort: false }, index);
|
const fuse = new HaFuse(this._items, { shouldSort: false }, index);
|
||||||
|
|
||||||
const results = fuse.multiTermsSearch(searchString);
|
const results = fuse.multiTermsSearch(searchString);
|
||||||
|
let filteredItems = this._items as PickerComboBoxItem[];
|
||||||
if (results) {
|
if (results) {
|
||||||
const items = results.map((result) => result.item);
|
const items = results.map((result) => result.item);
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
@ -246,10 +256,14 @@ export class HaPickerComboBox extends LitElement {
|
|||||||
}
|
}
|
||||||
const additionalItems = this._getAdditionalItems(searchString);
|
const additionalItems = this._getAdditionalItems(searchString);
|
||||||
items.push(...additionalItems);
|
items.push(...additionalItems);
|
||||||
target.filteredItems = items;
|
filteredItems = items;
|
||||||
} else {
|
|
||||||
target.filteredItems = this._items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.searchFn) {
|
||||||
|
filteredItems = this.searchFn(searchString, filteredItems, this._items);
|
||||||
|
}
|
||||||
|
|
||||||
|
target.filteredItems = filteredItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setValue(value: string | undefined) {
|
private _setValue(value: string | undefined) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user