From a2f7f978455ebc8a25f50916569c03e46d826363 Mon Sep 17 00:00:00 2001 From: Galen Date: Tue, 7 Jan 2025 15:17:43 -0600 Subject: [PATCH] chore: clean up copy texts --- .../IndexScene/ShareButtonScene.tsx | 18 ++---------- .../ServiceScene/LogsPanelScene.tsx | 4 +-- src/services/text.ts | 29 +++++-------------- 3 files changed, 12 insertions(+), 39 deletions(-) diff --git a/src/Components/IndexScene/ShareButtonScene.tsx b/src/Components/IndexScene/ShareButtonScene.tsx index 783dbd5c..672a514c 100644 --- a/src/Components/IndexScene/ShareButtonScene.tsx +++ b/src/Components/IndexScene/ShareButtonScene.tsx @@ -9,6 +9,7 @@ import { ButtonGroup, Dropdown, IconName, Menu, MenuGroup, ToolbarButton } from import React from 'react'; import { config, getAppEvents, getBackendSrv, locationService, reportInteraction } from '@grafana/runtime'; import { AppEvents, toUtc } from '@grafana/data'; +import { copyText } from '../../services/text'; interface ShortLinkMenuItemData { key: string; @@ -52,7 +53,7 @@ export class ShareButtonScene extends SceneObjectBase { createAndCopyShortLink(url || global.location.href); reportInteraction('grafana_explore_shortened_link_clicked', { isAbsoluteTime: absTime }); } else { - copyStringToClipboard( + copyText( url !== undefined ? `${window.location.protocol}//${window.location.host}${config.appSubUrl}${url}` : global.location.href @@ -222,7 +223,7 @@ export const createAndCopyShortLink = async (path: string) => { const appEvents = getAppEvents(); const shortLink = await createShortLink(path); if (shortLink) { - copyStringToClipboard(shortLink); + copyText(shortLink); appEvents.publish({ type: AppEvents.alertSuccess.name, payload: ['Shortened link copied to clipboard'], @@ -235,19 +236,6 @@ export const createAndCopyShortLink = async (path: string) => { } }; -export const copyStringToClipboard = (string: string) => { - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard.writeText(string); - } else { - const el = document.createElement('textarea'); - el.value = string; - document.body.appendChild(el); - el.select(); - document.execCommand('copy'); - document.body.removeChild(el); - } -}; - /** * Adapted from /grafana/grafana/public/app/features/explore/utils/links.ts * Returns the current URL with absolute time range diff --git a/src/Components/ServiceScene/LogsPanelScene.tsx b/src/Components/ServiceScene/LogsPanelScene.tsx index fa4b278b..2a8d3e5b 100644 --- a/src/Components/ServiceScene/LogsPanelScene.tsx +++ b/src/Components/ServiceScene/LogsPanelScene.tsx @@ -196,7 +196,6 @@ export class LogsPanelScene extends SceneObjectBase { private handleShareLogLineClick = (event: MouseEvent, row?: LogRowModel) => { if (row?.rowId && this.state.body) { const parent = this.getParentScene(); - const buttonRef = event.currentTarget instanceof HTMLButtonElement ? event.currentTarget : undefined; const timeRange = resolveRowTimeRangeForSharing(row); copyText( generateLogShortlink( @@ -205,8 +204,7 @@ export class LogsPanelScene extends SceneObjectBase { logs: { id: row.uid, displayedFields: parent.state.displayedFields }, }, timeRange - ), - buttonRef + ) ); } }; diff --git a/src/services/text.ts b/src/services/text.ts index 676c10f1..5e36d1a5 100644 --- a/src/services/text.ts +++ b/src/services/text.ts @@ -2,29 +2,16 @@ import { locationService } from '@grafana/runtime'; import { logger } from './logger'; import { dateTime, LogRowModel, TimeRange } from '@grafana/data'; -export const copyText = async ( - text: string, - buttonRef?: React.MutableRefObject | HTMLButtonElement -) => { +export const copyText = (string: string) => { if (navigator.clipboard && window.isSecureContext) { - return navigator.clipboard.writeText(text); - // eslint-disable-next-line deprecation/deprecation - } else if (document.execCommand && buttonRef) { - // Use a fallback method for browsers/contexts that don't support the Clipboard API. - // See https://web.dev/async-clipboard/#feature-detection. - // Use textarea so the user can copy multi-line content. - const textarea = document.createElement('textarea'); - // Normally we'd append this to the body. However if we're inside a focus manager - // from react-aria, we can't focus anything outside of the managed area. - // Instead, let's append it to the button. Then we're guaranteed to be able to focus + copy. - const buttonElement = buttonRef instanceof HTMLButtonElement ? buttonRef : buttonRef?.current; - buttonElement?.appendChild(textarea); - textarea.value = text; - textarea.focus(); - textarea.select(); - // eslint-disable-next-line deprecation/deprecation + navigator.clipboard.writeText(string); + } else { + const el = document.createElement('textarea'); + el.value = string; + document.body.appendChild(el); + el.select(); document.execCommand('copy'); - textarea.remove(); + document.body.removeChild(el); } };