diff --git a/src/common/util/copy-clipboard.ts b/src/common/util/copy-clipboard.ts index 9d7e6885fa65..1708858c85ac 100644 --- a/src/common/util/copy-clipboard.ts +++ b/src/common/util/copy-clipboard.ts @@ -1,4 +1,13 @@ -export const copyToClipboard = (str) => { +export const copyToClipboard = async (str) => { + if (navigator.clipboard) { + try { + await navigator.clipboard.writeText(str); + return; + } catch { + // just continue with the fallback coding below + } + } + const el = document.createElement("textarea"); el.value = str; document.body.appendChild(el); diff --git a/src/panels/developer-tools/state/developer-tools-state.js b/src/panels/developer-tools/state/developer-tools-state.js index 02f6e67ec21f..f85c81acea6c 100644 --- a/src/panels/developer-tools/state/developer-tools-state.js +++ b/src/panels/developer-tools/state/developer-tools-state.js @@ -13,8 +13,12 @@ import { EventsMixin } from "../../../mixins/events-mixin"; import LocalizeMixin from "../../../mixins/localize-mixin"; import "../../../styles/polymer-ha-style"; import { formatDateTimeWithSeconds } from "../../../common/datetime/format_date_time"; -import { mdiInformationOutline } from "@mdi/js"; +import { + mdiInformationOutline, + mdiClipboardTextMultipleOutline, +} from "@mdi/js"; import { computeRTL } from "../../../common/util/compute_rtl"; +import { copyToClipboard } from "../../../common/util/copy-clipboard"; const ERROR_SENTINEL = {}; /* @@ -205,6 +209,12 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) { title="[[localize('ui.panel.developer-tools.tabs.states.more_info')]]" path="[[informationOutlineIcon()]]" > + [[entity.entity_id]] @@ -296,6 +306,11 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) { }; } + copyEntity(ev) { + ev.preventDefault(); + copyToClipboard(ev.model.entity.entity_id); + } + entitySelected(ev) { const state = ev.model.entity; this._entityId = state.entity_id; @@ -345,6 +360,10 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) { return mdiInformationOutline; } + clipboardOutlineIcon() { + return mdiClipboardTextMultipleOutline; + } + computeEntities(hass, _entityFilter, _stateFilter, _attributeFilter) { return Object.keys(hass.states) .map(function (key) { diff --git a/src/translations/en.json b/src/translations/en.json index 10ad5be09782..50228b4ed786 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3063,7 +3063,8 @@ "more_info": "More Info", "alert_entity_field": "Entity is a mandatory field", "last_updated": "[%key:ui::dialogs::more_info_control::last_updated%]", - "last_changed": "[%key:ui::dialogs::more_info_control::last_changed%]" + "last_changed": "[%key:ui::dialogs::more_info_control::last_changed%]", + "copy_id": "Copy ID to clipboard" }, "templates": { "title": "Template",