mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Migrate developer events tools to LitElement (#17869)
This commit is contained in:
parent
44748df3ac
commit
13a691606f
@ -1,219 +0,0 @@
|
||||
import "@material/mwc-button";
|
||||
import "@polymer/iron-flex-layout/iron-flex-layout-classes";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { load } from "js-yaml";
|
||||
import "../../../components/ha-code-editor";
|
||||
import "../../../components/ha-textfield";
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { EventsMixin } from "../../../mixins/events-mixin";
|
||||
import LocalizeMixin from "../../../mixins/localize-mixin";
|
||||
import "../../../styles/polymer-ha-style";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import "./event-subscribe-card";
|
||||
import "./events-list";
|
||||
|
||||
const ERROR_SENTINEL = {};
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class HaPanelDevEvent extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style iron-flex iron-positioning"></style>
|
||||
<style>
|
||||
.content {
|
||||
padding: 16px;
|
||||
padding: max(16px, env(safe-area-inset-top))
|
||||
max(16px, env(safe-area-inset-right))
|
||||
max(16px, env(safe-area-inset-bottom))
|
||||
max(16px, env(safe-area-inset-left));
|
||||
max-width: 1200px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
-webkit-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
@apply --paper-font-body1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.inputs {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
mwc-button {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
ha-textfield {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.code-editor {
|
||||
margin-right: 16px;
|
||||
margin-inline-start: initial;
|
||||
margin-inline-end: 16px;
|
||||
direction: var(--direction);
|
||||
}
|
||||
|
||||
.header {
|
||||
@apply --paper-font-title;
|
||||
}
|
||||
|
||||
event-subscribe-card {
|
||||
display: block;
|
||||
margin: 16px 16px 0 0;
|
||||
margin-inline-start: initial;
|
||||
margin-inline-end: 16px;
|
||||
direction: var(--direction);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class$="[[computeFormClasses(narrow)]]">
|
||||
<div class="flex">
|
||||
<p>
|
||||
[[localize( 'ui.panel.developer-tools.tabs.events.description' )]]
|
||||
<a
|
||||
href="[[_computeDocumentationUrl(hass)]]"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
[[localize( 'ui.panel.developer-tools.tabs.events.documentation'
|
||||
)]]
|
||||
</a>
|
||||
</p>
|
||||
<div class="inputs">
|
||||
<ha-textfield
|
||||
label="[[localize(
|
||||
'ui.panel.developer-tools.tabs.events.type'
|
||||
)]]"
|
||||
autofocus
|
||||
required
|
||||
value="[[eventType]]"
|
||||
on-change="eventTypeChanged"
|
||||
></ha-textfield>
|
||||
<p>[[localize( 'ui.panel.developer-tools.tabs.events.data' )]]</p>
|
||||
</div>
|
||||
<div class="code-editor">
|
||||
<ha-code-editor
|
||||
mode="yaml"
|
||||
value="[[eventData]]"
|
||||
error="[[!validJSON]]"
|
||||
on-value-changed="_yamlChanged"
|
||||
dir="ltr"
|
||||
></ha-code-editor>
|
||||
</div>
|
||||
<mwc-button on-click="fireEvent" raised disabled="[[!validJSON]]"
|
||||
>[[localize( 'ui.panel.developer-tools.tabs.events.fire_event'
|
||||
)]]</mwc-button
|
||||
>
|
||||
<event-subscribe-card hass="[[hass]]"></event-subscribe-card>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="header">
|
||||
[[localize( 'ui.panel.developer-tools.tabs.events.active_listeners'
|
||||
)]]
|
||||
</div>
|
||||
<events-list
|
||||
on-event-selected="eventSelected"
|
||||
hass="[[hass]]"
|
||||
></events-list>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
eventType: {
|
||||
type: String,
|
||||
value: "",
|
||||
},
|
||||
|
||||
eventData: {
|
||||
type: String,
|
||||
value: "",
|
||||
},
|
||||
|
||||
parsedJSON: {
|
||||
type: Object,
|
||||
computed: "_computeParsedEventData(eventData)",
|
||||
},
|
||||
|
||||
validJSON: {
|
||||
type: Boolean,
|
||||
computed: "_computeValidJSON(parsedJSON)",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
eventSelected(ev) {
|
||||
this.eventType = ev.detail.eventType;
|
||||
}
|
||||
|
||||
eventTypeChanged(ev) {
|
||||
this.eventType = ev.target.value;
|
||||
}
|
||||
|
||||
_computeParsedEventData(eventData) {
|
||||
try {
|
||||
return eventData.trim() ? load(eventData) : {};
|
||||
} catch (err) {
|
||||
return ERROR_SENTINEL;
|
||||
}
|
||||
}
|
||||
|
||||
_computeDocumentationUrl(hass) {
|
||||
return documentationUrl(hass, "/docs/configuration/events/");
|
||||
}
|
||||
|
||||
_computeValidJSON(parsedJSON) {
|
||||
return parsedJSON !== ERROR_SENTINEL;
|
||||
}
|
||||
|
||||
_yamlChanged(ev) {
|
||||
this.eventData = ev.detail.value;
|
||||
}
|
||||
|
||||
fireEvent() {
|
||||
if (!this.eventType) {
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.alert_event_type"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.hass
|
||||
.callApi("POST", "events/" + this.eventType, this.parsedJSON)
|
||||
.then(() => {
|
||||
this.fire("hass-notification", {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.notification_event_fired",
|
||||
"type",
|
||||
this.eventType
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
computeFormClasses(narrow) {
|
||||
return narrow ? "content" : "content layout horizontal";
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("developer-tools-event", HaPanelDevEvent);
|
184
src/panels/developer-tools/event/developer-tools-event.ts
Normal file
184
src/panels/developer-tools/event/developer-tools-event.ts
Normal file
@ -0,0 +1,184 @@
|
||||
import { CSSResultGroup, LitElement, TemplateResult, css, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "@material/mwc-button";
|
||||
import "../../../components/ha-yaml-editor";
|
||||
import "../../../components/ha-textfield";
|
||||
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import { documentationUrl } from "../../../util/documentation-url";
|
||||
import "./event-subscribe-card";
|
||||
import "./events-list";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
|
||||
@customElement("developer-tools-event")
|
||||
class HaPanelDevEvent extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ type: Boolean }) public narrow!: boolean;
|
||||
|
||||
@state() private _eventType: string = "";
|
||||
|
||||
@state() private _eventData: object = {};
|
||||
|
||||
@state() private _isValid: boolean = true;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div class=${this.narrow ? "content" : "content layout horizontal"}>
|
||||
<div class="flex">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.description"
|
||||
)}
|
||||
<a
|
||||
href=${documentationUrl(this.hass, "/docs/configuration/events/")}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.documentation"
|
||||
)}
|
||||
</a>
|
||||
</p>
|
||||
<div class="inputs">
|
||||
<ha-textfield
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.type"
|
||||
)}
|
||||
autofocus
|
||||
required
|
||||
.value=${this._eventType}
|
||||
@change=${this._eventTypeChanged}
|
||||
></ha-textfield>
|
||||
<p>
|
||||
${this.hass.localize("ui.panel.developer-tools.tabs.events.data")}
|
||||
</p>
|
||||
</div>
|
||||
<div class="code-editor">
|
||||
<ha-yaml-editor
|
||||
.value=${this._eventData}
|
||||
.error=${!this._isValid}
|
||||
@value-changed=${this._yamlChanged}
|
||||
></ha-yaml-editor>
|
||||
</div>
|
||||
<mwc-button
|
||||
@click=${this._fireEvent}
|
||||
raised
|
||||
.disabled=${!this._isValid}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.fire_event"
|
||||
)}</mwc-button
|
||||
>
|
||||
<event-subscribe-card .hass=${this.hass}></event-subscribe-card>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.active_listeners"
|
||||
)}
|
||||
</div>
|
||||
<events-list
|
||||
@event-selected=${this._eventSelected}
|
||||
.hass=${this.hass}
|
||||
></events-list>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _eventSelected(ev) {
|
||||
this._eventType = ev.detail.eventType;
|
||||
}
|
||||
|
||||
private _eventTypeChanged(ev) {
|
||||
this._eventType = ev.target.value;
|
||||
}
|
||||
|
||||
private _yamlChanged(ev) {
|
||||
this._eventData = ev.detail.value;
|
||||
this._isValid = ev.detail.isValid;
|
||||
}
|
||||
|
||||
private async _fireEvent() {
|
||||
if (!this._eventType) {
|
||||
showAlertDialog(this, {
|
||||
text: this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.alert_event_type"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
await this.hass.callApi(
|
||||
"POST",
|
||||
`events/${this._eventType}`,
|
||||
this._eventData
|
||||
);
|
||||
fireEvent(this, "hass-notification", {
|
||||
message: this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.notification_event_fired",
|
||||
{ type: this._eventType }
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.content {
|
||||
padding: 16px;
|
||||
padding: max(16px, env(safe-area-inset-top))
|
||||
max(16px, env(safe-area-inset-right))
|
||||
max(16px, env(safe-area-inset-bottom))
|
||||
max(16px, env(safe-area-inset-left));
|
||||
max-width: 1200px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
:host {
|
||||
-ms-user-select: initial;
|
||||
-webkit-user-select: initial;
|
||||
-moz-user-select: initial;
|
||||
@apply --paper-font-body1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.inputs {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
mwc-button {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
ha-textfield {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.header {
|
||||
@apply --paper-font-title;
|
||||
}
|
||||
|
||||
event-subscribe-card {
|
||||
display: block;
|
||||
margin: 16px 16px 0 0;
|
||||
margin-inline-start: initial;
|
||||
margin-inline-end: 16px;
|
||||
direction: var(--direction);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"developer-tools-event": HaPanelDevEvent;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import { stringCompare } from "../../../common/string/compare";
|
||||
import { EventsMixin } from "../../../mixins/events-mixin";
|
||||
import LocalizeMixin from "../../../mixins/localize-mixin";
|
||||
|
||||
/*
|
||||
* @appliesMixin EventsMixin
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class EventsList extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
<ul>
|
||||
<template is="dom-repeat" items="[[events]]" as="event">
|
||||
<li>
|
||||
<a href="#" on-click="eventSelected">{{event.event}}</a>
|
||||
<span>
|
||||
[[localize(
|
||||
"ui.panel.developer-tools.tabs.events.count_listeners", "count",
|
||||
event.listener_count )]]</span
|
||||
>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
events: {
|
||||
type: Array,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.hass.callApi("GET", "events").then((events) => {
|
||||
this.events = events.sort((e1, e2) =>
|
||||
stringCompare(e1.event, e2.event, this.hass.locale.language)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
eventSelected(ev) {
|
||||
ev.preventDefault();
|
||||
this.fire("event-selected", { eventType: ev.model.event.event });
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("events-list", EventsList);
|
84
src/panels/developer-tools/event/events-list.ts
Normal file
84
src/panels/developer-tools/event/events-list.ts
Normal file
@ -0,0 +1,84 @@
|
||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { stringCompare } from "../../../common/string/compare";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
|
||||
interface EventListenerCount {
|
||||
event: string;
|
||||
listener_count: number;
|
||||
}
|
||||
|
||||
@customElement("events-list")
|
||||
class EventsList extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property() public events: EventListenerCount[] = [];
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<ul>
|
||||
${this.events.map(
|
||||
(event) => html`
|
||||
<li>
|
||||
<a href="#" @click=${this._eventSelected} .event=${event.event}
|
||||
>${event.event}</a
|
||||
>
|
||||
<span>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.events.count_listeners",
|
||||
{
|
||||
count: event.listener_count,
|
||||
}
|
||||
)}</span
|
||||
>
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
</ul>
|
||||
`;
|
||||
}
|
||||
|
||||
protected async firstUpdated() {
|
||||
const events = await this.hass.callApi<EventListenerCount[]>(
|
||||
"GET",
|
||||
"events"
|
||||
);
|
||||
this.events = events.sort((e1, e2) =>
|
||||
stringCompare(e1.event, e2.event, this.hass.locale.language)
|
||||
);
|
||||
}
|
||||
|
||||
private _eventSelected(ev: Event) {
|
||||
ev.preventDefault();
|
||||
const event: string = (ev.currentTarget! as any).event;
|
||||
fireEvent(this, "event-selected", { eventType: event });
|
||||
}
|
||||
|
||||
static get styles(): CSSResultGroup {
|
||||
return css`
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"events-list": EventsList;
|
||||
}
|
||||
interface HASSDomEvents {
|
||||
"event-selected": { eventType: string };
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user