Internationalization: mark up some grafana-ui components for translation (#101303)

This commit is contained in:
Laura Fernández
2025-02-26 12:41:27 +01:00
committed by GitHub
parent d7a081e3a1
commit fcdbb5887d
20 changed files with 332 additions and 173 deletions

View File

@ -518,120 +518,30 @@ exports[`better eslint`] = {
"packages/grafana-sql/src/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [ "packages/grafana-sql/src/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
], ],
"packages/grafana-ui/src/components/Alert/Alert.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/Card/Card.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"packages/grafana-ui/src/components/Cascader/Cascader.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx:5381": [ "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.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
], ],
"packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/Combobox/MultiCombobox.tsx:5381": [ "packages/grafana-ui/src/components/Combobox/MultiCombobox.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
"packages/grafana-ui/src/components/Combobox/ValuePill.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"packages/grafana-ui/src/components/Combobox/useOptions.ts:5381": [ "packages/grafana-ui/src/components/Combobox/useOptions.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
"packages/grafana-ui/src/components/ConfirmModal/ConfirmContent.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"]
],
"packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx:5381": [ "packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"] [0, 0, 0, "Do not use any type assertions.", "0"]
], ],
"packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx:5381": [ "packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"] [0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
], ],
"packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx:5381": [ "packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"]
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"]
],
"packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "6"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "7"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "8"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "9"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "10"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "11"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "12"]
],
"packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"]
],
"packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "6"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "7"]
], ],
"packages/grafana-ui/src/components/DataSourceSettings/types.ts:5381": [ "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.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"] [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 in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"]
],
"packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx:5381": [ "packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"] [0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
], ],

View File

@ -7,6 +7,7 @@ import { selectors } from '@grafana/e2e-selectors';
import { useTheme2 } from '../../themes'; import { useTheme2 } from '../../themes';
import { IconName } from '../../types/icon'; import { IconName } from '../../types/icon';
import { t } from '../../utils/i18n';
import { Button } from '../Button/Button'; import { Button } from '../Button/Button';
import { Icon } from '../Icon/Icon'; import { Icon } from '../Icon/Icon';
import { Box } from '../Layout/Box/Box'; import { Box } from '../Layout/Box/Box';
@ -53,6 +54,8 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
const role = restProps['role'] || rolesBySeverity[severity]; const role = restProps['role'] || rolesBySeverity[severity];
const ariaLabel = restProps['aria-label'] || title; const ariaLabel = restProps['aria-label'] || title;
const closeLabel = t('grafana-ui.alert.close-button', 'Close alert');
return ( return (
<div ref={ref} className={cx(styles.wrapper, className)} role={role} aria-label={ariaLabel} {...restProps}> <div ref={ref} className={cx(styles.wrapper, className)} role={role} aria-label={ariaLabel} {...restProps}>
<Box <Box
@ -83,7 +86,7 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
{onRemove && !buttonContent && ( {onRemove && !buttonContent && (
<div className={styles.close}> <div className={styles.close}>
<Button <Button
aria-label="Close alert" aria-label={closeLabel}
icon="times" icon="times"
onClick={onRemove} onClick={onRemove}
type="button" type="button"
@ -95,7 +98,7 @@ export const Alert = React.forwardRef<HTMLDivElement, Props>(
{onRemove && buttonContent && ( {onRemove && buttonContent && (
<Box marginLeft={1} display="flex" alignItems="center"> <Box marginLeft={1} display="flex" alignItems="center">
<Button aria-label="Close alert" variant="secondary" onClick={onRemove} type="button"> <Button aria-label={closeLabel} variant="secondary" onClick={onRemove} type="button">
{buttonContent} {buttonContent}
</Button> </Button>
</Box> </Box>

View File

@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes'; import { useStyles2 } from '../../themes';
import { getFocusStyles } from '../../themes/mixins'; import { getFocusStyles } from '../../themes/mixins';
import { t } from '../../utils/i18n';
import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer'; import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer';
@ -102,6 +103,7 @@ const Heading = ({ children, className, 'aria-label': ariaLabel }: ChildProps &
onClick: undefined, onClick: undefined,
isSelected: undefined, isSelected: undefined,
}; };
const optionLabel = t('grafana-ui.card.option', 'option');
return ( return (
<h2 className={cx(styles.heading, className)}> <h2 className={cx(styles.heading, className)}>
@ -117,7 +119,7 @@ const Heading = ({ children, className, 'aria-label': ariaLabel }: ChildProps &
<>{children}</> <>{children}</>
)} )}
{/* Input must be readonly because we are providing a value for the checked prop with no onChange handler */} {/* Input must be readonly because we are providing a value for the checked prop with no onChange handler */}
{isSelected !== undefined && <input aria-label="option" type="radio" checked={isSelected} readOnly />} {isSelected !== undefined && <input aria-label={optionLabel} type="radio" checked={isSelected} readOnly />}
</h2> </h2>
); );
}; };

View File

@ -8,6 +8,7 @@ import { SelectableValue } from '@grafana/data';
import { withTheme2 } from '../../themes'; import { withTheme2 } from '../../themes';
import { Themeable2 } from '../../types'; import { Themeable2 } from '../../types';
import { t } from '../../utils/i18n';
import { Icon } from '../Icon/Icon'; import { Icon } from '../Icon/Icon';
import { IconButton } from '../IconButton/IconButton'; import { IconButton } from '../IconButton/IconButton';
import { Input } from '../Input/Input'; import { Input } from '../Input/Input';
@ -286,7 +287,7 @@ class UnthemedCascader extends PureComponent<CascaderProps, CascaderState> {
{isClearable && activeLabel !== '' && ( {isClearable && activeLabel !== '' && (
<IconButton <IconButton
name="times" name="times"
aria-label="Clear selection" aria-label={t('grafana-ui.cascader.clear-button', 'Clear selection')}
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();

View File

@ -3,6 +3,7 @@ import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
import { t } from '../../utils/i18n';
import { ColorSwatch } from './ColorSwatch'; import { ColorSwatch } from './ColorSwatch';
import NamedColorsGroup from './NamedColorsGroup'; import NamedColorsGroup from './NamedColorsGroup';
@ -28,13 +29,13 @@ export const NamedColorsPalette = ({ color, onChange }: NamedColorsPaletteProps)
<ColorSwatch <ColorSwatch
isSelected={color === 'transparent'} isSelected={color === 'transparent'}
color={'rgba(0,0,0,0)'} color={'rgba(0,0,0,0)'}
label="Transparent" label={t('grafana-ui.named-colors-palette.transparent-swatch', 'Transparent')}
onClick={() => onChange('transparent')} onClick={() => onChange('transparent')}
/> />
<ColorSwatch <ColorSwatch
isSelected={color === 'text'} isSelected={color === 'text'}
color={theme.colors.text.primary} color={theme.colors.text.primary}
label="Text color" label={t('grafana-ui.named-colors-palette.text-color-swatch', 'Text color')}
onClick={() => onChange('text')} onClick={() => onChange('text')}
/> />
</div> </div>

View File

@ -1,4 +1,5 @@
import { withTheme2 } from '../../themes'; import { withTheme2 } from '../../themes';
import { t } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
import { InlineSwitch } from '../Switch/Switch'; import { InlineSwitch } from '../Switch/Switch';
import { PopoverContentProps } from '../Tooltip'; import { PopoverContentProps } from '../Tooltip';
@ -12,15 +13,15 @@ export interface SeriesColorPickerPopoverProps extends ColorPickerProps, Popover
export const SeriesColorPickerPopover = (props: SeriesColorPickerPopoverProps) => { export const SeriesColorPickerPopover = (props: SeriesColorPickerPopoverProps) => {
const { yaxis, onToggleAxis, color, ...colorPickerProps } = props; const { yaxis, onToggleAxis, color, ...colorPickerProps } = props;
const yAxisLabel = t('grafana-ui.series-color-picker-popover.y-axis-usage', 'Use right y-axis');
const customPickers = onToggleAxis const customPickers = onToggleAxis
? { ? {
yaxis: { yaxis: {
name: 'Y-Axis', name: 'Y-Axis',
tabComponent() { tabComponent() {
return ( return (
<InlineField labelWidth={20} label="Use right y-axis"> <InlineField labelWidth={20} label={yAxisLabel}>
<InlineSwitch value={yaxis === 2} label="Use right y-axis" onChange={onToggleAxis} /> <InlineSwitch value={yaxis === 2} label={yAxisLabel} onChange={onToggleAxis} />
</InlineField> </InlineField>
); );
}, },

View File

@ -4,6 +4,7 @@ import { forwardRef } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes'; import { useStyles2 } from '../../themes';
import { t } from '../../utils/i18n';
import { IconButton } from '../IconButton/IconButton'; import { IconButton } from '../IconButton/IconButton';
interface ValuePillProps { interface ValuePillProps {
@ -15,6 +16,7 @@ interface ValuePillProps {
export const ValuePill = forwardRef<HTMLSpanElement, ValuePillProps>( export const ValuePill = forwardRef<HTMLSpanElement, ValuePillProps>(
({ children, onRemove, disabled, ...rest }, ref) => { ({ children, onRemove, disabled, ...rest }, ref) => {
const styles = useStyles2(getValuePillStyles, disabled); const styles = useStyles2(getValuePillStyles, disabled);
const removeButtonLabel = t('grafana-ui.value-pill.remove-button', 'Remove {{children}}', { children });
return ( return (
<span className={styles.wrapper} {...rest} ref={ref}> <span className={styles.wrapper} {...rest} ref={ref}>
<span className={styles.text}>{children}</span> <span className={styles.text}>{children}</span>
@ -24,7 +26,7 @@ export const ValuePill = forwardRef<HTMLSpanElement, ValuePillProps>(
<IconButton <IconButton
name="times" name="times"
size="md" size="md"
aria-label={`Remove ${children}`} aria-label={removeButtonLabel}
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
onRemove(); onRemove();

View File

@ -7,6 +7,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '../../themes'; import { useStyles2 } from '../../themes';
import { t } from '../../utils/i18n';
import { Button, ButtonVariant } from '../Button'; import { Button, ButtonVariant } from '../Button';
import { Field } from '../Forms/Field'; import { Field } from '../Forms/Field';
import { Input } from '../Input/Input'; import { Input } from '../Input/Input';
@ -90,7 +91,9 @@ export const ConfirmContent = ({
}; };
const { handleSubmit } = useForm(); const { handleSubmit } = useForm();
const placeholder = t('grafana-ui.confirm-content.placeholder', 'Type "{{confirmPromptText}}" to confirm', {
confirmPromptText,
});
return ( return (
<form onSubmit={handleSubmit(onConfirmClick)}> <form onSubmit={handleSubmit(onConfirmClick)}>
<div className={styles.text}> <div className={styles.text}>
@ -100,7 +103,7 @@ export const ConfirmContent = ({
<div className={styles.confirmationInput}> <div className={styles.confirmationInput}>
<Stack alignItems="flex-start"> <Stack alignItems="flex-start">
<Field disabled={disabled}> <Field disabled={disabled}>
<Input placeholder={`Type "${confirmPromptText}" to confirm`} onChange={onConfirmationTextChange} /> <Input placeholder={placeholder} onChange={onConfirmationTextChange} />
</Field> </Field>
</Stack> </Stack>
</div> </div>

View File

@ -53,15 +53,19 @@ export const DataLinkEditor = memo(
return ( return (
<div className={styles.listItem}> <div className={styles.listItem}>
<Field label="Title"> <Field label={t('grafana-ui.data-link-editor.title-label', 'Title')}>
<Input value={value.title} onChange={onTitleChange} placeholder="Show details" /> <Input
value={value.title}
onChange={onTitleChange}
placeholder={t('grafana-ui.data-link-editor.title-placeholder', 'Show details')}
/>
</Field> </Field>
<Field label="URL"> <Field label={t('grafana-ui.data-link-editor.url-label', 'URL')}>
<DataLinkInput value={value.url} onChange={onUrlChange} suggestions={suggestions} /> <DataLinkInput value={value.url} onChange={onUrlChange} suggestions={suggestions} />
</Field> </Field>
<Field label="Open in new tab"> <Field label={t('grafana-ui.data-link-editor.new-tab-label', 'Open in new tab')}>
<Switch value={value.targetBlank || false} onChange={onOpenInNewTabChanged} /> <Switch value={value.targetBlank || false} onChange={onOpenInNewTabChanged} />
</Field> </Field>

View File

@ -1,7 +1,7 @@
import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { InlineSwitch } from '../../components/Switch/Switch'; import { InlineSwitch } from '../../components/Switch/Switch';
import { Trans } from '../../utils/i18n'; import { t, Trans } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
export interface Props<T extends DataSourceJsonData> export interface Props<T extends DataSourceJsonData>
@ -22,9 +22,12 @@ export function AlertingSettings<T extends AlertingConfig>({ options, onOptionsC
<div className="gf-form"> <div className="gf-form">
<InlineField <InlineField
labelWidth={29} labelWidth={29}
label="Manage alert rules in Alerting UI" label={t('grafana-ui.data-source-settings.alerting-settings-label', 'Manage alert rules in Alerting UI')}
disabled={options.readOnly} disabled={options.readOnly}
tooltip="Manage alert rules for this data source. To manage other alerting resources, add an Alertmanager data source." tooltip={t(
'grafana-ui.data-source-settings.alerting-settings-tooltip',
'Manage alert rules for this data source. To manage other alerting resources, add an Alertmanager data source.'
)}
> >
<InlineSwitch <InlineSwitch
value={options.jsonData.manageAlerts !== false} value={options.jsonData.manageAlerts !== false}

View File

@ -1,6 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import { InlineField } from '../../components/Forms/InlineField'; import { InlineField } from '../../components/Forms/InlineField';
import { t } from '../../utils/i18n';
import { FormField } from '../FormField/FormField'; import { FormField } from '../FormField/FormField';
import { SecretFormField } from '../SecretFormField/SecretFormField'; import { SecretFormField } from '../SecretFormField/SecretFormField';
@ -37,10 +38,10 @@ export const BasicAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsPr
<> <>
<InlineField disabled={dataSourceConfig.readOnly}> <InlineField disabled={dataSourceConfig.readOnly}>
<FormField <FormField
label="User" label={t('grafana-ui.data-source-basic-auth-settings.user-label', 'User')}
labelWidth={10} labelWidth={10}
inputWidth={18} inputWidth={18}
placeholder="user" placeholder={t('grafana-ui.data-source-basic-auth-settings.user-placeholder', 'user')}
value={dataSourceConfig.basicAuthUser} value={dataSourceConfig.basicAuthUser}
onChange={(event) => onChange({ ...dataSourceConfig, basicAuthUser: event.currentTarget.value })} onChange={(event) => onChange({ ...dataSourceConfig, basicAuthUser: event.currentTarget.value })}
/> />

View File

@ -5,7 +5,7 @@ import { PureComponent } from 'react';
import { DataSourceSettings } from '@grafana/data'; import { DataSourceSettings } from '@grafana/data';
import { useStyles2 } from '../../themes'; import { useStyles2 } from '../../themes';
import { Trans } from '../../utils/i18n'; import { t, Trans } from '../../utils/i18n';
import { Button } from '../Button'; import { Button } from '../Button';
import { FormField } from '../FormField/FormField'; import { FormField } from '../FormField/FormField';
import { Icon } from '../Icon/Icon'; import { Icon } from '../Icon/Icon';
@ -59,8 +59,9 @@ const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: Custom
return ( return (
<div className={styles.layout}> <div className={styles.layout}>
<FormField <FormField
label="Header" label={t('grafana-ui.data-source-settings.custom-headers-header', 'Header')}
name="name" name="name"
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="X-Custom-Header" placeholder="X-Custom-Header"
labelWidth={5} labelWidth={5}
value={header.name || ''} value={header.name || ''}
@ -68,21 +69,21 @@ const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: Custom
onBlur={onBlur} onBlur={onBlur}
/> />
<SecretFormField <SecretFormField
label="Value" label={t('grafana-ui.data-source-settings.custom-headers-header-value', 'Value')}
aria-label="Value" aria-label={t('grafana-ui.data-source-settings.custom-headers-header-value', 'Value')}
name="value" name="value"
isConfigured={header.configured} isConfigured={header.configured}
value={header.value} value={header.value}
labelWidth={5} labelWidth={5}
inputWidth={header.configured ? 11 : 12} inputWidth={header.configured ? 11 : 12}
placeholder="Header Value" placeholder={t('grafana-ui.data-source-settings.custom-headers-header-placeholder', 'Header Value')}
onReset={() => onReset(header.id)} onReset={() => onReset(header.id)}
onChange={(e) => onChange({ ...header, value: e.target.value })} onChange={(e) => onChange({ ...header, value: e.target.value })}
onBlur={onBlur} onBlur={onBlur}
/> />
<Button <Button
type="button" type="button"
aria-label="Remove header" aria-label={t('grafana-ui.data-source-settings.custom-headers-header-remove', 'Remove header')}
variant="secondary" variant="secondary"
size="xs" size="xs"
onClick={(_e) => onRemove(header.id)} onClick={(_e) => onRemove(header.id)}

View File

@ -5,7 +5,7 @@ import { SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors'; import { selectors } from '@grafana/e2e-selectors';
import { useTheme2 } from '../../themes'; import { useTheme2 } from '../../themes';
import { Trans } from '../../utils/i18n'; import { t, Trans } from '../../utils/i18n';
import { Alert } from '../Alert/Alert'; import { Alert } from '../Alert/Alert';
import { FormField } from '../FormField/FormField'; import { FormField } from '../FormField/FormField';
import { InlineFormLabel } from '../FormLabel/FormLabel'; import { InlineFormLabel } from '../FormLabel/FormLabel';
@ -26,22 +26,23 @@ import { HttpSettingsProps } from './types';
const ACCESS_OPTIONS: Array<SelectableValue<string>> = [ const ACCESS_OPTIONS: Array<SelectableValue<string>> = [
{ {
label: 'Server (default)', label: t('grafana-ui.data-source-http-settings.access-options-proxy', 'Server (default)'),
value: 'proxy', value: 'proxy',
}, },
{ {
label: 'Browser', label: t('grafana-ui.data-source-http-settings.access-options-browser', 'Browser'),
value: 'direct', value: 'direct',
}, },
]; ];
const DEFAULT_ACCESS_OPTION = { const DEFAULT_ACCESS_OPTION = {
label: 'Server (default)', label: t('grafana-ui.data-source-http-settings.access-options-proxy', 'Server (default)'),
value: 'proxy', value: 'proxy',
}; };
const HttpAccessHelp = () => { const HttpAccessHelp = () => {
return ( return (
// eslint-disable-next-line @grafana/no-untranslated-strings
<Alert severity="info" title="" topSpacing={3}> <Alert severity="info" title="" topSpacing={3}>
<p> <p>
<Trans i18nKey="grafana-ui.data-source-http-settings.access-help-details"> <Trans i18nKey="grafana-ui.data-source-http-settings.access-help-details">
@ -161,7 +162,7 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
const accessSelect = ( const accessSelect = (
<Select <Select
aria-label="Access" aria-label={t('grafana-ui.data-source-http-settings.default-url-access-select', 'Access')}
className="width-20 gf-form-input" className="width-20 gf-form-input"
options={ACCESS_OPTIONS} options={ACCESS_OPTIONS}
value={ACCESS_OPTIONS.filter((o) => o.value === dataSourceConfig.access)[0] || DEFAULT_ACCESS_OPTION} value={ACCESS_OPTIONS.filter((o) => o.value === dataSourceConfig.access)[0] || DEFAULT_ACCESS_OPTION}
@ -204,7 +205,7 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
<div className="gf-form"> <div className="gf-form">
<FormField <FormField
interactive={urlDocs ? true : false} interactive={urlDocs ? true : false}
label={urlLabel ?? 'URL'} label={urlLabel ?? t('grafana-ui.data-source-http-settings.url-label', 'URL')}
labelWidth={13} labelWidth={13}
tooltip={urlTooltip} tooltip={urlTooltip}
inputEl={urlInput} inputEl={urlInput}
@ -215,7 +216,12 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
<> <>
<div className="gf-form-inline"> <div className="gf-form-inline">
<div className="gf-form"> <div className="gf-form">
<FormField label="Access" labelWidth={13} inputWidth={20} inputEl={accessSelect} /> <FormField
label={t('grafana-ui.data-source-http-settings.access-label', 'Access')}
labelWidth={13}
inputWidth={20}
inputEl={accessSelect}
/>
</div> </div>
<div className="gf-form"> <div className="gf-form">
<button <button
@ -238,7 +244,10 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
<div className="gf-form"> <div className="gf-form">
<InlineFormLabel <InlineFormLabel
width={13} width={13}
tooltip="Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source." tooltip={t(
'grafana-ui.data-source-http-settings.allowed-cookies-tooltip',
'Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.'
)}
> >
<Trans i18nKey="grafana-ui.data-source-http-settings.allowed-cookies">Allowed cookies</Trans> <Trans i18nKey="grafana-ui.data-source-http-settings.allowed-cookies">Allowed cookies</Trans>
</InlineFormLabel> </InlineFormLabel>
@ -253,13 +262,13 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
</div> </div>
<div className="gf-form"> <div className="gf-form">
<FormField <FormField
label="Timeout" label={t('grafana-ui.data-source-http-settings.timeout-form-label', 'Timeout')}
type="number" type="number"
labelWidth={13} labelWidth={13}
inputWidth={20} inputWidth={20}
tooltip="HTTP request timeout in seconds" tooltip={t('grafana-ui.data-source-http-settings.timeout-tooltip', 'HTTP request timeout in seconds')}
placeholder="Timeout in seconds" placeholder={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout in seconds')}
aria-label="Timeout in seconds" aria-label={t('grafana-ui.data-source-http-settings.timeout-label', 'Timeout in seconds')}
value={dataSourceConfig.jsonData.timeout} value={dataSourceConfig.jsonData.timeout}
onChange={(event) => { onChange={(event) => {
onSettingsChange({ onSettingsChange({
@ -280,7 +289,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
</h3> </h3>
<div className="gf-form-group"> <div className="gf-form-group">
<div className="gf-form-inline"> <div className="gf-form-inline">
<InlineField label="Basic auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}> <InlineField
label={t('grafana-ui.data-source-http-settings.basic-auth-label', 'Basic auth')}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch <InlineSwitch
id="http-settings-basic-auth" id="http-settings-basic-auth"
value={dataSourceConfig.basicAuth} value={dataSourceConfig.basicAuth}
@ -291,8 +304,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
</InlineField> </InlineField>
<InlineField <InlineField
label="With Credentials" label={t('grafana-ui.data-source-http-settings.with-credential-label', 'With Credentials')}
tooltip="Whether credentials such as cookies or auth headers should be sent with cross-site requests." tooltip={t(
'grafana-ui.data-source-http-settings.with-credential-tooltip',
'Whether credentials such as cookies or auth headers should be sent with cross-site requests.'
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
@ -309,8 +325,11 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
{azureAuthSettings?.azureAuthSupported && ( {azureAuthSettings?.azureAuthSupported && (
<div className="gf-form-inline"> <div className="gf-form-inline">
<InlineField <InlineField
label="Azure Authentication" label={t('grafana-ui.data-source-http-settings.azure-auth-label', 'Azure Authentication')}
tooltip="Use Azure authentication for Azure endpoint." tooltip={t(
'grafana-ui.data-source-http-settings.azure-auth-tooltip',
'Use Azure authentication for Azure endpoint.'
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
@ -329,7 +348,12 @@ export const DataSourceHttpSettings = (props: HttpSettingsProps) => {
{sigV4AuthToggleEnabled && ( {sigV4AuthToggleEnabled && (
<div className="gf-form-inline"> <div className="gf-form-inline">
<InlineField label="SigV4 auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}> <InlineField
// eslint-disable-next-line @grafana/no-untranslated-strings
label="SigV4 auth"
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch <InlineSwitch
id="http-settings-sigv4-auth" id="http-settings-sigv4-auth"
value={dataSourceConfig.jsonData.sigV4Auth || false} value={dataSourceConfig.jsonData.sigV4Auth || false}

View File

@ -1,3 +1,4 @@
import { t } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
import { InlineSwitch } from '../Switch/Switch'; import { InlineSwitch } from '../Switch/Switch';
@ -13,7 +14,11 @@ export const HttpProxySettings = ({
return ( return (
<> <>
<div className="gf-form-inline"> <div className="gf-form-inline">
<InlineField label="TLS Client Auth" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}> <InlineField
label={t('grafana-ui.data-source-http-proxy-settings.ts-client-auth-label', 'TLS Client Auth')}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch <InlineSwitch
id="http-settings-tls-client-auth" id="http-settings-tls-client-auth"
value={dataSourceConfig.jsonData.tlsAuth || false} value={dataSourceConfig.jsonData.tlsAuth || false}
@ -21,8 +26,11 @@ export const HttpProxySettings = ({
/> />
</InlineField> </InlineField>
<InlineField <InlineField
label="With CA Cert" label={t('grafana-ui.data-source-http-proxy-settings.with-ca-cert-label', 'With CA Cert')}
tooltip="Needed for verifying self-signed TLS Certs" tooltip={t(
'grafana-ui.data-source-http-proxy-settings.with-ca-cert-tooltip',
'Needed for verifying self-signed TLS Certs'
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >
@ -36,7 +44,11 @@ export const HttpProxySettings = ({
</InlineField> </InlineField>
</div> </div>
<div className="gf-form-inline"> <div className="gf-form-inline">
<InlineField label="Skip TLS Verify" labelWidth={LABEL_WIDTH} disabled={dataSourceConfig.readOnly}> <InlineField
label={t('grafana-ui.data-source-http-proxy-settings.skip-tls-verify-label', 'Skip TLS Verify')}
labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly}
>
<InlineSwitch <InlineSwitch
id="http-settings-skip-tls-verify" id="http-settings-skip-tls-verify"
value={dataSourceConfig.jsonData.tlsSkipVerify || false} value={dataSourceConfig.jsonData.tlsSkipVerify || false}
@ -49,8 +61,11 @@ export const HttpProxySettings = ({
{showForwardOAuthIdentityOption && ( {showForwardOAuthIdentityOption && (
<div className="gf-form-inline"> <div className="gf-form-inline">
<InlineField <InlineField
label="Forward OAuth Identity" label={t('grafana-ui.data-source-http-proxy-settings.oauth-identity-label', 'Forward OAuth Identity')}
tooltip="Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)." tooltip={t(
'grafana-ui.data-source-http-proxy-settings.oauth-identity-tooltip',
"Forward the user's upstream OAuth identity to the data source (Their access token gets passed along)."
)}
labelWidth={LABEL_WIDTH} labelWidth={LABEL_WIDTH}
disabled={dataSourceConfig.readOnly} disabled={dataSourceConfig.readOnly}
> >

View File

@ -1,7 +1,7 @@
import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { DataSourceJsonData, DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { InlineSwitch } from '../../components/Switch/Switch'; import { InlineSwitch } from '../../components/Switch/Switch';
import { Trans } from '../../utils/i18n'; import { t, Trans } from '../../utils/i18n';
import { InlineField } from '../Forms/InlineField'; import { InlineField } from '../Forms/InlineField';
export interface Props<T extends DataSourceJsonData> export interface Props<T extends DataSourceJsonData>
@ -25,8 +25,11 @@ export function SecureSocksProxySettings<T extends SecureSocksProxyConfig>({
<div className="gf-form"> <div className="gf-form">
<InlineField <InlineField
labelWidth={26} labelWidth={26}
label="Enabled" label={t('grafana-ui.data-source-settings.secure-socks-label', 'Enabled')}
tooltip="Connect to this datasource via the secure socks proxy." tooltip={t(
'grafana-ui.data-source-settings.secure-socks-tooltip',
'Connect to this datasource via the secure socks proxy.'
)}
> >
<InlineSwitch <InlineSwitch
value={options.jsonData.enableSecureSocksProxy ?? false} value={options.jsonData.enableSecureSocksProxy ?? false}

View File

@ -3,7 +3,7 @@ import * as React from 'react';
import { KeyValue } from '@grafana/data'; import { KeyValue } from '@grafana/data';
import { Trans } from '../../utils/i18n'; import { t, Trans } from '../../utils/i18n';
import { FormField } from '../FormField/FormField'; import { FormField } from '../FormField/FormField';
import { Icon } from '../Icon/Icon'; import { Icon } from '../Icon/Icon';
import { Tooltip } from '../Tooltip/Tooltip'; import { Tooltip } from '../Tooltip/Tooltip';
@ -49,6 +49,9 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
}); });
}; };
const certificateBeginsWith = '-----BEGIN CERTIFICATE-----';
const privateKeyBeginsWith = '-----BEGIN RSA PRIVATE KEY-----';
return ( return (
<div className="gf-form-group"> <div className="gf-form-group">
<div <div
@ -64,7 +67,10 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
</h6> </h6>
<Tooltip <Tooltip
placement="right-end" placement="right-end"
content="TLS/SSL Certs are encrypted and stored in the Grafana database." content={t(
'grafana-ui.data-source-settings.tls-tooltip',
'TLS/SSL Certs are encrypted and stored in the Grafana database.'
)}
theme="info" theme="info"
> >
<Icon name="info-circle" size="xs" style={{ marginLeft: '10px' }} /> <Icon name="info-circle" size="xs" style={{ marginLeft: '10px' }} />
@ -75,8 +81,12 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
<CertificationKey <CertificationKey
hasCert={!!hasTLSCACert} hasCert={!!hasTLSCACert}
onChange={onCertificateChangeFactory('tlsCACert')} onChange={onCertificateChangeFactory('tlsCACert')}
placeholder="Begins with -----BEGIN CERTIFICATE-----" placeholder={t(
label="CA Cert" 'grafana-ui.data-source-settings.tls-certification-placeholder',
'Begins with {{certificateBeginsWith}}',
{ certificateBeginsWith }
)}
label={t('grafana-ui.data-source-settings.tls-certification-label', 'CA Cert')}
onClick={onResetClickFactory('tlsCACert')} onClick={onResetClickFactory('tlsCACert')}
/> />
)} )}
@ -85,9 +95,10 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
<> <>
<div className="gf-form"> <div className="gf-form">
<FormField <FormField
label="ServerName" label={t('grafana-ui.data-source-settings.tls-server-name-label', 'ServerName')}
labelWidth={7} labelWidth={7}
inputWidth={30} inputWidth={30}
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="domain.example.com" placeholder="domain.example.com"
value={hasServerName && dataSourceConfig.jsonData.serverName} value={hasServerName && dataSourceConfig.jsonData.serverName}
onChange={onServerNameLabelChange} onChange={onServerNameLabelChange}
@ -95,16 +106,24 @@ export const TLSAuthSettings = ({ dataSourceConfig, onChange }: HttpSettingsBase
</div> </div>
<CertificationKey <CertificationKey
hasCert={!!hasTLSClientCert} hasCert={!!hasTLSClientCert}
label="Client Cert" label={t('grafana-ui.data-source-settings.tls-client-certification-label', 'Client Cert')}
onChange={onCertificateChangeFactory('tlsClientCert')} onChange={onCertificateChangeFactory('tlsClientCert')}
placeholder="Begins with -----BEGIN CERTIFICATE-----" placeholder={t(
'grafana-ui.data-source-settings.tls-certification-placeholder',
'Begins with {{certificateBeginsWith}}',
{ certificateBeginsWith }
)}
onClick={onResetClickFactory('tlsClientCert')} onClick={onResetClickFactory('tlsClientCert')}
/> />
<CertificationKey <CertificationKey
hasCert={!!hasTLSClientKey} hasCert={!!hasTLSClientKey}
label="Client Key" label={t('grafana-ui.data-source-settings.tls-client-key-label', 'Client Key')}
placeholder="Begins with -----BEGIN RSA PRIVATE KEY-----" placeholder={t(
'grafana-ui.data-source-settings.tls-client-key-placeholder',
'Begins with {{privateKeyBeginsWith}}',
{ privateKeyBeginsWith }
)}
onChange={onCertificateChangeFactory('tlsClientKey')} onChange={onCertificateChangeFactory('tlsClientKey')}
onClick={onResetClickFactory('tlsClientKey')} onClick={onResetClickFactory('tlsClientKey')}
/> />

View File

@ -21,7 +21,7 @@ import {
import { Components } from '@grafana/e2e-selectors'; import { Components } from '@grafana/e2e-selectors';
import { useStyles2, useTheme2 } from '../../../themes'; import { useStyles2, useTheme2 } from '../../../themes';
import { Trans } from '../../../utils/i18n'; import { t, Trans } from '../../../utils/i18n';
import { Button } from '../../Button/Button'; import { Button } from '../../Button/Button';
import { InlineField } from '../../Forms/InlineField'; import { InlineField } from '../../Forms/InlineField';
import { Icon } from '../../Icon/Icon'; import { Icon } from '../../Icon/Icon';
@ -253,7 +253,14 @@ const DateTimeInput = React.forwardRef<HTMLInputElement, InputProps>(
onChange(); onChange();
}, [onChange]); }, [onChange]);
const icon = <Button aria-label="Time picker" icon="calendar-alt" variant="secondary" onClick={onOpen} />; const icon = (
<Button
aria-label={t('grafana-ui.date-time-picker.calendar-icon-label', 'Time picker')}
icon="calendar-alt"
variant="secondary"
onClick={onOpen}
/>
);
return ( return (
<InlineField label={label} invalid={!!(internalDate.value && internalDate.invalid)} className={styles.field}> <InlineField label={label} invalid={!!(internalDate.value && internalDate.invalid)} className={styles.field}>
<Input <Input
@ -262,7 +269,7 @@ const DateTimeInput = React.forwardRef<HTMLInputElement, InputProps>(
value={internalDate.value} value={internalDate.value}
onBlur={onBlur} onBlur={onBlur}
data-testid={Components.DateTimePicker.input} data-testid={Components.DateTimePicker.input}
placeholder="Select date/time" placeholder={t('grafana-ui.date-time-picker.select-placeholder', 'Select date/time')}
ref={ref} ref={ref}
suffix={ suffix={
clearable && clearable &&
@ -343,9 +350,9 @@ const DateTimeCalendar = React.forwardRef<HTMLDivElement, DateTimeCalendarProps>
prev2Label={null} prev2Label={null}
value={reactCalendarDate} value={reactCalendarDate}
nextLabel={<Icon name="angle-right" />} nextLabel={<Icon name="angle-right" />}
nextAriaLabel="Next month" nextAriaLabel={t('grafana-ui.date-time-picker.next-label', 'Next month')}
prevLabel={<Icon name="angle-left" />} prevLabel={<Icon name="angle-left" />}
prevAriaLabel="Previous month" prevAriaLabel={t('grafana-ui.date-time-picker.previous-label', 'Previous month')}
onChange={onChangeDate} onChange={onChangeDate}
locale="en" locale="en"
className={calendarStyles.body} className={calendarStyles.body}

View File

@ -179,7 +179,11 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
</Tooltip> </Tooltip>
</TimePickerTitle> </TimePickerTitle>
</div> </div>
<Field label="From" invalid={!from.validation.isValid} error={from.validation.errorMessage}> <Field
label={t('time-picker.time-range.from-label', 'From')}
invalid={!from.validation.isValid}
error={from.validation.errorMessage}
>
<Input <Input
onClick={(event) => event.stopPropagation()} onClick={(event) => event.stopPropagation()}
onBlur={() => setFrom({ ...from, validation: isRangeValid(from.value) })} onBlur={() => setFrom({ ...from, validation: isRangeValid(from.value) })}
@ -187,7 +191,11 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
value={from.value} value={from.value}
/> />
</Field> </Field>
<Field label="To" invalid={!to.validation.isValid} error={to.validation.errorMessage}> <Field
label={t('time-picker.time-range.to-label', 'To')}
invalid={!to.validation.isValid}
error={to.validation.errorMessage}
>
<Input <Input
onClick={(event) => event.stopPropagation()} onClick={(event) => event.stopPropagation()}
onBlur={() => setTo({ ...to, validation: isRangeValid(to.value) })} onBlur={() => setTo({ ...to, validation: isRangeValid(to.value) })}
@ -195,7 +203,10 @@ export function RelativeTimeRangePicker(props: RelativeTimeRangePickerProps) {
value={to.value} value={to.value}
/> />
</Field> </Field>
<Button aria-label="TimePicker submit button" onClick={onApply}> <Button
aria-label={t('time-picker.time-range.submit-button-label', 'TimePicker submit button')}
onClick={onApply}
>
<Trans i18nKey="time-picker.time-range.apply">Apply time range</Trans> <Trans i18nKey="time-picker.time-range.apply">Apply time range</Trans>
</Button> </Button>
</div> </div>

View File

@ -1706,10 +1706,19 @@
"one-click-description": "Only one link {{ action }} can have one click enabled at a time" "one-click-description": "Only one link {{ action }} can have one click enabled at a time"
} }
}, },
"alert": {
"close-button": "Close alert"
},
"auto-save-field": { "auto-save-field": {
"saved": "Saved!", "saved": "Saved!",
"saving": "Saving <1></1>" "saving": "Saving <1></1>"
}, },
"card": {
"option": "option"
},
"cascader": {
"clear-button": "Clear selection"
},
"color-picker-popover": { "color-picker-popover": {
"palette-tab": "Colors", "palette-tab": "Colors",
"spectrum-tab": "Custom" "spectrum-tab": "Custom"
@ -1717,8 +1726,15 @@
"confirm-button": { "confirm-button": {
"cancel": "Cancel" "cancel": "Cancel"
}, },
"confirm-content": {
"placeholder": "Type \"{{confirmPromptText}}\" to confirm"
},
"data-link-editor": { "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." "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.",
"new-tab-label": "Open in new tab",
"title-label": "Title",
"title-placeholder": "Show details",
"url-label": "URL"
}, },
"data-link-editor-modal": { "data-link-editor-modal": {
"cancel": "Cancel", "cancel": "Cancel",
@ -1738,32 +1754,77 @@
"tooltip-remove": "Remove", "tooltip-remove": "Remove",
"url-not-provided": "Data link url not provided" "url-not-provided": "Data link url not provided"
}, },
"data-source-basic-auth-settings": {
"user-label": "User",
"user-placeholder": "user"
},
"data-source-http-proxy-settings": {
"oauth-identity-label": "Forward OAuth Identity",
"oauth-identity-tooltip": "Forward the user's upstream OAuth identity to the data source (Their access token gets passed along).",
"skip-tls-verify-label": "Skip TLS Verify",
"ts-client-auth-label": "TLS Client Auth",
"with-ca-cert-label": "With CA Cert",
"with-ca-cert-tooltip": "Needed for verifying self-signed TLS Certs"
},
"data-source-http-settings": { "data-source-http-settings": {
"access-help": "Help <1></1>", "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.", "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.",
"access-label": "Access",
"access-options-browser": "Browser",
"access-options-proxy": "Server (default)",
"allowed-cookies": "Allowed cookies", "allowed-cookies": "Allowed cookies",
"allowed-cookies-tooltip": "Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source.",
"auth": "Auth", "auth": "Auth",
"azure-auth-label": "Azure Authentication",
"azure-auth-tooltip": "Use Azure authentication for Azure endpoint.",
"basic-auth": "Basic Auth Details", "basic-auth": "Basic Auth Details",
"basic-auth-label": "Basic auth",
"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-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>", "browser-mode-title": "<0>Browser access mode:</0>",
"default-url-access-select": "Access",
"default-url-tooltip": "Specify a complete HTTP URL (for example http://your_server:8080)", "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.", "direct-url-tooltip": "Your access method is <1>Browser</1>, this means the URL needs to be accessible from the browser.",
"heading": "HTTP", "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.", "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-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>" "server-mode-title": "<0>Server access mode (Default):</0>",
"timeout-form-label": "Timeout",
"timeout-label": "Timeout in seconds",
"timeout-tooltip": "HTTP request timeout in seconds",
"url-label": "URL",
"with-credential-label": "With Credentials",
"with-credential-tooltip": "Whether credentials such as cookies or auth headers should be sent with cross-site requests."
}, },
"data-source-settings": { "data-source-settings": {
"alerting-settings-heading": "Alerting", "alerting-settings-heading": "Alerting",
"alerting-settings-label": "Manage alert rules in Alerting UI",
"alerting-settings-tooltip": "Manage alert rules for this data source. To manage other alerting resources, add an Alertmanager data source.",
"cert-key-reset": "Reset", "cert-key-reset": "Reset",
"custom-headers-add": "Add header", "custom-headers-add": "Add header",
"custom-headers-header": "Header",
"custom-headers-header-placeholder": "Header Value",
"custom-headers-header-remove": "Remove header",
"custom-headers-header-value": "Value",
"custom-headers-title": "Custom HTTP Headers", "custom-headers-title": "Custom HTTP Headers",
"secure-socks-heading": "Secure Socks Proxy", "secure-socks-heading": "Secure Socks Proxy",
"tls-heading": "TLS/SSL Auth Details" "secure-socks-label": "Enabled",
"secure-socks-tooltip": "Connect to this datasource via the secure socks proxy.",
"tls-certification-label": "CA Cert",
"tls-certification-placeholder": "Begins with {{certificateBeginsWith}}",
"tls-client-certification-label": "Client Cert",
"tls-client-key-label": "Client Key",
"tls-client-key-placeholder": "Begins with {{privateKeyBeginsWith}}",
"tls-heading": "TLS/SSL Auth Details",
"tls-server-name-label": "ServerName",
"tls-tooltip": "TLS/SSL Certs are encrypted and stored in the Grafana database."
}, },
"date-time-picker": { "date-time-picker": {
"apply": "Apply", "apply": "Apply",
"cancel": "Cancel" "calendar-icon-label": "Time picker",
"cancel": "Cancel",
"next-label": "Next month",
"previous-label": "Previous month",
"select-placeholder": "Select date/time"
}, },
"drawer": { "drawer": {
"close": "Close" "close": "Close"
@ -1787,6 +1848,10 @@
"modal": { "modal": {
"close-tooltip": "Close" "close-tooltip": "Close"
}, },
"named-colors-palette": {
"text-color-swatch": "Text color",
"transparent-swatch": "Transparent"
},
"secret-form-field": { "secret-form-field": {
"reset": "Reset" "reset": "Reset"
}, },
@ -1800,6 +1865,9 @@
"no-options-label": "No options found", "no-options-label": "No options found",
"placeholder": "Choose" "placeholder": "Choose"
}, },
"series-color-picker-popover": {
"y-axis-usage": "Use right y-axis"
},
"spinner": { "spinner": {
"aria-label": "Loading" "aria-label": "Loading"
}, },
@ -1819,6 +1887,9 @@
"user-icon": { "user-icon": {
"active-text": "Active last 15m" "active-text": "Active last 15m"
}, },
"value-pill": {
"remove-button": "Remove {{children}}"
},
"viz-legend": { "viz-legend": {
"right-axis-indicator": "(right y-axis)" "right-axis-indicator": "(right y-axis)"
}, },
@ -3721,10 +3792,13 @@
"example": "Example: to select a time range from 10 minutes ago to now", "example": "Example: to select a time range from 10 minutes ago to now",
"example-details": "From: now-10m To: now", "example-details": "From: now-10m To: now",
"example-title": "Example time ranges", "example-title": "Example time ranges",
"from-label": "From",
"from-to": "{{timeOptionFrom}} to {{timeOptionTo}}", "from-to": "{{timeOptionFrom}} to {{timeOptionTo}}",
"more-info": "For more information see <2>docs <1></1></2>.", "more-info": "For more information see <2>docs <1></1></2>.",
"specify": "Specify time range <1></1>", "specify": "Specify time range <1></1>",
"supported-formats": "Supported formats: <1>now-[digit]s/m/h/d/w</1>" "submit-button-label": "TimePicker submit button",
"supported-formats": "Supported formats: <1>now-[digit]s/m/h/d/w</1>",
"to-label": "To"
}, },
"zone": { "zone": {
"select-aria-label": "Time zone picker", "select-aria-label": "Time zone picker",

View File

@ -1706,10 +1706,19 @@
"one-click-description": "Øʼnľy őʼnę ľįʼnĸ {{ action }} čäʼn ĥävę őʼnę čľįčĸ ęʼnäþľęđ äŧ ä ŧįmę" "one-click-description": "Øʼnľy őʼnę ľįʼnĸ {{ action }} čäʼn ĥävę őʼnę čľįčĸ ęʼnäþľęđ äŧ ä ŧįmę"
} }
}, },
"alert": {
"close-button": "Cľőşę äľęřŧ"
},
"auto-save-field": { "auto-save-field": {
"saved": "Ŝävęđ!", "saved": "Ŝävęđ!",
"saving": "Ŝävįʼnģ <1></1>" "saving": "Ŝävįʼnģ <1></1>"
}, },
"card": {
"option": "őpŧįőʼn"
},
"cascader": {
"clear-button": "Cľęäř şęľęčŧįőʼn"
},
"color-picker-popover": { "color-picker-popover": {
"palette-tab": "Cőľőřş", "palette-tab": "Cőľőřş",
"spectrum-tab": "Cūşŧőm" "spectrum-tab": "Cūşŧőm"
@ -1717,8 +1726,15 @@
"confirm-button": { "confirm-button": {
"cancel": "Cäʼnčęľ" "cancel": "Cäʼnčęľ"
}, },
"confirm-content": {
"placeholder": "Ŧypę \"{{confirmPromptText}}\" ŧő čőʼnƒįřm"
},
"data-link-editor": { "data-link-editor": {
"info": "Ŵįŧĥ đäŧä ľįʼnĸş yőū čäʼn řęƒęřęʼnčę đäŧä väřįäþľęş ľįĸę şęřįęş ʼnämę, ľäþęľş äʼnđ väľūęş. Ŧypę CMĐ+Ŝpäčę, CŦŖĿ+Ŝpäčę, őř $ ŧő őpęʼn väřįäþľę şūģģęşŧįőʼnş." "info": "Ŵįŧĥ đäŧä ľįʼnĸş yőū čäʼn řęƒęřęʼnčę đäŧä väřįäþľęş ľįĸę şęřįęş ʼnämę, ľäþęľş äʼnđ väľūęş. Ŧypę CMĐ+Ŝpäčę, CŦŖĿ+Ŝpäčę, őř $ ŧő őpęʼn väřįäþľę şūģģęşŧįőʼnş.",
"new-tab-label": "Øpęʼn įʼn ʼnęŵ ŧäþ",
"title-label": "Ŧįŧľę",
"title-placeholder": "Ŝĥőŵ đęŧäįľş",
"url-label": "ŮŖĿ"
}, },
"data-link-editor-modal": { "data-link-editor-modal": {
"cancel": "Cäʼnčęľ", "cancel": "Cäʼnčęľ",
@ -1738,32 +1754,77 @@
"tooltip-remove": "Ŗęmővę", "tooltip-remove": "Ŗęmővę",
"url-not-provided": "Đäŧä ľįʼnĸ ūřľ ʼnőŧ přővįđęđ" "url-not-provided": "Đäŧä ľįʼnĸ ūřľ ʼnőŧ přővįđęđ"
}, },
"data-source-basic-auth-settings": {
"user-label": "Ůşęř",
"user-placeholder": "ūşęř"
},
"data-source-http-proxy-settings": {
"oauth-identity-label": "Főřŵäřđ ØÅūŧĥ Ĩđęʼnŧįŧy",
"oauth-identity-tooltip": "Főřŵäřđ ŧĥę ūşęř'ş ūpşŧřęäm ØÅūŧĥ įđęʼnŧįŧy ŧő ŧĥę đäŧä şőūřčę (Ŧĥęįř äččęşş ŧőĸęʼn ģęŧş päşşęđ äľőʼnģ).",
"skip-tls-verify-label": "Ŝĸįp ŦĿŜ Vęřįƒy",
"ts-client-auth-label": "ŦĿŜ Cľįęʼnŧ Åūŧĥ",
"with-ca-cert-label": "Ŵįŧĥ CÅ Cęřŧ",
"with-ca-cert-tooltip": "Ńęęđęđ ƒőř vęřįƒyįʼnģ şęľƒ-şįģʼnęđ ŦĿŜ Cęřŧş"
},
"data-source-http-settings": { "data-source-http-settings": {
"access-help": "Ħęľp <1></1>", "access-help": "Ħęľp <1></1>",
"access-help-details": "Åččęşş mőđę čőʼnŧřőľş ĥőŵ řęqūęşŧş ŧő ŧĥę đäŧä şőūřčę ŵįľľ þę ĥäʼnđľęđ.<1> <1>Ŝęřvęř</1></1> şĥőūľđ þę ŧĥę přęƒęřřęđ ŵäy įƒ ʼnőŧĥįʼnģ ęľşę įş şŧäŧęđ.", "access-help-details": "Åččęşş mőđę čőʼnŧřőľş ĥőŵ řęqūęşŧş ŧő ŧĥę đäŧä şőūřčę ŵįľľ þę ĥäʼnđľęđ.<1> <1>Ŝęřvęř</1></1> şĥőūľđ þę ŧĥę přęƒęřřęđ ŵäy įƒ ʼnőŧĥįʼnģ ęľşę įş şŧäŧęđ.",
"access-label": "Åččęşş",
"access-options-browser": "ßřőŵşęř",
"access-options-proxy": "Ŝęřvęř (đęƒäūľŧ)",
"allowed-cookies": "Åľľőŵęđ čőőĸįęş", "allowed-cookies": "Åľľőŵęđ čőőĸįęş",
"allowed-cookies-tooltip": "Ğřäƒäʼnä přőχy đęľęŧęş ƒőřŵäřđęđ čőőĸįęş þy đęƒäūľŧ. Ŝpęčįƒy čőőĸįęş þy ʼnämę ŧĥäŧ şĥőūľđ þę ƒőřŵäřđęđ ŧő ŧĥę đäŧä şőūřčę.",
"auth": "Åūŧĥ", "auth": "Åūŧĥ",
"azure-auth-label": "Åžūřę Åūŧĥęʼnŧįčäŧįőʼn",
"azure-auth-tooltip": "Ůşę Åžūřę äūŧĥęʼnŧįčäŧįőʼn ƒőř Åžūřę ęʼnđpőįʼnŧ.",
"basic-auth": "ßäşįč Åūŧĥ Đęŧäįľş", "basic-auth": "ßäşįč Åūŧĥ Đęŧäįľş",
"basic-auth-label": "ßäşįč äūŧĥ",
"browser-mode-description": "Åľľ řęqūęşŧş ŵįľľ þę mäđę ƒřőm ŧĥę þřőŵşęř đįřęčŧľy ŧő ŧĥę đäŧä şőūřčę äʼnđ mäy þę şūþĵęčŧ ŧő Cřőşş-Øřįģįʼn Ŗęşőūřčę Ŝĥäřįʼnģ (CØŖŜ) řęqūįřęmęʼnŧş. Ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř įƒ yőū şęľęčŧ ŧĥįş äččęşş mőđę.", "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>", "browser-mode-title": "<0>ßřőŵşęř äččęşş mőđę:</0>",
"default-url-access-select": "Åččęşş",
"default-url-tooltip": "Ŝpęčįƒy ä čőmpľęŧę ĦŦŦP ŮŖĿ (ƒőř ęχämpľę ĥŧŧp://yőūř_şęřvęř:8080)", "default-url-tooltip": "Ŝpęčįƒy ä čőmpľęŧę ĦŦŦP ŮŖĿ (ƒőř ęχämpľę ĥŧŧp://yőūř_şęřvęř:8080)",
"direct-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>ßřőŵşęř</1>, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř.", "direct-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>ßřőŵşęř</1>, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř.",
"heading": "ĦŦŦP", "heading": "ĦŦŦP",
"proxy-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>Ŝęřvęř</1>, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę ģřäƒäʼnä þäčĸęʼnđ/şęřvęř.", "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-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>" "server-mode-title": "<0>Ŝęřvęř äččęşş mőđę (Đęƒäūľŧ):</0>",
"timeout-form-label": "Ŧįmęőūŧ",
"timeout-label": "Ŧįmęőūŧ įʼn şęčőʼnđş",
"timeout-tooltip": "ĦŦŦP řęqūęşŧ ŧįmęőūŧ įʼn şęčőʼnđş",
"url-label": "ŮŖĿ",
"with-credential-label": "Ŵįŧĥ Cřęđęʼnŧįäľş",
"with-credential-tooltip": "Ŵĥęŧĥęř čřęđęʼnŧįäľş şūčĥ äş čőőĸįęş őř äūŧĥ ĥęäđęřş şĥőūľđ þę şęʼnŧ ŵįŧĥ čřőşş-şįŧę řęqūęşŧş."
}, },
"data-source-settings": { "data-source-settings": {
"alerting-settings-heading": "Åľęřŧįʼnģ", "alerting-settings-heading": "Åľęřŧįʼnģ",
"alerting-settings-label": "Mäʼnäģę äľęřŧ řūľęş įʼn Åľęřŧįʼnģ ŮĨ",
"alerting-settings-tooltip": "Mäʼnäģę äľęřŧ řūľęş ƒőř ŧĥįş đäŧä şőūřčę. Ŧő mäʼnäģę őŧĥęř äľęřŧįʼnģ řęşőūřčęş, äđđ äʼn Åľęřŧmäʼnäģęř đäŧä şőūřčę.",
"cert-key-reset": "Ŗęşęŧ", "cert-key-reset": "Ŗęşęŧ",
"custom-headers-add": "Åđđ ĥęäđęř", "custom-headers-add": "Åđđ ĥęäđęř",
"custom-headers-header": "Ħęäđęř",
"custom-headers-header-placeholder": "Ħęäđęř Väľūę",
"custom-headers-header-remove": "Ŗęmővę ĥęäđęř",
"custom-headers-header-value": "Väľūę",
"custom-headers-title": "Cūşŧőm ĦŦŦP Ħęäđęřş", "custom-headers-title": "Cūşŧőm ĦŦŦP Ħęäđęřş",
"secure-socks-heading": "Ŝęčūřę Ŝőčĸş Přőχy", "secure-socks-heading": "Ŝęčūřę Ŝőčĸş Přőχy",
"tls-heading": "ŦĿŜ/ŜŜĿ Åūŧĥ Đęŧäįľş" "secure-socks-label": "Ēʼnäþľęđ",
"secure-socks-tooltip": "Cőʼnʼnęčŧ ŧő ŧĥįş đäŧäşőūřčę vįä ŧĥę şęčūřę şőčĸş přőχy.",
"tls-certification-label": "CÅ Cęřŧ",
"tls-certification-placeholder": "ßęģįʼnş ŵįŧĥ {{certificateBeginsWith}}",
"tls-client-certification-label": "Cľįęʼnŧ Cęřŧ",
"tls-client-key-label": "Cľįęʼnŧ Ķęy",
"tls-client-key-placeholder": "ßęģįʼnş ŵįŧĥ {{privateKeyBeginsWith}}",
"tls-heading": "ŦĿŜ/ŜŜĿ Åūŧĥ Đęŧäįľş",
"tls-server-name-label": "ŜęřvęřŃämę",
"tls-tooltip": "ŦĿŜ/ŜŜĿ Cęřŧş äřę ęʼnčřypŧęđ äʼnđ şŧőřęđ įʼn ŧĥę Ğřäƒäʼnä đäŧäþäşę."
}, },
"date-time-picker": { "date-time-picker": {
"apply": "Åppľy", "apply": "Åppľy",
"cancel": "Cäʼnčęľ" "calendar-icon-label": "Ŧįmę pįčĸęř",
"cancel": "Cäʼnčęľ",
"next-label": "Ńęχŧ mőʼnŧĥ",
"previous-label": "Přęvįőūş mőʼnŧĥ",
"select-placeholder": "Ŝęľęčŧ đäŧę/ŧįmę"
}, },
"drawer": { "drawer": {
"close": "Cľőşę" "close": "Cľőşę"
@ -1787,6 +1848,10 @@
"modal": { "modal": {
"close-tooltip": "Cľőşę" "close-tooltip": "Cľőşę"
}, },
"named-colors-palette": {
"text-color-swatch": "Ŧęχŧ čőľőř",
"transparent-swatch": "Ŧřäʼnşpäřęʼnŧ"
},
"secret-form-field": { "secret-form-field": {
"reset": "Ŗęşęŧ" "reset": "Ŗęşęŧ"
}, },
@ -1800,6 +1865,9 @@
"no-options-label": "Ńő őpŧįőʼnş ƒőūʼnđ", "no-options-label": "Ńő őpŧįőʼnş ƒőūʼnđ",
"placeholder": "Cĥőőşę" "placeholder": "Cĥőőşę"
}, },
"series-color-picker-popover": {
"y-axis-usage": "Ůşę řįģĥŧ y-äχįş"
},
"spinner": { "spinner": {
"aria-label": "Ŀőäđįʼnģ" "aria-label": "Ŀőäđįʼnģ"
}, },
@ -1819,6 +1887,9 @@
"user-icon": { "user-icon": {
"active-text": "Åčŧįvę ľäşŧ 15m" "active-text": "Åčŧįvę ľäşŧ 15m"
}, },
"value-pill": {
"remove-button": "Ŗęmővę {{children}}"
},
"viz-legend": { "viz-legend": {
"right-axis-indicator": "(řįģĥŧ y-äχįş)" "right-axis-indicator": "(řįģĥŧ y-äχįş)"
}, },
@ -3721,10 +3792,13 @@
"example": "Ēχämpľę: ŧő şęľęčŧ ä ŧįmę řäʼnģę ƒřőm 10 mįʼnūŧęş äģő ŧő ʼnőŵ", "example": "Ēχämpľę: ŧő şęľęčŧ ä ŧįmę řäʼnģę ƒřőm 10 mįʼnūŧęş äģő ŧő ʼnőŵ",
"example-details": "Fřőm: ʼnőŵ-10m Ŧő: ʼnőŵ", "example-details": "Fřőm: ʼnőŵ-10m Ŧő: ʼnőŵ",
"example-title": "Ēχämpľę ŧįmę řäʼnģęş", "example-title": "Ēχämpľę ŧįmę řäʼnģęş",
"from-label": "Fřőm",
"from-to": "{{timeOptionFrom}} ŧő {{timeOptionTo}}", "from-to": "{{timeOptionFrom}} ŧő {{timeOptionTo}}",
"more-info": "Főř mőřę įʼnƒőřmäŧįőʼn şęę <2>đőčş <1></1></2>.", "more-info": "Főř mőřę įʼnƒőřmäŧįőʼn şęę <2>đőčş <1></1></2>.",
"specify": "Ŝpęčįƒy ŧįmę řäʼnģę <1></1>", "specify": "Ŝpęčįƒy ŧįmę řäʼnģę <1></1>",
"supported-formats": "Ŝūppőřŧęđ ƒőřmäŧş: <1>ʼnőŵ-[đįģįŧ]ş/m/ĥ/đ/ŵ</1>" "submit-button-label": "ŦįmęPįčĸęř şūþmįŧ þūŧŧőʼn",
"supported-formats": "Ŝūppőřŧęđ ƒőřmäŧş: <1>ʼnőŵ-[đįģįŧ]ş/m/ĥ/đ/ŵ</1>",
"to-label": "Ŧő"
}, },
"zone": { "zone": {
"select-aria-label": "Ŧįmę žőʼnę pįčĸęř", "select-aria-label": "Ŧįmę žőʼnę pįčĸęř",