diff --git a/packages/grafana-i18n/src/eslint/no-untranslated-strings/no-untranslated-strings.cjs b/packages/grafana-i18n/src/eslint/no-untranslated-strings/no-untranslated-strings.cjs index 91de4620060..64ca4c5ff4a 100644 --- a/packages/grafana-i18n/src/eslint/no-untranslated-strings/no-untranslated-strings.cjs +++ b/packages/grafana-i18n/src/eslint/no-untranslated-strings/no-untranslated-strings.cjs @@ -24,7 +24,21 @@ const createRule = ESLintUtils.RuleCreator( /** * JSX props to check for untranslated strings */ -const propsToCheck = ['content', 'label', 'description', 'placeholder', 'aria-label', 'title', 'text', 'tooltip']; +const propsToCheck = [ + 'content', + 'label', + 'description', + 'placeholder', + 'aria-label', + 'ariaLabel', + 'title', + 'text', + 'tooltip', + 'confirmText', + 'body', + 'noOptionsMessage', + 'loadingMessage', +]; /** * Object properties to check for untranslated strings @@ -34,11 +48,15 @@ const propertiesToCheck = [ 'description', 'placeholder', 'aria-label', + 'ariaLabel', 'title', 'subTitle', 'text', 'tooltip', 'message', + 'confirmText', + 'placeholderText', + 'noFieldsMessage', ]; /** @type {RuleDefinition} */ diff --git a/packages/grafana-prometheus/src/configuration/PromSettings.tsx b/packages/grafana-prometheus/src/configuration/PromSettings.tsx index 63642bdb592..789275e0814 100644 --- a/packages/grafana-prometheus/src/configuration/PromSettings.tsx +++ b/packages/grafana-prometheus/src/configuration/PromSettings.tsx @@ -40,11 +40,6 @@ const httpOptions = [ { value: 'GET', label: 'GET' }, ]; -const editorOptions = [ - { value: QueryEditorMode.Builder, label: 'Builder' }, - { value: QueryEditorMode.Code, label: 'Code' }, -]; - const cacheValueOptions = [ { value: PrometheusCacheLevel.Low, label: 'Low' }, { value: PrometheusCacheLevel.Medium, label: 'Medium' }, @@ -86,6 +81,17 @@ export const PromSettings = (props: Props) => { const styles = overhaulStyles(theme); const { onOptionsChange } = props; + const editorOptions = [ + { + value: QueryEditorMode.Builder, + label: t('grafana-prometheus.configuration.prom-settings.editor-options.label-builder', 'Builder'), + }, + { + value: QueryEditorMode.Code, + label: t('grafana-prometheus.configuration.prom-settings.editor-options.label-code', 'Code'), + }, + ]; + const optionsWithDefaults = getOptionsWithDefaults(props.options); const [validDuration, updateValidDuration] = useState({ timeInterval: '', diff --git a/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json b/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json index 5de8bc8d245..d7c9b1f6b1b 100644 --- a/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json +++ b/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json @@ -157,6 +157,10 @@ "aria-label-prom-type-type": "{{promType}} type", "aria-label-prometheus-type": "Prometheus type", "aria-label-select-http-method": "Select HTTP method", + "editor-options": { + "label-builder": "Builder", + "label-code": "Code" + }, "label-cache-level": "Cache level", "label-custom-query-parameters": "Custom query parameters", "label-default-editor": "Default editor", @@ -195,6 +199,16 @@ "tooltip-use-series-endpoint": "Checking this option will favor the series endpoint with {{exampleParameter}} parameter over the label values endpoint with {{exampleParameter}} parameter. While the label values endpoint is considered more performant, some users may prefer the series because it has a POST method while the label values endpoint only has a GET method." } }, + "prom-query-legend-editor": { + "get-legend-mode-options": { + "description-auto": "Only includes unique labels", + "description-custom": "Provide a naming template", + "description-verbose": "All label names and values", + "label-auto": "Auto", + "label-custom": "Custom", + "label-verbose": "Verbose" + } + }, "querybuilder": { "additional-settings": { "content-filter-metric-names-regex-search-using": "Filter metric names by regex search, using an additional call on the Prometheus API.", @@ -204,6 +218,13 @@ "give-feedback": "Give feedback", "title-give-feedback": "The metrics explorer is new, please let us know how we can improve it" }, + "get-collapsed-info": { + "exemplars": "Exemplars: {{value}}", + "format": "Format: {{value}}", + "legend": "Legend: {{value}}", + "step": "Step: {{value}}", + "type": "Type: {{value}}" + }, "handle-function": { "text": { "query-parsing-is-ambiguous": "Query parsing is ambiguous." @@ -219,6 +240,10 @@ "label-label-filters": "Label filters", "tooltip-label-filters": "Optional: used to filter the metric select for this query type." }, + "label-param-editor": { + "loadingMessage-loading-labels": "Loading labels", + "noOptionsMessage-no-labels-found": "No labels found" + }, "metric-combobox": { "async-select": { "aria-label-open-metrics-explorer": "Open metrics explorer", @@ -274,6 +299,11 @@ "prom-query-builder-options": { "aria-label-lower-limit-parameter": "Set lower limit for the step parameter", "aria-label-select-resolution": "Select resolution", + "format-options": { + "label-heatmap": "Heatmap", + "label-table": "Table", + "label-time-series": "Time series" + }, "label-exemplars": "Exemplars", "label-format": "Format", "label-min-step": "Min step", @@ -288,6 +318,8 @@ "tooltip-autocomplete-suggestions-limited": "The number of metric names exceeds the autocomplete limit. Only the {{autocompleteLimit}}-most relevant metrics are displayed. You can adjust the threshold in the data source settings." }, "prom-query-editor-selector": { + "body-syntax-error": "There is a syntax error, or the query structure cannot be visualized when switching to the builder mode. Parts of the query may be lost.", + "confirmText-continue": "Continue", "kick-start-your-query": "Kick start your query", "label-explain": "Explain", "run-queries": "Run queries", @@ -304,6 +336,12 @@ "query-editor-hints": { "hint-details": "hint: {{hintDetails}}" }, + "query-editor-mode-toggle": { + "editor-modes": { + "label-builder": "Builder", + "label-code": "Code" + } + }, "query-pattern": { "apply-query": "Apply query", "aria-label-apply-query-starter-button": "apply query starter button", diff --git a/packages/grafana-prometheus/src/querybuilder/components/LabelParamEditor.tsx b/packages/grafana-prometheus/src/querybuilder/components/LabelParamEditor.tsx index ed978167f12..c51940fb3d6 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/LabelParamEditor.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/LabelParamEditor.tsx @@ -2,6 +2,7 @@ import { useState } from 'react'; import { DataSourceApi, SelectableValue, TimeRange, toOption } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { Select } from '@grafana/ui'; import { getOperationParamId } from '../shared/param_utils'; @@ -47,8 +48,14 @@ export function LabelParamEditor({ }} isLoading={state.isLoading} allowCustomValue - noOptionsMessage="No labels found" - loadingMessage="Loading labels" + noOptionsMessage={t( + 'grafana-prometheus.querybuilder.label-param-editor.noOptionsMessage-no-labels-found', + 'No labels found' + )} + loadingMessage={t( + 'grafana-prometheus.querybuilder.label-param-editor.loadingMessage-loading-labels', + 'Loading labels' + )} options={state.options} value={toOption(value as string)} onChange={(value) => onChange(index, value.value!)} diff --git a/packages/grafana-prometheus/src/querybuilder/components/PromQueryBuilderOptions.tsx b/packages/grafana-prometheus/src/querybuilder/components/PromQueryBuilderOptions.tsx index 4be75ddf2e8..67cd36830e1 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/PromQueryBuilderOptions.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/PromQueryBuilderOptions.tsx @@ -32,12 +32,6 @@ export interface PromQueryBuilderOptionsProps { onRunQuery: () => void; } -const FORMAT_OPTIONS: Array> = [ - { label: 'Time series', value: 'time_series' }, - { label: 'Table', value: 'table' }, - { label: 'Heatmap', value: 'heatmap' }, -]; - const INTERVAL_FACTOR_OPTIONS: Array> = map([1, 2, 3, 4, 5, 10], (value: number) => ({ value, label: '1/' + value, @@ -45,6 +39,24 @@ const INTERVAL_FACTOR_OPTIONS: Array> = map([1, 2, 3, 4, export const PromQueryBuilderOptions = React.memo( ({ query, app, onChange, onRunQuery }) => { + const FORMAT_OPTIONS: Array> = [ + { + label: t( + 'grafana-prometheus.querybuilder.prom-query-builder-options.format-options.label-time-series', + 'Time series' + ), + value: 'time_series', + }, + { + label: t('grafana-prometheus.querybuilder.prom-query-builder-options.format-options.label-table', 'Table'), + value: 'table', + }, + { + label: t('grafana-prometheus.querybuilder.prom-query-builder-options.format-options.label-heatmap', 'Heatmap'), + value: 'heatmap', + }, + ]; + const onChangeFormat = (value: SelectableValue) => { onChange({ ...query, format: value.value }); onRunQuery(); @@ -182,17 +194,25 @@ function getQueryTypeValue(query: PromQuery) { function getCollapsedInfo(query: PromQuery, formatOption: string, queryType: string, app?: CoreApp): string[] { const items: string[] = []; - items.push(`Legend: ${getLegendModeLabel(query.legendFormat)}`); - items.push(`Format: ${formatOption}`); - items.push(`Step: ${query.interval ?? 'auto'}`); - items.push(`Type: ${queryType}`); + items.push( + t('grafana-prometheus.querybuilder.get-collapsed-info.legend', 'Legend: {{value}}', { + value: getLegendModeLabel(query.legendFormat), + }) + ); + items.push( + t('grafana-prometheus.querybuilder.get-collapsed-info.format', 'Format: {{value}}', { value: formatOption }) + ); + items.push( + t('grafana-prometheus.querybuilder.get-collapsed-info.step', 'Step: {{value}}', { value: query.interval ?? 'auto' }) + ); + items.push(t('grafana-prometheus.querybuilder.get-collapsed-info.type', 'Type: {{value}}', { value: queryType })); if (shouldShowExemplarSwitch(query, app)) { - if (query.exemplar) { - items.push(`Exemplars: true`); - } else { - items.push(`Exemplars: false`); - } + items.push( + t('grafana-prometheus.querybuilder.get-collapsed-info.exemplars', 'Exemplars: {{value}}', { + value: query.exemplar ? 'true' : 'false', + }) + ); } return items; } diff --git a/packages/grafana-prometheus/src/querybuilder/components/PromQueryEditorSelector.tsx b/packages/grafana-prometheus/src/querybuilder/components/PromQueryEditorSelector.tsx index 1d500669f5b..adf3afebf28 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/PromQueryEditorSelector.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/PromQueryEditorSelector.tsx @@ -98,8 +98,11 @@ export const PromQueryEditorSelector = memo((props) => { 'grafana-prometheus.querybuilder.prom-query-editor-selector.title-parsing-error-switch-builder', 'Parsing error: Switch to the builder mode?' )} - body="There is a syntax error, or the query structure cannot be visualized when switching to the builder mode. Parts of the query may be lost. " - confirmText="Continue" + body={t( + 'grafana-prometheus.querybuilder.prom-query-editor-selector.body-syntax-error', + 'There is a syntax error, or the query structure cannot be visualized when switching to the builder mode. Parts of the query may be lost.' + )} + confirmText={t('grafana-prometheus.querybuilder.prom-query-editor-selector.confirmText-continue', 'Continue')} onConfirm={() => { changeEditorMode(query, QueryEditorMode.Builder, onChange); setParseModalOpen(false); diff --git a/packages/grafana-prometheus/src/querybuilder/components/PromQueryLegendEditor.tsx b/packages/grafana-prometheus/src/querybuilder/components/PromQueryLegendEditor.tsx index a793b2df79b..da6edf4d2c4 100644 --- a/packages/grafana-prometheus/src/querybuilder/components/PromQueryLegendEditor.tsx +++ b/packages/grafana-prometheus/src/querybuilder/components/PromQueryLegendEditor.tsx @@ -16,14 +16,31 @@ export interface PromQueryLegendEditorProps { onRunQuery: () => void; } -const legendModeOptions = [ +const getLegendModeOptions = () => [ { - label: 'Auto', + label: t('grafana-prometheus.prom-query-legend-editor.get-legend-mode-options.label-auto', 'Auto'), value: LegendFormatMode.Auto, - description: 'Only includes unique labels', + description: t( + 'grafana-prometheus.prom-query-legend-editor.get-legend-mode-options.description-auto', + 'Only includes unique labels' + ), + }, + { + label: t('grafana-prometheus.prom-query-legend-editor.get-legend-mode-options.label-verbose', 'Verbose'), + value: LegendFormatMode.Verbose, + description: t( + 'grafana-prometheus.prom-query-legend-editor.get-legend-mode-options.description-verbose', + 'All label names and values' + ), + }, + { + label: t('grafana-prometheus.prom-query-legend-editor.get-legend-mode-options.label-custom', 'Custom'), + value: LegendFormatMode.Custom, + description: t( + 'grafana-prometheus.prom-query-legend-editor.get-legend-mode-options.description-custom', + 'Provide a naming template' + ), }, - { label: 'Verbose', value: LegendFormatMode.Verbose, description: 'All label names and values' }, - { label: 'Custom', value: LegendFormatMode.Custom, description: 'Provide a naming template' }, ]; /** @@ -33,6 +50,7 @@ export const PromQueryLegendEditor = React.memo( ({ legendFormat, onChange, onRunQuery }) => { const mode = getLegendMode(legendFormat); const inputRef = useRef(null); + const legendModeOptions = getLegendModeOptions(); const onLegendFormatChanged = (evt: React.FormEvent) => { let newFormat = evt.currentTarget.value; @@ -124,6 +142,7 @@ function getLegendMode(legendFormat: string | undefined) { } export function getLegendModeLabel(legendFormat: string | undefined) { + const legendModeOptions = getLegendModeOptions(); const mode = getLegendMode(legendFormat); if (mode !== LegendFormatMode.Custom) { return legendModeOptions.find((x) => x.value === mode)?.label; diff --git a/packages/grafana-prometheus/src/querybuilder/shared/QueryEditorModeToggle.tsx b/packages/grafana-prometheus/src/querybuilder/shared/QueryEditorModeToggle.tsx index 0b0951cac5a..d57c654f13b 100644 --- a/packages/grafana-prometheus/src/querybuilder/shared/QueryEditorModeToggle.tsx +++ b/packages/grafana-prometheus/src/querybuilder/shared/QueryEditorModeToggle.tsx @@ -1,4 +1,5 @@ // Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/querybuilder/shared/QueryEditorModeToggle.tsx +import { t } from '@grafana/i18n'; import { RadioButtonGroup } from '@grafana/ui'; import { QueryEditorMode } from './types'; @@ -8,12 +9,17 @@ export interface Props { onChange: (mode: QueryEditorMode) => void; } -const editorModes = [ - { label: 'Builder', value: QueryEditorMode.Builder }, - { label: 'Code', value: QueryEditorMode.Code }, -]; - export function QueryEditorModeToggle({ mode, onChange }: Props) { + const editorModes = [ + { + label: t('grafana-prometheus.querybuilder.query-editor-mode-toggle.editor-modes.label-builder', 'Builder'), + value: QueryEditorMode.Builder, + }, + { + label: t('grafana-prometheus.querybuilder.query-editor-mode-toggle.editor-modes.label-code', 'Code'), + value: QueryEditorMode.Code, + }, + ]; return (
diff --git a/packages/grafana-sql/src/components/QueryHeader.tsx b/packages/grafana-sql/src/components/QueryHeader.tsx index de27061e390..240b73a3c27 100644 --- a/packages/grafana-sql/src/components/QueryHeader.tsx +++ b/packages/grafana-sql/src/components/QueryHeader.tsx @@ -28,11 +28,6 @@ export interface QueryHeaderProps { queryRowFilter: QueryRowFilter; } -const editorModes = [ - { label: 'Builder', value: EditorMode.Builder }, - { label: 'Code', value: EditorMode.Code }, -]; - export function QueryHeader({ db, dialect, @@ -51,6 +46,14 @@ export function QueryHeader({ const htmlId = useId(); + const editorModes = [ + { + label: t('grafana-sql.components.query-header.editor-modes.label-builder', 'Builder'), + value: EditorMode.Builder, + }, + { label: t('grafana-sql.components.query-header.editor-modes.label-code', 'Code'), value: EditorMode.Code }, + ]; + const onEditorModeChange = useCallback( (newEditorMode: EditorMode) => { if (newEditorMode === EditorMode.Code) { diff --git a/packages/grafana-sql/src/locales/en-US/grafana-sql.json b/packages/grafana-sql/src/locales/en-US/grafana-sql.json index d9cb9d1fa61..bc986568f18 100644 --- a/packages/grafana-sql/src/locales/en-US/grafana-sql.json +++ b/packages/grafana-sql/src/locales/en-US/grafana-sql.json @@ -55,6 +55,10 @@ }, "query-header": { "content-invalid-query": "Your query is invalid. Check below for details. <1>However, you can still run this query.", + "editor-modes": { + "label-builder": "Builder", + "label-code": "Code" + }, "label-dataset": "Dataset", "label-filter": "Filter", "label-format": "Format", diff --git a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx index ceebc2502b5..9122239ea0f 100644 --- a/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx +++ b/packages/grafana-ui/src/components/ConfirmButton/DeleteButton.tsx @@ -1,3 +1,5 @@ +import { t } from '@grafana/i18n'; + import { ComponentSize } from '../../types/size'; import { Button } from '../Button/Button'; @@ -18,7 +20,7 @@ export interface Props { export const DeleteButton = ({ size, disabled, onConfirm, 'aria-label': ariaLabel, closeOnConfirm }: Props) => { return ( { const { onChange, width, autoFocus = false, onBlur, value, disabled = false, inputId } = props; + const weekStarts: ComboboxOption[] = useMemo( + () => [ + { value: '', label: t('grafana-ui.week-start-picker.weekStarts-label-default', 'Default') }, + { value: 'saturday', label: t('grafana-ui.week-start-picker.weekStarts-label-saturday', 'Saturday') }, + { value: 'sunday', label: t('grafana-ui.week-start-picker.weekStarts-label-sunday', 'Sunday') }, + { value: 'monday', label: t('grafana-ui.week-start-picker.weekStarts-label-monday', 'Monday') }, + ], + [] + ); const onChangeWeekStart = useCallback( (selectable: ComboboxOption | null) => { @@ -63,7 +67,7 @@ export const WeekStartPicker = (props: Props) => { [onChange] ); - const selected = useMemo(() => weekStarts.find((item) => item.value === value)?.value ?? '', [value]); + const selected = useMemo(() => weekStarts.find((item) => item.value === value)?.value ?? '', [value, weekStarts]); return (
{loadingState === LoadingState.Loading ? ( - + ) : null}
@@ -362,7 +365,11 @@ export function PanelChrome({ {statusMessage && (
- +
)} @@ -380,7 +387,11 @@ export function PanelChrome({ > {statusMessage && (
- +
)} diff --git a/public/app/core/components/FolderFilter/FolderFilter.tsx b/public/app/core/components/FolderFilter/FolderFilter.tsx index cbd4e574235..b427eed4569 100644 --- a/public/app/core/components/FolderFilter/FolderFilter.tsx +++ b/public/app/core/components/FolderFilter/FolderFilter.tsx @@ -46,7 +46,7 @@ export function FolderFilter({ onChange, maxMenuHeight }: FolderFilterProps): JS loadOptions={debouncedLoadOptions} maxMenuHeight={maxMenuHeight} placeholder={t('folder-filter.select-placeholder', 'Filter by folder')} - noOptionsMessage="No folders found" + noOptionsMessage={t('folder-filter.noOptionsMessage-no-folders-found', 'No folders found')} prefix={} aria-label={t('folder-filter.select-aria-label', 'Folder filter')} defaultOptions diff --git a/public/app/core/components/Select/MetricSelect.tsx b/public/app/core/components/Select/MetricSelect.tsx index 771cf1aa6d2..d1655efb3f9 100644 --- a/public/app/core/components/Select/MetricSelect.tsx +++ b/public/app/core/components/Select/MetricSelect.tsx @@ -2,6 +2,7 @@ import { flatten } from 'lodash'; import { useCallback, useMemo } from 'react'; import { SelectableValue } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { Select } from '@grafana/ui'; import { Variable } from 'app/types/templates'; @@ -32,7 +33,7 @@ export const MetricSelect = (props: Props) => { isSearchable={isSearchable} maxMenuHeight={500} placeholder={placeholder} - noOptionsMessage="No options found" + noOptionsMessage={t('metric-select.noOptionsMessage-no-options-found', 'No options found')} value={selected} /> ); diff --git a/public/app/core/components/Select/OrgPicker.tsx b/public/app/core/components/Select/OrgPicker.tsx index af7759901b5..bc064c83d98 100644 --- a/public/app/core/components/Select/OrgPicker.tsx +++ b/public/app/core/components/Select/OrgPicker.tsx @@ -67,7 +67,7 @@ export function OrgPicker({ onSelected, className, inputId, autoFocus, excludeOr }} value={selected} placeholder={t('org-picker.select-placeholder', 'Select organization')} - noOptionsMessage="No organizations found" + noOptionsMessage={t('org-picker.noOptionsMessage-no-organizations-found', 'No organizations found')} /> ); } diff --git a/public/app/core/components/Select/ServiceAccountPicker.tsx b/public/app/core/components/Select/ServiceAccountPicker.tsx index 09f045c544f..b86a451dea1 100644 --- a/public/app/core/components/Select/ServiceAccountPicker.tsx +++ b/public/app/core/components/Select/ServiceAccountPicker.tsx @@ -67,7 +67,10 @@ export class ServiceAccountPicker extends Component { loadOptions={this.search} onChange={onSelected} placeholder={t('service-account-picker.select-placeholder', 'Start typing to search for service accounts')} - noOptionsMessage="No service accounts found" + noOptionsMessage={t( + 'service-account-picker.noOptionsMessage-no-service-accounts-found', + 'No service accounts found' + )} aria-label={t('service-account-picker.select-aria-label', 'Service account picker')} />
diff --git a/public/app/core/components/Select/TeamPicker.tsx b/public/app/core/components/Select/TeamPicker.tsx index d189e46877c..b3608b80105 100644 --- a/public/app/core/components/Select/TeamPicker.tsx +++ b/public/app/core/components/Select/TeamPicker.tsx @@ -84,7 +84,7 @@ export class TeamPicker extends Component { onChange={onSelected} className={className} placeholder={t('team-picker.select-placeholder', 'Select a team')} - noOptionsMessage="No teams found" + noOptionsMessage={t('team-picker.noOptionsMessage-no-teams-found', 'No teams found')} aria-label={t('team-picker.select-aria-label', 'Team picker')} /> diff --git a/public/app/core/components/Select/UserPicker.tsx b/public/app/core/components/Select/UserPicker.tsx index 91158b6901f..0b1b5cb129f 100644 --- a/public/app/core/components/Select/UserPicker.tsx +++ b/public/app/core/components/Select/UserPicker.tsx @@ -67,7 +67,7 @@ export class UserPicker extends Component { loadOptions={this.search} onChange={onSelected} placeholder={t('user-picker.select-placeholder', 'Start typing to search for user')} - noOptionsMessage="No users found" + noOptionsMessage={t('user-picker.noOptionsMessage-no-users-found', 'No users found')} aria-label={t('user-picker.select-aria-label', 'User picker')} /> diff --git a/public/app/features/admin/AdminFeatureTogglesTable.tsx b/public/app/features/admin/AdminFeatureTogglesTable.tsx index 3f97bb526c3..65b6112652c 100644 --- a/public/app/features/admin/AdminFeatureTogglesTable.tsx +++ b/public/app/features/admin/AdminFeatureTogglesTable.tsx @@ -186,7 +186,7 @@ export function AdminFeatureTogglesTable({ featureToggles, allowEditing, onUpdat

} - confirmText="Save changes" + confirmText={t('admin.admin-feature-toggles-table.confirmText-save-changes', 'Save changes')} onConfirm={async () => { showSaveChangesModal(false)(); handleSaveChanges(); diff --git a/public/app/features/admin/AdminOrgsTable.tsx b/public/app/features/admin/AdminOrgsTable.tsx index e11fde93557..9feba68ae31 100644 --- a/public/app/features/admin/AdminOrgsTable.tsx +++ b/public/app/features/admin/AdminOrgsTable.tsx @@ -72,7 +72,7 @@ function AdminOrgsTableComponent({ orgs, onDelete }: Props) { } - confirmText="Delete" + confirmText={t('admin.admin-orgs-table.confirmText-delete', 'Delete')} onDismiss={() => setDeleteOrg(undefined)} onConfirm={() => { onDelete(deleteOrg.id); diff --git a/public/app/features/admin/UserOrgs.tsx b/public/app/features/admin/UserOrgs.tsx index f17cb6290d9..6aac4d1721c 100644 --- a/public/app/features/admin/UserOrgs.tsx +++ b/public/app/features/admin/UserOrgs.tsx @@ -240,7 +240,7 @@ class UnThemedOrgRow extends PureComponent { {canRemoveFromOrg && ( ) : ( {t('admin.user-permissions.change-button', 'Change')} diff --git a/public/app/features/admin/UserProfile.tsx b/public/app/features/admin/UserProfile.tsx index bed64e97a3e..9b9522a084a 100644 --- a/public/app/features/admin/UserProfile.tsx +++ b/public/app/features/admin/UserProfile.tsx @@ -142,8 +142,8 @@ export function UserProfile({ @@ -162,8 +162,8 @@ export function UserProfile({ @@ -290,7 +290,7 @@ export class UserProfileRow extends PureComponent { {canLogout && ( @@ -115,8 +115,11 @@ class BaseUserSessions extends PureComponent { diff --git a/public/app/features/admin/Users/OrgUsersTable.tsx b/public/app/features/admin/Users/OrgUsersTable.tsx index 9e2ba45de63..d83485531db 100644 --- a/public/app/features/admin/Users/OrgUsersTable.tsx +++ b/public/app/features/admin/Users/OrgUsersTable.tsx @@ -261,8 +261,10 @@ export const OrgUsersTable = ({ {Boolean(userToRemove) && ( { setUserToRemove(null); diff --git a/public/app/features/alerting/unified/components/AlertManagerPicker.tsx b/public/app/features/alerting/unified/components/AlertManagerPicker.tsx index 90cbb059d9f..5a2a7ddc83e 100644 --- a/public/app/features/alerting/unified/components/AlertManagerPicker.tsx +++ b/public/app/features/alerting/unified/components/AlertManagerPicker.tsx @@ -2,6 +2,7 @@ import { css } from '@emotion/css'; import { ComponentProps, useMemo } from 'react'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { InlineField, Select, SelectMenuOptions, useStyles2 } from '@grafana/ui'; import { useAlertmanager } from '../state/AlertmanagerContext'; @@ -44,7 +45,10 @@ export const AlertManagerPicker = ({ disabled = false }: Props) => { } }} options={options} - noOptionsMessage="No datasources found" + noOptionsMessage={t( + 'alerting.alert-manager-picker.noOptionsMessage-no-datasources-found', + 'No datasources found' + )} value={selectedAlertmanager} getOptionLabel={(o) => o.label} components={{ Option: CustomOption }} diff --git a/public/app/features/alerting/unified/components/contact-points/ContactPointHeader.tsx b/public/app/features/alerting/unified/components/contact-points/ContactPointHeader.tsx index 57a7a4f48a6..40a7afeddeb 100644 --- a/public/app/features/alerting/unified/components/contact-points/ContactPointHeader.tsx +++ b/public/app/features/alerting/unified/components/contact-points/ContactPointHeader.tsx @@ -100,7 +100,7 @@ export const ContactPointHeader = ({ contactPoint, onDelete }: ContactPointHeade openExportDrawer(name)} @@ -159,7 +159,7 @@ export const ContactPointHeader = ({ contactPoint, onDelete }: ContactPointHeade > { await deleteMuteTiming.execute({ diff --git a/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx b/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx index 963ee48e6e0..ea00e22b280 100644 --- a/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx +++ b/public/app/features/alerting/unified/components/receivers/TemplatesTable.tsx @@ -102,8 +102,12 @@ export const TemplatesTable = ({ alertManagerName, templates }: Props) => { setTemplateToDelete(undefined)} /> diff --git a/public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.tsx b/public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.tsx index e77a425b6d5..de3cd0e3503 100644 --- a/public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.tsx +++ b/public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.tsx @@ -142,7 +142,10 @@ function TemplateSelector({ onSelect, onClose, option, valueInForm }: TemplateSe 'alerting.template-selector.template-options.label.select-notification-template', 'Select notification template' ), - ariaLabel: 'Select notification template', + ariaLabel: t( + 'alerting.template-selector.template-options.ariaLabel.select-notification-template', + 'Select notification template' + ), value: 'Existing', description: `Select an existing notification template and preview it, or copy it to paste it in the custom tab. ${templateOption === 'Existing' ? 'Clicking Save saves your changes to the selected template.' : ''}`, }, diff --git a/public/app/features/alerting/unified/components/rule-editor/GrafanaEvaluationBehavior.tsx b/public/app/features/alerting/unified/components/rule-editor/GrafanaEvaluationBehavior.tsx index 38dda76f142..50163827bdb 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GrafanaEvaluationBehavior.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GrafanaEvaluationBehavior.tsx @@ -213,7 +213,10 @@ export function GrafanaEvaluationBehaviorStep({ isLoading={loadingGroups} invalid={Boolean(folder?.uid) && !group && Boolean(fieldState.error)} cacheOptions - loadingMessage={'Loading groups...'} + loadingMessage={t( + 'alerting.grafana-evaluation-behavior-step.loadingMessage-loading-groups', + 'Loading groups...' + )} defaultValue={defaultGroupValue} options={groupOptions} getOptionLabel={(option: SelectableValue) => ( diff --git a/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx b/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx index 8f60198e042..43579acbcc7 100644 --- a/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx @@ -718,7 +718,7 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange, mod
} - confirmText="Deactivate" + confirmText={t('alerting.query-and-expressions-step.confirmText-deactivate', 'Deactivate')} icon="exclamation-triangle" onConfirm={() => { setValue('editorSettings.simplifiedQueryEditor', true); diff --git a/public/app/features/alerting/unified/components/rule-viewer/DeleteModal.tsx b/public/app/features/alerting/unified/components/rule-viewer/DeleteModal.tsx index e6b3f93bde4..a26a9709d38 100644 --- a/public/app/features/alerting/unified/components/rule-viewer/DeleteModal.tsx +++ b/public/app/features/alerting/unified/components/rule-viewer/DeleteModal.tsx @@ -82,7 +82,7 @@ export const useDeleteModal = (redirectToListView = false): DeleteModalHook => { 'Deleting this rule will permanently remove it from your alert rule list. Are you sure you want to delete this rule?' ) } - confirmText="Yes, delete" + confirmText={t('alerting.use-delete-modal.modal.confirmText-yes-delete', 'Yes, delete')} icon="exclamation-triangle" onConfirm={deleteRule} onDismiss={dismissModal} diff --git a/public/app/features/alerting/unified/components/rules/CloneRule.tsx b/public/app/features/alerting/unified/components/rules/CloneRule.tsx index 175612dde1b..a5be76cf102 100644 --- a/public/app/features/alerting/unified/components/rules/CloneRule.tsx +++ b/public/app/features/alerting/unified/components/rules/CloneRule.tsx @@ -56,7 +56,7 @@ export function RedirectToCloneRule({

} - confirmText="Copy" + confirmText={t('alerting.redirect-to-clone-rule.confirmText-copy', 'Copy')} onConfirm={() => setStage('redirect')} onDismiss={onDismiss} /> diff --git a/public/app/features/alerting/unified/components/rules/MultipleDataSourcePicker.tsx b/public/app/features/alerting/unified/components/rules/MultipleDataSourcePicker.tsx index a12cc9aae21..2d30594b2e2 100644 --- a/public/app/features/alerting/unified/components/rules/MultipleDataSourcePicker.tsx +++ b/public/app/features/alerting/unified/components/rules/MultipleDataSourcePicker.tsx @@ -177,7 +177,10 @@ export const MultipleDataSourcePicker = (props: MultipleDataSourcePickerProps) = openMenuOnFocus={openMenuOnFocus} maxMenuHeight={500} placeholder={placeholder} - noOptionsMessage="No datasources found" + noOptionsMessage={t( + 'alerting.multiple-data-source-picker.noOptionsMessage-no-datasources-found', + 'No datasources found' + )} value={value ?? []} invalid={Boolean(state?.error) || Boolean(props.invalid)} getOptionLabel={(o) => { diff --git a/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx b/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx index b70c903024f..c42566d7610 100644 --- a/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx +++ b/public/app/features/alerting/unified/components/settings/AlertmanagerConfig.tsx @@ -209,7 +209,7 @@ export default function AlertmanagerConfig({ alertmanagerName, onDismiss, onSave 'Reset Alertmanager configuration' )} body={confirmationText} - confirmText="Yes, reset configuration" + confirmText={t('alerting.alertmanager-config.confirmText-yes-reset-configuration', 'Yes, reset configuration')} onConfirm={() => { onReset(alertmanagerName); setShowResetConfirmation(false); diff --git a/public/app/features/alerting/unified/components/settings/VersionManager.tsx b/public/app/features/alerting/unified/components/settings/VersionManager.tsx index 981af90cee4..10b09a4809d 100644 --- a/public/app/features/alerting/unified/components/settings/VersionManager.tsx +++ b/public/app/features/alerting/unified/components/settings/VersionManager.tsx @@ -242,8 +242,14 @@ const AlertmanagerConfigurationVersionManager = ({ { if (activeRestoreVersion) { restoreVersion(activeRestoreVersion); diff --git a/public/app/features/annotations/components/AnnotationResultMapper.tsx b/public/app/features/annotations/components/AnnotationResultMapper.tsx index a78711d465a..475659c7620 100644 --- a/public/app/features/annotations/components/AnnotationResultMapper.tsx +++ b/public/app/features/annotations/components/AnnotationResultMapper.tsx @@ -10,7 +10,7 @@ import { AnnotationEventFieldSource, getValueFormat, } from '@grafana/data'; -import { Trans } from '@grafana/i18n'; +import { Trans, t } from '@grafana/i18n'; import { Select, Tooltip, Icon } from '@grafana/ui'; import { annotationEventNames, AnnotationFieldInfo } from '../standardAnnotationSupport'; @@ -171,7 +171,10 @@ export class AnnotationFieldMapper extends PureComponent { onChange={(v: SelectableValue) => { this.onFieldNameChange(row.key, v); }} - noOptionsMessage="Unknown field names" + noOptionsMessage={t( + 'annotations.annotation-field-mapper.noOptionsMessage-unknown-field-names', + 'Unknown field names' + )} allowCustomValue={true} isClearable /> diff --git a/public/app/features/auth-config/ProviderConfigForm.tsx b/public/app/features/auth-config/ProviderConfigForm.tsx index 8f1e3f80b91..861fe6acde9 100644 --- a/public/app/features/auth-config/ProviderConfigForm.tsx +++ b/public/app/features/auth-config/ProviderConfigForm.tsx @@ -263,7 +263,7 @@ export const ProviderConfigForm = ({ config, provider, isLoading }: ProviderConf } - confirmText="Reset" + confirmText={t('auth-config.provider-config-form.confirmText-reset', 'Reset')} onDismiss={() => setResetConfig(false)} onConfirm={async () => { await onResetConfig(); diff --git a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataTransformationsTab.tsx b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataTransformationsTab.tsx index e186910de28..27f434da0a9 100644 --- a/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataTransformationsTab.tsx +++ b/public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataTransformationsTab.tsx @@ -135,8 +135,11 @@ export function PanelDataTransformationsTabRendered({ model }: SceneComponentPro 'dashboard-scene.panel-data-transformations-tab-rendered.title-delete-all-transformations', 'Delete all transformations?' )} - body="By deleting all transformations, you will go back to the main selection screen." - confirmText="Delete all" + body={t( + 'dashboard-scene.panel-data-transformations-tab-rendered.body-delete-all-transformations', + 'By deleting all transformations, you will go back to the main selection screen.' + )} + confirmText={t('dashboard-scene.panel-data-transformations-tab-rendered.confirmText-delete-all', 'Delete all')} onConfirm={() => { model.onChangeTransformations([]); setConfirmModalOpen(false); diff --git a/public/app/features/dashboard-scene/saving/useSaveDashboard.ts b/public/app/features/dashboard-scene/saving/useSaveDashboard.ts index 8977abc2365..97a50aa3621 100644 --- a/public/app/features/dashboard-scene/saving/useSaveDashboard.ts +++ b/public/app/features/dashboard-scene/saving/useSaveDashboard.ts @@ -1,6 +1,7 @@ import { useAsyncFn } from 'react-use'; import { locationUtil } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { locationService, reportInteraction } from '@grafana/runtime'; import { Dashboard } from '@grafana/schema'; import { Spec as DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2alpha1/types.spec.gen'; @@ -59,7 +60,7 @@ export function useSaveDashboard(isCopy = false) { // important that these happen before location redirect below appEvents.publish(new DashboardSavedEvent()); - notifyApp.success('Dashboard saved'); + notifyApp.success(t('dashboard-scene.use-save-dashboard.message-dashboard-saved', 'Dashboard saved')); //Update local storage dashboard to handle things like last used datasource updateDashboardUidLastUsedDatasource(resultData.uid); diff --git a/public/app/features/dashboard-scene/scene/GoToSnapshotOriginButton.tsx b/public/app/features/dashboard-scene/scene/GoToSnapshotOriginButton.tsx index 735c81c8401..b384ecacbbf 100644 --- a/public/app/features/dashboard-scene/scene/GoToSnapshotOriginButton.tsx +++ b/public/app/features/dashboard-scene/scene/GoToSnapshotOriginButton.tsx @@ -48,7 +48,7 @@ const onOpenSnapshotOriginalDashboard = (originalUrl: string) => { ), confirmVariant: 'primary', - confirmText: 'Proceed', + confirmText: t('dashboard-scene.on-open-snapshot-original-dashboard.confirmText.proceed', 'Proceed'), onConfirm: () => { window.location.href = sanitizedAppUrl.href; }, diff --git a/public/app/features/dashboard-scene/scene/UnlinkModal.tsx b/public/app/features/dashboard-scene/scene/UnlinkModal.tsx index d092436c6d5..51dbd4b045d 100644 --- a/public/app/features/dashboard-scene/scene/UnlinkModal.tsx +++ b/public/app/features/dashboard-scene/scene/UnlinkModal.tsx @@ -12,9 +12,11 @@ export const UnlinkModal = ({ isOpen, onConfirm, onDismiss }: Props) => { { onConfirm(); onDismiss(); diff --git a/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx b/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx index ed7c74ee3e0..228240f721b 100644 --- a/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx +++ b/public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx @@ -35,17 +35,6 @@ import { DashboardEditView, DashboardEditViewState, useDashboardEditPageNav } fr export interface GeneralSettingsEditViewState extends DashboardEditViewState {} -const EDITABLE_OPTIONS = [ - { label: 'Editable', value: true }, - { label: 'Read-only', value: false }, -]; - -const GRAPH_TOOLTIP_OPTIONS = [ - { value: 0, label: 'Default' }, - { value: 1, label: 'Shared crosshair' }, - { value: 2, label: 'Shared Tooltip' }, -]; - export class GeneralSettingsEditView extends SceneObjectBase implements DashboardEditView @@ -176,6 +165,37 @@ export class GeneralSettingsEditView const { intervals } = model.getRefreshPicker().useState(); const { hideTimeControls } = model.getDashboardControls().useState(); const { enabled: liveNow } = model.getLiveNowTimer().useState(); + const EDITABLE_OPTIONS = [ + { + label: t('dashboard-scene.general-settings-edit-view.editable_options.label.editable', 'Editable'), + value: true, + }, + { + label: t('dashboard-scene.general-settings-edit-view.editable_options.label.readonly', 'Read-only'), + value: false, + }, + ]; + + const GRAPH_TOOLTIP_OPTIONS = [ + { + value: 0, + label: t('dashboard-scene.general-settings-edit-view.graph_tooltip_options.label.default', 'Default'), + }, + { + value: 1, + label: t( + 'dashboard-scene.general-settings-edit-view.graph_tooltip_options.label.shared-crosshair', + 'Shared crosshair' + ), + }, + { + value: 2, + label: t( + 'dashboard-scene.general-settings-edit-view.graph_tooltip_options.label.shared-tooltip', + 'Shared tooltip' + ), + }, + ]; return ( diff --git a/public/app/features/dashboard-scene/settings/links/DashboardLinkForm.tsx b/public/app/features/dashboard-scene/settings/links/DashboardLinkForm.tsx index fd784a09c8f..f82a9e78e61 100644 --- a/public/app/features/dashboard-scene/settings/links/DashboardLinkForm.tsx +++ b/public/app/features/dashboard-scene/settings/links/DashboardLinkForm.tsx @@ -7,11 +7,6 @@ import { CollapsableSection, TagsInput, Select, Field, Input, Checkbox, Button } import { LINK_ICON_MAP, NEW_LINK } from './utils'; -const linkTypeOptions = [ - { value: 'dashboards', label: 'Dashboards' }, - { value: 'link', label: 'Link' }, -]; - const linkIconOptions = Object.keys(LINK_ICON_MAP).map((key) => ({ label: key, value: key })); interface DashboardLinkFormProps { @@ -21,6 +16,13 @@ interface DashboardLinkFormProps { } export function DashboardLinkForm({ link, onUpdate, onGoBack }: DashboardLinkFormProps) { + const linkTypeOptions = [ + { + value: 'dashboards', + label: t('dashboard-scene.dashboard-link-form.link-type-options.label.dashboards', 'Dashboards'), + }, + { value: 'link', label: t('dashboard-scene.dashboard-link-form.link-type-options.label.link', 'Link') }, + ]; const onTagsChange = (tags: string[]) => { onUpdate({ ...link, tags: tags }); }; diff --git a/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx b/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx index a783a201324..a261cd00852 100644 --- a/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx +++ b/public/app/features/dashboard-scene/settings/variables/VariableEditorForm.tsx @@ -85,7 +85,7 @@ export function VariableEditorForm({ variable, onTypeChange, onGoBack, onDelete General ) : ( - `Run query` + t('dashbaord-scene.variable-editor-form.run-query', 'Run query') )} )} diff --git a/public/app/features/dashboard-scene/settings/variables/VariableEditorListRow.tsx b/public/app/features/dashboard-scene/settings/variables/VariableEditorListRow.tsx index 56a1ef550ea..1340fe923c0 100644 --- a/public/app/features/dashboard-scene/settings/variables/VariableEditorListRow.tsx +++ b/public/app/features/dashboard-scene/settings/variables/VariableEditorListRow.tsx @@ -122,8 +122,15 @@ export function VariableEditorListRow({ diff --git a/public/app/features/dashboard-scene/settings/variables/components/AdHocVariableForm.tsx b/public/app/features/dashboard-scene/settings/variables/components/AdHocVariableForm.tsx index 2d2beb67ff4..fcdf7881fce 100644 --- a/public/app/features/dashboard-scene/settings/variables/components/AdHocVariableForm.tsx +++ b/public/app/features/dashboard-scene/settings/variables/components/AdHocVariableForm.tsx @@ -119,7 +119,7 @@ export function AdHocVariableForm({ {datasourceSupported && onAllowCustomValueChange && ( Data source options diff --git a/public/app/features/dashboard-scene/settings/variables/components/SelectionOptionsForm.tsx b/public/app/features/dashboard-scene/settings/variables/components/SelectionOptionsForm.tsx index 56858da935e..7043e029d1b 100644 --- a/public/app/features/dashboard-scene/settings/variables/components/SelectionOptionsForm.tsx +++ b/public/app/features/dashboard-scene/settings/variables/components/SelectionOptionsForm.tsx @@ -31,7 +31,7 @@ export function SelectionOptionsForm({ )} diff --git a/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx index 57158f8820a..d5dd3579124 100644 --- a/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx +++ b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx @@ -25,7 +25,7 @@ export function TextBoxVariableForm({ defaultValue, value, onChange, onBlur, inl ) { - const value = useMemo(() => HIDE_OPTIONS.find((o) => o.value === hide)?.value ?? HIDE_OPTIONS[0].value, [hide]); + const HIDE_OPTIONS = useMemo( + () => [ + { + label: t('dashboard-scene.variable-hide-select.hide_options.label.nothing', 'Nothing'), + value: VariableHide.dontHide, + }, + { + label: t('dashboard-scene.variable-hide-select.hide_options.label.variable', 'Variable'), + value: VariableHide.hideVariable, + }, + { + label: t('dashboard-scene.variable-hide-select.hide_options.label.label', 'Label'), + value: VariableHide.hideLabel, + }, + ], + [] + ); + const value = useMemo( + () => HIDE_OPTIONS.find((o) => o.value === hide)?.value ?? HIDE_OPTIONS[0].value, + [hide, HIDE_OPTIONS] + ); if (type === 'constant') { return null; diff --git a/public/app/features/dashboard-scene/settings/variables/components/VariableTypeSelect.tsx b/public/app/features/dashboard-scene/settings/variables/components/VariableTypeSelect.tsx index 69a111f1cf2..3408469a6e2 100644 --- a/public/app/features/dashboard-scene/settings/variables/components/VariableTypeSelect.tsx +++ b/public/app/features/dashboard-scene/settings/variables/components/VariableTypeSelect.tsx @@ -2,6 +2,7 @@ import { PropsWithChildren, useMemo } from 'react'; import { SelectableValue, VariableType } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { t } from '@grafana/i18n'; import { VariableSelectField } from 'app/features/dashboard-scene/settings/variables/components/VariableSelectField'; import { EditableVariableType, getVariableTypeSelectOptions } from '../utils'; @@ -20,7 +21,7 @@ export function VariableTypeSelect({ onChange, type }: PropsWithChildren) return ( diff --git a/public/app/features/dashboard-scene/settings/version-history/RevertDashboardModal.tsx b/public/app/features/dashboard-scene/settings/version-history/RevertDashboardModal.tsx index ac45683edbc..535f191c393 100644 --- a/public/app/features/dashboard-scene/settings/version-history/RevertDashboardModal.tsx +++ b/public/app/features/dashboard-scene/settings/version-history/RevertDashboardModal.tsx @@ -44,7 +44,11 @@ export const RevertDashboardModal = ({ hideModal, onRestore, version }: RevertDa

} - confirmText={`Yes, restore to version ${version.version}`} + confirmText={t( + 'dashboard-scene.revert-dashboard-modal.confirmText-restore-version', + 'Yes, restore to version {{version}}', + { version: version.version } + )} /> ); }; diff --git a/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx b/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx index ba750d48f7d..f95912f333d 100644 --- a/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx +++ b/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx @@ -65,7 +65,7 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck, onRestore } {version.message} {idx === 0 ? ( - + ) : ( {({ showModal, hideModal }) => ( diff --git a/public/app/features/dashboard-scene/sharing/public-dashboards/ConfigPublicDashboard.tsx b/public/app/features/dashboard-scene/sharing/public-dashboards/ConfigPublicDashboard.tsx index 1c2ab358818..303492f492f 100644 --- a/public/app/features/dashboard-scene/sharing/public-dashboards/ConfigPublicDashboard.tsx +++ b/public/app/features/dashboard-scene/sharing/public-dashboards/ConfigPublicDashboard.tsx @@ -47,7 +47,10 @@ export function ConfigPublicDashboard({ model, publicDashboard, isGetLoading }: isOpen: true, title: t('dashboard-scene.config-public-dashboard.title.revoke-public-url', 'Revoke public URL'), icon: 'trash-alt', - confirmText: 'Revoke public URL', + confirmText: t( + 'dashboard-scene.config-public-dashboard.confirmText.revoke-public-url', + 'Revoke public URL' + ), body: (

diff --git a/public/app/features/dashboard/components/DashNav/DashNav.tsx b/public/app/features/dashboard/components/DashNav/DashNav.tsx index c7aef4cb7ac..b4a6e81d6cd 100644 --- a/public/app/features/dashboard/components/DashNav/DashNav.tsx +++ b/public/app/features/dashboard/components/DashNav/DashNav.tsx @@ -117,7 +117,7 @@ export const DashNav = memo((props) => { ), confirmVariant: 'primary', - confirmText: 'Proceed', + confirmText: t('dashboard.dash-nav.on-open-snapshot-original.confirmText.proceed', 'Proceed'), onConfirm: gotoSnapshotOrigin, }, }) diff --git a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx index 317b5734635..d7b32cfabb2 100644 --- a/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/GeneralSettings.tsx @@ -29,12 +29,6 @@ import { SettingsPageProps } from './types'; export type Props = SettingsPageProps & ConnectedProps; -const GRAPH_TOOLTIP_OPTIONS = [ - { value: 0, label: 'Default' }, - { value: 1, label: 'Shared crosshair' }, - { value: 2, label: 'Shared Tooltip' }, -]; - export function GeneralSettingsUnconnected({ dashboard, updateTimeZone, @@ -44,6 +38,20 @@ export function GeneralSettingsUnconnected({ const [renderCounter, setRenderCounter] = useState(0); const [dashboardTitle, setDashboardTitle] = useState(dashboard.title); const [dashboardDescription, setDashboardDescription] = useState(dashboard.description); + const GRAPH_TOOLTIP_OPTIONS = [ + { value: 0, label: t('dashboard.general-settings-unconnected.graph_tooltip_options.label.default', 'Default') }, + { + value: 1, + label: t( + 'dashboard.general-settings-unconnected.graph_tooltip_options.label.shared-crosshair', + 'Shared crosshair' + ), + }, + { + value: 2, + label: t('dashboard.general-settings-unconnected.graph_tooltip_options.label.shared-tooltip', 'Shared tooltip'), + }, + ]; const pageNav = sectionNav.node.parentItem; diff --git a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx index 72df57aeb96..ddf13763d79 100644 --- a/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx @@ -49,7 +49,7 @@ export const SaveDashboardErrorProxy = ({ } - confirmText="Save and overwrite" + confirmText={t('dashboard.save-dashboard-error-proxy.confirmText-save-and-overwrite', 'Save and overwrite')} onConfirm={async () => { await onDashboardSave(dashboardSaveModel, { overwrite: true }, dashboard); onDismiss(); @@ -90,7 +90,10 @@ export const SaveDashboardErrorProxy = ({ } - confirmText="Save and overwrite" + confirmText={t( + 'dashboard.save-dashboard-error-proxy.confirmText-save-and-overwrite', + 'Save and overwrite' + )} onConfirm={async () => { await onDashboardSave(dashboardSaveModel, { overwrite: true }, dashboard); onDismiss(); diff --git a/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx b/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx index bf03c12b87b..18435bc1e31 100644 --- a/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx +++ b/public/app/features/dashboard/components/SaveDashboard/useDashboardSave.tsx @@ -2,6 +2,7 @@ import { cloneDeep } from 'lodash'; import { useAsyncFn } from 'react-use'; import { locationUtil } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { locationService, reportInteraction } from '@grafana/runtime'; import { Dashboard } from '@grafana/schema'; import appEvents from 'app/core/app_events'; @@ -54,7 +55,7 @@ export const useDashboardSave = (isCopy = false) => { // important that these happen before location redirect below appEvents.publish(new DashboardSavedEvent()); - notifyApp.success('Dashboard saved'); + notifyApp.success(t('dashboard.save-dashboard.message-dashboard-saved', 'Dashboard saved')); //Update local storage dashboard to handle things like last used datasource updateDashboardUidLastUsedDatasource(result.uid); diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx index 70910408020..b77e0f41620 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx @@ -197,8 +197,11 @@ export const TransformationOperationRow = ({ title={t('dashboard.transformation-operation-row.title-delete', 'Delete {{name}}?', { name: uiConfig.name, })} - body="Note that removing one transformation may break others. If there is only a single transformation, you will go back to the main selection screen." - confirmText="Delete" + body={t( + 'dashboard.transformation-operation-row.body-delete', + 'Note that removing one transformation may break others. If there is only a single transformation, you will go back to the main selection screen.' + )} + confirmText={t('dashboard.transformation-operation-row.render-actions.confirmText-delete', 'Delete')} onConfirm={() => { setShowDeleteModal(false); onRemove(index); diff --git a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx index f3cd3798045..17d18efba74 100644 --- a/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx +++ b/public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx @@ -397,8 +397,11 @@ class UnThemedTransformationsEditor extends React.PureComponent this.onTransformationRemoveAll()} onDismiss={() => this.setState({ showRemoveAllModal: false })} /> diff --git a/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx b/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx index 61ee6af4cf6..9650d46f822 100644 --- a/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx +++ b/public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx @@ -34,7 +34,11 @@ export const RevertDashboardModal = ({ hideModal, id, version }: RevertDashboard

} - confirmText={`Yes, restore to version ${version}`} + confirmText={t( + 'dashboard.revert-dashboard-modal.confirmText-restore-version', + 'Yes, restore to version {{version}}', + { version } + )} /> ); }; diff --git a/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx b/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx index 7c25150f7b8..59c74d1d308 100644 --- a/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx +++ b/public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx @@ -63,7 +63,7 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck }: VersionsT {version.message} {idx === 0 ? ( - + ) : ( {({ showModal, hideModal }) => ( diff --git a/public/app/features/dimensions/editors/ColorDimensionEditor.tsx b/public/app/features/dimensions/editors/ColorDimensionEditor.tsx index 70f750c3cf3..a8c7d5af8c5 100644 --- a/public/app/features/dimensions/editors/ColorDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ColorDimensionEditor.tsx @@ -74,7 +74,7 @@ export const ColorDimensionEditor = (props: StandardEditorProps diff --git a/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx b/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx index 89b8f319c8e..a88c7334571 100644 --- a/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ScalarDimensionEditor.tsx @@ -107,7 +107,7 @@ export const ScalarDimensionEditor = ({ value, context, onChange, item }: Props) value={selectedOption} options={selectOptions} onChange={onSelectChange} - noOptionsMessage="No fields found" + noOptionsMessage={t('dimensions.scalar-dimension-editor.noOptionsMessage-no-fields-found', 'No fields found')} />
diff --git a/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx b/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx index 098ac6e038b..d5eb712d47d 100644 --- a/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx +++ b/public/app/features/dimensions/editors/ScaleDimensionEditor.tsx @@ -104,7 +104,7 @@ export const ScaleDimensionEditor = (props: StandardEditorProps
diff --git a/public/app/features/explore/TraceView/components/TracePageHeader/Actions/TracePageActions.tsx b/public/app/features/explore/TraceView/components/TracePageHeader/Actions/TracePageActions.tsx index 48b0b0f8f69..e1448a77f69 100644 --- a/public/app/features/explore/TraceView/components/TracePageHeader/Actions/TracePageActions.tsx +++ b/public/app/features/explore/TraceView/components/TracePageHeader/Actions/TracePageActions.tsx @@ -88,7 +88,7 @@ export default function TracePageActions(props: TracePageActionsProps) { diff --git a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx index 9110b547f6e..0708a574c17 100644 --- a/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx +++ b/public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx @@ -211,7 +211,7 @@ export const SpanFilters = memo((props: SpanFilterProps) => { />
setSpanFiltersSearch({ ...search, from: val })} isInvalidError="Invalid duration" // eslint-disable-next-line @grafana/i18n/no-untranslated-strings @@ -228,7 +228,7 @@ export const SpanFilters = memo((props: SpanFilterProps) => { value={search.toOperator} /> setSpanFiltersSearch({ ...search, to: val })} isInvalidError="Invalid duration" // eslint-disable-next-line @grafana/i18n/no-untranslated-strings diff --git a/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx b/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx index 3e48d672a3f..c90a9fb2128 100644 --- a/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/ChangeLibraryPanelModal/ChangeLibraryPanelModal.tsx @@ -1,3 +1,4 @@ +import { t } from '@grafana/i18n'; import { ConfirmModal } from '@grafana/ui'; import { PanelModel } from '../../../dashboard/state/PanelModel'; @@ -19,7 +20,11 @@ export const ChangeLibraryPanelModal = ({ onConfirm, onDismiss, panel }: ChangeL { isOpen={!!removeSnapshot} icon="trash-alt" title={t('manage-dashboards.snapshot-list-table.title-delete', 'Delete')} - body={`Are you sure you want to delete '${removeSnapshot?.name}'?`} - confirmText="Delete" + body={t( + 'manage-dashboards.snapshot-list-table.body-delete', + "Are you sure you want to delete '{{snapshotToRemove}}'?", + { snapshotToRemove: removeSnapshot?.name } + )} + confirmText={t('manage-dashboards.snapshot-list-table.confirmText-delete', 'Delete')} onDismiss={() => setRemoveSnapshot(undefined)} onConfirm={() => { doRemoveSnapshot(removeSnapshot!); diff --git a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx index 288eba13443..b4774e0dadd 100644 --- a/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx +++ b/public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx @@ -139,8 +139,11 @@ export function InstallControlsButton({ title={t('plugins.install-controls-button.title-uninstall-modal', 'Uninstall {{plugin}}', { plugin: plugin.name, })} - body="Are you sure you want to uninstall this plugin?" - confirmText="Confirm" + body={t( + 'plugins.install-controls-button.uninstall-controls.body-uninstall-plugin', + 'Are you sure you want to uninstall this plugin?' + )} + confirmText={t('plugins.install-controls-button.uninstall-controls.confirmText-confirm', 'Confirm')} icon="exclamation-triangle" onConfirm={onUninstall} onDismiss={hideConfirmModal} diff --git a/public/app/features/plugins/admin/components/VersionInstallButton.tsx b/public/app/features/plugins/admin/components/VersionInstallButton.tsx index 056ce1fa22f..188ecccf65b 100644 --- a/public/app/features/plugins/admin/components/VersionInstallButton.tsx +++ b/public/app/features/plugins/admin/components/VersionInstallButton.tsx @@ -121,7 +121,11 @@ export const VersionInstallButton = ({ @@ -239,8 +245,14 @@ export const ServiceAccountPageUnconnected = ({ 'serviceaccounts.service-account-page-unconnected.title-disable-service-account', 'Disable service account' )} - body="Are you sure you want to disable this service account?" - confirmText="Disable service account" + body={t( + 'serviceaccounts.service-account-page-unconnected.body-disable-service-account', + 'Are you sure you want to disable this service account?' + )} + confirmText={t( + 'serviceaccounts.service-account-page-unconnected.confirmText-disable-service-account', + 'Disable service account' + )} onConfirm={handleServiceAccountDisable} onDismiss={showDisableServiceAccountModal(false)} /> diff --git a/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx b/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx index 6a8292abd9c..ff6218e43e4 100644 --- a/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx +++ b/public/app/features/serviceaccounts/ServiceAccountsListPage.tsx @@ -1,5 +1,4 @@ import { css } from '@emotion/css'; -import pluralize from 'pluralize'; import { useEffect, useState } from 'react'; import { connect, ConnectedProps } from 'react-redux'; @@ -268,15 +267,25 @@ export const ServiceAccountsListPageUnconnected = ({ <> diff --git a/public/app/features/serviceaccounts/components/ServiceAccountProfileRow.tsx b/public/app/features/serviceaccounts/components/ServiceAccountProfileRow.tsx index a855b936e61..428c78175a8 100644 --- a/public/app/features/serviceaccounts/components/ServiceAccountProfileRow.tsx +++ b/public/app/features/serviceaccounts/components/ServiceAccountProfileRow.tsx @@ -85,7 +85,7 @@ export const ServiceAccountProfileRow = ({ label, value, inputType, disabled, on {onChange && ( > = [ - { label: 'Include', value: FilterByValueType.include }, - { label: 'Exclude', value: FilterByValueType.exclude }, -]; - -const filterMatch: Array> = [ - { label: 'Match all', value: FilterByValueMatch.all }, - { label: 'Match any', value: FilterByValueMatch.any }, -]; - export const FilterByValueTransformerEditor = (props: TransformerUIProps) => { const { input, options, onChange } = props; const fieldsInfo = useFieldsInfo(input); + const filterTypes: Array> = [ + { + label: t('transformers.filter-by-value-transformer-editor.filter-types.label.include', 'Include'), + value: FilterByValueType.include, + }, + { + label: t('transformers.filter-by-value-transformer-editor.filter-types.label.exclude', 'Exclude'), + value: FilterByValueType.exclude, + }, + ]; + + const filterMatch: Array> = [ + { + label: t('transformers.filter-by-value-transformer-editor.filter-match.label.match-all', 'Match all'), + value: FilterByValueMatch.all, + }, + { + label: t('transformers.filter-by-value-transformer-editor.filter-match.label.match-any', 'Match any'), + value: FilterByValueMatch.any, + }, + ]; + const onAddFilter = useCallback(() => { const frame = input[0]; const field = frame.fields.find((f) => f.type !== FieldType.time); diff --git a/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx b/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx index 2385bc72fd4..9508dfee1e7 100644 --- a/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx +++ b/public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx @@ -13,7 +13,7 @@ import { getTimeZones, } from '@grafana/data'; import { ConvertFieldTypeOptions, ConvertFieldTypeTransformerOptions } from '@grafana/data/internal'; -import { t } from '@grafana/i18n'; +import { t, Trans } from '@grafana/i18n'; import { Button, InlineField, InlineFieldRow, Input, Select } from '@grafana/ui'; import { allFieldTypeIconOptions, FieldNamePicker } from '@grafana/ui/internal'; import { findField } from 'app/features/dimensions/utils'; @@ -259,7 +259,9 @@ export const ConvertFieldTypeTransformerEditor = ({ 'Add a convert field type transformer' )} > - {'Convert field type'} + + Convert field type + ); diff --git a/public/app/features/transformers/editors/FormatStringTransformerEditor.tsx b/public/app/features/transformers/editors/FormatStringTransformerEditor.tsx index 5bfaaf40d71..4e23322f9ed 100644 --- a/public/app/features/transformers/editors/FormatStringTransformerEditor.tsx +++ b/public/app/features/transformers/editors/FormatStringTransformerEditor.tsx @@ -18,23 +18,29 @@ import { Select, InlineFieldRow, InlineField } from '@grafana/ui'; import { FieldNamePicker } from '@grafana/ui/internal'; import { NumberInput } from 'app/core/components/OptionsUI/NumberInput'; -const fieldNamePickerSettings: StandardEditorsRegistryItem = { - settings: { - width: 30, - filter: (f) => f.type === FieldType.string, - placeholderText: 'Select text field', - noFieldsMessage: 'No text fields found', - }, - name: '', - id: '', - editor: () => null, -}; - function FormatStringTransfomerEditor({ input, options, onChange, }: TransformerUIProps) { + const fieldNamePickerSettings: StandardEditorsRegistryItem = { + settings: { + width: 30, + filter: (f) => f.type === FieldType.string, + placeholderText: t( + 'transformers.format-string-transfomer-editor.field-name-picker-settings.placeholderText.select-text-field', + 'Select text field' + ), + noFieldsMessage: t( + 'transformers.format-string-transfomer-editor.field-name-picker-settings.noFieldsMessage.no-text-fields-found', + 'No text fields found' + ), + }, + name: '', + id: '', + editor: () => null, + }; + const onSelectField = useCallback( (value: string | undefined) => { const val = value ?? ''; diff --git a/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx b/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx index d49720810e0..e03cfb22c7b 100644 --- a/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx +++ b/public/app/features/transformers/extractFields/ExtractFieldsTransformerEditor.tsx @@ -20,21 +20,24 @@ import { extractFieldsTransformer } from './extractFields'; import { fieldExtractors } from './fieldExtractors'; import { ExtractFieldsOptions, FieldExtractorID, JSONPath } from './types'; -const fieldNamePickerSettings: StandardEditorsRegistryItem = { - settings: { - width: 30, - placeholderText: 'Select field', - }, - name: '', - id: '', - editor: () => null, -}; - export const extractFieldsTransformerEditor = ({ input, options = { delimiter: ',' }, onChange, }: TransformerUIProps) => { + const fieldNamePickerSettings: StandardEditorsRegistryItem = { + settings: { + width: 30, + placeholderText: t( + 'transformers.extract-fields-transformer-editor.field-name-picker-settings.placeholderText.select-field', + 'Select field' + ), + }, + name: '', + id: '', + editor: () => null, + }; + const onPickSourceField = (source?: string) => { onChange({ ...options, diff --git a/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx b/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx index 054bb6874e1..cc6390d543a 100644 --- a/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx +++ b/public/app/features/transformers/lookupGazetteer/FieldLookupTransformerEditor.tsx @@ -19,23 +19,29 @@ import { getTransformationContent } from '../docs/getTransformationContent'; import { FieldLookupOptions, fieldLookupTransformer } from './fieldLookup'; -const fieldNamePickerSettings: StandardEditorsRegistryItem = { - settings: { - width: 30, - filter: (f) => f.type === FieldType.string, - placeholderText: 'Select text field', - noFieldsMessage: 'No text fields found', - }, - name: '', - id: '', - editor: () => null, -}; - const fieldLookupSettings = { settings: {}, } as StandardEditorsRegistryItem; export const FieldLookupTransformerEditor = ({ input, options, onChange }: TransformerUIProps) => { + const fieldNamePickerSettings: StandardEditorsRegistryItem = { + settings: { + width: 30, + filter: (f) => f.type === FieldType.string, + placeholderText: t( + 'transformers.field-lookup-transformer-editor.field-name-picker-settings.placeholderText.select-text-field', + 'Select text field' + ), + noFieldsMessage: t( + 'transformers.field-lookup-transformer-editor.field-name-picker-settings.noFieldsMessage.no-text-fields-found', + 'No text fields found' + ), + }, + name: '', + id: '', + editor: () => null, + }; + const onPickLookupField = useCallback( (value: string | undefined) => { onChange({ diff --git a/public/app/features/variables/editor/ConfirmDeleteModal.tsx b/public/app/features/variables/editor/ConfirmDeleteModal.tsx index 45f7da8c1b0..dbe8a48ea14 100644 --- a/public/app/features/variables/editor/ConfirmDeleteModal.tsx +++ b/public/app/features/variables/editor/ConfirmDeleteModal.tsx @@ -17,11 +17,13 @@ export function ConfirmDeleteModal({ varName, isOpen = false, onConfirm, onDismi isOpen={isOpen} onConfirm={onConfirm} onDismiss={onDismiss} - body={` - Are you sure you want to delete variable "${varName}"? - `} + body={t( + 'variables.confirm-delete-modal.body-delete-variable', + 'Are you sure you want to delete variable "{{variableToDelete}}"?', + { variableToDelete: varName } + )} modalClass={styles.modal} - confirmText="Delete" + confirmText={t('variables.confirm-delete-modal.confirmText-delete', 'Delete')} /> ); } diff --git a/public/app/features/variables/editor/VariableEditorEditor.tsx b/public/app/features/variables/editor/VariableEditorEditor.tsx index a145ab0c72b..07cc03bac26 100644 --- a/public/app/features/variables/editor/VariableEditorEditor.tsx +++ b/public/app/features/variables/editor/VariableEditorEditor.tsx @@ -174,7 +174,7 @@ export class VariableEditorEditorUnConnected extends PureComponent /> testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2} /> ) return ( ) { - const value = useMemo(() => SORT_OPTIONS.find((o) => o.value === sort) ?? SORT_OPTIONS[0], [sort]); + const SORT_OPTIONS = useMemo( + () => [ + { + label: t('variables.query-variable-sort-select.sort_options.label.disabled', 'Disabled'), + value: VariableSort.disabled, + }, + { + label: t('variables.query-variable-sort-select.sort_options.label.alphabetical-asc', 'Alphabetical (asc)'), + value: VariableSort.alphabeticalAsc, + }, + { + label: t('variables.query-variable-sort-select.sort_options.label.alphabetical-desc', 'Alphabetical (desc)'), + value: VariableSort.alphabeticalDesc, + }, + { + label: t('variables.query-variable-sort-select.sort_options.label.numerical-asc', 'Numerical (asc)'), + value: VariableSort.numericalAsc, + }, + { + label: t('variables.query-variable-sort-select.sort_options.label.numerical-desc', 'Numerical (desc)'), + value: VariableSort.numericalDesc, + }, + { + label: t( + 'variables.query-variable-sort-select.sort_options.label.alphabetical-caseinsensitive-asc', + 'Alphabetical (case-insensitive, asc)' + ), + value: VariableSort.alphabeticalCaseInsensitiveAsc, + }, + { + label: t( + 'variables.query-variable-sort-select.sort_options.label.alphabetical-caseinsensitive-desc', + 'Alphabetical (case-insensitive, desc)' + ), + value: VariableSort.alphabeticalCaseInsensitiveDesc, + }, + { + label: t('variables.query-variable-sort-select.sort_options.label.natural-asc', 'Natural (asc)'), + value: VariableSort.naturalAsc, + }, + { + label: t('variables.query-variable-sort-select.sort_options.label.natural-desc', 'Natural (desc)'), + value: VariableSort.naturalDesc, + }, + ], + [] + ); + + const value = useMemo(() => SORT_OPTIONS.find((o) => o.value === sort) ?? SORT_OPTIONS[0], [sort, SORT_OPTIONS]); return ( { backspaceRemovesValue={true} placeholder={t('components.azure-cheat-sheet.placeholder-all-categories', 'All categories')} isClearable={true} - noOptionsMessage="Unable to list all categories" + noOptionsMessage={t( + 'components.azure-cheat-sheet.noOptionsMessage-unable-to-list-categories', + 'Unable to list all categories' + )} formatCreateLabel={(input: string) => `Category: ${input}`} isSearchable={true} isMulti={true} diff --git a/public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/LogsManagement.tsx b/public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/LogsManagement.tsx index adfe26927be..a54949c3187 100644 --- a/public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/LogsManagement.tsx +++ b/public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/LogsManagement.tsx @@ -15,12 +15,12 @@ export function LogsManagement({ query, onQueryChange: onChange }: AzureQueryEdi { setBasicLogsAckOpen(false); let updatedBasicLogsQuery = setBasicLogsQuery(query, true); diff --git a/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryHeader.tsx b/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryHeader.tsx index 9e871cb419c..035a918fc8d 100644 --- a/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryHeader.tsx +++ b/public/app/plugins/datasource/azuremonitor/components/QueryEditor/QueryHeader.tsx @@ -19,11 +19,6 @@ interface QueryTypeFieldProps { app: CoreApp | undefined; } -const EDITOR_MODES = [ - { label: 'Builder', value: LogsEditorMode.Builder }, - { label: 'KQL', value: LogsEditorMode.Raw }, -]; - export const QueryHeader = ({ query, onQueryChange, @@ -37,6 +32,11 @@ export const QueryHeader = ({ const [showModeSwitchWarning, setShowModeSwitchWarning] = useState(false); const [pendingModeChange, setPendingModeChange] = useState(null); + const EDITOR_MODES = [ + { label: t('components.query-header.editor-modes.label-builder', 'Builder'), value: LogsEditorMode.Builder }, + { label: t('components.query-header.editor-modes.label-kql', 'KQL'), value: LogsEditorMode.Raw }, + ]; + const currentMode = query.azureLogAnalytics?.mode; const queryTypes: Array<{ value: AzureQueryType; label: string }> = [ @@ -113,10 +113,18 @@ export const QueryHeader = ({ title={t('components.query-header.title-switch-mode', 'Switch editor mode?')} body={ pendingModeChange === LogsEditorMode.Builder - ? 'Switching to Builder will discard your current KQL query and clear the KQL editor. Are you sure?' - : 'Switching to KQL will discard your current builder settings. Are you sure?' + ? t( + 'components.query-header.body-switching-to-builder', + 'Switching to Builder will discard your current KQL query and clear the KQL editor. Are you sure?' + ) + : t( + 'components.query-header.body-switching-to-kql', + 'Switching to KQL will discard your current builder settings. Are you sure?' + ) } - confirmText={`Switch to ${pendingModeChange === LogsEditorMode.Builder ? 'Builder' : 'KQL'}`} + confirmText={t('components.query-header.confirmText-switch-to', 'Switch to {{newMode}}', { + newMode: pendingModeChange === LogsEditorMode.Builder ? 'Builder' : 'KQL', + })} onConfirm={() => { if (pendingModeChange) { applyModeChange(pendingModeChange); diff --git a/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json b/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json index 1031611467c..933c052938c 100644 --- a/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json +++ b/public/app/plugins/datasource/azuremonitor/locales/en-US/grafana-azure-monitor-datasource.json @@ -52,6 +52,7 @@ "button-use-query": "Use this query", "label-categories": "Categories", "label-query-results": "Query results: {{numResults}}", + "noOptionsMessage-unable-to-list-categories": "Unable to list all categories", "placeholder-all-categories": "All categories", "placeholder-search-logs": "Search Logs queries", "text-loading": "Loading..." @@ -161,6 +162,8 @@ "tooltip-limit": "Restrict the number of rows returned (default is 1000)." }, "logs-management": { + "body-basic-logs-queries": "Are you sure you want to switch to Basic Logs?", + "confirmText-confirm": "Confirm", "description-basic-logs-queries": "Basic Logs queries incur cost based on the amount of data scanned.", "label-logs": "Logs", "title-basic-logs-queries": "Basic Logs Queries", @@ -194,8 +197,15 @@ }, "query-header": { "aria-label-kick-start": "Azure logs kick start your query button", + "body-switching-to-builder": "Switching to Builder will discard your current KQL query and clear the KQL editor. Are you sure?", + "body-switching-to-kql": "Switching to KQL will discard your current builder settings. Are you sure?", "button-kick-start-your-query": "Kick start your query", "button-run-query": "Run query", + "confirmText-switch-to": "Switch to {{newMode}}", + "editor-modes": { + "label-builder": "Builder", + "label-kql": "KQL" + }, "label-service": "Service", "placeholder-service": "Service...", "title-switch-mode": "Switch editor mode?" diff --git a/public/app/plugins/panel/geomap/editor/StyleEditor.tsx b/public/app/plugins/panel/geomap/editor/StyleEditor.tsx index 517ba553513..c7f07fb2dba 100644 --- a/public/app/plugins/panel/geomap/editor/StyleEditor.tsx +++ b/public/app/plugins/panel/geomap/editor/StyleEditor.tsx @@ -138,7 +138,12 @@ export const StyleEditor = (props: Props) => { settings: { resourceType: 'icon', folderName: ResourceFolderName.Marker, - placeholderText: hasTextLabel ? 'Select a symbol' : 'Select a symbol or add a text label', + placeholderText: hasTextLabel + ? t('geomap.style-editor.placeholderText-select-symbol', 'Select a symbol') + : t( + 'geomap.style-editor.placeholderText-select-symbol-or-add-text', + 'Select a symbol or add a text label' + ), placeholderValue: defaultStyleConfig.symbol.fixed, showSourceRadio: false, maxFiles, @@ -228,7 +233,12 @@ export const StyleEditor = (props: Props) => { settings: { resourceType: MediaType.Icon, folderName: ResourceFolderName.Marker, - placeholderText: hasTextLabel ? 'Select a symbol' : 'Select a symbol or add a text label', + placeholderText: hasTextLabel + ? t('geomap.style-editor.placeholderText-select-symbol', 'Select a symbol') + : t( + 'geomap.style-editor.placeholderText-select-symbol-or-add-text', + 'Select a symbol or add a text label' + ), placeholderValue: defaultStyleConfig.symbol.fixed, showSourceRadio: false, maxFiles, diff --git a/public/app/plugins/panel/geomap/layers/data/photosLayer.tsx b/public/app/plugins/panel/geomap/layers/data/photosLayer.tsx index 2fbe96abb83..ffd64aa03cd 100644 --- a/public/app/plugins/panel/geomap/layers/data/photosLayer.tsx +++ b/public/app/plugins/panel/geomap/layers/data/photosLayer.tsx @@ -5,6 +5,7 @@ import { Stroke, Style } from 'ol/style'; import Photo from 'ol-ext/style/Photo'; import { MapLayerRegistryItem, PanelData, GrafanaTheme2, EventBus, PluginState, FieldType, Field } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { FrameGeometrySourceMode, MapLayerOptions } from '@grafana/schema'; import { findField } from 'app/features/dimensions/utils'; import { FrameVectorSource } from 'app/features/geo/utils/frameVectorSource'; @@ -187,7 +188,7 @@ export const photosLayer: MapLayerRegistryItem = { name: 'Image Source field', settings: { filter: (f: Field) => f.type === FieldType.string, - noFieldsMessage: 'No string fields found', + noFieldsMessage: t('geomap.photos-layer.noFieldsMessage-no-string-fields', 'No string fields found'), }, }) .addRadio({ diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index fc392dece19..e8c08c32dd0 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -84,6 +84,7 @@ "admin-feature-toggles-table": { "confirm-modal-body-1": "Some features are stable (GA) and enabled by default, whereas some are currently in their preliminary Beta phase, available for early adoption.", "confirm-modal-body-2": "We advise understanding the implications of each feature change before making modifications.", + "confirmText-save-changes": "Save changes", "get-stage-cell": { "beta": "Beta", "content-general-availability": "General availability", @@ -96,14 +97,21 @@ }, "admin-orgs-table": { "aria-label-delete-org": "Delete org", + "confirmText-delete": "Delete", "title-delete": "Delete" }, "anon-users": { "not-found": "No anonymous users found." }, "base-user-sessions": { + "body-force-logout-from-all-devices": "Are you sure you want to force logout from all devices?", + "confirmText-confirm-logout": "Confirm logout", + "confirmText-force-logout": "Force logout", "title-force-logout-from-all-devices": "Force logout from all devices" }, + "change-org-button": { + "confirmText-save": "Save" + }, "edit-org": { "access-denied": "You do not have permission to see users in this organization. To update this organization, contact your server administrator.", "heading": "Edit Organization", @@ -208,9 +216,11 @@ "not-editable": "This user's role is not editable because it is synchronized from your auth provider. Refer to the <1>Grafana authentication docs for details." }, "org-users-table": { + "body-delete": "Are you sure you want to delete user {{user}}?", "columns": { "aria-label-role": "Role" }, + "confirmText-delete": "Delete", "delete-aria-label": "Delete user: {{name}}", "title-delete": "Delete" }, @@ -241,6 +251,9 @@ "settings": { "info-description": "These system settings are defined in grafana.ini or custom.ini (or overridden in ENV variables). To change these you currently need to restart Grafana." }, + "un-themed-org-row": { + "confirmText-confirm-removal": "Confirm removal" + }, "upgrade-info": { "title": "Enterprise license" }, @@ -293,12 +306,17 @@ }, "user-permissions": { "change-button": "Change", + "confirmText-change": "Change", "grafana-admin-key": "Grafana Admin", "grafana-admin-no": "No", "grafana-admin-yes": "Yes", "title": "Permissions" }, "user-profile": { + "body-delete": "Are you sure you want to delete this user?", + "body-disable": "Are you sure you want to disable this user?", + "confirmText-delete-user": "Delete user", + "confirmText-disable-user": "Disable user", "delete-button": "Delete user", "disable-button": "Disable user", "edit-button": "Edit", @@ -312,6 +330,9 @@ "title-delete-user": "Delete user", "title-disable-user": "Disable user" }, + "user-profile-row": { + "confirmText-save": "Save" + }, "user-sessions": { "browser-column": "Browser and OS", "force-logout-all-button": "Force logout from all devices", @@ -461,6 +482,9 @@ "label-muting-grouping-and-timings-optional": "Muting, grouping and timings (optional)", "title-muting-grouping-and-timings": "Muting, grouping, and timings" }, + "alert-manager-picker": { + "noOptionsMessage-no-datasources-found": "No datasources found" + }, "alert-menu": { "copy-link": "Copy link", "duplicate": "Duplicate", @@ -550,6 +574,7 @@ "view-configuration": "View configuration" }, "alertmanager-config": { + "confirmText-yes-reset-configuration": "Yes, reset configuration", "gma-manual-configuration-description": "The internal Grafana Alertmanager configuration cannot be manually changed. To change this configuration, edit the individual resources through the UI.", "gma-manual-configuration-is-not-supported": "Manual configuration changes not supported", "message": { @@ -564,11 +589,13 @@ "title-resetting-alertmanager-configuration": "Resetting Alertmanager configuration" }, "alertmanager-configuration-version-manager": { + "body-restore-configuration-version-unsaved-changes": "Are you sure you want to restore the configuration to this version? All unsaved changes will be lost.", "columns": { "compare": "Compare", "restore": "Restore", "text-latest": "Latest" }, + "confirmText-yes-restore-configuration": "Yes, restore configuration", "loading": "Loading...", "no-previous-configurations": "No previous configurations", "this-might-take-a-while": "This might take a while...", @@ -848,8 +875,10 @@ }, "contact-point-header": { "aria-label-more-actions": "More actions for contact point \"{{contactPointName}}\"", + "ariaLabel-delete": "Delete", "button-edit": "Edit", "button-view": "View", + "export-ariaLabel-export": "Export", "export-label-export": "Export", "label-delete": "Delete", "label-manage-permissions": "Manage permissions", @@ -1384,6 +1413,7 @@ "label-disable-resolved-message": "Disable resolved message" }, "grafana-evaluation-behavior-step": { + "loadingMessage-loading-groups": "Loading groups...", "message": { "must-be-a-positive-integer": "Must be a positive integer.", "must-enter-a-group-name": "Must enter a group name" @@ -1842,7 +1872,11 @@ "other-data-sources": "Other data sources" } } - } + }, + "noOptionsMessage-no-datasources-found": "No datasources found" + }, + "mute-timing-actions-button": { + "body-delete-mute-timing": "Are you sure you would like to delete \"{{muteTiming}}\"?" }, "mute-timing-actions-buttons": { "text-disabled": "Disabled", @@ -2153,6 +2187,7 @@ "query-and-expressions-step": { "add-query": "Add query", "body-queries-expressions-configured": "Create at least one query or expression to be alerted on", + "confirmText-deactivate": "Deactivate", "expressions": "Expressions", "loading-data-sources": "Loading data sources...", "manipulate-returned-queries-other-operations": "Manipulate data returned from queries with math and other operations.", @@ -2220,6 +2255,7 @@ "redirect-to-clone-rule": { "body-evaluation-group": "You will need to set a new evaluation group for the copied rule because the original one has been provisioned and cannot be used for rules created in the UI.", "body-not-provisioned": "The new rule will <1>not be marked as a provisioned rule.", + "confirmText-copy": "Copy", "title-copy-provisioned-alert-rule": "Copy provisioned alert rule" }, "redirect-to-rule-viewer": { @@ -2766,6 +2802,9 @@ "existing-templates-selector-placeholder-choose-notification-template": "Choose notification template", "loading": "Loading...", "template-options": { + "ariaLabel": { + "select-notification-template": "Select notification template" + }, "label": { "select-notification-template": "Select notification template" } @@ -2792,6 +2831,8 @@ }, "templates-table": { "actions": "Actions", + "body-delete-template-group": "Are you sure you want to delete template group \"{{template}}\"?", + "confirmText-yes-delete": "Yes, delete", "no-templates-defined": "No templates defined.", "template-group": "Template group", "title-delete-template-group": "Delete template group" @@ -2919,6 +2960,11 @@ "title-delete-contact-point": "Delete contact point" } }, + "use-delete-modal": { + "modal": { + "confirmText-yes-delete": "Yes, delete" + } + }, "use-delete-policy-modal": { "modal-element": { "title-delete-notification-policy": "Delete notification policy" @@ -3075,7 +3121,8 @@ "annotation-field-mapper": { "annotation": "Annotation", "first-value": "First value", - "from": "From" + "from": "From", + "noOptionsMessage-unknown-field-names": "Unknown field names" }, "empty-state": { "button-title": "Add annotation query", @@ -3209,7 +3256,7 @@ "team-ids-github": "Integer list of Team IDs.", "team-ids-label": "Team IDs", "team-ids-numbers": "Team IDs must be numbers.", - "team-ids-other": "String list of Team Ids.", + "team-ids-other": "String list of Team IDs.", "team-ids-placeholder": "Enter Team IDs and press Enter to add", "teams-url-description": "The URL used to query for Team IDs. If not set, the default value is /teams.", "teams-url-description-oauth": "If you configure \"{{ teamsURLLabel }}\", you must also configure \"{{ teamIDsAttributePathLabel }}\".", @@ -3253,6 +3300,7 @@ "additional-actions-menu": { "label-reset-to-default-values": "Reset to default values" }, + "confirmText-reset": "Reset", "disable": "Disable", "disabling": "Disabling...", "discard": "Discard", @@ -4180,8 +4228,8 @@ } }, "dashbaord-scene": { - "interval-variable-form": { - "description-auto-option": "Dynamically calculates interval by dividing time range by the count specified" + "variable-editor-form": { + "run-query": "Run query" } }, "dashboard": { @@ -4343,6 +4391,9 @@ }, "dash-nav": { "on-open-snapshot-original": { + "confirmText": { + "proceed": "Proceed" + }, "title": { "proceed-to-external-site": "Proceed to external site?" } @@ -4557,6 +4608,13 @@ "editable": "Editable", "readonly": "Read-only" } + }, + "graph_tooltip_options": { + "label": { + "default": "Default", + "shared-crosshair": "Shared crosshair", + "shared-tooltip": "Shared tooltip" + } } }, "get-debug-dashboard": { @@ -4861,6 +4919,7 @@ }, "revert-dashboard-modal": { "body-restore-version": "Are you sure you want to restore the dashboard to version {{version}}? All unsaved changes will be lost.", + "confirmText-restore-version": "Yes, restore to version {{version}}", "title-restore-version": "Restore version" }, "row-options-button": { @@ -4911,6 +4970,9 @@ "title-not-unique": "This title is not unique" } }, + "save-dashboard": { + "message-dashboard-saved": "Dashboard saved" + }, "save-dashboard-as-button": { "save-as": "Save as" }, @@ -4945,6 +5007,7 @@ "save-dashboard-error-proxy": { "body-name-exists": "A dashboard with the same name in selected folder already exists.<1><2>Would you still like to save this dashboard?", "body-version-mismatch": "Someone else has updated this dashboard<1><2>Would you still like to save this dashboard?", + "confirmText-save-and-overwrite": "Save and overwrite", "title-name-exists": "Conflict", "title-version-mismatch": "Conflict" }, @@ -5141,7 +5204,9 @@ "label-apply-transformation-to": "Apply transformation to" }, "transformation-operation-row": { + "body-delete": "Note that removing one transformation may break others. If there is only a single transformation, you will go back to the main selection screen.", "render-actions": { + "confirmText-delete": "Delete", "title-debug": "Debug", "title-disable-transformation": "Disable transformation", "title-filter": "Filter", @@ -5163,10 +5228,14 @@ "show-images": "Show images", "title-add-another-transformation": "Add another transformation" }, + "un-theme-transformations-editor": { + "body-delete-all-transformations": "By deleting all transformations, you will go back to the main selection screen." + }, "un-themed-transformations-editor": { "actions": { "add-another-transformation": "Add another transformation" }, + "confirmText-delete-all": "Delete all", "delete-all-transformations": "Delete all transformations", "title-delete-all-transformations": "Delete all transformations?", "tooltip-clear-search": "Clear search", @@ -5203,6 +5272,7 @@ "version-history-table": { "aria-label-toggle-selection": "Toggle selection of version {{version}}", "date": "Date", + "name-latest": "Latest", "notes": "Notes", "restore": "Restore", "updated-by": "Updated by", @@ -5279,7 +5349,8 @@ "description-enables-users-custom-values": "Enables users to add custom values to the list", "description-provide-dimensions-as-csv-dimension-name-dimension-id": "Provide dimensions as CSV: {{name}}, {{value}}", "label-data-source": "Data source", - "label-use-static-key-dimensions": "Use static key dimensions" + "label-use-static-key-dimensions": "Use static key dimensions", + "name-allow-custom-values": "Allow custom values" }, "add-to-dashboard": { "message": { @@ -5352,6 +5423,9 @@ } }, "config-public-dashboard": { + "confirmText": { + "revoke-public-url": "Revoke public URL" + }, "title": { "revoke-public-url": "Revoke public URL" } @@ -5363,6 +5437,7 @@ }, "custom-variable-form": { "custom-options": "Custom options", + "name-values-separated-comma": "Values separated by comma", "selection-options": "Selection options" }, "dashboard-edit-pane-renderer": { @@ -5381,6 +5456,12 @@ "label-type": "Type", "label-url": "URL", "label-with-tags": "With tags", + "link-type-options": { + "label": { + "dashboards": "Dashboards", + "link": "Link" + } + }, "placeholder-open-dashboard": "Open dashboard" }, "dashboard-link-list": { @@ -5427,6 +5508,8 @@ "data-source-options": "Data source options", "description-instance-name-filter": "Regex filter for which data source instances to choose from in the variable value list. Leave empty for all.", "example-instance-name-filter": "Example: ", + "name-instance-name-filter": "Instance name filter", + "name-type": "Type", "selection-options": "Selection options" }, "default-grid-layout-manager": { @@ -5472,6 +5555,21 @@ "empty-transformations-message": { "add-transformation": "Add transformation" }, + "general-settings-edit-view": { + "editable_options": { + "label": { + "editable": "Editable", + "readonly": "Read-only" + } + }, + "graph_tooltip_options": { + "label": { + "default": "Default", + "shared-crosshair": "Shared crosshair", + "shared-tooltip": "Shared tooltip" + } + } + }, "get-edit-options": { "title": { "column-options": "Column options", @@ -5502,7 +5600,8 @@ "description-provide-dimensions-as-csv-dimension-name-dimension-id": "Provide dimensions as CSV: {{name}}, {{value}}", "group-by-options": "Group by options", "label-data-source": "Data source", - "label-use-static-group-by-dimensions": "Use static group dimensions" + "label-use-static-group-by-dimensions": "Use static group dimensions", + "name-allow-custom-values": "Allow custom values" }, "help-wizard": { "copy-to-clipboard": "Copy to clipboard", @@ -5538,9 +5637,14 @@ "apply": "Apply" }, "interval-variable-form": { + "description-auto-option": "Dynamically calculates interval by dividing time range by the count specified", "description-calculated-value-below-threshold": "The calculated value will not go below this threshold", "description-step-count": "How many times the current time range should be divided to calculate the value", - "interval-options": "Interval options" + "interval-options": "Interval options", + "name-auto-option": "Auto option", + "name-min-interval": "Min interval", + "name-step-count": "Step count", + "name-values": "Values" }, "json-model-edit-view": { "cancel-button": { @@ -5565,6 +5669,9 @@ "title-name-already-exists": "Name already exists" }, "on-open-snapshot-original-dashboard": { + "confirmText": { + "proceed": "Proceed" + }, "title": { "proceed-to-external-site": "Proceed to external site?" } @@ -5600,6 +5707,8 @@ }, "panel-data-transformations-tab-rendered": { "add-another-transformation": "Add another transformation", + "body-delete-all-transformations": "By deleting all transformations, you will go back to the main selection screen.", + "confirmText-delete-all": "Delete all", "delete-all-transformations": "Delete all transformations", "title-delete-all-transformations": "Delete all transformations?" }, @@ -5653,6 +5762,7 @@ "description-optional": "Optional, if you want to extract part of a series name or metric node segment.", "label-data-source": "Data source", "label-target-data-source": "Target data source", + "name-regex": "Regex", "query-options": "Query options", "selection-options": "Selection options" }, @@ -5667,6 +5777,7 @@ }, "revert-dashboard-modal": { "body-restore-version": "Are you sure you want to restore the dashboard to version {{version}}? All unsaved changes will be lost.", + "confirmText-restore-version": "Yes, restore to version {{version}}", "title-restore-version": "Restore version" }, "save-button": { @@ -5760,7 +5871,11 @@ "selection-options-form": { "description-enables-multiple-values-selected": "Enables multiple values to be selected at the same time", "description-enables-option-include-variables": "Enables an option to include all values", - "description-enables-users-custom-values": "Enables users to add custom values to the list" + "description-enables-users-custom-values": "Enables users to add custom values to the list", + "name-allow-custom-values": "Allow custom values", + "name-custom-all-value": "Custom all value", + "name-include-all-option": "Include All option", + "name-multi-value": "Multi-value" }, "share-button": { "aria-label-sharedropdownmenu": "Toggle share menu" @@ -5780,6 +5895,9 @@ "copy-to-clipboard-failed": "Copy to clipboard failed" } }, + "text-box-variable": { + "name-default-value": "Default value" + }, "text-box-variable-form": { "placeholder-default-value-if-any": "(optional)", "text-options": "Text options" @@ -5803,6 +5921,8 @@ } }, "unlink-modal": { + "body-unlink-panel": "If you unlink this panel, you will be able to edit it without affecting any other dashboards. However, once you make a change you will not be able to revert to its original reusable panel.", + "confirmText-yes-unlink": "Yes, unlink", "title-really-unlink-panel": "Do you really want to unlink this panel?" }, "unsaved-changes-modal": { @@ -5819,6 +5939,9 @@ } } }, + "use-save-dashboard": { + "message-dashboard-saved": "Dashboard saved" + }, "variable-check-indicator": { "aria-label-variable-referenced-dashboard": "This variable is not referenced by any variable or dashboard.", "aria-label-variable-referenced-other-variables-dashboard": "This variable is referenced by other variables or dashboard.", @@ -5828,10 +5951,16 @@ "variable-editor-form": { "aria-label-variable-editor-form": "Variable editor form", "back-to-list": "Back to list", + "confirmText": { + "delete-variable": "Delete variable" + }, "delete": "Delete", "description-optional-display-name": "Optional display name", "description-template-variable-characters": "The name of the template variable. (Max. 50 characters)", "general": "General", + "name-description": "Description", + "name-label": "Label", + "name-name": "Name", "placeholder-descriptive-text": "Descriptive text", "placeholder-label-name": "Label name", "placeholder-variable-name": "Variable name", @@ -5846,13 +5975,25 @@ "variable": "Variable" }, "variable-editor-list-row": { + "body-delete-variable": "Are you sure you want to delete: {{variable}}?", + "confirmText-delete-variable": "Delete variable", "title-delete-variable": "Delete variable", "tooltip-duplicate-variable": "Duplicate variable", "tooltip-remove-variable": "Remove variable" }, "variable-hide-select": { + "hide_options": { + "label": { + "label": "Label", + "nothing": "Nothing", + "variable": "Variable" + } + }, "label": "Hide" }, + "variable-type-select": { + "name-variable-type": "Variable type" + }, "variable-usages-button": { "title-show-usages": "Showing usages for: {{variableId}}", "tooltip-show-usages": "Show usages" @@ -5879,6 +6020,7 @@ "version-history-table": { "aria-label-toggle-selection": "Toggle selection of version {{version}}", "date": "Date", + "name-latest": "Latest", "notes": "Notes", "restore": "Restore", "updated-by": "Updated by", @@ -6266,7 +6408,8 @@ } }, "color-dimension-editor": { - "label-fixed-color": "Fixed color" + "label-fixed-color": "Fixed color", + "noOptionsMessage-no-fields-found": "No fields found" }, "file-dropzone-custom-children": { "upload": "Upload" @@ -6304,6 +6447,7 @@ }, "label-limit": "Limit", "label-value": "Value", + "noOptionsMessage-no-fields-found": "No fields found", "scalar-options": { "description-clamped": "Use field values, clamped to max and min", "description-mod": "Use field values, mod from max", @@ -6319,7 +6463,8 @@ }, "label-max": "Max", "label-min": "Min", - "label-value": "Value" + "label-value": "Value", + "noOptionsMessage-no-fields-found": "No fields found" }, "text-dimension-editor": { "description-field": "Display field value", @@ -6891,6 +7036,8 @@ "aria-label-select-service-name-operator": "Select service name operator", "aria-label-select-span-name": "Select span name", "aria-label-select-span-name-operator": "Select span name operator", + "ariaLabel-select-max-span-duration": "Select max span duration", + "ariaLabel-select-min-span-duration": "Select min span duration", "label-collapse": "Span Filters", "label-duration": "Duration", "label-service-name": "Service name", @@ -6961,6 +7108,8 @@ "split-widen": "Widen pane" }, "trace-page-actions": { + "ariaLabel-copy-trace-id": "Copy Trace ID", + "ariaLabel-export-trace": "Export Trace", "give-feedback": "Give feedback", "label-copied": "Copied!", "label-export": "Export", @@ -7098,6 +7247,7 @@ }, "folder-filter": { "clear-folder-button": "Clear folders", + "noOptionsMessage-no-folders-found": "No folders found", "select-aria-label": "Folder filter", "select-placeholder": "Filter by folder" }, @@ -7289,6 +7439,9 @@ "name-show-scale": "Show scale", "name-show-zoom": "Show zoom control", "name-tooltip": "Tooltip", + "photos-layer": { + "noFieldsMessage-no-string-fields": "No string fields found" + }, "plugin": { "basemap-layer-configured-server-admin": "The basemap layer is configured by the server admin." }, @@ -7312,6 +7465,8 @@ "label-text-label": "Text label", "label-x-offset": "X offset", "label-y-offset": "Y offset", + "placeholderText-select-symbol": "Select a symbol", + "placeholderText-select-symbol-or-add-text": "Select a symbol or add a text label", "vertical-align-options": { "label-bottom": "Bottom", "label-center": "Center", @@ -7585,7 +7740,8 @@ "aria-label-selected-color": "{{colorLabel}} color" }, "confirm-button": { - "cancel": "Cancel" + "cancel": "Cancel", + "confirmText-delete": "Delete" }, "confirm-content": { "placeholder": "Type \"{{confirmPromptText}}\" to confirm" @@ -7767,6 +7923,8 @@ }, "panel-chrome": { "aria-label-toggle-collapse": "toggle collapse panel", + "ariaLabel-panel-loading": "Panel loading bar", + "ariaLabel-panel-status": "Panel status", "tooltip-cancel": "Cancel query", "tooltip-cancel-loading": "Cancel query", "tooltip-stop-streaming": "Stop streaming", @@ -7934,6 +8092,12 @@ "footer-click-to-action": "Click to {{actionTitle}}", "footer-click-to-navigate": "Click to open {{linkTitle}}", "timestamp": "Timestamp" + }, + "week-start-picker": { + "weekStarts-label-default": "Default", + "weekStarts-label-monday": "Monday", + "weekStarts-label-saturday": "Saturday", + "weekStarts-label-sunday": "Sunday" } }, "graph": { @@ -8312,6 +8476,10 @@ "add-library-panel-modal": { "title-create-library-panel": "Create library panel" }, + "change-library-panel-modal": { + "confirmText-change": "Change", + "confirmText-replace": "Replace" + }, "confirm": { "delete-panel": "Do you want to delete this panel?" }, @@ -8756,6 +8924,8 @@ "updated-on": "Updated on" }, "snapshot-list-table": { + "body-delete": "Are you sure you want to delete '{{snapshotToRemove}}'?", + "confirmText-delete": "Delete", "title-delete": "Delete" }, "unthemed-dashboard-import": { @@ -8767,6 +8937,9 @@ } } }, + "metric-select": { + "noOptionsMessage-no-options-found": "No options found" + }, "migrate-to-cloud": { "build-snapshot": { "description": "This tool can migrate some resources from this installation to your cloud stack. To get started, you'll need to create a snapshot of this installation. Creating a snapshot typically takes less than two minutes. The snapshot is stored alongside this Grafana installation.", @@ -9465,7 +9638,7 @@ "marker": { "100-node-count": ">100 nodes", "aria-label-hidden-marker": "Hidden nodes marker: {{marker}}", - "node-count_one": "{{count}} node", + "node-count_one": "{{count}} nodes", "node-count_other": "{{count}} nodes" }, "node": { @@ -9475,10 +9648,10 @@ "aria-label-layered-layout-performance-warning": "Layered layout performance warning", "aria-label-nodes-hidden-warning": "Nodes hidden warning", "computing-layout": "Computing layout", - "hidden-nodes_one": "<0> {{count}} node is hidden for performance reasons.", + "hidden-nodes_one": "<0> {{count}} nodes are hidden for performance reasons.", "hidden-nodes_other": "<0> {{count}} nodes are hidden for performance reasons.", "no-data": "No data", - "processed-nodes_one": "<0> Layered layout may be slow with {{count}} node.", + "processed-nodes_one": "<0> Layered layout may be slow with {{count}} nodes.", "processed-nodes_other": "<0> Layered layout may be slow with {{count}} nodes." }, "node-graph-panel": { @@ -9605,6 +9778,7 @@ } }, "org-picker": { + "noOptionsMessage-no-organizations-found": "No organizations found", "select-placeholder": "Select organization" }, "page": { @@ -9871,8 +10045,7 @@ "update-status-text": "plugins updated" }, "versions": { - "confirmation-text-1": "Are you really sure you want to downgrade to version", - "confirmation-text-2": "You should normally not be doing this", + "confirmation-text": "Are you really sure you want to downgrade to version {{version}}? You should normally not be doing this", "downgrade-confirm": "Downgrade", "downgrade-title": "Downgrade plugin version" } @@ -9963,7 +10136,11 @@ "updating": "Updating" }, "install-controls-button": { - "title-uninstall-modal": "Uninstall {{plugin}}" + "title-uninstall-modal": "Uninstall {{plugin}}", + "uninstall-controls": { + "body-uninstall-plugin": "Are you sure you want to uninstall this plugin?", + "confirmText-confirm": "Confirm" + } }, "install-controls-warning": { "body-not-published": "This plugin is not published to <2>grafana.com/plugins and can't be managed via the catalog.", @@ -10999,6 +11176,7 @@ } }, "service-account-picker": { + "noOptionsMessage-no-service-accounts-found": "No service accounts found", "select-aria-label": "Service account picker", "select-placeholder": "Start typing to search for service accounts" }, @@ -11044,6 +11222,10 @@ }, "service-account-page-unconnected": { "add-service-account-token": "Add service account token", + "body-delete-service-account": "Are you sure you want to delete this service account?", + "body-disable-service-account": "Are you sure you want to disable this service account?", + "confirmText-delete-service-account": "Delete service account", + "confirmText-disable-service-account": "Disable service account", "delete-service-account": "Delete service account", "disable-service-account": "Disable service account", "enable-service-account": "Enable service account", @@ -11070,6 +11252,7 @@ "used-by": "Used by" }, "service-account-profile-row": { + "confirmText-save": "Save", "edit": "Edit" }, "service-account-role-row": { @@ -11083,6 +11266,12 @@ }, "service-accounts-list-page-unconnected": { "add-service-account": "Add service account", + "body-delete_one": "Are you sure you want to delete {{serviceAccountName}} and {{count}} accompanying tokens?", + "body-delete_other": "Are you sure you want to delete {{serviceAccountName}} and {{count}} accompanying tokens?", + "body-delete-with-tokens": "Are you sure you want to delete {{serviceAccountName}}?", + "body-disable-service-account": "Are you sure you want to disable '{{accountToDisable}}'?", + "confirmText-delete": "Delete", + "confirmText-disable-service-account": "Disable service account", "placeholder-search-service-account-by-name": "Search service account by name", "sub-title": "Service accounts and their tokens can be used to authenticate against the Grafana API. Find out more in our <2>documentation.", "title-delete-service-account": "Delete service account", @@ -11478,7 +11667,7 @@ "label-never": "Never" }, "status-history-panel": { - "too-many-points_one": "Too many points to visualize properly. <1>Update the query to return fewer points. <3>({{count}} point received)", + "too-many-points_one": "Too many points to visualize properly. <1>Update the query to return fewer points. <3>({{count}} points received)", "too-many-points_other": "Too many points to visualize properly. <1>Update the query to return fewer points. <3>({{count}} points received)" } }, @@ -11623,6 +11812,7 @@ "tag-option-label": "Tag option" }, "team-picker": { + "noOptionsMessage-no-teams-found": "No teams found", "select-aria-label": "Team picker", "select-placeholder": "Select a team" }, @@ -11948,6 +12138,7 @@ "convert-field-type-transformer-editor": { "aria-label-add-a-convert-field-type-transformer": "Add a convert field type transformer", "aria-label-remove-convert-field-type-transformer": "Remove convert field type transformer", + "convert-field-type": "Convert field type", "label": { "browser": "Browser", "utc": "UTC" @@ -11990,6 +12181,11 @@ "remove-enum-row-tooltip-delete": "Delete" }, "extract-fields-transformer-editor": { + "field-name-picker-settings": { + "placeholderText": { + "select-field": "Select field" + } + }, "label-delimiter": "Delimiter", "label-format": "Format", "label-keep-time": "Keep time", @@ -12003,6 +12199,14 @@ "aria-label-threshold-color": "Threshold color" }, "field-lookup-transformer-editor": { + "field-name-picker-settings": { + "noFieldsMessage": { + "no-text-fields-found": "No text fields found" + }, + "placeholderText": { + "select-text-field": "Select text field" + } + }, "label-field": "Field", "label-lookup": "Lookup" }, @@ -12028,10 +12232,30 @@ }, "filter-by-value-transformer-editor": { "add-condition": "Add condition", + "filter-match": { + "label": { + "match-all": "Match all", + "match-any": "Match any" + } + }, + "filter-types": { + "label": { + "exclude": "Exclude", + "include": "Include" + } + }, "label-conditions": "Conditions", "label-filter-type": "Filter type" }, "format-string-transfomer-editor": { + "field-name-picker-settings": { + "noFieldsMessage": { + "no-text-fields-found": "No text fields found" + }, + "placeholderText": { + "select-text-field": "Select text field" + } + }, "label-field": "Field", "label-format": "Format", "label-substring-range": "Substring range" @@ -12342,6 +12566,7 @@ "title": "Organizations" }, "user-picker": { + "noOptionsMessage-no-users-found": "No users found", "select-aria-label": "User picker", "select-placeholder": "Start typing to search for user" }, @@ -12427,6 +12652,8 @@ } }, "confirm-delete-modal": { + "body-delete-variable": "Are you sure you want to delete variable \"{{variableToDelete}}\"?", + "confirmText-delete": "Delete", "title-delete-variable": "Delete variable" }, "create-ad-hoc-variable-adapter": { @@ -12475,9 +12702,24 @@ "label-refresh": "Refresh" }, "query-variable-sort-select": { - "description-values-variable": "How to sort the values of this variable" + "description-values-variable": "How to sort the values of this variable", + "name-sort": "Sort", + "sort_options": { + "label": { + "alphabetical-asc": "Alphabetical (asc)", + "alphabetical-caseinsensitive-asc": "Alphabetical (case-insensitive, asc)", + "alphabetical-caseinsensitive-desc": "Alphabetical (case-insensitive, desc)", + "alphabetical-desc": "Alphabetical (desc)", + "disabled": "Disabled", + "natural-asc": "Natural (asc)", + "natural-desc": "Natural (desc)", + "numerical-asc": "Numerical (asc)", + "numerical-desc": "Numerical (desc)" + } + } }, "text-box-variable-editor": { + "name-default-value": "Default value", "placeholder-default-value-if-any": "default value, if any", "text-options": "Text options" }, @@ -12506,6 +12748,8 @@ "description-optional-display-name": "Optional display name", "description-template-variable-characters": "The name of the template variable. (Max. 50 characters)", "general": "General", + "name-label": "Label", + "name-name": "Name", "placeholder-descriptive-text": "Descriptive text", "placeholder-label-name": "Label name", "placeholder-variable-name": "Variable name", @@ -12520,9 +12764,15 @@ "tooltip-duplicate-variable": "Duplicate variable", "tooltip-remove-variable": "Remove variable" }, + "variable-editor-un-connected": { + "name-description": "Description" + }, "variable-options": { "aria-label-toggle-all-values": "Toggle all values" }, + "variable-type-select": { + "name-select-variable-type": "Select variable type" + }, "variable-usages-button": { "tooltip-show-usages": "Show usages" },