Create helpers from automation editor (#19287)

* Create helpers from automation editor

* support multiple createDomains

* localization

* fix lint

* Move multi domain to entity picker

* Update dialog-helper-detail.ts

* Update ha-config-helpers.ts

* optimize a little

---------

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
karwosts
2024-04-12 11:38:39 -07:00
committed by GitHub
parent 0118a5bf4c
commit 178feb7330
8 changed files with 268 additions and 169 deletions

View File

@@ -18,6 +18,12 @@ import "../ha-icon-button";
import "../ha-svg-icon";
import "./state-badge";
import { caseInsensitiveStringCompare } from "../../common/string/compare";
import { showHelperDetailDialog } from "../../panels/config/helpers/show-dialog-helper-detail";
import { domainToName } from "../../data/integration";
import {
isHelperDomain,
HelperDomain,
} from "../../panels/config/helpers/const";
interface HassEntityWithCachedName extends HassEntity, ScorableTextItem {
friendly_name: string;
@@ -25,6 +31,8 @@ interface HassEntityWithCachedName extends HassEntity, ScorableTextItem {
export type HaEntityPickerEntityFilterFunc = (entity: HassEntity) => boolean;
const CREATE_ID = "___create-new-entity___";
@customElement("ha-entity-picker")
export class HaEntityPicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -44,6 +52,8 @@ export class HaEntityPicker extends LitElement {
@property() public helper?: string;
@property({ type: Array }) public createDomains?: string[];
/**
* Show entities from specific domains.
* @type {Array}
@@ -130,7 +140,11 @@ export class HaEntityPicker extends LitElement {
></state-badge>`
: ""}
<span>${item.friendly_name}</span>
<span slot="secondary">${item.entity_id}</span>
<span slot="secondary"
>${item.entity_id.startsWith(CREATE_ID)
? this.hass.localize("ui.components.entity.entity-picker.new_entity")
: item.entity_id}</span
>
</ha-list-item>`;
private _getStates = memoizeOne(
@@ -143,7 +157,8 @@ export class HaEntityPicker extends LitElement {
includeDeviceClasses: this["includeDeviceClasses"],
includeUnitOfMeasurement: this["includeUnitOfMeasurement"],
includeEntities: this["includeEntities"],
excludeEntities: this["excludeEntities"]
excludeEntities: this["excludeEntities"],
createDomains: this["createDomains"]
): HassEntityWithCachedName[] => {
let states: HassEntityWithCachedName[] = [];
@@ -152,6 +167,34 @@ export class HaEntityPicker extends LitElement {
}
let entityIds = Object.keys(hass.states);
const createItems = createDomains?.length
? createDomains.map((domain) => {
const newFriendlyName = hass.localize(
"ui.components.entity.entity-picker.create_helper",
{
domain: isHelperDomain(domain)
? hass.localize(
`ui.panel.config.helpers.types.${domain as HelperDomain}`
)
: domainToName(hass.localize, domain),
}
);
return {
entity_id: CREATE_ID + domain,
state: "on",
last_changed: "",
last_updated: "",
context: { id: "", user_id: null, parent_id: null },
friendly_name: newFriendlyName,
attributes: {
icon: "mdi:plus",
},
strings: [domain, newFriendlyName],
};
})
: [];
if (!entityIds.length) {
return [
{
@@ -171,6 +214,7 @@ export class HaEntityPicker extends LitElement {
},
strings: [],
},
...createItems,
];
}
@@ -281,9 +325,14 @@ export class HaEntityPicker extends LitElement {
},
strings: [],
},
...createItems,
];
}
if (createItems?.length) {
states.push(...createItems);
}
return states;
}
);
@@ -310,13 +359,18 @@ export class HaEntityPicker extends LitElement {
this.includeDeviceClasses,
this.includeUnitOfMeasurement,
this.includeEntities,
this.excludeEntities
this.excludeEntities,
this.createDomains
);
if (this._initedStates) {
this.comboBox.filteredItems = this._states;
}
this._initedStates = true;
}
if (changedProps.has("createDomains") && this.createDomains?.length) {
this.hass.loadFragmentTranslation("config");
}
}
protected render(): TemplateResult {
@@ -354,6 +408,18 @@ export class HaEntityPicker extends LitElement {
private _valueChanged(ev: ValueChangedEvent<string>) {
ev.stopPropagation();
const newValue = ev.detail.value;
if (newValue.startsWith(CREATE_ID)) {
const domain = newValue.substring(CREATE_ID.length);
showHelperDetailDialog(this, {
domain,
dialogClosedCallback: (item) => {
if (item.entityId) this._setValue(item.entityId);
},
});
return;
}
if (newValue !== this._value) {
this._setValue(newValue);
}