Internationalisation: More automatic markup (#103203)

* easy changes

* couple of tweaks + translations

* update e2e tests

* kick CI
This commit is contained in:
Ashley Harrison 2025-04-02 10:03:12 +01:00 committed by GitHub
parent d6b71f171d
commit 38aee2dfa2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
58 changed files with 962 additions and 488 deletions

View File

@ -2575,22 +2575,8 @@ 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/dashboard-scene/addToDashboard/AddToDashboardForm.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. 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/dashboard-scene/edit-pane/DashboardAddPane.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/dashboard-scene/embedding/EmbeddedDashboardTestPage.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@ -2598,34 +2584,17 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/inspect/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 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 />", "14"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"]
[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"]
],
"public/app/features/dashboard-scene/inspect/HelpWizard/utils.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/dashboard-scene/inspect/InspectDataTab.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/inspect/PanelInspectDrawer.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/dashboard-scene/pages/DashboardScenePage.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@ -2635,40 +2604,20 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/panel-edit/LibraryVizPanelInfo.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/EmptyTransformationsMessage.tsx:5381": [
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/NewAlertRuleButton.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/NewAlertRuleButton.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"]
],
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataAlertingTab.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 />", "0"]
],
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataQueriesTab.tsx:5381": [
[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-scene/panel-edit/PanelDataPane/PanelDataTransformationsTab.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"]
],
"public/app/features/dashboard-scene/panel-edit/PanelDataPane/TransformationsDrawer.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/dashboard-scene/panel-edit/PanelEditControls.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/dashboard-scene/panel-edit/PanelEditorRenderer.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
@ -2679,40 +2628,8 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/panel-edit/PanelOptionsPane.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/dashboard-scene/panel-edit/PanelOptionsPane.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/dashboard-scene/panel-edit/PanelVizTypePicker.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/dashboard-scene/panel-edit/SaveLibraryVizPanelModal.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"]
],
"public/app/features/dashboard-scene/saving/DashboardPrompt.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"]
],
"public/app/features/dashboard-scene/saving/SaveDashboardAsForm.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. 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"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/saving/SaveDashboardDrawer.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
@ -2720,29 +2637,11 @@ exports[`better eslint`] = {
],
"public/app/features/dashboard-scene/saving/SaveDashboardForm.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 in text props. Wrap text with <Trans /> or use t()", "10"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "11"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "12"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"]
[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-scene/saving/SaveProvisionedDashboardForm.tsx:5381": [
[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 />", "0"]
],
"public/app/features/dashboard-scene/saving/getDashboardChanges.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
@ -2754,11 +2653,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "6"]
],
"public/app/features/dashboard-scene/saving/shared.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/dashboard-scene/scene/PanelLinks.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/scene/PanelMenuBehavior.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
@ -2766,9 +2661,6 @@ exports[`better eslint`] = {
"public/app/features/dashboard-scene/scene/PanelSearchLayout.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"public/app/features/dashboard-scene/scene/UnlinkModal.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/serialization/angularMigration.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@ -2793,195 +2685,57 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/dashboard-scene/settings/DeleteDashboardButton.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 />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/dashboard-scene/settings/JsonModelEditView.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. Wrap text with <Trans />", "5"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/settings/annotations/AnnotationSettingsEdit.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 in text props. Wrap text with <Trans /> or use t()", "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 in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/settings/annotations/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 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. 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"]
[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-scene/settings/annotations/index.tsx:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./AnnotationSettingsEdit\`)", "0"],
[0, 0, 0, "Do not re-export imported variable (\`./AnnotationSettingsList\`)", "1"]
],
"public/app/features/dashboard-scene/settings/links/DashboardLinkForm.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 in text props. Wrap text with <Trans /> or use t()", "10"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "11"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "12"]
],
"public/app/features/dashboard-scene/settings/links/DashboardLinkList.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"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"]
],
"public/app/features/dashboard-scene/settings/variables/VariableEditorForm.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. Wrap text with <Trans />", "7"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "8"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "9"]
],
"public/app/features/dashboard-scene/settings/variables/VariableEditorList.tsx:5381": [
[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"]
],
"public/app/features/dashboard-scene/settings/variables/VariableEditorListRow.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"]
],
"public/app/features/dashboard-scene/settings/variables/components/AdHocVariableForm.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"]
],
"public/app/features/dashboard-scene/settings/variables/components/ConstantVariableForm.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/dashboard-scene/settings/variables/components/CustomVariableForm.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 in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/settings/variables/components/DataSourceVariableForm.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"]
],
"public/app/features/dashboard-scene/settings/variables/components/GroupByVariableForm.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 />", "1"]
],
"public/app/features/dashboard-scene/settings/variables/components/IntervalVariableForm.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. Wrap text with <Trans />", "5"]
],
"public/app/features/dashboard-scene/settings/variables/components/QueryEditor.tsx:5381": [
[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 in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/dashboard-scene/settings/variables/components/QueryVariableForm.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 />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"]
],
"public/app/features/dashboard-scene/settings/variables/components/SelectionOptionsForm.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/dashboard-scene/settings/variables/components/TextBoxVariableForm.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/dashboard-scene/settings/variables/components/VariableHideSelect.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/settings/variables/components/VariableSelectField.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/dashboard-scene/settings/variables/components/VariableValuesPreview.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/dashboard-scene/settings/variables/utils.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"public/app/features/dashboard-scene/settings/version-history/RevertDashboardModal.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/dashboard-scene/settings/version-history/VersionHistoryButtons.tsx:5381": [
[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 />", "0"]
],
"public/app/features/dashboard-scene/settings/version-history/VersionHistoryComparison.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"]
],
"public/app/features/dashboard-scene/settings/version-history/VersionHistoryHeader.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"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
],
"public/app/features/dashboard-scene/settings/version-history/VersionHistoryHeader.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.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 in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/settings/version-history/index.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./HistorySrv\`)", "0"],
@ -2990,12 +2744,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not re-export imported variable (\`./VersionHistoryHeader\`)", "3"],
[0, 0, 0, "Do not re-export imported variable (\`./VersionHistoryTable\`)", "4"]
],
"public/app/features/dashboard-scene/sharing/ShareButton/ShareButton.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/sharing/ShareButton/share-externally/EmailShare/ConfigEmailSharing/EmailListConfiguration.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/dashboard-scene/sharing/ShareButton/share-snapshot/ShareSnapshot.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
@ -3020,8 +2768,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "2"]
],
"public/app/features/dashboard-scene/variables/VariableUsagesButton.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/api/ResponseTransformers.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],

View File

@ -1191,7 +1191,7 @@ Use this transformation to address issues when a data source returns time series
##### Wide time series
Select this option to transform the time series data frame from the long format to the wide format.
Select this option to transform the time series data frame from the long format to the wide format. If your data source returns time series data in a long format and your visualization requires a wide format, this transformation simplifies the process.
A wide time series combines data into a single frame with one shared, ascending time field. Time fields do not repeat and multiple values extend in separate columns.
@ -1217,7 +1217,7 @@ Multi-frame time series break data into multiple frames that all contain two fie
##### Long time series
A long time series combines data to one frame, with the first field being an ascending time field. The time field might have duplicates. String values are in separate fields, and there might be more than one.
A long time series combines data into one frame, with the first field being an ascending time field. The time field might have duplicates. String values are in separate fields, and there might be more than one.
**Example: Converting to long format**

View File

@ -157,7 +157,6 @@ describe('Variables - Query - Add variable', () => {
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInput().within((input) => {
expect(input.attr('placeholder')).equals('blank = auto');
expect(input.val()).equals('');
});

View File

@ -153,7 +153,6 @@ describe('Variables - Query - Add variable', () => {
});
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInput().within((input) => {
expect(input.attr('placeholder')).equals('blank = auto');
expect(input.val()).equals('');
});

View File

@ -8,6 +8,7 @@ import { Panel } from '@grafana/schema';
import { Alert, Button, Field, Modal, RadioButtonGroup } from '@grafana/ui';
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
import { contextSrv } from 'app/core/core';
import { t, Trans } from 'app/core/internationalization';
import { AccessControlAction } from 'app/types';
import { addToDashboard, SubmissionError } from './addToDashboard';
@ -112,7 +113,13 @@ export function AddToDashboardForm<TOptions = undefined>({
<Controller
control={control}
render={({ field: { ref, ...field } }) => (
<Field label="Target dashboard" description="Choose where to add the panel.">
<Field
label={t('dashboard-scene.add-to-dashboard-form.label-target-dashboard', 'Target dashboard')}
description={t(
'dashboard-scene.add-to-dashboard-form.description-choose-where-to-add-the-panel',
'Choose where to add the panel.'
)}
>
<RadioButtonGroup options={saveTargets} {...field} id="e2d-save-target" />
</Field>
)}
@ -127,8 +134,11 @@ export function AddToDashboardForm<TOptions = undefined>({
<Controller
render={({ field: { ref, value, onChange, ...field } }) => (
<Field
label="Dashboard"
description="Select in which dashboard the panel will be created."
label={t('dashboard-scene.add-to-dashboard-form.label-dashboard', 'Dashboard')}
description={t(
'dashboard-scene.add-to-dashboard-form.description-select-which-dashboard-panel-created',
'Select in which dashboard the panel will be created.'
)}
error={errors.dashboardUid?.message}
invalid={!!errors.dashboardUid}
>
@ -149,14 +159,17 @@ export function AddToDashboardForm<TOptions = undefined>({
})()}
{submissionError && (
<Alert severity="error" title="Error adding the panel">
<Alert
severity="error"
title={t('dashboard-scene.add-to-dashboard-form.title-error-adding-the-panel', 'Error adding the panel')}
>
{submissionError.message}
</Alert>
)}
<Modal.ButtonRow>
<Button type="reset" onClick={onClose} fill="outline" variant="secondary">
Cancel
<Trans i18nKey="dashboard-scene.add-to-dashboard-form.cancel">Cancel</Trans>
</Button>
<Button
type="submit"
@ -164,10 +177,10 @@ export function AddToDashboardForm<TOptions = undefined>({
onClick={handleSubmit(partial(onSubmit, true))}
icon="external-link-alt"
>
Open in new tab
<Trans i18nKey="dashboard-scene.add-to-dashboard-form.open-in-new-tab">Open in new tab</Trans>
</Button>
<Button type="submit" variant="primary" onClick={handleSubmit(partial(onSubmit, false))} icon="apps">
Open dashboard
<Trans i18nKey="dashboard-scene.add-to-dashboard-form.open-dashboard">Open dashboard</Trans>
</Button>
</Modal.ButtonRow>
</form>

View File

@ -87,7 +87,12 @@ export function DashboardAddPane({ editPane }: Props) {
return (
<>
<div className={styles.header}>
<IconButton name="arrow-left" size="lg" onClick={() => editPane.toggleAddPane()} aria-label="Close add pane" />
<IconButton
name="arrow-left"
size="lg"
onClick={() => editPane.toggleAddPane()}
aria-label={t('dashboard-scene.dashboard-add-pane.aria-label-close-add-pane', 'Close add pane')}
/>
{t('dashboard.edit-pane.add.title', 'Add element')}
</div>
<Box display="flex" direction="column" gap={1} padding={2}>

View File

@ -15,7 +15,7 @@ import {
Text,
Icon,
} from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { isInCloneChain } from '../utils/clone';
import { getDashboardSceneFor } from '../utils/utils';
@ -289,7 +289,9 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
onClick={() => setOutlineCollapsed(!outlineCollapsed)}
className={styles.outlineCollapseButton}
>
<Text weight="medium">Outline</Text>
<Text weight="medium">
<Trans i18nKey="dashboard-scene.dashboard-edit-pane-renderer.outline">Outline</Trans>
</Text>
<Icon name="angle-up" />
</div>
{!outlineCollapsed && (

View File

@ -22,6 +22,7 @@ import {
Icon,
Stack,
} from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv';
import { AccessControlAction } from 'app/types';
@ -69,7 +70,7 @@ export function HelpWizard({ panel, onClose }: Props) {
return (
<Drawer
title="Get help with this panel"
title={t('dashboard-scene.help-wizard.title-get-help-with-this-panel', 'Get help with this panel')}
size="lg"
onClose={onClose}
subtitle={
@ -116,13 +117,13 @@ export function HelpWizard({ panel, onClose }: Props) {
{currentTab === SnapshotTab.Data && (
<div className={styles.code}>
<div className={styles.opts}>
<Field label="Template" className={styles.field}>
<Field label={t('dashboard-scene.help-wizard.label-template', 'Template')} className={styles.field}>
<Select options={options} value={showMessage} onChange={service.onShowMessageChange} />
</Field>
{showMessage === ShowMessage.GithubComment ? (
<ClipboardButton icon="copy" getText={service.onGetMarkdownForClipboard}>
Copy to clipboard
<Trans i18nKey="dashboard-scene.help-wizard.copy-to-clipboard">Copy to clipboard</Trans>
</ClipboardButton>
) : (
<Button icon="download-alt" onClick={service.onDownloadDashboard}>
@ -149,26 +150,26 @@ export function HelpWizard({ panel, onClose }: Props) {
{currentTab === SnapshotTab.Support && (
<>
<Field
label="Randomize data"
label={t('dashboard-scene.help-wizard.label-randomize-data', 'Randomize data')}
description="Modify the original data to hide sensitive information. Note the lengths will stay the same, and duplicate values will be equal."
>
<Stack>
<InlineSwitch
label="Labels"
label={t('dashboard-scene.help-wizard.randomize-labels-label-labels', 'Labels')}
id="randomize-labels"
showLabel={true}
value={Boolean(randomize.labels)}
onChange={() => service.onToggleRandomize('labels')}
/>
<InlineSwitch
label="Field names"
label={t('dashboard-scene.help-wizard.randomize-field-names-label-field-names', 'Field names')}
id="randomize-field-names"
showLabel={true}
value={Boolean(randomize.names)}
onChange={() => service.onToggleRandomize('names')}
/>
<InlineSwitch
label="String values"
label={t('dashboard-scene.help-wizard.randomize-string-values-label-string-values', 'String values')}
id="randomize-string-values"
showLabel={true}
value={Boolean(randomize.values)}
@ -177,7 +178,10 @@ export function HelpWizard({ panel, onClose }: Props) {
</Stack>
</Field>
<Field label="Support snapshot" description={`Panel: ${panelTitle}`}>
<Field
label={t('dashboard-scene.help-wizard.label-support-snapshot', 'Support snapshot')}
description={`Panel: ${panelTitle}`}
>
<Stack>
<Button icon="download-alt" onClick={service.onDownloadDashboard}>
Dashboard ({snapshotSize})
@ -185,9 +189,12 @@ export function HelpWizard({ panel, onClose }: Props) {
<ClipboardButton
icon="github"
getText={service.onGetMarkdownForClipboard}
title="Copy a complete GitHub comment to the clipboard"
title={t(
'dashboard-scene.help-wizard.title-complete-git-hub-comment-clipboard',
'Copy a complete GitHub comment to the clipboard'
)}
>
Copy to clipboard
<Trans i18nKey="dashboard-scene.help-wizard.copy-to-clipboard">Copy to clipboard</Trans>
</ClipboardButton>
</Stack>
</Field>

View File

@ -9,7 +9,7 @@ import {
SceneObjectState,
VizPanel,
} from '@grafana/scenes';
import { t } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { InspectTab } from 'app/features/inspector/types';
import { GetDataOptions } from 'app/features/query/state/PanelQueryRunner';
@ -51,7 +51,9 @@ export class InspectDataTab extends SceneObjectBase<InspectDataTabState> {
const timeRange = sceneGraph.getTimeRange(panel);
if (!data) {
<div>No data found</div>;
<div>
<Trans i18nKey="dashboard-scene.inspect-data-tab.no-data-found">No data found</Trans>
</div>;
}
return (

View File

@ -17,7 +17,7 @@ import {
} from '@grafana/scenes';
import { LibraryPanel } from '@grafana/schema/';
import { Button, CodeEditor, Field, Select, useStyles2 } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { getPanelDataFrames } from 'app/features/dashboard/components/HelpWizard/utils';
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { getPanelInspectorStyles2 } from 'app/features/inspector/styles';
@ -177,7 +177,7 @@ export class InspectJsonTab extends SceneObjectBase<InspectJsonTabState> {
</Field>
{model.isEditable() && (
<Button className={styles.toolbarItem} onClick={model.onApplyChange}>
Apply
<Trans i18nKey="dashboard-scene.inspect-json-tab.apply">Apply</Trans>
</Button>
)}
</div>

View File

@ -11,6 +11,7 @@ import {
SceneObjectRef,
} from '@grafana/scenes';
import { Alert, Drawer, Tab, TabsBar } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { getDataSourceWithInspector } from 'app/features/dashboard/components/Inspector/hooks';
import { supportsDataQuery } from 'app/features/dashboard/components/PanelEditor/utils';
import { InspectTab } from 'app/features/inspector/types';
@ -135,7 +136,9 @@ function PanelInspectRenderer({ model }: SceneComponentProps<PanelInspectDrawer>
}
>
{pluginNotLoaded && (
<Alert title="Panel plugin not loaded">
<Alert
title={t('dashboard-scene.panel-inspect-renderer.title-panel-plugin-not-loaded', 'Panel plugin not loaded')}
>
Make sure the panel you want to inspect is visible and has been displayed before opening inspect.
</Alert>
)}

View File

@ -27,7 +27,7 @@ export function EmptyTransformationsMessage(props: EmptyTransformationsProps) {
onClick={props.onShowPicker}
data-testid={selectors.components.Transforms.addTransformationButton}
>
Add transformation
<Trans i18nKey="dashboard-scene.empty-transformations-message.add-transformation">Add transformation</Trans>
</Button>
</Stack>
</Box>

View File

@ -5,6 +5,7 @@ import { urlUtil } from '@grafana/data';
import { locationService, logInfo } from '@grafana/runtime';
import { VizPanel } from '@grafana/scenes';
import { Alert, Button } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { LogMessages } from 'app/features/alerting/unified/Analytics';
import { scenesPanelToRuleFormValues } from 'app/features/alerting/unified/utils/rule-form';
@ -18,12 +19,22 @@ export const ScenesNewRuleFromPanelButton = ({ panel, className }: ScenesNewRule
const { loading, value: formValues } = useAsync(() => scenesPanelToRuleFormValues(panel), [panel]);
if (loading) {
return <Button disabled={true}>New alert rule</Button>;
return (
<Button disabled={true}>
<Trans i18nKey="dashboard-scene.scenes-new-rule-from-panel-button.new-alert-rule">New alert rule</Trans>
</Button>
);
}
if (!formValues) {
return (
<Alert severity="info" title="No alerting capable query found">
<Alert
severity="info"
title={t(
'dashboard-scene.scenes-new-rule-from-panel-button.title-no-alerting-capable-query-found',
'No alerting capable query found'
)}
>
Cannot create alerts from this panel because no query to an alerting capable datasource is found.
</Alert>
);
@ -44,7 +55,7 @@ export const ScenesNewRuleFromPanelButton = ({ panel, className }: ScenesNewRule
return (
<Button icon="bell" onClick={onClick} className={className} data-testid="create-alert-rule-button">
New alert rule
<Trans i18nKey="dashboard-scene.scenes-new-rule-from-panel-button.new-alert-rule">New alert rule</Trans>
</Button>
);
};

View File

@ -5,7 +5,7 @@ import { config } from '@grafana/runtime';
import { SceneComponentProps, SceneObjectBase, SceneObjectRef, SceneObjectState, VizPanel } from '@grafana/scenes';
import { Alert, LoadingPlaceholder, Tab, useStyles2 } from '@grafana/ui';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { RulesTable } from 'app/features/alerting/unified/components/rules/RulesTable';
import { usePanelCombinedRules } from 'app/features/alerting/unified/hooks/usePanelCombinedRules';
import { getRulesPermissions } from 'app/features/alerting/unified/utils/access-control';
@ -64,7 +64,13 @@ export function PanelDataAlertingTabRendered({ model }: SceneComponentProps<Pane
});
const alert = errors.length ? (
<Alert title="Errors loading rules" severity="error">
<Alert
title={t(
'dashboard-scene.panel-data-alerting-tab-rendered.alert.title-errors-loading-rules',
'Errors loading rules'
)}
severity="error"
>
{errors.map((error, index) => (
<div key={index}>Failed to load Grafana rules state: {stringifyErrorLike(error)}</div>
))}
@ -75,7 +81,9 @@ export function PanelDataAlertingTabRendered({ model }: SceneComponentProps<Pane
return (
<>
{alert}
<LoadingPlaceholder text="Loading rules..." />
<LoadingPlaceholder
text={t('dashboard-scene.panel-data-alerting-tab-rendered.text-loading-rules', 'Loading rules...')}
/>
</>
);
}
@ -108,7 +116,10 @@ export function PanelDataAlertingTabRendered({ model }: SceneComponentProps<Pane
</>
)}
{isNew && !!dashboard.state.meta.canSave && (
<Alert severity="info" title="Dashboard not saved">
<Alert
severity="info"
title={t('dashboard-scene.panel-data-alerting-tab-rendered.title-dashboard-not-saved', 'Dashboard not saved')}
>
<Trans i18nKey="dashboard.panel-edit.alerting-tab.dashboard-not-saved">
Dashboard must be saved before alerts can be added.
</Trans>

View File

@ -377,7 +377,7 @@ export function PanelDataQueriesTabRendered({ model }: SceneComponentProps<Panel
variant="secondary"
data-testid={selectors.components.QueryTab.addQuery}
>
Add query
<Trans i18nKey="dashboard-scene.panel-data-queries-tab-rendered.add-query">Add query</Trans>
</Button>
{queryLibraryEnabled && (
<Button

View File

@ -14,6 +14,7 @@ import {
SceneObjectState,
} from '@grafana/scenes';
import { Button, ButtonGroup, ConfirmModal, Tab, useStyles2 } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { TransformationOperationRows } from 'app/features/dashboard/components/TransformationsEditor/TransformationOperationRows';
import { getQueryRunnerFor } from '../../utils/utils';
@ -112,7 +113,9 @@ export function PanelDataTransformationsTabRendered({ model }: SceneComponentPro
onClick={openDrawer}
data-testid={selectors.components.Transforms.addTransformationButton}
>
Add another transformation
<Trans i18nKey="dashboard-scene.panel-data-transformations-tab-rendered.add-another-transformation">
Add another transformation
</Trans>
</Button>
<Button
data-testid={selectors.components.Transforms.removeAllTransformationsButton}
@ -121,12 +124,17 @@ export function PanelDataTransformationsTabRendered({ model }: SceneComponentPro
variant="secondary"
onClick={() => setConfirmModalOpen(true)}
>
Delete all transformations
<Trans i18nKey="dashboard-scene.panel-data-transformations-tab-rendered.delete-all-transformations">
Delete all transformations
</Trans>
</Button>
</ButtonGroup>
<ConfirmModal
isOpen={confirmModalOpen}
title="Delete all transformations?"
title={t(
'dashboard-scene.panel-data-transformations-tab-rendered.title-delete-all-transformations',
'Delete all transformations?'
)}
body="By deleting all transformations, you will go back to the main selection screen."
confirmText="Delete all"
onConfirm={() => {

View File

@ -2,6 +2,7 @@ import { FormEvent, useMemo, useState } from 'react';
import { DataFrame, SelectableValue, standardTransformersRegistry } from '@grafana/data';
import { IconButton } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { TransformationPickerNg } from 'app/features/dashboard/components/TransformationsEditor/TransformationPickerNg';
import {
FilterCategory,
@ -65,7 +66,7 @@ export function TransformationsDrawer(props: TransformationsDrawerProps) {
onClick={() => {
setDrawerState({ ...drawerState, ...{ search: '' } });
}}
tooltip="Clear search"
tooltip={t('dashboard-scene.transformations-drawer.search-box-suffix.tooltip-clear-search', 'Clear search')}
/>
</>
);

View File

@ -1,5 +1,6 @@
import { selectors } from '@grafana/e2e-selectors';
import { InlineSwitch } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { PanelEditor } from './PanelEditor';
@ -14,12 +15,15 @@ export function PanelEditControls({ panelEditor }: Props) {
<>
{dataPane && (
<InlineSwitch
label="Table view"
label={t('dashboard-scene.panel-edit-controls.table-view-label-table-view', 'Table view')}
showLabel={true}
id="table-view"
value={tableView ? true : false}
onClick={panelEditor.onToggleTableView}
aria-label="toggle-table-view"
aria-label={t(
'dashboard-scene.panel-edit-controls.table-view-aria-label-toggletableview',
'Toggle table view'
)}
data-testid={selectors.components.PanelEditor.toggleTableView}
/>
)}

View File

@ -32,7 +32,7 @@ import {
ToolbarButton,
useStyles2,
} from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { OptionFilter } from 'app/features/dashboard/components/PanelEditor/OptionsPaneOptions';
import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError';
import { VizTypeChangeDetails } from 'app/features/panel/components/VizTypePicker/types';
@ -149,7 +149,7 @@ export class PanelOptionsPane extends SceneObjectBase<PanelOptionsPaneState> {
<FilterInput
className={styles.searchOptions}
value={searchQuery}
placeholder="Search options"
placeholder={t('dashboard-scene.panel-options-pane.placeholder-search-options', 'Search options')}
onChange={model.onSetSearchQuery}
/>
{showSearchRadioButtons && (
@ -263,11 +263,14 @@ export function VisualizationButton({ pluginId, onOpen }: VisualizationButtonPro
<Stack gap={1}>
<ToolbarButton
className={styles.vizButton}
tooltip="Click to change visualization"
tooltip={t(
'dashboard-scene.visualization-button.tooltip-click-to-change-visualization',
'Click to change visualization'
)}
imgSrc={pluginMeta.info.logos.small}
onClick={onOpen}
data-testid={selectors.components.PanelEditor.toggleVizPicker}
aria-label="Change Visualization"
aria-label={t('dashboard-scene.visualization-button.aria-label-change-visualization', 'Change visualization')}
variant="canvas"
isOpen={false}
fullWidth

View File

@ -9,6 +9,7 @@ import { reportInteraction } from '@grafana/runtime';
import { VizPanel } from '@grafana/scenes';
import { Button, Field, FilterInput, RadioButtonGroup, ScrollContainer, useStyles2 } from '@grafana/ui';
import { LS_VISUALIZATION_SELECT_TAB_KEY } from 'app/core/constants';
import { t } from 'app/core/internationalization';
import { VisualizationSelectPaneTab } from 'app/features/dashboard/components/PanelEditor/types';
import { VisualizationSuggestions } from 'app/features/panel/components/VizTypePicker/VisualizationSuggestions';
import { VizTypePicker } from 'app/features/panel/components/VizTypePicker/VizTypePicker';
@ -86,10 +87,10 @@ export function PanelVizTypePicker({ panel, data, onChange, onClose }: Props) {
value={searchQuery}
onChange={handleSearchChange}
autoFocus={true}
placeholder="Search for..."
placeholder={t('dashboard-scene.panel-viz-type-picker.placeholder-search-for', 'Search for...')}
/>
<Button
title="Close"
title={t('dashboard-scene.panel-viz-type-picker.title-close', 'Close')}
variant="secondary"
icon="angle-up"
className={styles.closeButton}

View File

@ -2,6 +2,7 @@ import { useCallback, useState } from 'react';
import { useAsync, useDebounce } from 'react-use';
import { Button, Icon, Input, Modal, useStyles2 } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { getConnectedDashboards } from 'app/features/library-panels/state/api';
import { getModalStyles } from 'app/features/library-panels/styles';
@ -62,17 +63,26 @@ export const SaveLibraryVizPanelModal = ({ libraryPanel, isUnsavedPrompt, onDism
<Input
className={styles.dashboardSearch}
prefix={<Icon name="search" />}
placeholder="Search affected dashboards"
placeholder={t(
'dashboard-scene.save-library-viz-panel-modal.placeholder-search-affected-dashboards',
'Search affected dashboards'
)}
value={searchString}
onChange={(e) => setSearchString(e.currentTarget.value)}
/>
{dashState.loading ? (
<p>Loading connected dashboards...</p>
<p>
<Trans i18nKey="dashboard-scene.save-library-viz-panel-modal.loading-connected-dashboards">
Loading connected dashboards...
</Trans>
</p>
) : (
<table className={styles.myTable}>
<thead>
<tr>
<th>Dashboard name</th>
<th>
<Trans i18nKey="dashboard-scene.save-library-viz-panel-modal.dashboard-name">Dashboard name</Trans>
</th>
</tr>
</thead>
<tbody>
@ -86,11 +96,11 @@ export const SaveLibraryVizPanelModal = ({ libraryPanel, isUnsavedPrompt, onDism
)}
<Modal.ButtonRow>
<Button variant="secondary" onClick={onDismiss} fill="outline">
Cancel
<Trans i18nKey="dashboard-scene.save-library-viz-panel-modal.cancel">Cancel</Trans>
</Button>
{isUnsavedPrompt && (
<Button variant="destructive" onClick={discardAndClose}>
Discard
<Trans i18nKey="dashboard-scene.save-library-viz-panel-modal.discard">Discard</Trans>
</Button>
)}
<Button
@ -98,7 +108,7 @@ export const SaveLibraryVizPanelModal = ({ libraryPanel, isUnsavedPrompt, onDism
onConfirm();
}}
>
Update all
<Trans i18nKey="dashboard-scene.save-library-viz-panel-modal.update-all">Update all</Trans>
</Button>
</Modal.ButtonRow>
</div>

View File

@ -5,6 +5,7 @@ import { memo, useContext, useEffect, useMemo } from 'react';
import { locationService } from '@grafana/runtime';
import { ModalsContext, Modal, Button, useStyles2 } from '@grafana/ui';
import { Prompt } from 'app/core/components/FormPrompt/Prompt';
import { t, Trans } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv';
import { SaveLibraryVizPanelModal } from '../panel-edit/SaveLibraryVizPanelModal';
@ -124,20 +125,24 @@ export const UnsavedChangesModal = ({ onDiscard, onDismiss, onSaveDashboardClick
return (
<Modal
isOpen={true}
title="Unsaved changes"
title={t('dashboard-scene.unsaved-changes-modal.title-unsaved-changes', 'Unsaved changes')}
onDismiss={onDismiss}
icon="exclamation-triangle"
className={styles.modal}
>
<h5>Do you want to save your changes?</h5>
<h5>
<Trans i18nKey="dashboard-scene.unsaved-changes-modal.changes">Do you want to save your changes?</Trans>
</h5>
<Modal.ButtonRow>
<Button variant="secondary" onClick={onDismiss} fill="outline">
Cancel
<Trans i18nKey="dashboard-scene.unsaved-changes-modal.cancel">Cancel</Trans>
</Button>
<Button variant="destructive" onClick={onDiscard}>
Discard
<Trans i18nKey="dashboard-scene.unsaved-changes-modal.discard">Discard</Trans>
</Button>
<Button onClick={onSaveDashboardClick}>
<Trans i18nKey="dashboard-scene.unsaved-changes-modal.save-dashboard">Save dashboard</Trans>
</Button>
<Button onClick={onSaveDashboardClick}>Save dashboard</Button>
</Modal.ButtonRow>
</Modal>
);

View File

@ -5,6 +5,7 @@ import { UseFormSetValue, useForm } from 'react-hook-form';
import { selectors } from '@grafana/e2e-selectors';
import { Button, Input, Switch, Field, Label, TextArea, Stack, Alert, Box } from '@grafana/ui';
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
import { Trans, t } from 'app/core/internationalization';
import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv';
import { DashboardScene } from '../scene/DashboardScene';
@ -77,7 +78,7 @@ export function SaveDashboardAsForm({ dashboard, changeInfo }: Props) {
const cancelButton = (
<Button variant="secondary" onClick={() => dashboard.closeModal()} fill="outline">
Cancel
<Trans i18nKey="dashboard-scene.save-dashboard-as-form.cancel-button.cancel">Cancel</Trans>
</Button>
);
@ -94,7 +95,13 @@ export function SaveDashboardAsForm({ dashboard, changeInfo }: Props) {
return (
<>
{error && formValuesMatchContentSent && (
<Alert title="Failed to save dashboard" severity="error">
<Alert
title={t(
'dashboard-scene.save-dashboard-as-form.render-footer.title-failed-to-save-dashboard',
'Failed to save dashboard'
)}
severity="error"
>
{error.message && <p>{error.message}</p>}
</Alert>
)}
@ -111,7 +118,10 @@ export function SaveDashboardAsForm({ dashboard, changeInfo }: Props) {
<Field label={<TitleFieldLabel onChange={setValue} />} invalid={!!errors.title} error={errors.title?.message}>
<Input
{...register('title', { required: 'Required', validate: validateDashboardName })}
aria-label="Save dashboard title field"
aria-label={t(
'dashboard-scene.save-dashboard-as-form.aria-label-save-dashboard-title-field',
'Save dashboard title field'
)}
data-testid={selectors.components.Drawer.DashboardSaveDrawer.saveAsTitleInput}
onChange={debounce(async (e: ChangeEvent<HTMLInputElement>) => {
setValue('title', e.target.value, { shouldValidate: true });
@ -125,12 +135,15 @@ export function SaveDashboardAsForm({ dashboard, changeInfo }: Props) {
>
<TextArea
{...register('description', { required: false })}
aria-label="Save dashboard description field"
aria-label={t(
'dashboard-scene.save-dashboard-as-form.aria-label-save-dashboard-description-field',
'Save dashboard description field'
)}
autoFocus
/>
</Field>
<Field label="Folder">
<Field label={t('dashboard-scene.save-dashboard-as-form.label-folder', 'Folder')}>
<FolderPicker
onChange={async (uid: string | undefined, title: string | undefined) => {
setValue('folder', { uid, title });
@ -152,7 +165,7 @@ export function SaveDashboardAsForm({ dashboard, changeInfo }: Props) {
/>
</Field>
{!changeInfo.isNew && (
<Field label="Copy tags">
<Field label={t('dashboard-scene.save-dashboard-as-form.label-copy-tags', 'Copy tags')}>
<Switch {...register('copyTags')} />
</Field>
)}
@ -168,7 +181,9 @@ export interface TitleLabelProps {
export function TitleFieldLabel(props: TitleLabelProps) {
return (
<Stack justifyContent="space-between">
<Label htmlFor="description">Title</Label>
<Label htmlFor="description">
<Trans i18nKey="dashboard-scene.title-field-label.title">Title</Trans>
</Label>
{/* {config.featureToggles.dashgpt && isNew && (
<GenAIDashDescriptionButton
onGenerate={(description) => field.onChange(description)}
@ -186,7 +201,9 @@ export interface DescriptionLabelProps {
export function DescriptionLabel(props: DescriptionLabelProps) {
return (
<Stack justifyContent="space-between">
<Label htmlFor="description">Description</Label>
<Label htmlFor="description">
<Trans i18nKey="dashboard-scene.description-label.description">Description</Trans>
</Label>
{/* {config.featureToggles.dashgpt && isNew && (
<GenAIDashDescriptionButton
onGenerate={(description) => field.onChange(description)}

View File

@ -47,7 +47,7 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
const cancelButton = (
<Button variant="secondary" onClick={() => dashboard.closeModal()} fill="outline">
Cancel
<Trans i18nKey="dashboard-scene.save-dashboard-form.cancel-button.cancel">Cancel</Trans>
</Button>
);
@ -77,8 +77,18 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
if (isVersionMismatchError(error)) {
return (
<Alert title="Someone else has updated this dashboard" severity="error">
<p>Would you still like to save this dashboard?</p>
<Alert
title={t(
'dashboard-scene.save-dashboard-form.render-footer.title-someone-else-has-updated-this-dashboard',
'Someone else has updated this dashboard'
)}
severity="error"
>
<p>
<Trans i18nKey="dashboard-scene.save-dashboard-form.render-footer.would-still-dashboard">
Would you still like to save this dashboard?
</Trans>
</p>
<Box paddingTop={2}>
<Stack alignItems="center">
{cancelButton}
@ -95,7 +105,10 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
if (isPluginDashboardError(error)) {
return (
<Alert title="Plugin dashboard" severity="error">
<Alert
title={t('dashboard-scene.save-dashboard-form.render-footer.title-plugin-dashboard', 'Plugin dashboard')}
severity="error"
>
<p>
Your changes will be lost when you update the plugin. Use <strong>Save As</strong> to create custom version.
</p>
@ -112,14 +125,26 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
return (
<>
{error && (
<Alert title="Failed to save dashboard" severity="error">
<Alert
title={t(
'dashboard-scene.save-dashboard-form.render-footer.title-failed-to-save-dashboard',
'Failed to save dashboard'
)}
severity="error"
>
<p>{error.message}</p>
</Alert>
)}
<Stack alignItems="center">
{cancelButton}
{saveButton(false)}
{!hasChanges && <div>No changes to save</div>}
{!hasChanges && (
<div>
<Trans i18nKey="dashboard-scene.save-dashboard-form.render-footer.no-changes-to-save">
No changes to save
</Trans>
</div>
)}
</Stack>
</>
);
@ -129,7 +154,13 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
<Stack gap={2} direction="column">
<SaveDashboardFormCommonOptions drawer={drawer} changeInfo={changeInfo} />
{hasMigratedToV2 && (
<Alert title="Dashboard drastically changed" severity="warning">
<Alert
title={t(
'dashboard-scene.save-dashboard-form.title-dashboard-drastically-changed',
'Dashboard drastically changed'
)}
severity="warning"
>
<p>
Because you're using new dashboards features only supported on new Grafana dashboard schema format, the
dashboard will be saved in the new format. Please make sure you want to perform this action or you prefer to
@ -137,9 +168,9 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
</p>
</Alert>
)}
<Field label="Message">
<Field label={t('dashboard-scene.save-dashboard-form.label-message', 'Message')}>
<TextArea
aria-label="message"
aria-label={t('dashboard-scene.save-dashboard-form.aria-label-message', 'message')}
value={options.message ?? ''}
onChange={(e) => {
setOptions({
@ -147,7 +178,10 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
message: e.currentTarget.value,
});
}}
placeholder="Add a note to describe your changes (optional)."
placeholder={t(
'dashboard-scene.save-dashboard-form.placeholder-describe-changes-optional',
'Add a note to describe your changes (optional).'
)}
autoFocus
rows={5}
/>
@ -173,7 +207,10 @@ export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashb
id="save-timerange"
checked={saveTimeRange}
onChange={drawer.onToggleSaveTimeRange}
label="Update default time range"
label={t(
'dashboard-scene.save-dashboard-form-common-options.save-timerange-label-update-default-time-range',
'Update default time range'
)}
description={'Will make current time range the new default'}
data-testid={selectors.pages.SaveDashboardModal.saveTimerange}
/>
@ -181,8 +218,14 @@ export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashb
{hasRefreshChange && (
<Checkbox
id="save-refresh"
label="Update default refresh value"
description="Will make the current refresh the new default"
label={t(
'dashboard-scene.save-dashboard-form-common-options.save-refresh-label-update-default-refresh-value',
'Update default refresh value'
)}
description={t(
'dashboard-scene.save-dashboard-form-common-options.save-refresh-description-current-refresh-default',
'Will make the current refresh the new default'
)}
checked={saveRefresh}
onChange={drawer.onToggleSaveRefresh}
data-testid={selectors.pages.SaveDashboardModal.saveRefresh}
@ -191,8 +234,14 @@ export function SaveDashboardFormCommonOptions({ drawer, changeInfo }: SaveDashb
{hasVariableValueChanges && (
<Checkbox
id="save-variables"
label="Update default variable values"
description="Will make the current values the new default"
label={t(
'dashboard-scene.save-dashboard-form-common-options.save-variables-label-update-default-variable-values',
'Update default variable values'
)}
description={t(
'dashboard-scene.save-dashboard-form-common-options.save-variables-description-current-values-default',
'Will make the current values the new default'
)}
checked={saveVariables}
onChange={drawer.onToggleSaveVariables}
data-testid={selectors.pages.SaveDashboardModal.saveVariables}

View File

@ -4,6 +4,7 @@ import { useCallback, useMemo } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { Button, ClipboardButton, Stack, CodeEditor, Box } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { DashboardScene } from '../scene/DashboardScene';
@ -70,13 +71,17 @@ export function SaveProvisionedDashboardForm({ dashboard, drawer, changeInfo }:
<Box paddingTop={2}>
<Stack gap={2}>
<Button variant="secondary" onClick={drawer.onClose} fill="outline">
Cancel
<Trans i18nKey="dashboard-scene.save-provisioned-dashboard-form.cancel">Cancel</Trans>
</Button>
<ClipboardButton icon="copy" getText={() => dashboardJSON}>
Copy JSON to clipboard
<Trans i18nKey="dashboard-scene.save-provisioned-dashboard-form.copy-json-to-clipboard">
Copy JSON to clipboard
</Trans>
</ClipboardButton>
<Button type="submit" onClick={saveToFile}>
Save JSON to file
<Trans i18nKey="dashboard-scene.save-provisioned-dashboard-form.save-json-to-file">
Save JSON to file
</Trans>
</Button>
</Stack>
</Box>

View File

@ -56,7 +56,10 @@ export function NameAlreadyExistsError({ cancelButton, saveButton }: NameAlready
</p>
</Alert>
) : (
<Alert title="Name already exists" severity="error">
<Alert
title={t('dashboard-scene.name-already-exists-error.title-name-already-exists', 'Name already exists')}
severity="error"
>
<p>
A dashboard with the same name in selected folder already exists. Would you still like to save this dashboard?
</p>

View File

@ -8,6 +8,7 @@ import {
VizPanel,
} from '@grafana/scenes';
import { Dropdown, Icon, Menu, PanelChrome, ToolbarButton } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { getPanelLinks } from './PanelMenuBehavior';
@ -56,7 +57,11 @@ function VizPanelLinksRenderer({ model }: SceneComponentProps<VizPanelLinks>) {
return <menu.Component model={menu} key={menu.state.key} />;
}}
>
<ToolbarButton icon="external-link-alt" iconSize="md" aria-label="panel links" />
<ToolbarButton
icon="external-link-alt"
iconSize="md"
aria-label={t('dashboard-scene.viz-panel-links-renderer.aria-label-panel-links', 'Panel links')}
/>
</Dropdown>
);
}

View File

@ -1,4 +1,5 @@
import { ConfirmModal } from '@grafana/ui';
import { t } from 'app/core/internationalization';
interface Props {
isOpen: boolean;
@ -9,7 +10,7 @@ interface Props {
export const UnlinkModal = ({ isOpen, onConfirm, onDismiss }: Props) => {
return (
<ConfirmModal
title="Do you really want to unlink this panel?"
title={t('dashboard-scene.unlink-modal.title-really-unlink-panel', 'Do you really want to unlink this panel?')}
icon="question-circle"
body="If you unlink this panel, you will be able to edit it without affecting any other dashboards.
However, once you make a change you will not be able to revert to its original reusable panel."

View File

@ -111,7 +111,15 @@ export function DeleteDashboardModal({ dashboardTitle, onConfirm, onClose }: Del
function ProvisionedDeleteModal({ dashboardId, onClose }: ProvisionedDeleteModalProps) {
return (
<Modal isOpen={true} title="Cannot delete provisioned dashboard" icon="trash-alt" onDismiss={onClose}>
<Modal
isOpen={true}
title={t(
'dashboard-scene.provisioned-delete-modal.title-cannot-delete-provisioned-dashboard',
'Cannot delete provisioned dashboard'
)}
icon="trash-alt"
onDismiss={onClose}
>
<p>
This dashboard is managed by Grafana provisioning and cannot be deleted. Remove the dashboard from the config
file to delete it.
@ -134,7 +142,7 @@ function ProvisionedDeleteModal({ dashboardId, onClose }: ProvisionedDeleteModal
</p>
<Modal.ButtonRow>
<Button variant="primary" onClick={onClose}>
OK
<Trans i18nKey="dashboard-scene.provisioned-delete-modal.ok">OK</Trans>
</Button>
</Modal.ButtonRow>
</Modal>

View File

@ -6,7 +6,7 @@ import { SceneComponentProps, SceneObjectBase, sceneUtils } from '@grafana/scene
import { Dashboard } from '@grafana/schema';
import { Alert, Box, Button, CodeEditor, Stack, useStyles2 } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { getPrettyJSON } from 'app/features/inspector/utils/utils';
import { DashboardDTO, SaveDashboardResponseDTO } from 'app/types';
@ -123,7 +123,7 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
const cancelButton = (
<Button variant="secondary" onClick={() => setIsSaving(false)} fill="outline">
Cancel
<Trans i18nKey="dashboard-scene.json-model-edit-view.cancel-button.cancel">Cancel</Trans>
</Button>
);
const styles = useStyles2(getStyles);
@ -132,8 +132,18 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
if (error && isSaving) {
if (isVersionMismatchError(error)) {
return (
<Alert title="Someone else has updated this dashboard" severity="error">
<p>Would you still like to save this dashboard?</p>
<Alert
title={t(
'dashboard-scene.json-model-edit-view.render-save-button-and-error.title-someone-else-has-updated-this-dashboard',
'Someone else has updated this dashboard'
)}
severity="error"
>
<p>
<Trans i18nKey="dashboard-scene.json-model-edit-view.render-save-button-and-error.would-still-dashboard">
Would you still like to save this dashboard?
</Trans>
</p>
<Box paddingTop={2}>
<Stack alignItems="center">
{cancelButton}
@ -150,7 +160,13 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
if (isPluginDashboardError(error)) {
return (
<Alert title="Plugin dashboard" severity="error">
<Alert
title={t(
'dashboard-scene.json-model-edit-view.render-save-button-and-error.title-plugin-dashboard',
'Plugin dashboard'
)}
severity="error"
>
<p>
Your changes will be lost when you update the plugin. Use <strong>Save As</strong> to create custom
version.
@ -166,7 +182,13 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
return (
<>
{error && isSaving && (
<Alert title="Failed to save dashboard" severity="error">
<Alert
title={t(
'dashboard-scene.json-model-edit-view.render-save-button-and-error.title-failed-to-save-dashboard',
'Failed to save dashboard'
)}
severity="error"
>
<p>{error.message}</p>
</Alert>
)}

View File

@ -16,7 +16,7 @@ import { VizPanel } from '@grafana/scenes';
import { AnnotationPanelFilter } from '@grafana/schema/src/raw/dashboard/x/dashboard_types.gen';
import { Button, Checkbox, Field, FieldSet, Input, MultiSelect, Select, useStyles2, Stack, Alert } from '@grafana/ui';
import { ColorValueEditor } from 'app/core/components/OptionsUI/color';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
@ -171,7 +171,7 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
return (
<div>
<FieldSet className={styles.settingsForm}>
<Field label="Name">
<Field label={t('dashboard-scene.annotation-settings-edit.label-name', 'Name')}>
<Input
data-testid={selectors.pages.Dashboard.Settings.Annotations.Settings.name}
name="name"
@ -181,17 +181,32 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
onChange={onNameChange}
/>
</Field>
<Field label="Data source" htmlFor="data-source-picker">
<Field
label={t('dashboard-scene.annotation-settings-edit.label-data-source', 'Data source')}
htmlFor="data-source-picker"
>
<DataSourcePicker annotations variables current={annotation.datasource} onChange={onDataSourceChange} />
</Field>
{!ds?.meta.annotations && (
<Alert title="No annotation support for this data source" severity="error">
<Alert
title={t(
'dashboard-scene.annotation-settings-edit.title-annotation-support-source',
'No annotation support for this data source'
)}
severity="error"
>
<Trans i18nKey="errors.dashboard-settings.annotations.datasource">
The selected data source does not support annotations. Please select a different data source.
</Trans>
</Alert>
)}
<Field label="Enabled" description="When enabled the annotation query is issued every dashboard refresh">
<Field
label={t('dashboard-scene.annotation-settings-edit.label-enabled', 'Enabled')}
description={t(
'dashboard-scene.annotation-settings-edit.description-enabled-annotation-query-issued-every-dashboard',
'When enabled the annotation query is issued every dashboard refresh'
)}
>
<Checkbox
name="enable"
id="enable"
@ -201,7 +216,7 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
/>
</Field>
<Field
label="Hidden"
label={t('dashboard-scene.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."
>
<Checkbox
@ -212,12 +227,21 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
data-testid={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.hide}
/>
</Field>
<Field label="Color" description="Color to use for the annotation event markers">
<Field
label={t('dashboard-scene.annotation-settings-edit.label-color', 'Color')}
description={t(
'dashboard-scene.annotation-settings-edit.description-color-annotation-event-markers',
'Color to use for the annotation event markers'
)}
>
<Stack>
<ColorValueEditor value={annotation?.iconColor} onChange={onColorChange} />
</Stack>
</Field>
<Field label="Show in" data-testid={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.showInLabel}>
<Field
label={t('dashboard-scene.annotation-settings-edit.label-show-in', 'Show in')}
data-testid={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.showInLabel}
>
<>
<Select
options={panelFilters}
@ -231,7 +255,7 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
value={selectablePanels.filter((panel) => annotation.filter?.ids.includes(panel.value!))}
onChange={onAddFilterPanelID}
isClearable={true}
placeholder="Choose panels"
placeholder={t('dashboard-scene.annotation-settings-edit.placeholder-choose-panels', 'Choose panels')}
width={100}
closeMenuOnSelect={false}
className={styles.select}
@ -242,7 +266,9 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
</Field>
</FieldSet>
<FieldSet>
<h3 className="page-heading">Query</h3>
<h3 className="page-heading">
<Trans i18nKey="dashboard-scene.annotation-settings-edit.query">Query</Trans>
</h3>
{ds?.annotations && dsi && (
<StandardAnnotationQueryEditor
datasource={ds}
@ -266,7 +292,7 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
onClick={onDeleteAndLeavePage}
data-testid={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.delete}
>
Delete
<Trans i18nKey="dashboard-scene.annotation-settings-edit.delete">Delete</Trans>
</Button>
)}
<Button
@ -274,7 +300,7 @@ export const AnnotationSettingsEdit = ({ annotation, editIndex, panels, onUpdate
onClick={onBackToList}
data-testid={selectors.pages.Dashboard.Settings.Annotations.NewAnnotation.apply}
>
Back to list
<Trans i18nKey="dashboard-scene.annotation-settings-edit.back-to-list">Back to list</Trans>
</Button>
</Stack>
</div>

View File

@ -44,8 +44,12 @@ export const AnnotationSettingsList = ({ annotations, onNew, onEdit, onMove, onD
<table role="grid" className="filter-table filter-table--hover">
<thead>
<tr>
<th>Query name</th>
<th>Data source</th>
<th>
<Trans i18nKey="dashboard-scene.annotation-settings-list.query-name">Query name</Trans>
</th>
<th>
<Trans i18nKey="dashboard-scene.annotation-settings-list.data-source">Data source</Trans>
</th>
<th colSpan={3}></th>
</tr>
</thead>
@ -70,7 +74,11 @@ export const AnnotationSettingsList = ({ annotations, onNew, onEdit, onMove, onD
</td>
<td role="gridcell" style={{ width: '1%' }}>
{idx !== 0 && (
<IconButton name="arrow-up" onClick={() => onMove(idx, MoveDirection.UP)} tooltip="Move up" />
<IconButton
name="arrow-up"
onClick={() => onMove(idx, MoveDirection.UP)}
tooltip={t('dashboard-scene.annotation-settings-list.tooltip-move-up', 'Move up')}
/>
)}
</td>
<td role="gridcell" style={{ width: '1%' }}>
@ -78,7 +86,7 @@ export const AnnotationSettingsList = ({ annotations, onNew, onEdit, onMove, onD
<IconButton
name="arrow-down"
onClick={() => onMove(idx, MoveDirection.DOWN)}
tooltip="Move down"
tooltip={t('dashboard-scene.annotation-settings-list.tooltip-move-down', 'Move down')}
/>
) : null}
</td>
@ -136,7 +144,7 @@ export const AnnotationSettingsList = ({ annotations, onNew, onEdit, onMove, onD
data-testid={selectors.pages.Dashboard.Settings.Annotations.List.addAnnotationCTAV2}
onClick={onNew}
>
New query
<Trans i18nKey="dashboard-scene.annotation-settings-list.new-query">New query</Trans>
</ListNewButton>
)}
</Stack>

View File

@ -3,6 +3,7 @@ import * as React from 'react';
import { SelectableValue } from '@grafana/data';
import { DashboardLink } from '@grafana/schema';
import { CollapsableSection, TagsInput, Select, Field, Input, Checkbox, Button } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { LINK_ICON_MAP, NEW_LINK } from './utils';
@ -54,55 +55,81 @@ export function DashboardLinkForm({ link, onUpdate, onGoBack }: DashboardLinkFor
return (
<div style={{ maxWidth: '600px' }}>
<Field label="Title">
<Field label={t('dashboard-scene.dashboard-link-form.label-title', 'Title')}>
<Input name="title" id="title" value={link.title} onChange={onChange} autoFocus={isNew} />
</Field>
<Field label="Type">
<Field label={t('dashboard-scene.dashboard-link-form.label-type', 'Type')}>
<Select inputId="link-type-input" value={link.type} options={linkTypeOptions} onChange={onTypeChange} />
</Field>
{link.type === 'dashboards' && (
<>
<Field label="With tags">
<Field label={t('dashboard-scene.dashboard-link-form.label-with-tags', 'With tags')}>
<TagsInput tags={link.tags} onChange={onTagsChange} />
</Field>
</>
)}
{link.type === 'link' && (
<>
<Field label="URL">
<Field label={t('dashboard-scene.dashboard-link-form.label-url', 'URL')}>
<Input name="url" value={link.url} onChange={onChange} />
</Field>
<Field label="Tooltip">
<Input name="tooltip" value={link.tooltip} onChange={onChange} placeholder="Open dashboard" />
<Field label={t('dashboard-scene.dashboard-link-form.label-tooltip', 'Tooltip')}>
<Input
name="tooltip"
value={link.tooltip}
onChange={onChange}
placeholder={t('dashboard-scene.dashboard-link-form.placeholder-open-dashboard', 'Open dashboard')}
/>
</Field>
<Field label="Icon">
<Field label={t('dashboard-scene.dashboard-link-form.label-icon', 'Icon')}>
<Select value={link.icon} options={linkIconOptions} onChange={onIconChange} />
</Field>
</>
)}
<CollapsableSection label="Options" isOpen={true}>
<CollapsableSection label={t('dashboard-scene.dashboard-link-form.label-options', 'Options')} isOpen={true}>
{link.type === 'dashboards' && (
<Field>
<Checkbox label="Show as dropdown" name="asDropdown" value={link.asDropdown} onChange={onChange} />
<Checkbox
label={t('dashboard-scene.dashboard-link-form.label-show-as-dropdown', 'Show as dropdown')}
name="asDropdown"
value={link.asDropdown}
onChange={onChange}
/>
</Field>
)}
<Field>
<Checkbox label="Include current time range" name="keepTime" value={link.keepTime} onChange={onChange} />
<Checkbox
label={t(
'dashboard-scene.dashboard-link-form.label-include-current-time-range',
'Include current time range'
)}
name="keepTime"
value={link.keepTime}
onChange={onChange}
/>
</Field>
<Field>
<Checkbox
label="Include current template variable values"
label={t(
'dashboard-scene.dashboard-link-form.label-include-current-template-variable-values',
'Include current template variable values'
)}
name="includeVars"
value={link.includeVars}
onChange={onChange}
/>
</Field>
<Field>
<Checkbox label="Open link in new tab" name="targetBlank" value={link.targetBlank} onChange={onChange} />
<Checkbox
label={t('dashboard-scene.dashboard-link-form.label-open-link-in-new-tab', 'Open link in new tab')}
name="targetBlank"
value={link.targetBlank}
onChange={onChange}
/>
</Field>
</CollapsableSection>
<Button variant="secondary" onClick={onGoBack}>
Back to list
<Trans i18nKey="dashboard-scene.dashboard-link-form.back-to-list">Back to list</Trans>
</Button>
</div>
);

View File

@ -57,8 +57,12 @@ export function DashboardLinkList({
<table role="grid" className="filter-table filter-table--hover">
<thead>
<tr>
<th>Type</th>
<th>Info</th>
<th>
<Trans i18nKey="dashboard-scene.dashboard-link-list.type">Type</Trans>
</th>
<th>
<Trans i18nKey="dashboard-scene.dashboard-link-list.info">Info</Trans>
</th>
<th colSpan={3} />
</tr>
</thead>
@ -77,16 +81,28 @@ export function DashboardLinkList({
</td>
<td style={{ width: '1%' }} role="gridcell">
{idx !== 0 && (
<IconButton name="arrow-up" onClick={() => onOrderChange(idx, -1)} tooltip="Move link up" />
<IconButton
name="arrow-up"
onClick={() => onOrderChange(idx, -1)}
tooltip={t('dashboard-scene.dashboard-link-list.tooltip-move-link-up', 'Move link up')}
/>
)}
</td>
<td style={{ width: '1%' }} role="gridcell">
{links.length > 1 && idx !== links.length - 1 ? (
<IconButton name="arrow-down" onClick={() => onOrderChange(idx, 1)} tooltip="Move link down" />
<IconButton
name="arrow-down"
onClick={() => onOrderChange(idx, 1)}
tooltip={t('dashboard-scene.dashboard-link-list.tooltip-move-link-down', 'Move link down')}
/>
) : null}
</td>
<td style={{ width: '1%' }} role="gridcell">
<IconButton name="copy" onClick={() => onDuplicate(link)} tooltip="Copy link" />
<IconButton
name="copy"
onClick={() => onDuplicate(link)}
tooltip={t('dashboard-scene.dashboard-link-list.tooltip-copy-link', 'Copy link')}
/>
</td>
<td style={{ width: '1%' }} role="gridcell">
<DeleteButton
@ -100,7 +116,7 @@ export function DashboardLinkList({
</tbody>
</table>
<Button className={styles.newLinkButton} icon="plus" onClick={onNew}>
New link
<Trans i18nKey="dashboard-scene.dashboard-link-list.new-link">New link</Trans>
</Button>
</>
);

View File

@ -9,6 +9,7 @@ import { reportInteraction } from '@grafana/runtime';
import { SceneVariable } from '@grafana/scenes';
import { VariableHide, defaultVariableModel } from '@grafana/schema';
import { Button, LoadingPlaceholder, ConfirmModal, ModalsController, Stack, useStyles2 } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { VariableHideSelect } from 'app/features/dashboard-scene/settings/variables/components/VariableHideSelect';
import { VariableLegend } from 'app/features/dashboard-scene/settings/variables/components/VariableLegend';
import { VariableTextAreaField } from 'app/features/dashboard-scene/settings/variables/components/VariableTextAreaField';
@ -76,14 +77,21 @@ export function VariableEditorForm({
};
return (
<form aria-label="Variable editor Form">
<form
aria-label={t('dashboard-scene.variable-editor-form.aria-label-variable-editor-form', 'Variable editor form')}
>
<VariableTypeSelect onChange={onVariableTypeChange} type={type} />
<VariableLegend>General</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.variable-editor-form.general">General</Trans>
</VariableLegend>
<VariableTextField
name="Name"
description="The name of the template variable. (Max. 50 characters)"
placeholder="Variable name"
description={t(
'dashboard-scene.variable-editor-form.description-template-variable-characters',
'The name of the template variable. (Max. 50 characters)'
)}
placeholder={t('dashboard-scene.variable-editor-form.placeholder-variable-name', 'Variable name')}
defaultValue={name ?? ''}
onChange={onNameChange}
onBlur={onNameBlur}
@ -95,8 +103,11 @@ export function VariableEditorForm({
/>
<VariableTextField
name="Label"
description="Optional display name"
placeholder="Label name"
description={t(
'dashboard-scene.variable-editor-form.description-optional-display-name',
'Optional display name'
)}
placeholder={t('dashboard-scene.variable-editor-form.placeholder-label-name', 'Label name')}
defaultValue={label ?? ''}
onBlur={onLabelBlur}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2}
@ -104,7 +115,7 @@ export function VariableEditorForm({
<VariableTextAreaField
name="Description"
defaultValue={description ?? ''}
placeholder="Descriptive text"
placeholder={t('dashboard-scene.variable-editor-form.placeholder-descriptive-text', 'Descriptive text')}
onBlur={onDescriptionBlur}
width={52}
/>
@ -133,7 +144,7 @@ export function VariableEditorForm({
});
}}
>
Delete
<Trans i18nKey="dashboard-scene.variable-editor-form.delete">Delete</Trans>
</Button>
)}
</ModalsController>
@ -142,7 +153,7 @@ export function VariableEditorForm({
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.General.applyButton}
onClick={onGoBack}
>
Back to list
<Trans i18nKey="dashboard-scene.variable-editor-form.back-to-list">Back to list</Trans>
</Button>
{isHasVariableOptions && (
@ -153,7 +164,10 @@ export function VariableEditorForm({
onClick={onRunQuery}
>
{runQueryState.loading ? (
<LoadingPlaceholder className={styles.loadingPlaceHolder} text="Running query..." />
<LoadingPlaceholder
className={styles.loadingPlaceHolder}
text={t('dashboard-scene.variable-editor-form.text-running-query', 'Running query...')}
/>
) : (
`Run query`
)}

View File

@ -57,8 +57,12 @@ export function VariableEditorList({
>
<thead>
<tr>
<th>Variable</th>
<th>Definition</th>
<th>
<Trans i18nKey="dashboard-scene.variable-editor-list.variable">Variable</Trans>
</th>
<th>
<Trans i18nKey="dashboard-scene.variable-editor-list.definition">Definition</Trans>
</th>
<th colSpan={5} />
</tr>
</thead>
@ -90,7 +94,7 @@ export function VariableEditorList({
<Stack>
<VariablesDependenciesButton variables={variables} />
<Button data-testid={selectors.pages.Dashboard.Settings.Variables.List.newButton} onClick={onAdd} icon="plus">
New variable
<Trans i18nKey="dashboard-scene.variable-editor-list.new-variable">New variable</Trans>
</Button>
</Stack>
</Stack>

View File

@ -7,6 +7,7 @@ import { selectors } from '@grafana/e2e-selectors';
import { reportInteraction } from '@grafana/runtime';
import { SceneVariable } from '@grafana/scenes';
import { Button, ConfirmModal, Icon, IconButton, Tooltip, useStyles2, useTheme2 } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { VariableUsagesButton } from '../../variables/VariableUsagesButton';
import { UsagesToNetwork, VariableUsageTree, getVariableUsages } from '../../variables/utils';
@ -101,7 +102,7 @@ export function VariableEditorListRow({
propsOnDuplicate(identifier);
}}
name="copy"
tooltip="Duplicate variable"
tooltip={t('dashboard-scene.variable-editor-list-row.tooltip-duplicate-variable', 'Duplicate variable')}
data-testid={selectors.pages.Dashboard.Settings.Variables.List.tableRowDuplicateButtons(
variableState.name
)}
@ -112,14 +113,14 @@ export function VariableEditorListRow({
setShowDeleteModal(true);
}}
name="trash-alt"
tooltip="Remove variable"
tooltip={t('dashboard-scene.variable-editor-list-row.tooltip-remove-variable', 'Remove variable')}
data-testid={selectors.pages.Dashboard.Settings.Variables.List.tableRowRemoveButtons(
variableState.name
)}
/>
<ConfirmModal
isOpen={showDeleteModal}
title="Delete variable"
title={t('dashboard-scene.variable-editor-list-row.title-delete-variable', 'Delete variable')}
body={`Are you sure you want to delete: ${variableState.name}?`}
confirmText="Delete variable"
onConfirm={onDeleteVariable}
@ -149,7 +150,10 @@ function VariableCheckIndicator({ passed }: VariableCheckIndicatorProps): ReactE
<Icon
name="check"
className={styles.iconPassed}
aria-label="This variable is referenced by other variables or dashboard."
aria-label={t(
'dashboard-scene.variable-check-indicator.aria-label-variable-referenced-other-variables-dashboard',
'This variable is referenced by other variables or dashboard.'
)}
/>
</Tooltip>
);
@ -160,7 +164,10 @@ function VariableCheckIndicator({ passed }: VariableCheckIndicatorProps): ReactE
<Icon
name="exclamation-triangle"
className={styles.iconFailed}
aria-label="This variable is not referenced by any variable or dashboard."
aria-label={t(
'dashboard-scene.variable-check-indicator.aria-label-variable-referenced-dashboard',
'This variable is not referenced by any variable or dashboard.'
)}
/>
</Tooltip>
);

View File

@ -4,6 +4,7 @@ import { DataSourceInstanceSettings, MetricFindValue, readCSV } from '@grafana/d
import { selectors } from '@grafana/e2e-selectors';
import { DataSourceRef } from '@grafana/schema';
import { Alert, CodeEditor, Field, Switch } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { VariableCheckboxField } from './VariableCheckboxField';
@ -43,8 +44,13 @@ export function AdHocVariableForm({
return (
<>
<VariableLegend>Ad-hoc options</VariableLegend>
<Field label="Data source" htmlFor="data-source-picker">
<VariableLegend>
<Trans i18nKey="dashboard-scene.ad-hoc-variable-form.adhoc-options">Ad-hoc options</Trans>
</VariableLegend>
<Field
label={t('dashboard-scene.ad-hoc-variable-form.label-data-source', 'Data source')}
htmlFor="data-source-picker"
>
<DataSourcePicker current={datasource} onChange={onDataSourceChange} width={30} variables={true} noDefault />
</Field>
@ -58,7 +64,17 @@ export function AdHocVariableForm({
{onDefaultKeysChange && (
<>
<Field label="Use static key dimensions" description="Provide dimensions as CSV: dimensionName, dimensionId">
<Field
label={t(
'dashboard-scene.ad-hoc-variable-form.label-use-static-key-dimensions',
'Use static key dimensions'
)}
description={t(
'dashboard-scene.ad-hoc-variable-form.description-provide-dimensions-as-csv-dimension-name-dimension-id',
'Provide dimensions as CSV: {{name}}, {{value}}',
{ name: 'dimensionName', value: 'dimensionId' }
)}
>
<Switch
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.modeToggle}
value={defaultKeys !== undefined}
@ -90,7 +106,10 @@ export function AdHocVariableForm({
<VariableCheckboxField
value={allowCustomValue ?? true}
name="Allow custom values"
description="Enables users to add custom values to the list"
description={t(
'dashboard-scene.ad-hoc-variable-form.description-enables-users-custom-values',
'Enables users to add custom values to the list'
)}
onChange={onAllowCustomValueChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsAllowCustomValueSwitch}
/>

View File

@ -1,6 +1,7 @@
import { FormEvent } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Trans, t } from 'app/core/internationalization';
import { VariableLegend } from './VariableLegend';
import { VariableTextField } from './VariableTextField';
@ -13,11 +14,13 @@ interface ConstantVariableFormProps {
export function ConstantVariableForm({ onChange, constantValue }: ConstantVariableFormProps) {
return (
<>
<VariableLegend>Constant options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.constant-variable-form.constant-options">Constant options</Trans>
</VariableLegend>
<VariableTextField
defaultValue={constantValue}
name="Value"
placeholder="your metric prefix"
placeholder={t('dashboard-scene.constant-variable-form.placeholder-your-metric-prefix', 'Your metric prefix')}
onBlur={onChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.ConstantVariable.constantOptionsQueryInputV2}
width={30}

View File

@ -1,6 +1,7 @@
import { FormEvent } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Trans } from 'app/core/internationalization';
import { VariableLegend } from '../components/VariableLegend';
import { VariableTextAreaField } from '../components/VariableTextAreaField';
@ -36,18 +37,23 @@ export function CustomVariableForm({
}: CustomVariableFormProps) {
return (
<>
<VariableLegend>Custom options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.custom-variable-form.custom-options">Custom options</Trans>
</VariableLegend>
<VariableTextAreaField
name="Values separated by comma"
defaultValue={query}
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="1, 10, mykey : myvalue, myvalue, escaped\,value"
onBlur={onQueryChange}
required
width={52}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.CustomVariable.customValueInput}
/>
<VariableLegend>Selection options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.custom-variable-form.selection-options">Selection options</Trans>
</VariableLegend>
<SelectionOptionsForm
multi={multi}
includeAll={includeAll}

View File

@ -2,6 +2,7 @@ import { FormEvent } from 'react';
import { SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Trans } from 'app/core/internationalization';
import { SelectionOptionsForm } from './SelectionOptionsForm';
import { VariableLegend } from './VariableLegend';
@ -45,7 +46,9 @@ export function DataSourceVariableForm({
return (
<>
<VariableLegend>Data source options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.data-source-variable-form.data-source-options">Data source options</Trans>
</VariableLegend>
<VariableSelectField
name="Type"
value={typeValue}
@ -69,7 +72,9 @@ export function DataSourceVariableForm({
}
/>
<VariableLegend>Selection options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.data-source-variable-form.selection-options">Selection options</Trans>
</VariableLegend>
<SelectionOptionsForm
multi={multi}
includeAll={includeAll}

View File

@ -4,6 +4,7 @@ import { DataSourceInstanceSettings, MetricFindValue, readCSV } from '@grafana/d
import { selectors } from '@grafana/e2e-selectors';
import { DataSourceRef } from '@grafana/schema';
import { Alert, CodeEditor, Field, Switch } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { VariableCheckboxField } from './VariableCheckboxField';
@ -43,8 +44,13 @@ export function GroupByVariableForm({
return (
<>
<VariableLegend>Group by options</VariableLegend>
<Field label="Data source" htmlFor="data-source-picker">
<VariableLegend>
<Trans i18nKey="dashboard-scene.group-by-variable-form.group-by-options">Group by options</Trans>
</VariableLegend>
<Field
label={t('dashboard-scene.group-by-variable-form.label-data-source', 'Data source')}
htmlFor="data-source-picker"
>
<DataSourcePicker current={datasource} onChange={onDataSourceChange} width={30} variables={true} noDefault />
</Field>
@ -56,7 +62,17 @@ export function GroupByVariableForm({
/>
) : null}
<Field label="Use static Group By dimensions" description="Provide dimensions as CSV: dimensionName, dimensionId">
<Field
label={t(
'dashboard-scene.group-by-variable-form.label-use-static-group-by-dimensions',
'Use static group dimensions'
)}
description={t(
'dashboard-scene.group-by-variable-form.description-provide-dimensions-as-csv-dimension-name-dimension-id',
'Provide dimensions as CSV: {{name}}, {{value}}',
{ name: 'dimensionName', value: 'dimensionId' }
)}
>
<Switch
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle}
value={defaultOptions !== undefined}
@ -85,7 +101,10 @@ export function GroupByVariableForm({
<VariableCheckboxField
value={allowCustomValue}
name="Allow custom values"
description="Enables users to add custom values to the list"
description={t(
'dashboard-scene.group-by-variable-form.description-enables-users-custom-values',
'Enables users to add custom values to the list'
)}
onChange={onAllowCustomValueChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsAllowCustomValueSwitch}
/>

View File

@ -4,6 +4,7 @@ import { ChangeEvent, FormEvent } from 'react';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { useStyles2 } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { VariableCheckboxField } from './VariableCheckboxField';
import { VariableLegend } from './VariableLegend';
@ -41,10 +42,13 @@ export function IntervalVariableForm({
return (
<>
<VariableLegend>Interval options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.interval-variable-form.interval-options">Interval options</Trans>
</VariableLegend>
<VariableTextField
defaultValue={intervals}
name="Values"
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="1m,10m,1h,6h,1d,7d"
onBlur={onIntervalsChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.IntervalVariable.intervalsValueInput}
@ -73,7 +77,11 @@ export function IntervalVariableForm({
<VariableTextField
value={autoMinInterval}
name="Min interval"
description="The calculated value will not go below this threshold"
description={t(
'dashboard-scene.interval-variable-form.description-calculated-value-below-threshold',
'The calculated value will not go below this threshold'
)}
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="10s"
onChange={onAutoMinIntervalChanged}
width={11}

View File

@ -2,6 +2,7 @@ import { DataSourceApi, LoadingState, TimeRange } from '@grafana/data';
import { getTemplateSrv } from '@grafana/runtime';
import { QueryVariable } from '@grafana/scenes';
import { Text, Box } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { isLegacyQueryEditor, isQueryEditor } from 'app/features/variables/guard';
import { VariableQueryEditorType } from 'app/features/variables/types';
@ -37,7 +38,9 @@ export function QueryEditor({
if (VariableQueryEditor && isLegacyQueryEditor(VariableQueryEditor, datasource)) {
return (
<Box marginBottom={2}>
<Text element={'h4'}>Query</Text>
<Text element={'h4'}>
<Trans i18nKey="dashboard-scene.query-editor.query">Query</Trans>
</Text>
<Box marginTop={1}>
<VariableQueryEditor
key={datasource.uid}
@ -54,7 +57,9 @@ export function QueryEditor({
if (VariableQueryEditor && isQueryEditor(VariableQueryEditor, datasource)) {
return (
<Box marginBottom={2}>
<Text element={'h4'}>Query</Text>
<Text element={'h4'}>
<Trans i18nKey="dashboard-scene.query-editor.query">Query</Trans>
</Text>
<Box marginTop={1}>
<VariableQueryEditor
key={datasource.uid}

View File

@ -7,6 +7,7 @@ import { getDataSourceSrv } from '@grafana/runtime';
import { QueryVariable } from '@grafana/scenes';
import { DataSourceRef, VariableRefresh, VariableSort } from '@grafana/schema';
import { Field } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { QueryEditor } from 'app/features/dashboard-scene/settings/variables/components/QueryEditor';
import { SelectionOptionsForm } from 'app/features/dashboard-scene/settings/variables/components/SelectionOptionsForm';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
@ -81,8 +82,13 @@ export function QueryVariableEditorForm({
return (
<>
<VariableLegend>Query options</VariableLegend>
<Field label="Data source" htmlFor="data-source-picker">
<VariableLegend>
<Trans i18nKey="dashboard-scene.query-variable-editor-form.query-options">Query options</Trans>
</VariableLegend>
<Field
label={t('dashboard-scene.query-variable-editor-form.label-data-source', 'Data source')}
htmlFor="data-source-picker"
>
<DataSourcePicker current={datasourceRef} onChange={onDataSourceChange} variables={true} width={30} />
</Field>
@ -115,6 +121,7 @@ export function QueryVariableEditorForm({
).
</div>
}
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="/.*-(?<text>.*)-(?<value>.*)-.*/"
onBlur={onRegExChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExInputV2}
@ -133,7 +140,9 @@ export function QueryVariableEditorForm({
refresh={refresh}
/>
<VariableLegend>Selection options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.query-variable-editor-form.selection-options">Selection options</Trans>
</VariableLegend>
<SelectionOptionsForm
multi={!!isMulti}
includeAll={!!includeAll}

View File

@ -2,6 +2,7 @@ import { ChangeEvent, FormEvent } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { VariableCheckboxField } from 'app/features/dashboard-scene/settings/variables/components/VariableCheckboxField';
import { VariableTextField } from 'app/features/dashboard-scene/settings/variables/components/VariableTextField';
@ -31,7 +32,10 @@ export function SelectionOptionsForm({
<VariableCheckboxField
value={multi}
name="Multi-value"
description="Enables multiple values to be selected at the same time"
description={t(
'dashboard-scene.selection-options-form.description-enables-multiple-values-selected',
'Enables multiple values to be selected at the same time'
)}
onChange={onMultiChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsMultiSwitch}
/>
@ -39,7 +43,10 @@ export function SelectionOptionsForm({
<VariableCheckboxField
value={allowCustomValue ?? true}
name="Allow custom values"
description="Enables users to add custom values to the list"
description={t(
'dashboard-scene.selection-options-form.description-enables-users-custom-values',
'Enables users to add custom values to the list'
)}
onChange={onAllowCustomValueChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsAllowCustomValueSwitch}
/>
@ -47,7 +54,10 @@ export function SelectionOptionsForm({
<VariableCheckboxField
value={includeAll}
name="Include All option"
description="Enables an option to include all variables"
description={t(
'dashboard-scene.selection-options-form.description-enables-option-include-variables',
'Enables an option to include all variables'
)}
onChange={onIncludeAllChange}
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsIncludeAllSwitch}
/>
@ -56,7 +66,6 @@ export function SelectionOptionsForm({
defaultValue={allValue ?? ''}
onBlur={onAllValueChange}
name="Custom all value"
placeholder="blank = auto"
testId={selectors.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInput}
/>
)}

View File

@ -1,6 +1,7 @@
import { FormEvent } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Trans, t } from 'app/core/internationalization';
import { VariableLegend } from 'app/features/dashboard-scene/settings/variables/components/VariableLegend';
import { VariableTextField } from 'app/features/dashboard-scene/settings/variables/components/VariableTextField';
@ -14,12 +15,14 @@ interface TextBoxVariableFormProps {
export function TextBoxVariableForm({ defaultValue, value, onChange, onBlur }: TextBoxVariableFormProps) {
return (
<>
<VariableLegend>Text options</VariableLegend>
<VariableLegend>
<Trans i18nKey="dashboard-scene.text-box-variable-form.text-options">Text options</Trans>
</VariableLegend>
<VariableTextField
value={value}
defaultValue={defaultValue}
name="Default value"
placeholder="default value, if any"
placeholder={t('dashboard-scene.text-box-variable-form.placeholder-default-value-if-any', '(optional)')}
onChange={onChange}
onBlur={onBlur}
width={30}

View File

@ -2,6 +2,7 @@ import { PropsWithChildren, useMemo } from 'react';
import { VariableType, VariableHide } from '@grafana/data';
import { Field, RadioButtonGroup } from '@grafana/ui';
import { t } from 'app/core/internationalization';
interface Props {
onChange: (option: VariableHide) => void;
@ -23,7 +24,7 @@ export function VariableHideSelect({ onChange, hide, type }: PropsWithChildren<P
}
return (
<Field label="Show on dashboard">
<Field label={t('dashboard-scene.variable-hide-select.label-show-on-dashboard', 'Show on dashboard')}>
<RadioButtonGroup options={HIDE_OPTIONS} onChange={onChange} value={value} />
</Field>
);

View File

@ -5,6 +5,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { VariableValueOption } from '@grafana/scenes';
import { Button, InlineFieldRow, InlineLabel, useStyles2 } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
export interface VariableValuesPreviewProps {
options: VariableValueOption[];
@ -29,7 +30,9 @@ export const VariableValuesPreview = ({ options }: VariableValuesPreviewProps) =
return (
<div style={{ display: 'flex', flexDirection: 'column', marginTop: '16px' }}>
<h5>Preview of values</h5>
<h5>
<Trans i18nKey="dashboard-scene.variable-values-preview.preview-of-values">Preview of values</Trans>
</h5>
<InlineFieldRow>
{previewOptions.map((o, index) => (
<InlineFieldRow key={`${o.value}-${index}`} className={styles.optionContainer}>
@ -41,13 +44,8 @@ export const VariableValuesPreview = ({ options }: VariableValuesPreviewProps) =
</InlineFieldRow>
{options.length > previewLimit && (
<InlineFieldRow className={styles.optionContainer}>
<Button
onClick={showMoreOptions}
variant="secondary"
size="sm"
aria-label="Variable editor Preview of Values Show More link"
>
Show more
<Button onClick={showMoreOptions} variant="secondary" size="sm">
<Trans i18nKey="dashboard-scene.variable-values-preview.show-more">Show more</Trans>
</Button>
</InlineFieldRow>
)}

View File

@ -1,5 +1,6 @@
import { ConfirmModal } from '@grafana/ui';
import { useAppNotification } from 'app/core/copy/appNotification';
import { t } from 'app/core/internationalization';
import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
import { DecoratedRevisionModel } from '../VersionsEditView';
@ -29,7 +30,7 @@ export const RevertDashboardModal = ({ hideModal, onRestore, version }: RevertDa
return (
<ConfirmModal
isOpen={true}
title="Restore Version"
title={t('dashboard-scene.revert-dashboard-modal.title-restore-version', 'Restore version')}
icon="history"
onDismiss={hideModal}
onConfirm={onRestoreDashboard}

View File

@ -1,4 +1,5 @@
import { Tooltip, Button, Stack } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
type VersionsButtonsType = {
@ -26,12 +27,12 @@ export const VersionsHistoryButtons = ({
variant="secondary"
disabled={isLastPage}
>
Show more versions
<Trans i18nKey="dashboard-scene.versions-history-buttons.show-more-versions">Show more versions</Trans>
</Button>
)}
<Tooltip content="Select two versions to start comparing" placement="bottom">
<Button type="button" disabled={!canCompare} onClick={getDiff} icon="code-branch">
Compare versions
<Trans i18nKey="dashboard-scene.versions-history-buttons.compare-versions">Compare versions</Trans>
</Button>
</Tooltip>
</Stack>

View File

@ -2,6 +2,7 @@ import { css, cx } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
import { Button, ModalsController, CollapsableSection, useStyles2, Stack, Icon, Box } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { DecoratedRevisionModel } from '../VersionsEditView';
@ -62,7 +63,10 @@ export const VersionHistoryComparison = ({ baseInfo, newInfo, diffData, isNewLat
))}
<Box paddingTop={2}>
<CollapsableSection isOpen={false} label="View JSON Diff">
<CollapsableSection
isOpen={false}
label={t('dashboard-scene.version-history-comparison.label-view-json-diff', 'View JSON diff')}
>
<DiffViewer
oldValue={JSON.stringify(diffData.lhs, null, 2)}
newValue={JSON.stringify(diffData.rhs, null, 2)}

View File

@ -3,6 +3,7 @@ import { noop } from 'lodash';
import { GrafanaTheme2 } from '@grafana/data';
import { Icon, IconButton, useStyles2 } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
type VersionHistoryHeaderProps = {
onClick?: () => void;
@ -21,10 +22,19 @@ export const VersionHistoryHeader = ({
return (
<h3 className={styles.header}>
<IconButton name="arrow-left" size="xl" onClick={onClick} tooltip="Reset version" />
<IconButton
name="arrow-left"
size="xl"
onClick={onClick}
tooltip={t('dashboard-scene.version-history-header.tooltip-reset-version', 'Reset version')}
/>
<span>
Comparing {baseVersion} <Icon name="arrows-h" /> {newVersion}{' '}
{isNewLatest && <cite className="muted">(Latest)</cite>}
{isNewLatest && (
<cite className="muted">
<Trans i18nKey="dashboard-scene.version-history-header.latest">(Latest)</Trans>
</cite>
)}
</span>
</h3>
);

View File

@ -3,6 +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 { DashboardInteractions } from 'app/features/dashboard-scene/utils/interactions';
import { DecoratedRevisionModel } from '../VersionsEditView';
@ -25,10 +26,18 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck, onRestore }
<thead>
<tr>
<th className="width-4"></th>
<th className="width-4">Version</th>
<th className="width-14">Date</th>
<th className="width-10">Updated by</th>
<th>Notes</th>
<th className="width-4">
<Trans i18nKey="dashboard-scene.version-history-table.version">Version</Trans>
</th>
<th className="width-14">
<Trans i18nKey="dashboard-scene.version-history-table.date">Date</Trans>
</th>
<th className="width-10">
<Trans i18nKey="dashboard-scene.version-history-table.updated-by">Updated by</Trans>
</th>
<th>
<Trans i18nKey="dashboard-scene.version-history-table.notes">Notes</Trans>
</th>
<th></th>
</tr>
</thead>
@ -74,7 +83,7 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck, onRestore }
});
}}
>
Restore
<Trans i18nKey="dashboard-scene.version-history-table.restore">Restore</Trans>
</Button>
)}
</ModalsController>

View File

@ -47,7 +47,7 @@ export default function ShareButton({ dashboard, panel }: { dashboard: Dashboard
</Button>
<Dropdown overlay={MenuActions} placement="bottom-end" onVisibleChange={onMenuClick}>
<Button
aria-label="share-dropdown-menu"
aria-label={t('dashboard-scene.share-button.aria-label-sharedropdownmenu', 'Toggle share menu')}
data-testid={newShareButtonSelector.arrowMenu}
size="sm"
icon={isOpen ? 'angle-up' : 'angle-down'}

View File

@ -77,7 +77,12 @@ const EmailList = ({
/>
}
>
<IconButton name="ellipsis-v" aria-label="email-menu" variant="secondary" size="lg" />
<IconButton
name="ellipsis-v"
aria-label={t('dashboard-scene.email-list.aria-label-emailmenu', 'Toggle email menu')}
variant="secondary"
size="lg"
/>
</Dropdown>
</td>
</tr>

View File

@ -2,6 +2,7 @@ import { useMemo } from 'react';
import { reportInteraction } from '@grafana/runtime';
import { IconButton } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { NetworkGraphModal } from 'app/features/variables/inspect/NetworkGraphModal';
import { UsagesToNetwork } from './utils';
@ -38,7 +39,7 @@ export const VariableUsagesButton = ({ id, usages, isAdhoc }: Props) => {
showModal();
}}
name="code-branch"
tooltip="Show usages"
tooltip={t('dashboard-scene.variable-usages-button.tooltip-show-usages', 'Show usages')}
/>
);
}}

View File

@ -1849,6 +1849,45 @@
}
},
"dashboard-scene": {
"ad-hoc-variable-form": {
"adhoc-options": "Ad-hoc options",
"description-enables-users-custom-values": "Enables users to add custom values to the list",
"description-provide-dimensions-as-csv-dimension-name-dimension-id": "Provide dimensions as CSV: {{name}}, {{value}}",
"label-data-source": "Data source",
"label-use-static-key-dimensions": "Use static key dimensions"
},
"add-to-dashboard-form": {
"cancel": "Cancel",
"description-choose-where-to-add-the-panel": "Choose where to add the panel.",
"description-select-which-dashboard-panel-created": "Select in which dashboard the panel will be created.",
"label-dashboard": "Dashboard",
"label-target-dashboard": "Target dashboard",
"open-dashboard": "Open dashboard",
"open-in-new-tab": "Open in new tab",
"title-error-adding-the-panel": "Error adding the panel"
},
"annotation-settings-edit": {
"back-to-list": "Back to list",
"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",
"label-color": "Color",
"label-data-source": "Data source",
"label-enabled": "Enabled",
"label-hidden": "Hidden",
"label-name": "Name",
"label-show-in": "Show in",
"placeholder-choose-panels": "Choose panels",
"query": "Query",
"title-annotation-support-source": "No annotation support for this data source"
},
"annotation-settings-list": {
"data-source": "Data source",
"new-query": "New query",
"query-name": "Query name",
"tooltip-move-down": "Move down",
"tooltip-move-up": "Move up"
},
"branch-validation-error": {
"cannot-contain-invalid-characters": "It cannot contain invalid characters: '~', '^', ':', '?', '*', '[', '\\\\', or ']'.",
"cannot-start-with": "It cannot start with '/' or end with '/', '.', or whitespace.",
@ -1856,6 +1895,43 @@
"it-cannot-contain-or": "It cannot contain '//' or '..'.",
"least-valid-character": "It must have at least one valid character."
},
"constant-variable-form": {
"constant-options": "Constant options",
"placeholder-your-metric-prefix": "Your metric prefix"
},
"custom-variable-form": {
"custom-options": "Custom options",
"selection-options": "Selection options"
},
"dashboard-add-pane": {
"aria-label-close-add-pane": "Close add pane"
},
"dashboard-edit-pane-renderer": {
"outline": "Outline"
},
"dashboard-link-form": {
"back-to-list": "Back to list",
"label-icon": "Icon",
"label-include-current-template-variable-values": "Include current template variable values",
"label-include-current-time-range": "Include current time range",
"label-open-link-in-new-tab": "Open link in new tab",
"label-options": "Options",
"label-show-as-dropdown": "Show as dropdown",
"label-title": "Title",
"label-tooltip": "Tooltip",
"label-type": "Type",
"label-url": "URL",
"label-with-tags": "With tags",
"placeholder-open-dashboard": "Open dashboard"
},
"dashboard-link-list": {
"info": "Info",
"new-link": "New link",
"tooltip-copy-link": "Copy link",
"tooltip-move-link-down": "Move link down",
"tooltip-move-link-up": "Move link up",
"type": "Type"
},
"dashboard-preview-banner": {
"not-saved": "The value is not yet saved in the Grafana database",
"not-yet-saved": "The value is not saved in the Grafana database",
@ -1867,17 +1943,160 @@
"value-not-saved": "The value is not yet saved in the Grafana database",
"view-pull-request-in-git-hub": "View pull request in GitHub"
},
"data-source-variable-form": {
"data-source-options": "Data source options",
"selection-options": "Selection options"
},
"description-label": {
"description": "Description"
},
"email-list": {
"aria-label-emailmenu": "Toggle email menu"
},
"empty-transformations-message": {
"add-transformation": "Add transformation"
},
"group-by-variable-form": {
"description-enables-users-custom-values": "Enables users to add custom values to the list",
"description-provide-dimensions-as-csv-dimension-name-dimension-id": "Provide dimensions as CSV: {{name}}, {{value}}",
"group-by-options": "Group by options",
"label-data-source": "Data source",
"label-use-static-group-by-dimensions": "Use static group dimensions"
},
"help-wizard": {
"copy-to-clipboard": "Copy to clipboard",
"label-randomize-data": "Randomize 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-get-help-with-this-panel": "Get help with this panel"
},
"inspect-data-tab": {
"no-data-found": "No data found"
},
"inspect-json-tab": {
"apply": "Apply"
},
"interval-variable-form": {
"description-calculated-value-below-threshold": "The calculated value will not go below this threshold",
"interval-options": "Interval options"
},
"json-model-edit-view": {
"cancel-button": {
"cancel": "Cancel"
},
"render-save-button-and-error": {
"title-failed-to-save-dashboard": "Failed to save dashboard",
"title-plugin-dashboard": "Plugin dashboard",
"title-someone-else-has-updated-this-dashboard": "Someone else has updated this dashboard",
"would-still-dashboard": "Would you still like to save this dashboard?"
}
},
"name-already-exists-error": {
"title-name-already-exists": "Name already exists"
},
"panel-data-alerting-tab-rendered": {
"alert": {
"title-errors-loading-rules": "Errors loading rules"
},
"text-loading-rules": "Loading rules...",
"title-dashboard-not-saved": "Dashboard not saved"
},
"panel-data-queries-tab-rendered": {
"add-query": "Add query"
},
"panel-data-transformations-tab-rendered": {
"add-another-transformation": "Add another transformation",
"delete-all-transformations": "Delete all transformations",
"title-delete-all-transformations": "Delete all transformations?"
},
"panel-edit-controls": {
"table-view-aria-label-toggletableview": "Toggle table view",
"table-view-label-table-view": "Table view"
},
"panel-inspect-renderer": {
"title-panel-plugin-not-loaded": "Panel plugin not loaded"
},
"panel-options-pane": {
"placeholder-search-options": "Search options"
},
"panel-viz-type-picker": {
"placeholder-search-for": "Search for...",
"title-close": "Close"
},
"provisioned-delete-modal": {
"ok": "OK",
"title-cannot-delete-provisioned-dashboard": "Cannot delete provisioned dashboard"
},
"provisioned-resource-delete-modal": {
"file-path": "File path:",
"managed-by-version-control": "This {type} is managed by version control and cannot be deleted. To remove it, delete it from the repository and synchronise to apply the changes.",
"ok": "OK",
"title-cannot-delete-provisioned-resource": "Cannot delete provisioned resource"
},
"query-editor": {
"query": "Query"
},
"query-variable-editor-form": {
"label-data-source": "Data source",
"query-options": "Query options",
"selection-options": "Selection options"
},
"revert-dashboard-modal": {
"title-restore-version": "Restore version"
},
"save-dashboard-as-form": {
"aria-label-save-dashboard-description-field": "Save dashboard description field",
"aria-label-save-dashboard-title-field": "Save dashboard title field",
"cancel-button": {
"cancel": "Cancel"
},
"label-copy-tags": "Copy tags",
"label-folder": "Folder",
"render-footer": {
"title-failed-to-save-dashboard": "Failed to save dashboard"
}
},
"save-dashboard-form": {
"aria-label-message": "message",
"cancel-button": {
"cancel": "Cancel"
},
"label-message": "Message",
"placeholder-describe-changes-optional": "Add a note to describe your changes (optional).",
"render-footer": {
"no-changes-to-save": "No changes to save",
"title-failed-to-save-dashboard": "Failed to save dashboard",
"title-plugin-dashboard": "Plugin dashboard",
"title-someone-else-has-updated-this-dashboard": "Someone else has updated this dashboard",
"would-still-dashboard": "Would you still like to save this dashboard?"
},
"title-dashboard-drastically-changed": "Dashboard drastically changed"
},
"save-dashboard-form-common-options": {
"save-refresh-description-current-refresh-default": "Will make the current refresh the new default",
"save-refresh-label-update-default-refresh-value": "Update default refresh value",
"save-timerange-label-update-default-time-range": "Update default time range",
"save-variables-description-current-values-default": "Will make the current values the new default",
"save-variables-label-update-default-variable-values": "Update default variable values"
},
"save-library-viz-panel-modal": {
"cancel": "Cancel",
"dashboard-name": "Dashboard name",
"discard": "Discard",
"loading-connected-dashboards": "Loading connected dashboards...",
"placeholder-search-affected-dashboards": "Search affected dashboards",
"update-all": "Update all"
},
"save-provisioned-dashboard-form": {
"api-error": "Error saving dashboard",
"api-success": "Dashboard changes saved",
"cancel": "Cancel",
"copy-json-message": "If you have direct access to the target, copy the JSON and paste it there.",
"copy-json-to-clipboard": "Copy JSON to clipboard",
"dashboard-comment-placeholder-describe-changes-optional": "Add a note to describe your changes (optional)",
"description-branch-name-in-git-hub": "Branch name in GitHub",
"description-inside-repository": "File path inside the repository (.json or .yaml)",
@ -1889,11 +2108,107 @@
"label-title": "Title",
"label-workflow": "Workflow",
"save": "Save",
"save-json-to-file": "Save JSON to file",
"saving": "Saving...",
"title-required": "Dashboard title is required",
"title-same-as-folder": "Dashboard name cannot be the same as the folder name",
"title-this-repository-is-read-only": "This repository is read only",
"title-validation-failed": "Dashboard title validation failed."
},
"scenes-new-rule-from-panel-button": {
"new-alert-rule": "New alert rule",
"title-no-alerting-capable-query-found": "No alerting capable query found"
},
"selection-options-form": {
"description-enables-multiple-values-selected": "Enables multiple values to be selected at the same time",
"description-enables-option-include-variables": "Enables an option to include all variables",
"description-enables-users-custom-values": "Enables users to add custom values to the list"
},
"share-button": {
"aria-label-sharedropdownmenu": "Toggle share menu"
},
"text-box-variable-form": {
"placeholder-default-value-if-any": "(optional)",
"text-options": "Text options"
},
"title-field-label": {
"title": "Title"
},
"transformations-drawer": {
"search-box-suffix": {
"tooltip-clear-search": "Clear search"
}
},
"unlink-modal": {
"title-really-unlink-panel": "Do you really want to unlink this panel?"
},
"unsaved-changes-modal": {
"cancel": "Cancel",
"changes": "Do you want to save your changes?",
"discard": "Discard",
"save-dashboard": "Save dashboard",
"title-unsaved-changes": "Unsaved changes"
},
"variable-check-indicator": {
"aria-label-variable-referenced-dashboard": "This variable is not referenced by any variable or dashboard.",
"aria-label-variable-referenced-other-variables-dashboard": "This variable is referenced by other variables or dashboard."
},
"variable-editor-form": {
"aria-label-variable-editor-form": "Variable editor form",
"back-to-list": "Back to list",
"delete": "Delete",
"description-optional-display-name": "Optional display name",
"description-template-variable-characters": "The name of the template variable. (Max. 50 characters)",
"general": "General",
"placeholder-descriptive-text": "Descriptive text",
"placeholder-label-name": "Label name",
"placeholder-variable-name": "Variable name",
"text-running-query": "Running query..."
},
"variable-editor-list": {
"definition": "Definition",
"new-variable": "New variable",
"variable": "Variable"
},
"variable-editor-list-row": {
"title-delete-variable": "Delete variable",
"tooltip-duplicate-variable": "Duplicate variable",
"tooltip-remove-variable": "Remove variable"
},
"variable-hide-select": {
"label-show-on-dashboard": "Show on dashboard"
},
"variable-usages-button": {
"tooltip-show-usages": "Show usages"
},
"variable-values-preview": {
"preview-of-values": "Preview of values",
"show-more": "Show more"
},
"version-history-comparison": {
"label-view-json-diff": "View JSON diff"
},
"version-history-header": {
"latest": "(Latest)",
"tooltip-reset-version": "Reset version"
},
"version-history-table": {
"date": "Date",
"notes": "Notes",
"restore": "Restore",
"updated-by": "Updated by",
"version": "Version"
},
"versions-history-buttons": {
"compare-versions": "Compare versions",
"show-more-versions": "Show more versions"
},
"visualization-button": {
"aria-label-change-visualization": "Change visualization",
"tooltip-click-to-change-visualization": "Click to change visualization"
},
"viz-panel-links-renderer": {
"aria-label-panel-links": "Panel links"
}
},
"dashboard-settings": {