Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions src/components/ha-blueprint-picker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
import { fireEvent } from "../common/dom/fire_event";
import { compare } from "../common/string/compare";
import { Blueprints, fetchBlueprints } from "../data/blueprint";
import { HomeAssistant } from "../types";

@customElement("ha-blueprint-picker")
class HaBluePrintPicker extends LitElement {
public hass?: HomeAssistant;

@property() public label?: string;

@property() public value = "";

@property() public domain = "automation";

@property() public blueprints?: Blueprints;

@property({ type: Boolean }) public disabled = false;

private _processedBlueprints = memoizeOne((blueprints?: Blueprints) => {
if (!blueprints) {
return [];
}
const result = Object.entries(blueprints).map(([path, blueprint]) => ({
...blueprint.metadata,
path,
}));
return result.sort((a, b) => compare(a.name, b.name));
});

protected render(): TemplateResult {
if (!this.hass) {
return html``;
}
return html`
<paper-dropdown-menu-light
.label=${this.label ||
this.hass.localize("ui.components.blueprint-picker.label")}
.disabled=${this.disabled}
>
<paper-listbox
slot="dropdown-content"
.selected=${this.value}
attr-for-selected="data-blueprint-path"
@iron-select=${this._blueprintChanged}
>
<paper-item data-blueprint-path="">
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still using Polymer 😬

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The paper-dropdown/paper-list you mean?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah.

${this.hass.localize(
"ui.components.blueprint-picker.select_blueprint"
)}
</paper-item>
${this._processedBlueprints(this.blueprints).map(
(blueprint) => html`
<paper-item data-blueprint-path=${blueprint.path}>
${blueprint.name}
</paper-item>
`
)}
</paper-listbox>
</paper-dropdown-menu-light>
`;
}

protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
if (this.blueprints === undefined) {
fetchBlueprints(this.hass!, this.domain).then((blueprints) => {
this.blueprints = blueprints;
});
}
}

private _blueprintChanged(ev) {
const newValue = ev.detail.item.dataset.blueprintPath;

if (newValue !== this.value) {
this.value = ev.detail.value;
setTimeout(() => {
fireEvent(this, "value-changed", { value: newValue });
fireEvent(this, "change");
}, 0);
}
}

static get styles(): CSSResult {
return css`
:host {
display: inline-block;
}
paper-dropdown-menu-light {
width: 100%;
min-width: 200px;
display: block;
}
paper-listbox {
min-width: 200px;
}
`;
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-blueprint-picker": HaBluePrintPicker;
}
}
15 changes: 12 additions & 3 deletions src/data/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from "home-assistant-js-websocket";
import { navigate } from "../common/navigate";
import { Context, HomeAssistant } from "../types";
import { BlueprintInput } from "./blueprint";
import { DeviceCondition, DeviceTrigger } from "./device_automation";
import { Action } from "./script";

Expand All @@ -14,17 +15,25 @@ export interface AutomationEntity extends HassEntityBase {
};
}

export interface AutomationConfig {
export type AutomationConfig =
| ManualAutomationConfig
| BlueprintAutomationConfig;

export interface ManualAutomationConfig {
id?: string;
alias: string;
description: string;
alias?: string;
description?: string;
trigger: Trigger[];
condition?: Condition[];
action: Action[];
mode?: "single" | "restart" | "queued" | "parallel";
max?: number;
}

export interface BlueprintAutomationConfig extends ManualAutomationConfig {
use_blueprint: { path: string; input?: BlueprintInput };
}

export interface ForDict {
hours?: number | string;
minutes?: number | string;
Expand Down
54 changes: 54 additions & 0 deletions src/data/blueprint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { HomeAssistant } from "../types";

export type Blueprints = Record<string, Blueprint>;

export interface Blueprint {
metadata: BlueprintMetaData;
}

export interface BlueprintMetaData {
domain: string;
name: string;
input: BlueprintInput;
}

export type BlueprintInput = Record<string, any>;

export interface BlueprintImportResult {
url: string;
suggested_filename: string;
raw_data: string;
blueprint: Blueprint;
}

export const fetchBlueprints = (hass: HomeAssistant, domain: string) =>
hass.callWS<Blueprints>({ type: "blueprint/list", domain });

export const importBlueprint = (hass: HomeAssistant, url: string) =>
hass.callWS<BlueprintImportResult>({ type: "blueprint/import", url });

export const saveBlueprint = (
hass: HomeAssistant,
domain: string,
path: string,
yaml: string,
source_url?: string
) =>
hass.callWS({
type: "blueprint/save",
domain,
path,
yaml,
source_url,
});

export const deleteBlueprint = (
hass: HomeAssistant,
domain: string,
path: string
) =>
hass.callWS<BlueprintImportResult>({
type: "blueprint/delete",
domain,
path,
});
Loading