Internationalisation: Lint rule improvement (#103788)

* improve autofix so it can fix foo={"bar"}

* apply fixes

* fix type checks + betterer

* tweak to make types happy
This commit is contained in:
Ashley Harrison
2025-04-10 16:22:52 +01:00
committed by GitHub
parent 4753c3f735
commit c83c486c9b
36 changed files with 275 additions and 159 deletions
+21 -101
View File
@@ -976,9 +976,8 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/alerting/unified/AlertGroups.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/AlertsFolderView.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
@@ -987,10 +986,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/NotificationPoliciesPage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/alerting/unified/PanelAlertTabContent.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@@ -1060,9 +1055,8 @@ exports[`better eslint`] = {
],
"public/app/features/alerting/unified/components/alert-groups/GroupBy.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@@ -1074,9 +1068,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/contact-points/components/GlobalConfigAlert.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/contact-points/components/Modals.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/components/contact-points/components/UnusedBadge.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
@@ -1121,8 +1112,7 @@ exports[`better eslint`] = {
],
"public/app/features/alerting/unified/components/notification-policies/EditNotificationPolicyForm.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"]
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/alerting/unified/components/notification-policies/Policy.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
@@ -1144,9 +1134,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/alerting/unified/components/receivers/TemplateForm.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@@ -1158,9 +1145,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/receivers/form/CloudReceiverForm.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/receivers/form/GenerateAlertDataModal.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
@@ -1174,9 +1158,8 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@@ -1229,9 +1212,7 @@ exports[`better eslint`] = {
],
"public/app/features/alerting/unified/components/rule-editor/GrafanaEvaluationBehavior.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"]
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/alerting/unified/components/rule-editor/NotificationsStep.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
@@ -1264,9 +1245,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/rule-editor/RecordingRuleEditor.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/RecordingRulesNameSpaceAndGroupStep.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/RuleEditorSection.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@@ -1278,9 +1256,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/components/rule-editor/alert-rule-form/ModifyExportRuleForm.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/route-settings/MuteTimingFields.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
@@ -1343,10 +1318,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v2.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/alerting/unified/components/rules/RuleConfigStatus.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@@ -1383,17 +1354,11 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/rules/state-history/StateHistory.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/settings/VersionManager.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/alerting/unified/components/silences/SilencePeriod.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/components/silences/SilencedAlertsTableRow.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@@ -1440,9 +1405,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/rule-list/components/AlertRuleListItem.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/types/receiver-form.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@@ -1666,12 +1628,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not re-export imported variable (\`./VersionHistoryHeader\`)", "3"],
[0, 0, 0, "Do not re-export imported variable (\`./VersionHistoryTable\`)", "4"]
],
"public/app/features/dashboard-scene/sharing/ShareButton/share-snapshot/ShareSnapshot.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/sharing/ShareButton/share-snapshot/UpsertSnapshot.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/solo/SoloPanelPage.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@@ -1737,9 +1693,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard/components/DashExportModal/index.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./DashboardExporter\`)", "0"]
],
"public/app/features/dashboard/components/DashNav/DashNav.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard/components/DashNav/index.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`DashNav\`)", "0"]
],
@@ -1806,8 +1759,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
],
"public/app/features/dashboard/components/PanelEditor/OptionsPaneOptions.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard/components/PanelEditor/OverrideCategoryTitle.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
@@ -1838,14 +1790,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
],
"public/app/features/dashboard/components/SaveDashboard/SaveDashboardDiff.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/dashboard/components/SaveDashboard/SaveDashboardDrawer.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/dashboard/components/SaveDashboard/SaveDashboardErrorProxy.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
@@ -2132,16 +2076,11 @@ exports[`better eslint`] = {
],
"public/app/features/dimensions/editors/ResourceDimensionEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/dimensions/editors/ResourcePicker.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/dimensions/editors/TextDimensionEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"]
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@@ -2207,11 +2146,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/explore/Logs/Logs.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/explore/Logs/LogsColumnSearch.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/explore/Logs/LogsFeedback.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
@@ -2229,9 +2164,6 @@ exports[`better eslint`] = {
"public/app/features/explore/Logs/LogsTableNavField.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/explore/Logs/LogsTableWrap.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/explore/Logs/LogsVolumePanelList.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@@ -2272,9 +2204,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/Actions/TracePageActions.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/SearchBar/NextPrevResult.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
@@ -2292,14 +2221,11 @@ exports[`better eslint`] = {
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/TracePageHeader.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./TracePageHeader\`)", "0"]
@@ -2316,17 +2242,12 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianText.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanDetailLinkButtons.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@@ -2372,8 +2293,7 @@ exports[`better eslint`] = {
],
"public/app/features/explore/TraceView/components/settings/SpanBarSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"]
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/explore/TraceView/components/types/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`../settings/SpanBarSettings\`)", "0"],
@@ -11,6 +11,7 @@ const {
canBeFixed,
elementIsTrans,
shouldBeFixed,
isStringLiteral,
} = require('./translation-utils.cjs');
const { ESLintUtils, AST_NODE_TYPES } = require('@typescript-eslint/utils');
@@ -34,7 +35,7 @@ const noUntranslatedStrings = createRule({
const isUntranslatedProp =
(node.value.type === 'Literal' && node.value.value !== '') ||
(node.value.type === AST_NODE_TYPES.JSXExpressionContainer &&
(node.value.expression.type === 'Literal' || node.value.expression.type === 'TemplateLiteral'));
((isStringLiteral(node.value.expression) && node.value.expression.value !== '') || node.value.expression.type === 'TemplateLiteral'));
if (isUntranslatedProp) {
const errorShouldBeFixed = shouldBeFixed(context);
@@ -22,6 +22,16 @@ const elementIsTrans = (node) => {
);
};
/**
* @param {Node} node
*/
const isStringLiteral = (node) => {
return (
node.type === AST_NODE_TYPES.Literal &&
typeof node.value === 'string'
);
}
/**
* Converts a string to kebab case
* @param {string} str The string to convert
@@ -71,7 +81,7 @@ function canBeFixed(node, context) {
return false;
}
if (node.value?.type === AST_NODE_TYPES.JSXExpressionContainer) {
return false;
return isStringLiteral(node.value.expression);
}
}
@@ -296,6 +306,16 @@ function getNodeValue(node) {
// Return the raw value if we can, so we can work out if there are any HTML entities
return node.raw;
}
if (node.type === AST_NODE_TYPES.JSXAttribute && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer) {
// this condition is basically `isStringLiteral`, but we can't use the function
// else it doesn't narrow the type correctly :(
if (
node.value.expression.type === AST_NODE_TYPES.Literal &&
typeof node.value.expression.value === 'string'
) {
return node.value.expression.value;
}
}
return '';
}
@@ -307,4 +327,5 @@ module.exports = {
canBeFixed,
shouldBeFixed,
elementIsTrans,
isStringLiteral,
};
@@ -44,6 +44,26 @@ ruleTester.run('eslint no-untranslated-strings', noUntranslatedStrings, {
name: 'Prop using t() function',
code: `<div aria-label={t('aria.label', 'Accessible label')} />`,
},
{
name: 'Empty string prop',
code: `<div title="" />`,
},
{
name: 'Prop using boolean',
code: `<div title={false} />`,
},
{
name: 'Prop using number',
code: `<div title={0} />`,
},
{
name: 'Prop using null',
code: `<div title={null} />`,
},
{
name: 'Prop using undefined',
code: `<div title={undefined} />`,
},
{
name: 'Variable interpolation',
code: `<div>{variable}</div>`,
@@ -306,6 +326,26 @@ const Foo = () => <div title={t("some-feature.foo.title-foo", "foo")} />`,
],
},
{
name: 'Fixes prop case with string literal inside expression container',
code: `
const Foo = () => <div title={"foo"} />`,
filename,
errors: [
{
messageId: 'noUntranslatedStringsProp',
suggestions: [
{
messageId: 'wrapWithT',
output: `
import { t } from 'app/core/internationalization';
const Foo = () => <div title={t("some-feature.foo.title-foo", "foo")} />`,
},
],
},
],
},
{
name: 'Fixes prop case with double quotes in value',
code: `
@@ -437,8 +477,8 @@ const Foo = () => {
},
{
name: 'Cannot fix JSXExpression in attribute',
code: `const Foo = () => <div title={"foo"} />`,
name: 'Cannot fix JSXExpression in attribute if it is template literal',
code: `const Foo = () => <div title={\`foo\`} />`,
filename,
errors: [{ messageId: 'noUntranslatedStringsProp' }],
},
@@ -60,7 +60,10 @@ const AlertGroups = () => {
<LoadingPlaceholder text={t('alerting.alert-groups.text-loading-notifications', 'Loading notifications')} />
)}
{error && !loading && (
<Alert title={'Error loading notifications'} severity={'error'}>
<Alert
title={t('alerting.alert-groups.title-error-loading-notifications', 'Error loading notifications')}
severity={'error'}
>
{error.message || 'Unknown error'}
</Alert>
)}
@@ -4,6 +4,7 @@ import { useState } from 'react';
import { GrafanaTheme2, UrlQueryMap } from '@grafana/data';
import { Tab, TabContent, TabsBar, useStyles2 } from '@grafana/ui';
import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { t } from 'app/core/internationalization';
import { useMuteTimings } from 'app/features/alerting/unified/components/mute-timings/useMuteTimings';
import { NotificationPoliciesList } from 'app/features/alerting/unified/components/notification-policies/NotificationPoliciesList';
import { AlertmanagerAction, useAlertmanagerAbility } from 'app/features/alerting/unified/hooks/useAbilities';
@@ -51,7 +52,7 @@ const NotificationPoliciesTabs = () => {
<TabsBar>
{policiesSupported && canSeePoliciesTab && (
<Tab
label={'Notification Policies'}
label={t('alerting.notification-policies-tabs.label-notification-policies', 'Notification Policies')}
active={policyTreeTabActive}
onChangeTab={() => {
setActiveTab(ActiveTab.NotificationPolicies);
@@ -61,7 +62,7 @@ const NotificationPoliciesTabs = () => {
)}
{timingsSupported && canSeeTimingsTab && (
<Tab
label={'Mute Timings'}
label={t('alerting.notification-policies-tabs.label-mute-timings', 'Mute Timings')}
active={muteTimingsTabActive}
counter={numberOfMuteTimings}
onChangeTab={() => {
@@ -37,7 +37,7 @@ export const GroupBy = ({ groups, groupBy, onGroupingChange }: Props) => {
</Tooltip>
</Label>
<MultiSelect
aria-label={'group by label keys'}
aria-label={t('alerting.group-by.aria-label-group-by-label-keys', 'Group by label keys')}
value={groupBy}
placeholder={t('alerting.group-by.placeholder-group-by', 'Group by')}
prefix={<Icon name={'tag-alt'} />}
@@ -94,7 +94,7 @@ const ErrorModal = ({ isOpen, onDismiss, error }: ErrorModalProps) => (
onDismiss={onDismiss}
closeOnBackdropClick={true}
closeOnEscape={true}
title={'Something went wrong'}
title={t('alerting.error-modal.title-something-went-wrong', 'Something went wrong')}
>
<p>
<Trans i18nKey="alerting.error-modal.failed-to-update-your-configuration">
@@ -115,7 +115,7 @@ export const AmRoutesExpandedForm = ({ actionButtons, route, onSubmit, defaults
autoFocus
/>
</Field>
<Field label={'Operator'}>
<Field label={t('alerting.am-routes-expanded-form.label-operator', 'Operator')}>
<Controller
render={({ field: { onChange, ref, ...field } }) => (
<Select
@@ -259,7 +259,10 @@ export const TemplateForm = ({ originalTemplate, prefill, alertmanager }: Props)
))}
<Menu.Divider />
<Menu.Item
label={'Examples documentation'}
label={t(
'alerting.template-form.label-examples-documentation',
'Examples documentation'
)}
url="https://grafana.com/docs/grafana/latest/alerting/configure-notifications/template-notifications/examples/"
target="_blank"
icon="external-link-alt"
@@ -6,7 +6,7 @@ import { FormProvider, useForm } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { Button, Card, Modal, RadioButtonGroup, Stack, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { TestTemplateAlert } from 'app/plugins/datasource/alertmanager/types';
import { KeyValueField } from '../../../api/templateApi';
@@ -88,7 +88,11 @@ export const GenerateAlertDataModal = ({ isOpen, onDismiss, onAccept }: Props) =
];
return (
<Modal onDismiss={onDismiss} isOpen={isOpen} title={'Add custom alerts'}>
<Modal
onDismiss={onDismiss}
isOpen={isOpen}
title={t('alerting.generate-alert-data-modal.title-add-custom-alerts', 'Add custom alerts')}
>
<FormProvider {...formMethods}>
<form
onSubmit={(e) => {
@@ -4,7 +4,7 @@ import { FormProvider, useForm } from 'react-hook-form';
import { GrafanaTheme2 } from '@grafana/data';
import { Button, Label, Modal, RadioButtonGroup, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { TestReceiversAlert } from 'app/plugins/datasource/alertmanager/types';
import { Annotations, Labels } from 'app/types/unified-alerting-dto';
@@ -66,7 +66,11 @@ export const TestContactPointModal = ({ isOpen, onDismiss, onTest }: Props) => {
};
return (
<Modal onDismiss={onDismiss} isOpen={isOpen} title={'Test contact point'}>
<Modal
onDismiss={onDismiss}
isOpen={isOpen}
title={t('alerting.test-contact-point-modal.title-test-contact-point', 'Test contact point')}
>
<div className={styles.section}>
<Label>
<Trans i18nKey="alerting.test-contact-point-modal.notification-message">Notification message</Trans>
@@ -227,7 +227,10 @@ export function GrafanaEvaluationBehaviorStep({
)}
</div>
)}
placeholder={'Select an evaluation group...'}
placeholder={t(
'alerting.grafana-evaluation-behavior-step.placeholder-select-an-evaluation-group',
'Select an evaluation group...'
)}
/>
)}
name="group"
@@ -444,7 +447,7 @@ function EvaluationGroupCreationModal({
<Modal
className={styles.modal}
isOpen={true}
title={'New evaluation group'}
title={t('alerting.evaluation-group-creation-modal.title-new-evaluation-group', 'New evaluation group')}
onDismiss={onCancel}
onClickBackdrop={onCancel}
>
@@ -19,7 +19,10 @@ export function RecordingRulesNameSpaceAndGroupStep() {
return (
<RuleEditorSection
stepNo={3}
title={'Add namespace and group'}
title={t(
'alerting.recording-rules-name-space-and-group-step.title-add-namespace-and-group',
'Add namespace and group'
)}
description={t(
'alerting.recording-rules-name-space-and-group-step.description-select-namespace-group-recording',
'Select the Namespace and Group for your recording rule.'
@@ -225,7 +225,7 @@ export const GrafanaRuleDesignExporter = memo(({ onClose, exportValues, uid }: G
return (
<GrafanaExportDrawer
title={'Export Group'}
title={t('alerting.grafana-rule-design-exporter.title-export-group', 'Export Group')}
activeTab={activeTab}
onTabChange={setActiveTab}
onClose={onClose}
@@ -48,13 +48,13 @@ export default function RulesFilter({ onClear = () => {} }: RulesFilterProps) {
<Tab
active={activeTab === 'custom'}
icon="filter"
label={'Custom filter'}
label={t('alerting.rules-filter.filter-options.label-custom-filter', 'Custom filter')}
onChangeTab={() => setActiveTab('custom')}
/>
<Tab
active={activeTab === 'saved'}
icon="bookmark"
label={'Saved searches'}
label={t('alerting.rules-filter.filter-options.label-saved-searches', 'Saved searches')}
onChangeTab={() => setActiveTab('saved')}
/>
</TabsBar>
@@ -42,11 +42,20 @@ const StateHistory = ({ ruleUID }: Props) => {
const styles = useStyles2(getStyles);
if (loading && !error) {
return <LoadingPlaceholder text={'Loading history...'} />;
return <LoadingPlaceholder text={t('alerting.state-history.text-loading-history', 'Loading history...')} />;
}
if (error && !loading) {
return <Alert title={'Failed to fetch alert state history'}>{error.message}</Alert>;
return (
<Alert
title={t(
'alerting.state-history.title-failed-to-fetch-alert-state-history',
'Failed to fetch alert state history'
)}
>
{error.message}
</Alert>
);
}
const columns: Array<DynamicTableColumnProps<StateHistoryRowItem>> = [
@@ -237,7 +237,7 @@ const AlertmanagerConfigurationVersionManager = ({
{/* TODO make this modal persist while restore is in progress */}
<ConfirmModal
isOpen={confirmRestore}
title={'Restore Version'}
title={t('alerting.alertmanager-configuration-version-manager.title-restore-version', 'Restore version')}
body={'Are you sure you want to restore the configuration to this version? All unsaved changes will be lost.'}
confirmText={'Yes, restore configuration'}
onConfirm={() => {
@@ -68,7 +68,7 @@ export const SilencePeriod = () => {
onChangeTimeZone={(newValue) => onChangeTimeZone(newValue)}
hideTimeZone={false}
hideQuickRanges={true}
placeholder={'Select time range'}
placeholder={t('alerting.silence-period.placeholder-select-time-range', 'Select time range')}
/>
</Field>
);
@@ -4,7 +4,7 @@ import { ReactNode, useEffect, useId } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Alert, Icon, Stack, Text, TextLink, Tooltip, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { Rule, RuleGroupIdentifierV2, RuleHealth, RulesSourceIdentifier } from 'app/types/unified-alerting';
import { Labels, PromAlertingRuleState, RulerRuleDTO, RulesSourceApplication } from 'app/types/unified-alerting-dto';
@@ -325,7 +325,10 @@ export const UnknownRuleListItem = ({ ruleName, groupIdentifier, ruleDefinition
}, [ruleName, groupIdentifier]);
return (
<Alert title={'Unknown rule type'} className={styles.resetMargin}>
<Alert
title={t('alerting.unknown-rule-list-item.title-unknown-rule-type', 'Unknown rule type')}
className={styles.resetMargin}
>
<details>
<summary>
<Trans i18nKey="alerting.alert-rules.rule-definition">Rule definition</Trans>
@@ -228,7 +228,7 @@ export const DashNav = memo<Props>((props) => {
buttons.push(
<DashNavButton
key="button-scenes"
tooltip={'View as Scene'}
tooltip={t('dashboard.dash-nav.render-left-actions.tooltip-view-as-scene', 'View as Scene')}
icon="apps"
onClick={() => {
locationService.partial({ scenes: true });
@@ -100,7 +100,12 @@ export const OptionsPaneOptions = (props: OptionPaneRenderProps) => {
<div className={styles.wrapper}>
<div className={styles.formBox}>
<div className={styles.formRow}>
<FilterInput width={0} value={searchQuery} onChange={setSearchQuery} placeholder={'Search options'} />
<FilterInput
width={0}
value={searchQuery}
onChange={setSearchQuery}
placeholder={t('dashboard.options-pane-options.placeholder-search-options', 'Search options')}
/>
</div>
{showSearchRadioButtons && (
<div className={styles.formRow}>
@@ -2,7 +2,7 @@ import { ReactElement } from 'react';
import { useAsync } from 'react-use';
import { Alert, Box, Spinner, Stack } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { Diffs } from 'app/features/dashboard-scene/settings/version-history/utils';
import { DiffGroup } from '../../../dashboard-scene/settings/version-history/DiffGroup';
@@ -67,9 +67,10 @@ export const SaveDashboardDiff = ({
{hasMigratedToV2 && (
<Box paddingTop={1}>
<Alert
title={
title={t(
'dashboard.save-dashboard-diff.title-because-dashboard-migrated-grafana-format',
'The diff is hard to read because the dashboard has been migrated to the new Grafana dashboard format'
}
)}
severity="info"
/>
</Box>
@@ -87,7 +88,7 @@ export const SaveDashboardDiff = ({
},
]}
key={'folder'}
title={'folder'}
title={t('dashboard.save-dashboard-diff.title-folder', 'folder')}
/>
)}
{(!value || !oldValue) && <Spinner />}
@@ -2,6 +2,7 @@ import { useMemo, useState } from 'react';
import { config, isFetchError } from '@grafana/runtime';
import { Drawer, Tab, TabsBar } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { jsonDiff } from 'app/features/dashboard-scene/settings/version-history/utils';
import DashboardValidation from './DashboardValidation';
@@ -116,9 +117,18 @@ export const SaveDashboardDrawer = ({ dashboard, onDismiss, onSaveSuccess, isCop
subtitle={dashboard.title}
tabs={
<TabsBar>
<Tab label={'Details'} active={!showDiff} onChangeTab={() => setShowDiff(false)} />
<Tab
label={t('dashboard.save-dashboard-drawer.label-details', 'Details')}
active={!showDiff}
onChangeTab={() => setShowDiff(false)}
/>
{data.hasChanges && (
<Tab label={'Changes'} active={showDiff} onChangeTab={() => setShowDiff(true)} counter={data.diffCount} />
<Tab
label={t('dashboard.save-dashboard-drawer.label-changes', 'Changes')}
active={showDiff}
onChangeTab={() => setShowDiff(true)}
counter={data.diffCount}
/>
)}
</TabsBar>
}
@@ -122,7 +122,11 @@ export const ResourceDimensionEditor = (
)}
{mode === ResourceDimensionMode.Mapping && (
<InlineFieldRow>
<InlineField label="Mappings" labelWidth={labelWidth} grow={true}>
<InlineField
label={t('dimensions.resource-dimension-editor.label-mappings', 'Mappings')}
labelWidth={labelWidth}
grow={true}
>
<div>TODO mappings editor!</div>
</InlineField>
</InlineFieldRow>
@@ -97,7 +97,11 @@ export const TextDimensionEditor = ({ value, context, onChange }: Props) => {
)}
{mode === TextDimensionMode.Fixed && (
<InlineFieldRow key={value?.fixed}>
<InlineField label={'Value'} labelWidth={labelWidth} grow={true}>
<InlineField
label={t('dimensions.text-dimension-editor.label-value', 'Value')}
labelWidth={labelWidth}
grow={true}
>
<StringValueEditor
context={context}
value={value?.fixed}
+1 -1
View File
@@ -861,7 +861,7 @@ const UnthemedLogs: React.FunctionComponent<Props> = (props: Props) => {
)
) : null,
]}
title={'Logs'}
title={t('explore.unthemed-logs.title-logs', 'Logs')}
actions={
<>
{config.featureToggles.logsExploreTableVisualisation && (
@@ -3,6 +3,7 @@ import * as React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Field, Input, useTheme2 } from '@grafana/ui';
import { t } from 'app/core/internationalization';
function getStyles(theme: GrafanaTheme2) {
return {
@@ -17,7 +18,12 @@ export function LogsColumnSearch(props: { onChange: (e: React.FormEvent<HTMLInpu
const styles = getStyles(theme);
return (
<Field className={styles.searchWrap}>
<Input value={props.value} type={'text'} placeholder={'Search fields by name'} onChange={props.onChange} />
<Input
value={props.value}
type={'text'}
placeholder={t('explore.logs-column-search.placeholder-search-fields-by-name', 'Search fields by name')}
onChange={props.onChange}
/>
</Field>
);
}
@@ -503,7 +503,7 @@ export function LogsTableWrap(props: Props) {
>
<Select
inputId={'explore_logs_table_frame_selector'}
aria-label={'Select query by name'}
aria-label={t('explore.logs-table-wrap.aria-label-select-query-by-name', 'Select query by name')}
value={currentDataFrame.refId}
options={logsFrames.map((frame) => {
return {
@@ -91,7 +91,12 @@ export default function TracePageActions(props: TracePageActionsProps) {
label={copyTraceIdClicked ? 'Copied!' : 'Trace ID'}
icon={'copy'}
/>
<ActionButton onClick={exportTrace} ariaLabel={'Export Trace'} label={'Export'} icon={'save'} />
<ActionButton
onClick={exportTrace}
ariaLabel={'Export Trace'}
label={t('explore.trace-page-actions.label-export', 'Export')}
icon={'save'}
/>
</div>
);
}
@@ -209,6 +209,7 @@ export const SpanFilters = memo((props: SpanFilterProps) => {
ariaLabel="Select min span duration"
onChange={(val) => setSpanFiltersSearch({ ...search, from: val })}
isInvalidError="Invalid duration"
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="e.g. 100ms, 1.2s"
width={18}
value={search.from || ''}
@@ -225,6 +226,7 @@ export const SpanFilters = memo((props: SpanFilterProps) => {
ariaLabel="Select max span duration"
onChange={(val) => setSpanFiltersSearch({ ...search, to: val })}
isInvalidError="Invalid duration"
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="e.g. 100ms, 1.2s"
width={18}
value={search.to || ''}
@@ -20,6 +20,7 @@ import * as React from 'react';
import { CoreApp, DataFrame, dateTimeFormat, GrafanaTheme2 } from '@grafana/data';
import { TimeZone } from '@grafana/schema';
import { Badge, BadgeColor, Tooltip, useStyles2 } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { SearchProps } from '../../useSearch';
import ExternalLinks from '../common/ExternalLinks';
@@ -133,7 +134,11 @@ export const TracePageHeader = memo((props: TracePageHeaderProps) => {
{data.meta?.custom?.partial && (
<Tooltip content={data.meta?.custom?.message} interactive={true}>
<span className={styles.tag}>
<Badge icon={'info-circle'} text={'Partial trace'} color={'orange'} />
<Badge
icon={'info-circle'}
text={t('explore.trace-page-header.text-partial-trace', 'Partial trace')}
color={'orange'}
/>
</span>
</Tooltip>
)}
@@ -17,7 +17,7 @@ import * as React from 'react';
import { Field, GrafanaTheme2, LinkModel } from '@grafana/data';
import { Icon, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { autoColor } from '../../Theme';
import { TraceSpanReference } from '../../types/trace';
@@ -174,7 +174,7 @@ export function References(props: ReferenceItemProps) {
highContrast
interactive={interactive}
isOpen={openedItems ? openedItems.has(reference) : false}
label={'attributes'}
label={t('explore.references.label-attributes', 'attributes')}
linksGetter={null}
onToggle={interactive && onItemToggle ? () => onItemToggle(reference) : null}
/>
@@ -6,6 +6,7 @@ import { config, locationService, reportInteraction, usePluginLinks } from '@gra
import { DataSourceRef } from '@grafana/schema';
import { DataLinkButton, Dropdown, Menu, ToolbarButton } from '@grafana/ui';
import { RelatedProfilesTitle } from '@grafana-plugins/tempo/resultTransformer';
import { t, Trans } from 'app/core/internationalization';
import { pyroscopeProfileIdTagKey } from '../../../createSpanLink';
import { SpanLinkFunc } from '../../types';
@@ -141,8 +142,13 @@ const DropDownMenu = ({ links }: { links: SpanLinkModel[] }) => {
return (
<Dropdown overlay={menu} placement="bottom-start" onVisibleChange={setIsOpen}>
<ToolbarButton variant="primary" icon="link" isOpen={isOpen} aria-label="Links">
Links
<ToolbarButton
variant="primary"
icon="link"
isOpen={isOpen}
aria-label={t('explore.drop-down-menu.aria-label-links', 'Links')}
>
<Trans i18nKey="explore.drop-down-menu.links">Links</Trans>
</ToolbarButton>
</Dropdown>
);
@@ -51,7 +51,7 @@ export default function SpanBarSettings({ options, onOptionsChange }: Props) {
}}
placeholder={t('explore.span-bar-settings.placeholder-duration', 'Duration')}
isClearable
aria-label={'select-label-name'}
aria-label={t('explore.span-bar-settings.aria-label-selectlabelname', 'Select label name')}
width={40}
/>
</InlineField>
+64 -11
View File
@@ -329,6 +329,7 @@
"alert-groups": {
"no-results": "No results.",
"text-loading-notifications": "Loading notifications",
"title-error-loading-notifications": "Error loading notifications",
"title-grafana-alerts-delivered-alertmanager": "Grafana alerts are not delivered to Grafana Alertmanager"
},
"alert-instance-details": {
@@ -436,6 +437,7 @@
},
"this-might-take-a-while": "This might take a while...",
"title-failed-to-load-configuration-history": "Failed to load configuration history",
"title-restore-version": "Restore version",
"title-restoring-alertmanager-configuration": "Restoring Alertmanager configuration"
},
"alerts-folder-view": {
@@ -510,6 +512,7 @@
"label-continue-matching-subsequent-sibling-nodes": "Continue matching subsequent sibling nodes",
"label-group-by": "Group by",
"label-label": "Label",
"label-operator": "Operator",
"label-override-general-timings": "Override general timings",
"label-override-grouping": "Override grouping",
"label-value": "Value",
@@ -803,7 +806,8 @@
"title-failed-to-fetch-notification-template": "Failed to fetch notification template"
},
"error-modal": {
"failed-to-update-your-configuration": "Failed to update your configuration:"
"failed-to-update-your-configuration": "Failed to update your configuration:",
"title-something-went-wrong": "Something went wrong"
},
"error-summary-button": {
"error": "1 error"
@@ -824,7 +828,8 @@
},
"evaluation-group-creation-modal": {
"description-often-rules-group-evaluated": "How often all rules in the group are evaluated.",
"placeholder-enter-a-name": "Enter a name"
"placeholder-enter-a-name": "Enter a name",
"title-new-evaluation-group": "New evaluation group"
},
"evaluation-group-loader": {
"title-something-wrong-trying-fetch-group-details": "Something went wrong when trying to fetch group details"
@@ -896,7 +901,8 @@
"generate-alert-data-modal": {
"add-alert-data": "Add alert data",
"add-alert-data-to-payload": "Add alert data to payload",
"review-alert-payload": " Review alert data to add to the payload:"
"review-alert-payload": " Review alert data to add to the payload:",
"title-add-custom-alerts": "Add custom alerts"
},
"get-preview-results": {
"title-error": "Error"
@@ -927,6 +933,7 @@
"grafana-evaluation-behavior-step": {
"missing-series-resolve-placeholder": "Default: 2",
"or": "or",
"placeholder-select-an-evaluation-group": "Select an evaluation group...",
"text-configure-no-data-and-error-handling": "Configure no data and error handling",
"title-set-evaluation-behavior": "Set evaluation behavior"
},
@@ -958,6 +965,9 @@
"grafana-rule-design-export-preview": {
"text-loading": "Loading...."
},
"grafana-rule-design-exporter": {
"title-export-group": "Export Group"
},
"grafana-rule-export-preview": {
"text-loading": "Loading...."
},
@@ -990,6 +1000,7 @@
"namespace-picker-label-namespace": "Namespace"
},
"group-by": {
"aria-label-group-by-label-keys": "Group by label keys",
"placeholder-group-by": "Group by"
},
"group-details": {
@@ -1318,6 +1329,10 @@
"title-error-loading-alertmanager-config": "Error loading Alertmanager config",
"title-notification-policies-have-changed": "Notification policies have changed"
},
"notification-policies-tabs": {
"label-mute-timings": "Mute Timings",
"label-notification-policies": "Notification Policies"
},
"notification-policy-matchers": {
"default-policy": "Default policy",
"no-matchers": "No matchers"
@@ -1532,7 +1547,8 @@
"label-target-data-source": "Target data source"
},
"recording-rules-name-space-and-group-step": {
"description-select-namespace-group-recording": "Select the Namespace and Group for your recording rule."
"description-select-namespace-group-recording": "Select the Namespace and Group for your recording rule.",
"title-add-namespace-and-group": "Add namespace and group"
},
"redirect-to-clone-rule": {
"title-copy-provisioned-alert-rule": "Copy provisioned alert rule"
@@ -1808,7 +1824,9 @@
"dashboard": "Dashboard",
"data-source-picker-inline-help-title-search-by-data-sources-help": "Search by data sources help",
"filter-options": {
"aria-label-show-filters": "Show filters"
"aria-label-show-filters": "Show filters",
"label-custom-filter": "Custom filter",
"label-saved-searches": "Saved searches"
},
"health": "Health",
"placeholder-all-data-sources": "All data sources",
@@ -1877,7 +1895,8 @@
"title-silence-alert-rule": "Silence alert rule"
},
"silence-period": {
"label-silence-start-and-end": "Silence start and end"
"label-silence-start-and-end": "Silence start and end",
"placeholder-select-time-range": "Select time range"
},
"silenced-instances-preview": {
"no-firing-alert-instances-found": "No firing alert instances found",
@@ -1922,7 +1941,9 @@
},
"state-history": {
"filter-group": "Filter group",
"placeholder-search": "Search"
"placeholder-search": "Search",
"text-loading-history": "Loading history...",
"title-failed-to-fetch-alert-state-history": "Failed to fetch alert state history"
},
"string-array-input": {
"add": "Add",
@@ -1947,6 +1968,7 @@
},
"template-form": {
"aria-label-template-form": "Template form",
"label-examples-documentation": "Examples documentation",
"label-template-group": "Template group",
"label-template-group-name": "Template group name",
"new-template-name-placeholder-give-your-template-group-a-name": "Give your template group a name",
@@ -1991,7 +2013,8 @@
},
"test-contact-point-modal": {
"notification-message": "Notification message",
"send-test-notification": "Send test notification"
"send-test-notification": "Send test notification",
"title-test-contact-point": "Test contact point"
},
"threshold": {
"to": "TO"
@@ -2012,6 +2035,9 @@
"title-warning": "Warning"
}
},
"unknown-rule-list-item": {
"title-unknown-rule-type": "Unknown rule type"
},
"unused-contact-point-badge": {
"aria-label-unused": "unused",
"text-unused": "Unused"
@@ -2701,7 +2727,8 @@
},
"dash-nav": {
"render-left-actions": {
"text-public": "Public"
"text-public": "Public",
"tooltip-view-as-scene": "View as Scene"
}
},
"dashboard-loading": {
@@ -2921,6 +2948,7 @@
"title-option": "Title"
},
"options-pane-options": {
"placeholder-search-options": "Search options",
"Recent options-title-recent-options": "Recent options"
},
"outline": {
@@ -3038,7 +3066,13 @@
},
"save-dashboard-diff": {
"full-json-diff": "Full JSON diff",
"no-changes-in-the-dashboard-json": "No changes in the dashboard JSON"
"no-changes-in-the-dashboard-json": "No changes in the dashboard JSON",
"title-because-dashboard-migrated-grafana-format": "The diff is hard to read because the dashboard has been migrated to the new Grafana dashboard format",
"title-folder": "folder"
},
"save-dashboard-drawer": {
"label-changes": "Changes",
"label-details": "Details"
},
"save-dashboard-error-proxy": {
"title-conflict": "Conflict"
@@ -3906,6 +3940,7 @@
},
"resource-dimension-editor": {
"label-field": "Field",
"label-mappings": "Mappings",
"label-source": "Source"
},
"resource-picker": {
@@ -3931,7 +3966,8 @@
"text-dimension-editor": {
"label-field": "Field",
"label-source": "Source",
"label-template": "Template"
"label-template": "Template",
"label-value": "Value"
},
"thresholds-editor": {
"add-threshold": "Add threshold",
@@ -4045,6 +4081,10 @@
"description": "Looking for the Grafana Explore apps? They are now called the Grafana Drilldown apps and can be found under <1>Menu > Drilldown</1>",
"title": "Explore Metrics, Logs, Traces and Profiles have moved!"
},
"drop-down-menu": {
"aria-label-links": "Links",
"links": "Links"
},
"explore": {
"title-flame-graph": "Flame graph",
"title-graph": "Graph",
@@ -4093,6 +4133,9 @@
"scan-for-older-logs": "Scan for older logs",
"stop-scan": "Stop scan"
},
"logs-column-search": {
"placeholder-search-fields-by-name": "Search fields by name"
},
"logs-container": {
"label-logs": "Logs"
},
@@ -4119,6 +4162,7 @@
"title-drag-and-drop-to-reorder": "Drag and drop to reorder"
},
"logs-table-wrap": {
"aria-label-select-query-by-name": "Select query by name",
"label-select-query": "Select query",
"tooltip-select-query-visualize-table": "Select a query to visualize in the table"
},
@@ -4150,6 +4194,9 @@
"raw-list-item": {
"tooltip-copy-to-clipboard": "Copy to clipboard"
},
"references": {
"label-attributes": "attributes"
},
"rich-history": {
"close-tooltip": "Close query history",
"datasource-a-z": "Data source A-Z",
@@ -4277,6 +4324,7 @@
"title-span-bar": "Span bar"
},
"span-bar-settings": {
"aria-label-selectlabelname": "Select label name",
"label-label": "Label",
"label-tag-key": "Tag key",
"placeholder-duration": "Duration",
@@ -4356,8 +4404,12 @@
},
"trace-page-actions": {
"give-feedback": "Give feedback",
"label-export": "Export",
"title-share-thoughts-about-tracing-grafana": "Share your thoughts about tracing in Grafana."
},
"trace-page-header": {
"text-partial-trace": "Partial trace"
},
"trace-view": {
"no-data": "No data"
},
@@ -4372,6 +4424,7 @@
"label-unique-labels": "Unique labels",
"label-wrap-lines": "Wrap lines",
"title-feedback": "Feedback",
"title-logs": "Logs",
"title-logs-volume": "Logs volume"
},
"unthemed-viewing-layer": {