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 d7c9b1f6b1b..7885c3d457c 100644
--- a/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json
+++ b/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json
@@ -225,6 +225,29 @@
"step": "Step: {{value}}",
"type": "Type: {{value}}"
},
+ "get-placeholders": {
+ "browse": "Search metrics by name",
+ "include-null-metadata": "Include results with no metadata",
+ "metadata-search-switch": "Include description in search",
+ "set-use-backend": "Enable regex search",
+ "type": "Filter by type"
+ },
+ "get-prom-types": {
+ "description-counter": "A cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on restart.",
+ "description-gauge": "A metric that represents a single numerical value that can arbitrarily go up and down.",
+ "description-histogram": "A histogram samples observations (usually things like request durations or response sizes) and counts them in configurable buckets.",
+ "description-native-histogram": "Native histograms are different from classic Prometheus histograms in a number of ways: Native histogram bucket boundaries are calculated by a formula that depends on the scale (resolution) of the native histogram, and are not user defined.",
+ "description-no-type": "These metrics have no defined type in the metadata.",
+ "description-summary": "A summary samples observations (usually things like request durations and response sizes) and can calculate configurable quantiles over a sliding time window.",
+ "description-unknown": "These metrics have been given the type unknown in the metadata.",
+ "label-counter": "Counter",
+ "label-gauge": "Gauge",
+ "label-histogram": "Histogram",
+ "label-native-histogram": "Native histogram",
+ "label-no-type": "No type",
+ "label-summary": "Summary",
+ "label-unknown": "Unknown"
+ },
"handle-function": {
"text": {
"query-parsing-is-ambiguous": "Query parsing is ambiguous."
@@ -368,6 +391,9 @@
"results-table": {
"content-descriptive-type": "When creating a {{descriptiveType}}, Prometheus exposes multiple series with the type counter. ",
"description": "Description",
+ "message-expand-label-filters": "There are no metrics found. Try to expand your label filters.",
+ "message-expand-search": "There are no metrics found. Try to expand your search and filters.",
+ "message-no-metrics-found": "There are no metrics found in the data source.",
"name": "Name",
"select": "Select",
"type": "Type"
diff --git a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/AdditionalSettings.tsx b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/AdditionalSettings.tsx
index a60a070b5b4..4ce04117dd9 100644
--- a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/AdditionalSettings.tsx
+++ b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/AdditionalSettings.tsx
@@ -7,7 +7,7 @@ import { Icon, Switch, Tooltip, useTheme2 } from '@grafana/ui';
import { metricsModaltestIds } from './shared/testIds';
import { AdditionalSettingsProps } from './shared/types';
-import { placeholders } from './state/helpers';
+import { getPlaceholders } from './state/helpers';
export function AdditionalSettings(props: AdditionalSettingsProps) {
const { state, onChangeFullMetaSearch, onChangeIncludeNullMetadata, onChangeDisableTextWrap, onChangeUseBackend } =
@@ -16,6 +16,8 @@ export function AdditionalSettings(props: AdditionalSettingsProps) {
const theme = useTheme2();
const styles = getStyles(theme);
+ const placeholders = getPlaceholders();
+
return (
<>
diff --git a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/MetricsModal.tsx b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/MetricsModal.tsx
index 3d2c500e795..f598cf0951d 100644
--- a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/MetricsModal.tsx
+++ b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/MetricsModal.tsx
@@ -32,8 +32,8 @@ import {
calculatePageList,
calculateResultsPerPage,
displayedMetrics,
- placeholders,
- promTypes,
+ getPlaceholders,
+ getPromTypes,
setMetrics,
tracking,
} from './state/helpers';
@@ -55,6 +55,8 @@ export const MetricsModal = (props: MetricsModalProps) => {
const theme = useTheme2();
const styles = getStyles(theme, state.disableTextWrap);
+ const placeholders = getPlaceholders();
+ const promTypes = getPromTypes();
/**
* loads metrics and metadata on opening modal and switching off useBackend
@@ -88,7 +90,7 @@ export const MetricsModal = (props: MetricsModalProps) => {
const typeOptions: SelectableValue[] = promTypes.map((t: PromFilterOption) => {
return {
value: t.value,
- label: t.value,
+ label: t.label,
description: t.description,
};
});
diff --git a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/ResultsTable.tsx b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/ResultsTable.tsx
index 47c990c091f..1e179d336ee 100644
--- a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/ResultsTable.tsx
+++ b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/ResultsTable.tsx
@@ -4,7 +4,7 @@ import { ReactElement } from 'react';
import Highlighter from 'react-highlight-words';
import { GrafanaTheme2 } from '@grafana/data';
-import { Trans } from '@grafana/i18n';
+import { t, Trans } from '@grafana/i18n';
import { Button, Icon, Tooltip, useTheme2 } from '@grafana/ui';
import { docsTip } from '../../../configuration/shared/utils';
@@ -106,15 +106,24 @@ export function ResultsTable(props: ResultsTableProps) {
let message;
if (!state.fuzzySearchQuery) {
- message = 'There are no metrics found in the data source.';
+ message = t(
+ 'grafana-prometheus.querybuilder.results-table.message-no-metrics-found',
+ 'There are no metrics found in the data source.'
+ );
}
if (query.labels.length > 0) {
- message = 'There are no metrics found. Try to expand your label filters.';
+ message = t(
+ 'grafana-prometheus.querybuilder.results-table.message-expand-label-filters',
+ 'There are no metrics found. Try to expand your label filters.'
+ );
}
if (state.fuzzySearchQuery || state.selectedTypes.length > 0) {
- message = 'There are no metrics found. Try to expand your search and filters.';
+ message = t(
+ 'grafana-prometheus.querybuilder.results-table.message-expand-search',
+ 'There are no metrics found. Try to expand your search and filters.'
+ );
}
return (
diff --git a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/state/helpers.ts b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/state/helpers.ts
index 66fa83e2624..88d5f9e27bf 100644
--- a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/state/helpers.ts
+++ b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/state/helpers.ts
@@ -1,6 +1,7 @@
// Core Grafana history https://github.com/grafana/grafana/blob/v11.0.0-preview/public/app/plugins/datasource/prometheus/querybuilder/components/metrics-modal/state/helpers.ts
import { AnyAction } from '@reduxjs/toolkit';
+import { t } from '@grafana/i18n';
import { reportInteraction } from '@grafana/runtime';
import { PrometheusDatasource } from '../../../../datasource';
@@ -232,45 +233,75 @@ export function tracking(event: string, state?: MetricsModalState | null, metric
}
}
-export const promTypes: PromFilterOption[] = [
+export const getPromTypes: () => PromFilterOption[] = () => [
{
value: 'counter',
- description:
- 'A cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on restart.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-counter', 'Counter'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-counter',
+ 'A cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on restart.'
+ ),
},
{
value: 'gauge',
- description: 'A metric that represents a single numerical value that can arbitrarily go up and down.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-gauge', 'Gauge'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-gauge',
+ 'A metric that represents a single numerical value that can arbitrarily go up and down.'
+ ),
},
{
value: 'histogram',
- description:
- 'A histogram samples observations (usually things like request durations or response sizes) and counts them in configurable buckets.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-histogram', 'Histogram'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-histogram',
+ 'A histogram samples observations (usually things like request durations or response sizes) and counts them in configurable buckets.'
+ ),
},
{
value: 'native histogram',
- description:
- 'Native histograms are different from classic Prometheus histograms in a number of ways: Native histogram bucket boundaries are calculated by a formula that depends on the scale (resolution) of the native histogram, and are not user defined.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-native-histogram', 'Native histogram'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-native-histogram',
+ 'Native histograms are different from classic Prometheus histograms in a number of ways: Native histogram bucket boundaries are calculated by a formula that depends on the scale (resolution) of the native histogram, and are not user defined.'
+ ),
},
{
value: 'summary',
- description:
- 'A summary samples observations (usually things like request durations and response sizes) and can calculate configurable quantiles over a sliding time window.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-summary', 'Summary'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-summary',
+ 'A summary samples observations (usually things like request durations and response sizes) and can calculate configurable quantiles over a sliding time window.'
+ ),
},
{
value: 'unknown',
- description: 'These metrics have been given the type unknown in the metadata.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-unknown', 'Unknown'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-unknown',
+ 'These metrics have been given the type unknown in the metadata.'
+ ),
},
{
value: 'no type',
- description: 'These metrics have no defined type in the metadata.',
+ label: t('grafana-prometheus.querybuilder.get-prom-types.label-no-type', 'No type'),
+ description: t(
+ 'grafana-prometheus.querybuilder.get-prom-types.description-no-type',
+ 'These metrics have no defined type in the metadata.'
+ ),
},
];
-export const placeholders = {
- browse: 'Search metrics by name',
- metadataSearchSwitch: 'Include description in search',
- type: 'Filter by type',
- includeNullMetadata: 'Include results with no metadata',
- setUseBackend: 'Enable regex search',
-};
+export const getPlaceholders = () => ({
+ browse: t('grafana-prometheus.querybuilder.get-placeholders.browse', 'Search metrics by name'),
+ metadataSearchSwitch: t(
+ 'grafana-prometheus.querybuilder.get-placeholders.metadata-search-switch',
+ 'Include description in search'
+ ),
+ type: t('grafana-prometheus.querybuilder.get-placeholders.type', 'Filter by type'),
+ includeNullMetadata: t(
+ 'grafana-prometheus.querybuilder.get-placeholders.include-null-metadata',
+ 'Include results with no metadata'
+ ),
+ setUseBackend: t('grafana-prometheus.querybuilder.get-placeholders.set-use-backend', 'Enable regex search'),
+});
diff --git a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/types.ts b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/types.ts
index 233f3765e8a..88d39441eb3 100644
--- a/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/types.ts
+++ b/packages/grafana-prometheus/src/querybuilder/components/metrics-modal/types.ts
@@ -9,6 +9,7 @@ export type MetricData = {
export type PromFilterOption = {
value: string;
+ label: string;
description: string;
};
diff --git a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx
index 808e5245ae0..7bcdbb6852a 100644
--- a/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx
+++ b/packages/grafana-ui/src/components/TagsInput/TagsInput.tsx
@@ -3,7 +3,7 @@ import { useCallback, useState, forwardRef } from 'react';
import * as React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
-import { Trans } from '@grafana/i18n';
+import { t, Trans } from '@grafana/i18n';
import { useStyles2, useTheme2 } from '../../themes/ThemeContext';
import { Button } from '../Button/Button';
@@ -32,7 +32,7 @@ export interface Props {
export const TagsInput = forwardRef
(
(
{
- placeholder = 'New tag (enter key to add)',
+ placeholder: placeholderProp,
tags = [],
onChange,
width,
@@ -45,6 +45,7 @@ export const TagsInput = forwardRef(
},
ref
) => {
+ const placeholder = placeholderProp ?? t('grafana-ui.tags-input.placeholder-new-tag', 'New tag (enter key to add)');
const [newTagName, setNewTagName] = useState('');
const styles = useStyles2(getStyles);
const theme = useTheme2();
diff --git a/public/app/features/annotations/components/AnnotationResultMapper.tsx b/public/app/features/annotations/components/AnnotationResultMapper.tsx
index 475659c7620..b572ab13e40 100644
--- a/public/app/features/annotations/components/AnnotationResultMapper.tsx
+++ b/public/app/features/annotations/components/AnnotationResultMapper.tsx
@@ -13,7 +13,7 @@ import {
import { Trans, t } from '@grafana/i18n';
import { Select, Tooltip, Icon } from '@grafana/ui';
-import { annotationEventNames, AnnotationFieldInfo } from '../standardAnnotationSupport';
+import { getAnnotationEventNames, AnnotationFieldInfo } from '../standardAnnotationSupport';
import { AnnotationQueryResponse } from '../types';
// const valueOptions: Array> = [
@@ -204,7 +204,7 @@ export class AnnotationFieldMapper extends PureComponent {
- {annotationEventNames.map((row) => {
+ {getAnnotationEventNames().map((row) => {
return this.renderRow(row, mappings[row.key] || {}, first);
})}
diff --git a/public/app/features/annotations/standardAnnotationSupport.ts b/public/app/features/annotations/standardAnnotationSupport.ts
index a2caca1d583..90d28715c7f 100644
--- a/public/app/features/annotations/standardAnnotationSupport.ts
+++ b/public/app/features/annotations/standardAnnotationSupport.ts
@@ -17,6 +17,7 @@ import {
KeyValue,
standardTransformers,
} from '@grafana/data';
+import { t } from '@grafana/i18n';
import { config } from 'app/core/config';
export const standardAnnotationSupport: AnnotationSupport = {
@@ -97,22 +98,44 @@ export interface AnnotationFieldInfo {
}
// These fields get added to the standard UI
-export const annotationEventNames: AnnotationFieldInfo[] = [
+export const getAnnotationEventNames: () => AnnotationFieldInfo[] = () => [
{
key: 'time',
field: (frame: DataFrame) => frame.fields.find((f) => f.type === FieldType.time),
- placeholder: 'time, or the first time field',
+ placeholder: t(
+ 'annotations.get-annotation-event-names.placeholder.time-or-the-first-field',
+ '{{defaultField}}, or the first time field',
+ { defaultField: 'time' }
+ ),
+ },
+ {
+ key: 'timeEnd',
+ // label: 'end time',
+ help: t(
+ 'annotations.get-annotation-event-names.help.annotation-treated-as-range',
+ 'When this field is defined, the annotation will be treated as a range'
+ ),
},
- { key: 'timeEnd', label: 'end time', help: 'When this field is defined, the annotation will be treated as a range' },
{
key: 'title',
},
{
key: 'text',
field: (frame: DataFrame) => frame.fields.find((f) => f.type === FieldType.string),
- placeholder: 'text, or the first text field',
+ placeholder: t(
+ 'annotations.get-annotation-event-names.placeholder.text-or-the-first-field',
+ '{{defaultField}}, or the first text field',
+ { defaultField: 'text' }
+ ),
+ },
+ {
+ key: 'tags',
+ split: ',',
+ help: t(
+ 'annotations.get-annotation-event-names.help.results-split-on-comma',
+ 'The results will be split on comma (,)'
+ ),
},
- { key: 'tags', split: ',', help: 'The results will be split on comma (,)' },
{
key: 'id',
},
@@ -134,7 +157,7 @@ export const publicDashboardEventNames: AnnotationFieldInfo[] = [
// pipeline, but include fields that should not be exposed generally
const alertEventAndAnnotationFields: AnnotationFieldInfo[] = [
...(config.publicDashboardAccessToken ? publicDashboardEventNames : []),
- ...annotationEventNames,
+ ...getAnnotationEventNames(),
{ key: 'userId' },
{ key: 'login' },
{ key: 'email' },
diff --git a/public/app/features/dashboard-scene/saving/SaveDashboardAsForm.tsx b/public/app/features/dashboard-scene/saving/SaveDashboardAsForm.tsx
index 9c2f783c49e..00001fac1f8 100644
--- a/public/app/features/dashboard-scene/saving/SaveDashboardAsForm.tsx
+++ b/public/app/features/dashboard-scene/saving/SaveDashboardAsForm.tsx
@@ -118,7 +118,10 @@ export function SaveDashboardAsForm({ dashboard, changeInfo }: Props) {