From 13a691606f75b4b60636d1c308ca9ce5ba854643 Mon Sep 17 00:00:00 2001
From: Simon Lamon <32477463+silamon@users.noreply.github.com>
Date: Thu, 28 Sep 2023 16:58:16 +0200
Subject: [PATCH] Migrate developer events tools to LitElement (#17869)
---
.../event/developer-tools-event.js | 219 ------------------
.../event/developer-tools-event.ts | 184 +++++++++++++++
.../developer-tools/event/events-list.js | 73 ------
.../developer-tools/event/events-list.ts | 84 +++++++
4 files changed, 268 insertions(+), 292 deletions(-)
delete mode 100644 src/panels/developer-tools/event/developer-tools-event.js
create mode 100644 src/panels/developer-tools/event/developer-tools-event.ts
delete mode 100644 src/panels/developer-tools/event/events-list.js
create mode 100644 src/panels/developer-tools/event/events-list.ts
diff --git a/src/panels/developer-tools/event/developer-tools-event.js b/src/panels/developer-tools/event/developer-tools-event.js
deleted file mode 100644
index b4925bf130..0000000000
--- a/src/panels/developer-tools/event/developer-tools-event.js
+++ /dev/null
@@ -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`
-
-
-
-
- `;
- }
-
- 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);
diff --git a/src/panels/developer-tools/event/developer-tools-event.ts b/src/panels/developer-tools/event/developer-tools-event.ts
new file mode 100644
index 0000000000..f0885df338
--- /dev/null
+++ b/src/panels/developer-tools/event/developer-tools-event.ts
@@ -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`
+
+ `;
+ }
+
+ 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;
+ }
+}
diff --git a/src/panels/developer-tools/event/events-list.js b/src/panels/developer-tools/event/events-list.js
deleted file mode 100644
index a6893d269e..0000000000
--- a/src/panels/developer-tools/event/events-list.js
+++ /dev/null
@@ -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`
-
-
-
-
- -
- {{event.event}}
-
- [[localize(
- "ui.panel.developer-tools.tabs.events.count_listeners", "count",
- event.listener_count )]]
-
-
-
- `;
- }
-
- 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);
diff --git a/src/panels/developer-tools/event/events-list.ts b/src/panels/developer-tools/event/events-list.ts
new file mode 100644
index 0000000000..7007ca6eab
--- /dev/null
+++ b/src/panels/developer-tools/event/events-list.ts
@@ -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`
+
+ ${this.events.map(
+ (event) => html`
+ -
+ ${event.event}
+
+ ${this.hass.localize(
+ "ui.panel.developer-tools.tabs.events.count_listeners",
+ {
+ count: event.listener_count,
+ }
+ )}
+
+ `
+ )}
+
+ `;
+ }
+
+ protected async firstUpdated() {
+ const events = await this.hass.callApi(
+ "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 };
+ }
+}