Internationalisation: Mark up @grafana/ui for translations (#94951)

* ensure grafana-ui is translated

* last couple

* improve name
This commit is contained in:
Ashley Harrison
2024-10-21 10:11:12 +01:00
committed by GitHub
parent e0446fc557
commit cbce49b163
37 changed files with 392 additions and 257 deletions
+4 -173
View File
@@ -556,119 +556,25 @@ exports[`better eslint`] = {
"packages/grafana-sql/src/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/AutoSaveField/EllipsisAnimated.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/ColorPicker/ColorPickerPopover.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/Combobox/Combobox.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"packages/grafana-ui/src/components/ConfirmButton/ConfirmButton.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinkEditorModalContent.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataLinks/FieldLinkList.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataSourceSettings/CertificationKey.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
],
"packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "8"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "9"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "18"]
],
"packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/DataSourceSettings/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "8"]
],
"packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/FileDropzone/FileListItem.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/FilterInput/FilterInput.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/Forms/FieldArray.story.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
@@ -715,10 +621,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/PanelChrome/PanelContext.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@@ -726,9 +628,6 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/PanelChrome/index.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/SecretFormField/SecretFormField.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/Segment/SegmentSelect.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -738,10 +637,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "8"]
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"packages/grafana-ui/src/components/Select/ValueContainer.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
@@ -790,15 +686,8 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/Table/Filter.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/Table/FilterList.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/Table/FilterPopup.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"]
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-ui/src/components/Table/FooterRow.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@@ -810,10 +699,7 @@ exports[`better eslint`] = {
"packages/grafana-ui/src/components/Table/Table.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"packages/grafana-ui/src/components/Table/TableCell.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@@ -840,64 +726,12 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
],
"packages/grafana-ui/src/components/TableInputCSV/TableInputCSV.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"packages/grafana-ui/src/components/Tags/Tag.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/Tags/TagList.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/TagsInput/TagsInput.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/ThemeDemos/EmotionPerfTest.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "8"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "9"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "18"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "19"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "20"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "21"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "22"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "23"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "24"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "25"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "26"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "27"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "28"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "29"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "30"]
],
"packages/grafana-ui/src/components/UsersIndicator/UserIcon.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"packages/grafana-ui/src/components/VizLegend/VizLegendTableItem.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/VizLegend/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@@ -910,9 +744,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-ui/src/components/VizTooltip/VizTooltipFooter.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"packages/grafana-ui/src/components/index.ts:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'./Layout/Layout\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
[0, 0, 0, "\'VerticalGroup\' import from \'./Layout/Layout\' is restricted from being used by a pattern. Use Stack component instead.", "1"]
@@ -4,6 +4,7 @@ import { useCallback, useMemo, useRef } from 'react';
import * as React from 'react';
import { useStyles2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Field, FieldProps } from '../Forms/Field';
import { InlineToast } from '../InlineToast/InlineToast';
@@ -106,12 +107,14 @@ export function AutoSaveField<T = string>(props: Props<T>) {
</Field>
{fieldState.isLoading && (
<InlineToast referenceElement={fieldRef.current} placement="right">
Saving <EllipsisAnimated />
<Trans i18nKey="grafana-ui.auto-save-field.saving">
Saving <EllipsisAnimated />
</Trans>
</InlineToast>
)}
{fieldState.showSuccess && (
<InlineToast suffixIcon={'check'} referenceElement={fieldRef.current} placement="right">
Saved!
<Trans i18nKey="grafana-ui.auto-save-field.saved">Saved!</Trans>
</InlineToast>
)}
</>
@@ -9,9 +9,9 @@ export const EllipsisAnimated = memo(() => {
const styles = useStyles2(getStyles);
return (
<div className={styles.ellipsis}>
<span className={styles.firstDot}>.</span>
<span className={styles.secondDot}>.</span>
<span className={styles.thirdDot}>.</span>
<span className={styles.firstDot}>{'.'}</span>
<span className={styles.secondDot}>{'.'}</span>
<span className={styles.thirdDot}>{'.'}</span>
</div>
);
});
@@ -7,6 +7,7 @@ import { GrafanaTheme2, colorManipulator } from '@grafana/data';
import { stylesFactory, withTheme2 } from '../../themes';
import { Themeable2 } from '../../types/theme';
import { Trans } from '../../utils/i18n';
import { PopoverContentProps } from '../Tooltip';
import { NamedColorsPalette } from './NamedColorsPalette';
@@ -122,10 +123,10 @@ class UnThemedColorPickerPopover<T extends CustomPickersDescriptor> extends Comp
<div tabIndex={-1} className={styles.colorPickerPopover}>
<div className={styles.colorPickerPopoverTabs}>
<button className={this.getTabClassName('palette')} onClick={this.onTabChange('palette')} type="button">
Colors
<Trans i18nKey="grafana-ui.color-picker-popover.palette-tab">Colors</Trans>
</button>
<button className={this.getTabClassName('spectrum')} onClick={this.onTabChange('spectrum')} type="button">
Custom
<Trans i18nKey="grafana-ui.color-picker-popover.spectrum-tab">Custom</Trans>
</button>
{this.renderCustomPickerTabs()}
</div>
@@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes';
import { ComponentSize } from '../../types/size';
import { Trans } from '../../utils/i18n';
import { Button, ButtonVariant } from '../Button';
export interface Props {
@@ -115,7 +116,7 @@ export const ConfirmButton = ({
{confirmText}
</Button>
<Button size={size} fill="text" onClick={onClickCancel}>
Cancel
<Trans i18nKey="grafana-ui.confirm-button.cancel">Cancel</Trans>
</Button>
</span>
</div>
@@ -5,6 +5,7 @@ import { VariableSuggestion, GrafanaTheme2, DataLink } from '@grafana/data';
import { useStyles2 } from '../../themes/index';
import { isCompactUrl } from '../../utils/dataLinks';
import { Trans } from '../../utils/i18n';
import { Field } from '../Forms/Field';
import { Input } from '../Input/Input';
import { Switch } from '../Switch/Switch';
@@ -64,8 +65,10 @@ export const DataLinkEditor = memo(({ index, value, onChange, suggestions, isLas
{isLast && (
<div className={styles.infoText}>
With data links you can reference data variables like series name, labels and values. Type CMD+Space,
CTRL+Space, or $ to open variable suggestions.
<Trans i18nKey="grafana-ui.data-link-editor.info">
With data links you can reference data variables like series name, labels and values. Type CMD+Space,
CTRL+Space, or $ to open variable suggestions.
</Trans>
</div>
)}
</div>
@@ -2,6 +2,7 @@ import { useState } from 'react';
import { DataFrame, DataLink, VariableSuggestion } from '@grafana/data';
import { Trans } from '../../../utils/i18n';
import { Button } from '../../Button';
import { Modal } from '../../Modal/Modal';
import { DataLinkEditor } from '../DataLinkEditor';
@@ -36,14 +37,14 @@ export const DataLinkEditorModalContent = ({
/>
<Modal.ButtonRow>
<Button variant="secondary" onClick={() => onCancel(index)} fill="outline">
Cancel
<Trans i18nKey="grafana-ui.data-link-editor-modal.cancel">Cancel</Trans>
</Button>
<Button
onClick={() => {
onSave(index, dirtyLink);
}}
>
Save
<Trans i18nKey="grafana-ui.data-link-editor-modal.save">Save</Trans>
</Button>
</Modal.ButtonRow>
</>
@@ -6,6 +6,7 @@ import { ReactNode, useEffect, useState } from 'react';
import { DataFrame, DataLink, GrafanaTheme2, VariableSuggestion } from '@grafana/data';
import { useStyles2 } from '../../../themes';
import { Trans } from '../../../utils/i18n';
import { Button } from '../../Button';
import { Modal } from '../../Modal/Modal';
@@ -94,7 +95,9 @@ export const DataLinksInlineEditor = ({
if (showOneClick) {
return (
<div className={styles.oneClickOverlay} key={key}>
<span className={styles.oneClickSpan}>One-click link</span>
<span className={styles.oneClickSpan}>
<Trans i18nKey="grafana-ui.data-links-inline-editor.one-click-link">One-click link</Trans>
</span>
{linkJSX}
</div>
);
@@ -159,7 +162,7 @@ export const DataLinksInlineEditor = ({
)}
<Button size="sm" icon="plus" onClick={onDataLinkAdd} variant="secondary" className={styles.button}>
Add link
<Trans i18nKey="grafana-ui.data-links-inline-editor.add-link">Add link</Trans>
</Button>
</>
);
@@ -5,6 +5,7 @@ import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../../themes';
import { isCompactUrl } from '../../../utils';
import { Trans } from '../../../utils/i18n';
import { FieldValidationMessage } from '../../Forms/FieldValidationMessage';
import { Icon } from '../../Icon/Icon';
import { IconButton } from '../../IconButton/IconButton';
@@ -51,7 +52,9 @@ export const DataLinksListItem = ({ link, onEdit, onRemove, index, itemKey }: Da
</div>
{isCompactExploreUrl && (
<FieldValidationMessage>
Explore data link may not work in the future. Please edit.
<Trans i18nKey="grafana-ui.data-links-list-item.compact-explore-disclaimer">
Explore data link may not work in the future. Please edit.
</Trans>
</FieldValidationMessage>
)}
</div>
@@ -3,6 +3,7 @@ import { css } from '@emotion/css';
import { Field, GrafanaTheme2, LinkModel } from '@grafana/data';
import { useStyles2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Icon } from '../Icon/Icon';
import { DataLinkButton } from './DataLinkButton';
@@ -30,7 +31,9 @@ export function FieldLinkList({ links }: Props) {
return <DataLinkButton key={i} link={link} />;
})}
<div className={styles.wrapper}>
<p className={styles.externalLinksHeading}>External links</p>
<p className={styles.externalLinksHeading}>
<Trans i18nKey="grafana-ui.field-link-list.external-links-heading">External links</Trans>
</p>
{externalLinks.map((link, i) => (
<a key={i} href={link.href} target={link.target} className={styles.externalLink}>
<Icon name="external-link-alt" />
@@ -1,6 +1,7 @@
import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { InlineSwitch } from '../../components/Switch/Switch';
import { Trans } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField';
export interface Props<T extends DataSourceJsonData>
@@ -13,7 +14,9 @@ export interface AlertingConfig extends DataSourceJsonData {
export function AlertingSettings<T extends AlertingConfig>({ options, onOptionsChange }: Props<T>): JSX.Element {
return (
<>
<h3 className="page-heading">Alerting</h3>
<h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-settings.alerting-settings-heading">Alerting</Trans>
</h3>
<div className="gf-form-group">
<div className="gf-form-inline">
<div className="gf-form">
@@ -1,5 +1,6 @@
import { ChangeEvent, MouseEvent } from 'react';
import { Trans } from '../../utils/i18n';
import { Button } from '../Button';
import { InlineField } from '../Forms/InlineField';
import { InlineFieldRow } from '../Forms/InlineFieldRow';
@@ -27,7 +28,7 @@ export const CertificationKey = ({ hasCert, label, onChange, onClick, placeholde
</InlineField>
{hasCert && (
<Button variant="secondary" onClick={onClick} style={{ marginLeft: 4 }}>
Reset
<Trans i18nKey="grafana-ui.data-source-settings.cert-key-reset">Reset</Trans>
</Button>
)}
</InlineFieldRow>
@@ -5,6 +5,7 @@ import { PureComponent } from 'react';
import { DataSourceSettings } from '@grafana/data';
import { useStyles2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Button } from '../Button';
import { FormField } from '../FormField/FormField';
import { Icon } from '../Icon/Icon';
@@ -199,7 +200,9 @@ export class CustomHeadersSettings extends PureComponent<Props, State> {
return (
<div className={'gf-form-group'}>
<div className="gf-form">
<h6>Custom HTTP Headers</h6>
<h6>
<Trans i18nKey="grafana-ui.data-source-settings.custom-headers-title">Custom HTTP Headers</Trans>
</h6>
</div>
<div>
{headers.map((header, i) => (
@@ -225,7 +228,7 @@ export class CustomHeadersSettings extends PureComponent<Props, State> {
this.onHeaderAdd();
}}
>
Add header
<Trans i18nKey="grafana-ui.data-source-settings.custom-headers-add">Add header</Trans>
</Button>
</div>
)}
@@ -5,6 +5,7 @@ import { SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Alert } from '../Alert/Alert';
import { FormField } from '../FormField/FormField';
import { InlineFormLabel } from '../FormLabel/FormLabel';
@@ -43,23 +44,33 @@ const HttpAccessHelp = () => {
return (
<Alert severity="info" title="" topSpacing={3}>
<p>
Access mode controls how requests to the data source will be handled.
<strong>
&nbsp;<i>Server</i>
</strong>{' '}
should be the preferred way if nothing else is stated.
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help-details">
Access mode controls how requests to the data source will be handled.
<strong>
&nbsp;<i>Server</i>
</strong>{' '}
should be the preferred way if nothing else is stated.
</Trans>
</p>
<Text weight="medium">Server access mode (Default):</Text>
<Trans i18nKey="grafana-ui.data-source-http-settings.server-mode-title">
<Text weight="medium">Server access mode (Default):</Text>
</Trans>
<p>
All requests will be made from the browser to Grafana backend/server which in turn will forward the requests to
the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS) requirements. The URL needs
to be accessible from the grafana backend/server if you select this access mode.
<Trans i18nKey="grafana-ui.data-source-http-settings.server-mode-description">
All requests will be made from the browser to Grafana backend/server which in turn will forward the requests
to the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS) requirements. The URL
needs to be accessible from the grafana backend/server if you select this access mode.
</Trans>
</p>
<Text weight="medium">Browser access mode:</Text>
<Trans i18nKey="grafana-ui.data-source-http-settings.browser-mode-title">
<Text weight="medium">Browser access mode:</Text>
</Trans>
<p>
All requests will be made from the browser directly to the data source and may be subject to Cross-Origin
Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if you select this access
mode.
<Trans i18nKey="grafana-ui.data-source-http-settings.browser-mode-description">
All requests will be made from the browser directly to the data source and may be subject to Cross-Origin
Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if you select this
access mode.
</Trans>
</p>
</Alert>
);
@@ -119,7 +130,9 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
case 'direct':
urlTooltip = (
<>
Your access method is <em>Browser</em>, this means the URL needs to be accessible from the browser.
<Trans i18nKey="grafana-ui.data-source-http-settings.direct-url-tooltip">
Your access method is <em>Browser</em>, this means the URL needs to be accessible from the browser.
</Trans>
{urlDocs}
</>
);
@@ -127,14 +140,23 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
case 'proxy':
urlTooltip = (
<>
Your access method is <em>Server</em>, this means the URL needs to be accessible from the grafana
backend/server.
<Trans i18nKey="grafana-ui.data-source-http-settings.proxy-url-tooltip">
Your access method is <em>Server</em>, this means the URL needs to be accessible from the grafana
backend/server.
</Trans>
{urlDocs}
</>
);
break;
default:
urlTooltip = <>Specify a complete HTTP URL (for example http://your_server:8080) {urlDocs}</>;
urlTooltip = (
<>
<Trans i18nKey="grafana-ui.data-source-http-settings.default-url-tooltip">
Specify a complete HTTP URL (for example http://your_server:8080)
</Trans>
{urlDocs}
</>
);
}
const accessSelect = (
@@ -175,7 +197,9 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
return (
<div className="gf-form-group">
<>
<h3 className="page-heading">HTTP</h3>
<h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.heading">HTTP</Trans>
</h3>
<div className="gf-form-group">
<div className="gf-form">
<FormField
@@ -199,8 +223,10 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
className="gf-form-label query-keyword pointer"
onClick={() => setIsAccessHelpVisible((isVisible) => !isVisible)}
>
Help&nbsp;
<Icon name={isAccessHelpVisible ? 'angle-down' : 'angle-right'} style={{ marginBottom: 0 }} />
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help">
Help&nbsp;
<Icon name={isAccessHelpVisible ? 'angle-down' : 'angle-right'} style={{ marginBottom: 0 }} />
</Trans>
</button>
</div>
</div>
@@ -214,7 +240,7 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
width={13}
tooltip="Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source."
>
Allowed cookies
<Trans i18nKey="grafana-ui.data-source-http-settings.allowed-cookies">Allowed cookies</Trans>
</InlineFormLabel>
<TagsInput
tags={dataSourceConfig.jsonData.keepCookies}
@@ -249,7 +275,9 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
</>
<>
<h3 className="page-heading">Auth</h3>
<h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-http-settings.auth">Auth</Trans>
</h3>
<div className="gf-form-group">
<div className="gf-form-inline">
<InlineField label="Basic auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}>
@@ -325,7 +353,9 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
</div>
{dataSourceConfig.basicAuth && (
<>
<h6>Basic Auth Details</h6>
<h6>
<Trans i18nKey="grafana-ui.data-source-http-settings.basic-auth">Basic Auth Details</Trans>
</h6>
<div className="gf-form-group">
<BasicAuthSettings {...props} />
</div>
@@ -1,6 +1,7 @@
import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { InlineSwitch } from '../../components/Switch/Switch';
import { Trans } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField';
export interface Props<T extends DataSourceJsonData>
@@ -16,7 +17,9 @@ export function SecureSocksProxySettings<T extends SecureSocksProxyConfig>({
}: Props<T>): JSX.Element {
return (
<>
<h3 className="page-heading">Secure Socks Proxy</h3>
<h3 className="page-heading">
<Trans i18nKey="grafana-ui.data-source-settings.secure-socks-heading">Secure Socks Proxy</Trans>
</h3>
<div className="gf-form-group">
<div className="gf-form-inline">
<div className="gf-form">
@@ -3,6 +3,7 @@ import * as React from 'react';
import { KeyValue } from '@grafana/data';
import { Trans } from '../../utils/i18n';
import { FormField } from '../FormField/FormField';
import { Icon } from '../Icon/Icon';
import { Tooltip } from '../Tooltip/Tooltip';
@@ -58,7 +59,9 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
})
)}
>
<h6>TLS/SSL Auth Details</h6>
<h6>
<Trans i18nKey="grafana-ui.data-source-settings.tls-heading">TLS/SSL Auth Details</Trans>
</h6>
<Tooltip
placement="right-end"
content="TLS/SSL Certs are encrypted and stored in the Grafana database."
@@ -21,6 +21,7 @@ import {
import { Components } from '@grafana/e2e-selectors';
import { useStyles2, useTheme2 } from '../../../themes';
import { Trans } from '../../../utils/i18n';
import { Button } from '../../Button/Button';
import { InlineField } from '../../Forms/InlineField';
import { Icon } from '../../Icon/Icon';
@@ -364,10 +365,10 @@ const DateTimeCalendar = React.forwardRef<HTMLDivElement, DateTimeCalendarProps>
</div>
<Stack>
<Button type="button" onClick={handleApply}>
Apply
<Trans i18nKey="grafana-ui.date-time-picker.apply">Apply</Trans>
</Button>
<Button variant="secondary" type="button" onClick={onClose}>
Cancel
<Trans i18nKey="grafana-ui.date-time-picker.cancel">Cancel</Trans>
</Button>
</Stack>
</div>
@@ -127,6 +127,8 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
setIsOpen(false);
};
const { from: timeOptionFrom, to: timeOptionTo } = timeOption;
return (
<div className={styles.container}>
<button
@@ -140,7 +142,9 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
<Icon name="clock-nine" />
</span>
<span>
{timeOption.from} to {timeOption.to}
<Trans i18nKey="time-picker.time-range.from-to">
{{ timeOptionFrom }} to {{ timeOptionTo }}
</Trans>
</span>
<span className={styles.caretIcon}>
<Icon name={isOpen ? 'angle-up' : 'angle-down'} size="lg" />
@@ -190,7 +194,7 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
/>
</Field>
<Button aria-label="TimePicker submit button" onClick={onApply}>
Apply time range
<Trans i18nKey="time-picker.time-range.apply">Apply time range</Trans>
</Button>
</div>
</div>
@@ -208,16 +212,26 @@ const TooltipContent = () => {
return (
<>
<div className={styles.supported}>
Supported formats: <code className={styles.tooltip}>now-[digit]s/m/h/d/w</code>
<Trans i18nKey="time-picker.time-range.supported-formats">
Supported formats: <code className={styles.tooltip}>now-[digit]s/m/h/d/w</code>
</Trans>
</div>
<div>Example: to select a time range from 10 minutes ago to now</div>
<code className={styles.tooltip}>From: now-10m To: now</code>
<div>
<Trans i18nKey="time-picker.time-range.example">
Example: to select a time range from 10 minutes ago to now
</Trans>
</div>
<code className={styles.tooltip}>
<Trans i18nKey="time-picker.time-range.example-details">From: now-10m To: now</Trans>
</code>
<div className={styles.link}>
For more information see{' '}
<a href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls/">
docs <Icon name="external-link-alt" />
</a>
.
<Trans i18nKey="time-picker.time-range.more-info">
For more information see{' '}
<a href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls/">
docs <Icon name="external-link-alt" />
</a>
.
</Trans>
</div>
</>
);
@@ -6,6 +6,7 @@ import { Accept, DropEvent, DropzoneOptions, FileError, FileRejection, useDropzo
import { formattedValueToString, getValueFormat, GrafanaTheme2 } from '@grafana/data';
import { useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Alert } from '../Alert/Alert';
import { Icon } from '../Icon/Icon';
@@ -185,6 +186,7 @@ export function FileDropzone({ options, children, readAs, onLoad, fileListRender
};
const renderErrorMessages = (errors: FileError[]) => {
const size = formattedValueToString(formattedSize);
return (
<div className={styles.errorAlert}>
<Alert title="Upload failed" severity="error" onRemove={clearAlert}>
@@ -193,7 +195,7 @@ export function FileDropzone({ options, children, readAs, onLoad, fileListRender
case ErrorCode.FileTooLarge:
return (
<div key={error.message + error.code}>
File is larger than {formattedValueToString(formattedSize)}
<Trans i18nKey="grafana-ui.file-dropzone.file-too-large">File is larger than {{ size }}</Trans>
</div>
);
default:
@@ -218,7 +220,7 @@ export function FileDropzone({ options, children, readAs, onLoad, fileListRender
{fileErrors.length > 0 && renderErrorMessages(fileErrors)}
<small className={cx(styles.small, styles.acceptContainer)}>
{options?.maxSize && `Max file size: ${formattedValueToString(formattedSize)}`}
{options?.maxSize && options?.accept && <span className={styles.acceptSeparator}>|</span>}
{options?.maxSize && options?.accept && <span className={styles.acceptSeparator}>{'|'}</span>}
{options?.accept && getAcceptedFileTypeText(options.accept)}
</small>
{fileList}
@@ -4,6 +4,7 @@ import { formattedValueToString, getValueFormat, GrafanaTheme2 } from '@grafana/
import { useStyles2 } from '../../themes';
import { trimFileName } from '../../utils/file';
import { Trans } from '../../utils/i18n';
import { Button } from '../Button';
import { Icon } from '../Icon/Icon';
import { IconButton } from '../IconButton/IconButton';
@@ -42,10 +43,13 @@ export function FileListItem({ file: customFile, removeFile }: FileListItemProps
return (
<>
<progress className={styles.progressBar} max={file.size} value={progress} />
<span className={styles.paddingLeft}>{Math.round((progress / file.size) * 100)}%</span>
<span className={styles.paddingLeft}>
{Math.round((progress / file.size) * 100)}
{'%'}
</span>
{abortUpload && (
<Button variant="secondary" type="button" fill="text" onClick={abortUpload}>
Cancel upload
<Trans i18nKey="grafana-ui.file-dropzone.cancel-upload">Cancel upload</Trans>
</Button>
)}
</>
@@ -2,6 +2,7 @@ import { forwardRef, useRef, HTMLProps } from 'react';
import { escapeStringForRegex, unEscapeStringFromRegex } from '@grafana/data';
import { Trans } from '../../utils/i18n';
import { useCombinedRefs } from '../../utils/useCombinedRefs';
import { Button } from '../Button';
import { Icon } from '../Icon/Icon';
@@ -31,7 +32,7 @@ export const FilterInput = forwardRef<HTMLInputElement, Props>(
e.stopPropagation();
}}
>
Clear
<Trans i18nKey="grafana-ui.filter-input.clear">Clear</Trans>
</Button>
) : null;
@@ -73,7 +73,12 @@ export const PageToolbar = memo(
const titleEl = (
<>
<span className={styles.truncateText}>{title}</span>
{section && <span className={styles.pre}> / {section}</span>}
{section && (
<span className={styles.pre}>
{' / '}
{section}
</span>
)}
</>
);
@@ -109,7 +114,7 @@ export const PageToolbar = memo(
</Link>
{titleHref && (
<span className={cx(styles.titleText, styles.titleDivider)} aria-hidden>
/
{'/'}
</span>
)}
</>
@@ -3,6 +3,7 @@ import { omit } from 'lodash';
import { InputHTMLAttributes } from 'react';
import * as React from 'react';
import { Trans } from '../../utils/i18n';
import { Button } from '../Button/Button';
import { FormField } from '../FormField/FormField';
import { Field } from '../Forms/Field';
@@ -74,7 +75,7 @@ export const SecretFormField = ({
{...omit(inputProps, 'value')}
/>
<Button onClick={onReset} variant="secondary" type="button">
Reset
<Trans i18nKey="grafana-ui.secret-form-field.reset">Reset</Trans>
</Button>
</>
) : (
@@ -15,6 +15,7 @@ import Creatable from 'react-select/creatable';
import { SelectableValue, toOption } from '@grafana/data';
import { useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Icon } from '../Icon/Icon';
import { Spinner } from '../Spinner/Spinner';
@@ -407,7 +408,7 @@ function defaultFormatCreateLabel(input: string) {
<div>{input}</div>
<div style={{ flexGrow: 1 }} />
<div className="muted small" style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
Hit enter to add
<Trans i18nKey="grafana-ui.select.default-create-label">Hit enter to add</Trans>
</div>
</div>
);
@@ -432,7 +433,7 @@ function CustomIndicatorsContainer(props: CustomIndicatorsContainerProps) {
-1,
0,
<span key="excess-values" id="excess-values">
(+{selectedValuesCount - maxVisibleValues})
{`(+${selectedValuesCount - maxVisibleValues})`}
</span>
);
@@ -7,6 +7,7 @@ import { GrafanaTheme2, formattedValueToString, getValueFormat, SelectableValue
import { ButtonSelect, Checkbox, FilterInput, Label, Stack } from '..';
import { useStyles2, useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
interface Props {
values: SelectableValue[];
@@ -210,7 +211,9 @@ export const FilterList = ({
</Stack>
</>
) : (
<Label className={styles.noValuesLabel}>No values</Label>
<Label className={styles.noValuesLabel}>
<Trans i18nKey="grafana-ui.table.no-values-label">No values</Trans>
</Label>
)}
</Stack>
);
@@ -6,6 +6,7 @@ import { Field, GrafanaTheme2, SelectableValue } from '@grafana/data';
import { Button, ClickOutsideWrapper, IconButton, Label, Stack } from '..';
import { useStyles2, useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { FilterList } from './FilterList';
import { TableStyles } from './styles';
@@ -69,7 +70,9 @@ export const FilterPopup = ({
<Stack direction="column" gap={3}>
<Stack direction="column" gap={0.5}>
<Stack justifyContent="space-between" alignItems="center">
<Label className={styles.label}>Filter by values:</Label>
<Label className={styles.label}>
<Trans i18nKey="grafana-ui.table.filter-popup-heading">Filter by values:</Trans>
</Label>
<IconButton
name="text-fields"
tooltip="Match case"
@@ -95,16 +98,16 @@ export const FilterPopup = ({
<Stack gap={3}>
<Stack>
<Button size="sm" onClick={onFilter}>
Ok
<Trans i18nKey="grafana-ui.table.filter-popup-apply">Ok</Trans>
</Button>
<Button size="sm" variant="secondary" onClick={onCancel}>
Cancel
<Trans i18nKey="grafana-ui.table.filter-popup-cancel">Cancel</Trans>
</Button>
</Stack>
{clearFilterVisible && (
<Stack>
<Button fill="text" size="sm" onClick={onClearFilter}>
Clear filter
<Trans i18nKey="grafana-ui.table.filter-popup-clear">Clear filter</Trans>
</Button>
</Stack>
)}
@@ -15,6 +15,7 @@ import { selectors } from '@grafana/e2e-selectors';
import { TableCellHeight } from '@grafana/schema';
import { useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar';
import { Pagination } from '../Pagination/Pagination';
@@ -280,6 +281,8 @@ export const Table = memo((props: Props) => {
if (itemsRangeEnd > data.length) {
itemsRangeEnd = data.length;
}
const numRows = rows.length;
const displayedEnd = itemsRangeEnd < rows.length ? itemsRangeEnd : rows.length;
paginationEl = (
<div className={tableStyles.paginationWrapper}>
<Pagination
@@ -290,7 +293,9 @@ export const Table = memo((props: Props) => {
/>
{isSmall ? null : (
<div className={tableStyles.paginationSummary}>
{itemsRangeStart} - {itemsRangeEnd < rows.length ? itemsRangeEnd : rows.length} of {rows.length} rows
<Trans i18nKey="grafana-ui.table.pagination-summary">
{{ itemsRangeStart }} - {{ displayedEnd }} of {{ numRows }} rows
</Trans>
</div>
)}
</div>
@@ -7,6 +7,7 @@ import { DataFrame, CSVConfig, readCSV, GrafanaTheme2 } from '@grafana/data';
import { stylesFactory, withTheme2 } from '../../themes';
import { Themeable2 } from '../../types/theme';
import { Trans } from '../../utils/i18n';
import { Icon } from '../Icon/Icon';
import { TextArea } from '../TextArea/TextArea';
@@ -81,10 +82,14 @@ export class UnThemedTableInputCSV extends PureComponent<Props, State> {
{data && (
<footer className={styles.footer}>
{data.map((frame, index) => {
const rows = frame.length;
const columns = frame.fields.length;
return (
<span key={index}>
Rows:{frame.length}, Columns:{frame.fields.length} &nbsp;
<Icon name="check-circle" />
<Trans i18nKey="grafana-ui.table.csv-counts">
Rows:{{ rows }}, Columns:{{ columns }} &nbsp;
<Icon name="check-circle" />
</Trans>
</span>
);
})}
@@ -48,7 +48,10 @@ const TagListComponent = memo(
</li>
))}
{displayMax && displayMax > 0 && numTags - displayMax > 0 && (
<span className={styles.moreTagsLabel}>+ {numTags - displayMax}</span>
<span className={styles.moreTagsLabel}>
{'+ '}
{numTags - displayMax}
</span>
)}
</ul>
);
@@ -5,6 +5,7 @@ import * as React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
import { Trans } from '../../utils/i18n';
import { Button } from '../Button';
import { Input } from '../Input/Input';
@@ -88,7 +89,7 @@ export const TagsInput = ({
size="md"
disabled={newTagName.length <= 0}
>
Add
<Trans i18nKey="grafana-ui.tags-input.add">Add</Trans>
</Button>
}
/>
@@ -1,3 +1,4 @@
/* eslint-disable @grafana/no-untranslated-strings */
/** @jsxImportSource @emotion/react */
/** @jsxRuntime classic */
import { css, cx } from '@emotion/css';
@@ -1,3 +1,4 @@
/* eslint-disable @grafana/no-untranslated-strings */
import { css, cx } from '@emotion/css';
import { useState } from 'react';
import * as React from 'react';
@@ -4,6 +4,7 @@ import { useMemo, PropsWithChildren } from 'react';
import { dateTime, DateTimeInput, GrafanaTheme2 } from '@grafana/data';
import { useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { Tooltip } from '../Tooltip';
import { UserView } from './types';
@@ -85,7 +86,9 @@ export const UserIcon = ({
<div className={styles.tooltipDate}>
{isActive ? (
<div className={styles.dotContainer}>
<span>Active last 15m</span>
<span>
<Trans i18nKey="grafana-ui.user-icon.active-text">Active last 15m</Trans>
</span>
<span className={styles.dot}></span>
</div>
) : (
@@ -6,6 +6,7 @@ import { formattedValueToString, GrafanaTheme2 } from '@grafana/data';
import { styleMixins } from '../../themes';
import { useStyles2 } from '../../themes/ThemeContext';
import { Trans } from '../../utils/i18n';
import { VizLegendSeriesIcon } from './VizLegendSeriesIcon';
import { VizLegendItem } from './types';
@@ -87,7 +88,12 @@ export const LegendTableItem = ({
onClick={!readonly ? onClick : undefined}
className={cx(styles.label, item.disabled && styles.labelDisabled)}
>
{item.label} {item.yAxis === 2 && <span className={styles.yAxisLabel}>(right y-axis)</span>}
{item.label}{' '}
{item.yAxis === 2 && (
<span className={styles.yAxisLabel}>
<Trans i18nKey="grafana-ui.viz-legend.right-axis-indicator">(right y-axis)</Trans>
</span>
)}
</button>
</span>
</td>
@@ -4,6 +4,7 @@ import { ActionModel, Field, GrafanaTheme2, LinkModel } from '@grafana/data';
import { Button, DataLinkButton, Stack } from '..';
import { useStyles2 } from '../../themes';
import { Trans } from '../../utils/i18n';
import { ActionButton } from '../Actions/ActionButton';
interface VizTooltipFooterProps {
@@ -44,7 +45,7 @@ export const VizTooltipFooter = ({ dataLinks, actions, annotate }: VizTooltipFoo
{annotate != null && (
<div className={styles.addAnnotations}>
<Button icon="comment-alt" variant="secondary" size="sm" id={ADD_ANNOTATION_ID} onClick={annotate}>
Add annotation
<Trans i18nKey="grafana-ui.viz-tooltip.footer-add-annotation">Add annotation</Trans>
</Button>
</div>
)}
+93 -2
View File
@@ -1062,18 +1062,84 @@
"send-custom-feedback": "Send"
},
"grafana-ui": {
"auto-save-field": {
"saved": "Saved!",
"saving": "Saving <1></1>"
},
"color-picker-popover": {
"palette-tab": "Colors",
"spectrum-tab": "Custom"
},
"confirm-button": {
"cancel": "Cancel"
},
"data-link-editor": {
"info": "With data links you can reference data variables like series name, labels and values. Type CMD+Space, CTRL+Space, or $ to open variable suggestions."
},
"data-link-editor-modal": {
"cancel": "Cancel",
"save": "Save"
},
"data-links-inline-editor": {
"add-link": "Add link",
"one-click-link": "One-click link"
},
"data-links-list-item": {
"compact-explore-disclaimer": "Explore data link may not work in the future. Please edit."
},
"data-source-http-settings": {
"access-help": "Help <1></1>",
"access-help-details": "Access mode controls how requests to the data source will be handled.<1> <1>Server</1></1> should be the preferred way if nothing else is stated.",
"allowed-cookies": "Allowed cookies",
"auth": "Auth",
"basic-auth": "Basic Auth Details",
"browser-mode-description": "All requests will be made from the browser directly to the data source and may be subject to Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the browser if you select this access mode.",
"browser-mode-title": "<0>Browser access mode:</0>",
"default-url-tooltip": "Specify a complete HTTP URL (for example http://your_server:8080)",
"direct-url-tooltip": "Your access method is <1>Browser</1>, this means the URL needs to be accessible from the browser.",
"heading": "HTTP",
"proxy-url-tooltip": "Your access method is <1>Server</1>, this means the URL needs to be accessible from the grafana backend/server.",
"server-mode-description": "All requests will be made from the browser to Grafana backend/server which in turn will forward the requests to the data source and by that circumvent possible Cross-Origin Resource Sharing (CORS) requirements. The URL needs to be accessible from the grafana backend/server if you select this access mode.",
"server-mode-title": "<0>Server access mode (Default):</0>"
},
"data-source-settings": {
"alerting-settings-heading": "Alerting",
"cert-key-reset": "Reset",
"custom-headers-add": "Add header",
"custom-headers-title": "Custom HTTP Headers",
"secure-socks-heading": "Secure Socks Proxy",
"tls-heading": "TLS/SSL Auth Details"
},
"date-time-picker": {
"apply": "Apply",
"cancel": "Cancel"
},
"drawer": {
"close": "Close"
},
"field-link-list": {
"external-links-heading": "External links"
},
"file-dropzone": {
"cancel-upload": "Cancel upload",
"file-too-large": "File is larger than {{size}}"
},
"filter-input": {
"clear": "Clear"
},
"modal": {
"close-tooltip": "Close"
},
"secret-form-field": {
"reset": "Reset"
},
"segment-async": {
"error": "Failed to load options",
"loading": "Loading options...",
"no-options": "No options found"
},
"select": {
"default-create-label": "Hit enter to add",
"no-options-label": "No options found",
"placeholder": "Choose"
},
@@ -1081,7 +1147,26 @@
"aria-label": "Loading"
},
"table": {
"copy": "Copy to Clipboard"
"copy": "Copy to Clipboard",
"csv-counts": "Rows:{{rows}}, Columns:{{columns}} <5></5>",
"filter-popup-apply": "Ok",
"filter-popup-cancel": "Cancel",
"filter-popup-clear": "Clear filter",
"filter-popup-heading": "Filter by values:",
"no-values-label": "No values",
"pagination-summary": "{{itemsRangeStart}} - {{displayedEnd}} of {{numRows}} rows"
},
"tags-input": {
"add": "Add"
},
"user-icon": {
"active-text": "Active last 15m"
},
"viz-legend": {
"right-axis-indicator": "(right y-axis)"
},
"viz-tooltip": {
"footer-add-annotation": "Add annotation"
}
},
"graph": {
@@ -2739,10 +2824,16 @@
"zoom-out-tooltip": "Time range zoom out <1></1> CTRL+Z"
},
"time-range": {
"apply": "Apply time range",
"aria-role": "Time range selection",
"default-title": "Time ranges",
"example": "Example: to select a time range from 10 minutes ago to now",
"example-details": "From: now-10m To: now",
"example-title": "Example time ranges",
"specify": "Specify time range <1></1>"
"from-to": "{{timeOptionFrom}} to {{timeOptionTo}}",
"more-info": "For more information see <2>docs <1></1></2>.",
"specify": "Specify time range <1></1>",
"supported-formats": "Supported formats: <1>now-[digit]s/m/h/d/w</1>"
},
"zone": {
"select-aria-label": "Time zone picker",
+93 -2
View File
@@ -1062,18 +1062,84 @@
"send-custom-feedback": "Ŝęʼnđ"
},
"grafana-ui": {
"auto-save-field": {
"saved": "Ŝävęđ!",
"saving": "Ŝävįʼnģ <1></1>"
},
"color-picker-popover": {
"palette-tab": "Cőľőřş",
"spectrum-tab": "Cūşŧőm"
},
"confirm-button": {
"cancel": "Cäʼnčęľ"
},
"data-link-editor": {
"info": "Ŵįŧĥ đäŧä ľįʼnĸş yőū čäʼn řęƒęřęʼnčę đäŧä väřįäþľęş ľįĸę şęřįęş ʼnämę, ľäþęľş äʼnđ väľūęş. Ŧypę CMĐ+Ŝpäčę, CŦŖĿ+Ŝpäčę, őř $ ŧő őpęʼn väřįäþľę şūģģęşŧįőʼnş."
},
"data-link-editor-modal": {
"cancel": "Cäʼnčęľ",
"save": "Ŝävę"
},
"data-links-inline-editor": {
"add-link": "Åđđ ľįʼnĸ",
"one-click-link": "Øʼnę-čľįčĸ ľįʼnĸ"
},
"data-links-list-item": {
"compact-explore-disclaimer": "Ēχpľőřę đäŧä ľįʼnĸ mäy ʼnőŧ ŵőřĸ įʼn ŧĥę ƒūŧūřę. Pľęäşę ęđįŧ."
},
"data-source-http-settings": {
"access-help": "Ħęľp <1></1>",
"access-help-details": "Åččęşş mőđę čőʼnŧřőľş ĥőŵ řęqūęşŧş ŧő ŧĥę đäŧä şőūřčę ŵįľľ þę ĥäʼnđľęđ.<1> <1>Ŝęřvęř</1></1> şĥőūľđ þę ŧĥę přęƒęřřęđ ŵäy įƒ ʼnőŧĥįʼnģ ęľşę įş şŧäŧęđ.",
"allowed-cookies": "Åľľőŵęđ čőőĸįęş",
"auth": "Åūŧĥ",
"basic-auth": "ßäşįč Åūŧĥ Đęŧäįľş",
"browser-mode-description": "Åľľ řęqūęşŧş ŵįľľ þę mäđę ƒřőm ŧĥę þřőŵşęř đįřęčŧľy ŧő ŧĥę đäŧä şőūřčę äʼnđ mäy þę şūþĵęčŧ ŧő Cřőşş-Øřįģįʼn Ŗęşőūřčę Ŝĥäřįʼnģ (CØŖŜ) řęqūįřęmęʼnŧş. Ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř įƒ yőū şęľęčŧ ŧĥįş äččęşş mőđę.",
"browser-mode-title": "<0>ßřőŵşęř äččęşş mőđę:</0>",
"default-url-tooltip": "Ŝpęčįƒy ä čőmpľęŧę ĦŦŦP ŮŖĿ (ƒőř ęχämpľę ĥŧŧp://yőūř_şęřvęř:8080)",
"direct-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>ßřőŵşęř</1>, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř.",
"heading": "ĦŦŦP",
"proxy-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>Ŝęřvęř</1>, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę ģřäƒäʼnä þäčĸęʼnđ/şęřvęř.",
"server-mode-description": "Åľľ řęqūęşŧş ŵįľľ þę mäđę ƒřőm ŧĥę þřőŵşęř ŧő Ğřäƒäʼnä þäčĸęʼnđ/şęřvęř ŵĥįčĥ įʼn ŧūřʼn ŵįľľ ƒőřŵäřđ ŧĥę řęqūęşŧş ŧő ŧĥę đäŧä şőūřčę äʼnđ þy ŧĥäŧ čįřčūmvęʼnŧ pőşşįþľę Cřőşş-Øřįģįʼn Ŗęşőūřčę Ŝĥäřįʼnģ (CØŖŜ) řęqūįřęmęʼnŧş. Ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę ģřäƒäʼnä þäčĸęʼnđ/şęřvęř įƒ yőū şęľęčŧ ŧĥįş äččęşş mőđę.",
"server-mode-title": "<0>Ŝęřvęř äččęşş mőđę (Đęƒäūľŧ):</0>"
},
"data-source-settings": {
"alerting-settings-heading": "Åľęřŧįʼnģ",
"cert-key-reset": "Ŗęşęŧ",
"custom-headers-add": "Åđđ ĥęäđęř",
"custom-headers-title": "Cūşŧőm ĦŦŦP Ħęäđęřş",
"secure-socks-heading": "Ŝęčūřę Ŝőčĸş Přőχy",
"tls-heading": "ŦĿŜ/ŜŜĿ Åūŧĥ Đęŧäįľş"
},
"date-time-picker": {
"apply": "Åppľy",
"cancel": "Cäʼnčęľ"
},
"drawer": {
"close": "Cľőşę"
},
"field-link-list": {
"external-links-heading": "Ēχŧęřʼnäľ ľįʼnĸş"
},
"file-dropzone": {
"cancel-upload": "Cäʼnčęľ ūpľőäđ",
"file-too-large": "Fįľę įş ľäřģęř ŧĥäʼn {{size}}"
},
"filter-input": {
"clear": "Cľęäř"
},
"modal": {
"close-tooltip": "Cľőşę"
},
"secret-form-field": {
"reset": "Ŗęşęŧ"
},
"segment-async": {
"error": "Fäįľęđ ŧő ľőäđ őpŧįőʼnş",
"loading": "Ŀőäđįʼnģ őpŧįőʼnş...",
"no-options": "Ńő őpŧįőʼnş ƒőūʼnđ"
},
"select": {
"default-create-label": "Ħįŧ ęʼnŧęř ŧő äđđ",
"no-options-label": "Ńő őpŧįőʼnş ƒőūʼnđ",
"placeholder": "Cĥőőşę"
},
@@ -1081,7 +1147,26 @@
"aria-label": "Ŀőäđįʼnģ"
},
"table": {
"copy": "Cőpy ŧő Cľįpþőäřđ"
"copy": "Cőpy ŧő Cľįpþőäřđ",
"csv-counts": "Ŗőŵş:{{rows}}, Cőľūmʼnş:{{columns}} <5></5>",
"filter-popup-apply": "Øĸ",
"filter-popup-cancel": "Cäʼnčęľ",
"filter-popup-clear": "Cľęäř ƒįľŧęř",
"filter-popup-heading": "Fįľŧęř þy väľūęş:",
"no-values-label": "Ńő väľūęş",
"pagination-summary": "{{itemsRangeStart}} - {{displayedEnd}} őƒ {{numRows}} řőŵş"
},
"tags-input": {
"add": "Åđđ"
},
"user-icon": {
"active-text": "Åčŧįvę ľäşŧ 15m"
},
"viz-legend": {
"right-axis-indicator": "(řįģĥŧ y-äχįş)"
},
"viz-tooltip": {
"footer-add-annotation": "Åđđ äʼnʼnőŧäŧįőʼn"
}
},
"graph": {
@@ -2739,10 +2824,16 @@
"zoom-out-tooltip": "Ŧįmę řäʼnģę žőőm őūŧ <1></1> CŦŖĿ+Ż"
},
"time-range": {
"apply": "Åppľy ŧįmę řäʼnģę",
"aria-role": "Ŧįmę řäʼnģę şęľęčŧįőʼn",
"default-title": "Ŧįmę řäʼnģęş",
"example": "Ēχämpľę: ŧő şęľęčŧ ä ŧįmę řäʼnģę ƒřőm 10 mįʼnūŧęş äģő ŧő ʼnőŵ",
"example-details": "Fřőm: ʼnőŵ-10m Ŧő: ʼnőŵ",
"example-title": "Ēχämpľę ŧįmę řäʼnģęş",
"specify": "Ŝpęčįƒy ŧįmę řäʼnģę <1></1>"
"from-to": "{{timeOptionFrom}} ŧő {{timeOptionTo}}",
"more-info": "Főř mőřę įʼnƒőřmäŧįőʼn şęę <2>đőčş <1></1></2>.",
"specify": "Ŝpęčįƒy ŧįmę řäʼnģę <1></1>",
"supported-formats": "Ŝūppőřŧęđ ƒőřmäŧş: <1>ʼnőŵ-[đįģįŧ]ş/m/ĥ/đ/ŵ</1>"
},
"zone": {
"select-aria-label": "Ŧįmę žőʼnę pįčĸęř",