mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Update create automation dialog (#15286)
This commit is contained in:
parent
c19cba85ec
commit
b2bfb1fdcb
@ -41,9 +41,9 @@ class HaBluePrintPicker extends LitElement {
|
||||
return [];
|
||||
}
|
||||
const result = Object.entries(blueprints)
|
||||
.filter(([_path, blueprint]) => !("error" in blueprint))
|
||||
.filter((entry): entry is [string, Blueprint] => !("error" in entry[1]))
|
||||
.map(([path, blueprint]) => ({
|
||||
...(blueprint as Blueprint).metadata,
|
||||
...blueprint.metadata,
|
||||
path,
|
||||
}));
|
||||
return result.sort((a, b) =>
|
||||
|
@ -16,6 +16,7 @@ export interface BlueprintMetaData {
|
||||
input?: Record<string, BlueprintInput | null>;
|
||||
description?: string;
|
||||
source_url?: string;
|
||||
author?: string;
|
||||
}
|
||||
|
||||
export interface BlueprintInput {
|
||||
@ -63,3 +64,19 @@ export const deleteBlueprint = (
|
||||
domain,
|
||||
path,
|
||||
});
|
||||
|
||||
export type BlueprintSourceType = "local" | "community" | "homeassistant";
|
||||
|
||||
export const getBlueprintSourceType = (
|
||||
blueprint: Blueprint
|
||||
): BlueprintSourceType => {
|
||||
const sourceUrl = blueprint.metadata.source_url;
|
||||
|
||||
if (!sourceUrl) {
|
||||
return "local";
|
||||
}
|
||||
if (sourceUrl.includes("github.com/home-assistant")) {
|
||||
return "homeassistant";
|
||||
}
|
||||
return "community";
|
||||
};
|
||||
|
@ -1,17 +1,40 @@
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import {
|
||||
mdiAccount,
|
||||
mdiFile,
|
||||
mdiHomeAssistant,
|
||||
mdiOpenInNew,
|
||||
mdiPencilOutline,
|
||||
mdiWeb,
|
||||
} from "@mdi/js";
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import "../../../components/ha-blueprint-picker";
|
||||
import "../../../components/ha-circular-progress";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event";
|
||||
import { stringCompare } from "../../../common/string/compare";
|
||||
import { createCloseHeading } from "../../../components/ha-dialog";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-tip";
|
||||
import { showAutomationEditor } from "../../../data/automation";
|
||||
import {
|
||||
Blueprint,
|
||||
Blueprints,
|
||||
BlueprintSourceType,
|
||||
fetchBlueprints,
|
||||
getBlueprintSourceType,
|
||||
} from "../../../data/blueprint";
|
||||
import { HassDialog } from "../../../dialogs/make-dialog-manager";
|
||||
import { haStyle, haStyleDialog } from "../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
|
||||
const SOURCE_TYPE_ICONS: Record<BlueprintSourceType, string> = {
|
||||
local: mdiFile,
|
||||
community: mdiAccount,
|
||||
homeassistant: mdiHomeAssistant,
|
||||
};
|
||||
|
||||
@customElement("ha-dialog-new-automation")
|
||||
class DialogNewAutomation extends LitElement implements HassDialog {
|
||||
@ -19,8 +42,13 @@ class DialogNewAutomation extends LitElement implements HassDialog {
|
||||
|
||||
@state() private _opened = false;
|
||||
|
||||
@state() public blueprints?: Blueprints;
|
||||
|
||||
public showDialog(): void {
|
||||
this._opened = true;
|
||||
fetchBlueprints(this.hass!, "automation").then((blueprints) => {
|
||||
this.blueprints = blueprints;
|
||||
});
|
||||
}
|
||||
|
||||
public closeDialog(): void {
|
||||
@ -30,10 +58,33 @@ class DialogNewAutomation extends LitElement implements HassDialog {
|
||||
this._opened = false;
|
||||
}
|
||||
|
||||
private _processedBlueprints = memoizeOne((blueprints?: Blueprints) => {
|
||||
if (!blueprints) {
|
||||
return [];
|
||||
}
|
||||
const result = Object.entries(blueprints)
|
||||
.filter((entry): entry is [string, Blueprint] => !("error" in entry[1]))
|
||||
.map(([path, blueprint]) => {
|
||||
const sourceType = getBlueprintSourceType(blueprint);
|
||||
|
||||
return {
|
||||
...blueprint.metadata,
|
||||
sourceType,
|
||||
path,
|
||||
};
|
||||
});
|
||||
return result.sort((a, b) =>
|
||||
stringCompare(a.name, b.name, this.hass!.locale.language)
|
||||
);
|
||||
});
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._opened) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
const processedBlueprints = this._processedBlueprints(this.blueprints);
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
@ -41,48 +92,117 @@ class DialogNewAutomation extends LitElement implements HassDialog {
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
this.hass.localize("ui.panel.config.automation.dialog_new.how")
|
||||
this.hass.localize("ui.panel.config.automation.dialog_new.header")
|
||||
)}
|
||||
>
|
||||
<mwc-list>
|
||||
<mwc-list-item twoline class="blueprint" @click=${this._blueprint}>
|
||||
<mwc-list
|
||||
innerRole="listbox"
|
||||
itemRoles="option"
|
||||
innerAriaLabel=${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.header"
|
||||
)}
|
||||
rootTabbable
|
||||
dialogInitialFocus
|
||||
>
|
||||
<ha-list-item
|
||||
hasmeta
|
||||
twoline
|
||||
graphic="icon"
|
||||
@request-selected=${this._blank}
|
||||
>
|
||||
<ha-svg-icon slot="graphic" .path=${mdiPencilOutline}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.blueprint.use_blueprint"
|
||||
)}
|
||||
<span slot="secondary">
|
||||
<ha-blueprint-picker
|
||||
@value-changed=${this._blueprintPicked}
|
||||
.hass=${this.hass}
|
||||
></ha-blueprint-picker>
|
||||
</span>
|
||||
</mwc-list-item>
|
||||
<li divider role="separator"></li>
|
||||
<mwc-list-item hasmeta twoline @click=${this._blank}>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.start_empty"
|
||||
"ui.panel.config.automation.dialog_new.create_empty"
|
||||
)}
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.start_empty_description"
|
||||
"ui.panel.config.automation.dialog_new.create_empty_description"
|
||||
)}
|
||||
</span>
|
||||
<ha-icon-next slot="meta"></ha-icon-next>
|
||||
</mwc-list-item>
|
||||
</ha-list-item>
|
||||
<li divider role="separator"></li>
|
||||
${processedBlueprints.map(
|
||||
(blueprint) => html`
|
||||
<ha-list-item
|
||||
hasmeta
|
||||
twoline
|
||||
graphic="icon"
|
||||
@request-selected=${this._blueprint}
|
||||
.path=${blueprint.path}
|
||||
>
|
||||
<ha-svg-icon
|
||||
slot="graphic"
|
||||
.path=${SOURCE_TYPE_ICONS[blueprint.sourceType]}
|
||||
></ha-svg-icon>
|
||||
${blueprint.name}
|
||||
<span slot="secondary">
|
||||
${blueprint.author
|
||||
? this.hass.localize(
|
||||
`ui.panel.config.automation.dialog_new.blueprint_source.author`,
|
||||
{ author: blueprint.author }
|
||||
)
|
||||
: this.hass.localize(
|
||||
`ui.panel.config.automation.dialog_new.blueprint_source.${blueprint.sourceType}`
|
||||
)}
|
||||
</span>
|
||||
<ha-icon-next slot="meta"></ha-icon-next>
|
||||
</ha-list-item>
|
||||
`
|
||||
)}
|
||||
${processedBlueprints.length === 0
|
||||
? html`
|
||||
<a
|
||||
href=${documentationUrl(this.hass, "/get-blueprints")}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
class="item"
|
||||
>
|
||||
<ha-list-item hasmeta twoline graphic="icon">
|
||||
<ha-svg-icon slot="graphic" .path=${mdiWeb}></ha-svg-icon>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.create_blueprint"
|
||||
)}
|
||||
<span slot="secondary">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.create_blueprint_description"
|
||||
)}
|
||||
</span>
|
||||
<ha-svg-icon slot="meta" path=${mdiOpenInNew}></ha-svg-icon>
|
||||
</ha-list-item>
|
||||
</a>
|
||||
`
|
||||
: html`
|
||||
<ha-tip>
|
||||
<a
|
||||
href=${documentationUrl(this.hass, "/get-blueprints")}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.dialog_new.discover_blueprint_tip"
|
||||
)}
|
||||
</a>
|
||||
</ha-tip>
|
||||
`}
|
||||
</mwc-list>
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private async _blueprintPicked(ev: CustomEvent) {
|
||||
private async _blueprint(ev) {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
const path = (ev.currentTarget! as any).path;
|
||||
this.closeDialog();
|
||||
showAutomationEditor({ use_blueprint: { path: ev.detail.value } });
|
||||
showAutomationEditor({ use_blueprint: { path } });
|
||||
}
|
||||
|
||||
private async _blueprint() {
|
||||
this.shadowRoot!.querySelector("ha-blueprint-picker")!.open();
|
||||
}
|
||||
|
||||
private async _blank() {
|
||||
private async _blank(ev) {
|
||||
if (!shouldHandleRequestSelectedEvent(ev)) {
|
||||
return;
|
||||
}
|
||||
this.closeDialog();
|
||||
showAutomationEditor();
|
||||
}
|
||||
@ -92,14 +212,24 @@ class DialogNewAutomation extends LitElement implements HassDialog {
|
||||
haStyle,
|
||||
haStyleDialog,
|
||||
css`
|
||||
mwc-list-item.blueprint {
|
||||
height: 110px;
|
||||
}
|
||||
ha-blueprint-picker {
|
||||
margin-top: 8px;
|
||||
}
|
||||
ha-dialog {
|
||||
--dialog-content-padding: 0;
|
||||
--mdc-dialog-max-height: 60vh;
|
||||
}
|
||||
@media all and (min-width: 550px) {
|
||||
ha-dialog {
|
||||
--mdc-dialog-min-width: 500px;
|
||||
}
|
||||
}
|
||||
ha-icon-next {
|
||||
width: 24px;
|
||||
}
|
||||
ha-tip {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
a.item {
|
||||
text-decoration: unset;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -1931,19 +1931,18 @@
|
||||
}
|
||||
},
|
||||
"dialog_new": {
|
||||
"header": "Create a new automation",
|
||||
"how": "How do you want to create your new automation?",
|
||||
"blueprint": {
|
||||
"use_blueprint": "Use a blueprint"
|
||||
"header": "Create automation",
|
||||
"create_empty": "Create new automation",
|
||||
"create_empty_description": "Start with an empty automation from scratch",
|
||||
"create_blueprint": "Create from blueprint",
|
||||
"create_blueprint_description": "Discover community blueprints",
|
||||
"blueprint_source": {
|
||||
"author": "By {author}",
|
||||
"local": "By you",
|
||||
"community": "By the community",
|
||||
"homeassistant": "By Home Assistant"
|
||||
},
|
||||
"thingtalk": {
|
||||
"header": "Describe the automation you want to create",
|
||||
"intro": "And we will try to create it for you. For example: Turn the lights off when I leave.",
|
||||
"input_label": "What should this automation do?",
|
||||
"create": "Create"
|
||||
},
|
||||
"start_empty": "Start with an empty automation",
|
||||
"start_empty_description": "Create a new automation from scratch"
|
||||
"discover_blueprint_tip": "Discover more community blueprints"
|
||||
},
|
||||
"editor": {
|
||||
"enable": "[%key:ui::common::enable%]",
|
||||
|
Loading…
x
Reference in New Issue
Block a user