mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Internationalisation: Translate the Share modal (#52457)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { saveAs } from 'file-saver';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
@@ -134,26 +135,38 @@ export class ShareExport extends PureComponent<Props, State> {
|
||||
const { shareExternally } = this.state;
|
||||
const { trimDefaults } = this.state;
|
||||
|
||||
const exportExternallyTranslation = t({
|
||||
id: 'share-modal.export.share-externally-label',
|
||||
message: `Export for sharing externally`,
|
||||
});
|
||||
|
||||
const exportDefaultTranslation = t({
|
||||
id: 'share-modal.export.share-default-label',
|
||||
message: `Export with default values removed`,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="share-modal-info-text">Export this dashboard.</p>
|
||||
<Field label="Export for sharing externally">
|
||||
<p className="share-modal-info-text">
|
||||
<Trans id="share-modal.export.info-text">Export this dashboard.</Trans>
|
||||
</p>
|
||||
<Field label={exportExternallyTranslation}>
|
||||
<Switch id="share-externally-toggle" value={shareExternally} onChange={this.onShareExternallyChange} />
|
||||
</Field>
|
||||
{config.featureToggles.trimDefaults && (
|
||||
<Field label="Export with default values removed">
|
||||
<Field label={exportDefaultTranslation}>
|
||||
<Switch id="trim-defaults-toggle" value={trimDefaults} onChange={this.onTrimDefaultsChange} />
|
||||
</Field>
|
||||
)}
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" onClick={onDismiss} fill="outline">
|
||||
Cancel
|
||||
<Trans id="share-modal.export.cancel-button">Cancel</Trans>
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={this.onViewJson}>
|
||||
View JSON
|
||||
<Trans id="share-modal.export.view-button">View JSON</Trans>
|
||||
</Button>
|
||||
<Button variant="primary" onClick={this.onSaveAsFile}>
|
||||
Save to file
|
||||
<Trans id="share-modal.export.save-button">Save to file</Trans>
|
||||
</Button>
|
||||
</Modal.ButtonRow>
|
||||
</>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
@@ -9,12 +10,6 @@ import config from 'app/core/config';
|
||||
import { ShareModalTabProps } from './types';
|
||||
import { buildImageUrl, buildShareUrl } from './utils';
|
||||
|
||||
const themeOptions: Array<SelectableValue<string>> = [
|
||||
{ label: 'Current', value: 'current' },
|
||||
{ label: 'Dark', value: 'dark' },
|
||||
{ label: 'Light', value: 'light' },
|
||||
];
|
||||
|
||||
export interface Props extends ShareModalTabProps {}
|
||||
|
||||
export interface State {
|
||||
@@ -86,37 +81,85 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
const selectors = e2eSelectors.pages.SharePanelModal;
|
||||
const isDashboardSaved = Boolean(dashboard.id);
|
||||
|
||||
const timeRangeLabelTranslation = t({
|
||||
id: 'share-modal.link.time-range-label',
|
||||
message: `Lock time range`,
|
||||
});
|
||||
|
||||
const timeRangeDescriptionTranslation = t({
|
||||
id: 'share-modal.link.time-range-description',
|
||||
message: `Transforms the current relative time range to an absolute time range`,
|
||||
});
|
||||
|
||||
const shortenURLTranslation = t({
|
||||
id: 'share-modal.link.shorten-url',
|
||||
message: `Shorten URL`,
|
||||
});
|
||||
|
||||
const linkURLTranslation = t({
|
||||
id: 'share-modal.link.link-url',
|
||||
message: `Link URL`,
|
||||
});
|
||||
|
||||
const themeOptions: Array<SelectableValue<string>> = [
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.link.theme-current',
|
||||
message: `Current`,
|
||||
}),
|
||||
value: 'current',
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.link.theme-dark',
|
||||
message: `Dark`,
|
||||
}),
|
||||
value: 'dark',
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.link.theme-light',
|
||||
message: `Light`,
|
||||
}),
|
||||
value: 'light',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="share-modal-info-text">
|
||||
Create a direct link to this dashboard or panel, customized with the options below.
|
||||
<Trans id="share-modal.link.info-text">
|
||||
Create a direct link to this dashboard or panel, customized with the options below.
|
||||
</Trans>
|
||||
</p>
|
||||
<FieldSet>
|
||||
<Field
|
||||
label="Lock time range"
|
||||
description={isRelativeTime ? 'Transforms the current relative time range to an absolute time range' : ''}
|
||||
>
|
||||
<Field label={timeRangeLabelTranslation} description={isRelativeTime ? timeRangeDescriptionTranslation : ''}>
|
||||
<Switch
|
||||
id="share-current-time-range"
|
||||
value={useCurrentTimeRange}
|
||||
onChange={this.onUseCurrentTimeRangeChange}
|
||||
/>
|
||||
</Field>
|
||||
<Field label="Theme">
|
||||
<Field
|
||||
label={t({
|
||||
id: 'share-modal.link.theme',
|
||||
message: `Theme`,
|
||||
})}
|
||||
>
|
||||
<RadioButtonGroup options={themeOptions} value={selectedTheme} onChange={this.onThemeChange} />
|
||||
</Field>
|
||||
<Field label="Shorten URL">
|
||||
<Field label={shortenURLTranslation}>
|
||||
<Switch id="share-shorten-url" value={useShortUrl} onChange={this.onUrlShorten} />
|
||||
</Field>
|
||||
|
||||
<Field label="Link URL">
|
||||
<Field label={linkURLTranslation}>
|
||||
<Input
|
||||
id="link-url-input"
|
||||
value={shareUrl}
|
||||
readOnly
|
||||
addonAfter={
|
||||
<ClipboardButton icon="copy" variant="primary" getText={this.getShareUrl}>
|
||||
Copy
|
||||
<Trans id="share-modal.link.copy-link-button">Copy</Trans>
|
||||
</ClipboardButton>
|
||||
}
|
||||
/>
|
||||
@@ -128,31 +171,45 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
{isDashboardSaved && (
|
||||
<div className="gf-form">
|
||||
<a href={imageUrl} target="_blank" rel="noreferrer" aria-label={selectors.linkToRenderedImage}>
|
||||
<Icon name="camera" /> Direct link rendered image
|
||||
<Icon name="camera" />
|
||||
|
||||
<Trans id="share-modal.link.rendered-image">Direct link rendered image</Trans>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!isDashboardSaved && (
|
||||
<Alert severity="info" title="Dashboard is not saved" bottomSpacing={0}>
|
||||
To render a panel image, you must save the dashboard first.
|
||||
<Alert
|
||||
severity="info"
|
||||
title={t({ id: 'share-modal.link.save-alert', message: `Dashboard is not saved` })}
|
||||
bottomSpacing={0}
|
||||
>
|
||||
<Trans id="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="Image renderer plugin not installed" bottomSpacing={0}>
|
||||
<>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.
|
||||
<Alert
|
||||
severity="info"
|
||||
title={t({ id: 'share-modal.link.render-alert', message: `Image renderer plugin not installed` })}
|
||||
bottomSpacing={0}
|
||||
>
|
||||
<Trans id="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>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
@@ -12,13 +13,6 @@ import { ShareModalTabProps } from './types';
|
||||
|
||||
const snapshotApiUrl = '/api/snapshots';
|
||||
|
||||
const expireOptions: Array<SelectableValue<number>> = [
|
||||
{ label: 'Never', value: 0 },
|
||||
{ label: '1 Hour', value: 60 * 60 },
|
||||
{ label: '1 Day', value: 60 * 60 * 24 },
|
||||
{ label: '7 Days', value: 60 * 60 * 24 * 7 },
|
||||
];
|
||||
|
||||
interface Props extends ShareModalTabProps {}
|
||||
|
||||
interface State {
|
||||
@@ -36,15 +30,46 @@ interface State {
|
||||
|
||||
export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
private dashboard: DashboardModel;
|
||||
private expireOptions: Array<SelectableValue<number>>;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.dashboard = props.dashboard;
|
||||
this.expireOptions = [
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-never',
|
||||
message: `Never`,
|
||||
}),
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-hour',
|
||||
message: `1 Hour`,
|
||||
}),
|
||||
value: 60 * 60,
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-day',
|
||||
message: `1 Day`,
|
||||
}),
|
||||
value: 60 * 60 * 24,
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-week',
|
||||
message: `7 Days`,
|
||||
}),
|
||||
value: 60 * 60 * 24 * 7,
|
||||
},
|
||||
];
|
||||
this.state = {
|
||||
isLoading: false,
|
||||
step: 1,
|
||||
selectedExpireOption: expireOptions[0],
|
||||
snapshotExpires: expireOptions[0].value,
|
||||
selectedExpireOption: this.expireOptions[0],
|
||||
snapshotExpires: this.expireOptions[0].value,
|
||||
snapshotName: props.dashboard.title,
|
||||
timeoutSeconds: 4,
|
||||
snapshotUrl: '',
|
||||
@@ -202,42 +227,63 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
const { snapshotName, selectedExpireOption, timeoutSeconds, isLoading, sharingButtonText, externalEnabled } =
|
||||
this.state;
|
||||
|
||||
const snapshotNameTranslation = t({
|
||||
id: 'share-modal.snapshot.name',
|
||||
message: `Snapshot name`,
|
||||
});
|
||||
|
||||
const expireTranslation = t({
|
||||
id: 'share-modal.snapshot.expire',
|
||||
message: `Expire`,
|
||||
});
|
||||
|
||||
const timeoutTranslation = t({
|
||||
id: 'share-modal.snapshot.timeout',
|
||||
message: `Timeout (seconds)`,
|
||||
});
|
||||
|
||||
const timeoutDescriptionTranslation = t({
|
||||
id: 'share-modal.snapshot.timeout-description',
|
||||
message: `You might need to configure the timeout value if it takes a long time to collect your dashboard
|
||||
metrics.`,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<p className="share-modal-info-text">
|
||||
A snapshot is an instant way to share an interactive dashboard publicly. When created, we strip sensitive
|
||||
data like queries (metric, template, and annotation) and panel links, leaving only the visible metric data
|
||||
and series names embedded in your dashboard.
|
||||
<Trans id="share-modal.snapshot.info-text-1">
|
||||
A snapshot is an instant way to share an interactive dashboard publicly. When created, we strip sensitive
|
||||
data like queries (metric, template, and annotation) and panel links, leaving only the visible metric data
|
||||
and series names embedded in your dashboard.
|
||||
</Trans>
|
||||
</p>
|
||||
<p className="share-modal-info-text">
|
||||
Keep in mind, your snapshot <em>can be viewed by anyone</em> that has the link and can access the URL. Share
|
||||
wisely.
|
||||
<Trans id="share-modal.snapshot.info-text-2">
|
||||
Keep in mind, your snapshot <em>can be viewed by anyone</em> that has the link and can access the URL.
|
||||
Share wisely.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<Field label="Snapshot name">
|
||||
<Field label={snapshotNameTranslation}>
|
||||
<Input id="snapshot-name-input" width={30} value={snapshotName} onChange={this.onSnapshotNameChange} />
|
||||
</Field>
|
||||
<Field label="Expire">
|
||||
<Field label={expireTranslation}>
|
||||
<Select
|
||||
inputId="expire-select-input"
|
||||
width={30}
|
||||
options={expireOptions}
|
||||
options={this.expireOptions}
|
||||
value={selectedExpireOption}
|
||||
onChange={this.onExpireChange}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
label="Timeout (seconds)"
|
||||
description="You might need to configure the timeout value if it takes a long time to collect your dashboard
|
||||
metrics."
|
||||
>
|
||||
<Field label={timeoutTranslation} description={timeoutDescriptionTranslation}>
|
||||
<Input id="timeout-input" type="number" width={21} value={timeoutSeconds} onChange={this.onTimeoutChange} />
|
||||
</Field>
|
||||
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" onClick={onDismiss} fill="outline">
|
||||
Cancel
|
||||
<Trans id="share-modal.snapshot.cancel-button">Cancel</Trans>
|
||||
</Button>
|
||||
{externalEnabled && (
|
||||
<Button variant="secondary" disabled={isLoading} onClick={this.createSnapshot(true)}>
|
||||
@@ -245,7 +291,7 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
</Button>
|
||||
)}
|
||||
<Button variant="primary" disabled={isLoading} onClick={this.createSnapshot()}>
|
||||
Local Snapshot
|
||||
<Trans id="share-modal.snapshot.local-button">Local Snapshot</Trans>
|
||||
</Button>
|
||||
</Modal.ButtonRow>
|
||||
</>
|
||||
@@ -264,16 +310,16 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
readOnly
|
||||
addonAfter={
|
||||
<ClipboardButton icon="copy" variant="primary" getText={this.getSnapshotUrl}>
|
||||
Copy
|
||||
<Trans id="share-modal.snapshot.copy-link-button">Copy</Trans>
|
||||
</ClipboardButton>
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<div className="pull-right" style={{ padding: '5px' }}>
|
||||
Did you make a mistake?{' '}
|
||||
<Trans id="share-modal.snapshot.mistake-message">Did you make a mistake? </Trans>
|
||||
<LinkButton fill="text" target="_blank" onClick={this.deleteSnapshot}>
|
||||
Delete snapshot.
|
||||
<Trans id="share-modal.snapshot.delete-button">Delete snapshot.</Trans>
|
||||
</LinkButton>
|
||||
</div>
|
||||
</>
|
||||
@@ -284,8 +330,10 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-header">
|
||||
<p className="share-modal-info-text">
|
||||
The snapshot has been deleted. If you have already accessed it once, then it might take up to an hour before
|
||||
before it is removed from browser caches or CDN caches.
|
||||
<Trans id="share-modal.snapshot.deleted-message">
|
||||
The snapshot has been deleted. If you have already accessed it once, then it might take up to an hour before
|
||||
before it is removed from browser caches or CDN caches.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user