From db071e49392058c1667c2bf12296c5079d4a486a Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Wed, 14 Oct 2020 17:08:27 +0200 Subject: [PATCH] Explore: Allow shortlink generation (#28222) * Add short link functionality to Explore and Rich history * Update documentation * Implement short url for explore * Implement short link in Rich history * Update docs * Add error alert --- docs/sources/explore/index.md | 10 ++++++-- public/app/core/utils/explore.ts | 9 ++++++++ public/app/core/utils/richHistory.ts | 9 -------- .../app/features/explore/ExploreToolbar.tsx | 22 +++++++++++++++++- .../explore/RichHistory/RichHistoryCard.tsx | 19 ++++++++++----- public/app/features/explore/utils/links.ts | 23 ++++++++++++++++++- 6 files changed, 73 insertions(+), 19 deletions(-) diff --git a/docs/sources/explore/index.md b/docs/sources/explore/index.md index 2530a3aae5f..7dca10ce46c 100644 --- a/docs/sources/explore/index.md +++ b/docs/sources/explore/index.md @@ -49,9 +49,15 @@ In split view, timepickers for both panels can be linked (if you change one, the You can close the newly created query by clicking on the Close Split button. +## Share shortened link + +> Share shortened link is only available in Grafana 7.3 and above. + +The Share shortened link capability allows you to create smaller and simpler URLs of the format /goto/:uid instead of using longer URLs containing complex query parameters. You can create a shortened link by clicking on the **Share** option in Explore toolbar. + ## Query history -Query history is a list of queries that you have used in Explore. The history is local to your browser and is not shared with others. To open and interact with your history, click the **Query history** button in Explore. +Query history is a list of queries that you have used in Explore. The history is local to your browser and is not shared. To open and interact with your history, click the **Query history** button in Explore. ### View query history @@ -60,7 +66,7 @@ Query history lets you view the history of your querying. For each individual qu - Run a query. - Create and/or edit a comment. - Copy a query to the clipboard. -- Copy a URL link with the query to the clipboard. +- Copy a shortened link with the query to the clipboard. - Star a query. ### Manage favorite queries diff --git a/public/app/core/utils/explore.ts b/public/app/core/utils/explore.ts index b801ba3453d..624881ea6dc 100644 --- a/public/app/core/utils/explore.ts +++ b/public/app/core/utils/explore.ts @@ -481,3 +481,12 @@ export const getFirstNonQueryRowSpecificError = (queryErrors?: DataQueryError[]) const refId = getValueWithRefId(queryErrors); return refId ? undefined : getFirstQueryErrorWithoutRefId(queryErrors); }; + +export const copyStringToClipboard = (string: string) => { + const el = document.createElement('textarea'); + el.value = string; + document.body.appendChild(el); + el.select(); + document.execCommand('copy'); + document.body.removeChild(el); +}; diff --git a/public/app/core/utils/richHistory.ts b/public/app/core/utils/richHistory.ts index b0eb3e7b97e..2ad5fb00f98 100644 --- a/public/app/core/utils/richHistory.ts +++ b/public/app/core/utils/richHistory.ts @@ -170,15 +170,6 @@ export const sortQueries = (array: RichHistoryQuery[], sortOrder: SortOrder) => return array.sort(sortFunc); }; -export const copyStringToClipboard = (string: string) => { - const el = document.createElement('textarea'); - el.value = string; - document.body.appendChild(el); - el.select(); - document.execCommand('copy'); - document.body.removeChild(el); -}; - export const createUrlFromRichHistory = (query: RichHistoryQuery) => { const exploreState: ExploreUrlState = { /* Default range, as we are not saving timerange in rich history */ diff --git a/public/app/features/explore/ExploreToolbar.tsx b/public/app/features/explore/ExploreToolbar.tsx index 210316f8753..6e8a5125053 100644 --- a/public/app/features/explore/ExploreToolbar.tsx +++ b/public/app/features/explore/ExploreToolbar.tsx @@ -7,9 +7,11 @@ import { css } from 'emotion'; import { ExploreId, ExploreItemState } from 'app/types/explore'; import { Icon, IconButton, LegacyForms, SetInterval, Tooltip } from '@grafana/ui'; -import { DataQuery, RawTimeRange, TimeRange, TimeZone } from '@grafana/data'; +import { DataQuery, RawTimeRange, TimeRange, TimeZone, AppEvents } from '@grafana/data'; import { DataSourcePicker } from 'app/core/components/Select/DataSourcePicker'; import { StoreState } from 'app/types/store'; +import { copyStringToClipboard } from 'app/core/utils/explore'; +import appEvents from 'app/core/app_events'; import { cancelQueries, changeDatasource, @@ -25,6 +27,7 @@ import { getTimeZone } from '../profile/state/selectors'; import { updateTimeZoneForSession } from '../profile/state/reducers'; import { getDashboardSrv } from '../dashboard/services/DashboardSrv'; import kbn from '../../core/utils/kbn'; +import { createShortLink } from './utils/links'; import { ExploreTimeControls } from './ExploreTimeControls'; import { LiveTailButton } from './LiveTailButton'; import { ResponsiveButton } from './ResponsiveButton'; @@ -152,6 +155,16 @@ export class UnConnectedExploreToolbar extends PureComponent { return datasourceName ? exploreDatasources.find(datasource => datasource.name === datasourceName) : undefined; }; + copyAndSaveShortLink = async () => { + const shortLink = await createShortLink(window.location.href); + if (shortLink) { + copyStringToClipboard(shortLink); + appEvents.emit(AppEvents.alertSuccess, ['Shortened link copied to clipboard']); + } else { + appEvents.emit(AppEvents.alertError, ['Error generating shortened link']); + } + }; + render() { const { datasourceMissing, @@ -262,6 +275,13 @@ export class UnConnectedExploreToolbar extends PureComponent { /> ) : null} +
+ + + +
{!isLive && (
{ - const url = createUrlFromRichHistory(query); - copyStringToClipboard(url); - appEvents.emit(AppEvents.alertSuccess, ['Link copied to clipboard']); + const onCreateLink = async () => { + const link = createUrlFromRichHistory(query); + const shortLink = await createShortLink(link); + if (shortLink) { + copyStringToClipboard(shortLink); + appEvents.emit(AppEvents.alertSuccess, ['Shortened link copied to clipboard']); + } else { + appEvents.emit(AppEvents.alertError, ['Error generating shortened link']); + } }; const onDeleteQuery = () => { @@ -254,7 +261,7 @@ export function RichHistoryCard(props: Props) { title={query.comment?.length > 0 ? 'Edit comment' : 'Add comment'} /> - {!isRemoved && } + {!isRemoved && }