Internationalisation: More markup (#103970)

* more markup!

* fix tests

* use times symbol
pull/103982/head^2
Ashley Harrison 3 months ago committed by GitHub
parent 9748b16ee8
commit a2b06e2ec9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 245
      .betterer.results
  2. 18
      public/app/features/admin/UpgradePage.tsx
  3. 2
      public/app/features/alerting/unified/AlertsFolderView.tsx
  4. 8
      public/app/features/alerting/unified/RedirectToRuleViewer.tsx
  5. 4
      public/app/features/alerting/unified/components/AlertLabelDropdown.tsx
  6. 7
      public/app/features/alerting/unified/components/DynamicTable.tsx
  7. 14
      public/app/features/alerting/unified/components/Provisioning.tsx
  8. 9
      public/app/features/alerting/unified/components/contact-points/ContactPointHeader.tsx
  9. 12
      public/app/features/alerting/unified/components/contact-points/ContactPoints.test.tsx
  10. 5
      public/app/features/alerting/unified/components/contact-points/components/UnusedBadge.tsx
  11. 4
      public/app/features/alerting/unified/components/export/GrafanaRuleFolderExporter.tsx
  12. 2
      public/app/features/alerting/unified/components/export/GrafanaRuleGroupExporter.tsx
  13. 2
      public/app/features/alerting/unified/components/expressions/Expression.tsx
  14. 10
      public/app/features/alerting/unified/components/mute-timings/MuteTimingTimeInterval.tsx
  15. 5
      public/app/features/alerting/unified/components/mute-timings/MuteTimingTimeRange.tsx
  16. 26
      public/app/features/alerting/unified/components/notification-policies/AlertGroupsSummary.tsx
  17. 20
      public/app/features/alerting/unified/components/notification-policies/EditDefaultPolicyForm.tsx
  18. 10
      public/app/features/alerting/unified/components/notification-policies/EditNotificationPolicyForm.tsx
  19. 6
      public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.tsx
  20. 5
      public/app/features/alerting/unified/components/receivers/form/GrafanaCommonChannelSettings.tsx
  21. 19
      public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.tsx
  22. 19
      public/app/features/alerting/unified/components/rule-editor/AlertRuleNameInput.tsx
  23. 5
      public/app/features/alerting/unified/components/rule-editor/CloudEvaluationBehavior.tsx
  24. 10
      public/app/features/alerting/unified/components/rule-editor/GrafanaEvaluationBehavior.tsx
  25. 5
      public/app/features/alerting/unified/components/rule-editor/QueryWrapper.tsx
  26. 5
      public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/route-settings/MuteTimingFields.tsx
  27. 5
      public/app/features/alerting/unified/components/rule-editor/alert-rule-form/simplifiedRouting/route-settings/RouteSettings.tsx
  28. 21
      public/app/features/alerting/unified/components/silences/SilencesEditor.tsx
  29. 7
      public/app/features/alerting/unified/components/silences/SilencesTable.tsx
  30. 52
      public/app/features/alerting/unified/home/GettingStarted.tsx
  31. 4
      public/app/features/dashboard-scene/v2schema/ImportDashboardFormV2.tsx
  32. 5
      public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx
  33. 6
      public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.tsx
  34. 24
      public/app/features/dashboard/components/HelpWizard/HelpWizard.tsx
  35. 5
      public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx
  36. 4
      public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.tsx
  37. 8
      public/app/features/dashboard/components/VersionHistory/VersionHistoryTable.tsx
  38. 9
      public/app/features/dashboard/containers/SoloPanelPage.tsx
  39. 6
      public/app/features/datasources/components/BasicSettings.tsx
  40. 11
      public/app/features/datasources/components/DataSourceTestingStatus.tsx
  41. 6
      public/app/features/explore/CorrelationTransformationAddModal.tsx
  42. 7
      public/app/features/explore/CorrelationUnsavedChangesModal.tsx
  43. 33
      public/app/features/explore/Logs/LogsFeedback.tsx
  44. 3
      public/app/features/explore/NodeGraph/NodeGraphContainer.tsx
  45. 14
      public/app/features/explore/PrometheusListView/RawListContainer.tsx
  46. 6
      public/app/features/explore/TraceView/components/TracePageHeader/SearchBar/NextPrevResult.tsx
  47. 8
      public/app/features/explore/TraceView/components/TracePageHeader/SearchBar/TracePageSearchBar.tsx
  48. 9
      public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx
  49. 10
      public/app/features/explore/TraceView/components/settings/SpanBarSettings.tsx
  50. 67
      public/app/features/expressions/components/Math.tsx
  51. 12
      public/app/features/manage-dashboards/components/ImportDashboardForm.tsx
  52. 5
      public/app/features/notifications/StoredNotifications.tsx
  53. 5
      public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx
  54. 24
      public/app/features/plugins/admin/components/InstallControls/InstallControlsWarning.tsx
  55. 4
      public/app/features/plugins/admin/components/PluginUsage.tsx
  56. 27
      public/app/features/plugins/components/PluginsErrorsInfo.tsx
  57. 199
      public/locales/en-US/grafana.json

@ -938,14 +938,6 @@ exports[`better eslint`] = {
"public/app/features/actions/ParamsEditor.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/admin/UpgradePage.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. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
],
"public/app/features/alerting/routes.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@ -979,9 +971,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/AlertsFolderView.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/GrafanaRuleQueryViewer.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
@ -990,12 +979,8 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/RedirectToRuleViewer.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/AlertLabelDropdown.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/AlertLabels.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@ -1007,9 +992,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/alerting/unified/components/DynamicTable.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/GrafanaAlertmanagerDeliveryWarning.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
@ -1025,10 +1007,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/Provisioning.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/alerting/unified/components/alert-groups/AlertDetails.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@ -1058,16 +1036,9 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/alert-groups/MatcherFilter.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/contact-points/ContactPointHeader.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/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/UnusedBadge.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/export/FileExportPreview.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
@ -1076,39 +1047,12 @@ exports[`better eslint`] = {
"public/app/features/alerting/unified/components/export/GrafanaModifyExport.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/export/GrafanaRuleFolderExporter.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/export/GrafanaRuleGroupExporter.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/expressions/Expression.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/mute-timings/MuteTimingTimeInterval.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"]
],
"public/app/features/alerting/unified/components/mute-timings/MuteTimingTimeRange.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/notification-policies/AlertGroupsSummary.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"]
],
"public/app/features/alerting/unified/components/notification-policies/EditDefaultPolicyForm.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"]
],
"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. Wrap text with <Trans />", "0"]
],
"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"]
@ -1135,15 +1079,9 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/features/alerting/unified/components/receivers/form/ChannelSubForm.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/CloudReceiverForm.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "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"]
],
"public/app/features/alerting/unified/components/receivers/form/GrafanaReceiverForm.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@ -1174,26 +1112,12 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.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"]
],
"public/app/features/alerting/unified/components/rule-editor/AlertRuleNameInput.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. Wrap text with <Trans />", "3"]
],
"public/app/features/alerting/unified/components/rule-editor/AnnotationKeyInput.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/CloudAlertPreview.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/rule-editor/CloudEvaluationBehavior.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/DashboardAnnotationField.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
@ -1206,10 +1130,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/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"]
],
"public/app/features/alerting/unified/components/rule-editor/NotificationsStep.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
@ -1234,9 +1154,8 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/alerting/unified/components/rule-editor/QueryWrapper.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/rule-editor/RecordingRuleEditor.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@ -1249,13 +1168,9 @@ 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/simplifiedRouting/route-settings/MuteTimingFields.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/RouteSettings.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/rule-editor/notificaton-preview/NotificationRoute.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@ -1344,27 +1259,12 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/alerting/unified/components/silences/SilencesEditor.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 in text props. Wrap text with <Trans /> or use t()", "2"]
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/alerting/unified/components/silences/SilencesFilter.tsx:5381": [
[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/components/silences/SilencesTable.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/alerting/unified/home/GettingStarted.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 />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "7"]
],
"public/app/features/alerting/unified/home/Insights.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
@ -1638,11 +1538,9 @@ exports[`better eslint`] = {
],
"public/app/features/dashboard-scene/v2schema/ImportDashboardFormV2.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, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
[0, 0, 0, "Unexpected any. Specify a different type.", "5"]
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
],
"public/app/features/dashboard-scene/v2schema/ImportDashboardOverviewV2.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@ -1678,13 +1576,11 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not re-export imported variable (\`./AddLibraryPanelWidget\`)", "0"]
],
"public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsEdit.tsx:5381": [
[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, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
"public/app/features/dashboard/components/AnnotationSettings/AnnotationSettingsList.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/dashboard/components/AnnotationSettings/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./AnnotationSettingsEdit\`)", "0"],
@ -1756,11 +1652,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard/components/HelpWizard/HelpWizard.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. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"]
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard/components/Inspector/PanelInspector.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@ -1784,8 +1676,7 @@ exports[`better eslint`] = {
],
"public/app/features/dashboard/components/PanelEditor/PanelEditor.tsx:5381": [
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "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/dashboard/components/PanelEditor/VisualizationSelectPane.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
@ -1847,8 +1738,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/features/dashboard/components/TransformationsEditor/TransformationOperationRow.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/TransformationsEditor/TransformationPicker.tsx:5381": [
[0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
@ -1866,9 +1756,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/dashboard/components/VersionHistory/VersionHistoryTable.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard/components/VersionHistory/useDashboardRestore.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
@ -1889,9 +1776,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard/containers/PublicDashboardPage.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/dashboard/containers/SoloPanelPage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard/dashgrid/SeriesVisibilityConfigFactory.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@ -2038,9 +1922,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"],
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "1"]
],
"public/app/features/datasources/components/BasicSettings.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/datasources/components/ButtonRow.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@ -2051,11 +1932,6 @@ exports[`better eslint`] = {
"public/app/features/datasources/components/DataSourcePluginConfigPage.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/datasources/components/DataSourceTestingStatus.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"]
],
"public/app/features/datasources/components/DataSourceTypeCard.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"]
@ -2143,12 +2019,8 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
],
"public/app/features/explore/CorrelationTransformationAddModal.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/explore/CorrelationUnsavedChangesModal.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/explore/ExploreRunQueryButton.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
@ -2159,10 +2031,6 @@ exports[`better eslint`] = {
"public/app/features/explore/Logs/LiveLogs.tsx:5381": [
[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"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/explore/Logs/LogsSamplePanel.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@ -2176,13 +2044,10 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/explore/NodeGraph/NodeGraphContainer.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 />", "0"]
],
"public/app/features/explore/PrometheusListView/RawListContainer.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/explore/RichHistory/RichHistorySettingsTab.tsx:5381": [
[0, 0, 0, "Do not use the t() function outside of a component or function", "0"],
@ -2198,23 +2063,14 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "1"]
],
"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"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "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 />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/SearchBar/TracePageSearchBar.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. Wrap text with <Trans />", "3"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx:5381": [
[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. Wrap text with <Trans />", "3"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/explore/TraceView/components/TracePageHeader/TracePageHeader.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@ -2274,10 +2130,6 @@ exports[`better eslint`] = {
"public/app/features/explore/TraceView/components/model/transform-trace-data.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"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"]
],
"public/app/features/explore/TraceView/components/types/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`../settings/SpanBarSettings\`)", "0"],
[0, 0, 0, "Do not re-export imported variable (\`./TNil\`)", "1"],
@ -2334,20 +2186,10 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/expressions/components/Math.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()", "4"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "5"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "6"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "7"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "8"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "9"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "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 />", "3"]
],
"public/app/features/expressions/guards.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@ -2438,10 +2280,6 @@ exports[`better eslint`] = {
"public/app/features/logs/utils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/manage-dashboards/components/ImportDashboardForm.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/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
@ -2483,9 +2321,6 @@ exports[`better eslint`] = {
"public/app/features/migrate-to-cloud/onprem/useNotifyOnSuccess.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/notifications/StoredNotifications.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/org/NewOrgPage.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
@ -2547,14 +2382,8 @@ exports[`better eslint`] = {
"public/app/features/plugins/admin/components/GetStartedWithPlugin/index.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./GetStartedWithPlugin\`)", "0"]
],
"public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/plugins/admin/components/InstallControls/InstallControlsWarning.tsx:5381": [
[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. Wrap text with <Trans />", "3"]
[0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
"public/app/features/plugins/admin/components/InstallControls/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./InstallControlsButton\`)", "0"],
@ -2581,9 +2410,8 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/plugins/admin/components/PluginUsage.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/plugins/admin/components/VersionList.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
@ -2599,11 +2427,6 @@ exports[`better eslint`] = {
"public/app/features/plugins/admin/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/plugins/components/PluginsErrorsInfo.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/plugins/datasource_srv.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],

@ -122,16 +122,20 @@ const ServiceInfo = () => {
title={t('admin.service-info.title-unlimited-expert-support', 'Unlimited Expert Support')}
image="public/img/licensing/customer_support.svg"
>
24 x 7 x 365 support via
<Trans i18nKey="admin.service-info.year-round-support">24 × 7 × 365 support via</Trans>
<List nested={true}>
<Item title="Email" />
<Item title="Private Slack channel" />
<Item title="Phone" />
<Item title={t('admin.service-info.title-email', 'Email')} />
<Item title={t('admin.service-info.title-private-slack-channel', 'Private Slack channel')} />
<Item title={t('admin.service-info.title-phone', 'Phone')} />
</List>
</Item>
<Item title="Hand-in-hand support" image="public/img/licensing/handinhand_support.svg">
in the upgrade process
</Item>
<Item
title={t(
'admin.service-info.title-handinhand-support-in-the-upgrade-process',
'Hand-in-hand support in the upgrade process'
)}
image="public/img/licensing/handinhand_support.svg"
/>
</List>
<div style={{ marginTop: '20px' }}>

@ -80,7 +80,7 @@ export const AlertsFolderView = ({ folder }: Props) => {
options={sortOptions}
width={25}
aria-label={t('alerting.alerts-folder-view.aria-label-sort', 'Sort')}
placeholder={`Sort (Default A-Z)`}
placeholder={t('alerting.alerts-folder-view.placeholder-sort-default-az', 'Sort (Default A-Z)')}
prefix={<Icon name={sortOrder === SortOrder.Ascending ? 'sort-amount-up' : 'sort-amount-down'} />}
/>
<FilterInput

@ -61,7 +61,13 @@ export function RedirectToRuleViewer(): JSX.Element | null {
if (error) {
return (
<RuleViewerLayout title={pageTitle}>
<Alert title={`Failed to load rules from ${sourceName}`}>
<Alert
title={t(
'alerting.redirect-to-rule-viewer.title-failed-to-load',
'Failed to load rules from {{sourceName}}',
{ sourceName }
)}
>
{isFetchError(error) && (
<details className={styles.errorMessage}>
{error.message}

@ -5,6 +5,8 @@ import { GroupBase, OptionsOrGroups, createFilter } from 'react-select';
import { SelectableValue } from '@grafana/data';
import { Field, Select, useStyles2 } from '@grafana/ui';
import { t } from '../../../../core/internationalization';
export interface AlertLabelDropdownProps {
onChange: (newValue: SelectableValue<string>) => void;
onOpenMenu?: () => void;
@ -42,7 +44,7 @@ const AlertLabelDropdown: FC<AlertLabelDropdownProps> = forwardRef<HTMLDivElemen
<div ref={ref}>
<Field disabled={false} data-testid={`alertlabel-${type}-picker`} className={styles.resetMargin}>
<Select<string>
placeholder={`Choose ${type}`}
placeholder={t('alerting.alert-label-dropdown.placeholder-select', 'Choose {{type}}', { type })}
width={29}
className="ds-picker select-container"
backspaceRemovesValue={false}

@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { IconButton, Pagination, useStyles2 } from '@grafana/ui';
import { t } from '../../../../core/internationalization';
import { usePagination } from '../hooks/usePagination';
import { getPaginationStyles } from '../styles/pagination';
@ -127,7 +128,11 @@ export const DynamicTable = <T extends object>({
{isExpandable && (
<div className={cx(styles.cell(), styles.expandCell)}>
<IconButton
tooltip={`${isItemExpanded ? 'Collapse' : 'Expand'} row`}
tooltip={
isItemExpanded
? t('alerting.dynamic-table.tooltip-collapse-row', 'Collapse row')
: t('alerting.dynamic-table.tooltip-expand-row', 'Expand row')
}
data-testid={selectors.components.AlertRules.toggle}
name={isItemExpanded ? 'angle-down' : 'angle-right'}
onClick={() => toggleExpanded(item)}

@ -20,9 +20,17 @@ interface ProvisioningAlertProps extends ExtraAlertProps {
export const ProvisioningAlert = ({ resource, ...rest }: ProvisioningAlertProps) => {
return (
<Alert title={`This ${resource} cannot be edited through the UI`} severity="info" {...rest}>
This {resource} has been provisioned, that means it was created by config. Please contact your server admin to
update this {resource}.
<Alert
title={t('alerting.provisioning.title-provisioned', 'This {{resource}} cannot be edited through the UI', {
resource,
})}
severity="info"
{...rest}
>
<Trans i18nKey="alerting.provisioning.body-provisioned">
This {{ resource }} has been provisioned, that means it was created by config. Please contact your server admin
to update this {{ resource }}.
</Trans>
</Alert>
);
};

@ -221,7 +221,6 @@ export const ContactPointHeader = ({ contactPoint, onDelete }: ContactPointHeade
size="sm"
icon={canEdit ? 'pen' : 'eye'}
type="button"
aria-label={`${canEdit ? 'edit' : 'view'}-action`}
data-testid={`${canEdit ? 'edit' : 'view'}-action`}
href={`/alerting/notifications/receivers/${encodeURIComponent(urlId)}/edit`}
>
@ -229,7 +228,13 @@ export const ContactPointHeader = ({ contactPoint, onDelete }: ContactPointHeade
</LinkButton>
{menuActions.length > 0 && (
<Dropdown overlay={<Menu>{menuActions}</Menu>}>
<MoreButton aria-label={`More actions for contact point "${contactPoint.name}"`} />
<MoreButton
aria-label={t(
'alerting.contact-point-header.aria-label-more-actions',
'More actions for contact point "{{contactPointName}}"',
{ contactPointName: contactPoint.name }
)}
/>
</Dropdown>
)}
</Stack>

@ -184,11 +184,11 @@ describe('contact points', () => {
const unusedBadge = screen.getAllByLabelText('unused');
expect(unusedBadge).toHaveLength(4);
const viewProvisioned = screen.getByRole('link', { name: 'view-action' });
const viewProvisioned = screen.getByTestId('view-action');
expect(viewProvisioned).toBeInTheDocument();
expect(viewProvisioned).toBeEnabled();
const editButtons = screen.getAllByRole('link', { name: 'edit-action' });
const editButtons = screen.getAllByTestId('edit-action');
expect(editButtons).toHaveLength(4);
editButtons.forEach((button) => {
expect(button).toBeEnabled();
@ -213,11 +213,11 @@ describe('contact points', () => {
expect(screen.getByRole('link', { name: 'add contact point' })).toHaveAttribute('aria-disabled', 'true');
// edit permission is based on API response - we should have 3 buttons
const editButtons = await screen.findAllByRole('link', { name: 'edit-action' });
const editButtons = await screen.findAllByTestId('edit-action');
expect(editButtons).toHaveLength(3);
// there should be view buttons though - one for provisioned, and one for the un-editable contact point
const viewButtons = screen.getAllByRole('link', { name: 'view-action' });
const viewButtons = screen.getAllByTestId('view-action');
expect(viewButtons).toHaveLength(2);
// check buttons in Notification Templates
@ -373,7 +373,7 @@ describe('contact points', () => {
const unusedBadge = screen.getAllByLabelText('unused');
expect(unusedBadge).toHaveLength(1);
const editButtons = screen.getAllByRole('link', { name: 'edit-action' });
const editButtons = screen.getAllByTestId('edit-action');
expect(editButtons).toHaveLength(2);
editButtons.forEach((button) => {
expect(button).toBeEnabled();
@ -417,7 +417,7 @@ describe('contact points', () => {
expect(screen.queryByRole('link', { name: 'add contact point' })).not.toBeInTheDocument();
const viewProvisioned = screen.getByRole('link', { name: 'view-action' });
const viewProvisioned = screen.getByTestId('view-action');
expect(viewProvisioned).toBeInTheDocument();
expect(viewProvisioned).toBeEnabled();

@ -7,6 +7,9 @@ export const UnusedContactPointBadge = () => (
aria-label={t('alerting.unused-contact-point-badge.aria-label-unused', 'unused')}
color="orange"
icon="exclamation-triangle"
tooltip="This contact point is not used in any notification policy or alert rule"
tooltip={t(
'alerting.unused-contact-point-badge.tooltip-unused',
'This contact point is not used in any notification policy or alert rule'
)}
/>
);

@ -20,7 +20,9 @@ export function GrafanaRuleFolderExporter({ folder, onClose }: GrafanaRuleFolder
return (
<GrafanaExportDrawer
title={`Export ${folder.title} rules`}
title={t('alerting.grafana-rule-folder-exporter.title-drawer', 'Export {{folderName}} rules', {
folderName: folder.title,
})}
activeTab={activeTab}
onTabChange={setActiveTab}
onClose={onClose}

@ -20,7 +20,7 @@ export function GrafanaRuleGroupExporter({ folderUid, groupName, onClose }: Graf
return (
<GrafanaExportDrawer
title={`Export ${groupName} rules`}
title={t('alerting.grafana-rule-group-exporter.title-drawer', 'Export {{groupName}} rules', { groupName })}
activeTab={activeTab}
onTabChange={setActiveTab}
onClose={onClose}

@ -388,7 +388,7 @@ const Header: FC<HeaderProps> = ({
variant="secondary"
className={styles.mutedIcon}
onClick={onRemoveExpression}
tooltip={`Remove expression "${refId}"`}
tooltip={t('alerting.header.tooltip-remove', 'Remove expression "{{refId}}"', { refId })}
/>
</Stack>
</header>

@ -73,7 +73,10 @@ export const MuteTimingTimeInterval = () => {
</Field>
<Field
label={t('alerting.mute-timing-time-interval.label-days-of-the-month', 'Days of the month')}
description="The days of the month, 1:31, of a month. Negative values can be used to represent days which begin at the end of the month"
description={t(
'alerting.mute-timing-time-interval.description-dats-of-the-month',
'The days of the month, 1:31, of a month. Negative values can be used to represent days which begin at the end of the month'
)}
invalid={!!errors.time_intervals?.[timeIntervalIndex]?.days_of_month}
error={errors.time_intervals?.[timeIntervalIndex]?.days_of_month?.message}
>
@ -93,7 +96,10 @@ export const MuteTimingTimeInterval = () => {
</Field>
<Field
label={t('alerting.mute-timing-time-interval.label-months', 'Months')}
description="The months of the year in either numerical or the full calendar month"
description={t(
'alerting.mute-timing-time-interval.description-months',
'The months of the year in either numerical or the full calendar month'
)}
invalid={!!errors.time_intervals?.[timeIntervalIndex]?.months}
error={errors.time_intervals?.[timeIntervalIndex]?.months?.message}
>

@ -37,7 +37,10 @@ export const MuteTimingTimeRange = ({ intervalIndex }: Props) => {
<Field
className={styles.field}
label={t('alerting.mute-timing-time-range.label-time-range', 'Time range')}
description="The time inclusive of the start and exclusive of the end time (in UTC if no location has been selected, otherwise local time)"
description={t(
'alerting.mute-timing-time-range.description-time-range',
'The time inclusive of the start and exclusive of the end time (in UTC if no location has been selected, otherwise local time)'
)}
invalid={timeRangeInvalid}
>
<>

@ -4,6 +4,8 @@ import * as React from 'react';
import { Badge, Stack } from '@grafana/ui';
import { t } from '../../../../../core/internationalization';
interface Props {
active?: number;
suppressed?: number;
@ -15,15 +17,33 @@ export const AlertGroupsSummary = ({ active = 0, suppressed = 0, unprocessed = 0
const total = active + suppressed + unprocessed;
if (active) {
statsComponents.push(<Badge color="red" key="firing" text={`${active} firing`} />);
statsComponents.push(
<Badge
color="red"
key="firing"
text={t('alerting.alert-groups-summary.text-firing', '{{count}} firing', { count: active })}
/>
);
}
if (suppressed) {
statsComponents.push(<Badge color="blue" key="suppressed" text={`${suppressed} suppressed`} />);
statsComponents.push(
<Badge
color="blue"
key="suppressed"
text={t('alerting.alert-groups-summary.text-suppressed', '{{count}} suppressed', { count: suppressed })}
/>
);
}
if (unprocessed) {
statsComponents.push(<Badge color="orange" key="unprocessed" text={`${unprocessed} unprocessed`} />);
statsComponents.push(
<Badge
color="orange"
key="unprocessed"
text={t('alerting.alert-groups-summary.text-unprocessed', '{{count}} unprocessed', { count: unprocessed })}
/>
);
}
// if we only have one category it's not really necessary to repeat the total

@ -85,7 +85,10 @@ export const AmRootRouteForm = ({ actionButtons, alertManagerSourceName, onSubmi
</Field>
<Field
label={t('alerting.am-root-route-form.am-group-select-label-group-by', 'Group by')}
description="Combine multiple alerts into a single notification by grouping them by the same label values."
description={t(
'alerting.am-root-route-form.am-group-select-description-group-by',
'Combine multiple alerts into a single notification by grouping them by the same label values.'
)}
data-testid="am-group-select"
>
<Controller
@ -117,7 +120,10 @@ export const AmRootRouteForm = ({ actionButtons, alertManagerSourceName, onSubmi
<div className={styles.timingFormContainer}>
<Field
label={t('alerting.am-root-route-form.am-group-wait-label-group-wait', 'Group wait')}
description="The waiting time before sending the first notification for a new group of alerts. Default 30 seconds."
description={t(
'alerting.am-root-route-form.am-group-description-label',
'The waiting time before sending the first notification for a new group of alerts. Default 30 seconds.'
)}
invalid={!!errors.groupWaitValue}
error={errors.groupWaitValue?.message}
data-testid="am-group-wait"
@ -131,7 +137,10 @@ export const AmRootRouteForm = ({ actionButtons, alertManagerSourceName, onSubmi
</Field>
<Field
label={t('alerting.am-root-route-form.am-group-interval-label-group-interval', 'Group interval')}
description="The wait time before sending a notification about changes in the alert group after the first notification has been sent. Default is 5 minutes."
description={t(
'alerting.am-root-route-form.am-group-interval-description',
'The wait time before sending a notification about changes in the alert group after the first notification has been sent. Default is 5 minutes.'
)}
invalid={!!errors.groupIntervalValue}
error={errors.groupIntervalValue?.message}
data-testid="am-group-interval"
@ -145,7 +154,10 @@ export const AmRootRouteForm = ({ actionButtons, alertManagerSourceName, onSubmi
</Field>
<Field
label={t('alerting.am-root-route-form.am-repeat-interval-label-repeat-interval', 'Repeat interval')}
description="The wait time before resending a notification that has already been sent successfully. Default is 4 hours. Should be a multiple of Group interval."
description={t(
'alerting.am-root-route-form.am-repeat-interval-description',
'The wait time before resending a notification that has already been sent successfully. Default is 4 hours. Should be a multiple of Group interval.'
)}
invalid={!!errors.repeatIntervalValue}
error={errors.repeatIntervalValue?.message}
data-testid="am-repeat-interval"

@ -95,7 +95,10 @@ export const AmRoutesExpandedForm = ({ actionButtons, route, onSubmit, defaults
color="orange"
className={styles.noMatchersWarning}
icon="exclamation-triangle"
text="If no matchers are specified, this notification policy will handle all alert instances."
text={t(
'alerting.am-routes-expanded-form.badge-no-matchers',
'If no matchers are specified, this notification policy will handle all alert instances.'
)}
/>
)}
{fields.length > 0 && (
@ -197,7 +200,10 @@ export const AmRoutesExpandedForm = ({ actionButtons, route, onSubmit, defaults
{watch().overrideGrouping && (
<Field
label={t('alerting.am-routes-expanded-form.label-group-by', 'Group by')}
description="Combine multiple alerts into a single notification by grouping them by the same label values. If empty, it is inherited from the parent policy."
description={t(
'alerting.am-routes-expanded-form.description-group-by',
'Combine multiple alerts into a single notification by grouping them by the same label values. If empty, it is inherited from the parent policy.'
)}
>
<Controller
rules={{

@ -230,7 +230,11 @@ export function ChannelSubForm<R extends ChannelValues>({
customValidators={customValidators}
/>
{!!(mandatoryOptions?.length && optionalOptions?.length) && (
<CollapsibleSection label={`Optional ${notifier.dto.name} settings`}>
<CollapsibleSection
label={t('alerting.channel-sub-form.label-section', 'Optional {{name}} settings', {
name: notifier.dto.name,
})}
>
{notifier.dto.info !== '' && (
<Alert title="" severity="info">
{notifier.dto.info}

@ -20,7 +20,10 @@ export const GrafanaCommonChannelSettings = ({
'alerting.grafana-common-channel-settings.label-disable-resolved-message',
'Disable resolved message'
)}
description="Disable the resolve message [OK] that is sent when alerting state returns to false"
description={t(
'alerting.grafana-common-channel-settings.description-disable-resolved-message',
'Disable the resolve message [OK] that is sent when alerting state returns to false'
)}
disabled={readOnly}
/>
</Field>

@ -54,16 +54,24 @@ export function TemplatesPicker({ onSelect, option, valueInForm }: TemplatesPick
<>
<Button
icon="edit"
tooltip={`Edit ${option.label.toLowerCase()} using existing notification templates.`}
tooltip={t('alerting.templates-picker.tooltip-edit', 'Edit {{name}} using existing notification templates.', {
name: option.label.toLowerCase(),
})}
onClick={onClick}
variant="secondary"
size="sm"
>
{`Edit ${option.label}`}
<Trans i18nKey="alerting.templates-picker.button-edit" values={{ name: option.label }}>
Edit {'{{name}}'}
</Trans>
</Button>
{showTemplates && (
<Drawer title={`Edit ${option.label}`} size="md" onClose={handleClose}>
<Drawer
title={t('alerting.templates-picker.title-drawer', 'Edit {{name}}', { name: option.label })}
size="md"
onClose={handleClose}
>
<TemplateSelector onSelect={onSelect} onClose={handleClose} option={option} valueInForm={valueInForm} />
</Drawer>
)}
@ -219,7 +227,10 @@ function TemplateSelector({ onSelect, onClose, option, valueInForm }: TemplateSe
defaultValue={defaultTemplateValue}
/>
<IconButton
tooltip="Copy selected notification template to clipboard. You can use it in the custom tab."
tooltip={t(
'alerting.template-selector.tooltip-copy',
'Copy selected notification template to clipboard. You can use it in the custom tab.'
)}
onClick={() => copyToClipboard(template?.value?.content ?? defaultTemplateValue?.value?.content ?? '')}
name="copy"
/>

@ -4,7 +4,7 @@ import { DataSourceInstanceSettings } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { config } from '@grafana/runtime';
import { Field, Input, Stack, Text } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { RuleFormType, RuleFormValues } from '../../types/rule-form';
@ -46,10 +46,12 @@ export const AlertRuleNameAndMetric = () => {
return (
<RuleEditorSection
stepNo={1}
title={`Enter ${entityName} name`}
title={t('alerting.alert-rule-name-and-metric.title-section', 'Enter {{entityName}} name', { entityName })}
description={
<Text variant="bodySmall" color="secondary">
Enter a name to identify your {entityName}.
<Trans i18nKey="alerting.alert-rule-name-and-metric.description-section">
Enter a name to identify your {{ entityName }}.
</Trans>
</Text>
}
>
@ -70,7 +72,11 @@ export const AlertRuleNameAndMetric = () => {
: undefined,
})}
aria-label={t('alerting.alert-rule-name-and-metric.aria-label-name', 'name')}
placeholder={`Give your ${namePlaceholder} a name`}
placeholder={t(
'alerting.alert-rule-name-and-metric.placeholder-name',
'Give your {{namePlaceholder}} a name',
{ namePlaceholder }
)}
/>
</Field>
{isGrafanaRecordingRule && (
@ -87,7 +93,10 @@ export const AlertRuleNameAndMetric = () => {
pattern: recordingRuleNameValidationPattern(RuleFormType.grafanaRecording),
})}
aria-label={t('alerting.alert-rule-name-and-metric.metric-aria-label-metric', 'metric')}
placeholder={`Give the name of the new recorded metric`}
placeholder={t(
'alerting.alert-rule-name-and-metric.metric-placeholder-recorded-metric',
'Give the name of the new recorded metric'
)}
/>
</Field>
)}

@ -31,7 +31,10 @@ export const CloudEvaluationBehavior = () => {
>
<Field
label={t('alerting.cloud-evaluation-behavior.label-pending-period', 'Pending period')}
description='Period during which the threshold condition must be met to trigger an alert. Selecting "None" triggers the alert immediately once the condition is met.'
description={t(
'alerting.cloud-evaluation-behavior.description-pending-period',
'Period during which the threshold condition must be met to trigger an alert. Selecting "None" triggers the alert immediately once the condition is met.'
)}
>
<div className={styles.flexRow}>
<Field invalid={!!errors.forTime?.message} error={errors.forTime?.message} className={styles.inlineField}>

@ -459,7 +459,10 @@ function EvaluationGroupCreationModal({
label={
<Label
htmlFor={evaluationGroupNameId}
description="A group evaluates all its rules over the same evaluation interval."
description={t(
'alerting.evaluation-group-creation-modal.description-group-name',
'A group evaluates all its rules over the same evaluation interval.'
)}
>
<Trans i18nKey="alerting.rule-form.evaluation.group-name">Evaluation group name</Trans>
</Label>
@ -546,7 +549,10 @@ export function ForInput({ evaluateEvery }: { evaluateEvery: string }) {
label={
<Label
htmlFor={evaluateForId}
description='Period during which the threshold condition must be met to trigger an alert. Selecting "None" triggers the alert immediately once the condition is met.'
description={t(
'alerting.for-input.description-pending',
'Period during which the threshold condition must be met to trigger an alert. Selecting "None" triggers the alert immediately once the condition is met.'
)}
>
<Trans i18nKey="alerting.rule-form.evaluation-behaviour.pending-period">Pending period</Trans>
</Label>

@ -256,7 +256,10 @@ export function MaxDataPointsOption({
<InlineField
labelWidth={24}
label={t('alerting.max-data-points-option.label-max-data-points', 'Max data points')}
tooltip="The maximum data points per series. Used directly by some data sources and used in calculation of auto interval. With streaming data this value is used for the rolling buffer."
tooltip={t(
'alerting.max-data-points-option.tooltip-max-data-points',
'The maximum data points per series. Used directly by some data sources and used in calculation of auto interval. With streaming data this value is used for the rolling buffer.'
)}
>
<Input
type="number"

@ -21,7 +21,10 @@ export function MuteTimingFields({ alertmanager }: BaseAlertmanagerArgs) {
<Field
label={t('alerting.mute-timing-fields.am-mute-timing-select-label-mute-timings', 'Mute timings')}
data-testid="am-mute-timing-select"
description="Select a mute timing to define when not to send notifications for this alert rule"
description={t(
'alerting.mute-timing-fields.am-mute-timing-select-description-mute-timings',
'Select a mute timing to define when not to send notifications for this alert rule'
)}
className={styles.muteTimingField}
invalid={!!errors.contactPoints?.[alertmanager]?.muteTimeIntervals}
>

@ -73,7 +73,10 @@ export const RoutingSettings = ({ alertManager }: RoutingSettingsProps) => {
{overrideGrouping && (
<Field
label={t('alerting.routing-settings.label-group-by', 'Group by')}
description="Combine multiple alerts into a single notification by grouping them by the same label values. If empty, it is inherited from the default notification policy."
description={t(
'alerting.routing-settings.description-group-by',
'Combine multiple alerts into a single notification by grouping them by the same label values. If empty, it is inherited from the default notification policy.'
)}
{...register(`contactPoints.${alertManager}.groupBy`)}
invalid={!!errors.contactPoints?.[alertManager]?.groupBy}
className={styles.optionalContent}

@ -90,13 +90,30 @@ const ExistingSilenceEditor = () => {
isFetchError(errorGettingExistingSilence) && errorGettingExistingSilence.status === 404;
if (existingSilenceNotFound) {
return <Alert title={`Existing silence "${silenceId}" not found`} severity="warning" />;
return (
<Alert
title={t(
'alerting.existing-silence-editor.title-silence-not-found',
'Existing silence "{{silenceId}}" not found',
{ silenceId }
)}
severity="warning"
/>
);
}
const canEditSilence = isGrafanaAlertManager ? silence?.accessControl?.write : true;
if (!canEditSilence) {
return <Alert title={`You do not have permission to edit/recreate this silence`} severity="error" />;
return (
<Alert
title={t(
'alerting.existing-silence-editor.title-permission-editrecreate-silence',
'You do not have permission to edit/recreate this silence'
)}
severity="error"
/>
);
}
return (

@ -163,7 +163,12 @@ const SilencesTable = () => {
dataTestId="not-expired-table"
/>
{itemsExpired.length > 0 && (
<CollapsableSection label={`Expired silences (${itemsExpired.length})`} isOpen={showExpiredFromUrl}>
<CollapsableSection
label={t('alerting.silences-table.label-section-expired', 'Expired silences ({{numExpired}})', {
numExpired: itemsExpired.length,
})}
isOpen={showExpiredFromUrl}
>
<div className={styles.callout}>
<Icon className={styles.calloutIcon} name="info-circle" />
<span>

@ -19,15 +19,25 @@ export default function GettingStarted() {
</Text>
<ul className={styles.list}>
<li>
Grafana alerting periodically queries data sources and evaluates the condition defined in the alert rule
<Trans i18nKey="alerting.getting-started.periodically-queries-data-sources">
Grafana alerting periodically queries data sources and evaluates the condition defined in the alert rule
</Trans>
</li>
<li>
<Trans i18nKey="alerting.getting-started.condition-breached-alert-instance-fires">
If the condition is breached, an alert instance fires
</Trans>
</li>
<li>Firing instances are routed to notification policies based on matching labels</li>
<li>Notifications are sent out to the contact points specified in the notification policy</li>
<li>
<Trans i18nKey="alerting.getting-started.firing-instances-routed-notification-policies">
Firing instances are routed to notification policies based on matching labels
</Trans>
</li>
<li>
<Trans i18nKey="alerting.getting-started.notification-policies-contact-points">
Notifications are sent out to the contact points specified in the notification policy
</Trans>
</li>
</ul>
<div className={styles.svgContainer}>
<Stack justifyContent={'center'}>
@ -47,27 +57,30 @@ export default function GettingStarted() {
</Text>
<ul className={styles.list}>
<li>
<Text weight="bold">Create an alert rule</Text> to query a data source and evaluate the condition defined
in the alert rule
<Trans i18nKey="alerting.getting-started.create-alert-rule">
<Text weight="bold">Create an alert rule</Text> to query a data source and evaluate the condition
defined in the alert rule
</Trans>
</li>
<li>
<Text weight="bold">Route alert notifications</Text> either directly to a contact point or through
notification policies for more flexibility
<Trans i18nKey="alerting.getting-started.route-alert-notifications">
<Text weight="bold">Route alert notifications</Text> either directly to a contact point or through
notification policies for more flexibility
</Trans>
</li>
<li>
<Text weight="bold">Monitor</Text> your alert rules using dashboards and visualizations
<Trans i18nKey="alerting.getting-started.monitor-alert-rules">
<Text weight="bold">Monitor</Text> your alert rules using dashboards and visualizations
</Trans>
</li>
</ul>
<p>
For a hands-on introduction, refer to our{' '}
<TextLink
href="https://grafana.com/tutorials/alerting-get-started/"
icon="angle-right"
inline={true}
external
>
tutorial to get started with Grafana Alerting
</TextLink>
<Trans i18nKey="alerting.getting-stared.learn-more">
For a hands-on introduction, refer to our{' '}
<TextLink href="https://grafana.com/tutorials/alerting-get-started/" inline={true} external>
tutorial to get started with Grafana Alerting
</TextLink>
</Trans>
</p>
</Stack>
</ContentBox>
@ -112,7 +125,10 @@ export function WelcomeHeader({ className }: { className?: string }) {
<ContentBox className={cx(styles.ctaContainer, className)}>
<WelcomeCTABox
title={t('alerting.welcome-header.title-alert-rules', 'Alert rules')}
description="Define the condition that must be met before an alert rule fires"
description={t(
'alerting.welcome-header.description-alert-rules',
'Define the condition that must be met before an alert rule fires'
)}
href="/alerting/list"
hrefText="Manage alert rules"
/>

@ -72,7 +72,7 @@ export const ImportDashboardFormV2 = ({
data-testid={selectors.components.ImportDashboardForm.name}
/>
</Field>
<Field label="Folder">
<Field label={t('dashboard-scene.import-dashboard-form-v2.label-folder', 'Folder')}>
<Controller<any>
render={({ field: { ref, value, onChange, ...field } }) => (
<FolderPicker
@ -144,7 +144,7 @@ export const ImportDashboardFormV2 = ({
{getButtonText(errors)}
</Button>
<Button type="reset" variant="secondary" onClick={onCancel}>
Cancel
<Trans i18nKey="dashboard-scene.import-dashboard-form-v2.cancel">Cancel</Trans>
</Button>
</Stack>
</>

@ -217,7 +217,10 @@ export const AnnotationSettingsEdit = ({ editIdx, dashboard }: Props) => {
</Field>
<Field
label={t('dashboard.annotation-settings-edit.label-hidden', 'Hidden')}
description="Annotation queries can be toggled on or off at the top of the dashboard. With this option checked this toggle will be hidden."
description={t(
'dashboard.annotation-settings-edit.description-hidden',
'Annotation queries can be toggled on or off at the top of the dashboard. With this option checked this toggle will be hidden.'
)}
>
<Checkbox name="hide" id="hide" value={annotation.hide} onChange={onChange} />
</Field>

@ -111,7 +111,11 @@ export const AnnotationSettingsList = ({ dashboard, onNew, onEdit }: Props) => {
<DeleteButton
size="sm"
onConfirm={() => onDelete(idx)}
aria-label={`Delete query with title "${annotation.name}"`}
aria-label={t(
'dashboard.annotation-settings-list.aria-label-delete',
'Delete query with title "{{title}}"',
{ title: annotation.name }
)}
/>
)}
</td>

@ -17,8 +17,8 @@ import {
Alert,
Select,
ClipboardButton,
Icon,
Stack,
TextLink,
} from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv';
@ -69,20 +69,15 @@ export function HelpWizard({ panel, plugin, onClose }: Props) {
return (
<Drawer
title={`Get help with this panel`}
title={t('dashboard.help-wizard.title-get-help-with-this-panel', 'Get help with this panel')}
size="lg"
onClose={onClose}
subtitle={
<Stack direction="column" gap={1}>
<Stack direction="row" gap={1}>
<a
href="https://grafana.com/docs/grafana/latest/troubleshooting/"
target="blank"
className="external-link"
rel="noopener noreferrer"
>
Troubleshooting docs <Icon name="external-link-alt" />
</a>
<TextLink href="https://grafana.com/docs/grafana/latest/troubleshooting/" external>
<Trans i18nKey="dashboard.help-wizard.troubleshooting-docs">Troubleshooting docs</Trans>
</TextLink>
</Stack>
<span className="muted">
<Trans i18nKey="help-wizard.troubleshooting-help">
@ -129,7 +124,7 @@ export function HelpWizard({ panel, plugin, onClose }: Props) {
</ClipboardButton>
) : (
<Button icon="download-alt" onClick={service.onDownloadDashboard}>
Download ({snapshotSize})
<Trans i18nKey="dashboard.help-wizard.download-snapshot">Download ({{ snapshotSize }})</Trans>
</Button>
)}
</div>
@ -153,7 +148,10 @@ export function HelpWizard({ panel, plugin, onClose }: Props) {
<>
<Field
label={t('dashboard.help-wizard.label-obfuscate-data', 'Obfuscate data')}
description="Modify the original data to hide sensitve information. Note the lengths will stay the same, and duplicate values will be equal."
description={t(
'dashboard.help-wizard.description-obfuscate-data',
'Modify the original data to hide sensitve information. Note the lengths will stay the same, and duplicate values will be equal.'
)}
>
<Stack direction="row" gap={1}>
<InlineSwitch
@ -186,7 +184,7 @@ export function HelpWizard({ panel, plugin, onClose }: Props) {
>
<Stack>
<Button icon="download-alt" onClick={service.onDownloadDashboard}>
<Trans i18nKey="help-wizard.download-snapshot">Download snapshot</Trans> ({snapshotSize})
<Trans i18nKey="help-wizard.download-snapshot">Download snapshot ({{ snapshotSize }})</Trans>
</Button>
<ClipboardButton
icon="github"

@ -398,7 +398,10 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
isOpen: true,
});
}}
title="Disconnects this panel from the library panel so that you can edit it regularly."
title={t(
'dashboard.panel-editor-unconnected.title-unlink',
'Disconnects this panel from the library panel so that you can edit it regularly.'
)}
key="unlink"
>
<Trans i18nKey="dashboard.panel-editor-unconnected.unlink">Unlink</Trans>

@ -194,7 +194,9 @@ export const TransformationOperationRow = ({
{config.featureToggles.transformationsRedesign && (
<ConfirmModal
isOpen={showDeleteModal}
title={`Delete ${uiConfig.name}?`}
title={t('dashboard.transformation-operation-row.title-delete', 'Delete {{name}}?', {
name: uiConfig.name,
})}
body="Note that removing one transformation may break others. If there is only a single transformation, you will go back to the main selection screen."
confirmText="Delete"
onConfirm={() => {

@ -3,7 +3,7 @@ import * as React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Checkbox, Button, Tag, ModalsController, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { DecoratedRevisionModel } from '../DashboardSettings/VersionsSettings';
@ -44,7 +44,11 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck }: VersionsT
<tr key={version.id}>
<td>
<Checkbox
aria-label={`Toggle selection of version ${version.version}`}
aria-label={t(
'dashboard.version-history-table.aria-label-toggle-selection',
'Toggle selection of version {{version}}',
{ version: version.version }
)}
className={css({
display: 'inline',
})}

@ -6,7 +6,7 @@ import AutoSizer from 'react-virtualized-auto-sizer';
import { GrafanaTheme2 } from '@grafana/data';
import { Alert, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
import { DashboardModel } from 'app/features/dashboard/state/DashboardModel';
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
@ -99,7 +99,12 @@ export interface SoloPanelProps extends State {
export const SoloPanel = ({ dashboard, notFound, panel, panelId, timezone }: SoloPanelProps) => {
const styles = useStyles2(getStyles);
if (notFound) {
return <Alert severity="error" title={`Panel with id ${panelId} not found`} />;
return (
<Alert
severity="error"
title={t('dashboard.solo-panel.title-not-found', 'Panel with id {{panelId}} not found', { panelId })}
/>
);
}
if (!panel || !dashboard) {

@ -29,8 +29,10 @@ export function BasicSettings({ dataSourceName, isDefault, onDefaultChange, onNa
<div className="gf-form max-width-30">
<InlineField
label={t('datasources.basic-settings.label-name', 'Name')}
tooltip="The name is used when you select the data source in panels. The default data source is
'preselected in new panels."
tooltip={t(
'datasources.basic-serttings.tooltip-name',
'The name is used when you select the data source in panels. The default data source is preselected in new panels.'
)}
grow
disabled={disabled}
labelWidth={14}

@ -5,7 +5,7 @@ import { DataSourceSettings as DataSourceSettingsType, GrafanaTheme2 } from '@gr
import { selectors as e2eSelectors } from '@grafana/e2e-selectors';
import { TestingStatus, config } from '@grafana/runtime';
import { AlertVariant, Alert, useTheme2, Link, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { contextSrv } from '../../../core/core';
import { trackCreateDashboardClicked } from '../tracking';
@ -50,7 +50,7 @@ const AlertSuccessMessage = ({ title, exploreUrl, dataSourceId, onDashboardLinkC
<Trans i18nKey="data-source-testing-status-page.success-more-details-links">
Next, you can start to visualize data by{' '}
<Link
aria-label={`Create a dashboard`}
aria-label={t('datasources.alert-success-message.aria-label-create-a-dashboard', 'Create a dashboard')}
href={`/dashboard/new-with-ds/${dataSourceId}`}
className="external-link"
onClick={onDashboardLinkClicked}
@ -59,7 +59,7 @@ const AlertSuccessMessage = ({ title, exploreUrl, dataSourceId, onDashboardLinkC
</Link>
, or by querying data in the{' '}
<Link
aria-label={`Explore data`}
aria-label={t('datasources.alert-success-message.aria-label-explore-data', 'Explore data')}
className={cx('external-link', {
[`${styles.disabled}`]: !canExploreDataSources,
'test-disabled': !canExploreDataSources,
@ -102,7 +102,10 @@ const ErrorDetailsLink = ({ link }: ErrorDetailsLinkProps) => {
<Trans i18nKey="data-source-testing-status-page.error-more-details-link">
Click{' '}
<Link
aria-label={`More details about the error`}
aria-label={t(
'datasources.error-details-link.aria-label-more-details-about-the-error',
'More details about the error'
)}
className={'external-link'}
href={link}
target="_blank"

@ -130,7 +130,11 @@ export const CorrelationTransformationAddModal = ({
return (
<Modal
isOpen={true}
title={`${transformationToEdit ? 'Edit' : 'Add'} transformation`}
title={
transformationToEdit
? t('explore.correlation-transformation-add-modal.title-edit', 'Edit transformation')
: t('explore.correlation-transformation-add-modal.title-add', 'Add transformation')
}
onDismiss={onCancel}
className={css({ width: '700px' })}
>

@ -1,7 +1,7 @@
import { css } from '@emotion/css';
import { Button, Modal } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
interface UnsavedChangesModalProps {
message: string;
@ -14,7 +14,10 @@ export const CorrelationUnsavedChangesModal = ({ onSave, onDiscard, onCancel, me
return (
<Modal
isOpen={true}
title={`Unsaved changes to correlation`}
title={t(
'explore.correlation-unsaved-changes-modal.title-unsaved-changes-to-correlation',
'Unsaved changes to correlation'
)}
onDismiss={onCancel}
icon="exclamation-triangle"
className={css({ width: '600px' })}

@ -1,37 +1,16 @@
import { css } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { Icon, Stack, useStyles2 } from '@grafana/ui';
import { Stack, TextLink } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
interface Props {
feedbackUrl?: string;
feedbackUrl: string;
}
export function LogsFeedback({ feedbackUrl }: Props) {
const styles = useStyles2(getStyles);
return (
<Stack>
<a
href={feedbackUrl}
className={styles.link}
title="The logs table is new, please let us know how we can improve it"
target="_blank"
rel="noreferrer noopener"
>
<Icon name="comment-alt-message" /> Give feedback
</a>
<TextLink href={feedbackUrl} external>
<Trans i18nKey="explore.logs-feedback.give-feedback">Give feedback</Trans>
</TextLink>
</Stack>
);
}
function getStyles(theme: GrafanaTheme2) {
return {
link: css({
color: theme.colors.text.secondary,
fontSize: theme.typography.bodySmall.fontSize,
':hover': {
color: theme.colors.text.link,
},
}),
};
}

@ -6,6 +6,7 @@ import { useToggle, useWindowSize } from 'react-use';
import { applyFieldOverrides, DataFrame, GrafanaTheme2, SplitOpen } from '@grafana/data';
import { config, reportInteraction } from '@grafana/runtime';
import { useStyles2, useTheme2, PanelChrome } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { layeredLayoutThreshold } from 'app/plugins/panel/nodeGraph/NodeGraph';
import { NodeGraph } from '../../../plugins/panel/nodeGraph';
@ -91,7 +92,7 @@ export function UnconnectedNodeGraphContainer(props: Props) {
return (
<PanelChrome
title={`Node graph`}
title={t('explore.unconnected-node-graph-container.title-node-graph', 'Node graph')}
titleItems={countWarning}
// We allow collapsing this only when it is shown together with trace view.
collapsible={!!withTraceView}

@ -7,6 +7,7 @@ import { VariableSizeList as List } from 'react-window';
import { DataFrame, Field as DataFrameField } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { Field, Switch } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { ItemLabels } from './ItemLabels';
import RawListItem from './RawListItem';
@ -117,9 +118,18 @@ const RawListContainer = (props: RawListContainerProps) => {
return (
<section>
<header className={styles.header}>
<Field className={styles.switchWrapper} label={`Expand results`} htmlFor={'isExpandedView'}>
<Field
className={styles.switchWrapper}
label={t('explore.raw-list-container.label-expand-results', 'Expand results')}
htmlFor={'isExpandedView'}
>
<div className={styles.switch}>
<Switch onChange={onContentClick} id={switchId} value={isExpandedView} label={`Expand results`} />
<Switch
onChange={onContentClick}
id={switchId}
value={isExpandedView}
label={t('explore.raw-list-container.label-expand-results', 'Expand results')}
/>
</div>
</Field>

@ -21,7 +21,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { config, reportInteraction } from '@grafana/runtime';
import { Icon, PopoverContent, Tooltip, useTheme2 } from '@grafana/ui';
import { getButtonStyles } from '@grafana/ui/internal';
import { Trans } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { Trace } from '../../types';
@ -198,7 +198,7 @@ export default memo(function NextPrevResult(props: NextPrevResultProps) {
<span className={styles.matches}>{getMatchesMetadata(depth, services)}</span>
<div className={buttonEnabled ? styles.buttons : cx(styles.buttons, styles.buttonsDisabled)}>
<div
aria-label="Prev result button"
aria-label={t('explore.next-prev-result.aria-label-prev', 'Prev result button')}
className={buttonClass}
onClick={(event) => prevResult(event, buttonEnabled)}
onKeyDown={(event) => prevResultOnKeyDown(event, buttonEnabled)}
@ -208,7 +208,7 @@ export default memo(function NextPrevResult(props: NextPrevResultProps) {
<Trans i18nKey="explore.prev">Prev</Trans>
</div>
<div
aria-label="Next result button"
aria-label={t('explore.next-prev-result.aria-label-next', 'Next result button')}
className={buttonClass}
onClick={(event) => nextResult(event, buttonEnabled)}
onKeyDown={(event) => nextResultOnKeyDown(event, buttonEnabled)}

@ -18,7 +18,7 @@ import { memo, Dispatch, SetStateAction, useMemo } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Button, Switch, useStyles2 } from '@grafana/ui';
import { getButtonStyles } from '@grafana/ui/internal';
import { Trans } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { SearchProps } from '../../../useSearch';
import { Trace } from '../../types';
@ -81,7 +81,7 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps)
disabled={!clearEnabled}
type="button"
fill="outline"
aria-label="Clear filters button"
aria-label={t('explore.trace-page-search-bar.aria-label-clear-filters', 'Clear filters button')}
onClick={clear}
>
<Trans i18nKey="explore.clear">Clear</Trans>
@ -90,7 +90,7 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps)
<Switch
value={search.matchesOnly}
onChange={(value) => setShowSpanFilterMatchesOnly(value.currentTarget.checked ?? false)}
label="Show matches only switch"
label={t('explore.trace-page-search-bar.label-show-matches', 'Show matches only switch')}
disabled={!spanFilterMatches?.size}
/>
<Button
@ -107,7 +107,7 @@ export default memo(function TracePageSearchBar(props: TracePageSearchBarProps)
<Switch
value={search.criticalPathOnly}
onChange={(value) => setShowCriticalPathSpansOnly(value.currentTarget.checked ?? false)}
label="Show critical path only switch"
label={t('explore.trace-page-search-bar.label-show-paths', 'Show critical path only switch')}
/>
<Button
onClick={() => setShowCriticalPathSpansOnly(!search.criticalPathOnly)}

@ -195,7 +195,9 @@ export const SpanFilters = memo((props: SpanFilterProps) => {
<InlineField
label={t('explore.span-filters.label-duration', 'Duration')}
labelWidth={16}
tooltip="Filter by duration. Accepted units are ns, us, ms, s, m, h"
tooltip={t('explore.span-filters.tooltip-duration', 'Filter by duration. Accepted units are {{units}}', {
units: 'ns, us, ms, s, m, h',
})}
>
<HorizontalGroup spacing="xs" align="flex-start">
<Select
@ -239,7 +241,10 @@ export const SpanFilters = memo((props: SpanFilterProps) => {
<InlineField
label={t('explore.span-filters.label-tags', 'Tags')}
labelWidth={16}
tooltip="Filter by tags, process tags or log fields in your spans."
tooltip={t(
'explore.span-filters.tooltip-tags',
'Filter by tags, process tags or log fields in your spans.'
)}
>
<SpanFiltersTags
search={search}

@ -61,7 +61,10 @@ export default function SpanBarSettings({ options, onOptionsChange }: Props) {
<InlineField
label={t('explore.span-bar-settings.label-tag-key', 'Tag key')}
labelWidth={26}
tooltip="Tag key which will be used to get the tag value. A span's attributes and resources will be searched for the tag key"
tooltip={t(
'explore.span-bar-settings.tooltip-tag-key',
"Tag key which will be used to get the tag value. A span's attributes and resources will be searched for the tag key"
)}
>
<Input
type="text"
@ -91,7 +94,10 @@ export const SpanBarSection = ({ options, onOptionsChange }: DataSourcePluginOpt
title={t('explore.span-bar-section.title-span-bar', 'Span bar')}
description={
<ConfigDescriptionLink
description="Add additional info next to the service and operation on a span bar row in the trace view."
description={t(
'explore.span-bar-section.description-link',
'Add additional info next to the service and operation on a span bar row in the trace view.'
)}
suffix={suffix}
feature="the span bar"
/>

@ -3,8 +3,8 @@ import { ChangeEvent } from 'react';
import * as React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Icon, InlineField, InlineLabel, TextArea, Toggletip, useStyles2, Stack } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Icon, InlineField, InlineLabel, TextArea, Toggletip, useStyles2, Stack, TextLink } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { ExpressionQuery } from '../types';
@ -53,43 +53,73 @@ export const Math = ({ labelWidth, onChange, query, onRunQuery }: Props) => {
<div className={styles.documentationFunctions}>
<DocumentedFunction
name="abs"
description="returns the absolute value of its argument which can be a number or a series"
description={t(
'expression.math.description-abs',
'Returns the absolute value of its argument which can be a number or a series'
)}
/>
<DocumentedFunction
name="is_inf"
description="returns 1 for Inf values (negative or positive) and 0 for other values. It's able to operate on series or scalar values."
description={t(
'expression.math.description-is-inf',
"Returns 1 for Inf values (negative or positive) and 0 for other values. It's able to operate on series or scalar values."
)}
/>
<DocumentedFunction
name="is_nan"
description="returns 1 for NaN values and 0 for other values. It's able to operate on series or scalar values."
description={t(
'expression.math.description-is-nan',
"Returns 1 for NaN values and 0 for other values. It's able to operate on series or scalar values."
)}
/>
<DocumentedFunction
name="is_null"
description="returns 1 for null values and 0 for other values. It's able to operate on series or scalar values."
description={t(
'expression.math.description-is-null',
"Returns 1 for null values and 0 for other values. It's able to operate on series or scalar values."
)}
/>
<DocumentedFunction
name="is_number"
description="returns 1 for all real number values and 0 for non-number. It's able to operate on series or scalar values."
description={t(
'expression.math.description-is-number',
"Returns 1 for all real number values and 0 for non-number. It's able to operate on series or scalar values."
)}
/>
<DocumentedFunction
name="log"
description="returns the natural logarithm of its argument, which can be a number or a series"
description={t(
'expression.math.description-log',
'Returns the natural logarithm of its argument, which can be a number or a series'
)}
/>
<DocumentedFunction
name="inf, infn, nan, and null"
description="The inf for infinity positive, infn for infinity negative, nan, and null functions all return a single scalar value that matches its name."
description={t(
'expression.math.description-inf-nan-null',
'The inf for infinity positive, infn for infinity negative, nan, and null functions all return a single scalar value that matches its name.'
)}
/>
<DocumentedFunction
name="round"
description="returns a rounded integer value. It's able to operate on series or escalar values."
description={t(
'expression.math.description-round',
"Returns a rounded integer value. It's able to operate on series or escalar values."
)}
/>
<DocumentedFunction
name="ceil"
description="rounds the number up to the nearest integer value. It's able to operate on series or escalar values."
description={t(
'expression.math.description-ceil',
"Rounds the number up to the nearest integer value. It's able to operate on series or escalar values."
)}
/>
<DocumentedFunction
name="floor"
description="rounds the number down to the nearest integer value. It's able to operate on series or escalar values."
description={t(
'expression.math.description-floor',
"Rounds the number down to the nearest integer value. It's able to operate on series or escalar values."
)}
/>
</div>
</div>
@ -102,14 +132,12 @@ export const Math = ({ labelWidth, onChange, query, onRunQuery }: Props) => {
footer={
<div>
See our additional documentation on{' '}
<a
className={styles.documentationLink}
target="_blank"
<TextLink
external
href="https://grafana.com/docs/grafana/latest/panels/query-a-data-source/use-expressions-to-manipulate-data/about-expressions/#math"
rel="noreferrer"
>
<Icon size="xs" name="external-link-alt" /> Math expressions
</a>
Math expressions
</TextLink>
.
</div>
}
@ -159,9 +187,6 @@ const getStyles = (theme: GrafanaTheme2) => ({
fontSize: theme.typography.h5.fontSize,
fontWeight: theme.typography.h5.fontWeight,
}),
documentationLink: css({
color: theme.colors.text.link,
}),
documentationContainer: css({
display: 'flex',
flex: 1,

@ -86,9 +86,10 @@ export const ImportDashboardForm = ({
</Field>
<Field
label={t('manage-dashboards.import-dashboard-form.label-unique-identifier-uid', 'Unique identifier (UID)')}
description="The unique identifier (UID) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs.
The UID allows having consistent URLs for accessing dashboards so changing the title of a dashboard will not break any
bookmarked links to that dashboard."
description={t(
'manage-dashboards.import-dashboard-form.description-unique-identifier-uid',
'The unique identifier (UID) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs. The UID allows having consistent URLs for accessing dashboards so changing the title of a dashboard will not break any bookmarked links to that dashboard.'
)}
invalid={!!errors.uid}
error={errors.uid && errors.uid.message}
>
@ -168,7 +169,10 @@ export const ImportDashboardForm = ({
<ImportDashboardLibraryPanelsList
inputs={existingLibraryPanels}
label={t('manage-dashboards.import-dashboard-form.label-existing-library-panels', 'Existing library panels')}
description="List of existing library panels. These panels are not affected by the import."
description={t(
'manage-dashbaords.import-dashboard-form.description-existing-library-panels',
'List of existing library panels. These panels are not affected by the import.'
)}
folderName={watchFolder.title}
/>
<Stack>

@ -67,7 +67,10 @@ export function StoredNotifications() {
<div className={styles.wrapper}>
<Alert
severity="info"
title="This page displays past errors and warnings. Once dismissed, they cannot be retrieved."
title={t(
'notifications.stored-notifications.title-alert',
'This page displays past errors and warnings. Once dismissed, they cannot be retrieved.'
)}
/>
<div className={styles.topRow}>
<Checkbox

@ -9,6 +9,7 @@ import { useQueryParams } from 'app/core/hooks/useQueryParams';
import { removePluginFromNavTree } from 'app/core/reducers/navBarTree';
import { useDispatch } from 'app/types';
import { t } from '../../../../../core/internationalization';
import { isDisabledAngularPlugin } from '../../helpers';
import {
useInstallStatus,
@ -134,7 +135,9 @@ export function InstallControlsButton({
<>
<ConfirmModal
isOpen={isConfirmModalVisible}
title={`Uninstall ${plugin.name}`}
title={t('plugins.install-controls-button.title-uninstall-modal', 'Uninstall {{plugin}}', {
plugin: plugin.name,
})}
body="Are you sure you want to uninstall this plugin?"
confirmText="Confirm"
icon="exclamation-triangle"

@ -2,7 +2,7 @@ import { css } from '@emotion/css';
import { GrafanaTheme2, PluginType } from '@grafana/data';
import { config, featureEnabled } from '@grafana/runtime';
import { HorizontalGroup, LinkButton, useStyles2, Alert } from '@grafana/ui';
import { HorizontalGroup, LinkButton, useStyles2, Alert, TextLink } from '@grafana/ui';
import { contextSrv } from 'app/core/core';
import { t, Trans } from 'app/core/internationalization';
import { AccessControlAction } from 'app/types';
@ -65,7 +65,10 @@ export const InstallControlsWarning = ({ plugin, pluginStatus, latestCompatibleV
return (
<Alert
severity="warning"
title="This is a development build of the plugin and can&#39;t be uninstalled."
title={t(
'plugins.install-controls-warning.title-dev-alert',
"This is a development build of the plugin and can't be uninstalled."
)}
className={styles.alert}
/>
);
@ -79,11 +82,13 @@ export const InstallControlsWarning = ({ plugin, pluginStatus, latestCompatibleV
return (
<Alert severity="warning" title="" className={styles.alert}>
<div>
This plugin is not published to{' '}
<a href="https://www.grafana.com/plugins" target="__blank" rel="noreferrer">
grafana.com/plugins
</a>{' '}
and can&#39;t be managed via the catalog.
<Trans i18nKey="plugins.install-controls-warning.body-not-published">
This plugin is not published to{' '}
<TextLink href="https://www.grafana.com/plugins" external>
grafana.com/plugins
</TextLink>{' '}
and can't be managed via the catalog.
</Trans>
</div>
</Alert>
);
@ -106,7 +111,10 @@ export const InstallControlsWarning = ({ plugin, pluginStatus, latestCompatibleV
return (
<Alert
severity="warning"
title="The install controls have been disabled because the Grafana server cannot access grafana.com."
title={t(
'plugins.install-controls-warning.title-remote-plugins-unavailable',
'The install controls have been disabled because the Grafana server cannot access grafana.com.'
)}
className={styles.alert}
/>
);

@ -85,7 +85,9 @@ export function PluginUsage({ plugin }: Props) {
return (
<EmptyListCTA
title={`${plugin.name} is not used in any dashboards yet`}
title={t('plugins.plugin-usage.title-not-used-yet', '{{pluginName}} is not used in any dashboards yet', {
pluginName: plugin.name,
})}
buttonIcon="plus"
buttonTitle="Create Dashboard"
buttonLink={`dashboard/new?panelType=${plugin.id}&editPanel=1`}

@ -2,8 +2,10 @@ import { css } from '@emotion/css';
import { GrafanaTheme2, PluginErrorCode, PluginSignatureStatus, PluginType } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Alert, Icon, List, PluginSignatureBadge, Stack, useStyles2 } from '@grafana/ui';
import { Alert, List, PluginSignatureBadge, Stack, TextLink, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { t } from '../../../core/internationalization';
import { useGetErrors, useFetchStatus } from '../admin/state/hooks';
type PluginsErrorInfoProps = {
@ -21,11 +23,18 @@ export function PluginsErrorsInfo({ filterByPluginType }: PluginsErrorInfoProps)
return (
<Alert
title="Unsigned plugins were found during plugin initialization. Grafana Labs cannot guarantee the integrity of these plugins. We recommend only using signed plugins."
title={t(
'plugins.plugins-errors-info.title-unsigned-plugins',
'Unsigned plugins were found during plugin initialization. Grafana Labs cannot guarantee the integrity of these plugins. We recommend only using signed plugins.'
)}
data-testid={selectors.pages.PluginsList.signatureErrorNotice}
severity="warning"
>
<p>The following plugins are disabled and not shown in the list below:</p>
<p>
<Trans i18nKey="plugins.plugins-errors-info.disabled-list">
The following plugins are disabled and not shown in the list below:
</Trans>
</p>
<List
items={errors}
className={styles.list}
@ -41,14 +50,15 @@ export function PluginsErrorsInfo({ filterByPluginType }: PluginsErrorInfoProps)
</div>
)}
/>
<a
<TextLink
href="https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/"
external
className={styles.docsLink}
target="_blank"
rel="noreferrer"
>
<Icon name="book" /> Read more about plugin signing
</a>
<Trans i18nKey="plugins.plugins-errors-info.read-more-about-plugin-signing">
Read more about plugin signing
</Trans>
</TextLink>
</Alert>
);
}
@ -79,7 +89,6 @@ function getStyles(theme: GrafanaTheme2) {
}),
docsLink: css({
display: 'inline-block',
color: theme.colors.text.link,
marginTop: theme.spacing(2),
}),
};

@ -194,8 +194,13 @@
},
"service-info": {
"title-critical-sla-hours": "Critical SLA: 2 hours",
"title-email": "Email",
"title-enterprise-plugins": "Enterprise Plugins",
"title-unlimited-expert-support": "Unlimited Expert Support"
"title-handinhand-support-in-the-upgrade-process": "Hand-in-hand support in the upgrade process",
"title-phone": "Phone",
"title-private-slack-channel": "Private Slack channel",
"title-unlimited-expert-support": "Unlimited Expert Support",
"year-round-support": "24 × 7 × 365 support via"
},
"settings": {
"info-description": "These system settings are defined in grafana.ini or custom.ini (or overridden in ENV variables). To change these you currently need to restart Grafana."
@ -332,6 +337,14 @@
"title-error-loading-notifications": "Error loading notifications",
"title-grafana-alerts-delivered-alertmanager": "Grafana alerts are not delivered to Grafana Alertmanager"
},
"alert-groups-summary": {
"text-firing_one": "{{count}} firing",
"text-firing_other": "{{count}} firing",
"text-suppressed_one": "{{count}} suppressed",
"text-suppressed_other": "{{count}} suppressed",
"text-unprocessed_one": "{{count}} unprocessed",
"text-unprocessed_other": "{{count}} unprocessed"
},
"alert-instance-details": {
"label-value": "Value"
},
@ -352,6 +365,9 @@
"alert-label": {
"tooltip-remove-label": "Remove label"
},
"alert-label-dropdown": {
"placeholder-select": "Choose {{type}}"
},
"alert-labels": {
"aria-label-labels": "Labels"
},
@ -382,9 +398,13 @@
},
"alert-rule-name-and-metric": {
"aria-label-name": "name",
"description-section": "Enter a name to identify your {{entityName}}.",
"label-metric": "Metric",
"label-name": "Name",
"metric-aria-label-metric": "metric"
"metric-aria-label-metric": "metric",
"metric-placeholder-recorded-metric": "Give the name of the new recorded metric",
"placeholder-name": "Give your {{namePlaceholder}} a name",
"title-section": "Enter {{entityName}} name"
},
"alert-rules": {
"firing-for": "Firing for",
@ -451,7 +471,8 @@
"aria-label-sort": "Sort",
"label-filter-placeholder-search-alerts-by-labels": "Search alerts by labels",
"name-filter-placeholder-search-alert-rules-by-name": "Search alert rules by name",
"no-alert-rules-found": "No alert rules found"
"no-alert-rules-found": "No alert rules found",
"placeholder-sort-default-az": "Sort (Default A-Z)"
},
"alertVersionHistory": {
"alerting": "Alerting",
@ -496,9 +517,13 @@
"warning-restore-manually-title": "Restoring rule manually"
},
"am-root-route-form": {
"am-group-description-label": "The waiting time before sending the first notification for a new group of alerts. Default 30 seconds.",
"am-group-interval-description": "The wait time before sending a notification about changes in the alert group after the first notification has been sent. Default is 5 minutes.",
"am-group-interval-label-group-interval": "Group interval",
"am-group-select-description-group-by": "Combine multiple alerts into a single notification by grouping them by the same label values.",
"am-group-select-label-group-by": "Group by",
"am-group-wait-label-group-wait": "Group wait",
"am-repeat-interval-description": "The wait time before resending a notification that has already been sent successfully. Default is 4 hours. Should be a multiple of Group interval.",
"am-repeat-interval-label-repeat-interval": "Repeat interval",
"aria-label-group-by": "Group by",
"aria-label-group-interval": "Group interval",
@ -515,6 +540,8 @@
"am-mute-timing-select-label-mute-timings": "Mute timings",
"aria-label-group-by": "Group by",
"aria-label-operator": "Operator",
"badge-no-matchers": "If no matchers are specified, this notification policy will handle all alert instances.",
"description-group-by": "Combine multiple alerts into a single notification by grouping them by the same label values. If empty, it is inherited from the parent policy.",
"label-contact-point": "Contact point",
"label-continue-matching-subsequent-sibling-nodes": "Continue matching subsequent sibling nodes",
"label-group-by": "Group by",
@ -589,6 +616,7 @@
"duplicate": "Duplicate",
"label-integration": "Integration",
"label-notification-settings": "Notification settings",
"label-section": "Optional {{name}} settings",
"test": "Test"
},
"classic-condition-viewer": {
@ -613,6 +641,7 @@
"label-send-resolved": "Send resolved"
},
"cloud-evaluation-behavior": {
"description-pending-period": "Period during which the threshold condition must be met to trigger an alert. Selecting \"None\" triggers the alert immediately once the condition is met.",
"label-pending-period": "Pending period",
"title-set-evaluation-behavior": "Set evaluation behavior"
},
@ -638,6 +667,7 @@
"return": "Return"
},
"contact-point-header": {
"aria-label-more-actions": "More actions for contact point \"{{contactPointName}}\"",
"export-label-export": "Export",
"label-delete": "Delete",
"label-manage-permissions": "Manage permissions"
@ -803,6 +833,10 @@
"text-loading-notification-template": "Loading notification template",
"title-error-loading-notification-template": "Error loading notification template"
},
"dynamic-table": {
"tooltip-collapse-row": "Collapse row",
"tooltip-expand-row": "Expand row"
},
"edit-contact-point": {
"text-loading": "Loading...",
"title-failed-to-fetch-contact-point": "Failed to fetch contact point",
@ -834,6 +868,7 @@
"text-provisioned": "Provisioned"
},
"evaluation-group-creation-modal": {
"description-group-name": "A group evaluates all its rules over the same evaluation interval.",
"description-often-rules-group-evaluated": "How often all rules in the group are evaluated.",
"placeholder-enter-a-name": "Enter a name",
"title-new-evaluation-group": "New evaluation group"
@ -853,7 +888,9 @@
"title-rule-not-found": "Rule not found"
},
"existing-silence-editor": {
"text-loading-existing-silence-information": "Loading existing silence information..."
"text-loading-existing-silence-information": "Loading existing silence information...",
"title-permission-editrecreate-silence": "You do not have permission to edit/recreate this silence",
"title-silence-not-found": "Existing silence \"{{silenceId}}\" not found"
},
"export": {
"subtitle": {
@ -905,6 +942,9 @@
}
}
},
"for-input": {
"description-pending": "Period during which the threshold condition must be met to trigger an alert. Selecting \"None\" triggers the alert immediately once the condition is met."
},
"generate-alert-data-modal": {
"add-alert-data": "Add alert data",
"add-alert-data-to-payload": "Add alert data to payload",
@ -914,10 +954,19 @@
"get-preview-results": {
"title-error": "Error"
},
"getting-stared": {
"learn-more": "For a hands-on introduction, refer to our <2>tutorial to get started with Grafana Alerting</2>"
},
"getting-started": {
"condition-breached-alert-instance-fires": "If the condition is breached, an alert instance fires",
"create-alert-rule": "<0>Create an alert rule</0> to query a data source and evaluate the condition defined in the alert rule",
"firing-instances-routed-notification-policies": "Firing instances are routed to notification policies based on matching labels",
"get-started": "Get started",
"how-it-works": "How it works"
"how-it-works": "How it works",
"monitor-alert-rules": "<0>Monitor</0> your alert rules using dashboards and visualizations",
"notification-policies-contact-points": "Notifications are sent out to the contact points specified in the notification policy",
"periodically-queries-data-sources": "Grafana alerting periodically queries data sources and evaluates the condition defined in the alert rule",
"route-alert-notifications": "<0>Route alert notifications</0> either directly to a contact point or through notification policies for more flexibility"
},
"global-config": {
"title-failed-to-fetch-notification-template": "Failed to fetch notification template"
@ -935,6 +984,7 @@
"title-you-have-additional-alertmanagers-to-configure": "You have additional Alertmanagers to configure"
},
"grafana-common-channel-settings": {
"description-disable-resolved-message": "Disable the resolve message [OK] that is sent when alerting state returns to false",
"label-disable-resolved-message": "Disable resolved message"
},
"grafana-evaluation-behavior-step": {
@ -981,9 +1031,15 @@
"grafana-rule-folder-export-preview": {
"text-loading": "Loading...."
},
"grafana-rule-folder-exporter": {
"title-drawer": "Export {{folderName}} rules"
},
"grafana-rule-group-export-preview": {
"text-loading": "Loading...."
},
"grafana-rule-group-exporter": {
"title-drawer": "Export {{groupName}} rules"
},
"grafana-rules": {
"export-all-grafana-rules-aria-label-export-all-grafana-rules": "export all grafana rules",
"export-all-grafana-rules-tooltip-export-all-grafanamanaged-rules": "Export all Grafana-managed rules",
@ -1052,6 +1108,9 @@
"group-loader": {
"group-load-failed": "Failed to load rules from group {{ groupName }} in {{ namespaceName }}"
},
"header": {
"tooltip-remove": "Remove expression \"{{refId}}\""
},
"home": {
"label-get-started": "Get started",
"label-insights": "Insights",
@ -1234,7 +1293,8 @@
"input": "Input"
},
"max-data-points-option": {
"label-max-data-points": "Max data points"
"label-max-data-points": "Max data points",
"tooltip-max-data-points": "The maximum data points per series. Used directly by some data sources and used in calculation of auto interval. With streaming data this value is used for the rolling buffer."
},
"migrate-to-gmabutton": {
"aria-label-new": "new"
@ -1258,6 +1318,7 @@
"title-delete-mute-timing": "Delete mute timing"
},
"mute-timing-fields": {
"am-mute-timing-select-description-mute-timings": "Select a mute timing to define when not to send notifications for this alert rule",
"am-mute-timing-select-label-mute-timings": "Mute timings"
},
"mute-timing-form": {
@ -1268,6 +1329,8 @@
},
"mute-timing-time-interval": {
"add-another-time-interval": "Add another time interval",
"description-dats-of-the-month": "The days of the month, 1:31, of a month. Negative values can be used to represent days which begin at the end of the month",
"description-months": "The months of the year in either numerical or the full calendar month",
"label-days-of-the-month": "Days of the month",
"label-days-of-the-week": "Days of the week",
"label-disable": "Disable",
@ -1282,6 +1345,7 @@
},
"mute-timing-time-range": {
"add-another-time-range": "Add another time range",
"description-time-range": "The time inclusive of the start and exclusive of the end time (in UTC if no location has been selected, otherwise local time)",
"label-end-time": "End time",
"label-start-time": "Start time",
"label-time-range": "Time range",
@ -1507,7 +1571,9 @@
},
"provisioning": {
"badge-tooltip-provenance": "This resource has been provisioned via {{provenance}} and cannot be edited through the UI",
"badge-tooltip-standard": "This resource has been provisioned and cannot be edited through the UI"
"badge-tooltip-standard": "This resource has been provisioned and cannot be edited through the UI",
"body-provisioned": "This {{resource}} has been provisioned, that means it was created by config. Please contact your server admin to update this {{resource}}.",
"title-provisioned": "This {{resource}} cannot be edited through the UI"
},
"provisioning-badge": {
"badge": {
@ -1562,7 +1628,8 @@
},
"redirect-to-rule-viewer": {
"text-loading-rule": "Loading rule...",
"title-could-not-view-rule": "Could not view rule"
"title-could-not-view-rule": "Could not view rule",
"title-failed-to-load": "Failed to load rules from {{sourceName}}"
},
"reduce-condition-viewer": {
"function": "Function",
@ -1583,6 +1650,7 @@
},
"routing-settings": {
"aria-label-group-by": "Group by",
"description-group-by": "Combine multiple alerts into a single notification by grouping them by the same label values. If empty, it is inherited from the default notification policy.",
"label-group-by": "Group by",
"label-override-grouping": "Override grouping",
"label-override-timings": "Override timings"
@ -1934,6 +2002,7 @@
"search-query-input-placeholder-search": "Search"
},
"silences-table": {
"label-section-expired": "Expired silences ({{numExpired}})",
"text-loading-silences": "Loading silences...",
"title-error-loading-silences": "Error loading silences",
"title-the-selected-alertmanager-has-no-configuration": "The selected Alertmanager has no configuration"
@ -2001,7 +2070,8 @@
"error-loading-templates": "Error loading templates",
"existing-templates-selector-aria-label-choose-notification-template": "Choose notification template",
"existing-templates-selector-placeholder-choose-notification-template": "Choose notification template",
"loading": "Loading..."
"loading": "Loading...",
"tooltip-copy": "Copy selected notification template to clipboard. You can use it in the custom tab."
},
"templates": {
"editor": {
@ -2016,6 +2086,11 @@
"misconfigured-warning": "This template is misconfigured.",
"misconfigured-warning-details": "Templates must be defined in both the <1></1> and <4></4> sections of your alertmanager configuration."
},
"templates-picker": {
"button-edit": "Edit {{name}}",
"title-drawer": "Edit {{name}}",
"tooltip-edit": "Edit {{name}} using existing notification templates."
},
"templates-table": {
"actions": "Actions",
"no-templates-defined": "No templates defined.",
@ -2051,7 +2126,8 @@
},
"unused-contact-point-badge": {
"aria-label-unused": "unused",
"text-unused": "Unused"
"text-unused": "Unused",
"tooltip-unused": "This contact point is not used in any notification policy or alert rule"
},
"use-add-policy-modal": {
"modal-element": {
@ -2103,6 +2179,7 @@
"table": "Table"
},
"welcome-header": {
"description-alert-rules": "Define the condition that must be met before an alert rule fires",
"description-configure-firing-alert-instances-routed-contact": "Configure how firing alert instances are routed to contact points",
"description-configure-receives-notifications": "Configure who receives notifications and how they are sent",
"title-alert-rules": "Alert rules",
@ -2615,6 +2692,7 @@
"delete": "Delete",
"description-color-annotation-event-markers": "Color to use for the annotation event markers",
"description-enabled-annotation-query-issued-every-dashboard": "When enabled the annotation query is issued every dashboard refresh",
"description-hidden": "Annotation queries can be toggled on or off at the top of the dashboard. With this option checked this toggle will be hidden.",
"label-color": "Color",
"label-data-source": "Data source",
"label-enabled": "Enabled",
@ -2627,6 +2705,7 @@
"title-annotation-support-source": "No annotation support for this data source"
},
"annotation-settings-list": {
"aria-label-delete": "Delete query with title \"{{title}}\"",
"data-source": "Data source",
"new-query": "New query",
"query-name": "Query name",
@ -2899,13 +2978,17 @@
},
"help-wizard": {
"copy-to-clipboard": "Copy to clipboard",
"description-obfuscate-data": "Modify the original data to hide sensitve information. Note the lengths will stay the same, and duplicate values will be equal.",
"download-snapshot": "Download ({{snapshotSize}})",
"label-obfuscate-data": "Obfuscate data",
"label-support-snapshot": "Support snapshot",
"label-template": "Template",
"randomize-field-names-label-field-names": "Field names",
"randomize-labels-label-labels": "Labels",
"randomize-string-values-label-string-values": "String values",
"title-complete-git-hub-comment-clipboard": "Copy a complete GitHub comment to the clipboard"
"title-complete-git-hub-comment-clipboard": "Copy a complete GitHub comment to the clipboard",
"title-get-help-with-this-panel": "Get help with this panel",
"troubleshooting-docs": "Troubleshooting docs"
},
"inspect": {
"data-tab": "Data",
@ -3029,6 +3112,7 @@
"title-undo-all-changes": "Undo all changes"
},
"table-view-label-table-view": "Table view",
"title-unlink": "Disconnects this panel from the library panel so that you can edit it regularly.",
"unlink": "Unlink"
},
"panel-links": {
@ -3133,7 +3217,8 @@
"save-json-to-file": "Save JSON to file"
},
"solo-panel": {
"loading-initializing-dashboard": "Loading & initializing dashboard"
"loading-initializing-dashboard": "Loading & initializing dashboard",
"title-not-found": "Panel with id {{panelId}} not found"
},
"sub-menu-un-connected": {
"aria-label-template-variables": "Template variables"
@ -3304,7 +3389,8 @@
"title-filter": "Filter",
"title-remove": "Remove",
"title-show-transform-help": "Show transform help"
}
},
"title-delete": "Delete {{name}}?"
},
"transformation-picker": {
"placeholder-search-for-transformation": "Search for transformation",
@ -3345,6 +3431,7 @@
"label-view-json-diff": "View JSON diff"
},
"version-history-table": {
"aria-label-toggle-selection": "Toggle selection of version {{version}}",
"date": "Date",
"notes": "Notes",
"restore": "Restore",
@ -3533,6 +3620,10 @@
"troubleshooting-docs": "Troubleshooting docs",
"troubleshooting-request-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."
},
"import-dashboard-form-v2": {
"cancel": "Cancel",
"label-folder": "Folder"
},
"inspect-data-tab": {
"no-data-found": "No data found"
},
@ -3920,10 +4011,17 @@
}
},
"datasources": {
"alert-success-message": {
"aria-label-create-a-dashboard": "Create a dashboard",
"aria-label-explore-data": "Explore data"
},
"alerting-enabled": {
"text-alerting-not-supported": "Alerting not supported",
"text-alerting-supported": "Alerting supported"
},
"basic-serttings": {
"tooltip-name": "The name is used when you select the data source in panels. The default data source is preselected in new panels."
},
"basic-settings": {
"aria-label-datasource-settings-page-basic": "Datasource settings page basic settings",
"basic-settings-name-placeholder-name": "Name",
@ -3968,6 +4066,9 @@
"build-a-dashboard": "Build a dashboard",
"explore-data": "Explore data"
},
"error-details-link": {
"aria-label-more-details-about-the-error": "More details about the error"
},
"footer": {
"add-csv-or-spreadsheet": "Add csv or spreadsheet"
},
@ -4113,12 +4214,15 @@
"label-expression": "Expression",
"label-field": "Field",
"label-type": "Type",
"label-variable-name": "Variable name"
"label-variable-name": "Variable name",
"title-add": "Add transformation",
"title-edit": "Edit transformation"
},
"correlation-unsaved-changes-modal": {
"cancel": "Cancel",
"continue-without-saving": "Continue without saving",
"save-correlation": "Save correlation"
"save-correlation": "Save correlation",
"title-unsaved-changes-to-correlation": "Unsaved changes to correlation"
},
"draggable-manager-demo": {
"click-horizontally-somewhere-colored-below": "Click and drag horizontally somewhere in the colored area, below.",
@ -4189,6 +4293,9 @@
"logs-container": {
"label-logs": "Logs"
},
"logs-feedback": {
"give-feedback": "Give feedback"
},
"logs-meta-row": {
"download": "Download",
"show-original-line": "Show original line"
@ -4228,6 +4335,10 @@
"aria-label-query": "query"
},
"next": "Next",
"next-prev-result": {
"aria-label-next": "Next result button",
"aria-label-prev": "Prev result button"
},
"no-data-source-call-to-action": {
"cta-element": {
"add-data-source": "Add data source"
@ -4241,6 +4352,9 @@
"queryless-apps-extensions": {
"aria-label-go-queryless": "Go queryless"
},
"raw-list-container": {
"label-expand-results": "Expand results"
},
"raw-list-item": {
"tooltip-copy-to-clipboard": "Copy to clipboard"
},
@ -4371,6 +4485,7 @@
"show-critical-path-only": "Show critical path only",
"show-matches-only": "Show matches only",
"span-bar-section": {
"description-link": "Add additional info next to the service and operation on a span bar row in the trace view.",
"title-span-bar": "Span bar"
},
"span-bar-settings": {
@ -4379,7 +4494,8 @@
"label-tag-key": "Tag key",
"placeholder-duration": "Duration",
"placeholder-enter-tag-key": "Enter tag key",
"tooltip-default-duration": "Default: duration"
"tooltip-default-duration": "Default: duration",
"tooltip-tag-key": "Tag key which will be used to get the tag value. A span's attributes and resources will be searched for the tag key"
},
"span-detail": {
"label-resource-attributes": "Resource attributes",
@ -4399,7 +4515,9 @@
"label-span-name": "Span name",
"label-tags": "Tags",
"placeholder-all-service-names": "All service names",
"placeholder-all-span-names": "All span names"
"placeholder-all-span-names": "All span names",
"tooltip-duration": "Filter by duration. Accepted units are {{units}}",
"tooltip-tags": "Filter by tags, process tags or log fields in your spans."
},
"span-filters-tags": {
"aria-label-add-tag": "Add tag",
@ -4460,12 +4578,20 @@
"trace-page-header": {
"text-partial-trace": "Partial trace"
},
"trace-page-search-bar": {
"aria-label-clear-filters": "Clear filters button",
"label-show-matches": "Show matches only switch",
"label-show-paths": "Show critical path only switch"
},
"trace-view": {
"no-data": "No data"
},
"trace-view-container": {
"title-trace": "Trace"
},
"unconnected-node-graph-container": {
"title-node-graph": "Node graph"
},
"unthemed-logs": {
"label-deduplication": "Deduplication",
"label-display-results": "Display results",
@ -4499,6 +4625,20 @@
"export-as-json-tooltip": "Export"
}
},
"expression": {
"math": {
"description-abs": "Returns the absolute value of its argument which can be a number or a series",
"description-ceil": "Rounds the number up to the nearest integer value. It's able to operate on series or escalar values.",
"description-floor": "Rounds the number down to the nearest integer value. It's able to operate on series or escalar values.",
"description-inf-nan-null": "The inf for infinity positive, infn for infinity negative, nan, and null functions all return a single scalar value that matches its name.",
"description-is-inf": "Returns 1 for Inf values (negative or positive) and 0 for other values. It's able to operate on series or scalar values.",
"description-is-nan": "Returns 1 for NaN values and 0 for other values. It's able to operate on series or scalar values.",
"description-is-null": "Returns 1 for null values and 0 for other values. It's able to operate on series or scalar values.",
"description-is-number": "Returns 1 for all real number values and 0 for non-number. It's able to operate on series or scalar values.",
"description-log": "Returns the natural logarithm of its argument, which can be a number or a series",
"description-round": "Returns a rounded integer value. It's able to operate on series or escalar values."
}
},
"expressions": {
"classic-conditions": {
"label-conditions": "Conditions"
@ -4943,7 +5083,7 @@
"title": "Shortcuts"
},
"help-wizard": {
"download-snapshot": "Download snapshot",
"download-snapshot": "Download snapshot ({{snapshotSize}})",
"github-comment": "Copy Github comment",
"support-bundle": "You can also retrieve a support bundle containing information concerning your Grafana instance and configured datasources in the <1>support bundles section</1>.",
"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."
@ -5405,11 +5545,17 @@
"tooltip-hide-adhoc-statistics": "Hide ad-hoc statistics"
}
},
"manage-dashbaords": {
"import-dashboard-form": {
"description-existing-library-panels": "List of existing library panels. These panels are not affected by the import."
}
},
"manage-dashboards": {
"import-dashboard-form": {
"cancel": "Cancel",
"change-uid": "Change uid",
"description-library-panels-imported": "List of new library panels that will get imported.",
"description-unique-identifier-uid": "The unique identifier (UID) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs. The UID allows having consistent URLs for accessing dashboards so changing the title of a dashboard will not break any bookmarked links to that dashboard.",
"label-existing-library-panels": "Existing library panels",
"label-folder": "Folder",
"label-name": "Name",
@ -6080,7 +6226,8 @@
},
"starred-dashboard": "Dashboard starred",
"stored-notifications": {
"dismiss-notifications": "Dismiss notifications"
"dismiss-notifications": "Dismiss notifications",
"title-alert": "This page displays past errors and warnings. Once dismissed, they cannot be retrieved."
},
"unstarred-dashboard": "Dashboard unstarred"
},
@ -6350,10 +6497,16 @@
"get-started-with-data-source": {
"add-new-data-source": "Add new data source"
},
"install-controls-button": {
"title-uninstall-modal": "Uninstall {{plugin}}"
},
"install-controls-warning": {
"body-not-published": "This plugin is not published to <2>grafana.com/plugins</2> and can't be managed via the catalog.",
"learn-more": "Learn more",
"no-valid-grafana-enterprise-license-detected": "No valid Grafana Enterprise license detected.",
"title-dev-alert": "This is a development build of the plugin and can't be uninstalled.",
"title-plugin-doesnt-support-version-grafana": "This plugin doesn't support your version of Grafana.",
"title-remote-plugins-unavailable": "The install controls have been disabled because the Grafana server cannot access grafana.com.",
"title-renderer-plugins-cannot-managed-plugin-catalog": "Renderer plugins cannot be managed by the Plugin Catalog."
},
"log-view-filters": {
@ -6408,7 +6561,13 @@
"update-available": "Update available!"
},
"plugin-usage": {
"title-missing-feature-toggle-panel-title-search": "Missing feature toggle: {{toggle}}"
"title-missing-feature-toggle-panel-title-search": "Missing feature toggle: {{toggle}}",
"title-not-used-yet": "{{pluginName}} is not used in any dashboards yet"
},
"plugins-errors-info": {
"disabled-list": "The following plugins are disabled and not shown in the list below:",
"read-more-about-plugin-signing": "Read more about plugin signing",
"title-unsigned-plugins": "Unsigned plugins were found during plugin initialization. Grafana Labs cannot guarantee the integrity of these plugins. We recommend only using signed plugins."
},
"search-field": {
"placeholder-search-grafana-plugins": "Search Grafana plugins"

Loading…
Cancel
Save