Pimp script editor (#3192)

* Pimp script editor

* Use property for define

* Show toasts
This commit is contained in:
Paulus Schoutsen 2019-05-12 21:28:25 -07:00 committed by GitHub
parent 1b50100b6c
commit e02d11a51f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 219 additions and 231 deletions

View File

@ -1,5 +1,14 @@
import { HomeAssistant } from "../types";
import computeObjectId from "../common/entity/compute_object_id";
export interface EventAction {
event: string;
event_data?: { [key: string]: any };
event_data_template?: { [key: string]: any };
}
export const triggerScript = (
hass: HomeAssistant,
entityId: string,
variables?: {}
) => hass.callService("script", computeObjectId(entityId), variables);

View File

@ -1,54 +0,0 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import LocalizeMixin from "../mixins/localize-mixin";
import { computeRTL } from "../common/util/compute_rtl";
class NotificationManager extends LocalizeMixin(PolymerElement) {
static get template() {
return html`
<style>
paper-toast {
z-index: 1;
}
</style>
<ha-toast
id="toast"
dir="[[_rtl]]"
no-cancel-on-outside-click="[[_cancelOnOutsideClick]]"
></ha-toast>
`;
}
static get properties() {
return {
hass: Object,
_cancelOnOutsideClick: {
type: Boolean,
value: false,
},
_rtl: {
type: String,
computed: "_computeRTLDirection(hass)",
},
};
}
ready() {
super.ready();
import(/* webpackChunkName: "ha-toast" */ "../components/ha-toast");
}
showDialog({ message }) {
this.$.toast.show(message);
}
_computeRTLDirection(hass) {
return computeRTL(hass) ? "rtl" : "ltr";
}
}
customElements.define("notification-manager", NotificationManager);

View File

@ -0,0 +1,30 @@
import { computeRTL } from "../common/util/compute_rtl";
import "../components/ha-toast";
import { LitElement, query, property, TemplateResult, html } from "lit-element";
import { HomeAssistant } from "../types";
// Typing
// tslint:disable-next-line: no-duplicate-imports
import { HaToast } from "../components/ha-toast";
export interface ShowToastParams {
message: string;
}
class NotificationManager extends LitElement {
@property() public hass!: HomeAssistant;
@query("ha-toast") private _toast!: HaToast;
public showDialog({ message }: ShowToastParams) {
const toast = this._toast;
toast.setAttribute("dir", computeRTL(this.hass) ? "rtl" : "ltr");
toast.show(message);
}
protected render(): TemplateResult | void {
return html`
<ha-toast dir="[[_rtl]]" noCancelOnOutsideClick=${false}></ha-toast>
`;
}
}
customElements.define("notification-manager", NotificationManager);

View File

@ -1,176 +0,0 @@
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import "@polymer/paper-fab/paper-fab";
import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-item/paper-item-body";
import "@polymer/paper-item/paper-item";
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import { computeRTL } from "../../../common/util/compute_rtl";
import "../../../layouts/ha-app-layout";
import "../../../components/ha-card";
import "../../../components/ha-icon-next";
import "../../../components/ha-paper-icon-button-arrow-prev";
import "../ha-config-section";
import computeStateName from "../../../common/entity/compute_state_name";
import NavigateMixin from "../../../mixins/navigate-mixin";
import LocalizeMixin from "../../../mixins/localize-mixin";
/*
* @appliesMixin LocalizeMixin
* @appliesMixin NavigateMixin
*/
class HaScriptPicker extends LocalizeMixin(NavigateMixin(PolymerElement)) {
static get template() {
return html`
<style include="ha-style">
:host {
display: block;
}
ha-card {
overflow: hidden;
}
paper-item {
cursor: pointer;
}
paper-fab {
position: fixed;
bottom: 16px;
right: 16px;
z-index: 1;
}
paper-fab[is-wide] {
bottom: 24px;
right: 24px;
}
paper-fab[rtl] {
right: auto;
left: 16px;
}
paper-fab[rtl][is-wide] {
bottom: 24px;
right: auto;
left: 24px;
}
a {
color: var(--primary-color);
}
</style>
<ha-app-layout has-scrolling-region="">
<app-header slot="header" fixed="">
<app-toolbar>
<ha-paper-icon-button-arrow-prev
on-click="_backTapped"
></ha-paper-icon-button-arrow-prev>
<div main-title="">
[[localize('ui.panel.config.script.caption')]]
</div>
</app-toolbar>
</app-header>
<ha-config-section is-wide="[[isWide]]">
<div slot="header">Script Editor</div>
<div slot="introduction">
The script editor allows you to create and edit scripts. Please read
<a
href="https://home-assistant.io/docs/scripts/editor/"
target="_blank"
>the instructions</a
>
to make sure that you have configured Home Assistant correctly.
</div>
<ha-card header="Pick script to edit">
<template is="dom-if" if="[[!scripts.length]]">
<div class="card-content">
<p>We couldn't find any editable scripts.</p>
</div>
</template>
<template is="dom-repeat" items="[[scripts]]" as="script">
<paper-item>
<paper-item-body two-line="" on-click="scriptTapped">
<div>[[computeName(script)]]</div>
<div secondary="">[[computeDescription(script)]]</div>
</paper-item-body>
<ha-icon-next></ha-icon-next>
</paper-item>
</template>
</ha-card>
</ha-config-section>
<paper-fab
slot="fab"
is-wide$="[[isWide]]"
icon="hass:plus"
title="Add Script"
on-click="addScript"
rtl$="[[rtl]]"
></paper-fab>
</ha-app-layout>
`;
}
static get properties() {
return {
hass: {
type: Object,
},
scripts: {
type: Array,
},
isWide: {
type: Boolean,
},
rtl: {
type: Boolean,
reflectToAttribute: true,
computed: "_computeRTL(hass)",
},
};
}
scriptTapped(ev) {
this.navigate(
"/config/script/edit/" + this.scripts[ev.model.index].entity_id
);
}
addScript() {
this.navigate("/config/script/new");
}
computeName(script) {
return computeStateName(script);
}
// Still thinking of something to add here.
// eslint-disable-next-line
computeDescription(script) {
return "";
}
_backTapped() {
history.back();
}
_computeRTL(hass) {
return computeRTL(hass);
}
}
customElements.define("ha-script-picker", HaScriptPicker);

View File

@ -0,0 +1,173 @@
import {
LitElement,
html,
CSSResultArray,
css,
TemplateResult,
property,
customElement,
} from "lit-element";
import "@polymer/paper-fab/paper-fab";
import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-item/paper-item-body";
import { HassEntity } from "home-assistant-js-websocket";
import "../../../layouts/hass-subpage";
import { computeRTL } from "../../../common/util/compute_rtl";
import "../../../components/ha-card";
import "../ha-config-section";
import computeStateName from "../../../common/entity/compute_state_name";
import { haStyle } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
import { triggerScript } from "../../../data/script";
import { showToast } from "../../../util/toast";
@customElement("ha-script-picker")
class HaScriptPicker extends LitElement {
@property() public hass!: HomeAssistant;
@property() public scripts!: HassEntity[];
@property() public isWide!: boolean;
protected render(): TemplateResult | void {
return html`
<hass-subpage
.header=${this.hass.localize("ui.panel.config.script.caption")}
>
<ha-config-section .isWide=${this.isWide}>
<div slot="header">Script Editor</div>
<div slot="introduction">
The script editor allows you to create and edit scripts. Please read
<a
href="https://home-assistant.io/docs/scripts/editor/"
target="_blank"
>the instructions</a
>
to make sure that you have configured Home Assistant correctly.
</div>
<ha-card header="Pick script to edit">
${this.scripts.length === 0
? html`
<div class="card-content">
<p>We couldn't find any scripts.</p>
</div>
`
: this.scripts.map(
(script) => html`
<div class="script">
<paper-icon-button
.script=${script}
icon="hass:play"
@click=${this._runScript}
></paper-icon-button>
<paper-item-body>
<div>${computeStateName(script)}</div>
</paper-item-body>
<div class="actions">
<a href=${`/config/script/edit/${script.entity_id}`}>
<paper-icon-button
icon="hass:pencil"
></paper-icon-button>
</a>
</div>
</div>
`
)}
</ha-card>
</ha-config-section>
<a href="/config/script/new">
<paper-fab
slot="fab"
?is-wide=${this.isWide}
icon="hass:plus"
title="Add Script"
?rtl=${computeRTL(this.hass)}
></paper-fab>
</a>
</hass-subpage>
`;
}
private async _runScript(ev) {
const script = ev.currentTarget.script as HassEntity;
await triggerScript(this.hass, script.entity_id);
showToast(this, {
message: `Triggered ${computeStateName(script)}`,
});
}
static get styles(): CSSResultArray {
return [
haStyle,
css`
:host {
display: block;
}
ha-card {
padding-bottom: 8px;
margin-bottom: 56px;
}
.script {
display: flex;
flex-direction: horizontal;
align-items: center;
padding: 0 8px;
margin: 4px 0;
}
.script > *:first-child {
margin-right: 8px;
}
.script a[href],
paper-icon-button {
color: var(--primary-text-color);
}
.actions {
display: flex;
}
paper-fab {
position: fixed;
bottom: 16px;
right: 16px;
z-index: 1;
}
paper-fab[is-wide] {
bottom: 24px;
right: 24px;
}
paper-fab[rtl] {
right: auto;
left: 16px;
}
paper-fab[rtl][is-wide] {
bottom: 24px;
right: auto;
left: 24px;
}
a {
color: var(--primary-color);
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-script-picker": HaScriptPicker;
}
}

View File

@ -1,6 +1,6 @@
export default (superClass) =>
class extends superClass {
firstUpdated(changedProps) {
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this.registerDialog({
dialogShowEvent: "hass-notification",

6
src/util/toast.ts Normal file
View File

@ -0,0 +1,6 @@
import { ShowToastParams } from "../managers/notification-manager";
import { fireEvent } from "../common/dom/fire_event";
export const showToast = (el: HTMLElement, params: ShowToastParams) =>
fireEvent(el, "hass-notification", params);