mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
I18n: Migrate to I18next (#55845)
* Switch from lingui from i18next * Change lingui messages to i18next messages * Change lingui messages to i18next messages (grafana-ui) * Init i18n for tests
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { t, Trans } from '@lingui/macro';
|
||||
import React, { FC, ReactNode } from 'react';
|
||||
import { connect, ConnectedProps } from 'react-redux';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
@@ -20,6 +19,7 @@ import { NavToolbarSeparator } from 'app/core/components/AppChrome/NavToolbarSep
|
||||
import config from 'app/core/config';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { useBusEvent } from 'app/core/hooks/useBusEvent';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { DashboardCommentsModal } from 'app/features/dashboard/components/DashboardComments/DashboardCommentsModal';
|
||||
import { SaveDashboardDrawer } from 'app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer';
|
||||
import { ShareModal } from 'app/features/dashboard/components/ShareModal';
|
||||
@@ -139,8 +139,8 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
|
||||
if (canStar) {
|
||||
let desc = isStarred
|
||||
? t({ id: 'dashboard.toolbar.unmark-favorite', message: 'Unmark as favorite' })
|
||||
: t({ id: 'dashboard.toolbar.mark-favorite', message: 'Mark as favorite' });
|
||||
? t('dashboard.toolbar.unmark-favorite', 'Unmark as favorite')
|
||||
: t('dashboard.toolbar.mark-favorite', 'Mark as favorite');
|
||||
buttons.push(
|
||||
<DashNavButton
|
||||
tooltip={desc}
|
||||
@@ -158,7 +158,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
<ModalsController key="button-share">
|
||||
{({ showModal, hideModal }) => (
|
||||
<DashNavButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.share', message: 'Share dashboard or panel' })}
|
||||
tooltip={t('dashboard.toolbar.share', 'Share dashboard or panel')}
|
||||
icon="share-alt"
|
||||
iconSize="lg"
|
||||
onClick={() => {
|
||||
@@ -184,7 +184,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
<ModalsController key="button-dashboard-comments">
|
||||
{({ showModal, hideModal }) => (
|
||||
<DashNavButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.comments-show', message: 'Show dashboard comments' })}
|
||||
tooltip={t('dashboard.toolbar.comments-show', 'Show dashboard comments')}
|
||||
icon="comment-alt-message"
|
||||
iconSize="lg"
|
||||
onClick={() => {
|
||||
@@ -207,16 +207,16 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
return (
|
||||
<ButtonGroup key="playlist-buttons">
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.playlist-previous', message: 'Go to previous dashboard' })}
|
||||
tooltip={t('dashboard.toolbar.playlist-previous', 'Go to previous dashboard')}
|
||||
icon="backward"
|
||||
onClick={onPlaylistPrev}
|
||||
narrow
|
||||
/>
|
||||
<ToolbarButton onClick={onPlaylistStop}>
|
||||
<Trans id="dashboard.toolbar.playlist-stop">Stop playlist</Trans>
|
||||
<Trans i18nKey="dashboard.toolbar.playlist-stop">Stop playlist</Trans>
|
||||
</ToolbarButton>
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.playlist-next', message: 'Go to next dashboard' })}
|
||||
tooltip={t('dashboard.toolbar.playlist-next', 'Go to next dashboard')}
|
||||
icon="forward"
|
||||
onClick={onPlaylistNext}
|
||||
narrow
|
||||
@@ -245,7 +245,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
const buttons: ReactNode[] = [];
|
||||
const tvButton = config.featureToggles.topnav ? null : (
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.tv-button', message: 'Cycle view mode' })}
|
||||
tooltip={t('dashboard.toolbar.tv-button', 'Cycle view mode')}
|
||||
icon="monitor"
|
||||
onClick={onToggleTVMode}
|
||||
key="tv-button"
|
||||
@@ -263,7 +263,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
if (canEdit && !isFullscreen) {
|
||||
buttons.push(
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.add-panel', message: 'Add panel' })}
|
||||
tooltip={t('dashboard.toolbar.add-panel', 'Add panel')}
|
||||
icon="panel-add"
|
||||
onClick={onAddPanel}
|
||||
key="button-panel-add"
|
||||
@@ -276,7 +276,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
<ModalsController key="button-save">
|
||||
{({ showModal, hideModal }) => (
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.save', message: 'Save dashboard' })}
|
||||
tooltip={t('dashboard.toolbar.save', 'Save dashboard')}
|
||||
icon="save"
|
||||
onClick={() => {
|
||||
showModal(SaveDashboardDrawer, {
|
||||
@@ -293,7 +293,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
if (snapshotUrl) {
|
||||
buttons.push(
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.open-original', message: 'Open original dashboard' })}
|
||||
tooltip={t('dashboard.toolbar.open-original', 'Open original dashboard')}
|
||||
onClick={() => gotoSnapshotOrigin(snapshotUrl)}
|
||||
icon="link"
|
||||
key="button-snapshot"
|
||||
@@ -304,7 +304,7 @@ export const DashNav = React.memo<Props>((props) => {
|
||||
if (showSettings) {
|
||||
buttons.push(
|
||||
<ToolbarButton
|
||||
tooltip={t({ id: 'dashboard.toolbar.settings', message: 'Dashboard settings' })}
|
||||
tooltip={t('dashboard.toolbar.settings', 'Dashboard settings')}
|
||||
icon="cog"
|
||||
onClick={onOpenSettings}
|
||||
key="button-settings"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import React, { Component } from 'react';
|
||||
import { Unsubscribable } from 'rxjs';
|
||||
|
||||
@@ -7,6 +6,7 @@ import { TimeRangeUpdatedEvent } from '@grafana/runtime';
|
||||
import { defaultIntervals, RefreshPicker } from '@grafana/ui';
|
||||
import { TimePickerWithHistory } from 'app/core/components/TimePicker/TimePickerWithHistory';
|
||||
import { appEvents } from 'app/core/core';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
|
||||
import { ShiftTimeEvent, ShiftTimeEventDirection, ZoomOutEvent } from '../../../../types/events';
|
||||
@@ -107,20 +107,20 @@ export class DashNavTimeControls extends Component<Props> {
|
||||
value={dashboard.refresh}
|
||||
intervals={intervals}
|
||||
isOnCanvas={isOnCanvas}
|
||||
tooltip={t({ id: 'dashboard.toolbar.refresh', message: 'Refresh dashboard' })}
|
||||
tooltip={t('dashboard.toolbar.refresh', 'Refresh dashboard')}
|
||||
noIntervalPicker={hideIntervalPicker}
|
||||
offDescriptionAriaLabelMsg={t({
|
||||
id: 'dashboard.refresh-picker.off-description',
|
||||
message: 'Auto refresh turned off. Choose refresh time interval',
|
||||
})}
|
||||
offDescriptionAriaLabelMsg={t(
|
||||
'dashboard.refresh-picker.off-description',
|
||||
'Auto refresh turned off. Choose refresh time interval'
|
||||
)}
|
||||
onDescriptionAriaLabelMsg={(durationAriaLabel) =>
|
||||
t({
|
||||
id: 'dashboard.refresh-picker.on-description',
|
||||
message: `Choose refresh time interval with current interval ${durationAriaLabel} selected`,
|
||||
})
|
||||
t(
|
||||
'dashboard.refresh-picker.on-description',
|
||||
`Choose refresh time interval with current interval ${durationAriaLabel} selected`
|
||||
)
|
||||
}
|
||||
offOptionLabelMsg={t({ id: 'dashboard.refresh-picker.off-label', message: 'Off' })}
|
||||
offOptionAriaLabelMsg={t({ id: 'dashboard.refresh-picker.off-arialabel', message: 'Turn off auto refresh' })}
|
||||
offOptionLabelMsg={t('dashboard.refresh-picker.off-label', 'Off')}
|
||||
offOptionAriaLabelMsg={t('dashboard.refresh-picker.off-arialabel', 'Turn off auto refresh')}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { CoreApp, DataSourceApi, formattedValueToString, getValueFormat, PanelData, PanelPlugin } from '@grafana/data';
|
||||
import { getTemplateSrv } from '@grafana/runtime';
|
||||
import { Drawer, Tab, TabsBar } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { InspectDataTab } from 'app/features/inspector/InspectDataTab';
|
||||
import { InspectErrorTab } from 'app/features/inspector/InspectErrorTab';
|
||||
import { InspectJSONTab } from 'app/features/inspector/InspectJSONTab';
|
||||
@@ -59,10 +59,7 @@ export const InspectContent = ({
|
||||
}
|
||||
|
||||
const panelTitle = getTemplateSrv().replace(panel.title, panel.scopedVars, 'text') || 'Panel';
|
||||
const title = t({
|
||||
id: 'dashboard.inspect.title',
|
||||
message: `Inspect: ${panelTitle}`,
|
||||
});
|
||||
const title = t('dashboard.inspect.title', 'Inspect: {{panelTitle}}', { panelTitle });
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
@@ -74,13 +71,13 @@ export const InspectContent = ({
|
||||
scrollableContent
|
||||
tabs={
|
||||
<TabsBar>
|
||||
{tabs.map((t, index) => {
|
||||
{tabs.map((tab, index) => {
|
||||
return (
|
||||
<Tab
|
||||
key={`${t.value}-${index}`}
|
||||
label={t.label}
|
||||
active={t.value === activeTab}
|
||||
onChangeTab={() => setCurrentTab(t.value || InspectTab.Data)}
|
||||
key={`${tab.value}-${index}`}
|
||||
label={tab.label}
|
||||
active={tab.value === activeTab}
|
||||
onChangeTab={() => setCurrentTab(tab.value || InspectTab.Data)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -124,8 +121,9 @@ function formatStats(data: PanelData) {
|
||||
const requestTime = request.endTime ? request.endTime - request.startTime : 0;
|
||||
const formatted = formattedValueToString(getValueFormat('ms')(requestTime));
|
||||
|
||||
return t({
|
||||
id: 'dashboard.inspect.subtitle',
|
||||
message: `${queryCount} queries with total query time of ${formatted}`,
|
||||
});
|
||||
return (
|
||||
<Trans i18nKey="dashboard.inspect.subtitle">
|
||||
{{ queryCount }} queries with total query time of {{ formatted }}
|
||||
</Trans>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import { useMemo } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
|
||||
import { DataQueryError, DataSourceApi, PanelData, PanelPlugin } from '@grafana/data';
|
||||
import { getDataSourceSrv } from '@grafana/runtime';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { InspectTab } from 'app/features/inspector/types';
|
||||
|
||||
@@ -48,18 +48,18 @@ export const useInspectTabs = (
|
||||
return useMemo(() => {
|
||||
const tabs = [];
|
||||
if (supportsDataQuery(plugin)) {
|
||||
tabs.push({ label: t({ id: 'dashboard.inspect.data-tab', message: 'Data' }), value: InspectTab.Data });
|
||||
tabs.push({ label: t({ id: 'dashboard.inspect.stats-tab', message: 'Stats' }), value: InspectTab.Stats });
|
||||
tabs.push({ label: t('dashboard.inspect.data-tab', 'Data'), value: InspectTab.Data });
|
||||
tabs.push({ label: t('dashboard.inspect.stats-tab', 'Stats'), value: InspectTab.Stats });
|
||||
}
|
||||
|
||||
if (metaDs) {
|
||||
tabs.push({ label: t({ id: 'dashboard.inspect.meta-tab', message: 'Meta Data' }), value: InspectTab.Meta });
|
||||
tabs.push({ label: t('dashboard.inspect.meta-tab', 'Meta Data'), value: InspectTab.Meta });
|
||||
}
|
||||
|
||||
tabs.push({ label: t({ id: 'dashboard.inspect.json-tab', message: 'JSON' }), value: InspectTab.JSON });
|
||||
tabs.push({ label: t('dashboard.inspect.json-tab', 'JSON'), value: InspectTab.JSON });
|
||||
|
||||
if (error && error.message) {
|
||||
tabs.push({ label: t({ id: 'dashboard.inspect.error-tab', message: 'Error' }), value: InspectTab.Error });
|
||||
tabs.push({ label: t('dashboard.inspect.error-tab', 'Error'), value: InspectTab.Error });
|
||||
}
|
||||
|
||||
// This is a quick internal hack to allow custom actions in inspect
|
||||
@@ -67,13 +67,13 @@ export const useInspectTabs = (
|
||||
const supplier = (window as any).grafanaPanelInspectActionSupplier as PanelInspectActionSupplier;
|
||||
if (supplier && supplier.getActions(panel)?.length) {
|
||||
tabs.push({
|
||||
label: t({ id: 'dashboard.inspect.actions-tab', message: 'Actions' }),
|
||||
label: t('dashboard.inspect.actions-tab', 'Actions'),
|
||||
value: InspectTab.Actions,
|
||||
});
|
||||
}
|
||||
|
||||
if (dashboard.meta.canEdit && supportsDataQuery(plugin)) {
|
||||
tabs.push({ label: t({ id: 'dashboard.inspect.query-tab', message: 'Query' }), value: InspectTab.Query });
|
||||
tabs.push({ label: t('dashboard.inspect.query-tab', 'Query'), value: InspectTab.Query });
|
||||
}
|
||||
return tabs;
|
||||
}, [panel, plugin, metaDs, dashboard, error]);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { t, Trans } from '@lingui/macro';
|
||||
import React, { FormEvent, PureComponent } from 'react';
|
||||
|
||||
import { reportInteraction } from '@grafana/runtime/src';
|
||||
import { ClipboardButton, Field, Modal, Switch, TextArea } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ThemePicker } from './ThemePicker';
|
||||
import { ShareModalTabProps } from './types';
|
||||
@@ -65,21 +65,18 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
const isRelativeTime = this.props.dashboard ? this.props.dashboard.time.to === 'now' : false;
|
||||
|
||||
const timeRangeDescription = isRelativeTime
|
||||
? t({
|
||||
id: 'share-modal.embed.time-range-description',
|
||||
message: 'Transforms the current relative time range to an absolute time range',
|
||||
})
|
||||
? t(
|
||||
'share-modal.embed.time-range-description',
|
||||
'Transforms the current relative time range to an absolute time range'
|
||||
)
|
||||
: '';
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="share-modal-info-text">
|
||||
<Trans id="share-modal.embed.info">Generate HTML for embedding an iframe with this panel.</Trans>
|
||||
<Trans i18nKey="share-modal.embed.info">Generate HTML for embedding an iframe with this panel.</Trans>
|
||||
</p>
|
||||
<Field
|
||||
label={t({ id: 'share-modal.embed.time-range', message: 'Current time range' })}
|
||||
description={timeRangeDescription}
|
||||
>
|
||||
<Field label={t('share-modal.embed.time-range', 'Current time range')} description={timeRangeDescription}>
|
||||
<Switch
|
||||
id="share-current-time-range"
|
||||
value={useCurrentTimeRange}
|
||||
@@ -88,13 +85,11 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
</Field>
|
||||
<ThemePicker selectedTheme={selectedTheme} onChange={this.onThemeChange} />
|
||||
<Field
|
||||
label={t({ id: 'share-modal.embed.html', message: 'Embed HTML' })}
|
||||
description={
|
||||
<Trans id="share-modal.embed.html-description">
|
||||
The HTML code below can be pasted and included in another web page. Unless anonymous access is enabled,
|
||||
the user viewing that page need to be signed into Grafana for the graph to load.
|
||||
</Trans>
|
||||
}
|
||||
label={t('share-modal.embed.html', 'Embed HTML')}
|
||||
description={t(
|
||||
'share-modal.embed.html-description',
|
||||
'The HTML code below can be pasted and included in another web page. Unless anonymous access is enabled, the user viewing that page need to be signed into Grafana for the graph to load.'
|
||||
)}
|
||||
>
|
||||
<TextArea
|
||||
data-testid="share-embed-html"
|
||||
@@ -106,7 +101,7 @@ export class ShareEmbed extends PureComponent<Props, State> {
|
||||
</Field>
|
||||
<Modal.ButtonRow>
|
||||
<ClipboardButton icon="copy" variant="primary" getText={this.getIframeHtml}>
|
||||
<Trans id="share-modal.embed.copy">Copy to clipboard</Trans>
|
||||
<Trans i18nKey="share-modal.embed.copy">Copy to clipboard</Trans>
|
||||
</ClipboardButton>
|
||||
</Modal.ButtonRow>
|
||||
</>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { saveAs } from 'file-saver';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { config, reportInteraction } from '@grafana/runtime';
|
||||
import { Button, Field, Modal, Switch } from '@grafana/ui';
|
||||
import { appEvents } from 'app/core/core';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { DashboardExporter } from 'app/features/dashboard/components/DashExportModal';
|
||||
import { ShowModalReactEvent } from 'app/types/events';
|
||||
@@ -135,20 +135,14 @@ 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 exportExternallyTranslation = t('share-modal.export.share-externally-label', `Export for sharing externally`);
|
||||
|
||||
const exportDefaultTranslation = t({
|
||||
id: 'share-modal.export.share-default-label',
|
||||
message: `Export with default values removed`,
|
||||
});
|
||||
const exportDefaultTranslation = t('share-modal.export.share-default-label', `Export with default values removed`);
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="share-modal-info-text">
|
||||
<Trans id="share-modal.export.info-text">Export this dashboard.</Trans>
|
||||
<Trans i18nKey="share-modal.export.info-text">Export this dashboard.</Trans>
|
||||
</p>
|
||||
<Field label={exportExternallyTranslation}>
|
||||
<Switch id="share-externally-toggle" value={shareExternally} onChange={this.onShareExternallyChange} />
|
||||
@@ -160,13 +154,13 @@ export class ShareExport extends PureComponent<Props, State> {
|
||||
)}
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" onClick={onDismiss} fill="outline">
|
||||
<Trans id="share-modal.export.cancel-button">Cancel</Trans>
|
||||
<Trans i18nKey="share-modal.export.cancel-button">Cancel</Trans>
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={this.onViewJson}>
|
||||
<Trans id="share-modal.export.view-button">View JSON</Trans>
|
||||
<Trans i18nKey="share-modal.export.view-button">View JSON</Trans>
|
||||
</Button>
|
||||
<Button variant="primary" onClick={this.onSaveAsFile}>
|
||||
<Trans id="share-modal.export.save-button">Save to file</Trans>
|
||||
<Trans i18nKey="share-modal.export.save-button">Save to file</Trans>
|
||||
</Button>
|
||||
</Modal.ButtonRow>
|
||||
</>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Trans } from '@lingui/macro';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import { reportInteraction } from '@grafana/runtime/src';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { AddLibraryPanelContents } from 'app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal';
|
||||
|
||||
import { ShareModalTabProps } from './types';
|
||||
@@ -22,7 +22,7 @@ export const ShareLibraryPanel = ({ panel, initialFolderId, onDismiss }: Props)
|
||||
return (
|
||||
<>
|
||||
<p className="share-modal-info-text">
|
||||
<Trans id="share-modal.library.info">Create library panel.</Trans>
|
||||
<Trans i18nKey="share-modal.library.info">Create library panel.</Trans>
|
||||
</p>
|
||||
<AddLibraryPanelContents panel={panel} initialFolderId={initialFolderId} onDismiss={onDismiss!} />
|
||||
</>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
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';
|
||||
@@ -81,30 +81,21 @@ 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 timeRangeLabelTranslation = t('share-modal.link.time-range-label', `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 timeRangeDescriptionTranslation = t(
|
||||
'share-modal.link.time-range-description',
|
||||
`Transforms the current relative time range to an absolute time range`
|
||||
);
|
||||
|
||||
const shortenURLTranslation = t({
|
||||
id: 'share-modal.link.shorten-url',
|
||||
message: `Shorten URL`,
|
||||
});
|
||||
const shortenURLTranslation = t('share-modal.link.shorten-url', `Shorten URL`);
|
||||
|
||||
const linkURLTranslation = t({
|
||||
id: 'share-modal.link.link-url',
|
||||
message: `Link URL`,
|
||||
});
|
||||
const linkURLTranslation = t('share-modal.link.link-url', `Link URL`);
|
||||
|
||||
return (
|
||||
<>
|
||||
<p className="share-modal-info-text">
|
||||
<Trans id="share-modal.link.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>
|
||||
@@ -128,7 +119,7 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
readOnly
|
||||
addonAfter={
|
||||
<ClipboardButton icon="copy" variant="primary" getText={this.getShareUrl}>
|
||||
<Trans id="share-modal.link.copy-link-button">Copy</Trans>
|
||||
<Trans i18nKey="share-modal.link.copy-link-button">Copy</Trans>
|
||||
</ClipboardButton>
|
||||
}
|
||||
/>
|
||||
@@ -142,7 +133,7 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
<a href={imageUrl} target="_blank" rel="noreferrer" aria-label={selectors.linkToRenderedImage}>
|
||||
<Icon name="camera" />
|
||||
|
||||
<Trans id="share-modal.link.rendered-image">Direct link rendered image</Trans>
|
||||
<Trans i18nKey="share-modal.link.rendered-image">Direct link rendered image</Trans>
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
@@ -150,10 +141,10 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
{!isDashboardSaved && (
|
||||
<Alert
|
||||
severity="info"
|
||||
title={t({ id: 'share-modal.link.save-alert', message: `Dashboard is not saved` })}
|
||||
title={t('share-modal.link.save-alert', 'Dashboard is not saved')}
|
||||
bottomSpacing={0}
|
||||
>
|
||||
<Trans id="share-modal.link.save-dashboard">
|
||||
<Trans i18nKey="share-modal.link.save-dashboard">
|
||||
To render a panel image, you must save the dashboard first.
|
||||
</Trans>
|
||||
</Alert>
|
||||
@@ -164,10 +155,10 @@ export class ShareLink extends PureComponent<Props, State> {
|
||||
{panel && !config.rendererAvailable && (
|
||||
<Alert
|
||||
severity="info"
|
||||
title={t({ id: 'share-modal.link.render-alert', message: `Image renderer plugin not installed` })}
|
||||
title={t('share-modal.link.render-alert', 'Image renderer plugin not installed')}
|
||||
bottomSpacing={0}
|
||||
>
|
||||
<Trans id="share-modal.link.render-instructions">
|
||||
<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"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import React from 'react';
|
||||
|
||||
import { reportInteraction } from '@grafana/runtime/src';
|
||||
import { Modal, ModalTabsHeader, TabContent } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { SharePublicDashboard } from 'app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
import { isPanelModelLibraryPanel } from 'app/features/library-panels/guard';
|
||||
@@ -38,25 +38,25 @@ function getInitialState(props: Props): State {
|
||||
function getTabs(props: Props) {
|
||||
const { panel } = props;
|
||||
|
||||
const linkLabel = t({ id: 'share-modal.tab-title.link', message: 'Link' });
|
||||
const linkLabel = t('share-modal.tab-title.link', 'Link');
|
||||
const tabs: ShareModalTabModel[] = [{ label: linkLabel, value: 'link', component: ShareLink }];
|
||||
|
||||
if (contextSrv.isSignedIn) {
|
||||
const snapshotLabel = t({ id: 'share-modal.tab-title.snapshot', message: 'Snapshot' });
|
||||
const snapshotLabel = t('share-modal.tab-title.snapshot', 'Snapshot');
|
||||
tabs.push({ label: snapshotLabel, value: 'snapshot', component: ShareSnapshot });
|
||||
}
|
||||
|
||||
if (panel) {
|
||||
const embedLabel = t({ id: 'share-modal.tab-title.embed', message: 'Embed' });
|
||||
const embedLabel = t('share-modal.tab-title.embed', 'Embed');
|
||||
tabs.push({ label: embedLabel, value: 'embed', component: ShareEmbed });
|
||||
|
||||
if (!isPanelModelLibraryPanel(panel)) {
|
||||
const libraryPanelLabel = t({ id: 'share-modal.tab-title.library-panel', message: 'Library panel' });
|
||||
const libraryPanelLabel = t('share-modal.tab-title.library-panel', 'Library panel');
|
||||
tabs.push({ label: libraryPanelLabel, value: 'library_panel', component: ShareLibraryPanel });
|
||||
}
|
||||
tabs.push(...customPanelTabs);
|
||||
} else {
|
||||
const exportLabel = t({ id: 'share-modal.tab-title.export', message: 'Export' });
|
||||
const exportLabel = t('share-modal.tab-title.export', 'Export');
|
||||
tabs.push({ label: exportLabel, value: 'export', component: ShareExport });
|
||||
tabs.push(...customDashboardTabs);
|
||||
}
|
||||
@@ -106,15 +106,7 @@ export class ShareModal extends React.Component<Props, State> {
|
||||
renderTitle() {
|
||||
const { panel } = this.props;
|
||||
const { activeTab } = this.state;
|
||||
const title = panel
|
||||
? t({
|
||||
id: 'share-modal.panel.title',
|
||||
message: 'Share Panel',
|
||||
})
|
||||
: t({
|
||||
id: 'share-modal.dashboard.title',
|
||||
message: 'Share',
|
||||
});
|
||||
const title = panel ? t('share-modal.panel.title', 'Share Panel') : t('share-modal.dashboard.title', 'Share');
|
||||
const tabs = this.getTabs();
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { getBackendSrv, reportInteraction } from '@grafana/runtime';
|
||||
import { Button, ClipboardButton, Field, Input, LinkButton, Modal, Select, Spinner } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||
|
||||
@@ -37,31 +37,19 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
this.dashboard = props.dashboard;
|
||||
this.expireOptions = [
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-never',
|
||||
message: `Never`,
|
||||
}),
|
||||
label: t('share-modal.snapshot.expire-never', `Never`),
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-hour',
|
||||
message: `1 Hour`,
|
||||
}),
|
||||
label: t('share-modal.snapshot.expire-hour', `1 Hour`),
|
||||
value: 60 * 60,
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-day',
|
||||
message: `1 Day`,
|
||||
}),
|
||||
label: t('share-modal.snapshot.expire-day', `1 Day`),
|
||||
value: 60 * 60 * 24,
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.snapshot.expire-week',
|
||||
message: `7 Days`,
|
||||
}),
|
||||
label: t('share-modal.snapshot.expire-week', `7 Days`),
|
||||
value: 60 * 60 * 24 * 7,
|
||||
},
|
||||
];
|
||||
@@ -227,39 +215,26 @@ 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.`,
|
||||
});
|
||||
const snapshotNameTranslation = t('share-modal.snapshot.name', `Snapshot name`);
|
||||
const expireTranslation = t('share-modal.snapshot.expire', `Expire`);
|
||||
const timeoutTranslation = t('share-modal.snapshot.timeout', `Timeout (seconds)`);
|
||||
const timeoutDescriptionTranslation = t(
|
||||
'share-modal.snapshot.timeout-description',
|
||||
`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">
|
||||
<Trans id="share-modal.snapshot.info-text-1">
|
||||
<Trans i18nKey="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">
|
||||
<Trans id="share-modal.snapshot.info-text-2">
|
||||
<Trans i18nKey="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>
|
||||
@@ -283,7 +258,7 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" onClick={onDismiss} fill="outline">
|
||||
<Trans id="share-modal.snapshot.cancel-button">Cancel</Trans>
|
||||
<Trans i18nKey="share-modal.snapshot.cancel-button">Cancel</Trans>
|
||||
</Button>
|
||||
{externalEnabled && (
|
||||
<Button variant="secondary" disabled={isLoading} onClick={this.createSnapshot(true)}>
|
||||
@@ -291,7 +266,7 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
</Button>
|
||||
)}
|
||||
<Button variant="primary" disabled={isLoading} onClick={this.createSnapshot()}>
|
||||
<Trans id="share-modal.snapshot.local-button">Local Snapshot</Trans>
|
||||
<Trans i18nKey="share-modal.snapshot.local-button">Local Snapshot</Trans>
|
||||
</Button>
|
||||
</Modal.ButtonRow>
|
||||
</>
|
||||
@@ -310,16 +285,16 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
readOnly
|
||||
addonAfter={
|
||||
<ClipboardButton icon="copy" variant="primary" getText={this.getSnapshotUrl}>
|
||||
<Trans id="share-modal.snapshot.copy-link-button">Copy</Trans>
|
||||
<Trans i18nKey="share-modal.snapshot.copy-link-button">Copy</Trans>
|
||||
</ClipboardButton>
|
||||
}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<div className="pull-right" style={{ padding: '5px' }}>
|
||||
<Trans id="share-modal.snapshot.mistake-message">Did you make a mistake? </Trans>
|
||||
<Trans i18nKey="share-modal.snapshot.mistake-message">Did you make a mistake? </Trans>
|
||||
<LinkButton fill="text" target="_blank" onClick={this.deleteSnapshot}>
|
||||
<Trans id="share-modal.snapshot.delete-button">Delete snapshot.</Trans>
|
||||
<Trans i18nKey="share-modal.snapshot.delete-button">Delete snapshot.</Trans>
|
||||
</LinkButton>
|
||||
</div>
|
||||
</>
|
||||
@@ -330,7 +305,7 @@ export class ShareSnapshot extends PureComponent<Props, State> {
|
||||
return (
|
||||
<div className="share-modal-header">
|
||||
<p className="share-modal-info-text">
|
||||
<Trans id="share-modal.snapshot.deleted-message">
|
||||
<Trans i18nKey="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>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { t } from '@lingui/macro';
|
||||
import React from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { RadioButtonGroup, Field } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
interface Props {
|
||||
selectedTheme: string;
|
||||
@@ -12,35 +12,21 @@ interface Props {
|
||||
export const ThemePicker = ({ selectedTheme = 'current', onChange }: Props) => {
|
||||
const themeOptions: Array<SelectableValue<string>> = [
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.theme-picker.current',
|
||||
message: `Current`,
|
||||
}),
|
||||
label: t('share-modal.theme-picker.current', `Current`),
|
||||
value: 'current',
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.theme-picker.dark',
|
||||
message: `Dark`,
|
||||
}),
|
||||
label: t('share-modal.theme-picker.dark', `Dark`),
|
||||
value: 'dark',
|
||||
},
|
||||
{
|
||||
label: t({
|
||||
id: 'share-modal.theme-picker.light',
|
||||
message: `Light`,
|
||||
}),
|
||||
label: t('share-modal.theme-picker.light', `Light`),
|
||||
value: 'light',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Field
|
||||
label={t({
|
||||
id: 'share-modal.theme-picker.field-name',
|
||||
message: `Theme`,
|
||||
})}
|
||||
>
|
||||
<Field label={t('share-modal.theme-picker.field-name', `Theme`)}>
|
||||
<RadioButtonGroup options={themeOptions} value={selectedTheme} onChange={onChange} />
|
||||
</Field>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user