mirror of
https://github.com/home-assistant/frontend.git
synced 2026-10-26 23:54:13 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b07a0b5a37 |
No files matched your search
@@ -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>`,
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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");
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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>`
|
||||
|
||||
@@ -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");
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user