From 14a49d666416912f69e7c154c0d512022c86d7a6 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 4 Dec 2023 06:24:35 -0800 Subject: [PATCH] `Copy to clipboard` button for service response (#18872) --- src/components/ha-yaml-editor.ts | 52 ++++++++++++++++++- .../config/automation/ha-automation-editor.ts | 45 +++------------- src/panels/config/script/ha-script-editor.ts | 42 ++++----------- .../service/developer-tools-service.ts | 2 + src/translations/en.json | 3 ++ 5 files changed, 75 insertions(+), 69 deletions(-) diff --git a/src/components/ha-yaml-editor.ts b/src/components/ha-yaml-editor.ts index 847bef1e7a67..882a12cd73a3 100644 --- a/src/components/ha-yaml-editor.ts +++ b/src/components/ha-yaml-editor.ts @@ -1,9 +1,19 @@ import { DEFAULT_SCHEMA, dump, load, Schema } from "js-yaml"; -import { html, LitElement, nothing, PropertyValues } from "lit"; +import { + CSSResultGroup, + css, + html, + LitElement, + nothing, + PropertyValues, +} from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; import type { HomeAssistant } from "../types"; +import { haStyle } from "../resources/styles"; import "./ha-code-editor"; +import { showToast } from "../util/toast"; +import { copyToClipboard } from "../common/util/copy-clipboard"; const isEmpty = (obj: Record): boolean => { if (typeof obj !== "object") { @@ -37,6 +47,8 @@ export class HaYamlEditor extends LitElement { @property({ type: Boolean }) public required = false; + @property({ type: Boolean }) public copyClipboard = false; + @state() private _yaml = ""; public setValue(value): void { @@ -88,6 +100,15 @@ export class HaYamlEditor extends LitElement { @value-changed=${this._onChange} dir="ltr" > + ${this.copyClipboard + ? html`
+ + ${this.hass.localize( + "ui.components.yaml-editor.copy_to_clipboard" + )} + +
` + : nothing} `; } @@ -117,6 +138,35 @@ export class HaYamlEditor extends LitElement { get yaml() { return this._yaml; } + + private async _copyYaml(): Promise { + if (this.yaml) { + await copyToClipboard(this.yaml); + showToast(this, { + message: this.hass.localize("ui.common.copied_clipboard"), + }); + } + } + + static get styles(): CSSResultGroup { + return [ + haStyle, + css` + .card-actions { + border-radius: var( + --actions-border-radius, + 0px 0px var(--ha-card-border-radius, 12px) + var(--ha-card-border-radius, 12px) + ); + border: 1px solid var(--divider-color); + padding: 5px 16px; + } + ha-code-editor { + flex-grow: 1; + } + `, + ]; + } } declare global { diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts index 7df66a42ae4c..2c6429d642e1 100644 --- a/src/panels/config/automation/ha-automation-editor.ts +++ b/src/panels/config/automation/ha-automation-editor.ts @@ -25,19 +25,16 @@ import { html, nothing, } from "lit"; -import { property, query, state } from "lit/decorators"; +import { property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { fireEvent } from "../../../common/dom/fire_event"; import { navigate } from "../../../common/navigate"; -import { copyToClipboard } from "../../../common/util/copy-clipboard"; import { afterNextRender } from "../../../common/util/render-status"; import "../../../components/ha-button-menu"; -import "../../../components/ha-card"; import "../../../components/ha-fab"; import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import "../../../components/ha-yaml-editor"; -import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import { AutomationConfig, AutomationEntity, @@ -112,8 +109,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { @state() private _validationErrors?: (string | TemplateResult)[]; - @query("ha-yaml-editor", true) private _yamlEditor?: HaYamlEditor; - private _configSubscriptions: Record< string, (config?: AutomationConfig) => void @@ -342,8 +337,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { > ` : this._mode === "yaml" - ? html` - ${this._readOnly + ? html` ${this._readOnly ? html` ${this.hass.localize( "ui.panel.config.automation.editor.read_only" @@ -376,22 +370,13 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { ` : ""} - -
- - ${this.hass.localize( - "ui.panel.config.automation.editor.copy_to_clipboard" - )} - -
-
- ` - : ``} + >` + : nothing} ` : ""} @@ -612,15 +597,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { return cleanConfig; } - private async _copyYaml(): Promise { - if (this._yamlEditor?.yaml) { - await copyToClipboard(this._yamlEditor.yaml); - showToast(this, { - message: this.hass.localize("ui.common.copied_clipboard"), - }); - } - } - private _yamlChanged(ev: CustomEvent) { ev.stopPropagation(); if (!ev.detail.isValid) { @@ -776,9 +752,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { return [ haStyle, css` - ha-card { - overflow: hidden; - } .content { padding-bottom: 20px; } @@ -796,13 +769,11 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) { } ha-yaml-editor { flex-grow: 1; + --actions-border-radius: 0; --code-mirror-height: 100%; min-height: 0; - } - .yaml-mode ha-card { - overflow: initial; - --ha-card-border-radius: 0; - border-bottom: 1px solid var(--divider-color); + display: flex; + flex-direction: column; } p { margin-bottom: 0; diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts index 0f00810cc015..72bd14c13c31 100644 --- a/src/panels/config/script/ha-script-editor.ts +++ b/src/panels/config/script/ha-script-editor.ts @@ -26,7 +26,6 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { navigate } from "../../../common/navigate"; import { slugify } from "../../../common/string/slugify"; import { computeRTL } from "../../../common/util/compute_rtl"; -import { copyToClipboard } from "../../../common/util/copy-clipboard"; import { afterNextRender } from "../../../common/util/render-status"; import "../../../components/ha-button-menu"; import "../../../components/ha-card"; @@ -38,7 +37,6 @@ import type { import "../../../components/ha-icon-button"; import "../../../components/ha-svg-icon"; import "../../../components/ha-yaml-editor"; -import type { HaYamlEditor } from "../../../components/ha-yaml-editor"; import { validateConfig } from "../../../data/config"; import { UNAVAILABLE } from "../../../data/entity"; import { EntityRegistryEntry } from "../../../data/entity_registry"; @@ -94,8 +92,6 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { @state() private _readOnly = false; - @query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor; - @query("manual-script-editor") private _manualEditor?: HaManualScriptEditor; @@ -405,24 +401,14 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { ` : this._mode === "yaml" - ? html` - - -
- - ${this.hass.localize( - "ui.panel.config.automation.editor.copy_to_clipboard" - )} - -
-
- ` - : ``} + ? html` ` + : nothing} { - if (this._yamlEditor?.yaml) { - await copyToClipboard(this._yamlEditor.yaml); - showToast(this, { - message: this.hass.localize("ui.common.copied_clipboard"), - }); - } - } - private _yamlChanged(ev: CustomEvent) { ev.stopPropagation(); if (!ev.detail.isValid) { @@ -903,8 +880,11 @@ export class HaScriptEditor extends KeyboardShortcutMixin(LitElement) { } ha-yaml-editor { flex-grow: 1; + --actions-border-radius: 0; --code-mirror-height: 100%; min-height: 0; + display: flex; + flex-direction: column; } .yaml-mode ha-card { overflow: initial; diff --git a/src/panels/developer-tools/service/developer-tools-service.ts b/src/panels/developer-tools/service/developer-tools-service.ts index ffff14b1aa43..394ed6d9fa90 100644 --- a/src/panels/developer-tools/service/developer-tools-service.ts +++ b/src/panels/developer-tools/service/developer-tools-service.ts @@ -184,6 +184,8 @@ class HaPanelDevService extends LitElement { >