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 845a8a5a369..5de8bc8d245 100644 --- a/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json +++ b/packages/grafana-prometheus/src/locales/en-US/grafana-prometheus.json @@ -170,8 +170,8 @@ "label-query-overlap-window": "Query overlap window", "label-query-timeout": "Query timeout", "label-scrape-interval": "Scrape interval", - "label-use-series-endpoint": "Use series endpoint", "label-series-limit": "Series limit", + "label-use-series-endpoint": "Use series endpoint", "more-info": "For more information on configuring prometheus type and version in data sources, see the <2>provisioning documentation.", "placeholder-example-maxsourceresolutionmtimeout": "Example: {{example}}", "title-interval-behaviour": "Interval behaviour", @@ -191,8 +191,8 @@ "tooltip-query-overlap-window": "Set a duration like {{example1}} or {{example2}} or {{example3}}. Default of {{default}}. This duration will be added to the duration of each incremental request.", "tooltip-query-timeout": "Set the Prometheus query timeout.", "tooltip-scrape-interval": "This interval is how frequently Prometheus scrapes targets. Set this to the typical scrape and evaluation interval configured in your Prometheus config file. If you set this to a greater value than your Prometheus config file interval, Grafana will evaluate the data according to this interval and you will see less data points. Defaults to {{default}}.", - "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.", - "tooltip-series-limit": "The limit applies to all resources (metrics, labels, and values) for both endpoints (series and labels). Leave the field empty to use the default limit (40000). Set to 0 to disable the limit and fetch everything — this may cause performance issues. Default limit is 40000." + "tooltip-series-limit": "The limit applies to all resources (metrics, labels, and values) for both endpoints (series and labels). Leave the field empty to use the default limit (40000). Set to 0 to disable the limit and fetch everything — this may cause performance issues. Default limit is 40000.", + "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." } }, "querybuilder": { diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx index be53d365b5c..7451ed5c2ce 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNameByRegexMatcherEditor.tsx @@ -28,11 +28,14 @@ export const FieldNameByRegexMatcherEditor = memo>((props }); FieldNameByRegexMatcherEditor.displayName = 'FieldNameByRegexMatcherEditor'; -export const fieldNameByRegexMatcherItem: FieldMatcherUIRegistryItem = { +export const getFieldNameByRegexMatcherItem: () => FieldMatcherUIRegistryItem = () => ({ id: FieldMatcherID.byRegexp, component: FieldNameByRegexMatcherEditor, matcher: fieldMatchers.get(FieldMatcherID.byRegexp), - name: 'Fields with name matching regex', - description: 'Set properties for fields with names matching a regex', + name: t('grafana-ui.matchers-ui.name-field-name-by-regex-matcher', 'Fields with name matching regex'), + description: t( + 'grafana-ui.matchers-ui.description-field-name-by-regex-matcher', + 'Set properties for fields with names matching a regex' + ), optionsToLabel: (options) => options, -}; +}); diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx index 109b2eb5392..1c0dccae69e 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNameMatcherEditor.tsx @@ -1,6 +1,7 @@ import { memo, useCallback } from 'react'; import { FieldMatcherID, fieldMatchers, SelectableValue } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { Select } from '../Select/Select'; @@ -27,11 +28,11 @@ export const FieldNameMatcherEditor = memo>((props) => { }); FieldNameMatcherEditor.displayName = 'FieldNameMatcherEditor'; -export const fieldNameMatcherItem: FieldMatcherUIRegistryItem = { +export const getFieldNameMatcherItem: () => FieldMatcherUIRegistryItem = () => ({ id: FieldMatcherID.byName, component: FieldNameMatcherEditor, matcher: fieldMatchers.get(FieldMatcherID.byName), - name: 'Fields with name', - description: 'Set properties for a specific field', + name: t('grafana-ui.matchers-ui.name-fields-with-name', 'Fields with name'), + description: t('grafana-ui.matchers-ui.description-fields-with-name', 'Set properties for a specific field'), optionsToLabel: (options) => options, -}; +}); diff --git a/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx b/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx index 2dda1448627..63240a9b0eb 100644 --- a/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx +++ b/packages/grafana-ui/src/components/MatchersUI/FieldNamePicker.tsx @@ -1,6 +1,7 @@ import { useCallback } from 'react'; import { FieldNamePickerConfigSettings, SelectableValue, StandardEditorProps } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { Select } from '../Select/Select'; @@ -29,7 +30,9 @@ export const FieldNamePicker = ({ value, onChange, context, item }: Props) => { <> { const { thresholds } = this.props; const { steps } = this.state; + const modes: Array> = [ + { + value: ThresholdsMode.Absolute, + label: t('dimensions.thresholds-editor.modes.label.absolute', 'Absolute'), + description: t( + 'dimensions.thresholds-editor.modes.description.thresholds-based-absolute-values', + 'Pick thresholds based on the absolute values' + ), + }, + { + value: ThresholdsMode.Percentage, + label: t('dimensions.thresholds-editor.modes.label.percentage', 'Percentage'), + description: t( + 'dimensions.thresholds-editor.modes.description.threshold-based-percent-between-minmax', + 'Pick threshold based on the percent between min/max' + ), + }, + ]; + return ( {(theme) => { diff --git a/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx b/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx index 6a970660510..7282ddba598 100644 --- a/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx +++ b/public/app/features/transformers/calculateHeatmap/editor/AxisEditor.tsx @@ -10,32 +10,41 @@ import { SuggestionsInput } from '../../suggestionsInput/SuggestionsInput'; import { numberOrVariableValidator } from '../../utils'; import { convertDurationToMilliseconds } from '../utils'; -const modeOptions: Array> = [ - { - label: 'Size', - value: HeatmapCalculationMode.Size, - description: 'Split the buckets based on size', - }, - { - label: 'Count', - value: HeatmapCalculationMode.Count, - description: 'Split the buckets based on count', - }, -]; - -const logModeOptions: Array> = [ - { - label: 'Split', - value: HeatmapCalculationMode.Size, - description: 'Split the buckets based on size', - }, -]; - export const AxisEditor = ({ value, onChange, item }: StandardEditorProps) => { const [isInvalid, setInvalid] = useState(false); const modeSwitchCounter = useRef(0); + const modeOptions: Array> = [ + { + label: t('transformers.axis-editor.mode-options.label.size', 'Size'), + value: HeatmapCalculationMode.Size, + description: t( + 'transformers.axis-editor.mode-options.description.split-the-buckets-based-on-size', + 'Split the buckets based on size' + ), + }, + { + label: t('transformers.axis-editor.mode-options.label.count', 'Count'), + value: HeatmapCalculationMode.Count, + description: t( + 'transformers.axis-editor.mode-options.description.split-the-buckets-based-on-count', + 'Split the buckets based on count' + ), + }, + ]; + + const logModeOptions: Array> = [ + { + label: t('transformers.axis-editor.log-mode-options.label.split', 'Split'), + value: HeatmapCalculationMode.Size, + description: t( + 'transformers.axis-editor.log-mode-options.description.split-the-buckets-based-on-size', + 'Split the buckets based on size' + ), + }, + ]; + const allowInterval = item.settings?.allowInterval ?? false; const onValueChange = ({ mode, scale, value = '' }: HeatmapCalculationBucketConfig) => { diff --git a/public/app/features/transformers/calculateHeatmap/editor/helper.ts b/public/app/features/transformers/calculateHeatmap/editor/helper.ts index e33c70210e8..f58e2857d00 100644 --- a/public/app/features/transformers/calculateHeatmap/editor/helper.ts +++ b/public/app/features/transformers/calculateHeatmap/editor/helper.ts @@ -1,4 +1,5 @@ import { PanelOptionsEditorBuilder } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { ScaleDistribution, HeatmapCalculationMode, HeatmapCalculationOptions } from '@grafana/schema'; import { ScaleDistributionEditor } from '@grafana/ui/internal'; @@ -13,7 +14,7 @@ export function addHeatmapCalculationOptions( builder.addCustomEditor({ id: 'xBuckets', path: `${prefix}xBuckets`, - name: 'X Bucket', + name: t('transformers.calculate-heatmap.add-heatmap-calculation-options.name-x-bucket', 'X Bucket'), editor: AxisEditor, category, defaultValue: { @@ -27,7 +28,7 @@ export function addHeatmapCalculationOptions( builder.addCustomEditor({ id: 'yBuckets', path: `${prefix}yBuckets`, - name: 'Y Bucket', + name: t('transformers.calculate-heatmap.add-heatmap-calculation-options.name-y-bucket', 'Y Bucket'), editor: AxisEditor, category, defaultValue: { @@ -38,7 +39,7 @@ export function addHeatmapCalculationOptions( builder.addCustomEditor({ id: 'yBuckets-scale', path: `${prefix}yBuckets.scale`, - name: 'Y Bucket scale', + name: t('transformers.calculate-heatmap.add-heatmap-calculation-options.name-y-bucket-scale', 'Y Bucket scale'), category, editor: ScaleDistributionEditor, defaultValue: { type: ScaleDistribution.Linear }, diff --git a/public/app/plugins/panel/alertlist/module.tsx b/public/app/plugins/panel/alertlist/module.tsx index c176845cf1e..9e8df21539e 100644 --- a/public/app/plugins/panel/alertlist/module.tsx +++ b/public/app/plugins/panel/alertlist/module.tsx @@ -1,5 +1,5 @@ import { DataSourceInstanceSettings, PanelPlugin } from '@grafana/data'; -import { Trans } from '@grafana/i18n'; +import { t, Trans } from '@grafana/i18n'; import { Button, Stack } from '@grafana/ui'; import { NestedFolderPicker } from 'app/core/components/NestedFolderPicker/NestedFolderPicker'; import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker'; @@ -14,41 +14,50 @@ import { UnifiedAlertListPanel } from './UnifiedAlertList'; import { GroupMode, SortOrder, UnifiedAlertListOptions, ViewMode } from './types'; const unifiedAlertList = new PanelPlugin(UnifiedAlertListPanel).setPanelOptions((builder) => { + const optionsCategory = [t('alertlist.category-options', 'Options')]; + const filterCategory = [t('alertlist.category-filter', 'Filter')]; + const alertStateCategory = [t('alertlist.category-alert-state-filter', 'Alert state filter')]; builder .addRadio({ path: 'viewMode', - name: 'View mode', - description: 'Toggle between list view and stat view', + name: t('alertlist.name-view-mode', 'View mode'), + description: t('alertlist.description-view-mode', 'Toggle between list view and stat view'), defaultValue: ViewMode.List, settings: { options: [ - { label: 'List', value: ViewMode.List }, - { label: 'Stat', value: ViewMode.Stat }, + { label: t('alertlist.view-mode-options.label-list', 'List'), value: ViewMode.List }, + { label: t('alertlist.view-mode-options.label-stat', 'Stat'), value: ViewMode.Stat }, ], }, - category: ['Options'], + category: optionsCategory, }) .addRadio({ path: 'groupMode', - name: 'Group mode', - description: 'How alert instances should be grouped', + name: t('alertlist.name-group-mode', 'Group mode'), + description: t('alertlist.description-group-mode', 'How alert instances should be grouped'), defaultValue: GroupMode.Default, settings: { options: [ - { value: GroupMode.Default, label: 'Default grouping' }, - { value: GroupMode.Custom, label: 'Custom grouping' }, + { + value: GroupMode.Default, + label: t('alertlist.group-mode-options.label-default-grouping', 'Default grouping'), + }, + { + value: GroupMode.Custom, + label: t('alertlist.group-mode-options.label-custom-grouping', 'Custom grouping'), + }, ], }, - category: ['Options'], + category: optionsCategory, }) .addCustomEditor({ path: 'groupBy', - name: 'Group by', - description: 'Filter alerts using label querying', + name: t('alertlist.name-group-by', 'Group by'), + description: t('alertlist.description-group-by', 'Filter alerts using label querying'), id: 'groupBy', defaultValue: [], showIf: (options) => options.groupMode === GroupMode.Custom, - category: ['Options'], + category: optionsCategory, editor: (props) => { return ( (UnifiedAlertLi }, }) .addNumberInput({ - name: 'Max items', + name: t('alertlist.name-max-items', 'Max items'), path: 'maxItems', - description: 'Maximum alerts to display', + description: t('alertlist.description-max-items', 'Maximum alerts to display'), defaultValue: 20, - category: ['Options'], + category: optionsCategory, }) .addSelect({ - name: 'Sort order', + name: t('alertlist.name-sort-order', 'Sort order'), path: 'sortOrder', - description: 'Sort order of alerts and alert instances', + description: t('alertlist.description-sort-order', 'Sort order of alerts and alert instances'), settings: { options: [ - { label: 'Alphabetical (asc)', value: SortOrder.AlphaAsc }, - { label: 'Alphabetical (desc)', value: SortOrder.AlphaDesc }, - { label: 'Importance', value: SortOrder.Importance }, - { label: 'Time (asc)', value: SortOrder.TimeAsc }, - { label: 'Time (desc)', value: SortOrder.TimeDesc }, + { + label: t('alertlist.sort-order-options.label-alphabetical-asc', 'Alphabetical (asc)'), + value: SortOrder.AlphaAsc, + }, + { + label: t('alertlist.sort-order-options.label-alphabetical-desc', 'Alphabetical (desc)'), + value: SortOrder.AlphaDesc, + }, + { label: t('alertlist.sort-order-options.label-importance', 'Importance'), value: SortOrder.Importance }, + { label: t('alertlist.sort-order-options.label-time-asc', 'Time (asc)'), value: SortOrder.TimeAsc }, + { label: t('alertlist.sort-order-options.label-time-desc', 'Time (desc)'), value: SortOrder.TimeDesc }, ], }, defaultValue: SortOrder.AlphaAsc, - category: ['Options'], + category: optionsCategory, }) .addBooleanSwitch({ path: 'dashboardAlerts', - name: 'Alerts linked to this dashboard', - description: 'Only show alerts linked to this dashboard', + name: t('alertlist.name-alerts-linked-to-dashboard', 'Alerts linked to this dashboard'), + description: t('alertlist.descriptino-alerts-linked-to-dashboard', 'Only show alerts linked to this dashboard'), defaultValue: false, - category: ['Options'], + category: optionsCategory, }) .addTextInput({ path: 'alertName', - name: 'Alert name', - description: 'Filter for alerts containing this text', + name: t('alertlist.name-alert-name', 'Alert name'), + description: t('alertlist.description-alert-name', 'Filter for alerts containing this text'), defaultValue: '', - category: ['Filter'], + category: filterCategory, }) .addTextInput({ path: 'alertInstanceLabelFilter', - name: 'Alert instance label', - description: 'Filter alert instances using label querying, ex: {severity="critical", instance=~"cluster-us-.+"}', + name: t('alertlist.name-alert-instance-label', 'Alert instance label'), + description: t( + 'alertlist.description-alert-instance-label', + 'Filter alert instances using label querying, ex: {severity="critical", instance=~"cluster-us-.+"}' + ), defaultValue: '', - category: ['Filter'], + category: filterCategory, }) .addCustomEditor({ path: 'datasource', - name: 'Datasource', - description: 'Filter from alert source', + name: t('alertlist.name-datasource', 'Datasource'), + description: t('alertlist.description-datasource', 'Filter from alert source'), id: 'datasource', defaultValue: null, editor: function RenderDatasourcePicker(props) { @@ -133,13 +151,16 @@ const unifiedAlertList = new PanelPlugin(UnifiedAlertLi ); }, - category: ['Filter'], + category: filterCategory, }) .addCustomEditor({ showIf: (options) => options.datasource === GRAFANA_DATASOURCE_NAME || !Boolean(options.datasource), path: 'folder', - name: 'Folder', - description: 'Filter for alerts in the selected folder (for Grafana-managed alert rules only)', + name: t('alertlist.name-folder', 'Folder'), + description: t( + 'alertlist.description-folder', + 'Filter for alerts in the selected folder (for Grafana-managed alert rules only)' + ), id: 'folder', defaultValue: null, editor: function RenderFolderPicker(props) { @@ -154,51 +175,53 @@ const unifiedAlertList = new PanelPlugin(UnifiedAlertLi /> ); }, - category: ['Filter'], + category: filterCategory, }) .addBooleanSwitch({ path: 'showInactiveAlerts', - name: 'Show alerts with 0 instances', - description: - 'Include alert rules which have 0 (zero) instances. Because these rules have no instances, they remain hidden if the Alert instance label filter is configured.', + name: t('alertlist.name-show-inactive-alerts', 'Show alerts with 0 instances'), + description: t( + 'alertlist.description-show-inactive-alerts', + 'Include alert rules which have 0 (zero) instances. Because these rules have no instances, they remain hidden if the Alert instance label filter is configured.' + ), defaultValue: false, - category: ['Filter'], + category: filterCategory, }) .addBooleanSwitch({ path: 'stateFilter.firing', - name: 'Alerting / Firing', + name: t('alertlist.name-firing', 'Alerting / Firing'), defaultValue: true, - category: ['Alert state filter'], + category: alertStateCategory, }) .addBooleanSwitch({ path: 'stateFilter.pending', - name: 'Pending', + name: t('alertlist.name-pending', 'Pending'), defaultValue: true, - category: ['Alert state filter'], + category: alertStateCategory, }) .addBooleanSwitch({ path: 'stateFilter.recovering', - name: 'Recovering', + name: t('alertlist.name-recovering', 'Recovering'), defaultValue: true, - category: ['Alert state filter'], + category: alertStateCategory, }) .addBooleanSwitch({ path: 'stateFilter.noData', - name: 'No Data', + name: t('alertlist.name-no-data', 'No Data'), defaultValue: false, - category: ['Alert state filter'], + category: alertStateCategory, }) .addBooleanSwitch({ path: 'stateFilter.normal', - name: 'Normal', + name: t('alertlist.name-normal', 'Normal'), defaultValue: false, - category: ['Alert state filter'], + category: alertStateCategory, }) .addBooleanSwitch({ path: 'stateFilter.error', - name: 'Error', + name: t('alertlist.name-error', 'Error'), defaultValue: true, - category: ['Alert state filter'], + category: alertStateCategory, }); }); diff --git a/public/app/plugins/panel/annolist/module.tsx b/public/app/plugins/panel/annolist/module.tsx index 2c402b7da94..512fb014928 100644 --- a/public/app/plugins/panel/annolist/module.tsx +++ b/public/app/plugins/panel/annolist/module.tsx @@ -1,4 +1,5 @@ import { PanelModel, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { TagsInput } from '@grafana/ui'; import { AnnoListPanel } from './AnnoListPanel'; @@ -6,88 +7,91 @@ import { defaultOptions, Options } from './panelcfg.gen'; export const plugin = new PanelPlugin(AnnoListPanel) .setPanelOptions((builder) => { + const category = [t('annolist.category-annotation-query', 'Annotation query')]; + const displayCategory = [t('annolist.category-display', 'Display')]; + const linkBehaviourCategory = [t('annolist.category-link-behaviour', 'Link behavior')]; builder .addRadio({ - category: ['Annotation query'], + category, path: 'onlyFromThisDashboard', - name: 'Query filter', + name: t('annolist.name-query-filter', 'Query filter'), defaultValue: defaultOptions.onlyFromThisDashboard, settings: { options: [ - { value: false, label: 'All dashboards' }, - { value: true, label: 'This dashboard' }, + { value: false, label: t('annolist.query-filter-options.label-all-dashboards', 'All dashboards') }, + { value: true, label: t('annolist.query-filter-options.label-this-dashboard', 'This dashboard') }, ], }, }) .addRadio({ - category: ['Annotation query'], + category, path: 'onlyInTimeRange', - name: 'Time range', + name: t('annolist.name-time-range', 'Time range'), defaultValue: defaultOptions.onlyInTimeRange, settings: { options: [ - { value: false, label: 'None' }, - { value: true, label: 'This dashboard' }, + { value: false, label: t('annolist.time-range-options.label-none', 'None') }, + { value: true, label: t('annolist.time-range-options.label-this-dashboard', 'This dashboard') }, ], }, }) .addCustomEditor({ - category: ['Annotation query'], + category, id: 'tags', path: 'tags', - name: 'Tags', - description: 'Match annotation tags', + name: t('annolist.name-tags', 'Tags'), + description: t('annolist.description-tags', 'Match annotation tags'), editor(props) { return ; }, }) .addNumberInput({ - category: ['Annotation query'], + category, path: 'limit', - name: 'Limit', + name: t('annolist.name-limit', 'Limit'), defaultValue: defaultOptions.limit, }) .addBooleanSwitch({ - category: ['Display'], + category: displayCategory, path: 'showUser', - name: 'Show user', + name: t('annolist.name-show-user', 'Show user'), defaultValue: defaultOptions.showUser, }) .addBooleanSwitch({ - category: ['Display'], + category: displayCategory, path: 'showTime', - name: 'Show time', + name: t('annolist.name-show-time', 'Show time'), defaultValue: defaultOptions.showTime, }) .addBooleanSwitch({ - category: ['Display'], + category: displayCategory, path: 'showTags', - name: 'Show tags', + name: t('annolist.name-show-tags', 'Show tags'), defaultValue: defaultOptions.showTags, }) .addRadio({ - category: ['Link behavior'], + category: linkBehaviourCategory, path: 'navigateToPanel', - name: 'Link target', + name: t('annolist.name-link-target', 'Link target'), defaultValue: defaultOptions.navigateToPanel, settings: { options: [ - { value: true, label: 'Panel' }, - { value: false, label: 'Dashboard' }, + { value: true, label: t('annolist.link-target-options.label-panel', 'Panel') }, + { value: false, label: t('annolist.link-target-options.label-dashboard', 'Dashboard') }, ], }, }) .addTextInput({ - category: ['Link behavior'], + category: linkBehaviourCategory, path: 'navigateBefore', - name: 'Time before', + name: t('annolist.name-time-before', 'Time before'), defaultValue: defaultOptions.navigateBefore, description: '', }) .addTextInput({ - category: ['Link behavior'], + category: linkBehaviourCategory, path: 'navigateAfter', - name: 'Time after', + name: t('annolist.name-time-after', 'Time after'), defaultValue: defaultOptions.navigateAfter, description: '', }); diff --git a/public/app/plugins/panel/barchart/TickSpacingEditor.tsx b/public/app/plugins/panel/barchart/TickSpacingEditor.tsx index 8fd048be082..da553368a0f 100644 --- a/public/app/plugins/panel/barchart/TickSpacingEditor.tsx +++ b/public/app/plugins/panel/barchart/TickSpacingEditor.tsx @@ -2,30 +2,35 @@ import { SelectableValue, StandardEditorProps } from '@grafana/data'; import { t } from '@grafana/i18n'; import { Checkbox, HorizontalGroup, RadioButtonGroup, Tooltip } from '@grafana/ui'; -const GAPS_OPTIONS: Array> = [ - { - label: 'None', - value: 0, - description: 'Show all tick marks', - }, - { - label: 'Small', - value: 100, - description: 'Require 100px spacing', - }, - { - label: 'Medium', - value: 200, - description: 'Require 200px spacing', - }, - { - label: 'Large', - value: 300, - description: 'Require 300px spacing', - }, -]; - export const TickSpacingEditor = (props: StandardEditorProps) => { + const GAPS_OPTIONS: Array> = [ + { + label: t('barchart.tick-spacing-editor.gaps-options.label-none', 'None'), + value: 0, + description: t('barchart.tick-spacing-editor.gaps-options.description-none', 'Show all tick marks'), + }, + { + label: t('barchart.tick-spacing-editor.gaps-options.label-small', 'Small'), + value: 100, + description: t('barchart.tick-spacing-editor.gaps-options.description-small', 'Require {{spacing}} spacing', { + spacing: '100px', + }), + }, + { + label: t('barchart.tick-spacing-editor.gaps-options.label-medium', 'Medium'), + value: 200, + description: t('barchart.tick-spacing-editor.gaps-options.description-medium', 'Require {{spacing}} spacing', { + spacing: '200px', + }), + }, + { + label: t('barchart.tick-spacing-editor.gaps-options.label-large', 'Large'), + value: 300, + description: t('barchart.tick-spacing-editor.gaps-options.description-large', 'Require {{spacing}} spacing', { + spacing: '300px', + }), + }, + ]; let value = props.value ?? 0; const isRTL = value < 0; if (isRTL) { diff --git a/public/app/plugins/panel/barchart/module.tsx b/public/app/plugins/panel/barchart/module.tsx index 11dfc45e823..34df5c40933 100644 --- a/public/app/plugins/panel/barchart/module.tsx +++ b/public/app/plugins/panel/barchart/module.tsx @@ -7,8 +7,9 @@ import { PanelPlugin, VizOrientation, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { GraphTransform, GraphThresholdsStyleMode, StackingMode, VisibilityMode } from '@grafana/schema'; -import { graphFieldOptions, commonOptionsBuilder } from '@grafana/ui'; +import { getGraphFieldOptions, commonOptionsBuilder } from '@grafana/ui'; import { optsWithHideZeros } from '@grafana/ui/internal'; import { ThresholdsStyleEditor } from '../timeseries/ThresholdsStyleEditor'; @@ -47,7 +48,7 @@ export const plugin = new PanelPlugin(BarChartPanel) builder .addSliderInput({ path: 'lineWidth', - name: 'Line width', + name: t('barchart.config.name-line-width', 'Line width'), defaultValue: cfg.lineWidth, settings: { min: 0, @@ -57,7 +58,7 @@ export const plugin = new PanelPlugin(BarChartPanel) }) .addSliderInput({ path: 'fillOpacity', - name: 'Fill opacity', + name: t('barchart.config.name-fill-opacity', 'Fill opacity'), defaultValue: cfg.fillOpacity, settings: { min: 0, @@ -67,28 +68,34 @@ export const plugin = new PanelPlugin(BarChartPanel) }) .addRadio({ path: 'gradientMode', - name: 'Gradient mode', - defaultValue: graphFieldOptions.fillGradient[0].value, + name: t('barchart.config.name-gradient-mode', 'Gradient mode'), + defaultValue: getGraphFieldOptions().fillGradient[0].value, settings: { - options: graphFieldOptions.fillGradient, + options: getGraphFieldOptions().fillGradient, }, }); builder.addSelect({ category: ['Graph styles'], - name: 'Transform', + name: t('barchart.config.name-transform', 'Transform'), path: 'transform', settings: { options: [ { - label: 'Constant', + label: t('barchart.config.transform-options.label-constant', 'Constant'), value: GraphTransform.Constant, - description: 'The first value will be shown as a constant line', + description: t( + 'barchart.config.transform-options.description-constant', + 'The first value will be shown as a constant line' + ), }, { - label: 'Negative Y', + label: t('barchart.config.transform-options.label-negative-y', 'Negative Y'), value: GraphTransform.NegativeY, - description: 'Flip the results to negative values on the y axis', + description: t( + 'barchart.config.transform-options.description-negative-y', + 'Flip the results to negative values on the y axis' + ), }, ], isClearable: true, @@ -99,11 +106,11 @@ export const plugin = new PanelPlugin(BarChartPanel) builder.addCustomEditor({ id: 'thresholdsStyle', path: 'thresholdsStyle', - name: 'Show thresholds', - category: ['Thresholds'], + name: t('barchart.config.name-show-thresholds', 'Show thresholds'), + category: [t('barchart.config.category-thresholds', 'Thresholds')], defaultValue: { mode: GraphThresholdsStyleMode.Off }, settings: { - options: graphFieldOptions.thresholdsDisplayModes, + options: getGraphFieldOptions().thresholdsDisplayModes, }, editor: ThresholdsStyleEditor, override: ThresholdsStyleEditor, @@ -119,26 +126,32 @@ export const plugin = new PanelPlugin(BarChartPanel) builder .addFieldNamePicker({ path: 'xField', - name: 'X Axis', + name: t('barchart.config.name-x-axis', 'X Axis'), settings: { - placeholderText: 'First string or time field', + placeholderText: t('barchart.config.placeholder-x-axis', 'First string or time field'), }, }) .addRadio({ path: 'orientation', - name: 'Orientation', + name: t('barchart.config.name-orientation', 'Orientation'), settings: { options: [ - { value: VizOrientation.Auto, label: 'Auto' }, - { value: VizOrientation.Horizontal, label: 'Horizontal' }, - { value: VizOrientation.Vertical, label: 'Vertical' }, + { value: VizOrientation.Auto, label: t('barchart.config.orientation-options.label-auto', 'Auto') }, + { + value: VizOrientation.Horizontal, + label: t('barchart.config.orientation-options.label-horizontal', 'Horizontal'), + }, + { + value: VizOrientation.Vertical, + label: t('barchart.config.orientation-options.label-line-vertical', 'Vertical'), + }, ], }, defaultValue: defaultOptions.orientation, }) .addSliderInput({ path: 'xTickLabelRotation', - name: 'Rotate x-axis tick labels', + name: t('barchart.config.name-rotate-x-labels', 'Rotate x-axis tick labels'), defaultValue: defaultOptions.xTickLabelRotation, settings: { min: -90, @@ -150,10 +163,13 @@ export const plugin = new PanelPlugin(BarChartPanel) }) .addNumberInput({ path: 'xTickLabelMaxLength', - name: 'X-axis tick label max length', - description: 'X-axis labels will be truncated to the length provided', + name: t('barchart.config.name-x-label-max-length', 'X-axis tick label max length'), + description: t( + 'barchart.config.description-x-label-max-length', + 'X-axis labels will be truncated to the length provided' + ), settings: { - placeholder: 'None', + placeholder: t('barchart.config.placeholder-x-label-max-length', 'None'), min: 0, }, showIf: (opts) => opts.xTickLabelRotation !== 0, @@ -161,33 +177,33 @@ export const plugin = new PanelPlugin(BarChartPanel) .addCustomEditor({ id: 'xTickLabelSpacing', path: 'xTickLabelSpacing', - name: 'X-axis labels minimum spacing', + name: t('barchart.config.name-x-label-min-spacing', 'X-axis labels minimum spacing'), defaultValue: defaultOptions.xTickLabelSpacing, editor: TickSpacingEditor, }) .addRadio({ path: 'showValue', - name: 'Show values', + name: t('barchart.config.name-show-values', 'Show values'), settings: { options: [ - { value: VisibilityMode.Auto, label: 'Auto' }, - { value: VisibilityMode.Always, label: 'Always' }, - { value: VisibilityMode.Never, label: 'Never' }, + { value: VisibilityMode.Auto, label: t('barchart.config.show-values-options.label-auto', 'Auto') }, + { value: VisibilityMode.Always, label: t('barchart.config.show-values-options.label-always', 'Always') }, + { value: VisibilityMode.Never, label: t('barchart.config.show-values-options.label-never', 'Never') }, ], }, defaultValue: defaultOptions.showValue, }) .addRadio({ path: 'stacking', - name: 'Stacking', + name: t('barchart.config.name-stacking', 'Stacking'), settings: { - options: graphFieldOptions.stacking, + options: getGraphFieldOptions().stacking, }, defaultValue: defaultOptions.stacking, }) .addSliderInput({ path: 'groupWidth', - name: 'Group width', + name: t('barchart.config.name-group-width', 'Group width'), defaultValue: defaultOptions.groupWidth, settings: { min: 0, @@ -203,7 +219,7 @@ export const plugin = new PanelPlugin(BarChartPanel) }) .addSliderInput({ path: 'barWidth', - name: 'Bar width', + name: t('barchart.config.name-bar-width', 'Bar width'), defaultValue: defaultOptions.barWidth, settings: { min: 0, @@ -213,7 +229,7 @@ export const plugin = new PanelPlugin(BarChartPanel) }) .addSliderInput({ path: 'barRadius', - name: 'Bar radius', + name: t('barchart.config.name-bar-radius', 'Bar radius'), defaultValue: defaultOptions.barRadius, settings: { min: 0, @@ -223,15 +239,18 @@ export const plugin = new PanelPlugin(BarChartPanel) }) .addBooleanSwitch({ path: 'fullHighlight', - name: 'Highlight full area on hover', + name: t('barchart.config.name-full-highlight', 'Highlight full area on hover'), defaultValue: defaultOptions.fullHighlight, showIf: (c) => c.stacking === StackingMode.None, }); builder.addFieldNamePicker({ path: 'colorByField', - name: 'Color by field', - description: 'Use the color value for a sibling field to color each bar value.', + name: t('barchart.config.name-color-by-field', 'Color by field'), + description: t( + 'barchart.config.description-color-by-field', + 'Use the color value for a sibling field to color each bar value.' + ), }); commonOptionsBuilder.addTooltipOptions(builder, false, false, optsWithHideZeros); diff --git a/public/app/plugins/panel/bargauge/module.tsx b/public/app/plugins/panel/bargauge/module.tsx index cf2605b7121..c04444de809 100644 --- a/public/app/plugins/panel/bargauge/module.tsx +++ b/public/app/plugins/panel/bargauge/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin, VizOrientation } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { BarGaugeDisplayMode, BarGaugeNamePlacement, BarGaugeSizing, BarGaugeValueMode } from '@grafana/schema'; import { commonOptionsBuilder, sharedSingleStatPanelChangedHandler } from '@grafana/ui'; @@ -12,45 +13,58 @@ import { BarGaugeSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(BarGaugePanel) .useFieldConfig() .setPanelOptions((builder) => { + const category = [t('bargauge.category-bar-gauge', 'Bar gauge')]; addStandardDataReduceOptions(builder); - addOrientationOption(builder); + addOrientationOption(builder, category); commonOptionsBuilder.addLegendOptions(builder, true, false); commonOptionsBuilder.addTextSizeOptions(builder); builder .addRadio({ path: 'displayMode', - name: 'Display mode', + name: t('bargauge.name-display-mode', 'Display mode'), + category, settings: { options: [ - { value: BarGaugeDisplayMode.Gradient, label: 'Gradient' }, - { value: BarGaugeDisplayMode.Lcd, label: 'Retro LCD' }, - { value: BarGaugeDisplayMode.Basic, label: 'Basic' }, + { + value: BarGaugeDisplayMode.Gradient, + label: t('bargauge.display-mode-options.label-gradient', 'Gradient'), + }, + { value: BarGaugeDisplayMode.Lcd, label: t('bargauge.display-mode-options.label-retro', 'Retro LCD') }, + { value: BarGaugeDisplayMode.Basic, label: t('bargauge.display-mode-options.label-basic', 'Basic') }, ], }, defaultValue: defaultOptions.displayMode, }) .addRadio({ path: 'valueMode', - name: 'Value display', + name: t('bargauge.name-value-display', 'Value display'), + category, settings: { options: [ - { value: BarGaugeValueMode.Color, label: 'Value color' }, - { value: BarGaugeValueMode.Text, label: 'Text color' }, - { value: BarGaugeValueMode.Hidden, label: 'Hidden' }, + { + value: BarGaugeValueMode.Color, + label: t('bargauge.value-display-options.label-value-color', 'Value color'), + }, + { + value: BarGaugeValueMode.Text, + label: t('bargauge.value-display-options.label-text-color', 'Text color'), + }, + { value: BarGaugeValueMode.Hidden, label: t('bargauge.value-display-options.label-hidden', 'Hidden') }, ], }, defaultValue: defaultOptions.valueMode, }) .addRadio({ path: 'namePlacement', - name: 'Name placement', + name: t('bargauge.name-name-placement', 'Name placement'), + category, settings: { options: [ - { value: BarGaugeNamePlacement.Auto, label: 'Auto' }, - { value: BarGaugeNamePlacement.Top, label: 'Top' }, - { value: BarGaugeNamePlacement.Left, label: 'Left' }, - { value: BarGaugeNamePlacement.Hidden, label: 'Hidden' }, + { value: BarGaugeNamePlacement.Auto, label: t('bargauge.name-placement-options.label-auto', 'Auto') }, + { value: BarGaugeNamePlacement.Top, label: t('bargauge.name-placement-options.label-top', 'Top') }, + { value: BarGaugeNamePlacement.Left, label: t('bargauge.name-placement-options.label-left', 'Left') }, + { value: BarGaugeNamePlacement.Hidden, label: t('bargauge.name-placement-options.label-hidden', 'Hidden') }, ], }, defaultValue: defaultOptions.namePlacement, @@ -58,11 +72,12 @@ export const plugin = new PanelPlugin(BarGaugePanel) }) .addRadio({ path: 'namePlacement', - name: 'Name placement', + name: t('bargauge.name-name-placement', 'Name placement'), + category, settings: { options: [ - { value: BarGaugeNamePlacement.Auto, label: 'Auto' }, - { value: BarGaugeNamePlacement.Hidden, label: 'Hidden' }, + { value: BarGaugeNamePlacement.Auto, label: t('bargauge.name-placement-options.label-auto', 'Auto') }, + { value: BarGaugeNamePlacement.Hidden, label: t('bargauge.name-placement-options.label-hidden', 'Hidden') }, ], }, defaultValue: defaultOptions.namePlacement, @@ -70,26 +85,29 @@ export const plugin = new PanelPlugin(BarGaugePanel) }) .addBooleanSwitch({ path: 'showUnfilled', - name: 'Show unfilled area', - description: 'When enabled renders the unfilled region as gray', + name: t('bargauge.name-show-unfilled-area', 'Show unfilled area'), + category, + description: t('bargauge.description-show-unfilled-area', 'When enabled renders the unfilled region as gray'), defaultValue: defaultOptions.showUnfilled, showIf: (options) => options.displayMode !== 'lcd', }) .addRadio({ path: 'sizing', - name: 'Bar size', + name: t('bargauge.name-bar-size', 'Bar size'), + category, settings: { options: [ - { value: BarGaugeSizing.Auto, label: 'Auto' }, - { value: BarGaugeSizing.Manual, label: 'Manual' }, + { value: BarGaugeSizing.Auto, label: t('bargauge.bar-size-options.label-auto', 'Auto') }, + { value: BarGaugeSizing.Manual, label: t('bargauge.bar-size-options.label-manual', 'Manual') }, ], }, defaultValue: defaultOptions.sizing, }) .addSliderInput({ path: 'minVizWidth', - name: 'Min width', - description: 'Minimum column width (vertical orientation)', + name: t('bargauge.name-min-width', 'Min width'), + category, + description: t('bargauge.description-min-width', 'Minimum column width (vertical orientation)'), defaultValue: defaultOptions.minVizWidth, settings: { min: 0, @@ -102,8 +120,9 @@ export const plugin = new PanelPlugin(BarGaugePanel) }) .addSliderInput({ path: 'minVizHeight', - name: 'Min height', - description: 'Minimum row height (horizontal orientation)', + name: t('bargauge.name-min-height', 'Min height'), + category, + description: t('bargauge.description-min-height', 'Minimum row height (horizontal orientation)'), defaultValue: defaultOptions.minVizHeight, settings: { min: 0, @@ -116,8 +135,9 @@ export const plugin = new PanelPlugin(BarGaugePanel) }) .addSliderInput({ path: 'maxVizHeight', - name: 'Max height', - description: 'Maximum row height (horizontal orientation)', + name: t('bargauge.name-max-height', 'Max height'), + category, + description: t('bargauge.description-max-height', 'Maximum row height (horizontal orientation)'), defaultValue: defaultOptions.maxVizHeight, settings: { min: 0, diff --git a/public/app/plugins/panel/candlestick/fields.ts b/public/app/plugins/panel/candlestick/fields.ts index 5019dfe06d0..29ce56ec079 100644 --- a/public/app/plugins/panel/candlestick/fields.ts +++ b/public/app/plugins/panel/candlestick/fields.ts @@ -8,6 +8,7 @@ import { TimeRange, } from '@grafana/data'; import { maybeSortFrame } from '@grafana/data/internal'; +import { t } from '@grafana/i18n'; import { findField } from 'app/features/dimensions'; import { prepareGraphableFields } from '../timeseries/utils'; @@ -28,37 +29,39 @@ export interface FieldPickerInfo { description: string; } -export const candlestickFieldsInfo: Record = { - open: { - key: 'open', - name: 'Open', - defaults: ['open', 'o'], - description: 'Value at the start of the period', - }, - high: { - key: 'high', - name: 'High', - defaults: ['high', 'h', 'max'], - description: 'Maximum value within the period', - }, - low: { - key: 'low', - name: 'Low', - defaults: ['low', 'l', 'min'], - description: 'Minimum value within the period', - }, - close: { - key: 'close', - name: 'Close', - defaults: ['close', 'c'], - description: 'Value at the end of the period', - }, - volume: { - key: 'volume', - name: 'Volume', - defaults: ['volume', 'v'], - description: 'Sample count within the period', - }, +export const getCandlestickFieldsInfo: () => Record = () => { + return { + open: { + key: 'open', + name: t('candlestick.name-open', 'Open'), + defaults: ['open', 'o'], + description: t('candlestick.description-open', 'Value at the start of the period'), + }, + high: { + key: 'high', + name: t('candlestick.name-high', 'High'), + defaults: ['high', 'h', 'max'], + description: t('candlestick.description-high', 'Maximum value within the period'), + }, + low: { + key: 'low', + name: t('candlestick.name-low', 'Low'), + defaults: ['low', 'l', 'min'], + description: t('candlestick.description-low', 'Minimum value within the period'), + }, + close: { + key: 'close', + name: t('candlestick.name-close', 'Close'), + defaults: ['close', 'c'], + description: t('candlestick.description-close', 'Value at the end of the period'), + }, + volume: { + key: 'volume', + name: t('candlestick.name-volume', 'Volume'), + defaults: ['volume', 'v'], + description: t('candlestick.description-volume', 'Sample count within the period'), + }, + }; }; export interface CandlestickData { @@ -103,6 +106,7 @@ export function prepareCandlestickFields( if (!series?.length) { return null; } + const candlestickFieldsInfo = getCandlestickFieldsInfo(); // All fields const fieldMap = options.fields ?? {}; diff --git a/public/app/plugins/panel/candlestick/module.tsx b/public/app/plugins/panel/candlestick/module.tsx index 596d288199b..8a57e4801c1 100644 --- a/public/app/plugins/panel/candlestick/module.tsx +++ b/public/app/plugins/panel/candlestick/module.tsx @@ -1,11 +1,5 @@ -import { - Field, - FieldType, - getFieldDisplayName, - PanelOptionsEditorBuilder, - PanelPlugin, - SelectableValue, -} from '@grafana/data'; +import { Field, FieldType, getFieldDisplayName, PanelOptionsEditorBuilder, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { config } from '@grafana/runtime'; import { GraphFieldConfig } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; @@ -13,32 +7,17 @@ import { commonOptionsBuilder } from '@grafana/ui'; import { defaultGraphConfig, getGraphFieldConfig } from '../timeseries/config'; import { CandlestickPanel } from './CandlestickPanel'; -import { CandlestickData, candlestickFieldsInfo, FieldPickerInfo, prepareCandlestickFields } from './fields'; +import { CandlestickData, getCandlestickFieldsInfo, FieldPickerInfo, prepareCandlestickFields } from './fields'; import { CandlestickSuggestionsSupplier } from './suggestions'; import { defaultCandlestickColors, defaultOptions, Options, VizDisplayMode, ColorStrategy, CandleStyle } from './types'; -const modeOptions: Array> = [ - { label: 'Candles', value: VizDisplayMode.Candles }, - { label: 'Volume', value: VizDisplayMode.Volume }, - { label: 'Both', value: VizDisplayMode.CandlesVolume }, -]; - -const candleStyles: Array> = [ - { label: 'Candles', value: CandleStyle.Candles }, - { label: 'OHLC Bars', value: CandleStyle.OHLCBars }, -]; - -const colorStrategies: Array> = [ - { label: 'Since Open', value: ColorStrategy.OpenClose }, - { label: 'Since Prior Close', value: ColorStrategy.CloseClose }, -]; - const numericFieldFilter = (f: Field) => f.type === FieldType.number; function addFieldPicker( builder: PanelOptionsEditorBuilder, info: FieldPickerInfo, - data: CandlestickData | null + data: CandlestickData | null, + category?: string[] ) { let placeholderText = 'Auto '; @@ -60,6 +39,7 @@ function addFieldPicker( path: `fields.${info.key}`, name: info.name, description: info.description, + category, settings: { filter: numericFieldFilter, placeholderText, @@ -70,68 +50,95 @@ function addFieldPicker( export const plugin = new PanelPlugin(CandlestickPanel) .useFieldConfig(getGraphFieldConfig(defaultGraphConfig)) .setPanelOptions((builder, context) => { + const category = [t('candlestick.category-candlestick', 'Candlestick')]; const opts = context.options ?? defaultOptions; const info = prepareCandlestickFields(context.data, opts, config.theme2); builder .addRadio({ path: 'mode', - name: 'Mode', + name: t('candlestick.name-mode', 'Mode'), + category, description: '', defaultValue: defaultOptions.mode, settings: { - options: modeOptions, + options: [ + { label: t('candlestick.mode-options.label-candles', 'Candles'), value: VizDisplayMode.Candles }, + { label: t('candlestick.mode-options.label-volume', 'Volume'), value: VizDisplayMode.Volume }, + { label: t('candlestick.mode-options.label-both', 'Both'), value: VizDisplayMode.CandlesVolume }, + ], }, }) .addRadio({ path: 'candleStyle', - name: 'Candle style', + name: t('candlestick.name-candle-style', 'Candle style'), + category, description: '', defaultValue: defaultOptions.candleStyle, settings: { - options: candleStyles, + options: [ + { label: t('candlestick.candle-style-options.label-candles', 'Candles'), value: CandleStyle.Candles }, + { label: t('candlestick.candle-style-options.label-ohlc-bars', 'OHLC Bars'), value: CandleStyle.OHLCBars }, + ], }, showIf: (opts) => opts.mode !== VizDisplayMode.Volume, }) .addRadio({ path: 'colorStrategy', - name: 'Color strategy', + name: t('candlestick.name-color-strategy', 'Color strategy'), + category, description: '', defaultValue: defaultOptions.colorStrategy, settings: { - options: colorStrategies, + options: [ + { + label: t('candlestick.color-strategy-options.label-since-open', 'Since Open'), + value: ColorStrategy.OpenClose, + }, + { + label: t('candlestick.color-strategy-options.label-since-prior-close', 'Since Prior Close'), + value: ColorStrategy.CloseClose, + }, + ], }, }) .addColorPicker({ path: 'colors.up', - name: 'Up color', + name: t('candlestick.name-up-color', 'Up color'), + category, defaultValue: defaultCandlestickColors.up, }) .addColorPicker({ path: 'colors.down', - name: 'Down color', + name: t('candlestick.name-down-color', 'Down color'), + category, defaultValue: defaultCandlestickColors.down, }); - addFieldPicker(builder, candlestickFieldsInfo.open, info); + const candlestickFieldsInfo = getCandlestickFieldsInfo(); + addFieldPicker(builder, candlestickFieldsInfo.open, info, category); if (opts.mode !== VizDisplayMode.Volume) { - addFieldPicker(builder, candlestickFieldsInfo.high, info); - addFieldPicker(builder, candlestickFieldsInfo.low, info); + addFieldPicker(builder, candlestickFieldsInfo.high, info, category); + addFieldPicker(builder, candlestickFieldsInfo.low, info, category); } - addFieldPicker(builder, candlestickFieldsInfo.close, info); + addFieldPicker(builder, candlestickFieldsInfo.close, info, category); if (opts.mode !== VizDisplayMode.Candles) { - addFieldPicker(builder, candlestickFieldsInfo.volume, info); + addFieldPicker(builder, candlestickFieldsInfo.volume, info, category); } builder.addRadio({ path: 'includeAllFields', - name: 'Additional fields', - description: 'Use standard timeseries options to configure any fields not mapped above', + name: t('candlestick.name-additional-fields', 'Additional fields'), + category, + description: t( + 'candlestick.description-additional-fields', + 'Use standard timeseries options to configure any fields not mapped above' + ), defaultValue: defaultOptions.includeAllFields, settings: { options: [ - { label: 'Ignore', value: false }, - { label: 'Include', value: true }, + { label: t('candlestick.additional-fields-options.label-ignore', 'Ignore'), value: false }, + { label: t('candlestick.additional-fields-options.label-include', 'Include'), value: true }, ], }, }); diff --git a/public/app/plugins/panel/dashlist/module.tsx b/public/app/plugins/panel/dashlist/module.tsx index a4033ebc7dc..1af3300e104 100644 --- a/public/app/plugins/panel/dashlist/module.tsx +++ b/public/app/plugins/panel/dashlist/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { TagsInput } from '@grafana/ui'; import { FolderPicker } from 'app/core/components/Select/FolderPicker'; @@ -8,55 +9,66 @@ import { defaultOptions, Options } from './panelcfg.gen'; export const plugin = new PanelPlugin(DashList) .setPanelOptions((builder) => { + const category = [t('dashlist.category-dashboard-list', 'Dashboard list')]; builder .addBooleanSwitch({ path: 'keepTime', - name: 'Include current time range', + name: t('dashlist.name-include-current-time-range', 'Include current time range'), + category, defaultValue: defaultOptions.keepTime, }) .addBooleanSwitch({ path: 'includeVars', - name: 'Include current template variable values', + name: t('dashlist.name-include-current-template-variables', 'Include current template variable values'), + category, defaultValue: defaultOptions.includeVars, }) .addBooleanSwitch({ path: 'showStarred', - name: 'Starred', + name: t('dashlist.name-starred', 'Starred'), + category, defaultValue: defaultOptions.showStarred, }) .addBooleanSwitch({ path: 'showRecentlyViewed', - name: 'Recently viewed', + name: t('dashlist.name-recently-viewed', 'Recently viewed'), + category, defaultValue: defaultOptions.showRecentlyViewed, }) .addBooleanSwitch({ path: 'showSearch', - name: 'Search', + name: t('dashlist.name-search', 'Search'), + category, defaultValue: defaultOptions.showSearch, }) .addBooleanSwitch({ path: 'showHeadings', - name: 'Show headings', + name: t('dashlist.name-show-headings', 'Show headings'), + category, defaultValue: defaultOptions.showHeadings, }) .addBooleanSwitch({ path: 'showFolderNames', - name: 'Show folder names', + name: t('dashlist.name-show-folder-names', 'Show folder names'), + category, defaultValue: defaultOptions.showFolderNames, }) .addNumberInput({ path: 'maxItems', - name: 'Max items', + name: t('dashlist.name-max-items', 'Max items'), + category, defaultValue: defaultOptions.maxItems, }) .addTextInput({ path: 'query', - name: 'Query', + name: t('dashlist.name-query', 'Query'), + category, defaultValue: defaultOptions.query, }) .addCustomEditor({ path: 'folderUID', - name: 'Folder', + name: t('dashlist.name-folder', 'Folder'), + category, id: 'folderUID', defaultValue: undefined, editor: function RenderFolderPicker({ value, onChange }) { @@ -68,7 +80,8 @@ export const plugin = new PanelPlugin(DashList) .addCustomEditor({ id: 'tags', path: 'tags', - name: 'Tags', + name: t('dashlist.name-tags', 'Tags'), + category, description: '', defaultValue: defaultOptions.tags, editor(props) { diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index d2dbf9369fc..0dbedaaaaa4 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { BarGaugeSizing, VizOrientation } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; @@ -14,61 +15,67 @@ export const plugin = new PanelPlugin(GaugePanel) useCustomConfig: (builder) => { builder.addNumberInput({ path: 'neutral', - name: 'Neutral', - description: 'Leave empty to use Min as neutral point', - category: ['Gauge'], + name: t('gauge.name-neutral', 'Neutral'), + description: t('gauge.description-neutral', 'Leave empty to use Min as neutral point'), + category: [t('gauge.category-gauge', 'Gauge')], settings: { - placeholder: 'auto', + placeholder: t('gauge.placeholder-neutral', 'auto'), }, }); }, }) .setPanelOptions((builder) => { + const category = [t('gauge.category-gauge', 'Gauge')]; addStandardDataReduceOptions(builder); - addOrientationOption(builder); + addOrientationOption(builder, category); builder .addBooleanSwitch({ path: 'showThresholdLabels', - name: 'Show threshold labels', - description: 'Render the threshold values around the gauge bar', + name: t('gauge.name-show-threshold-labels', 'Show threshold labels'), + description: t('gauge.description-show-threshold-labels', 'Render the threshold values around the gauge bar'), + category, defaultValue: defaultOptions.showThresholdLabels, }) .addBooleanSwitch({ path: 'showThresholdMarkers', - name: 'Show threshold markers', - description: 'Renders the thresholds as an outer bar', + name: t('gauge.name-show-threshold-markers', 'Show threshold markers'), + description: t('gauge.description-show-threshold-markers', 'Renders the thresholds as an outer bar'), + category, defaultValue: defaultOptions.showThresholdMarkers, }) .addRadio({ path: 'sizing', - name: 'Gauge size', + name: t('gauge.name-gauge-size', 'Gauge size'), settings: { options: [ - { value: BarGaugeSizing.Auto, label: 'Auto' }, - { value: BarGaugeSizing.Manual, label: 'Manual' }, + { value: BarGaugeSizing.Auto, label: t('gauge.gauge-size-options.label-auto', 'Auto') }, + { value: BarGaugeSizing.Manual, label: t('gauge.gauge-size-options.label-manual', 'Manual') }, ], }, + category, defaultValue: defaultOptions.sizing, showIf: (options: Options) => options.orientation !== VizOrientation.Auto, }) .addSliderInput({ path: 'minVizWidth', - name: 'Min width', - description: 'Minimum column width (vertical orientation)', + name: t('gauge.name-min-width', 'Min width'), + description: t('gauge.description-min-width', 'Minimum column width (vertical orientation)'), defaultValue: defaultOptions.minVizWidth, settings: { min: 0, max: 600, step: 1, }, + category, showIf: (options: Options) => options.sizing === BarGaugeSizing.Manual && options.orientation === VizOrientation.Vertical, }) .addSliderInput({ path: 'minVizHeight', - name: 'Min height', - description: 'Minimum row height (horizontal orientation)', + name: t('gauge.name-min-height', 'Min height'), + description: t('gauge.description-min-height', 'Minimum row height (horizontal orientation)'), defaultValue: defaultOptions.minVizHeight, + category, settings: { min: 0, max: 600, diff --git a/public/app/plugins/panel/heatmap/module.tsx b/public/app/plugins/panel/heatmap/module.tsx index 915f2b947ec..6375f7e012b 100644 --- a/public/app/plugins/panel/heatmap/module.tsx +++ b/public/app/plugins/panel/heatmap/module.tsx @@ -1,4 +1,5 @@ import { DataFrame, FieldConfigProperty, FieldType, identityOverrideProcessor, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { config } from '@grafana/runtime'; import { AxisPlacement, @@ -31,11 +32,12 @@ export const plugin = new PanelPlugin(HeatmapPanel) }, }, useCustomConfig: (builder) => { + const category = [t('heatmap.category-heatmap', 'Heatmap')]; builder.addCustomEditor({ id: 'scaleDistribution', path: 'scaleDistribution', - name: 'Y axis scale', - category: ['Heatmap'], + name: t('heatmap.name-y-axis-scale', 'Y axis scale'), + category, editor: ScaleDistributionEditor, override: ScaleDistributionEditor, defaultValue: { type: ScaleDistribution.Linear }, @@ -68,17 +70,17 @@ export const plugin = new PanelPlugin(HeatmapPanel) } catch {} } - let category = ['Heatmap']; + let category = [t('heatmap.category-heatmap', 'Heatmap')]; builder.addRadio({ path: 'calculate', - name: 'Calculate from data', + name: t('heatmap.name-calculate-from-data', 'Calculate from data'), defaultValue: defaultOptions.calculate, category, settings: { options: [ - { label: 'Yes', value: true }, - { label: 'No', value: false }, + { label: t('heatmap.calculate-from-data-options.label-yes', 'Yes'), value: true }, + { label: t('heatmap.calculate-from-data-options.label-no', 'No'), value: false }, ], }, }); @@ -87,26 +89,26 @@ export const plugin = new PanelPlugin(HeatmapPanel) addHeatmapCalculationOptions('calculation.', builder, opts.calculation, category); } - category = ['Y Axis']; + category = [t('heatmap.category-y-axis', 'Y Axis')]; builder .addRadio({ path: 'yAxis.axisPlacement', - name: 'Placement', + name: t('heatmap.name-placement', 'Placement'), defaultValue: defaultOptions.yAxis.axisPlacement ?? AxisPlacement.Left, category, settings: { options: [ - { label: 'Left', value: AxisPlacement.Left }, - { label: 'Right', value: AxisPlacement.Right }, - { label: 'Hidden', value: AxisPlacement.Hidden }, + { label: t('heatmap.placement-options.label-left', 'Left'), value: AxisPlacement.Left }, + { label: t('heatmap.placement-options.label-right', 'Right'), value: AxisPlacement.Right }, + { label: t('heatmap.placement-options.label-hidden', 'Hidden'), value: AxisPlacement.Hidden }, ], }, }) .addUnitPicker({ category, path: 'yAxis.unit', - name: 'Unit', + name: t('heatmap.name-unit', 'Unit'), defaultValue: undefined, settings: { isClearable: true, @@ -115,9 +117,9 @@ export const plugin = new PanelPlugin(HeatmapPanel) .addNumberInput({ category, path: 'yAxis.decimals', - name: 'Decimals', + name: t('heatmap.name-decimals', 'Decimals'), settings: { - placeholder: 'Auto', + placeholder: t('heatmap.placeholder-decimals', 'Auto'), }, }); @@ -126,17 +128,17 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder .addNumberInput({ path: 'yAxis.min', - name: 'Min value', + name: t('heatmap.name-min-value', 'Min value'), settings: { - placeholder: 'Auto', + placeholder: t('heatmap.placeholder-min-value', 'Auto'), }, category, }) .addTextInput({ path: 'yAxis.max', - name: 'Max value', + name: t('heatmap.name-max-value', 'Max value'), settings: { - placeholder: 'Auto', + placeholder: t('heatmap.placeholder-max-value', 'Auto'), }, category, }); @@ -145,20 +147,20 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder .addNumberInput({ path: 'yAxis.axisWidth', - name: 'Axis width', + name: t('heatmap.name-axis-width', 'Axis width'), defaultValue: defaultOptions.yAxis.axisWidth, settings: { - placeholder: 'Auto', + placeholder: t('heatmap.placeholder-axis-width', 'Auto'), min: 5, // smaller should just be hidden }, category, }) .addTextInput({ path: 'yAxis.axisLabel', - name: 'Axis label', + name: t('heatmap.name-axis-label', 'Axis label'), defaultValue: defaultOptions.yAxis.axisLabel, settings: { - placeholder: 'Auto', + placeholder: t('heatmap.placeholder-axis-label', 'Auto'), }, category, }); @@ -166,44 +168,44 @@ export const plugin = new PanelPlugin(HeatmapPanel) if (!opts.calculate) { builder.addRadio({ path: 'rowsFrame.layout', - name: 'Tick alignment', + name: t('heatmap.name-tick-alignment', 'Tick alignment'), defaultValue: defaultOptions.rowsFrame?.layout ?? HeatmapCellLayout.auto, category, settings: { options: [ - { label: 'Auto', value: HeatmapCellLayout.auto }, - { label: 'Top (LE)', value: HeatmapCellLayout.le }, - { label: 'Middle', value: HeatmapCellLayout.unknown }, - { label: 'Bottom (GE)', value: HeatmapCellLayout.ge }, + { label: t('heatmap.tick-alignment-options.label-auto', 'Auto'), value: HeatmapCellLayout.auto }, + { label: t('heatmap.tick-alignment-options.label-top', 'Top (LE)'), value: HeatmapCellLayout.le }, + { label: t('heatmap.tick-alignment-options.label-middle', 'Middle'), value: HeatmapCellLayout.unknown }, + { label: t('heatmap.tick-alignment-options.label-bottom', 'Bottom (GE)'), value: HeatmapCellLayout.ge }, ], }, }); } builder.addBooleanSwitch({ path: 'yAxis.reverse', - name: 'Reverse', + name: t('heatmap.name-reverse', 'Reverse'), defaultValue: defaultOptions.yAxis.reverse === true, category, }); - category = ['Colors']; + category = [t('heatmap.category-colors', 'Colors')]; builder.addRadio({ path: `color.mode`, - name: 'Mode', + name: t('heatmap.name-mode', 'Mode'), defaultValue: defaultOptions.color.mode, category, settings: { options: [ - { label: 'Scheme', value: HeatmapColorMode.Scheme }, - { label: 'Opacity', value: HeatmapColorMode.Opacity }, + { label: t('heatmap.mode-options.label-scheme', 'Scheme'), value: HeatmapColorMode.Scheme }, + { label: t('heatmap.mode-options.label-opacity', 'Opacity'), value: HeatmapColorMode.Opacity }, ], }, }); builder.addColorPicker({ path: `color.fill`, - name: 'Color', + name: t('heatmap.name-color', 'Color'), defaultValue: defaultOptions.color.fill, category, showIf: (opts) => opts.color.mode === HeatmapColorMode.Opacity, @@ -211,13 +213,13 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder.addRadio({ path: `color.scale`, - name: 'Scale', + name: t('heatmap.name-scale', 'Scale'), defaultValue: defaultOptions.color.scale, category, settings: { options: [ - { label: 'Exponential', value: HeatmapColorScale.Exponential }, - { label: 'Linear', value: HeatmapColorScale.Linear }, + { label: t('heatmap.scale-options.label-exponential', 'Exponential'), value: HeatmapColorScale.Exponential }, + { label: t('heatmap.scale-options.label-linear', 'Linear'), value: HeatmapColorScale.Linear }, ], }, showIf: (opts) => opts.color.mode === HeatmapColorMode.Opacity, @@ -225,7 +227,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder.addSliderInput({ path: 'color.exponent', - name: 'Exponent', + name: t('heatmap.name-exponent', 'Exponent'), defaultValue: defaultOptions.color.exponent, category, settings: { @@ -239,7 +241,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder.addSelect({ path: `color.scheme`, - name: 'Scheme', + name: t('heatmap.name-scheme', 'Scheme'), description: '', defaultValue: defaultOptions.color.scheme, category, @@ -256,7 +258,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder .addSliderInput({ path: 'color.steps', - name: 'Steps', + name: t('heatmap.name-steps', 'Steps'), defaultValue: defaultOptions.color.steps, category, settings: { @@ -267,7 +269,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) }) .addBooleanSwitch({ path: 'color.reverse', - name: 'Reverse', + name: t('heatmap.name-reverse', 'Reverse'), defaultValue: defaultOptions.color.reverse, category, }) @@ -289,32 +291,32 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder .addNumberInput({ path: 'color.min', - name: 'Start color scale from value', + name: t('heatmap.name-start-color-from-value', 'Start color scale from value'), defaultValue: defaultOptions.color.min, settings: { - placeholder: 'Auto (min)', + placeholder: t('heatmap.placeholder-start-color-from-value', 'Auto (min)'), }, category, }) .addNumberInput({ path: 'color.max', - name: 'End color scale at value', + name: t('heatmap.name-end-color-at-value', 'End color scale at value'), defaultValue: defaultOptions.color.max, settings: { - placeholder: 'Auto (max)', + placeholder: t('heatmap.placeholder-end-color-at-value', 'Auto (max)'), }, category, }); - category = ['Cell display']; + category = [t('heatmap.category-cell-display', 'Cell display')]; if (!opts.calculate) { builder.addTextInput({ path: 'rowsFrame.value', - name: 'Value name', + name: t('heatmap.name-value-name', 'Value name'), defaultValue: defaultOptions.rowsFrame?.value, settings: { - placeholder: 'Value', + placeholder: t('heatmap.placeholder-value-name', 'Value'), }, category, }); @@ -324,7 +326,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) .addUnitPicker({ category, path: 'cellValues.unit', - name: 'Unit', + name: t('heatmap.name-unit', 'Unit'), defaultValue: undefined, settings: { isClearable: true, @@ -333,9 +335,9 @@ export const plugin = new PanelPlugin(HeatmapPanel) .addNumberInput({ category, path: 'cellValues.decimals', - name: 'Decimals', + name: t('heatmap.name-decimals', 'Decimals'), settings: { - placeholder: 'Auto', + placeholder: t('heatmap.placeholder-decimals', 'Auto'), }, }); @@ -354,7 +356,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) // }, // }) .addSliderInput({ - name: 'Cell gap', + name: t('heatmap.name-cell-gap', 'Cell gap'), path: 'cellGap', defaultValue: defaultOptions.cellGap, category, @@ -365,19 +367,19 @@ export const plugin = new PanelPlugin(HeatmapPanel) }) .addNumberInput({ path: 'filterValues.le', - name: 'Hide cells with values <=', + name: t('heatmap.name-hide-cells-lt', 'Hide cells with values <='), defaultValue: defaultOptions.filterValues?.le, settings: { - placeholder: 'None', + placeholder: t('heatmap.placeholder-hide-cells-lt', 'None'), }, category, }) .addNumberInput({ path: 'filterValues.ge', - name: 'Hide cells with values >=', + name: t('heatmap.name-hide-cells-gt', 'Hide cells with values >='), defaultValue: defaultOptions.filterValues?.ge, settings: { - placeholder: 'None', + placeholder: t('heatmap.placeholder-hide-cells-gt', 'None'), }, category, }); @@ -392,25 +394,25 @@ export const plugin = new PanelPlugin(HeatmapPanel) // }, // }) - category = ['Tooltip']; + category = [t('heatmap.category-tooltip', 'Tooltip')]; builder.addRadio({ path: 'tooltip.mode', - name: 'Tooltip mode', + name: t('heatmap.name-tooltip-mode', 'Tooltip mode'), category, defaultValue: TooltipDisplayMode.Single, settings: { options: [ - { value: TooltipDisplayMode.Single, label: 'Single' }, - { value: TooltipDisplayMode.Multi, label: 'All' }, - { value: TooltipDisplayMode.None, label: 'Hidden' }, + { value: TooltipDisplayMode.Single, label: t('heatmap.tooltip-mode-options.label-single', 'Single') }, + { value: TooltipDisplayMode.Multi, label: t('heatmap.tooltip-mode-options.label-all', 'All') }, + { value: TooltipDisplayMode.None, label: t('heatmap.tooltip-mode-options.label-hidden', 'Hidden') }, ], }, }); builder.addBooleanSwitch({ path: 'tooltip.yHistogram', - name: 'Show histogram (Y axis)', + name: t('heatmap.name-show-histogram', 'Show histogram (Y axis)'), defaultValue: defaultOptions.tooltip.yHistogram, category, showIf: (opts) => opts.tooltip.mode === TooltipDisplayMode.Single, @@ -418,7 +420,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder.addBooleanSwitch({ path: 'tooltip.showColorScale', - name: 'Show color scale', + name: t('heatmap.name-show-color-scale', 'Show color scale'), defaultValue: defaultOptions.tooltip.showColorScale, category, showIf: (opts) => opts.tooltip.mode === TooltipDisplayMode.Single, @@ -426,7 +428,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder.addNumberInput({ path: 'tooltip.maxWidth', - name: 'Max width', + name: t('heatmap.name-max-width', 'Max width'), category, settings: { integer: true, @@ -436,7 +438,7 @@ export const plugin = new PanelPlugin(HeatmapPanel) builder.addNumberInput({ path: 'tooltip.maxHeight', - name: 'Max height', + name: t('heatmap.name-max-height', 'Max height'), category, defaultValue: undefined, settings: { @@ -447,18 +449,18 @@ export const plugin = new PanelPlugin(HeatmapPanel) annotations?.some((df) => df.meta?.custom?.resultType === 'exemplar'), }); - category = ['Legend']; + category = [t('heatmap.category-legend', 'Legend')]; builder.addBooleanSwitch({ path: 'legend.show', - name: 'Show legend', + name: t('heatmap.name-show-legend', 'Show legend'), defaultValue: defaultOptions.legend.show, category, }); - category = ['Exemplars']; + category = [t('heatmap.category-exemplars', 'Exemplars')]; builder.addColorPicker({ path: 'exemplars.color', - name: 'Color', + name: t('heatmap.name-color', 'Color'), defaultValue: defaultOptions.exemplars.color, category, showIf: (options: Options, data: DataFrame[] | undefined, annotations: DataFrame[] | undefined) => diff --git a/public/app/plugins/panel/histogram/module.tsx b/public/app/plugins/panel/histogram/module.tsx index 2584b008737..4ee2fa97a09 100644 --- a/public/app/plugins/panel/histogram/module.tsx +++ b/public/app/plugins/panel/histogram/module.tsx @@ -6,7 +6,8 @@ import { PanelPlugin, histogramFieldInfo, } from '@grafana/data'; -import { commonOptionsBuilder, graphFieldOptions } from '@grafana/ui'; +import { t } from '@grafana/i18n'; +import { commonOptionsBuilder, getGraphFieldOptions } from '@grafana/ui'; import { StackingEditor } from '@grafana/ui/internal'; import { HistogramPanel } from './HistogramPanel'; @@ -18,11 +19,13 @@ import { originalDataHasHistogram } from './utils'; export const plugin = new PanelPlugin(HistogramPanel) .setPanelChangeHandler(changeToHistogramPanelMigrationHandler) .setPanelOptions((builder) => { + const category = [t('histogram.category-histogram', 'Histogram')]; builder .addCustomEditor({ id: '__calc__', path: '__calc__', name: 'Values', + category, description: 'Showing frequencies that are calculated in the query', editor: () => null, // empty editor showIf: (opts, data) => originalDataHasHistogram(data), @@ -30,6 +33,7 @@ export const plugin = new PanelPlugin(HistogramPanel) .addNumberInput({ path: 'bucketCount', name: histogramFieldInfo.bucketCount.name, + category, description: histogramFieldInfo.bucketCount.description, settings: { placeholder: `Default: ${defaultOptions.bucketCount}`, @@ -40,6 +44,7 @@ export const plugin = new PanelPlugin(HistogramPanel) .addNumberInput({ path: 'bucketSize', name: histogramFieldInfo.bucketSize.name, + category, description: histogramFieldInfo.bucketSize.description, settings: { placeholder: 'Auto', @@ -51,6 +56,7 @@ export const plugin = new PanelPlugin(HistogramPanel) .addNumberInput({ path: 'bucketOffset', name: histogramFieldInfo.bucketOffset.name, + category, description: histogramFieldInfo.bucketOffset.description, settings: { placeholder: `Default: ${defaultOptions.bucketOffset}`, @@ -61,6 +67,7 @@ export const plugin = new PanelPlugin(HistogramPanel) .addBooleanSwitch({ path: 'combine', name: histogramFieldInfo.combine.name, + category, description: histogramFieldInfo.combine.description, defaultValue: defaultOptions.combine, showIf: (opts, data) => !originalDataHasHistogram(data), @@ -89,13 +96,15 @@ export const plugin = new PanelPlugin(HistogramPanel) }, useCustomConfig: (builder) => { const cfg = defaultFieldConfig; + const graphFieldOptions = getGraphFieldOptions(); + const category = [t('histogram.category-histogram', 'Histogram')]; builder .addCustomEditor({ id: 'stacking', path: 'stacking', - name: 'Stacking', - category: ['Histogram'], + name: t('histogram.name-stacking', 'Stacking'), + category, defaultValue: defaultHistogramConfig.stacking, editor: StackingEditor, override: StackingEditor, @@ -108,7 +117,8 @@ export const plugin = new PanelPlugin(HistogramPanel) }) .addSliderInput({ path: 'lineWidth', - name: 'Line width', + name: t('histogram.name-line-width', 'Line width'), + category, defaultValue: cfg.lineWidth, settings: { min: 0, @@ -118,7 +128,8 @@ export const plugin = new PanelPlugin(HistogramPanel) }) .addSliderInput({ path: 'fillOpacity', - name: 'Fill opacity', + name: t('histogram.name-fill-opacity', 'Fill opacity'), + category, defaultValue: cfg.fillOpacity, settings: { min: 0, @@ -128,7 +139,8 @@ export const plugin = new PanelPlugin(HistogramPanel) }) .addRadio({ path: 'gradientMode', - name: 'Gradient mode', + name: t('histogram.name-gradient-mode', 'Gradient mode'), + category, defaultValue: graphFieldOptions.fillGradient[0].value, settings: { options: graphFieldOptions.fillGradient, diff --git a/public/app/plugins/panel/logs-new/module.tsx b/public/app/plugins/panel/logs-new/module.tsx index d82afba84d1..04c6be4c61c 100644 --- a/public/app/plugins/panel/logs-new/module.tsx +++ b/public/app/plugins/panel/logs-new/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin, LogsSortOrder, LogsDedupStrategy, LogsDedupDescription } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { LogsPanel } from './LogsPanel'; import { Options } from './panelcfg.gen'; @@ -6,63 +7,84 @@ import { LogsPanelSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(LogsPanel) .setPanelOptions((builder) => { + const category = [t('logs-new.category-logs', 'Logs')]; builder .addBooleanSwitch({ path: 'showTime', - name: 'Time', + name: t('logs-new.name-time', 'Time'), + category, description: '', defaultValue: false, }) .addBooleanSwitch({ path: 'wrapLogMessage', - name: 'Wrap lines', + name: t('logs-new.name-wrap-lines', 'Wrap lines'), + category, description: '', defaultValue: false, }) .addBooleanSwitch({ path: 'syntaxHighlighting', - name: 'Enable syntax highlighting', - description: 'Use a predefined syntax coloring grammar to highlight relevant parts of the log lines', + name: t('logs-new.name-syntax-highlighting', 'Enable syntax highlighting'), + category, + description: t( + 'logs-new.description-syntax-highlighting', + 'Use a predefined syntax coloring grammar to highlight relevant parts of the log lines' + ), defaultValue: true, }) .addBooleanSwitch({ path: 'enableLogDetails', - name: 'Enable log details', + name: t('logs-new.name-enable-log-details', 'Enable log details'), + category, description: '', defaultValue: true, }) .addBooleanSwitch({ path: 'showControls', - name: 'Show controls', - description: 'Display controls to jump to the last or first log line, and filters by log level', + name: t('logs-new.name-show-controls', 'Show controls'), + category, + description: t( + 'logs-new.description-show-controls', + 'Display controls to jump to the last or first log line, and filters by log level' + ), defaultValue: false, }) .addBooleanSwitch({ path: 'enableInfiniteScrolling', - name: 'Enable infinite scrolling', - description: 'Experimental. Request more results by scrolling to the bottom of the logs list.', + name: t('logs-new.name-infinite-scrolling', 'Enable infinite scrolling'), + category, + description: t( + 'logs-new.description-infinite-scrolling', + 'Experimental. Request more results by scrolling to the bottom of the logs list.' + ), defaultValue: false, }) .addRadio({ path: 'dedupStrategy', - name: 'Deduplication', + name: t('logs-new.name-deduplication', 'Deduplication'), + category, description: '', settings: { options: [ - { value: LogsDedupStrategy.none, label: 'None', description: LogsDedupDescription[LogsDedupStrategy.none] }, + { + value: LogsDedupStrategy.none, + label: t('logs-new.deduplication-options.label-none', 'None'), + description: LogsDedupDescription[LogsDedupStrategy.none], + }, { value: LogsDedupStrategy.exact, - label: 'Exact', + label: t('logs-new.deduplication-options.label-exact', 'Exact'), description: LogsDedupDescription[LogsDedupStrategy.exact], }, { value: LogsDedupStrategy.numbers, - label: 'Numbers', + label: t('logs-new.deduplication-options.label-numbers', 'Numbers'), description: LogsDedupDescription[LogsDedupStrategy.numbers], }, { value: LogsDedupStrategy.signature, - label: 'Signature', + label: t('logs-new.deduplication-options.label-signature', 'Signature'), description: LogsDedupDescription[LogsDedupStrategy.signature], }, ], @@ -71,12 +93,13 @@ export const plugin = new PanelPlugin(LogsPanel) }) .addRadio({ path: 'sortOrder', - name: 'Order', + name: t('logs-new.name-order', 'Order'), + category, description: '', settings: { options: [ - { value: LogsSortOrder.Descending, label: 'Newest first' }, - { value: LogsSortOrder.Ascending, label: 'Oldest first' }, + { value: LogsSortOrder.Descending, label: t('logs-new.order-options.label-newest-first', 'Newest first') }, + { value: LogsSortOrder.Ascending, label: t('logs-new.order-options.label-oldest-first', 'Oldest first') }, ], }, defaultValue: LogsSortOrder.Descending, diff --git a/public/app/plugins/panel/logs/module.tsx b/public/app/plugins/panel/logs/module.tsx index dd034a995aa..0e339918d65 100644 --- a/public/app/plugins/panel/logs/module.tsx +++ b/public/app/plugins/panel/logs/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin, LogsSortOrder, LogsDedupStrategy, LogsDedupDescription } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { config } from '@grafana/runtime'; import { LogsPanel } from './LogsPanel'; @@ -7,9 +8,11 @@ import { LogsPanelSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(LogsPanel) .setPanelOptions((builder) => { + const category = [t('logs.category-logs', 'Logs')]; builder.addBooleanSwitch({ path: 'showTime', - name: 'Time', + name: t('logs.name-time', 'Time'), + category, description: '', defaultValue: false, }); @@ -18,13 +21,15 @@ export const plugin = new PanelPlugin(LogsPanel) builder .addBooleanSwitch({ path: 'showLabels', - name: 'Unique labels', + name: t('logs.name-unique-labels', 'Unique labels'), + category, description: '', defaultValue: false, }) .addBooleanSwitch({ path: 'showCommonLabels', - name: 'Common labels', + name: t('logs.name-common-labels', 'Common labels'), + category, description: '', defaultValue: false, }); @@ -32,7 +37,8 @@ export const plugin = new PanelPlugin(LogsPanel) builder.addBooleanSwitch({ path: 'wrapLogMessage', - name: 'Wrap lines', + name: t('logs.name-wrap-lines', 'Wrap lines'), + category, description: '', defaultValue: false, }); @@ -40,13 +46,18 @@ export const plugin = new PanelPlugin(LogsPanel) if (config.featureToggles.newLogsPanel) { builder.addBooleanSwitch({ path: 'syntaxHighlighting', - name: 'Enable syntax highlighting', - description: 'Use a predefined syntax coloring grammar to highlight relevant parts of the log lines', + name: t('logs.name-enable-syntax-highlighting', 'Enable syntax highlighting'), + category, + description: t( + 'logs.description-enable-syntax-highlighting', + 'Use a predefined syntax coloring grammar to highlight relevant parts of the log lines' + ), }); } else { builder.addBooleanSwitch({ path: 'prettifyLogMessage', - name: 'Prettify JSON', + name: t('logs.name-prettify-json', 'Prettify JSON'), + category, description: '', defaultValue: false, }); @@ -55,14 +66,19 @@ export const plugin = new PanelPlugin(LogsPanel) builder .addBooleanSwitch({ path: 'enableLogDetails', - name: 'Enable log details', + name: t('logs.name-enable-log-details', 'Enable log details'), + category, description: '', defaultValue: true, }) .addBooleanSwitch({ path: 'enableInfiniteScrolling', - name: 'Enable infinite scrolling', - description: 'Experimental. Request more results by scrolling to the bottom of the logs list.', + name: t('logs.name-enable-infinite-scrolling', 'Enable infinite scrolling'), + category, + description: t( + 'logs.description-enable-infinite-scrolling', + 'Experimental. Request more results by scrolling to the bottom of the logs list.' + ), defaultValue: false, }); @@ -70,20 +86,25 @@ export const plugin = new PanelPlugin(LogsPanel) builder .addBooleanSwitch({ path: 'showControls', - name: 'Show controls', - description: 'Display controls to jump to the last or first log line, and filters by log level', + name: t('logs.name-show-controls', 'Show controls'), + category, + description: t( + 'logs.description-show-controls', + 'Display controls to jump to the last or first log line, and filters by log level' + ), defaultValue: false, }) .addRadio({ path: 'fontSize', - name: 'Font size', + name: t('logs.name-font-size', 'Font size'), + category, description: '', settings: { options: [ - { value: 'default', label: 'Default' }, + { value: 'default', label: t('logs.font-size-options.label-default', 'Default') }, { value: 'small', - label: 'Small', + label: t('logs.font-size-options.label-small', 'Small'), }, ], }, @@ -93,24 +114,29 @@ export const plugin = new PanelPlugin(LogsPanel) builder .addRadio({ path: 'dedupStrategy', - name: 'Deduplication', + name: t('logs.name-deduplication', 'Deduplication'), + category, description: '', settings: { options: [ - { value: LogsDedupStrategy.none, label: 'None', description: LogsDedupDescription[LogsDedupStrategy.none] }, + { + value: LogsDedupStrategy.none, + label: t('logs.deduplication-options.label-none', 'None'), + description: LogsDedupDescription[LogsDedupStrategy.none], + }, { value: LogsDedupStrategy.exact, - label: 'Exact', + label: t('logs.deduplication-options.label-exact', 'Exact'), description: LogsDedupDescription[LogsDedupStrategy.exact], }, { value: LogsDedupStrategy.numbers, - label: 'Numbers', + label: t('logs.deduplication-options.label-numbers', 'Numbers'), description: LogsDedupDescription[LogsDedupStrategy.numbers], }, { value: LogsDedupStrategy.signature, - label: 'Signature', + label: t('logs.deduplication-options.label-signature', 'Signature'), description: LogsDedupDescription[LogsDedupStrategy.signature], }, ], @@ -119,12 +145,13 @@ export const plugin = new PanelPlugin(LogsPanel) }) .addRadio({ path: 'sortOrder', - name: 'Order', + name: t('logs.name-order', 'Order'), + category, description: '', settings: { options: [ - { value: LogsSortOrder.Descending, label: 'Newest first' }, - { value: LogsSortOrder.Ascending, label: 'Oldest first' }, + { value: LogsSortOrder.Descending, label: t('logs.order-options.label-newest-first', 'Newest first') }, + { value: LogsSortOrder.Ascending, label: t('logs.order-options.label-oldest-first', 'Oldest first') }, ], }, defaultValue: LogsSortOrder.Descending, diff --git a/public/app/plugins/panel/news/module.tsx b/public/app/plugins/panel/news/module.tsx index a072d45e34a..2976ca967b5 100644 --- a/public/app/plugins/panel/news/module.tsx +++ b/public/app/plugins/panel/news/module.tsx @@ -1,15 +1,18 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { NewsPanel } from './NewsPanel'; import { DEFAULT_FEED_URL } from './constants'; import { Options, defaultOptions } from './panelcfg.gen'; export const plugin = new PanelPlugin(NewsPanel).setPanelOptions((builder) => { + const category = [t('news.category-news', 'News')]; builder .addTextInput({ path: 'feedUrl', - name: 'URL', - description: 'Supports RSS and Atom feeds', + name: t('news.name-url', 'URL'), + category, + description: t('news.description-url', 'Supports RSS and Atom feeds'), settings: { placeholder: DEFAULT_FEED_URL, }, @@ -17,8 +20,12 @@ export const plugin = new PanelPlugin(NewsPanel).setPanelOptions((build }) .addBooleanSwitch({ path: 'showImage', - name: 'Show image', - description: 'Controls if the news item social (og:image) image is shown above text content', + name: t('news.name-show-image', 'Show image'), + category, + description: t( + 'news.description-show-image', + 'Controls if the news item social (og:image) image is shown above text content' + ), defaultValue: defaultOptions.showImage, }); }); diff --git a/public/app/plugins/panel/nodeGraph/module.tsx b/public/app/plugins/panel/nodeGraph/module.tsx index 4805a7be6e3..9bfa3456fc4 100644 --- a/public/app/plugins/panel/nodeGraph/module.tsx +++ b/public/app/plugins/panel/nodeGraph/module.tsx @@ -1,4 +1,5 @@ import { FieldConfigProperty, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { NodeGraphPanel } from './NodeGraphPanel'; import { ArcOptionsEditor } from './editor/ArcOptionsEditor'; @@ -10,43 +11,66 @@ export const plugin = new PanelPlugin(NodeGraphPanel) disableStandardOptions: Object.values(FieldConfigProperty).filter((v) => v !== FieldConfigProperty.Links), }) .setPanelOptions((builder, context) => { + const category = [t('node-graph.category-node-graph', 'Node graph')]; builder.addSelect({ - name: 'Zoom mode', + name: t('node-graph.name-zoom-mode', 'Zoom mode'), + category, path: 'zoomMode', defaultValue: 'cooperative', settings: { options: [ - { value: 'cooperative', label: 'Cooperative', description: 'Lets you scroll the page normally' }, - { value: 'greedy', label: 'Greedy', description: 'Reacts to all zoom gestures' }, + { + value: 'cooperative', + label: t('node-graph.zoom-mode-options.label-cooperative', 'Cooperative'), + description: t('node-graph.zoom-mode-options.description-cooperative', 'Lets you scroll the page normally'), + }, + { + value: 'greedy', + label: t('node-graph.zoom-mode-options.label-greedy', 'Greedy'), + description: t('node-graph.zoom-mode-options.description-greedy', 'Reacts to all zoom gestures'), + }, ], }, }); builder.addSelect({ - name: 'Layout algorithm', + name: t('node-graph.name-layout-algorithm', 'Layout algorithm'), + category, path: 'layoutAlgorithm', defaultValue: LayoutAlgorithm.Layered, settings: { options: [ - { label: 'Layered', value: LayoutAlgorithm.Layered, description: 'Use a layered layout' }, - { label: 'Force', value: LayoutAlgorithm.Force, description: 'Use a force-directed layout' }, - { label: 'Grid', value: LayoutAlgorithm.Grid, description: 'Use a grid layout' }, + { + label: t('node-graph.layout-algorithm-options.label-layered', 'Layered'), + value: LayoutAlgorithm.Layered, + description: t('node-graph.layout-algorithm-options.description-layered', 'Use a layered layout'), + }, + { + label: t('node-graph.layout-algorithm-options.label-force', 'Force'), + value: LayoutAlgorithm.Force, + description: t('node-graph.layout-algorithm-options.description-force', 'Use a force-directed layout'), + }, + { + label: t('node-graph.layout-algorithm-options.label-grid', 'Grid'), + value: LayoutAlgorithm.Grid, + description: t('node-graph.layout-algorithm-options.description-grid', 'Use a grid layout'), + }, ], }, }); builder.addNestedOptions({ - category: ['Nodes'], + category: [t('node-graph.category-nodes', 'Nodes')], path: 'nodes', build: (builder) => { builder.addUnitPicker({ - name: 'Main stat unit', + name: t('node-graph.name-main-stat-unit', 'Main stat unit'), path: 'mainStatUnit', }); builder.addUnitPicker({ - name: 'Secondary stat unit', + name: t('node-graph.name-secondary-stat-unit', 'Secondary stat unit'), path: 'secondaryStatUnit', }); builder.addCustomEditor({ - name: 'Arc sections', + name: t('node-graph.name-arc-sections', 'Arc sections'), path: 'arcs', id: 'arcs', editor: ArcOptionsEditor, @@ -54,15 +78,15 @@ export const plugin = new PanelPlugin(NodeGraphPanel) }, }); builder.addNestedOptions({ - category: ['Edges'], + category: [t('node-graph.category-edges', 'Edges')], path: 'edges', build: (builder) => { builder.addUnitPicker({ - name: 'Main stat unit', + name: t('node-graph.name-main-stat-unit', 'Main stat unit'), path: 'mainStatUnit', }); builder.addUnitPicker({ - name: 'Secondary stat unit', + name: t('node-graph.name-secondary-stat-unit', 'Secondary stat unit'), path: 'secondaryStatUnit', }); }, diff --git a/public/app/plugins/panel/piechart/module.tsx b/public/app/plugins/panel/piechart/module.tsx index 48989f14444..111c481f533 100644 --- a/public/app/plugins/panel/piechart/module.tsx +++ b/public/app/plugins/panel/piechart/module.tsx @@ -1,4 +1,5 @@ import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { commonOptionsBuilder } from '@grafana/ui'; import { optsWithHideZeros } from '@grafana/ui/internal'; @@ -31,28 +32,32 @@ export const plugin = new PanelPlugin(PieChartPanel) }) .setPanelOptions((builder) => { addStandardDataReduceOptions(builder); + const category = [t('piechart.category-pie-chart', 'Pie chart')]; + const legendCategory = [t('piechart.category-legend', 'Legend')]; builder .addRadio({ - name: 'Piechart type', - description: 'How the piechart should be rendered', + name: t('piechart.name-pie-chart-type', 'Pie chart type'), + category, + description: t('piechart.description-pie-chart-type', 'How the pie chart should be rendered'), path: 'pieType', settings: { options: [ - { value: PieChartType.Pie, label: 'Pie' }, - { value: PieChartType.Donut, label: 'Donut' }, + { value: PieChartType.Pie, label: t('piechart.pie-chart-type-options.label-pie', 'Pie') }, + { value: PieChartType.Donut, label: t('piechart.pie-chart-type-options.label-donut', 'Donut') }, ], }, defaultValue: PieChartType.Pie, }) .addMultiSelect({ - name: 'Labels', + name: t('piechart.name-labels', 'Labels'), + category, path: 'displayLabels', - description: 'Select the labels to be displayed in the pie chart', + description: t('piechart.description-labels', 'Select the labels to be displayed in the pie chart'), settings: { options: [ - { value: PieChartLabels.Percent, label: 'Percent' }, - { value: PieChartLabels.Name, label: 'Name' }, - { value: PieChartLabels.Value, label: 'Value' }, + { value: PieChartLabels.Percent, label: t('piechart.labels-options.label-percent', 'Percent') }, + { value: PieChartLabels.Name, label: t('piechart.labels-options.label-name', 'Name') }, + { value: PieChartLabels.Value, label: t('piechart.labels-options.label-value', 'Value') }, ], }, }); @@ -61,13 +66,13 @@ export const plugin = new PanelPlugin(PieChartPanel) commonOptionsBuilder.addLegendOptions(builder, false); builder.addMultiSelect({ - name: 'Legend values', + name: t('piechart.name-legend-values', 'Legend values'), path: 'legend.values', - category: ['Legend'], + category: legendCategory, settings: { options: [ - { value: PieChartLegendValues.Percent, label: 'Percent' }, - { value: PieChartLegendValues.Value, label: 'Value' }, + { value: PieChartLegendValues.Percent, label: t('piechart.legend-values-options.label-percent', 'Percent') }, + { value: PieChartLegendValues.Value, label: t('piechart.legend-values-options.label-value', 'Value') }, ], }, showIf: (c) => c.legend.showLegend !== false, diff --git a/public/app/plugins/panel/stat/common.ts b/public/app/plugins/panel/stat/common.ts index 60000103575..9a3d3160ffd 100644 --- a/public/app/plugins/panel/stat/common.ts +++ b/public/app/plugins/panel/stat/common.ts @@ -8,22 +8,26 @@ import { ReducerID, standardEditorsRegistry, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { SingleStatBaseOptions, VizOrientation } from '@grafana/schema'; export function addStandardDataReduceOptions( builder: PanelOptionsEditorBuilder, includeFieldMatcher = true ) { - const valueOptionsCategory = ['Value options']; + const valueOptionsCategory = [t('stat.add-standard-data-reduce-options.category-value-options', 'Value options')]; builder.addRadio({ path: 'reduceOptions.values', - name: 'Show', - description: 'Calculate a single value per column or series or show each row', + name: t('stat.add-standard-data-reduce-options.name-show', 'Show'), + description: t( + 'stat.add-standard-data-reduce-options.description-show', + 'Calculate a single value per column or series or show each row' + ), settings: { options: [ - { value: false, label: 'Calculate' }, - { value: true, label: 'All values' }, + { value: false, label: t('stat.add-standard-data-reduce-options.show-options.label-calculate', 'Calculate') }, + { value: true, label: t('stat.add-standard-data-reduce-options.show-options.label-all-values', 'All values') }, ], }, category: valueOptionsCategory, @@ -32,8 +36,8 @@ export function addStandardDataReduceOptions( builder.addNumberInput({ path: 'reduceOptions.limit', - name: 'Limit', - description: 'Max number of rows to display', + name: t('stat.add-standard-data-reduce-options.name-limit', 'Limit'), + description: t('stat.add-standard-data-reduce-options.description-limit', 'Max number of rows to display'), category: valueOptionsCategory, settings: { placeholder: '25', @@ -47,8 +51,11 @@ export function addStandardDataReduceOptions( builder.addCustomEditor({ id: 'reduceOptions.calcs', path: 'reduceOptions.calcs', - name: 'Calculation', - description: 'Choose a reducer function / calculation', + name: t('stat.add-standard-data-reduce-options.name-calculation', 'Calculation'), + description: t( + 'stat.add-standard-data-reduce-options.description-calculation', + 'Choose a reducer function / calculation' + ), category: valueOptionsCategory, editor: standardEditorsRegistry.get('stats-picker').editor, // TODO: Get ReducerID from generated schema one day? @@ -60,16 +67,25 @@ export function addStandardDataReduceOptions( if (includeFieldMatcher) { builder.addSelect({ path: 'reduceOptions.fields', - name: 'Fields', - description: 'Select the fields that should be included in the panel', + name: t('stat.add-standard-data-reduce-options.name-fields', 'Fields'), + description: t( + 'stat.add-standard-data-reduce-options.description-fields', + 'Select the fields that should be included in the panel' + ), category: valueOptionsCategory, settings: { allowCustomValue: true, options: [], getOptions: async (context: FieldOverrideContext) => { const options = [ - { value: '', label: 'Numeric Fields' }, - { value: '/.*/', label: 'All Fields' }, + { + value: '', + label: t('stat.add-standard-data-reduce-options.fields-options.label-numeric-fields', 'Numeric Fields'), + }, + { + value: '/.*/', + label: t('stat.add-standard-data-reduce-options.fields-options.label-all-fields', 'All Fields'), + }, ]; if (context && context.data) { for (const frame of context.data) { @@ -94,14 +110,20 @@ export function addOrientationOption( ) { builder.addRadio({ path: 'orientation', - name: 'Orientation', - description: 'Layout orientation', + name: t('stat.add-orientation-option.name-orientation', 'Orientation'), + description: t('stat.add-orientation-option.description-orientation', 'Layout orientation'), category, settings: { options: [ - { value: VizOrientation.Auto, label: 'Auto' }, - { value: VizOrientation.Horizontal, label: 'Horizontal' }, - { value: VizOrientation.Vertical, label: 'Vertical' }, + { value: VizOrientation.Auto, label: t('stat.add-orientation-option.orientation-options.label-auto', 'Auto') }, + { + value: VizOrientation.Horizontal, + label: t('stat.add-orientation-option.orientation-options.label-horizontal', 'Horizontal'), + }, + { + value: VizOrientation.Vertical, + label: t('stat.add-orientation-option.orientation-options.label-vertical', 'Vertical'), + }, ], }, defaultValue: VizOrientation.Auto, diff --git a/public/app/plugins/panel/stat/module.tsx b/public/app/plugins/panel/stat/module.tsx index d5c297fc0fe..4a22ef382c9 100644 --- a/public/app/plugins/panel/stat/module.tsx +++ b/public/app/plugins/panel/stat/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { BigValueColorMode, BigValueGraphMode, @@ -17,7 +18,7 @@ import { StatSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(StatPanel) .useFieldConfig() .setPanelOptions((builder) => { - const mainCategory = ['Stat styles']; + const mainCategory = [t('stat.category-stat-styles', 'Stat styles')]; addStandardDataReduceOptions(builder); addOrientationOption(builder, mainCategory); @@ -26,28 +27,31 @@ export const plugin = new PanelPlugin(StatPanel) builder .addSelect({ path: 'textMode', - name: 'Text mode', - description: 'Control if name and value is displayed or just name', + name: t('stat.name-text-mode', 'Text mode'), + description: t('stat.description-text-mode', 'Control if name and value is displayed or just name'), category: mainCategory, settings: { options: [ - { value: BigValueTextMode.Auto, label: 'Auto' }, - { value: BigValueTextMode.Value, label: 'Value' }, - { value: BigValueTextMode.ValueAndName, label: 'Value and name' }, - { value: BigValueTextMode.Name, label: 'Name' }, - { value: BigValueTextMode.None, label: 'None' }, + { value: BigValueTextMode.Auto, label: t('stat.text-mode-options.label-auto', 'Auto') }, + { value: BigValueTextMode.Value, label: t('stat.text-mode-options.label-value', 'Value') }, + { + value: BigValueTextMode.ValueAndName, + label: t('stat.text-mode-options.label-value-and-name', 'Value and name'), + }, + { value: BigValueTextMode.Name, label: t('stat.text-mode-options.label-name', 'Name') }, + { value: BigValueTextMode.None, label: t('stat.text-mode-options.label-none', 'None') }, ], }, defaultValue: defaultOptions.textMode, }) .addRadio({ path: 'wideLayout', - name: 'Wide layout', + name: t('stat.name-wide-layout', 'Wide layout'), category: mainCategory, settings: { options: [ - { value: true, label: 'On' }, - { value: false, label: 'Off' }, + { value: true, label: t('stat.wide-layout-options.label-on', 'On') }, + { value: false, label: t('stat.wide-layout-options.label-off', 'Off') }, ], }, defaultValue: defaultOptions.wideLayout, @@ -57,60 +61,75 @@ export const plugin = new PanelPlugin(StatPanel) builder .addSelect({ path: 'colorMode', - name: 'Color mode', + name: t('stat.name-color-modcolor-mode-options.label', 'Color mode'), defaultValue: BigValueColorMode.Value, category: mainCategory, settings: { options: [ - { value: BigValueColorMode.None, label: 'None' }, - { value: BigValueColorMode.Value, label: 'Value' }, - { value: BigValueColorMode.Background, label: 'Background Gradient' }, - { value: BigValueColorMode.BackgroundSolid, label: 'Background Solid' }, + { value: BigValueColorMode.None, label: t('stat.color-mode-options.label-none', 'None') }, + { value: BigValueColorMode.Value, label: t('stat.color-mode-options.label-value', 'Value') }, + { + value: BigValueColorMode.Background, + label: t('stat.color-mode-options.label-background-gradient', 'Background Gradient'), + }, + { + value: BigValueColorMode.BackgroundSolid, + label: t('stat.color-mode-options.label-background-solid', 'Background Solid'), + }, ], }, }) .addRadio({ path: 'graphMode', - name: 'Graph mode', - description: 'Stat panel graph / sparkline mode', + name: t('stat.name-graph-mode', 'Graph mode'), + description: t('stat.description-graph-mode', 'Stat panel graph / sparkline mode'), category: mainCategory, defaultValue: defaultOptions.graphMode, settings: { options: [ - { value: BigValueGraphMode.None, label: 'None' }, - { value: BigValueGraphMode.Area, label: 'Area' }, + { value: BigValueGraphMode.None, label: t('stat.graph-mode.options.label-none', 'None') }, + { value: BigValueGraphMode.Area, label: t('stat.graph-mode.options.label-area', 'Area') }, ], }, }) .addRadio({ path: 'justifyMode', - name: 'Text alignment', + name: t('stat.name-text-alignment', 'Text alignment'), defaultValue: defaultOptions.justifyMode, category: mainCategory, settings: { options: [ - { value: BigValueJustifyMode.Auto, label: 'Auto' }, - { value: BigValueJustifyMode.Center, label: 'Center' }, + { value: BigValueJustifyMode.Auto, label: t('stat.text-alignment-options.label-auto', 'Auto') }, + { value: BigValueJustifyMode.Center, label: t('stat.text-alignment-options.label-center', 'Center') }, ], }, }) .addBooleanSwitch({ path: 'showPercentChange', - name: 'Show percent change', + name: t('stat.name-show-percent-change', 'Show percent change'), defaultValue: defaultOptions.showPercentChange, category: mainCategory, showIf: (config) => !config.reduceOptions.values, }) .addSelect({ path: 'percentChangeColorMode', - name: 'Percent change color mode', + name: t('stat.percent-change-color-mode', 'Percent change color mode'), defaultValue: defaultOptions.percentChangeColorMode, category: mainCategory, settings: { options: [ - { value: PercentChangeColorMode.Standard, label: 'Standard' }, - { value: PercentChangeColorMode.Inverted, label: 'Inverted' }, - { value: PercentChangeColorMode.SameAsValue, label: 'Same as Value' }, + { + value: PercentChangeColorMode.Standard, + label: t('stat.percent-change-color-mode-options.label-standard', 'Standard'), + }, + { + value: PercentChangeColorMode.Inverted, + label: t('stat.percent-change-color-mode-options.label-inverted', 'Inverted'), + }, + { + value: PercentChangeColorMode.SameAsValue, + label: t('stat.percent-change-color-mode-options.label-same-as-value', 'Same as Value'), + }, ], }, showIf: (config) => config.showPercentChange, diff --git a/public/app/plugins/panel/state-timeline/module.tsx b/public/app/plugins/panel/state-timeline/module.tsx index 7d84934e74a..61053b28090 100644 --- a/public/app/plugins/panel/state-timeline/module.tsx +++ b/public/app/plugins/panel/state-timeline/module.tsx @@ -5,6 +5,7 @@ import { identityOverrideProcessor, PanelPlugin, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { AxisPlacement, VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; @@ -39,10 +40,12 @@ export const plugin = new PanelPlugin(StateTimelinePanel) }, }, useCustomConfig: (builder) => { + const category = [t('state-timeline.category-state-timeline', 'State timeline')]; builder .addSliderInput({ path: 'lineWidth', - name: 'Line width', + name: t('state-timeline.name-line-width', 'Line width'), + category, defaultValue: defaultFieldConfig.lineWidth, settings: { min: 0, @@ -52,7 +55,8 @@ export const plugin = new PanelPlugin(StateTimelinePanel) }) .addSliderInput({ path: 'fillOpacity', - name: 'Fill opacity', + name: t('state-timeline.name-fill-opacity', 'Fill opacity'), + category, defaultValue: defaultFieldConfig.fillOpacity, settings: { min: 0, @@ -63,7 +67,8 @@ export const plugin = new PanelPlugin(StateTimelinePanel) .addCustomEditor({ id: 'spanNulls', path: 'spanNulls', - name: 'Connect null values', + name: t('state-timeline.name-connect-null-values', 'Connect null values'), + category, defaultValue: false, editor: SpanNullsEditor, override: SpanNullsEditor, @@ -74,7 +79,8 @@ export const plugin = new PanelPlugin(StateTimelinePanel) .addCustomEditor({ id: 'insertNulls', path: 'insertNulls', - name: 'Disconnect values', + name: t('state-timeline.name-disconnect-values', 'Disconnect values'), + category, defaultValue: false, editor: InsertNullsEditor, override: InsertNullsEditor, @@ -92,39 +98,44 @@ export const plugin = new PanelPlugin(StateTimelinePanel) }, }) .setPanelOptions((builder) => { + const category = [t('state-timeline.category-state-timeline', 'State timeline')]; builder .addBooleanSwitch({ path: 'mergeValues', - name: 'Merge equal consecutive values', + name: t('state-timeline.name-merge-equal-consecutive-values', 'Merge equal consecutive values'), + category, defaultValue: defaultOptions.mergeValues, }) .addRadio({ path: 'showValue', - name: 'Show values', + name: t('state-timeline.name-show-values', 'Show values'), + category, settings: { options: [ - { value: VisibilityMode.Auto, label: 'Auto' }, - { value: VisibilityMode.Always, label: 'Always' }, - { value: VisibilityMode.Never, label: 'Never' }, + { value: VisibilityMode.Auto, label: t('state-timeline.show-values-options.label-auto', 'Auto') }, + { value: VisibilityMode.Always, label: t('state-timeline.show-values-options.label-always', 'Always') }, + { value: VisibilityMode.Never, label: t('state-timeline.show-values-options.label-never', 'Never') }, ], }, defaultValue: defaultOptions.showValue, }) .addRadio({ path: 'alignValue', - name: 'Align values', + name: t('state-timeline.name-align-values', 'Align values'), + category, settings: { options: [ - { value: 'left', label: 'Left' }, - { value: 'center', label: 'Center' }, - { value: 'right', label: 'Right' }, + { value: 'left', label: t('state-timeline.align-values-options.label-left', 'Left') }, + { value: 'center', label: t('state-timeline.align-values-options.label-center', 'Center') }, + { value: 'right', label: t('state-timeline.align-values-options.label-right', 'Right') }, ], }, defaultValue: defaultOptions.alignValue, }) .addSliderInput({ path: 'rowHeight', - name: 'Row height', + name: t('state-timeline.name-row-height', 'Row height'), + category, settings: { min: 0, max: 1, @@ -134,7 +145,8 @@ export const plugin = new PanelPlugin(StateTimelinePanel) }) .addNumberInput({ path: 'perPage', - name: 'Page size (enable pagination)', + name: t('state-timeline.name-page-size', 'Page size (enable pagination)'), + category, settings: { min: 1, step: 1, diff --git a/public/app/plugins/panel/status-history/module.tsx b/public/app/plugins/panel/status-history/module.tsx index d556c52ccc0..1e07588d664 100644 --- a/public/app/plugins/panel/status-history/module.tsx +++ b/public/app/plugins/panel/status-history/module.tsx @@ -1,4 +1,5 @@ import { FieldColorModeId, FieldConfigProperty, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { AxisPlacement, VisibilityMode } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; @@ -27,10 +28,12 @@ export const plugin = new PanelPlugin(StatusHistoryPanel) }, }, useCustomConfig: (builder) => { + const category = [t('status-history.category-status-history', 'Status history')]; builder .addSliderInput({ path: 'lineWidth', - name: 'Line width', + name: t('status-history.name-line-width', 'Line width'), + category, defaultValue: defaultFieldConfig.lineWidth, settings: { min: 0, @@ -40,7 +43,8 @@ export const plugin = new PanelPlugin(StatusHistoryPanel) }) .addSliderInput({ path: 'fillOpacity', - name: 'Fill opacity', + name: t('status-history.name-fill-opacity', 'Fill opacity'), + category, defaultValue: defaultFieldConfig.fillOpacity, settings: { min: 0, @@ -58,22 +62,25 @@ export const plugin = new PanelPlugin(StatusHistoryPanel) }, }) .setPanelOptions((builder) => { + const category = [t('status-history.category-status-history', 'Status history')]; builder .addRadio({ path: 'showValue', - name: 'Show values', + name: t('status-history.name-show-values', 'Show values'), + category, settings: { options: [ - { value: VisibilityMode.Auto, label: 'Auto' }, - { value: VisibilityMode.Always, label: 'Always' }, - { value: VisibilityMode.Never, label: 'Never' }, + { value: VisibilityMode.Auto, label: t('status-history.show-values-options.label-auto', 'Auto') }, + { value: VisibilityMode.Always, label: t('status-history.show-values-options.label-always', 'Always') }, + { value: VisibilityMode.Never, label: t('status-history.show-values-options.label-never', 'Never') }, ], }, defaultValue: VisibilityMode.Auto, }) .addSliderInput({ path: 'rowHeight', - name: 'Row height', + name: t('status-history.name-row-height', 'Row height'), + category, defaultValue: 0.9, settings: { min: 0, @@ -83,7 +90,8 @@ export const plugin = new PanelPlugin(StatusHistoryPanel) }) .addSliderInput({ path: 'colWidth', - name: 'Column width', + name: t('status-history.name-column-width', 'Column width'), + category, defaultValue: 0.9, settings: { min: 0, @@ -93,7 +101,8 @@ export const plugin = new PanelPlugin(StatusHistoryPanel) }) .addNumberInput({ path: 'perPage', - name: 'Page size (enable pagination)', + name: t('status-history.name-page-size', 'Page size (enable pagination)'), + category, settings: { min: 1, step: 1, diff --git a/public/app/plugins/panel/table/module.tsx b/public/app/plugins/panel/table/module.tsx index cdfbf7499c1..66250d8ffaf 100644 --- a/public/app/plugins/panel/table/module.tsx +++ b/public/app/plugins/panel/table/module.tsx @@ -8,6 +8,7 @@ import { identityOverrideProcessor, FieldConfigProperty, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { TableCellOptions, TableCellDisplayMode, defaultTableFieldOptions, TableCellHeight } from '@grafana/schema'; import { PaginationEditor } from './PaginationEditor'; @@ -17,9 +18,6 @@ import { tableMigrationHandler, tablePanelChangedHandler } from './migrations'; import { Options, defaultOptions, FieldConfig } from './panelcfg.gen'; import { TableSuggestionsSupplier } from './suggestions'; -const footerCategory = 'Table footer'; -const cellCategory = ['Cell options']; - export const plugin = new PanelPlugin(TablePanel) .setPanelChangeHandler(tablePanelChangedHandler) .setMigrationHandler(tableMigrationHandler) @@ -30,11 +28,14 @@ export const plugin = new PanelPlugin(TablePanel) }, }, useCustomConfig: (builder) => { + const category = [t('table.category-table', 'Table')]; + const cellCategory = [t('table.category-cell-options', 'Cell options')]; builder .addNumberInput({ path: 'minWidth', - name: 'Minimum column width', - description: 'The minimum width for column auto resizing', + name: t('table.name-min-column-width', 'Minimum column width'), + category, + description: t('table.description-min-column-width', 'The minimum width for column auto resizing'), settings: { placeholder: '150', min: 50, @@ -45,9 +46,10 @@ export const plugin = new PanelPlugin(TablePanel) }) .addNumberInput({ path: 'width', - name: 'Column width', + name: t('table.name-column-width', 'Column width'), + category, settings: { - placeholder: 'auto', + placeholder: t('table.placeholder-column-width', 'auto'), min: 20, max: 300, }, @@ -56,13 +58,14 @@ export const plugin = new PanelPlugin(TablePanel) }) .addRadio({ path: 'align', - name: 'Column alignment', + name: t('table.name-column-alignment', 'Column alignment'), + category, settings: { options: [ - { label: 'Auto', value: 'auto' }, - { label: 'Left', value: 'left' }, - { label: 'Center', value: 'center' }, - { label: 'Right', value: 'right' }, + { label: t('table.column-alignment-options.label-auto', 'Auto'), value: 'auto' }, + { label: t('table.column-alignment-options.label-left', 'Left'), value: 'left' }, + { label: t('table.column-alignment-options.label-center', 'Center'), value: 'center' }, + { label: t('table.column-alignment-options.label-right', 'Right'), value: 'right' }, ], }, defaultValue: defaultTableFieldOptions.align, @@ -70,7 +73,7 @@ export const plugin = new PanelPlugin(TablePanel) .addCustomEditor({ id: 'cellOptions', path: 'cellOptions', - name: 'Cell type', + name: t('table.name-cell-type', 'Cell type'), editor: TableCellOptionEditor, override: TableCellOptionEditor, defaultValue: defaultTableFieldOptions.cellOptions, @@ -80,8 +83,8 @@ export const plugin = new PanelPlugin(TablePanel) }) .addBooleanSwitch({ path: 'inspect', - name: 'Cell value inspect', - description: 'Enable cell value inspection in a modal window', + name: t('table.name-cell-value-inspect', 'Cell value inspect'), + description: t('table.description-cell-value-inspect', 'Enable cell value inspection in a modal window'), defaultValue: false, category: cellCategory, showIf: (cfg) => { @@ -95,70 +98,76 @@ export const plugin = new PanelPlugin(TablePanel) }) .addBooleanSwitch({ path: 'filterable', - name: 'Column filter', - description: 'Enables/disables field filters in table', + name: t('table.name-column-filter', 'Column filter'), + category, + description: t('table.description-column-filter', 'Enables/disables field filters in table'), defaultValue: defaultTableFieldOptions.filterable, }) .addBooleanSwitch({ path: 'hidden', - name: 'Hide in table', + name: t('table.name-hide-in-table', 'Hide in table'), + category, defaultValue: undefined, hideFromDefaults: true, }); }, }) .setPanelOptions((builder) => { + const category = [t('table.category-table', 'Table')]; + const footerCategory = [t('table.category-table-footer', 'Table footer')]; builder .addBooleanSwitch({ path: 'showHeader', - name: 'Show table header', + name: t('table.name-show-table-header', 'Show table header'), + category, defaultValue: defaultOptions.showHeader, }) .addRadio({ path: 'cellHeight', - name: 'Cell height', + name: t('table.name-cell-height', 'Cell height'), + category, defaultValue: defaultOptions.cellHeight, settings: { options: [ - { value: TableCellHeight.Sm, label: 'Small' }, - { value: TableCellHeight.Md, label: 'Medium' }, - { value: TableCellHeight.Lg, label: 'Large' }, + { value: TableCellHeight.Sm, label: t('table.cell-height-options.label-small', 'Small') }, + { value: TableCellHeight.Md, label: t('table.cell-height-options.label-medium', 'Medium') }, + { value: TableCellHeight.Lg, label: t('table.cell-height-options.label-large', 'Large') }, ], }, }) .addBooleanSwitch({ path: 'footer.show', - category: [footerCategory], - name: 'Show table footer', + category: footerCategory, + name: t('table.name-show-table-footer', 'Show table footer'), defaultValue: defaultOptions.footer?.show, }) .addCustomEditor({ id: 'footer.reducer', - category: [footerCategory], + category: footerCategory, path: 'footer.reducer', - name: 'Calculation', - description: 'Choose a reducer function / calculation', + name: t('table.name-calculation', 'Calculation'), + description: t('table.description-calculation', 'Choose a reducer function / calculation'), editor: standardEditorsRegistry.get('stats-picker').editor, defaultValue: [ReducerID.sum], showIf: (cfg) => cfg.footer?.show, }) .addBooleanSwitch({ path: 'footer.countRows', - category: [footerCategory], - name: 'Count rows', - description: 'Display a single count for all data rows', + category: footerCategory, + name: t('table.name-count-rows', 'Count rows'), + description: t('table.description-count-rows', 'Display a single count for all data rows'), defaultValue: defaultOptions.footer?.countRows, showIf: (cfg) => cfg.footer?.reducer?.length === 1 && cfg.footer?.reducer[0] === ReducerID.count, }) .addMultiSelect({ path: 'footer.fields', - category: [footerCategory], - name: 'Fields', - description: 'Select the fields that should be calculated', + category: footerCategory, + name: t('table.name-fields', 'Fields'), + description: t('table.description-fields', 'Select the fields that should be calculated'), settings: { allowCustomValue: false, options: [], - placeholder: 'All Numeric Fields', + placeholder: t('table.placeholder-fields', 'All Numeric Fields'), getOptions: async (context: FieldOverrideContext) => { const options = []; if (context && context.data && context.data.length > 0) { @@ -180,7 +189,8 @@ export const plugin = new PanelPlugin(TablePanel) .addCustomEditor({ id: 'footer.enablePagination', path: 'footer.enablePagination', - name: 'Enable pagination', + name: t('table.name-enable-paginations', 'Enable pagination'), + category, editor: PaginationEditor, }); }) diff --git a/public/app/plugins/panel/table/table-new/module.tsx b/public/app/plugins/panel/table/table-new/module.tsx index cdfbf7499c1..ecbe9cbf782 100644 --- a/public/app/plugins/panel/table/table-new/module.tsx +++ b/public/app/plugins/panel/table/table-new/module.tsx @@ -8,6 +8,7 @@ import { identityOverrideProcessor, FieldConfigProperty, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { TableCellOptions, TableCellDisplayMode, defaultTableFieldOptions, TableCellHeight } from '@grafana/schema'; import { PaginationEditor } from './PaginationEditor'; @@ -17,9 +18,6 @@ import { tableMigrationHandler, tablePanelChangedHandler } from './migrations'; import { Options, defaultOptions, FieldConfig } from './panelcfg.gen'; import { TableSuggestionsSupplier } from './suggestions'; -const footerCategory = 'Table footer'; -const cellCategory = ['Cell options']; - export const plugin = new PanelPlugin(TablePanel) .setPanelChangeHandler(tablePanelChangedHandler) .setMigrationHandler(tableMigrationHandler) @@ -30,11 +28,14 @@ export const plugin = new PanelPlugin(TablePanel) }, }, useCustomConfig: (builder) => { + const category = [t('table-new.category-table', 'Table')]; + const cellCategory = [t('table-new.category-cell-options', 'Cell options')]; builder .addNumberInput({ path: 'minWidth', - name: 'Minimum column width', - description: 'The minimum width for column auto resizing', + name: t('table-new.name-min-column-width', 'Minimum column width'), + category, + description: t('table-new.description-min-column-width', 'The minimum width for column auto resizing'), settings: { placeholder: '150', min: 50, @@ -45,9 +46,10 @@ export const plugin = new PanelPlugin(TablePanel) }) .addNumberInput({ path: 'width', - name: 'Column width', + name: t('table-new.name-column-width', 'Column width'), + category, settings: { - placeholder: 'auto', + placeholder: t('table-new.placeholder-column-width', 'auto'), min: 20, max: 300, }, @@ -56,13 +58,14 @@ export const plugin = new PanelPlugin(TablePanel) }) .addRadio({ path: 'align', - name: 'Column alignment', + name: t('table-new.name-column-alignment', 'Column alignment'), + category, settings: { options: [ - { label: 'Auto', value: 'auto' }, - { label: 'Left', value: 'left' }, - { label: 'Center', value: 'center' }, - { label: 'Right', value: 'right' }, + { label: t('table-new.column-alignment-options.label-auto', 'Auto'), value: 'auto' }, + { label: t('table-new.column-alignment-options.label-left', 'Left'), value: 'left' }, + { label: t('table-new.column-alignment-options.label-center', 'Center'), value: 'center' }, + { label: t('table-new.column-alignment-options.label-right', 'Right'), value: 'right' }, ], }, defaultValue: defaultTableFieldOptions.align, @@ -70,7 +73,7 @@ export const plugin = new PanelPlugin(TablePanel) .addCustomEditor({ id: 'cellOptions', path: 'cellOptions', - name: 'Cell type', + name: t('table-new.name-cell-type', 'Cell type'), editor: TableCellOptionEditor, override: TableCellOptionEditor, defaultValue: defaultTableFieldOptions.cellOptions, @@ -80,8 +83,8 @@ export const plugin = new PanelPlugin(TablePanel) }) .addBooleanSwitch({ path: 'inspect', - name: 'Cell value inspect', - description: 'Enable cell value inspection in a modal window', + name: t('table-new.name-cell-value-inspect', 'Cell value inspect'), + description: t('table-new.description-cell-value-inspect', 'Enable cell value inspection in a modal window'), defaultValue: false, category: cellCategory, showIf: (cfg) => { @@ -95,70 +98,76 @@ export const plugin = new PanelPlugin(TablePanel) }) .addBooleanSwitch({ path: 'filterable', - name: 'Column filter', - description: 'Enables/disables field filters in table', + name: t('table-new.name-column-filter', 'Column filter'), + category, + description: t('table-new.description-column-filter', 'Enables/disables field filters in table'), defaultValue: defaultTableFieldOptions.filterable, }) .addBooleanSwitch({ path: 'hidden', - name: 'Hide in table', + name: t('table-new.name-hide-in-table', 'Hide in table'), + category, defaultValue: undefined, hideFromDefaults: true, }); }, }) .setPanelOptions((builder) => { + const footerCategory = [t('table-new.category-table-footer', 'Table footer')]; + const category = [t('table-new.category-table', 'Table')]; builder .addBooleanSwitch({ path: 'showHeader', - name: 'Show table header', + name: t('table-new.name-show-table-header', 'Show table header'), + category, defaultValue: defaultOptions.showHeader, }) .addRadio({ path: 'cellHeight', - name: 'Cell height', + name: t('table-new.name-cell-height', 'Cell height'), + category, defaultValue: defaultOptions.cellHeight, settings: { options: [ - { value: TableCellHeight.Sm, label: 'Small' }, - { value: TableCellHeight.Md, label: 'Medium' }, - { value: TableCellHeight.Lg, label: 'Large' }, + { value: TableCellHeight.Sm, label: t('table-new.cell-height-options.label-small', 'Small') }, + { value: TableCellHeight.Md, label: t('table-new.cell-height-options.label-medium', 'Medium') }, + { value: TableCellHeight.Lg, label: t('table-new.cell-height-options.label-large', 'Large') }, ], }, }) .addBooleanSwitch({ path: 'footer.show', - category: [footerCategory], - name: 'Show table footer', + category: footerCategory, + name: t('table-new.name-show-table-footer', 'Show table footer'), defaultValue: defaultOptions.footer?.show, }) .addCustomEditor({ id: 'footer.reducer', - category: [footerCategory], + category: footerCategory, path: 'footer.reducer', - name: 'Calculation', - description: 'Choose a reducer function / calculation', + name: t('table-new.name-calculation', 'Calculation'), + description: t('table-new.description-calculation', 'Choose a reducer function / calculation'), editor: standardEditorsRegistry.get('stats-picker').editor, defaultValue: [ReducerID.sum], showIf: (cfg) => cfg.footer?.show, }) .addBooleanSwitch({ path: 'footer.countRows', - category: [footerCategory], - name: 'Count rows', - description: 'Display a single count for all data rows', + category: footerCategory, + name: t('table-new.name-count-rows', 'Count rows'), + description: t('table-new.description-count-rows', 'Display a single count for all data rows'), defaultValue: defaultOptions.footer?.countRows, showIf: (cfg) => cfg.footer?.reducer?.length === 1 && cfg.footer?.reducer[0] === ReducerID.count, }) .addMultiSelect({ path: 'footer.fields', - category: [footerCategory], - name: 'Fields', - description: 'Select the fields that should be calculated', + category: footerCategory, + name: t('table-new.name-fields', 'Fields'), + description: t('table-new.description-fields', 'Select the fields that should be calculated'), settings: { allowCustomValue: false, options: [], - placeholder: 'All Numeric Fields', + placeholder: t('table-new.placeholder-fields', 'All Numeric Fields'), getOptions: async (context: FieldOverrideContext) => { const options = []; if (context && context.data && context.data.length > 0) { @@ -180,7 +189,8 @@ export const plugin = new PanelPlugin(TablePanel) .addCustomEditor({ id: 'footer.enablePagination', path: 'footer.enablePagination', - name: 'Enable pagination', + name: t('table-new.name-enable-pagination', 'Enable pagination'), + category, editor: PaginationEditor, }); }) diff --git a/public/app/plugins/panel/text/module.tsx b/public/app/plugins/panel/text/module.tsx index ae1f9021363..22a6d85972e 100644 --- a/public/app/plugins/panel/text/module.tsx +++ b/public/app/plugins/panel/text/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { TextPanel } from './TextPanel'; import { TextPanelEditor } from './TextPanelEditor'; @@ -7,22 +8,25 @@ import { textPanelMigrationHandler } from './textPanelMigrationHandler'; export const plugin = new PanelPlugin(TextPanel) .setPanelOptions((builder) => { + const category = [t('text.category-text', 'Text')]; builder .addRadio({ path: 'mode', - name: 'Mode', + name: t('text.name-mode', 'Mode'), + category, settings: { options: [ - { value: TextMode.Markdown, label: 'Markdown' }, - { value: TextMode.HTML, label: 'HTML' }, - { value: TextMode.Code, label: 'Code' }, + { value: TextMode.Markdown, label: t('text.mode-options.label-markdown', 'Markdown') }, + { value: TextMode.HTML, label: t('text.mode-options.label-html', 'HTML') }, + { value: TextMode.Code, label: t('text.mode-options.label-code', 'Code') }, ], }, defaultValue: defaultOptions.mode, }) .addSelect({ path: 'code.language', - name: 'Language', + name: t('text.name-language', 'Language'), + category, settings: { options: Object.values(CodeLanguage).map((v) => ({ value: v, @@ -34,20 +38,23 @@ export const plugin = new PanelPlugin(TextPanel) }) .addBooleanSwitch({ path: 'code.showLineNumbers', - name: 'Show line numbers', + name: t('text.name-show-line-numbers', 'Show line numbers'), + category, defaultValue: defaultCodeOptions.showLineNumbers, showIf: (v) => v.mode === TextMode.Code, }) .addBooleanSwitch({ path: 'code.showMiniMap', - name: 'Show mini map', + name: t('text.name-show-mini-map', 'Show mini map'), + category, defaultValue: defaultCodeOptions.showMiniMap, showIf: (v) => v.mode === TextMode.Code, }) .addCustomEditor({ id: 'content', path: 'content', - name: 'Content', + name: t('text.name-content', 'Content'), + category, editor: TextPanelEditor, defaultValue: defaultOptions.content, }); diff --git a/public/app/plugins/panel/timeseries/InsertNullsEditor.tsx b/public/app/plugins/panel/timeseries/InsertNullsEditor.tsx index 868393ca497..dcd724f7057 100644 --- a/public/app/plugins/panel/timeseries/InsertNullsEditor.tsx +++ b/public/app/plugins/panel/timeseries/InsertNullsEditor.tsx @@ -1,22 +1,22 @@ import { StandardEditorProps, SelectableValue } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { HorizontalGroup, RadioButtonGroup } from '@grafana/ui'; import { InputPrefix, NullsThresholdInput } from './NullsThresholdInput'; -const DISCONNECT_OPTIONS: Array> = [ - { - label: 'Never', - value: false, - }, - { - label: 'Threshold', - value: 3600000, // 1h - }, -]; - type Props = StandardEditorProps; export const InsertNullsEditor = ({ value, onChange, item }: Props) => { + const DISCONNECT_OPTIONS: Array> = [ + { + label: t('timeseries.insert-nulls-editor.disconnect-options.label-never', 'Never'), + value: false, + }, + { + label: t('timeseries.insert-nulls-editor.disconnect-options.label-threshold', 'Threshold'), + value: 3600000, // 1h + }, + ]; const isThreshold = typeof value === 'number'; DISCONNECT_OPTIONS[1].value = isThreshold ? value : 3600000; // 1h diff --git a/public/app/plugins/panel/timeseries/LineStyleEditor.tsx b/public/app/plugins/panel/timeseries/LineStyleEditor.tsx index 41cf67a76af..dc83dd1bfcb 100644 --- a/public/app/plugins/panel/timeseries/LineStyleEditor.tsx +++ b/public/app/plugins/panel/timeseries/LineStyleEditor.tsx @@ -7,21 +7,6 @@ import { HorizontalGroup, IconButton, RadioButtonGroup, Select } from '@grafana/ type LineFill = 'solid' | 'dash' | 'dot'; -const lineFillOptions: Array> = [ - { - label: 'Solid', - value: 'solid', - }, - { - label: 'Dash', - value: 'dash', - }, - { - label: 'Dots', - value: 'dot', - }, -]; - const dashOptions: Array> = [ '10, 10', // default '10, 15', @@ -56,6 +41,20 @@ const dotOptions: Array> = [ type Props = StandardEditorProps; export const LineStyleEditor = ({ value, onChange }: Props) => { + const lineFillOptions: Array> = [ + { + label: t('timeseries.line-style-editor.line-fill-options.label-solid', 'Solid'), + value: 'solid', + }, + { + label: t('timeseries.line-style-editor.line-fill-options.label-dash', 'Dash'), + value: 'dash', + }, + { + label: t('timeseries.line-style-editor.line-fill-options.label-dots', 'Dots'), + value: 'dot', + }, + ]; const options = useMemo(() => (value?.fill === 'dash' ? dashOptions : dotOptions), [value]); const current = useMemo(() => { if (!value?.dash?.length) { diff --git a/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx b/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx index f7ac5d4ebc2..558580299a4 100644 --- a/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx +++ b/public/app/plugins/panel/timeseries/SpanNullsEditor.tsx @@ -1,26 +1,26 @@ import { StandardEditorProps, SelectableValue } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { HorizontalGroup, RadioButtonGroup } from '@grafana/ui'; import { InputPrefix, NullsThresholdInput } from './NullsThresholdInput'; -const GAPS_OPTIONS: Array> = [ - { - label: 'Never', - value: false, - }, - { - label: 'Always', - value: true, - }, - { - label: 'Threshold', - value: 3600000, // 1h - }, -]; - type Props = StandardEditorProps; export const SpanNullsEditor = ({ value, onChange, item }: Props) => { + const GAPS_OPTIONS: Array> = [ + { + label: t('timeseries.span-nulls-editor.gaps-options.label-never', 'Never'), + value: false, + }, + { + label: t('timeseries.span-nulls-editor.gaps-options.label-always', 'Always'), + value: true, + }, + { + label: t('timeseries.span-nulls-editor.gaps-options.label-threshold', 'Threshold'), + value: 3600000, // 1h + }, + ]; const isThreshold = typeof value === 'number'; GAPS_OPTIONS[2].value = isThreshold ? value : 3600000; // 1h diff --git a/public/app/plugins/panel/timeseries/config.ts b/public/app/plugins/panel/timeseries/config.ts index 39e6a283d01..1ad68d0584c 100644 --- a/public/app/plugins/panel/timeseries/config.ts +++ b/public/app/plugins/panel/timeseries/config.ts @@ -6,6 +6,7 @@ import { SetFieldConfigOptionsArgs, Field, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { BarAlignment, GraphDrawStyle, @@ -18,7 +19,7 @@ import { GraphThresholdsStyleMode, GraphTransform, } from '@grafana/schema'; -import { graphFieldOptions, commonOptionsBuilder } from '@grafana/ui'; +import { getGraphFieldOptions, commonOptionsBuilder } from '@grafana/ui'; import { InsertNullsEditor } from './InsertNullsEditor'; import { LineStyleEditor } from './LineStyleEditor'; @@ -42,11 +43,11 @@ export const defaultGraphConfig: GraphFieldConfig = { axisBorderShow: false, }; -const categoryStyles = ['Graph styles']; - export type NullEditorSettings = { isTime: boolean }; export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFieldConfigOptionsArgs { + const graphFieldOptions = getGraphFieldOptions(); + const categoryStyles = [t('timeseries.config.get-graph-field-config.category-graph-styles', 'Graph styles')]; return { standardOptions: { [FieldConfigProperty.Color]: { @@ -72,7 +73,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi builder .addRadio({ path: 'drawStyle', - name: 'Style', + name: t('timeseries.config.get-graph-field-config.name-style', 'Style'), category: categoryStyles, defaultValue: cfg.drawStyle, settings: { @@ -81,7 +82,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi }) .addRadio({ path: 'lineInterpolation', - name: 'Line interpolation', + name: t('timeseries.config.get-graph-field-config.name-line-interpolation', 'Line interpolation'), category: categoryStyles, defaultValue: cfg.lineInterpolation, settings: { @@ -91,7 +92,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi }) .addRadio({ path: 'barAlignment', - name: 'Bar alignment', + name: t('timeseries.config.get-graph-field-config.name-bar-alignment', 'Bar alignment'), category: categoryStyles, defaultValue: cfg.barAlignment, settings: { @@ -101,46 +102,49 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi }) .addSliderInput({ path: 'barWidthFactor', - name: 'Bar width factor', + name: t('timeseries.config.get-graph-field-config.name-bar-width-factor', 'Bar width factor'), category: categoryStyles, defaultValue: cfg.barWidthFactor, settings: { min: 0.1, max: 1.0, step: 0.1, - ariaLabelForHandle: 'Bar width factor', + ariaLabelForHandle: t( + 'timeseries.config.get-graph-field-config.aria-label-bar-width-factor', + 'Bar width factor' + ), }, showIf: (config) => config.drawStyle === GraphDrawStyle.Bars, }) .addSliderInput({ path: 'lineWidth', - name: 'Line width', + name: t('timeseries.config.get-graph-field-config.name-line-width', 'Line width'), category: categoryStyles, defaultValue: cfg.lineWidth, settings: { min: 0, max: 10, step: 1, - ariaLabelForHandle: 'Line width', + ariaLabelForHandle: t('timeseries.config.get-graph-field-config.aria-label-line-width', 'Line width'), }, showIf: (config) => config.drawStyle !== GraphDrawStyle.Points, }) .addSliderInput({ path: 'fillOpacity', - name: 'Fill opacity', + name: t('timeseries.config.get-graph-field-config.name-fill-opacity', 'Fill opacity'), category: categoryStyles, defaultValue: cfg.fillOpacity, settings: { min: 0, max: 100, step: 1, - ariaLabelForHandle: 'Fill opacity', + ariaLabelForHandle: t('timeseries.config.get-graph-field-config.aria-label-fill-opacity', 'Fill opacity'), }, showIf: (config) => config.drawStyle !== GraphDrawStyle.Points, }) .addRadio({ path: 'gradientMode', - name: 'Gradient mode', + name: t('timeseries.config.get-graph-field-config.name-gradient-mode', 'Gradient mode'), category: categoryStyles, defaultValue: graphFieldOptions.fillGradient[0].value, settings: { @@ -150,7 +154,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi }) .addFieldNamePicker({ path: 'fillBelowTo', - name: 'Fill below to', + name: t('timeseries.config.get-graph-field-config.name-fill-below-to', 'Fill below to'), category: categoryStyles, hideFromDefaults: true, settings: { @@ -160,7 +164,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi .addCustomEditor({ id: 'lineStyle', path: 'lineStyle', - name: 'Line style', + name: t('timeseries.config.get-graph-field-config.name-line-style', 'Line style'), category: categoryStyles, showIf: (config) => config.drawStyle === GraphDrawStyle.Line, editor: LineStyleEditor, @@ -171,7 +175,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi .addCustomEditor({ id: 'spanNulls', path: 'spanNulls', - name: 'Connect null values', + name: t('timeseries.config.get-graph-field-config.name-connect-nulls', 'Connect null values'), category: categoryStyles, defaultValue: false, editor: SpanNullsEditor, @@ -184,7 +188,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi .addCustomEditor({ id: 'insertNulls', path: 'insertNulls', - name: 'Disconnect values', + name: t('timeseries.config.get-graph-field-config.name-disconnect-values', 'Disconnect values'), category: categoryStyles, defaultValue: false, editor: InsertNullsEditor, @@ -196,7 +200,7 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi }) .addRadio({ path: 'showPoints', - name: 'Show points', + name: t('timeseries.config.get-graph-field-config.name-show-points', 'Show points'), category: categoryStyles, defaultValue: graphFieldOptions.showPoints[0].value, settings: { @@ -206,14 +210,14 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi }) .addSliderInput({ path: 'pointSize', - name: 'Point size', + name: t('timeseries.config.get-graph-field-config.name-point-size', 'Point size'), category: categoryStyles, defaultValue: 5, settings: { min: 1, max: 40, step: 1, - ariaLabelForHandle: 'Point size', + ariaLabelForHandle: t('timeseries.config.get-graph-field-config.aria-label-point-size', 'Point size'), }, showIf: (config) => config.showPoints !== VisibilityMode.Never || config.drawStyle === GraphDrawStyle.Points, }); @@ -222,19 +226,25 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi builder.addSelect({ category: categoryStyles, - name: 'Transform', + name: t('timeseries.config.get-graph-field-config.name-transform', 'Transform'), path: 'transform', settings: { options: [ { - label: 'Constant', + label: t('timeseries.config.get-graph-field-config.transform-options.label-constant', 'Constant'), value: GraphTransform.Constant, - description: 'The first value will be shown as a constant line', + description: t( + 'timeseries.config.get-graph-field-config.transform-options.description-constant', + 'The first value will be shown as a constant line' + ), }, { - label: 'Negative Y', + label: t('timeseries.config.get-graph-field-config.transform-options.label-style', 'Negative Y'), value: GraphTransform.NegativeY, - description: 'Flip the results to negative values on the y axis', + description: t( + 'timeseries.config.get-graph-field-config.transform-options.description-style', + 'Flip the results to negative values on the y axis' + ), }, ], isClearable: true, @@ -248,8 +258,8 @@ export function getGraphFieldConfig(cfg: GraphFieldConfig, isTime = true): SetFi builder.addCustomEditor({ id: 'thresholdsStyle', path: 'thresholdsStyle', - name: 'Show thresholds', - category: ['Thresholds'], + name: t('timeseries.config.get-graph-field-config.name-show-thresholds', 'Show thresholds'), + category: [t('timeseries.config.get-graph-field-config.category-thresholds', 'Thresholds')], defaultValue: { mode: GraphThresholdsStyleMode.Off }, settings: { options: graphFieldOptions.thresholdsDisplayModes, diff --git a/public/app/plugins/panel/timeseries/module.tsx b/public/app/plugins/panel/timeseries/module.tsx index 50ed7800b2e..beccdf480d6 100644 --- a/public/app/plugins/panel/timeseries/module.tsx +++ b/public/app/plugins/panel/timeseries/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { commonOptionsBuilder } from '@grafana/ui'; import { optsWithHideZeros } from '@grafana/ui/internal'; @@ -18,9 +19,9 @@ export const plugin = new PanelPlugin(TimeSeriesPanel) builder.addCustomEditor({ id: 'timezone', - name: 'Time zone', + name: t('timeseries.name-time-zone', 'Time zone'), path: 'timezone', - category: ['Axis'], + category: [t('timeseries.category-axis', 'Axis')], editor: TimezonesEditor, defaultValue: undefined, }); diff --git a/public/app/plugins/panel/traces/module.tsx b/public/app/plugins/panel/traces/module.tsx index 9c1696ab137..cb3bca215f0 100644 --- a/public/app/plugins/panel/traces/module.tsx +++ b/public/app/plugins/panel/traces/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin, toOption } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { getTraceServiceNames, getTraceSpanNames } from '../../../features/explore/TraceView/utils/tags'; import { transformDataFrames } from '../../../features/explore/TraceView/utils/transform'; @@ -9,25 +10,25 @@ import { TracesSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(TracesPanel) .setPanelOptions((builder, context) => { - const category = ['Span filters']; + const category = [t('traces.category-span-filters', 'Span filters')]; const trace = transformDataFrames(context?.data?.[0]); // Find builder .addTextInput({ path: 'spanFilters.query', - name: 'Find in trace', + name: t('traces.name-find-in-trace', 'Find in trace'), category, }) .addBooleanSwitch({ path: 'spanFilters.matchesOnly', - name: 'Show matches only', + name: t('traces.name-show-matches-only', 'Show matches only'), defaultValue: false, category, }) .addBooleanSwitch({ path: 'spanFilters.criticalPathOnly', - name: 'Show critical path only', + name: t('traces.name-critical-path-only', 'Show critical path only'), defaultValue: false, category, }); @@ -36,7 +37,7 @@ export const plugin = new PanelPlugin(TracesPanel) builder .addSelect({ path: 'spanFilters.serviceName', - name: 'Service name', + name: t('traces.name-service-name', 'Service name'), category, settings: { options: trace ? getTraceServiceNames(trace).map(toOption) : [], @@ -46,7 +47,7 @@ export const plugin = new PanelPlugin(TracesPanel) }) .addRadio({ path: 'spanFilters.serviceNameOperator', - name: 'Service name operator', + name: t('traces.name-service-name-operator', 'Service name operator'), defaultValue: '=', settings: { options: [ @@ -61,7 +62,7 @@ export const plugin = new PanelPlugin(TracesPanel) builder .addSelect({ path: 'spanFilters.spanName', - name: 'Span name', + name: t('traces.name-span-name', 'Span name'), category, settings: { options: trace ? getTraceSpanNames(trace).map(toOption) : [], @@ -71,7 +72,7 @@ export const plugin = new PanelPlugin(TracesPanel) }) .addRadio({ path: 'spanFilters.spanNameOperator', - name: 'Span name operator', + name: t('traces.name-span-name-operator', 'Span name operator'), defaultValue: '=', settings: { options: [ @@ -86,18 +87,18 @@ export const plugin = new PanelPlugin(TracesPanel) builder .addTextInput({ path: 'spanFilters.from', - name: 'Min duration', + name: t('traces.name-min-duration', 'Min duration'), category, }) .addTextInput({ path: 'spanFilters.to', - name: 'Max duration', + name: t('traces.name-max-duration', 'Max duration'), category, }); builder.addCustomEditor({ id: 'tags', - name: 'Tags', + name: t('traces.name-tags', 'Tags'), path: 'spanFilters', category, editor: TagsEditor, diff --git a/public/app/plugins/panel/trend/module.tsx b/public/app/plugins/panel/trend/module.tsx index 2d09bed7cec..ec823e00644 100644 --- a/public/app/plugins/panel/trend/module.tsx +++ b/public/app/plugins/panel/trend/module.tsx @@ -1,4 +1,5 @@ import { Field, FieldType, PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { commonOptionsBuilder } from '@grafana/ui'; import { optsWithHideZeros } from '@grafana/ui/internal'; @@ -11,16 +12,16 @@ import { TrendSuggestionsSupplier } from './suggestions'; export const plugin = new PanelPlugin(TrendPanel) .useFieldConfig(getGraphFieldConfig(defaultGraphConfig, false)) .setPanelOptions((builder) => { - const category = ['X axis']; + const category = [t('trend.category-x-axis', 'X axis')]; builder.addFieldNamePicker({ path: 'xField', - name: 'X field', - description: 'An increasing numeric value', + name: t('trend.name-x-field', 'X field'), + description: t('trend.description-x-field', 'An increasing numeric value'), category, defaultValue: undefined, settings: { isClearable: true, - placeholderText: 'First numeric value', + placeholderText: t('trend.placeholder-x-field', 'First numeric value'), filter: (field: Field) => field.type === FieldType.number, }, }); diff --git a/public/app/plugins/panel/xychart/SeriesEditor.tsx b/public/app/plugins/panel/xychart/SeriesEditor.tsx index 8e93c1344a6..a68cf297ac3 100644 --- a/public/app/plugins/panel/xychart/SeriesEditor.tsx +++ b/public/app/plugins/panel/xychart/SeriesEditor.tsx @@ -186,7 +186,9 @@ export const SeriesEditor = ({ !field.config.custom?.hideFrom?.viz, baseNameMode, placeholderText: - mapping === SeriesMapping.Auto ? 'First number or time field in each frame' : undefined, + mapping === SeriesMapping.Auto + ? t('xychart.series-editor.placeholder-x-field', 'First number or time field in each frame') + : undefined, }, }} /> @@ -221,7 +223,10 @@ export const SeriesEditor = ({ field.type === FieldType.number && !field.config.custom?.hideFrom?.viz, baseNameMode, - placeholderText: mapping === SeriesMapping.Auto ? 'Remaining number fields in each frame' : undefined, + placeholderText: + mapping === SeriesMapping.Auto + ? t('xychart.series-editor.placeholder-y-field', 'Remaining number fields in each frame') + : undefined, }, }} /> diff --git a/public/app/plugins/panel/xychart/config.ts b/public/app/plugins/panel/xychart/config.ts index bff3ffb8774..4e3b0fb1f08 100644 --- a/public/app/plugins/panel/xychart/config.ts +++ b/public/app/plugins/panel/xychart/config.ts @@ -5,6 +5,7 @@ import { identityOverrideProcessor, SetFieldConfigOptionsArgs, } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { LineStyle } from '@grafana/schema'; import { commonOptionsBuilder } from '@grafana/ui'; @@ -58,16 +59,18 @@ export function getScatterFieldConfig(cfg: FieldConfig): SetFieldConfigOptionsAr }, useCustomConfig: (builder) => { + const category = [t('xychart.category-xychart', 'XY Chart')]; builder .addRadio({ path: 'show', - name: 'Show', + name: t('xychart.name-show', 'Show'), + category, defaultValue: cfg.show, settings: { options: [ - { label: 'Points', value: XYShowMode.Points }, - { label: 'Lines', value: XYShowMode.Lines }, - { label: 'Both', value: XYShowMode.PointsAndLines }, + { label: t('xychart.show-options.label-points', 'Points'), value: XYShowMode.Points }, + { label: t('xychart.show-options.label-lines', 'Lines'), value: XYShowMode.Lines }, + { label: t('xychart.show-options.label-both', 'Both'), value: XYShowMode.PointsAndLines }, ], }, }) @@ -92,7 +95,8 @@ export function getScatterFieldConfig(cfg: FieldConfig): SetFieldConfigOptionsAr // ) .addSliderInput({ path: 'pointSize.fixed', - name: 'Point size', + name: t('xychart.name-point-size', 'Point size'), + category, defaultValue: cfg.pointSize?.fixed ?? DEFAULT_POINT_SIZE, settings: { min: 1, @@ -103,29 +107,33 @@ export function getScatterFieldConfig(cfg: FieldConfig): SetFieldConfigOptionsAr }) .addNumberInput({ path: 'pointSize.min', - name: 'Min point size', + name: t('xychart.name-min-point-size', 'Min point size'), + category, showIf: (c) => c.show !== XYShowMode.Lines, }) .addNumberInput({ path: 'pointSize.max', - name: 'Max point size', + name: t('xychart.name-max-point-size', 'Max point size'), + category, showIf: (c) => c.show !== XYShowMode.Lines, }) .addRadio({ path: 'pointShape', - name: 'Point shape', + name: t('xychart.name-point-shape', 'Point shape'), + category, defaultValue: PointShape.Circle, settings: { options: [ - { value: PointShape.Circle, label: 'Circle' }, - { value: PointShape.Square, label: 'Square' }, + { value: PointShape.Circle, label: t('xychart.point-shape-options.label-circle', 'Circle') }, + { value: PointShape.Square, label: t('xychart.point-shape-options.label-square', 'Square') }, ], }, showIf: (c) => c.show !== XYShowMode.Lines, }) .addSliderInput({ path: 'pointStrokeWidth', - name: 'Point stroke width', + name: t('xychart.name-point-stroke-width', 'Point stroke width'), + category, defaultValue: 1, settings: { min: 0, @@ -135,7 +143,8 @@ export function getScatterFieldConfig(cfg: FieldConfig): SetFieldConfigOptionsAr }) .addSliderInput({ path: 'fillOpacity', - name: 'Fill opacity', + name: t('xychart.name-fill-opacity', 'Fill opacity'), + category, defaultValue: 50, settings: { min: 0, @@ -147,7 +156,8 @@ export function getScatterFieldConfig(cfg: FieldConfig): SetFieldConfigOptionsAr .addCustomEditor({ id: 'lineStyle', path: 'lineStyle', - name: 'Line style', + name: t('xychart.name-line-style', 'Line style'), + category, showIf: (c) => c.show !== XYShowMode.Points, editor: LineStyleEditor, override: LineStyleEditor, @@ -156,7 +166,8 @@ export function getScatterFieldConfig(cfg: FieldConfig): SetFieldConfigOptionsAr }) .addSliderInput({ path: 'lineWidth', - name: 'Line width', + name: t('xychart.name-line-width', 'Line width'), + category, defaultValue: cfg.lineWidth, settings: { min: 0, diff --git a/public/app/plugins/panel/xychart/module.tsx b/public/app/plugins/panel/xychart/module.tsx index f0fd0b0b6a5..3c772258c6e 100644 --- a/public/app/plugins/panel/xychart/module.tsx +++ b/public/app/plugins/panel/xychart/module.tsx @@ -1,4 +1,5 @@ import { PanelPlugin } from '@grafana/data'; +import { t } from '@grafana/i18n'; import { commonOptionsBuilder } from '@grafana/ui'; import { SeriesEditor } from './SeriesEditor'; @@ -12,15 +13,17 @@ export const plugin = new PanelPlugin(XYChartPanel2) .setMigrationHandler(xyChartMigrationHandler) .useFieldConfig(getScatterFieldConfig(defaultFieldConfig)) .setPanelOptions((builder) => { + const category = [t('xychart.category-xychart', 'XY Chart')]; builder .addRadio({ path: 'mapping', - name: 'Series mapping', + name: t('xychart.name-series-mapping', 'Series mapping'), + category, defaultValue: 'auto', settings: { options: [ - { value: 'auto', label: 'Auto' }, - { value: 'manual', label: 'Manual' }, + { value: 'auto', label: t('xychart.series-mapping-options.label-auto', 'Auto') }, + { value: 'manual', label: t('xychart.series-mapping-options.label-manual', 'Manual') }, ], }, }) @@ -28,6 +31,7 @@ export const plugin = new PanelPlugin(XYChartPanel2) id: 'series', path: 'series', name: '', + category, editor: SeriesEditor, defaultValue: [{}], }); diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 3bc6c47ec73..da8b883534a 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -2948,10 +2948,52 @@ } }, "alertlist": { + "category-alert-state-filter": "Alert state filter", + "category-filter": "Filter", + "category-options": "Options", + "descriptino-alerts-linked-to-dashboard": "Only show alerts linked to this dashboard", + "description-alert-instance-label": "Filter alert instances using label querying, ex: {severity=\"critical\", instance=~\"cluster-us-.+\"}", + "description-alert-name": "Filter for alerts containing this text", + "description-datasource": "Filter from alert source", + "description-folder": "Filter for alerts in the selected folder (for Grafana-managed alert rules only)", + "description-group-by": "Filter alerts using label querying", + "description-group-mode": "How alert instances should be grouped", + "description-max-items": "Maximum alerts to display", + "description-show-inactive-alerts": "Include alert rules which have 0 (zero) instances. Because these rules have no instances, they remain hidden if the Alert instance label filter is configured.", + "description-sort-order": "Sort order of alerts and alert instances", + "description-view-mode": "Toggle between list view and stat view", "group-by": { "aria-label-group-by-label-keys": "group by label keys", "placeholder-group-by": "Group by" }, + "group-mode-options": { + "label-custom-grouping": "Custom grouping", + "label-default-grouping": "Default grouping" + }, + "name-alert-instance-label": "Alert instance label", + "name-alert-name": "Alert name", + "name-alerts-linked-to-dashboard": "Alerts linked to this dashboard", + "name-datasource": "Datasource", + "name-error": "Error", + "name-firing": "Alerting / Firing", + "name-folder": "Folder", + "name-group-by": "Group by", + "name-group-mode": "Group mode", + "name-max-items": "Max items", + "name-no-data": "No Data", + "name-normal": "Normal", + "name-pending": "Pending", + "name-recovering": "Recovering", + "name-show-inactive-alerts": "Show alerts with 0 instances", + "name-sort-order": "Sort order", + "name-view-mode": "View mode", + "sort-order-options": { + "label-alphabetical-asc": "Alphabetical (asc)", + "label-alphabetical-desc": "Alphabetical (desc)", + "label-importance": "Importance", + "label-time-asc": "Time (asc)", + "label-time-desc": "Time (desc)" + }, "ungrouped-mode-view": { "active-for": "for <1>{{duration}}", "aria-label-view-alert-rule": "View alert rule", @@ -2964,6 +3006,10 @@ "unified-alert-list-panel": { "body-permission-required": "Sorry, you do not have the required permissions to read alert rules.", "title-permission-required": "Permission required" + }, + "view-mode-options": { + "label-list": "List", + "label-stat": "Stat" } }, "annolist": { @@ -2975,6 +3021,32 @@ }, "annotation-list-item": { "tooltip-created-by": "Created by:<1> {{email}}" + }, + "category-annotation-query": "Annotation query", + "category-display": "Display", + "category-link-behaviour": "Link behavior", + "description-tags": "Match annotation tags", + "link-target-options": { + "label-dashboard": "Dashboard", + "label-panel": "Panel" + }, + "name-limit": "Limit", + "name-link-target": "Link target", + "name-query-filter": "Query filter", + "name-show-tags": "Show tags", + "name-show-time": "Show time", + "name-show-user": "Show user", + "name-tags": "Tags", + "name-time-after": "Time after", + "name-time-before": "Time before", + "name-time-range": "Time range", + "query-filter-options": { + "label-all-dashboards": "All dashboards", + "label-this-dashboard": "This dashboard" + }, + "time-range-options": { + "label-none": "None", + "label-this-dashboard": "This dashboard" } }, "annotations": { @@ -3184,11 +3256,96 @@ "subtitle": "Manage your auth settings and configure single sign-on. Find out more in our <2>documentation." }, "barchart": { + "config": { + "category-thresholds": "Thresholds", + "description-color-by-field": "Use the color value for a sibling field to color each bar value.", + "description-x-label-max-length": "X-axis labels will be truncated to the length provided", + "name-bar-radius": "Bar radius", + "name-bar-width": "Bar width", + "name-color-by-field": "Color by field", + "name-fill-opacity": "Fill opacity", + "name-full-highlight": "Highlight full area on hover", + "name-gradient-mode": "Gradient mode", + "name-group-width": "Group width", + "name-line-width": "Line width", + "name-orientation": "Orientation", + "name-rotate-x-labels": "Rotate x-axis tick labels", + "name-show-thresholds": "Show thresholds", + "name-show-values": "Show values", + "name-stacking": "Stacking", + "name-transform": "Transform", + "name-x-axis": "X Axis", + "name-x-label-max-length": "X-axis tick label max length", + "name-x-label-min-spacing": "X-axis labels minimum spacing", + "orientation-options": { + "label-auto": "Auto", + "label-horizontal": "Horizontal", + "label-line-vertical": "Vertical" + }, + "placeholder-x-axis": "First string or time field", + "placeholder-x-label-max-length": "None", + "show-values-options": { + "label-always": "Always", + "label-auto": "Auto", + "label-never": "Never" + }, + "transform-options": { + "description-constant": "The first value will be shown as a constant line", + "description-negative-y": "Flip the results to negative values on the y axis", + "label-constant": "Constant", + "label-negative-y": "Negative Y" + } + }, "tick-spacing-editor": { "content-require-space-from-the-right-side": "Require space from the right side", + "gaps-options": { + "description-large": "Require {{spacing}} spacing", + "description-medium": "Require {{spacing}} spacing", + "description-none": "Show all tick marks", + "description-small": "Require {{spacing}} spacing", + "label-large": "Large", + "label-medium": "Medium", + "label-none": "None", + "label-small": "Small" + }, "label-rtl": "RTL" } }, + "bargauge": { + "bar-size-options": { + "label-auto": "Auto", + "label-manual": "Manual" + }, + "category-bar-gauge": "Bar gauge", + "description-max-height": "Maximum row height (horizontal orientation)", + "description-min-height": "Minimum row height (horizontal orientation)", + "description-min-width": "Minimum column width (vertical orientation)", + "description-show-unfilled-area": "When enabled renders the unfilled region as gray", + "display-mode-options": { + "label-basic": "Basic", + "label-gradient": "Gradient", + "label-retro": "Retro LCD" + }, + "name-bar-size": "Bar size", + "name-display-mode": "Display mode", + "name-max-height": "Max height", + "name-min-height": "Min height", + "name-min-width": "Min width", + "name-name-placement": "Name placement", + "name-placement-options": { + "label-auto": "Auto", + "label-hidden": "Hidden", + "label-left": "Left", + "label-top": "Top" + }, + "name-show-unfilled-area": "Show unfilled area", + "name-value-display": "Value display", + "value-display-options": { + "label-hidden": "Hidden", + "label-text-color": "Text color", + "label-value-color": "Value color" + } + }, "bookmarks-page": { "empty": { "message": "It looks like you haven’t created any bookmarks yet", @@ -3316,6 +3473,43 @@ }, "text-this-repository-is-read-only": "If you have direct access to the target, copy the JSON and paste it there." }, + "candlestick": { + "additional-fields-options": { + "label-ignore": "Ignore", + "label-include": "Include" + }, + "candle-style-options": { + "label-candles": "Candles", + "label-ohlc-bars": "OHLC Bars" + }, + "category-candlestick": "Candlestick", + "color-strategy-options": { + "label-since-open": "Since Open", + "label-since-prior-close": "Since Prior Close" + }, + "description-additional-fields": "Use standard timeseries options to configure any fields not mapped above", + "description-close": "Value at the end of the period", + "description-high": "Maximum value within the period", + "description-low": "Minimum value within the period", + "description-open": "Value at the start of the period", + "description-volume": "Sample count within the period", + "mode-options": { + "label-both": "Both", + "label-candles": "Candles", + "label-volume": "Volume" + }, + "name-additional-fields": "Additional fields", + "name-candle-style": "Candle style", + "name-close": "Close", + "name-color-strategy": "Color strategy", + "name-down-color": "Down color", + "name-high": "High", + "name-low": "Low", + "name-mode": "Mode", + "name-open": "Open", + "name-up-color": "Up color", + "name-volume": "Volume" + }, "canvas": { "apieditor": { "label-endpoint": "Endpoint", @@ -4186,6 +4380,7 @@ "get-field-override-categories": { "label-add-field-override": "Add field override", "label-add-override-property": "Add override property", + "override-name": "Override {{overrideNum}}", "title": { "add-button": "add button" } @@ -5189,6 +5384,9 @@ "remove-panel": "Remove panel" } }, + "panel-data-alerting-tab": { + "tab-label": "Alert" + }, "panel-data-alerting-tab-rendered": { "alert": { "title-errors-loading-rules": "Errors loading rules" @@ -5197,10 +5395,16 @@ "text-loading-rules": "Loading rules...", "title-dashboard-not-saved": "Dashboard not saved" }, + "panel-data-queries-tab": { + "tab-label": "Queries" + }, "panel-data-queries-tab-rendered": { "add-query": "Add query", "expression": "Expression " }, + "panel-data-transformations-tab": { + "tab-label": "Transformations" + }, "panel-data-transformations-tab-rendered": { "add-another-transformation": "Add another transformation", "delete-all-transformations": "Delete all transformations", @@ -5602,6 +5806,20 @@ } } }, + "dashlist": { + "category-dashboard-list": "Dashboard list", + "name-folder": "Folder", + "name-include-current-template-variables": "Include current template variable values", + "name-include-current-time-range": "Include current time range", + "name-max-items": "Max items", + "name-query": "Query", + "name-recently-viewed": "Recently viewed", + "name-search": "Search", + "name-show-folder-names": "Show folder names", + "name-show-headings": "Show headings", + "name-starred": "Starred", + "name-tags": "Tags" + }, "data-source-list": { "empty-state": { "button-title": "Add data source", @@ -5909,7 +6127,18 @@ "add-threshold": "Add threshold", "aria-label-threshold": "Threshold {{thresholdNumber}}", "description-percentage-means-thresholds-relative": "Percentage means thresholds relative to min & max", - "thresholds-mode": "Thresholds mode" + "modes": { + "description": { + "threshold-based-percent-between-minmax": "Pick threshold based on the percent between min/max", + "thresholds-based-absolute-values": "Pick thresholds based on the absolute values" + }, + "label": { + "absolute": "Absolute", + "percentage": "Percentage" + } + }, + "thresholds-mode": "Thresholds mode", + "value-base": "Base" }, "urlpicker-tab": { "label-preview": "Preview" @@ -6703,6 +6932,25 @@ "discard-button": "Discard unsaved changes", "title": "Leave page?" }, + "gauge": { + "category-gauge": "Gauge", + "description-min-height": "Minimum row height (horizontal orientation)", + "description-min-width": "Minimum column width (vertical orientation)", + "description-neutral": "Leave empty to use Min as neutral point", + "description-show-threshold-labels": "Render the threshold values around the gauge bar", + "description-show-threshold-markers": "Renders the thresholds as an outer bar", + "gauge-size-options": { + "label-auto": "Auto", + "label-manual": "Manual" + }, + "name-gauge-size": "Gauge size", + "name-min-height": "Min height", + "name-min-width": "Min width", + "name-neutral": "Neutral", + "name-show-threshold-labels": "Show threshold labels", + "name-show-threshold-markers": "Show threshold markers", + "placeholder-neutral": "auto" + }, "gen-ai": { "apply-suggestion": "Apply", "incomplete-request-error": "Sorry, I was unable to complete your request. Please try again.", @@ -6933,6 +7181,90 @@ "linear-threshold": "Linear threshold", "log-base": "Log base" }, + "builder": { + "axis": { + "category-axis": "Axis", + "color-label": "Color", + "color-options": { + "label-series": "Series", + "label-text": "Text" + }, + "grid-line-options": { + "label-auto": "Auto", + "label-off": "Off", + "label-on": "On" + }, + "name-centered-zero": "Centered zero", + "name-grid-lines": "Show grid lines", + "name-label": "Label", + "name-placement": "Placement", + "name-scale": "Scale", + "name-show-border": "Show border", + "name-soft-max": "Soft max", + "name-soft-min": "Soft min", + "name-width": "Width", + "placeholder-label": "Optional text", + "placeholder-soft-max": "See: Standard options > Max", + "placeholder-soft-min": "See: Standard options > Min", + "placeholder-width": "Auto", + "scale-distribution-editor": { + "distribution-options": { + "label-linear": "Linear", + "label-log": "Logarithmic", + "label-symlog": "Symlog" + } + } + }, + "legend": { + "category": "Legend", + "description-values": "Select values or calculations to show in legend", + "mode-options": { + "label-list": "List", + "label-table": "Table" + }, + "name-mode": "Mode", + "name-placement": "Placement", + "name-values": "Values", + "name-visibility": "Visibility", + "name-width": "Width", + "placement-options": { + "label-bottom": "Bottom", + "label-right": "Right" + } + }, + "stacking": { + "name-stack-series": "Stack series" + }, + "text": { + "category-text-size": "Text size", + "name-percent-change": "Percent change", + "name-title": "Title", + "name-value": "Value", + "placeholder-percent-change": "Auto", + "placeholder-title": "Auto", + "placeholder-value": "Auto" + }, + "tooltip": { + "category": "Tooltip", + "description-hover-proximity": "How close the cursor must be to a point to trigger the tooltip, in pixels", + "modeOptions": { + "label-all": "All", + "label-hidden": "Hidden", + "label-single": "Single" + }, + "name-hide-zeros": "Hide zeros", + "name-hover-proximity": "Hover proximity", + "name-max-height": "Max height", + "name-max-width": "Max width", + "name-tooltip-mode": "Tooltip mode", + "name-values-sort-order": "Values sort order", + "sortOptions": { + "label-ascending": "Ascending", + "label-descending": "Descending", + "label-none": "None" + } + } + }, "card": { "option": "option" }, @@ -7089,6 +7421,21 @@ "tooltip-collapse-all": "Collapse all rows", "tooltip-expand-all": "Expand all rows" }, + "matchers-ui": { + "description-field-name-by-regex-matcher": "Set properties for fields with names matching a regex", + "description-fields-by-query": "Set properties for fields from a specific query", + "description-fields-with-name": "Set properties for a specific field", + "description-fields-with-type": "Set properties for fields of a specific type (number, string, boolean)", + "description-fields-with-value": "Set properties for fields with reducer condition", + "field-name-picker": { + "placeholder": "Select field" + }, + "name-field-name-by-regex-matcher": "Fields with name matching regex", + "name-fields-by-query": "Fields returned by query", + "name-fields-with-name": "Fields with name", + "name-fields-with-type": "Fields with type", + "name-fields-with-value": "Fields with values" + }, "menu-item": { "keyboard-shortcut-label": "Keyboard shortcut" }, @@ -7201,6 +7548,63 @@ "toolbar-button-row": { "show-more": "Show more items" }, + "u-plot": { + "config": { + "get-graph-field-options": { + "axis-placement": { + "description-auto": "First field on the left, everything else on the right", + "label-auto": "Auto", + "label-hidden": "Hidden", + "label-left": "Left", + "label-right": "Right" + }, + "bar-alignment": { + "description-after": "After", + "description-before": "Before", + "description-center": "Center" + }, + "draw-style": { + "label-bars": "Bars", + "label-lines": "Lines", + "label-points": "Points" + }, + "fill-gradient": { + "description-hue": "Small color hue gradient", + "description-opacity": "Enable fill opacity gradient", + "description-scheme": "Use color scheme to define gradient", + "label-hue": "Hue", + "label-none": "None", + "label-opacity": "Opacity", + "label-scheme": "Scheme" + }, + "line-interpolation": { + "description-linear": "Linear", + "description-smooth": "Smooth", + "description-step-after": "Step after", + "description-step-before": "Step before" + }, + "show-points": { + "description-auto": "Show points when the density is low", + "label-always": "Always", + "label-auto": "Auto", + "label-never": "Never" + }, + "stacking": { + "label-100": "100%", + "label-normal": "Normal", + "label-off": "Off" + }, + "thresholds-display-mode": { + "label-dashed-lines": "As lines (dashed)", + "label-filled-regions": "As filled regions", + "label-filled-regions-and-dashed-lines": "As filled regions and lines (dashed)", + "label-filled-regions-and-lines": "As filled regions and lines", + "label-lines": "As lines", + "label-off": "Off" + } + } + } + }, "unit-picker": { "placeholder": "Choose" }, @@ -7235,6 +7639,82 @@ "title": "Graph" } }, + "heatmap": { + "calculate-from-data-options": { + "label-no": "No", + "label-yes": "Yes" + }, + "category-cell-display": "Cell display", + "category-colors": "Colors", + "category-exemplars": "Exemplars", + "category-heatmap": "Heatmap", + "category-legend": "Legend", + "category-tooltip": "Tooltip", + "category-y-axis": "Y Axis", + "mode-options": { + "label-opacity": "Opacity", + "label-scheme": "Scheme" + }, + "name-axis-label": "Axis label", + "name-axis-width": "Axis width", + "name-calculate-from-data": "Calculate from data", + "name-cell-gap": "Cell gap", + "name-color": "Color", + "name-decimals": "Decimals", + "name-end-color-at-value": "End color scale at value", + "name-exponent": "Exponent", + "name-hide-cells-gt": "Hide cells with values >=", + "name-hide-cells-lt": "Hide cells with values <=", + "name-max-height": "Max height", + "name-max-value": "Max value", + "name-max-width": "Max width", + "name-min-value": "Min value", + "name-mode": "Mode", + "name-placement": "Placement", + "name-reverse": "Reverse", + "name-scale": "Scale", + "name-scheme": "Scheme", + "name-show-color-scale": "Show color scale", + "name-show-histogram": "Show histogram (Y axis)", + "name-show-legend": "Show legend", + "name-start-color-from-value": "Start color scale from value", + "name-steps": "Steps", + "name-tick-alignment": "Tick alignment", + "name-tooltip-mode": "Tooltip mode", + "name-unit": "Unit", + "name-value-name": "Value name", + "name-y-axis-scale": "Y axis scale", + "placeholder-axis-label": "Auto", + "placeholder-axis-width": "Auto", + "placeholder-decimals": "Auto", + "placeholder-end-color-at-value": "Auto (max)", + "placeholder-hide-cells-gt": "None", + "placeholder-hide-cells-lt": "None", + "placeholder-max-value": "Auto", + "placeholder-min-value": "Auto", + "placeholder-start-color-from-value": "Auto (min)", + "placeholder-value-name": "Value", + "placement-options": { + "label-hidden": "Hidden", + "label-left": "Left", + "label-right": "Right" + }, + "scale-options": { + "label-exponential": "Exponential", + "label-linear": "Linear" + }, + "tick-alignment-options": { + "label-auto": "Auto", + "label-bottom": "Bottom (GE)", + "label-middle": "Middle", + "label-top": "Top (LE)" + }, + "tooltip-mode-options": { + "label-all": "All", + "label-hidden": "Hidden", + "label-single": "Single" + } + }, "help-modal": { "column-headers": { "description": "Description", @@ -7292,9 +7772,14 @@ "troubleshooting-help": "To request troubleshooting help, send a snapshot of this panel to Grafana Labs Technical Support. The snapshot contains query response data and panel settings." }, "histogram": { + "category-histogram": "Histogram", "histogram-panel": { "no-histogram-found-in-response": "No histogram found in response" - } + }, + "name-fill-opacity": "Fill opacity", + "name-gradient-mode": "Gradient mode", + "name-line-width": "Line width", + "name-stacking": "Stacking" }, "inspector": { "inspect-data-tab": { @@ -7673,6 +8158,20 @@ } }, "logs": { + "category-logs": "Logs", + "deduplication-options": { + "label-exact": "Exact", + "label-none": "None", + "label-numbers": "Numbers", + "label-signature": "Signature" + }, + "description-enable-infinite-scrolling": "Experimental. Request more results by scrolling to the bottom of the logs list.", + "description-enable-syntax-highlighting": "Use a predefined syntax coloring grammar to highlight relevant parts of the log lines", + "description-show-controls": "Display controls to jump to the last or first log line, and filters by log level", + "font-size-options": { + "label-default": "Default", + "label-small": "Small" + }, "get-dataframe-fields": { "vars": { "text": { @@ -7816,6 +8315,22 @@ "common-labels": "Common labels:" } }, + "name-common-labels": "Common labels", + "name-deduplication": "Deduplication", + "name-enable-infinite-scrolling": "Enable infinite scrolling", + "name-enable-log-details": "Enable log details", + "name-enable-syntax-highlighting": "Enable syntax highlighting", + "name-font-size": "Font size", + "name-order": "Order", + "name-prettify-json": "Prettify JSON", + "name-show-controls": "Show controls", + "name-time": "Time", + "name-unique-labels": "Unique labels", + "name-wrap-lines": "Wrap lines", + "order-options": { + "label-newest-first": "Newest first", + "label-oldest-first": "Oldest first" + }, "out-of-range-message": { "end-of-the-selected-time-range": "End of the selected time range." }, @@ -7847,6 +8362,30 @@ "label-log-stats": "{{label}}: {{total}} of {{rowCount}} rows have that label" } }, + "logs-new": { + "category-logs": "Logs", + "deduplication-options": { + "label-exact": "Exact", + "label-none": "None", + "label-numbers": "Numbers", + "label-signature": "Signature" + }, + "description-infinite-scrolling": "Experimental. Request more results by scrolling to the bottom of the logs list.", + "description-show-controls": "Display controls to jump to the last or first log line, and filters by log level", + "description-syntax-highlighting": "Use a predefined syntax coloring grammar to highlight relevant parts of the log lines", + "name-deduplication": "Deduplication", + "name-enable-log-details": "Enable log details", + "name-infinite-scrolling": "Enable infinite scrolling", + "name-order": "Order", + "name-show-controls": "Show controls", + "name-syntax-highlighting": "Enable syntax highlighting", + "name-time": "Time", + "name-wrap-lines": "Wrap lines", + "order-options": { + "label-newest-first": "Newest first", + "label-oldest-first": "Oldest first" + } + }, "manage-dashbaords": { "import-dashboard-form": { "description-existing-library-panels": "List of existing library panels. These panels are not affected by the import." @@ -8529,7 +9068,12 @@ "rss-button": "Latest from the blog" }, "news": { + "category-news": "News", + "description-show-image": "Controls if the news item social (og:image) image is shown above text content", + "description-url": "Supports RSS and Atom feeds", "link-title": "Go to Grafana labs blog", + "name-show-image": "Show image", + "name-url": "URL", "news-panel": { "body-error-loading-rss-feed": "Make sure that the feed URL is correct and that CORS is configured correctly on the server. See <2>News panel documentation.", "loading": "Loading...", @@ -8537,6 +9081,30 @@ }, "title": "Latest from the blog" }, + "node-graph": { + "category-edges": "Edges", + "category-node-graph": "Node graph", + "category-nodes": "Nodes", + "layout-algorithm-options": { + "description-force": "Use a force-directed layout", + "description-grid": "Use a grid layout", + "description-layered": "Use a layered layout", + "label-force": "Force", + "label-grid": "Grid", + "label-layered": "Layered" + }, + "name-arc-sections": "Arc sections", + "name-layout-algorithm": "Layout algorithm", + "name-main-stat-unit": "Main stat unit", + "name-secondary-stat-unit": "Secondary stat unit", + "name-zoom-mode": "Zoom mode", + "zoom-mode-options": { + "description-cooperative": "Lets you scroll the page normally", + "description-greedy": "Reacts to all zoom gestures", + "label-cooperative": "Cooperative", + "label-greedy": "Greedy" + } + }, "nodeGraph": { "arc-options-editor": { "add-arc": "Add arc", @@ -8611,6 +9179,44 @@ "field-color": { "color-by-label": "Color series by" }, + "registry": { + "get-all-option-editors": { + "description-time-zone": "Time zone selection", + "name-time-zone": "Time zone" + }, + "standard-field-condigs": { + "category-data-links": "Data links and actions" + }, + "standard-field-configs": { + "category": "Standard options", + "category-thresholds": "Thresholds", + "category-value-mappings": "Value mappings", + "description-display-name": "Change the field or series name", + "description-field-min-max": "Calculate min max per field", + "description-max": "Leave empty to calculate based on all values", + "description-min": "Leave empty to calculate based on all values", + "description-no-value": "What to show when there is no value", + "description-value-mappings": "Modify the display text based on input value", + "name-actions": "Actions", + "name-ad-hoc": "Ad-hoc filterable", + "name-color-scheme": "Color scheme", + "name-data-links": "Data links", + "name-decimals": "Decimals", + "name-display-name": "Display name", + "name-field-min-max": "Field min/max", + "name-max": "Max", + "name-min": "Min", + "name-no-value": "No value", + "name-thresholds": "Thresholds", + "name-unit": "Unit", + "name-value-mappings": "Value mappings", + "placeholder-decimals": "auto", + "placeholder-display-name": "none", + "placeholder-max": "auto", + "placeholder-min": "auto", + "placeholder-unit": "none" + } + }, "units": { "clear-tooltip": "Clear unit selection" } @@ -8752,6 +9358,28 @@ "select-no-options": "No panel types found", "select-placeholder": "Filter by type" }, + "piechart": { + "category-legend": "Legend", + "category-pie-chart": "Pie chart", + "description-labels": "Select the labels to be displayed in the pie chart", + "description-pie-chart-type": "How the pie chart should be rendered", + "labels-options": { + "label-name": "Name", + "label-percent": "Percent", + "label-value": "Value" + }, + "legend-values-options": { + "label-percent": "Percent", + "label-value": "Value" + }, + "name-labels": "Labels", + "name-legend-values": "Legend values", + "name-pie-chart-type": "Pie chart type", + "pie-chart-type-options": { + "label-donut": "Donut", + "label-pie": "Pie" + } + }, "playlist": { "playlist-new-page": { "page-nav": { @@ -10368,7 +10996,115 @@ "sort-picker": { "select-aria-label": "Sort" }, + "stat": { + "add-orientation-option": { + "description-orientation": "Layout orientation", + "name-orientation": "Orientation", + "orientation-options": { + "label-auto": "Auto", + "label-horizontal": "Horizontal", + "label-vertical": "Vertical" + } + }, + "add-standard-data-reduce-options": { + "category-value-options": "Value options", + "description-calculation": "Choose a reducer function / calculation", + "description-fields": "Select the fields that should be included in the panel", + "description-limit": "Max number of rows to display", + "description-show": "Calculate a single value per column or series or show each row", + "fields-options": { + "label-all-fields": "All Fields", + "label-numeric-fields": "Numeric Fields" + }, + "name-calculation": "Calculation", + "name-fields": "Fields", + "name-limit": "Limit", + "name-show": "Show", + "show-options": { + "label-all-values": "All values", + "label-calculate": "Calculate" + } + }, + "category-stat-styles": "Stat styles", + "color-mode-options": { + "label-background-gradient": "Background Gradient", + "label-background-solid": "Background Solid", + "label-none": "None", + "label-value": "Value" + }, + "description-graph-mode": "Stat panel graph / sparkline mode", + "description-text-mode": "Control if name and value is displayed or just name", + "graph-mode": { + "options": { + "label-area": "Area", + "label-none": "None" + } + }, + "name-color-modcolor-mode-options": { + "label": "Color mode" + }, + "name-graph-mode": "Graph mode", + "name-show-percent-change": "Show percent change", + "name-text-alignment": "Text alignment", + "name-text-mode": "Text mode", + "name-wide-layout": "Wide layout", + "percent-change-color-mode": "Percent change color mode", + "percent-change-color-mode-options": { + "label-inverted": "Inverted", + "label-same-as-value": "Same as Value", + "label-standard": "Standard" + }, + "text-alignment-options": { + "label-auto": "Auto", + "label-center": "Center" + }, + "text-mode-options": { + "label-auto": "Auto", + "label-name": "Name", + "label-none": "None", + "label-value": "Value", + "label-value-and-name": "Value and name" + }, + "wide-layout-options": { + "label-off": "Off", + "label-on": "On" + } + }, + "state-timeline": { + "align-values-options": { + "label-center": "Center", + "label-left": "Left", + "label-right": "Right" + }, + "category-state-timeline": "State timeline", + "name-align-values": "Align values", + "name-connect-null-values": "Connect null values", + "name-disconnect-values": "Disconnect values", + "name-fill-opacity": "Fill opacity", + "name-line-width": "Line width", + "name-merge-equal-consecutive-values": "Merge equal consecutive values", + "name-page-size": "Page size (enable pagination)", + "name-row-height": "Row height", + "name-show-values": "Show values", + "show-values-options": { + "label-always": "Always", + "label-auto": "Auto", + "label-never": "Never" + } + }, "status-history": { + "category-status-history": "Status history", + "name-column-width": "Column width", + "name-fill-opacity": "Fill opacity", + "name-line-width": "Line width", + "name-page-size": "Page size (enable pagination)", + "name-row-height": "Row height", + "name-show-values": "Show values", + "show-values-options": { + "label-always": "Always", + "label-auto": "Auto", + "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_other": "Too many points to visualize properly. <1>Update the query to return fewer points. <3>({{count}} points received)" @@ -10407,6 +11143,14 @@ "label-gauge-display-mode": "Gauge display mode", "label-value-display": "Value display" }, + "category-cell-options": "Cell options", + "category-table": "Table", + "category-table-footer": "Table footer", + "cell-height-options": { + "label-large": "Large", + "label-medium": "Medium", + "label-small": "Small" + }, "color-background-cell-options-editor": { "description-apply-to-entire-row": "If selected the entire row will be colored as this cell would be.", "description-wrap-text": "If selected text will be wrapped to the width of text in the configured column", @@ -10418,17 +11162,83 @@ "label-wrap-text": "Wrap text", "wrap-text": "Wrap text" }, + "column-alignment-options": { + "label-auto": "Auto", + "label-center": "Center", + "label-left": "Left", + "label-right": "Right" + }, "container": { "content": "Showing too many columns in a single table may impact performance and make data harder to read. Consider refining your queries.", "show-all-series": "Show all columns", "show-only-series": "Showing only {{MAX_NUMBER_OF_COLUMNS}} columns" }, + "description-calculation": "Choose a reducer function / calculation", + "description-cell-value-inspect": "Enable cell value inspection in a modal window", + "description-column-filter": "Enables/disables field filters in table", + "description-count-rows": "Display a single count for all data rows", + "description-fields": "Select the fields that should be calculated", + "description-min-column-width": "The minimum width for column auto resizing", "image-cell-options-editor": { "description-alt-text": "Alternative text that will be displayed if an image can't be displayed or for users who use a screen reader", "description-title-text": "Text that will be displayed when the image is hovered by a cursor", "label-alt-text": "Alt text", "label-title-text": "Title text" - } + }, + "name-calculation": "Calculation", + "name-cell-height": "Cell height", + "name-cell-type": "Cell type", + "name-cell-value-inspect": "Cell value inspect", + "name-column-alignment": "Column alignment", + "name-column-filter": "Column filter", + "name-column-width": "Column width", + "name-count-rows": "Count rows", + "name-enable-paginations": "Enable pagination", + "name-fields": "Fields", + "name-hide-in-table": "Hide in table", + "name-min-column-width": "Minimum column width", + "name-show-table-footer": "Show table footer", + "name-show-table-header": "Show table header", + "placeholder-column-width": "auto", + "placeholder-fields": "All Numeric Fields" + }, + "table-new": { + "category-cell-options": "Cell options", + "category-table": "Table", + "category-table-footer": "Table footer", + "cell-height-options": { + "label-large": "Large", + "label-medium": "Medium", + "label-small": "Small" + }, + "column-alignment-options": { + "label-auto": "Auto", + "label-center": "Center", + "label-left": "Left", + "label-right": "Right" + }, + "description-calculation": "Choose a reducer function / calculation", + "description-cell-value-inspect": "Enable cell value inspection in a modal window", + "description-column-filter": "Enables/disables field filters in table", + "description-count-rows": "Display a single count for all data rows", + "description-fields": "Select the fields that should be calculated", + "description-min-column-width": "The minimum width for column auto resizing", + "name-calculation": "Calculation", + "name-cell-height": "Cell height", + "name-cell-type": "Cell type", + "name-cell-value-inspect": "Cell value inspect", + "name-column-alignment": "Column alignment", + "name-column-filter": "Column filter", + "name-column-width": "Column width", + "name-count-rows": "Count rows", + "name-enable-pagination": "Enable pagination", + "name-fields": "Fields", + "name-hide-in-table": "Hide in table", + "name-min-column-width": "Minimum column width", + "name-show-table-footer": "Show table footer", + "name-show-table-header": "Show table header", + "placeholder-column-width": "auto", + "placeholder-fields": "All Numeric Fields" }, "tag-filter": { "clear-button": "Clear tags", @@ -10511,6 +11321,19 @@ "description": "Team Sync makes it easier for you to manage users' access in Grafana, by immediately updating each user's Grafana teams and permissions based on their single sign-on group membership, instead of when users sign in" } }, + "text": { + "category-text": "Text", + "mode-options": { + "label-code": "Code", + "label-html": "HTML", + "label-markdown": "Markdown" + }, + "name-content": "Content", + "name-language": "Language", + "name-mode": "Mode", + "name-show-line-numbers": "Show line numbers", + "name-show-mini-map": "Show mini map" + }, "theme-preview": { "breadcrumbs": { "dashboards": "Dashboards", @@ -10601,10 +11424,54 @@ "tooltip-delete": "Delete", "tooltip-edit": "Edit" }, + "category-axis": "Axis", + "config": { + "get-graph-field-config": { + "aria-label-bar-width-factor": "Bar width factor", + "aria-label-fill-opacity": "Fill opacity", + "aria-label-line-width": "Line width", + "aria-label-point-size": "Point size", + "category-graph-styles": "Graph styles", + "category-thresholds": "Thresholds", + "name-bar-alignment": "Bar alignment", + "name-bar-width-factor": "Bar width factor", + "name-connect-nulls": "Connect null values", + "name-disconnect-values": "Disconnect values", + "name-fill-below-to": "Fill below to", + "name-fill-opacity": "Fill opacity", + "name-gradient-mode": "Gradient mode", + "name-line-interpolation": "Line interpolation", + "name-line-style": "Line style", + "name-line-width": "Line width", + "name-point-size": "Point size", + "name-show-points": "Show points", + "name-show-thresholds": "Show thresholds", + "name-style": "Style", + "name-transform": "Transform", + "transform-options": { + "description-constant": "The first value will be shown as a constant line", + "description-style": "Flip the results to negative values on the y axis", + "label-constant": "Constant", + "label-style": "Negative Y" + } + } + }, + "insert-nulls-editor": { + "disconnect-options": { + "label-never": "Never", + "label-threshold": "Threshold" + } + }, "line-style-editor": { + "line-fill-options": { + "label-dash": "Dash", + "label-dots": "Dots", + "label-solid": "Solid" + }, "title-the-input-expects-a-segment-list": "The input expects a segment list", "tooltip-help": "Help" }, + "name-time-zone": "Time zone", "nulls-threshold-input": { "placeholder-never": "Never" }, @@ -10612,12 +11479,30 @@ "data-outside-time-range": "Data outside time range", "zoom-to-data": "Zoom to data" }, + "span-nulls-editor": { + "gaps-options": { + "label-always": "Always", + "label-never": "Never", + "label-threshold": "Threshold" + } + }, "timezones-editor": { "tooltip-add-timezone": "Add timezone", "tooltip-remove-timezone": "Remove timezone" } }, "traces": { + "category-span-filters": "Span filters", + "name-critical-path-only": "Show critical path only", + "name-find-in-trace": "Find in trace", + "name-max-duration": "Max duration", + "name-min-duration": "Min duration", + "name-service-name": "Service name", + "name-service-name-operator": "Service name operator", + "name-show-matches-only": "Show matches only", + "name-span-name": "Span name", + "name-span-name-operator": "Span name operator", + "name-tags": "Tags", "traces-panel": { "no-data-found-in-response": "No data found in response" } @@ -10630,6 +11515,24 @@ }, "transformers": { "axis-editor": { + "log-mode-options": { + "description": { + "split-the-buckets-based-on-size": "Split the buckets based on size" + }, + "label": { + "split": "Split" + } + }, + "mode-options": { + "description": { + "split-the-buckets-based-on-count": "Split the buckets based on count", + "split-the-buckets-based-on-size": "Split the buckets based on size" + }, + "label": { + "count": "Count", + "size": "Size" + } + }, "placeholder-auto": "Auto" }, "basic-matcher-editor": { @@ -10645,6 +11548,13 @@ "label-mode": "Mode", "label-replace-all-fields": "Replace all fields" }, + "calculate-heatmap": { + "add-heatmap-calculation-options": { + "name-x-bucket": "X Bucket", + "name-y-bucket": "Y Bucket", + "name-y-bucket-scale": "Y Bucket scale" + } + }, "concatenate-transformer-editor": { "label-label": "Label", "label-name": "Name", @@ -11030,6 +11940,12 @@ } } }, + "trend": { + "category-x-axis": "X axis", + "description-x-field": "An increasing numeric value", + "name-x-field": "X field", + "placeholder-x-field": "First numeric value" + }, "upgrade-box": { "discovery-text": "You’ve discovered a Pro feature!", "discovery-text-continued": "Get the Grafana Pro plan to access {{featureName}}.", @@ -11255,6 +12171,21 @@ } }, "xychart": { + "category-xychart": "XY Chart", + "name-fill-opacity": "Fill opacity", + "name-line-style": "Line style", + "name-line-width": "Line width", + "name-max-point-size": "Max point size", + "name-min-point-size": "Min point size", + "name-point-shape": "Point shape", + "name-point-size": "Point size", + "name-point-stroke-width": "Point stroke width", + "name-series-mapping": "Series mapping", + "name-show": "Show", + "point-shape-options": { + "label-circle": "Circle", + "label-square": "Square" + }, "series-editor": { "add-series": "Add series", "aria-label-select-series": "Select series {{seriesNum}}", @@ -11265,7 +12196,18 @@ "label-y-field": "Y field", "placeholder-all-frames": "All frames", "placeholder-select-frame": "Select frame", + "placeholder-x-field": "First number or time field in each frame", + "placeholder-y-field": "Remaining number fields in each frame", "tooltip-delete-series": "Delete series" + }, + "series-mapping-options": { + "label-auto": "Auto", + "label-manual": "Manual" + }, + "show-options": { + "label-both": "Both", + "label-lines": "Lines", + "label-points": "Points" } } }