mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 17:26:42 +00:00
Pimp script editor (#3192)
* Pimp script editor * Use property for define * Show toasts
This commit is contained in:
parent
1b50100b6c
commit
e02d11a51f
@ -1,5 +1,14 @@
|
|||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
import computeObjectId from "../common/entity/compute_object_id";
|
||||||
|
|
||||||
export interface EventAction {
|
export interface EventAction {
|
||||||
event: string;
|
event: string;
|
||||||
event_data?: { [key: string]: any };
|
event_data?: { [key: string]: any };
|
||||||
event_data_template?: { [key: string]: any };
|
event_data_template?: { [key: string]: any };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const triggerScript = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entityId: string,
|
||||||
|
variables?: {}
|
||||||
|
) => hass.callService("script", computeObjectId(entityId), variables);
|
||||||
|
@ -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);
|
|
30
src/managers/notification-manager.ts
Normal file
30
src/managers/notification-manager.ts
Normal 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);
|
@ -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);
|
|
173
src/panels/config/script/ha-script-picker.ts
Normal file
173
src/panels/config/script/ha-script-picker.ts
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
export default (superClass) =>
|
export default (superClass) =>
|
||||||
class extends superClass {
|
class extends superClass {
|
||||||
firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this.registerDialog({
|
this.registerDialog({
|
||||||
dialogShowEvent: "hass-notification",
|
dialogShowEvent: "hass-notification",
|
6
src/util/toast.ts
Normal file
6
src/util/toast.ts
Normal 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);
|
Loading…
x
Reference in New Issue
Block a user