diff --git a/.betterer.results b/.betterer.results
index 2a993529fb0..976a2137c61 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -1029,9 +1029,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
],
- "public/app/features/alerting/unified/components/RuleLocation.tsx:5381": [
- [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"]
- ],
"public/app/features/alerting/unified/components/alert-groups/AlertDetails.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
@@ -1088,8 +1085,7 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/expressions/Expression.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "2"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "3"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
],
"public/app/features/alerting/unified/components/mute-timings/MuteTimingTimeInterval.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"],
@@ -1245,9 +1241,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/rule-editor/RecordingRuleEditor.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/alerting/unified/components/rule-editor/RuleEditorSection.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/alerting/unified/components/rule-editor/RuleInspector.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
@@ -1264,10 +1257,6 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
],
- "public/app/features/alerting/unified/components/rule-editor/labels/LabelsField.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
- ],
"public/app/features/alerting/unified/components/rule-editor/notificaton-preview/NotificationRoute.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
@@ -1333,19 +1322,11 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "5"]
],
- "public/app/features/alerting/unified/components/rules/RuleListStateSection.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/alerting/unified/components/rules/RuleState.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/alerting/unified/components/rules/RuleStats.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/alerting/unified/components/rules/RulesGroup.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
"public/app/features/alerting/unified/components/rules/state-history/LogRecordViewer.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
@@ -1356,10 +1337,6 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/rules/state-history/StateHistory.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/alerting/unified/components/settings/VersionManager.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
- ],
"public/app/features/alerting/unified/components/silences/SilencedAlertsTableRow.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
@@ -1519,9 +1496,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
- "public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/dashboard-scene/inspect/HelpWizard/utils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@@ -1542,9 +1516,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
- "public/app/features/dashboard-scene/panel-edit/PanelDataPane/TransformationsDrawer.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/dashboard-scene/panel-edit/PanelOptionsPane.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -1766,8 +1737,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/dashboard/components/DashboardRow/DashboardRow.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
"public/app/features/dashboard/components/DashboardRow/index.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./DashboardRow\`)", "0"]
@@ -1789,8 +1759,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "3"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "4"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "5"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "4"]
],
"public/app/features/dashboard/components/Inspector/PanelInspector.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@@ -1886,8 +1855,7 @@ exports[`better eslint`] = {
],
"public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.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. Wrap text with ", "2"]
+ [0, 0, 0, "Do not use any type assertions.", "1"]
],
"public/app/features/dashboard/components/VersionHistory/RevertDashboardModal.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
@@ -2132,15 +2100,13 @@ exports[`better eslint`] = {
],
"public/app/features/dimensions/editors/ThresholdsEditor/ThresholdsEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
- [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
+ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"]
],
"public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingEditRow.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
"public/app/features/dimensions/editors/ValueMappingsEditor/ValueMappingsEditor.tsx:5381": [
- [0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
+ [0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
"public/app/features/dimensions/editors/index.ts:5381": [
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"],
@@ -2173,8 +2139,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "2"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "3"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "4"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "3"]
],
"public/app/features/explore/CorrelationTransformationAddModal.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"],
@@ -2193,9 +2158,6 @@ exports[`better eslint`] = {
"public/app/features/explore/Logs/LiveLogs.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/explore/Logs/Logs.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/explore/Logs/LogsFeedback.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
@@ -2209,15 +2171,9 @@ exports[`better eslint`] = {
"public/app/features/explore/Logs/LogsTableMultiSelect.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/explore/Logs/LogsTableNavField.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/explore/Logs/LogsVolumePanelList.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/explore/MetaInfoText.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/explore/NodeGraph/NodeGraphContainer.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
@@ -2227,24 +2183,12 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
],
- "public/app/features/explore/PrometheusListView/RawListItem.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
- "public/app/features/explore/PrometheusListView/RawListItemAttributes.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "2"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "3"]
- ],
"public/app/features/explore/RichHistory/RichHistorySettingsTab.tsx:5381": [
[0, 0, 0, "Do not use the t() function outside of a component or function", "0"],
[0, 0, 0, "Do not use the t() function outside of a component or function", "1"],
[0, 0, 0, "Do not use the t() function outside of a component or function", "2"],
[0, 0, 0, "Do not use the t() function outside of a component or function", "3"]
],
- "public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
- ],
"public/app/features/explore/ShortLinkButtonMenu.tsx:5381": [
[0, 0, 0, "Do not use the t() function outside of a component or function", "0"]
],
@@ -2272,8 +2216,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "3"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/TracePageHeader.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./TracePageHeader\`)", "0"]
@@ -2281,19 +2224,10 @@ exports[`better eslint`] = {
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanBar.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianKeyValues.tsx:5381": [
+ "public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
- "public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianLogs.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "2"]
- ],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianReferences.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
- ],
- "public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/AccordianText.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"]
],
"public/app/features/explore/TraceView/components/TraceTimelineViewer/TimelineHeaderRow/TimelineHeaderRow.tsx:5381": [
@@ -2417,10 +2351,6 @@ exports[`better eslint`] = {
"public/app/features/expressions/guards.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
- "public/app/features/geo/editor/GazetteerPathEditor.tsx:5381": [
- [0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "1"]
- ],
"public/app/features/geo/editor/locationModeEditor.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
@@ -2466,10 +2396,9 @@ exports[`better eslint`] = {
"public/app/features/inspector/QueryInspector.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "1"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "2"],
- [0, 0, 0, "Unexpected any. Specify a different type.", "3"],
- [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"],
- [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "5"]
+ [0, 0, 0, "Unexpected any. Specify a different type.", "2"],
+ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"],
+ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"]
],
"public/app/features/invites/SignupInvited.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
@@ -2742,9 +2671,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "5"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "6"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "7"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "8"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "6"]
],
"public/app/features/query/state/DashboardQueryRunner/AnnotationsQueryRunner.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
diff --git a/packages/grafana-eslint-rules/rules/no-untranslated-strings.cjs b/packages/grafana-eslint-rules/rules/no-untranslated-strings.cjs
index 53c4215ac26..2ea64533af2 100644
--- a/packages/grafana-eslint-rules/rules/no-untranslated-strings.cjs
+++ b/packages/grafana-eslint-rules/rules/no-untranslated-strings.cjs
@@ -11,7 +11,7 @@ const {
canBeFixed,
elementIsTrans,
shouldBeFixed,
- isStringLiteral,
+ isStringNonAlphanumeric,
} = require('./translation-utils.cjs');
const { ESLintUtils, AST_NODE_TYPES } = require('@typescript-eslint/utils');
@@ -32,11 +32,12 @@ const noUntranslatedStrings = createRule({
return;
}
- const isUntranslatedProp =
- (node.value.type === 'Literal' && node.value.value !== '') ||
- (node.value.type === AST_NODE_TYPES.JSXExpressionContainer &&
- ((isStringLiteral(node.value.expression) && node.value.expression.value !== '') ||
- node.value.expression.type === 'TemplateLiteral'));
+ const nodeValue = getNodeValue(node);
+ const isAlphaNumeric = !isStringNonAlphanumeric(nodeValue);
+ const isTemplateLiteral =
+ node.value.type === AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === 'TemplateLiteral';
+
+ const isUntranslatedProp = (nodeValue.trim() && isAlphaNumeric) || isTemplateLiteral;
if (isUntranslatedProp) {
const errorShouldBeFixed = shouldBeFixed(context);
@@ -64,8 +65,8 @@ const noUntranslatedStrings = createRule({
const children = node.children;
const untranslatedTextNodes = children.filter((child) => {
if (child.type === AST_NODE_TYPES.JSXText) {
- const hasValue = child.value.trim();
- if (!hasValue) {
+ const nodeValue = child.value.trim();
+ if (!nodeValue || isStringNonAlphanumeric(nodeValue)) {
return false;
}
const ancestors = context.sourceCode.getAncestors(node);
diff --git a/packages/grafana-eslint-rules/rules/translation-utils.cjs b/packages/grafana-eslint-rules/rules/translation-utils.cjs
index 8625e4f44cf..a5e3aad8c63 100644
--- a/packages/grafana-eslint-rules/rules/translation-utils.cjs
+++ b/packages/grafana-eslint-rules/rules/translation-utils.cjs
@@ -41,6 +41,14 @@ function toKebabCase(str) {
.replace(/\s+/g, '-');
}
+/**
+ * Checks if a string is non-alphanumeric
+ * @param {string} str The string to check
+ * @returns {boolean}
+ */
+function isStringNonAlphanumeric(str) {
+ return !/[a-zA-Z0-9]/.test(str);
+}
/**
* Checks if we _should_ fix an error automatically
* @param {RuleContextWithOptions} context
@@ -321,5 +329,5 @@ module.exports = {
canBeFixed,
shouldBeFixed,
elementIsTrans,
- isStringLiteral,
+ isStringNonAlphanumeric,
};
diff --git a/packages/grafana-eslint-rules/tests/no-untranslated-strings.test.js b/packages/grafana-eslint-rules/tests/no-untranslated-strings.test.js
index 970f0065eba..35b2d1cb251 100644
--- a/packages/grafana-eslint-rules/tests/no-untranslated-strings.test.js
+++ b/packages/grafana-eslint-rules/tests/no-untranslated-strings.test.js
@@ -68,6 +68,18 @@ ruleTester.run('eslint no-untranslated-strings', noUntranslatedStrings, {
name: 'Variable interpolation',
code: `
{variable}
`,
},
+ {
+ name: 'Entirely non-alphanumeric text (prop)',
+ code: ``,
+ },
+ {
+ name: 'Entirely non-alphanumeric text',
+ code: `-
`,
+ },
+ {
+ name: 'Non-alphanumeric siblings',
+ code: `({variable})
`,
+ },
],
invalid: [
/**
@@ -416,12 +428,6 @@ const Foo = () => {
],
},
- {
- name: 'Cannot fix entirely non-alphanumeric text',
- code: `const Foo = () => -
`,
- filename,
- errors: [{ messageId: 'noUntranslatedStrings' }],
- },
{
name: 'Cannot fix text with expression sibling',
code: `const Foo = () => {name} Hello
`,