mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
* Switch from lingui from i18next * Change lingui messages to i18next messages * Change lingui messages to i18next messages (grafana-ui) * Init i18n for tests
179 lines
5.9 KiB
TypeScript
179 lines
5.9 KiB
TypeScript
import React, { PureComponent } from 'react';
|
|
|
|
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
|
|
import { reportInteraction } from '@grafana/runtime/src';
|
|
import { Alert, ClipboardButton, Field, FieldSet, Icon, Input, Switch } from '@grafana/ui';
|
|
import config from 'app/core/config';
|
|
import { t, Trans } from 'app/core/internationalization';
|
|
|
|
import { ThemePicker } from './ThemePicker';
|
|
import { ShareModalTabProps } from './types';
|
|
import { buildImageUrl, buildShareUrl } from './utils';
|
|
|
|
export interface Props extends ShareModalTabProps {}
|
|
|
|
export interface State {
|
|
useCurrentTimeRange: boolean;
|
|
useShortUrl: boolean;
|
|
selectedTheme: string;
|
|
shareUrl: string;
|
|
imageUrl: string;
|
|
}
|
|
|
|
export class ShareLink extends PureComponent<Props, State> {
|
|
constructor(props: Props) {
|
|
super(props);
|
|
this.state = {
|
|
useCurrentTimeRange: true,
|
|
useShortUrl: false,
|
|
selectedTheme: 'current',
|
|
shareUrl: '',
|
|
imageUrl: '',
|
|
};
|
|
}
|
|
|
|
componentDidMount() {
|
|
reportInteraction('grafana_dashboards_link_share_viewed');
|
|
this.buildUrl();
|
|
}
|
|
|
|
componentDidUpdate(prevProps: Props, prevState: State) {
|
|
const { useCurrentTimeRange, useShortUrl, selectedTheme } = this.state;
|
|
if (
|
|
prevState.useCurrentTimeRange !== useCurrentTimeRange ||
|
|
prevState.selectedTheme !== selectedTheme ||
|
|
prevState.useShortUrl !== useShortUrl
|
|
) {
|
|
this.buildUrl();
|
|
}
|
|
}
|
|
|
|
buildUrl = async () => {
|
|
const { panel, dashboard } = this.props;
|
|
const { useCurrentTimeRange, useShortUrl, selectedTheme } = this.state;
|
|
|
|
const shareUrl = await buildShareUrl(useCurrentTimeRange, selectedTheme, panel, useShortUrl);
|
|
const imageUrl = buildImageUrl(useCurrentTimeRange, dashboard.uid, selectedTheme, panel);
|
|
|
|
this.setState({ shareUrl, imageUrl });
|
|
};
|
|
|
|
onUseCurrentTimeRangeChange = () => {
|
|
this.setState({ useCurrentTimeRange: !this.state.useCurrentTimeRange });
|
|
};
|
|
|
|
onUrlShorten = () => {
|
|
this.setState({ useShortUrl: !this.state.useShortUrl });
|
|
};
|
|
|
|
onThemeChange = (value: string) => {
|
|
this.setState({ selectedTheme: value });
|
|
};
|
|
|
|
getShareUrl = () => {
|
|
return this.state.shareUrl;
|
|
};
|
|
|
|
render() {
|
|
const { panel, dashboard } = this.props;
|
|
const isRelativeTime = dashboard ? dashboard.time.to === 'now' : false;
|
|
const { useCurrentTimeRange, useShortUrl, selectedTheme, shareUrl, imageUrl } = this.state;
|
|
const selectors = e2eSelectors.pages.SharePanelModal;
|
|
const isDashboardSaved = Boolean(dashboard.id);
|
|
|
|
const timeRangeLabelTranslation = t('share-modal.link.time-range-label', `Lock time range`);
|
|
|
|
const timeRangeDescriptionTranslation = t(
|
|
'share-modal.link.time-range-description',
|
|
`Transforms the current relative time range to an absolute time range`
|
|
);
|
|
|
|
const shortenURLTranslation = t('share-modal.link.shorten-url', `Shorten URL`);
|
|
|
|
const linkURLTranslation = t('share-modal.link.link-url', `Link URL`);
|
|
|
|
return (
|
|
<>
|
|
<p className="share-modal-info-text">
|
|
<Trans i18nKey="share-modal.link.info-text">
|
|
Create a direct link to this dashboard or panel, customized with the options below.
|
|
</Trans>
|
|
</p>
|
|
<FieldSet>
|
|
<Field label={timeRangeLabelTranslation} description={isRelativeTime ? timeRangeDescriptionTranslation : ''}>
|
|
<Switch
|
|
id="share-current-time-range"
|
|
value={useCurrentTimeRange}
|
|
onChange={this.onUseCurrentTimeRangeChange}
|
|
/>
|
|
</Field>
|
|
<ThemePicker selectedTheme={selectedTheme} onChange={this.onThemeChange} />
|
|
<Field label={shortenURLTranslation}>
|
|
<Switch id="share-shorten-url" value={useShortUrl} onChange={this.onUrlShorten} />
|
|
</Field>
|
|
|
|
<Field label={linkURLTranslation}>
|
|
<Input
|
|
id="link-url-input"
|
|
value={shareUrl}
|
|
readOnly
|
|
addonAfter={
|
|
<ClipboardButton icon="copy" variant="primary" getText={this.getShareUrl}>
|
|
<Trans i18nKey="share-modal.link.copy-link-button">Copy</Trans>
|
|
</ClipboardButton>
|
|
}
|
|
/>
|
|
</Field>
|
|
</FieldSet>
|
|
|
|
{panel && config.rendererAvailable && (
|
|
<>
|
|
{isDashboardSaved && (
|
|
<div className="gf-form">
|
|
<a href={imageUrl} target="_blank" rel="noreferrer" aria-label={selectors.linkToRenderedImage}>
|
|
<Icon name="camera" />
|
|
|
|
<Trans i18nKey="share-modal.link.rendered-image">Direct link rendered image</Trans>
|
|
</a>
|
|
</div>
|
|
)}
|
|
|
|
{!isDashboardSaved && (
|
|
<Alert
|
|
severity="info"
|
|
title={t('share-modal.link.save-alert', 'Dashboard is not saved')}
|
|
bottomSpacing={0}
|
|
>
|
|
<Trans i18nKey="share-modal.link.save-dashboard">
|
|
To render a panel image, you must save the dashboard first.
|
|
</Trans>
|
|
</Alert>
|
|
)}
|
|
</>
|
|
)}
|
|
|
|
{panel && !config.rendererAvailable && (
|
|
<Alert
|
|
severity="info"
|
|
title={t('share-modal.link.render-alert', 'Image renderer plugin not installed')}
|
|
bottomSpacing={0}
|
|
>
|
|
<Trans i18nKey="share-modal.link.render-instructions">
|
|
To render a panel image, you must install the
|
|
<a
|
|
href="https://grafana.com/grafana/plugins/grafana-image-renderer"
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="external-link"
|
|
>
|
|
Grafana image renderer plugin
|
|
</a>
|
|
. Please contact your Grafana administrator to install the plugin.
|
|
</Trans>
|
|
</Alert>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
}
|