Automation editor tweaks (#19225)

* Automation editor tweaks

* fix styling
This commit is contained in:
Bram Kragten 2024-01-02 13:36:06 +01:00 committed by GitHub
parent c650e23432
commit 52fcf64cfd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 108 additions and 42 deletions

View File

@ -46,7 +46,6 @@ export const CONDITION_GROUPS: AutomationElementGroup = {
icon: mdiDotsHorizontal,
members: {
template: {},
trigger: {},
},
},
} as const;

View File

@ -1,7 +1,14 @@
import "@material/mwc-list/mwc-list";
import { mdiClose, mdiContentPaste, mdiPlus } from "@mdi/js";
import Fuse, { IFuseOptions } from "fuse.js";
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import {
CSSResultGroup,
LitElement,
PropertyValues,
css,
html,
nothing,
} from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import { repeat } from "lit/directives/repeat";
@ -42,6 +49,8 @@ import {
AddAutomationElementDialogParams,
PASTE_VALUE,
} from "./show-add-automation-element-dialog";
import { computeDomain } from "../../../common/entity/compute_domain";
import { deepEqual } from "../../../common/util/deep-equal";
const TYPES = {
trigger: { groups: TRIGGER_GROUPS, icons: TRIGGER_ICONS },
@ -93,13 +102,15 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
@state() private _manifests?: DomainManifestLookup;
@state() private _domains?: Set<string>;
@query("ha-dialog") private _dialog?: HaDialog;
private _fullScreen = false;
private _width?: number;
@state() private _width?: number;
private _height?: number;
@state() private _height?: number;
public showDialog(params): void {
this._params = params;
@ -124,6 +135,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._prev = undefined;
this._filter = "";
this._manifests = undefined;
this._domains = undefined;
}
private _convertToItem = (
@ -152,6 +164,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getFilteredItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
root: AddAutomationElementDialogParams["root"],
group: string | undefined,
filter: string,
localize: LocalizeFunc,
@ -164,6 +177,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
: TYPES[type].groups[group].members!
: TYPES[type].groups;
if (type === "condition" && group === "other" && !root) {
groups.trigger = {};
}
const flattenGroups = (grp: AutomationElementGroup) =>
Object.entries(grp).map(([key, options]) =>
options.members
@ -191,7 +208,9 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
private _getGroupItems = memoizeOne(
(
type: AddAutomationElementDialogParams["type"],
root: AddAutomationElementDialogParams["root"],
group: string | undefined,
domains: Set<string> | undefined,
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests?: DomainManifestLookup
@ -208,6 +227,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
? TYPES[type].groups[group].members!
: TYPES[type].groups;
if (type === "condition" && group === "other" && !root) {
groups.trigger = {};
}
const result = Object.entries(groups).map(([key, options]) =>
this._convertToItem(key, options, type, localize)
);
@ -215,15 +238,33 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
if (type === "action") {
if (!this._group) {
result.unshift(
...this._serviceGroups(localize, services, manifests, undefined)
...this._serviceGroups(
localize,
services,
manifests,
domains,
undefined
)
);
} else if (this._group === "helpers") {
result.unshift(
...this._serviceGroups(localize, services, manifests, "helper")
...this._serviceGroups(
localize,
services,
manifests,
domains,
"helper"
)
);
} else if (this._group === "other") {
result.unshift(
...this._serviceGroups(localize, services, manifests, "other")
...this._serviceGroups(
localize,
services,
manifests,
domains,
"other"
)
);
}
}
@ -243,42 +284,44 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
}
);
private _serviceGroups = memoizeOne(
(
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests: DomainManifestLookup | undefined,
type: "helper" | "other" | undefined
): ListItem[] => {
if (!services || !manifests) {
return [];
}
const result: ListItem[] = [];
Object.keys(services).forEach((domain) => {
const manifest = manifests[domain];
if (
(type === undefined &&
manifest?.integration_type === "entity" &&
!ENTITY_DOMAINS_OTHER.has(domain)) ||
(type === "helper" && manifest?.integration_type === "helper") ||
(type === "other" &&
(ENTITY_DOMAINS_OTHER.has(domain) ||
!["helper", "entity"].includes(manifest?.integration_type || "")))
) {
result.push({
group: true,
icon: domainIcon(domain),
key: `${SERVICE_PREFIX}${domain}`,
name: domainToName(localize, domain, manifest),
description: "",
});
}
});
return result.sort((a, b) =>
stringCompare(a.name, b.name, this.hass.locale.language)
);
private _serviceGroups = (
localize: LocalizeFunc,
services: HomeAssistant["services"],
manifests: DomainManifestLookup | undefined,
domains: Set<string> | undefined,
type: "helper" | "other" | undefined
): ListItem[] => {
if (!services || !manifests) {
return [];
}
);
const result: ListItem[] = [];
Object.keys(services).forEach((domain) => {
const manifest = manifests[domain];
const domainUsed = !domains ? true : domains.has(domain);
if (
(type === undefined &&
manifest?.integration_type === "entity" &&
domainUsed &&
!ENTITY_DOMAINS_OTHER.has(domain)) ||
(type === "helper" && manifest?.integration_type === "helper") ||
(type === "other" &&
(ENTITY_DOMAINS_OTHER.has(domain) ||
(!domainUsed && manifest?.integration_type === "entity") ||
!["helper", "entity"].includes(manifest?.integration_type || "")))
) {
result.push({
group: true,
icon: domainIcon(domain),
key: `${SERVICE_PREFIX}${domain}`,
name: domainToName(localize, domain, manifest),
description: "",
});
}
});
return result.sort((a, b) =>
stringCompare(a.name, b.name, this.hass.locale.language)
);
};
private _services = memoizeOne(
(
@ -368,6 +411,19 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
this._height = boundingRect?.height;
}
protected willUpdate(changedProperties: PropertyValues): void {
if (
this._params?.type === "action" &&
changedProperties.has("hass") &&
changedProperties.get("hass")?.states !== this.hass.states
) {
const domains = new Set(Object.keys(this.hass.states).map(computeDomain));
if (!deepEqual(domains, this._domains)) {
this._domains = domains;
}
}
}
protected render() {
if (!this._params) {
return nothing;
@ -376,6 +432,7 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
const items = this._filter
? this._getFilteredItems(
this._params.type,
this._params.root,
this._group,
this._filter,
this.hass.localize,
@ -384,7 +441,9 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
)
: this._getGroupItems(
this._params.type,
this._params.root,
this._group,
this._domains,
this.hass.localize,
this.hass.services,
this._manifests
@ -562,6 +621,10 @@ class DialogAddAutomationElement extends LitElement implements HassDialog {
ha-icon-next {
width: 24px;
}
mwc-list {
max-height: 468px;
max-width: 100vw;
}
search-input {
display: block;
margin: 0 16px;

View File

@ -203,6 +203,7 @@ export default class HaAutomationCondition extends LitElement {
showAddAutomationElementDialog(this, {
type: "condition",
add: this._addCondition,
root: !this.nested,
clipboardItem: this._clipboard?.condition?.condition,
});
}

View File

@ -168,6 +168,7 @@ export class HaDeviceCondition extends LitElement {
}
ha-form {
display: block;
margin-top: 24px;
}
`;

View File

@ -6,6 +6,7 @@ export interface AddAutomationElementDialogParams {
type: "trigger" | "condition" | "action";
add: (key: string) => void;
clipboardItem: string | undefined;
root?: boolean;
group?: string;
}
const loadDialog = () => import("./add-automation-element-dialog");

View File

@ -174,6 +174,7 @@ export class HaDeviceTrigger extends LitElement {
}
ha-form {
display: block;
margin-top: 24px;
}
`;