mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-08 02:19:43 +00:00
Fix duplicated name in entity name picker and fix missing entity id support (#27538)
This commit is contained in:
@@ -86,8 +86,8 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
|
|
||||||
private _editIndex?: number;
|
private _editIndex?: number;
|
||||||
|
|
||||||
private _validOptions = memoizeOne((entityId?: string) => {
|
private _validTypes = memoizeOne((entityId?: string) => {
|
||||||
const options = new Set<string>();
|
const options = new Set<string>(["text"]);
|
||||||
if (!entityId) {
|
if (!entityId) {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
@@ -119,22 +119,22 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const options = this._validOptions(entityId);
|
const types = this._validTypes(entityId);
|
||||||
|
|
||||||
const items = (
|
const items = (
|
||||||
["entity", "device", "area", "floor"] as const
|
["entity", "device", "area", "floor"] as const
|
||||||
).map<EntityNameOption>((name) => {
|
).map<EntityNameOption>((name) => {
|
||||||
const stateObj = this.hass.states[entityId];
|
const stateObj = this.hass.states[entityId];
|
||||||
const isValid = options.has(name);
|
const isValid = types.has(name);
|
||||||
const primary = this.hass.localize(
|
const primary = this.hass.localize(
|
||||||
`ui.components.entity.entity-name-picker.types.${name}`
|
`ui.components.entity.entity-name-picker.types.${name}`
|
||||||
);
|
);
|
||||||
const secondary =
|
const secondary =
|
||||||
stateObj && isValid
|
(stateObj && isValid
|
||||||
? this.hass.formatEntityName(stateObj, { type: name })
|
? this.hass.formatEntityName(stateObj, { type: name })
|
||||||
: this.hass.localize(
|
: this.hass.localize(
|
||||||
`ui.components.entity.entity-name-picker.types.${name}_missing` as LocalizeKeys
|
`ui.components.entity.entity-name-picker.types.${name}_missing` as LocalizeKeys
|
||||||
) || "-";
|
)) || "-";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
primary,
|
primary,
|
||||||
@@ -169,9 +169,9 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const value = this._value;
|
const value = this._items;
|
||||||
const options = this._getOptions(this.entityId);
|
const options = this._getOptions(this.entityId);
|
||||||
const validOptions = this._validOptions(this.entityId);
|
const validTypes = this._validTypes(this.entityId);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this.label ? html`<label>${this.label}</label>` : nothing}
|
${this.label ? html`<label>${this.label}</label>` : nothing}
|
||||||
@@ -185,12 +185,11 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
>
|
>
|
||||||
<ha-chip-set>
|
<ha-chip-set>
|
||||||
${repeat(
|
${repeat(
|
||||||
this._value,
|
this._items,
|
||||||
(item) => item,
|
(item) => item,
|
||||||
(item: EntityNameItem, idx) => {
|
(item: EntityNameItem, idx) => {
|
||||||
const label = this._formatItem(item);
|
const label = this._formatItem(item);
|
||||||
const isValid =
|
const isValid = validTypes.has(item.type);
|
||||||
item.type === "text" || validOptions.has(item.type);
|
|
||||||
return html`
|
return html`
|
||||||
<ha-input-chip
|
<ha-input-chip
|
||||||
data-idx=${idx}
|
data-idx=${idx}
|
||||||
@@ -238,7 +237,7 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${""}
|
.value=${""}
|
||||||
.autofocus=${this.autofocus}
|
.autofocus=${this.autofocus}
|
||||||
.disabled=${this.disabled || !this.entityId}
|
.disabled=${this.disabled}
|
||||||
.required=${this.required && !value.length}
|
.required=${this.required && !value.length}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
.items=${options}
|
.items=${options}
|
||||||
@@ -285,7 +284,7 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
this._opened = true;
|
this._opened = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private get _value(): EntityNameItem[] {
|
private get _items(): EntityNameItem[] {
|
||||||
return this._toItems(this.value);
|
return this._toItems(this.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,19 +317,21 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
const options = this._comboBox.items || [];
|
const options = this._comboBox.items || [];
|
||||||
|
|
||||||
const initialItem =
|
const initialItem =
|
||||||
this._editIndex != null ? this._value[this._editIndex] : undefined;
|
this._editIndex != null ? this._items[this._editIndex] : undefined;
|
||||||
|
|
||||||
const initialValue = initialItem ? formatOptionValue(initialItem) : "";
|
const initialValue = initialItem ? formatOptionValue(initialItem) : "";
|
||||||
|
|
||||||
const filteredItems = this._filterSelectedOptions(options, initialValue);
|
const filteredItems = this._filterSelectedOptions(options, initialValue);
|
||||||
|
|
||||||
if (initialItem && initialItem.type === "text" && initialItem.text) {
|
if (initialItem?.type === "text" && initialItem.text) {
|
||||||
filteredItems.push(this._customNameOption(initialItem.text));
|
filteredItems.push(this._customNameOption(initialItem.text));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._comboBox.filteredItems = filteredItems;
|
this._comboBox.filteredItems = filteredItems;
|
||||||
this._comboBox.setInputValue(initialValue);
|
this._comboBox.setInputValue(initialValue);
|
||||||
} else {
|
} else {
|
||||||
this._opened = false;
|
this._opened = false;
|
||||||
|
this._comboBox.setInputValue("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,15 +339,16 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
options: EntityNameOption[],
|
options: EntityNameOption[],
|
||||||
current?: string
|
current?: string
|
||||||
) => {
|
) => {
|
||||||
const value = this._value;
|
const items = this._items;
|
||||||
|
|
||||||
const types = value.map((item) => item.type) as string[];
|
const excludedValues = new Set(
|
||||||
|
items
|
||||||
|
.filter((item) => UNIQUE_TYPES.has(item.type))
|
||||||
|
.map((item) => formatOptionValue(item))
|
||||||
|
);
|
||||||
|
|
||||||
const filteredOptions = options.filter(
|
const filteredOptions = options.filter(
|
||||||
(option) =>
|
(option) => !excludedValues.has(option.value) || option.value === current
|
||||||
!UNIQUE_TYPES.has(option.value) ||
|
|
||||||
!types.includes(option.value) ||
|
|
||||||
option.value === current
|
|
||||||
);
|
);
|
||||||
return filteredOptions;
|
return filteredOptions;
|
||||||
};
|
};
|
||||||
@@ -357,16 +359,14 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
const options = this._comboBox.items || [];
|
const options = this._comboBox.items || [];
|
||||||
|
|
||||||
const currentItem =
|
const currentItem =
|
||||||
this._editIndex != null ? this._value[this._editIndex] : undefined;
|
this._editIndex != null ? this._items[this._editIndex] : undefined;
|
||||||
|
|
||||||
const currentValue = currentItem ? formatOptionValue(currentItem) : "";
|
const currentValue = currentItem ? formatOptionValue(currentItem) : "";
|
||||||
|
|
||||||
this._comboBox.filteredItems = this._filterSelectedOptions(
|
let filteredItems = this._filterSelectedOptions(options, currentValue);
|
||||||
options,
|
|
||||||
currentValue
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!filter) {
|
if (!filter) {
|
||||||
|
this._comboBox.filteredItems = filteredItems;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,9 +378,8 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
ignoreDiacritics: true,
|
ignoreDiacritics: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const fuse = new Fuse(this._comboBox.filteredItems, fuseOptions);
|
const fuse = new Fuse(filteredItems, fuseOptions);
|
||||||
const filteredItems = fuse.search(filter).map((result) => result.item);
|
filteredItems = fuse.search(filter).map((result) => result.item);
|
||||||
|
|
||||||
filteredItems.push(this._customNameOption(input));
|
filteredItems.push(this._customNameOption(input));
|
||||||
this._comboBox.filteredItems = filteredItems;
|
this._comboBox.filteredItems = filteredItems;
|
||||||
}
|
}
|
||||||
@@ -388,7 +387,7 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
private async _moveItem(ev: CustomEvent) {
|
private async _moveItem(ev: CustomEvent) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const { oldIndex, newIndex } = ev.detail;
|
const { oldIndex, newIndex } = ev.detail;
|
||||||
const value = this._value;
|
const value = this._items;
|
||||||
const newValue = value.concat();
|
const newValue = value.concat();
|
||||||
const element = newValue.splice(oldIndex, 1)[0];
|
const element = newValue.splice(oldIndex, 1)[0];
|
||||||
newValue.splice(newIndex, 0, element);
|
newValue.splice(newIndex, 0, element);
|
||||||
@@ -399,7 +398,7 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
|
|
||||||
private async _removeItem(ev) {
|
private async _removeItem(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const value = [...this._value];
|
const value = [...this._items];
|
||||||
const idx = parseInt(ev.target.dataset.idx, 10);
|
const idx = parseInt(ev.target.dataset.idx, 10);
|
||||||
value.splice(idx, 1);
|
value.splice(idx, 1);
|
||||||
this._setValue(value);
|
this._setValue(value);
|
||||||
@@ -417,7 +416,7 @@ export class HaEntityNamePicker extends LitElement {
|
|||||||
|
|
||||||
const item: EntityNameItem = parseOptionValue(value);
|
const item: EntityNameItem = parseOptionValue(value);
|
||||||
|
|
||||||
const newValue = [...this._value];
|
const newValue = [...this._items];
|
||||||
|
|
||||||
if (this._editIndex != null) {
|
if (this._editIndex != null) {
|
||||||
newValue[this._editIndex] = item;
|
newValue[this._editIndex] = item;
|
||||||
|
|||||||
Reference in New Issue
Block a user