Compare commits

..
Author SHA1 Message Date
Petar Petrov b07a0b5a37 Drop hass from the label pickers
The label registry helpers take callWS, so ha-label-picker, ha-labels-picker and ha-selector-label read their data from contexts.
2026-10-26 17:54:36 +02:00
20 changed files with 203 additions and 187 deletions

No files matched your search

@@ -1,27 +1,17 @@
import type { HassEntity } from "home-assistant-js-websocket";
import { LitElement, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { LitElement, html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
import { ensureArray } from "../../common/array/ensure-array";
import { consume } from "../../common/decorators/consume";
import {
consumeEntityStates,
consumeLocalize,
} from "../../common/decorators/consume-context-entry";
import { transform } from "../../common/decorators/transform";
import { fireEvent } from "../../common/dom/fire_event";
import type { LocalizeFunc } from "../../common/translations/localize";
import { formattersContext } from "../../data/context";
import type { HomeAssistantFormatters, ValueChangedEvent } from "../../types";
import type { HomeAssistant, ValueChangedEvent } from "../../types";
import "../ha-generic-picker";
import type { PickerComboBoxItem } from "../ha-picker-combo-box";
import type { PickerValueRenderer } from "../ha-picker-field";
type FormatEntityAttributeName =
HomeAssistantFormatters["formatEntityAttributeName"];
@customElement("ha-entity-attribute-picker")
class HaEntityAttributePicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public entityId?: string | string[];
/**
@@ -48,32 +38,18 @@ class HaEntityAttributePicker extends LitElement {
@property() public helper?: string;
@state()
@consumeEntityStates({ entityIdPath: ["entityId"] })
private _stateObjs?: Record<string, HassEntity>;
@state()
@consume({ context: formattersContext, subscribe: true })
@transform<HomeAssistantFormatters, FormatEntityAttributeName>({
transformer: (formatters) => formatters?.formatEntityAttributeName,
})
private _formatEntityAttributeName!: FormatEntityAttributeName;
@state() @consumeLocalize() private _localize!: LocalizeFunc;
private _getItemsMemoized = memoizeOne(
(
entityId: string | string[] | undefined,
stateObjs: Record<string, HassEntity> | undefined,
hideAttributes: string[] | undefined,
formatEntityAttributeName: FormatEntityAttributeName
hass: HomeAssistant
): PickerComboBoxItem[] => {
const entityIds = entityId ? ensureArray(entityId) : [];
const options: PickerComboBoxItem[] = [];
const optionsSet = new Set<string>();
for (const id of entityIds) {
const stateObj = stateObjs?.[id];
const stateObj = hass.states[id];
if (!stateObj) {
continue;
}
@@ -87,7 +63,7 @@ class HaEntityAttributePicker extends LitElement {
optionsSet.add(attribute);
options.push({
id: attribute,
primary: formatEntityAttributeName(stateObj, attribute),
primary: hass.formatEntityAttributeName(stateObj, attribute),
sorting_label: attribute,
});
}
@@ -99,28 +75,19 @@ class HaEntityAttributePicker extends LitElement {
);
private _getItems = () =>
this._getItemsMemoized(
this.entityId,
this._stateObjs,
this.hideAttributes,
this._formatEntityAttributeName
);
private _valueRenderer = memoizeOne(
(items: PickerComboBoxItem[]): PickerValueRenderer =>
(value: string) => {
const item = items.find((option) => option.id === value);
return html`<span slot="headline">${item?.primary ?? value}</span>`;
}
);
this._getItemsMemoized(this.entityId, this.hideAttributes, this.hass);
protected render() {
if (!this.hass) {
return nothing;
}
return html`
<ha-generic-picker
.value=${this.value}
.label=${
this.label ??
this._localize(
this.hass.localize(
"ui.components.entity.entity-attribute-picker.attribute"
)
}
@@ -129,13 +96,19 @@ class HaEntityAttributePicker extends LitElement {
.helper=${this.helper}
.allowCustomValue=${this.allowCustomValue}
.getItems=${this._getItems}
.valueRenderer=${this._valueRenderer(this._getItems())}
.valueRenderer=${this._valueRenderer}
@value-changed=${this._valueChanged}
>
</ha-generic-picker>
`;
}
private _valueRenderer: PickerValueRenderer = (value: string) => {
const items = this._getItems();
const item = items.find((option) => option.id === value);
return html`<span slot="headline">${item?.primary ?? value}</span>`;
};
private _valueChanged(ev: ValueChangedEvent<string>) {
ev.stopPropagation();
const newValue = ev.detail.value;
@@ -1,27 +1,18 @@
import type { ContextType } from "@lit/context";
import { mdiDragHorizontalVariant, mdiPlus } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import { css, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { customElement, property, query } from "lit/decorators";
import { repeat } from "lit/directives/repeat";
import memoizeOne from "memoize-one";
import { ensureArray } from "../../common/array/ensure-array";
import { consume } from "../../common/decorators/consume";
import {
consumeEntityState,
consumeLocalize,
} from "../../common/decorators/consume-context-entry";
import { transform } from "../../common/decorators/transform";
import { fireEvent } from "../../common/dom/fire_event";
import { computeDomain } from "../../common/entity/compute_domain";
import { getEntityContext } from "../../common/entity/context/get_entity_context";
import type { LocalizeFunc } from "../../common/translations/localize";
import { formattersContext, registriesContext } from "../../data/context";
import {
STATE_DISPLAY_SPECIAL_CONTENT,
STATE_DISPLAY_SPECIAL_CONTENT_DOMAINS,
} from "../../state-display/state-display";
import type { HomeAssistantFormatters, ValueChangedEvent } from "../../types";
import type { HomeAssistant, ValueChangedEvent } from "../../types";
import "../chips/ha-assist-chip";
import "../chips/ha-chip-set";
import "../chips/ha-input-chip";
@@ -88,11 +79,10 @@ const HIDDEN_ATTRIBUTES = [
"wind_speed_unit",
];
type FormatEntityAttributeName =
HomeAssistantFormatters["formatEntityAttributeName"];
@customElement("ha-entity-state-content-picker")
export class HaStateContentPicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public entityId?: string;
// eslint-disable-next-line lit/no-native-attributes
@@ -116,48 +106,34 @@ export class HaStateContentPicker extends LitElement {
@query("ha-generic-picker", true) private _picker?: HaGenericPicker;
@state()
@consumeEntityState({ entityIdPath: ["entityId"] })
private _stateObj?: HassEntity;
@state()
@consume({ context: registriesContext, subscribe: true })
private _registries!: ContextType<typeof registriesContext>;
@state()
@consume({ context: formattersContext, subscribe: true })
@transform<HomeAssistantFormatters, FormatEntityAttributeName>({
transformer: (formatters) => formatters?.formatEntityAttributeName,
})
private _formatEntityAttributeName!: FormatEntityAttributeName;
@state() @consumeLocalize() private _localize!: LocalizeFunc;
private _editIndex?: number;
private _getItems = memoizeOne(
(
entityId: string | undefined,
stateObj: HassEntity | undefined,
allowName: boolean,
allowContext: boolean,
localize: LocalizeFunc,
registries: ContextType<typeof registriesContext>,
formatEntityAttributeName: FormatEntityAttributeName
entityId?: string,
stateObj?: HassEntity,
allowName?: boolean,
allowContext?: boolean
) => {
const domain = entityId ? computeDomain(entityId) : undefined;
const items: PickerComboBoxItem[] = [
{
id: "state",
primary: localize("ui.components.state-content-picker.state"),
sorting_label: localize("ui.components.state-content-picker.state"),
primary: this.hass.localize(
"ui.components.state-content-picker.state"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.state"
),
},
...(allowName
? [
{
id: "name",
primary: localize("ui.components.state-content-picker.name"),
sorting_label: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.name"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.name"
),
} satisfies PickerComboBoxItem,
@@ -165,15 +141,19 @@ export class HaStateContentPicker extends LitElement {
: []),
{
id: "last_changed",
primary: localize("ui.components.state-content-picker.last_changed"),
sorting_label: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.last_changed"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.last_changed"
),
},
{
id: "last_updated",
primary: localize("ui.components.state-content-picker.last_updated"),
sorting_label: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.last_updated"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.last_updated"
),
},
@@ -181,19 +161,19 @@ export class HaStateContentPicker extends LitElement {
? (() => {
const context = getEntityContext(
stateObj,
registries.entities,
registries.devices,
registries.areas,
registries.floors
this.hass.entities,
this.hass.devices,
this.hass.areas,
this.hass.floors
);
const contextItems: PickerComboBoxItem[] = [];
if (context.device) {
contextItems.push({
id: "device_name",
primary: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.device_name"
),
sorting_label: localize(
sorting_label: this.hass.localize(
"ui.components.state-content-picker.device_name"
),
});
@@ -201,10 +181,10 @@ export class HaStateContentPicker extends LitElement {
if (context.parentDevice) {
contextItems.push({
id: "parent_device_name",
primary: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.parent_device_name"
),
sorting_label: localize(
sorting_label: this.hass.localize(
"ui.components.state-content-picker.parent_device_name"
),
});
@@ -212,10 +192,10 @@ export class HaStateContentPicker extends LitElement {
if (context.area) {
contextItems.push({
id: "area_name",
primary: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.area_name"
),
sorting_label: localize(
sorting_label: this.hass.localize(
"ui.components.state-content-picker.area_name"
),
});
@@ -223,10 +203,10 @@ export class HaStateContentPicker extends LitElement {
if (context.floor) {
contextItems.push({
id: "floor_name",
primary: localize(
primary: this.hass.localize(
"ui.components.state-content-picker.floor_name"
),
sorting_label: localize(
sorting_label: this.hass.localize(
"ui.components.state-content-picker.floor_name"
),
});
@@ -241,10 +221,10 @@ export class HaStateContentPicker extends LitElement {
(content) =>
({
id: content,
primary: localize(
primary: this.hass.localize(
`ui.components.state-content-picker.${content}`
),
sorting_label: localize(
sorting_label: this.hass.localize(
`ui.components.state-content-picker.${content}`
),
}) satisfies PickerComboBoxItem
@@ -256,8 +236,14 @@ export class HaStateContentPicker extends LitElement {
(attribute) =>
({
id: attribute,
primary: formatEntityAttributeName(stateObj!, attribute),
sorting_label: formatEntityAttributeName(stateObj!, attribute),
primary: this.hass.formatEntityAttributeName(
stateObj!,
attribute
),
sorting_label: this.hass.formatEntityAttributeName(
stateObj!,
attribute
),
}) satisfies PickerComboBoxItem
),
];
@@ -265,21 +251,13 @@ export class HaStateContentPicker extends LitElement {
}
);
private _items() {
return this._getItems(
this.entityId,
this._stateObj,
this.allowName,
this.allowContext,
this._localize,
this._registries,
this._formatEntityAttributeName
);
}
protected render() {
const value = this._value;
const stateObj = this.entityId
? this.hass.states[this.entityId]
: undefined;
return html`
${this.label ? html`<label>${this.label}</label>` : nothing}
<ha-generic-picker
@@ -304,7 +282,7 @@ export class HaStateContentPicker extends LitElement {
this._value,
(item) => item,
(item: string, idx) => {
const label = this._getItemLabel(item);
const label = this._getItemLabel(item, stateObj);
const isValid = !!label;
return html`
<ha-input-chip
@@ -331,7 +309,7 @@ export class HaStateContentPicker extends LitElement {
<ha-assist-chip
@click=${this._addItem}
.disabled=${this.disabled}
label=${this._localize(
label=${this.hass.localize(
"ui.components.entity.entity-state-content-picker.add"
)}
class="add"
@@ -376,9 +354,20 @@ export class HaStateContentPicker extends LitElement {
return !this.value ? [] : ensureArray(this.value);
}
private _getItemLabel(value: string): string | undefined {
return this._items().find((item) => item.id === value)?.primary;
}
private _getItemLabel = memoizeOne(
(value: string, stateObj?: HassEntity): string | undefined => {
const stateObjForItems = this.entityId
? this.hass.states[this.entityId]
: stateObj;
const items = this._getItems(
this.entityId,
stateObjForItems,
this.allowName,
this.allowContext
);
return items.find((item) => item.id === value)?.primary;
}
);
private _toValue = memoizeOne((value: string[]): typeof this.value => {
if (value.length === 0) {
@@ -398,9 +387,9 @@ export class HaStateContentPicker extends LitElement {
}
private _customValueOption = memoizeOne(
(text: string, localize: LocalizeFunc): PickerComboBoxItem => ({
(text: string): PickerComboBoxItem => ({
id: text,
primary: localize(
primary: this.hass.localize(
"ui.components.entity.entity-state-content-picker.custom_attribute"
),
secondary: `"${text}"`,
@@ -414,7 +403,15 @@ export class HaStateContentPicker extends LitElement {
);
private _getFilteredItems = (): PickerComboBoxItem[] => {
const items = this._items();
const stateObj = this.entityId
? this.hass.states[this.entityId]
: undefined;
const items = this._getItems(
this.entityId,
stateObj,
this.allowName,
this.allowContext
);
const currentValue =
this._editIndex != null ? this._value[this._editIndex] : undefined;
@@ -426,7 +423,7 @@ export class HaStateContentPicker extends LitElement {
// When editing an existing custom value, include it in the base items
if (currentValue && !items.find((item) => item.id === currentValue)) {
filteredItems.push(this._customValueOption(currentValue, this._localize));
filteredItems.push(this._customValueOption(currentValue));
}
return filteredItems;
@@ -435,13 +432,21 @@ export class HaStateContentPicker extends LitElement {
private _getAdditionalItems = (
searchString?: string
): PickerComboBoxItem[] => {
const items = this._items();
const stateObj = this.entityId
? this.hass.states[this.entityId]
: undefined;
const items = this._getItems(
this.entityId,
stateObj,
this.allowName,
this.allowContext
);
// If the search string does not match with the id of any of the items,
// offer to add it as a custom attribute
const existingItem = items.find((item) => item.id === searchString);
if (searchString && !existingItem) {
return [this._customValueOption(searchString, this._localize)];
return [this._customValueOption(searchString)];
}
return [];
+45 -19
View File
@@ -1,3 +1,4 @@
import type { ContextType } from "@lit/context";
import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize";
import { mdiPlus } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
@@ -15,7 +16,13 @@ import memoizeOne from "memoize-one";
import { consume } from "../common/decorators/consume";
import { computeCssColor } from "../common/color/compute-color";
import { fireEvent } from "../common/dom/fire_event";
import { labelsContext } from "../data/context";
import {
apiContext,
internationalizationContext,
labelsContext,
registriesContext,
statesContext,
} from "../data/context";
import {
getLabels,
labelComboBoxKeys,
@@ -27,7 +34,7 @@ import {
} from "../data/label/label_registry";
import { showAlertDialog } from "../dialogs/generic/show-dialog-box";
import { showLabelDetailDialog } from "../panels/config/labels/show-dialog-label-detail";
import type { HomeAssistant, ValueChangedEvent } from "../types";
import type { ValueChangedEvent } from "../types";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./ha-generic-picker";
import type { HaGenericPicker } from "./ha-generic-picker";
@@ -53,8 +60,6 @@ export const renderLabelColorBadge = (color: string | undefined) =>
@customElement("ha-label-picker")
export class HaLabelPicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public label?: string;
@property() public value?: string;
@@ -112,6 +117,19 @@ export class HaLabelPicker extends LitElement {
@state()
private _labels?: LabelRegistryEntry[];
@state()
@consume({ context: internationalizationContext, subscribe: true })
private _i18n!: ContextType<typeof internationalizationContext>;
@consume({ context: statesContext, subscribe: true })
private _states?: ContextType<typeof statesContext>;
@consume({ context: registriesContext, subscribe: true })
private _registries?: ContextType<typeof registriesContext>;
@consume({ context: apiContext, subscribe: true })
private _api!: ContextType<typeof apiContext>;
@queryAssignedElements({ flatten: true })
private _slotNodes?: NodeListOf<HTMLElement>;
@@ -149,12 +167,16 @@ export class HaLabelPicker extends LitElement {
private _getLabelsMemoized = memoizeOne(getLabels);
private _getItems = () =>
this._getLabelsMemoized(
this.hass.states,
this.hass.areas,
this.hass.devices,
this.hass.entities,
private _getItems = () => {
const { areas, devices, entities } = this._registries ?? {};
if (!this._states || !areas || !devices || !entities) {
return [];
}
return this._getLabelsMemoized(
this._states,
areas,
devices,
entities,
this._labels,
this.includeDomains,
this.excludeDomains,
@@ -163,6 +185,7 @@ export class HaLabelPicker extends LitElement {
this.entityFilter,
this.excludeLabels
);
};
private _allLabelNames = memoizeOne((labels?: LabelRegistryEntry[]) => {
if (!labels) {
@@ -190,7 +213,7 @@ export class HaLabelPicker extends LitElement {
return [
{
id: ADD_NEW_ID + searchString,
primary: this.hass.localize(
primary: this._i18n.localize(
"ui.components.label-picker.add_new_suggestion",
{
name: searchString,
@@ -204,7 +227,7 @@ export class HaLabelPicker extends LitElement {
return [
{
id: ADD_NEW_ID,
primary: this.hass.localize("ui.components.label-picker.add_new"),
primary: this._i18n.localize("ui.components.label-picker.add_new"),
icon_path: mdiPlus,
},
];
@@ -213,7 +236,7 @@ export class HaLabelPicker extends LitElement {
protected render(): TemplateResult {
const placeholder =
this.placeholder ??
this.hass.localize("ui.components.label-picker.label");
this._i18n.localize("ui.components.label-picker.label");
return html`
<ha-generic-picker
@@ -222,10 +245,10 @@ export class HaLabelPicker extends LitElement {
.label=${this.label}
.helper=${this.helper}
.notFoundLabel=${this._notFoundLabel}
.emptyLabel=${this.hass.localize(
.emptyLabel=${this._i18n.localize(
"ui.components.label-picker.no_labels"
)}
.addButtonLabel=${this.hass.localize("ui.components.label-picker.add")}
.addButtonLabel=${this._i18n.localize("ui.components.label-picker.add")}
.placeholder=${placeholder}
.value=${this.value}
.getItems=${this._getItems}
@@ -253,7 +276,7 @@ export class HaLabelPicker extends LitElement {
}
if (value.startsWith(ADD_NEW_ID)) {
this.hass.loadFragmentTranslation("config");
this._i18n.loadFragmentTranslation("config");
const suggestedName = value.substring(ADD_NEW_ID.length);
@@ -261,7 +284,10 @@ export class HaLabelPicker extends LitElement {
suggestedName: suggestedName,
createEntry: async (values) => {
try {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(
this._api.callWS,
values
);
if (this._labels?.some((l) => l.label_id === label.label_id)) {
this._setValue(label.label_id);
} else {
@@ -269,7 +295,7 @@ export class HaLabelPicker extends LitElement {
}
} catch (err: any) {
showAlertDialog(this, {
title: this.hass.localize(
title: this._i18n.localize(
"ui.components.label-picker.failed_create_label"
),
text: err.message,
@@ -292,7 +318,7 @@ export class HaLabelPicker extends LitElement {
}
private _notFoundLabel = (search: string) =>
this.hass.localize("ui.components.label-picker.no_match", {
this._i18n.localize("ui.components.label-picker.no_match", {
term: html`<b>‘${search}’</b>`,
});
+21 -8
View File
@@ -1,3 +1,4 @@
import type { ContextType } from "@lit/context";
import { mdiPlaylistPlus } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import type { TemplateResult } from "lit";
@@ -8,11 +9,15 @@ import memoizeOne from "memoize-one";
import { consume } from "../common/decorators/consume";
import { fireEvent } from "../common/dom/fire_event";
import { stringCompare } from "../common/string/compare";
import { labelsContext } from "../data/context";
import {
apiContext,
internationalizationContext,
labelsContext,
} from "../data/context";
import type { LabelRegistryEntry } from "../data/label/label_registry";
import { updateLabelRegistryEntry } from "../data/label/label_registry";
import { showLabelDetailDialog } from "../panels/config/labels/show-dialog-label-detail";
import type { HomeAssistant, ValueChangedEvent } from "../types";
import type { ValueChangedEvent } from "../types";
import "./chips/ha-chip-set";
import "./chips/ha-input-chip";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
@@ -23,8 +28,6 @@ import "./ha-tooltip";
@customElement("ha-labels-picker")
export class HaLabelsPicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public label?: string;
@property({ attribute: false }) public value?: string[];
@@ -82,6 +85,13 @@ export class HaLabelsPicker extends LitElement {
@state()
private _labels?: LabelRegistryEntry[];
@state()
@consume({ context: internationalizationContext, subscribe: true })
private _i18n!: ContextType<typeof internationalizationContext>;
@consume({ context: apiContext, subscribe: true })
private _api!: ContextType<typeof apiContext>;
@query("ha-label-picker", true) public labelPicker!: HaLabelPicker;
public async open() {
@@ -114,12 +124,11 @@ export class HaLabelsPicker extends LitElement {
const labels = this._sortedLabels(
this.value,
this._labels,
this.hass.locale.language
this._i18n.locale.language
);
return html`
${this.label ? html`<label>${this.label}</label>` : nothing}
<ha-label-picker
.hass=${this.hass}
.helper=${this.helper}
.disabled=${this.disabled}
.required=${this.required}
@@ -175,7 +184,7 @@ export class HaLabelsPicker extends LitElement {
.disabled=${this.disabled}
>
<ha-svg-icon .path=${mdiPlaylistPlus} slot="start"></ha-svg-icon>
${this.hass.localize("ui.components.label-picker.add")}
${this._i18n.localize("ui.components.label-picker.add")}
</ha-button>
</ha-chip-set>
</ha-label-picker>
@@ -196,7 +205,11 @@ export class HaLabelsPicker extends LitElement {
showLabelDetailDialog(this, {
entry: label,
updateEntry: async (values) => {
await updateLabelRegistryEntry(this.hass, label.label_id, values);
await updateLabelRegistryEntry(
this._api.callWS,
label.label_id,
values
);
},
});
}
@@ -6,10 +6,13 @@ import { ensureArray } from "../../common/array/ensure-array";
import { consumeEntityStates } from "../../common/decorators/consume-context-entry";
import { fireEvent } from "../../common/dom/fire_event";
import type { AttributeSelector } from "../../data/selector";
import type { HomeAssistant } from "../../types";
import "../entity/ha-entity-attribute-picker";
@customElement("ha-selector-attribute")
export class HaSelectorAttribute extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public selector!: AttributeSelector;
@property() public value?: any;
@@ -33,6 +36,7 @@ export class HaSelectorAttribute extends LitElement {
protected render() {
return html`
<ha-entity-attribute-picker
.hass=${this.hass}
.entityId=${
this.selector.attribute?.entity_id || this.context?.filter_entity
}
@@ -3,13 +3,10 @@ import { customElement, property } from "lit/decorators";
import { ensureArray } from "../../common/array/ensure-array";
import { fireEvent } from "../../common/dom/fire_event";
import type { LabelSelector } from "../../data/selector";
import type { HomeAssistant } from "../../types";
import "../ha-labels-picker";
@customElement("ha-selector-label")
export class HaLabelSelector extends LitElement {
@property({ attribute: false }) public hass?: HomeAssistant;
@property() public value?: string | string[];
@property() public name?: string;
@@ -31,7 +28,6 @@ export class HaLabelSelector extends LitElement {
return html`
<ha-labels-picker
no-add
.hass=${this.hass}
.value=${ensureArray(this.value ?? [])}
.required=${this.required}
.disabled=${this.disabled}
@@ -45,7 +41,6 @@ export class HaLabelSelector extends LitElement {
return html`
<ha-label-picker
no-add
.hass=${this.hass}
.value=${this.value}
.required=${this.required}
.disabled=${this.disabled}
@@ -1,10 +1,14 @@
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import type { UiStateContentSelector } from "../../data/selector";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../types";
import "../entity/ha-entity-state-content-picker";
@customElement("ha-selector-ui_state_content")
export class HaSelectorUiStateContent extends LitElement {
export class HaSelectorUiStateContent extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public selector!: UiStateContentSelector;
@property() public value?: string | string[];
@@ -24,6 +28,7 @@ export class HaSelectorUiStateContent extends LitElement {
protected render() {
return html`
<ha-entity-state-content-picker
.hass=${this.hass}
.entityId=${
this.selector.ui_state_content?.entity_id ||
this.context?.filter_entity
+6 -6
View File
@@ -61,30 +61,30 @@ export const subscribeLabelRegistry = (
);
export const createLabelRegistryEntry = (
hass: HomeAssistant,
callWS: HomeAssistant["callWS"],
values: LabelRegistryEntryMutableParams
) =>
hass.callWS<LabelRegistryEntry>({
callWS<LabelRegistryEntry>({
type: "config/label_registry/create",
...values,
});
export const updateLabelRegistryEntry = (
hass: HomeAssistant,
callWS: HomeAssistant["callWS"],
labelId: string,
updates: Partial<LabelRegistryEntryMutableParams>
) =>
hass.callWS<LabelRegistryEntry>({
callWS<LabelRegistryEntry>({
type: "config/label_registry/update",
label_id: labelId,
...updates,
});
export const deleteLabelRegistryEntry = (
hass: HomeAssistant,
callWS: HomeAssistant["callWS"],
labelId: string
) =>
hass.callWS({
callWS({
type: "config/label_registry/delete",
label_id: labelId,
});
@@ -204,7 +204,6 @@ class DialogAreaDetail
<ha-labels-picker
.label=${this.hass.localize("ui.components.label-picker.labels")}
.hass=${this.hass}
.value=${this._labels}
@value-changed=${this._labelsChanged}
.placeholder=${this.hass.localize(
@@ -218,7 +218,6 @@ class DialogAutomationSave
this._visibleOptionals.includes("labels")
? html` <ha-labels-picker
id="labels"
.hass=${this.hass}
.value=${this._entryUpdates.labels}
@value-changed=${this._registryEntryChanged}
></ha-labels-picker>`
@@ -1416,7 +1416,7 @@ ${rejected
private _bulkCreateLabel = () => {
showLabelDetailDialog(this, {
createEntry: async (values) => {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(this.hass.callWS, values);
this._bulkLabel(label.label_id, "add");
},
});
@@ -114,7 +114,6 @@ class DialogDeviceRegistryDetail extends DirtyStateProviderMixin<DeviceFormState
@value-changed=${this._areaPicked}
></ha-area-picker>
<ha-labels-picker
.hass=${this.hass}
.value=${this._labels}
@value-changed=${this._labelsChanged}
></ha-labels-picker>
@@ -1247,7 +1247,7 @@ ${rejected
private _bulkCreateLabel = () => {
showLabelDetailDialog(this, {
createEntry: async (values) => {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(this.hass.callWS, values);
this._bulkLabel(label.label_id, "add");
},
});
@@ -990,7 +990,6 @@ export class EntityRegistrySettingsEditor extends LitElement {
: nothing
}
<ha-labels-picker
.hass=${this.hass}
.value=${this._labels}
.disabled=${!!this.disabled}
@value-changed=${this._labelsChanged}
@@ -1447,7 +1447,7 @@ ${rejected
private _bulkCreateLabel = () => {
showLabelDetailDialog(this, {
createEntry: async (values) => {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(this.hass.callWS, values);
this._bulkLabel(label.label_id, "add");
},
});
@@ -1563,7 +1563,7 @@ ${rejected
private _bulkCreateLabel = () => {
showLabelDetailDialog(this, {
createEntry: async (values) => {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(this.hass.callWS, values);
this._bulkLabel(label.label_id, "add");
},
});
+4 -4
View File
@@ -358,7 +358,7 @@ export class HaConfigLabels extends LitElement {
private async _createLabel(
values: LabelRegistryEntryMutableParams
): Promise<LabelRegistryEntry> {
const newTag = await createLabelRegistryEntry(this.hass, values);
const newTag = await createLabelRegistryEntry(this.hass.callWS, values);
this._labels = [...this._labels, newTag];
return newTag;
}
@@ -368,7 +368,7 @@ export class HaConfigLabels extends LitElement {
values: Partial<LabelRegistryEntryMutableParams>
): Promise<LabelRegistryEntry> {
const updated = await updateLabelRegistryEntry(
this.hass,
this.hass.callWS,
selectedLabel.label_id,
values
);
@@ -399,7 +399,7 @@ export class HaConfigLabels extends LitElement {
return false;
}
try {
await deleteLabelRegistryEntry(this.hass, selectedLabel.label_id);
await deleteLabelRegistryEntry(this.hass.callWS, selectedLabel.label_id);
this._labels = this._labels.filter(
(label) => label.label_id !== selectedLabel.label_id
);
@@ -431,7 +431,7 @@ export class HaConfigLabels extends LitElement {
action: async () => {
const results = await Promise.allSettled(
this._selected.map((labelId) =>
deleteLabelRegistryEntry(this.hass, labelId)
deleteLabelRegistryEntry(this.hass.callWS, labelId)
)
);
const deletedIds = new Set(
@@ -1158,7 +1158,7 @@ ${rejected
private _bulkCreateLabel = () => {
showLabelDetailDialog(this, {
createEntry: async (values) => {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(this.hass.callWS, values);
this._bulkLabel(label.label_id, "add");
},
});
@@ -175,7 +175,6 @@ class DialogSceneSave extends DirtyStateProviderMixin<SceneSaveState>()(
this._visibleOptionals.includes("labels")
? html` <ha-labels-picker
id="labels"
.hass=${this.hass}
.value=${this._entryUpdates.labels}
@value-changed=${this._registryEntryChanged}
></ha-labels-picker>`
+1 -1
View File
@@ -1136,7 +1136,7 @@ ${rejected
private _bulkCreateLabel = () => {
showLabelDetailDialog(this, {
createEntry: async (values) => {
const label = await createLabelRegistryEntry(this.hass, values);
const label = await createLabelRegistryEntry(this.hass.callWS, values);
this._bulkLabel(label.label_id, "add");
},
});