Internationalisation: Auto markup some translations (#102389)

* auto markup admin

* more automarkup

* betterer results
This commit is contained in:
Ashley Harrison
2025-03-19 13:49:17 +00:00
committed by GitHub
parent ebeef2064e
commit 24391a0277
38 changed files with 531 additions and 317 deletions
+17 -193
View File
@@ -1134,127 +1134,25 @@ exports[`better eslint`] = {
[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/admin/AdminEditOrgPage.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/admin/AdminFeatureTogglesTable.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/admin/AdminOrgsTable.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/admin/OrgRolePicker.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/admin/UpgradePage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings 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 in text props. Wrap text with <Trans /> or use t()", "13"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "14"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "15"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "16"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "17"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "18"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "19"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "20"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "21"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "22"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "23"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "24"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "25"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "26"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "27"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "28"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "29"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "30"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "31"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "32"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "33"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "34"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "35"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "36"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "37"]
],
"public/app/features/admin/UserCreatePage.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/admin/UserLdapSyncInfo.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/admin/UserListAdminPage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/admin/UserListAnonymousPage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/admin/UserListPage.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/admin/UserOrgs.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/admin/UserProfile.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"]
],
"public/app/features/admin/UserSessions.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 />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
],
"public/app/features/admin/Users/OrgUsersTable.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()", "0"]
],
"public/app/features/admin/Users/UsersTable.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/admin/ldap/LdapConnectionStatus.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/admin/ldap/LdapDrawer.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/admin/ldap/LdapPage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/admin/ldap/LdapSettingsPage.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"]
],
"public/app/features/alerting/routes.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
@@ -2710,15 +2608,6 @@ exports[`better eslint`] = {
"public/app/features/browse-dashboards/api/browseDashboardsAPI.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`@reduxjs/toolkit/query/react\`)", "0"]
],
"public/app/features/browse-dashboards/components/BrowseActions/DescendantCount.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/browse-dashboards/components/BrowseView.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/browse-dashboards/components/NameCell.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/browse-dashboards/state/index.ts:5381": [
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"],
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "1"],
@@ -4604,39 +4493,17 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "9"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"]
],
"public/app/features/library-panels/components/AddLibraryPanelModal/AddLibraryPanelModal.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/library-panels/components/DeleteLibraryPanelModal/DeleteLibraryPanelModal.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"]
],
"public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.tsx:5381": [
[0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"]
[0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
"public/app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup.tsx:5381": [
[0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
[0, 0, 0, "\'VerticalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"]
],
"public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "4"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "6"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/live/LiveConnectionWarning.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
@@ -4785,29 +4652,13 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
],
"public/app/features/org/NewOrgPage.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"]
],
"public/app/features/org/OrgProfile.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "2"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/org/SelectOrgPage.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/org/UserInviteForm.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 />", "8"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/org/UserInvitePage.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
@@ -4862,16 +4713,7 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "3"]
],
"public/app/features/playlist/StartModal.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. Wrap text with <Trans />", "9"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
],
"public/app/features/plugins/admin/__mocks__/index.ts:5381": [
[0, 0, 0, "Do not re-export imported variable (\`./localPlugin.mock\`)", "0"],
@@ -5356,11 +5198,7 @@ exports[`better eslint`] = {
],
"public/app/features/teams/CreateTeam.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 in text props. Wrap text with <Trans /> or use t()", "1"]
],
"public/app/features/teams/TeamGroupSync.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],
@@ -5368,31 +5206,17 @@ exports[`better eslint`] = {
[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. 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 />", "8"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "9"],
[0, 0, 0, "Unexpected any. Specify a different type.", "10"],
[0, 0, 0, "Unexpected any. Specify a different type.", "11"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"],
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"]
],
"public/app/features/teams/TeamList.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 in text props. Wrap text with <Trans /> or use t()", "2"]
],
"public/app/features/teams/TeamSettings.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 in text props. Wrap text with <Trans /> or use t()", "0"]
],
"public/app/features/teams/state/reducers.ts:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
+11 -3
View File
@@ -7,7 +7,7 @@ import { NavModelItem } from '@grafana/data';
import { Field, Input, Button, Legend, Alert } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { OrgUser, AccessControlAction, OrgRole } from 'app/types';
import { OrgUsersTable } from './Users/OrgUsersTable';
@@ -56,7 +56,10 @@ const AdminEditOrgPage = () => {
};
const renderMissingPermissionMessage = () => (
<Alert severity="info" title="Access denied">
<Alert
severity="info"
title={t('admin.admin-edit-org-page.render-missing-permission-message.title-access-denied', 'Access denied')}
>
<Trans i18nKey="admin.edit-org.access-denied">
You do not have permission to see users in this organization. To update this organization, contact your server
administrator.
@@ -93,7 +96,12 @@ const AdminEditOrgPage = () => {
</Legend>
{orgState.value && (
<form onSubmit={handleSubmit(onUpdateOrgName)} style={{ maxWidth: '600px' }}>
<Field label="Name" invalid={!!errors.orgName} error="Name is required" disabled={!canWriteOrg}>
<Field
label={t('admin.admin-edit-org-page.label-name', 'Name')}
invalid={!!errors.orgName}
error="Name is required"
disabled={!canWriteOrg}
>
<Input
{...register('orgName', { required: true })}
id="org-name-input"
@@ -1,6 +1,7 @@
import { useState, useRef } from 'react';
import { Switch, InteractiveTable, Tooltip, type CellProps, Button, ConfirmModal, type SortByFn } from '@grafana/ui';
import { Trans, t } from 'app/core/internationalization';
import { FeatureToggle, getTogglesAPI } from './AdminFeatureTogglesAPI';
@@ -91,15 +92,17 @@ export function AdminFeatureTogglesTable({ featureToggles, allowEditing, onUpdat
case 'GA':
return (
<Tooltip content={'General availability'}>
<div>GA</div>
<div>
<Trans i18nKey="admin.admin-feature-toggles-table.get-stage-cell.ga">GA</Trans>
</div>
</Tooltip>
);
case 'privatePreview':
case 'preview':
case 'experimental':
return 'Beta';
return t('admin.admin-feature-toggles-table.get-stage-cell.beta', 'Beta');
case 'deprecated':
return 'Deprecated';
return t('admin.admin-feature-toggles-table.get-stage-cell.deprecated', 'Deprecated');
default:
return stage;
}
@@ -156,7 +159,10 @@ export function AdminFeatureTogglesTable({ featureToggles, allowEditing, onUpdat
</Button>
<ConfirmModal
isOpen={showSaveModel}
title="Apply feature toggle changes"
title={t(
'admin.admin-feature-toggles-table.title-apply-feature-toggle-changes',
'Apply feature toggle changes'
)}
body={
<div>
<p>
+3 -3
View File
@@ -6,7 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { Button, ConfirmModal, useStyles2 } from '@grafana/ui';
import { SkeletonComponent, attachSkeleton } from '@grafana/ui/unstable';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { AccessControlAction, Organization } from 'app/types';
interface Props {
@@ -51,7 +51,7 @@ function AdminOrgsTableComponent({ orgs, onDelete }: Props) {
size="sm"
icon="times"
onClick={() => setDeleteOrg(org)}
aria-label="Delete org"
aria-label={t('admin.admin-orgs-table.aria-label-delete-org', 'Delete org')}
disabled={!canDeleteOrgs}
/>
</td>
@@ -62,7 +62,7 @@ function AdminOrgsTableComponent({ orgs, onDelete }: Props) {
<ConfirmModal
isOpen
icon="trash-alt"
title="Delete"
title={t('admin.admin-orgs-table.title-delete', 'Delete')}
body={
<div>
<Trans i18nKey="admin.orgs.delete-body">
+2 -1
View File
@@ -1,5 +1,6 @@
import { OrgRole } from '@grafana/data';
import { Select } from '@grafana/ui';
import { t } from 'app/core/internationalization';
interface Props {
value: OrgRole;
@@ -21,7 +22,7 @@ export function OrgRolePicker({ value, onChange, 'aria-label': ariaLabel, inputI
value={value}
options={options}
onChange={(val) => onChange(val.value ?? OrgRole.None)}
placeholder="Choose role..."
placeholder={t('admin.org-role-picker.placeholder-choose-role', 'Choose role...')}
aria-label={ariaLabel}
autoFocus={autoFocus}
{...restProps}
+36 -18
View File
@@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import { GrafanaTheme2, NavModel } from '@grafana/data';
import { LinkButton, 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 { getNavModel } from '../../core/selectors/navModel';
import { StoreState } from '../../types';
@@ -110,9 +110,18 @@ const ServiceInfo = () => {
</h4>
<List>
<Item title="Enterprise Plugins" image="public/img/licensing/plugin_enterprise.svg" />
<Item title="Critical SLA: 2 hours" image="public/img/licensing/sla.svg" />
<Item title="Unlimited Expert Support" image="public/img/licensing/customer_support.svg">
<Item
title={t('admin.service-info.title-enterprise-plugins', 'Enterprise Plugins')}
image="public/img/licensing/plugin_enterprise.svg"
/>
<Item
title={t('admin.service-info.title-critical-sla-hours', 'Critical SLA: 2 hours')}
image="public/img/licensing/sla.svg"
/>
<Item
title={t('admin.service-info.title-unlimited-expert-support', 'Unlimited Expert Support')}
image="public/img/licensing/customer_support.svg"
>
24 x 7 x 365 support via
<List nested={true}>
<Item title="Email" />
@@ -154,26 +163,34 @@ const FeatureInfo = () => {
const FeatureListing = () => {
return (
<List>
<Item title="Data source permissions" />
<Item title="Reporting" />
<Item title="SAML authentication" />
<Item title="Enhanced LDAP integration" />
<Item title="Team Sync">
<Item title={t('admin.feature-listing.title-data-source-permissions', 'Data source permissions')} />
<Item title={t('admin.feature-listing.title-reporting', 'Reporting')} />
<Item title={t('admin.feature-listing.title-saml-authentication', 'SAML authentication')} />
<Item title={t('admin.feature-listing.title-enhanced-ldap-integration', 'Enhanced LDAP integration')} />
<Item title={t('admin.feature-listing.title-team-sync', 'Team Sync')}>
<Trans i18nKey="admin.get-enterprise.team-sync-details">LDAP, GitHub OAuth, Auth Proxy, Okta</Trans>
</Item>
<Item title="White labeling" />
<Item title="Auditing" />
<Item title="Settings updates at runtime" />
<Item title="Grafana usage insights">
<Item title={t('admin.feature-listing.title-white-labeling', 'White labeling')} />
<Item title={t('admin.feature-listing.title-auditing', 'Auditing')} />
<Item title={t('admin.feature-listing.title-settings-updates-at-runtime', 'Settings updates at runtime')} />
<Item title={t('admin.feature-listing.title-grafana-usage-insights', 'Grafana usage insights')}>
<List nested={true}>
<Item title="Sort dashboards by popularity in search" />
<Item title="Find unused dashboards" />
<Item title="Dashboard usage stats drawer" />
<Item title="Dashboard presence indicators" />
<Item
title={t(
'admin.feature-listing.title-sort-dashboards-by-popularity-in-search',
'Sort dashboards by popularity in search'
)}
/>
<Item title={t('admin.feature-listing.title-find-unused-dashboards', 'Find unused dashboards')} />
<Item title={t('admin.feature-listing.title-dashboard-usage-stats-drawer', 'Dashboard usage stats drawer')} />
<Item
title={t('admin.feature-listing.title-dashboard-presence-indicators', 'Dashboard presence indicators')}
/>
</List>
</Item>
<Item title="Enterprise plugins">
<Item title={t('admin.feature-listing.title-enterprise-plugins', 'Enterprise plugins')}>
<List nested={true}>
{/* eslint-disable @grafana/no-untranslated-strings */}
<Item title="Oracle" />
<Item title="Splunk" />
<Item title="Service Now" />
@@ -189,6 +206,7 @@ const FeatureListing = () => {
<Item title="Salesforce" />
<Item title="Snowflake" />
<Item title="Wavefront" />
{/* eslint-enable @grafana/no-untranslated-strings */}
</List>
</Item>
</List>
+10 -5
View File
@@ -6,7 +6,7 @@ import { NavModelItem } from '@grafana/data';
import { getBackendSrv } from '@grafana/runtime';
import { Button, Input, Field } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
interface UserDTO {
name: string;
@@ -45,19 +45,24 @@ const UserCreatePage = () => {
<Page navId="global-users" pageNav={pageNav}>
<Page.Contents>
<form onSubmit={handleSubmit(onSubmit)} style={{ maxWidth: '600px' }}>
<Field label="Name" required invalid={!!errors.name} error={errors.name ? 'Name is required' : undefined}>
<Field
label={t('admin.user-create-page.label-name', 'Name')}
required
invalid={!!errors.name}
error={errors.name ? 'Name is required' : undefined}
>
<Input id="name-input" {...register('name', { required: true })} />
</Field>
<Field label="Email">
<Field label={t('admin.user-create-page.label-email', 'Email')}>
<Input id="email-input" {...register('email')} />
</Field>
<Field label="Username">
<Field label={t('admin.user-create-page.label-username', 'Username')}>
<Input id="username-input" {...register('login')} />
</Field>
<Field
label="Password"
label={t('admin.user-create-page.label-password', 'Password')}
required
invalid={!!errors.password}
error={errors.password ? 'Password is required and must contain at least 4 characters' : undefined}
@@ -3,7 +3,7 @@ import { PureComponent } from 'react';
import { dateTimeFormat } from '@grafana/data';
import { Button, LinkButton } from '@grafana/ui';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { AccessControlAction, SyncInfo, UserDTO } from 'app/types';
import { TagBadge } from '../../core/components/TagFilter/TagBadge';
@@ -51,7 +51,12 @@ export class UserLdapSyncInfo extends PureComponent<Props, State> {
</Trans>
</td>
<td>
<TagBadge label="LDAP" removeIcon={false} count={0} onClick={undefined} />
<TagBadge
label={t('admin.user-ldap-sync-info.label-ldap', 'LDAP')}
removeIcon={false}
count={0}
onClick={undefined}
/>
</td>
</tr>
<tr>
@@ -75,7 +75,10 @@ const UserListAdminPageUnConnected = ({
<div className={styles.actionBar} data-testid={selectors.container}>
<div className={styles.row}>
<FilterInput
placeholder="Search user by login, email, or name."
placeholder={t(
'admin.user-list-admin-page-un-connected.placeholder-search-login-email',
'Search user by login, email, or name.'
)}
autoFocus={true}
value={query}
onChange={changeQuery}
@@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
import { RadioButtonGroup, useStyles2, FilterInput } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { t } from 'app/core/internationalization';
import { StoreState } from '../../types';
@@ -59,7 +60,10 @@ const UserListAnonymousDevicesPageUnConnected = ({
<div className={styles.actionBar} data-testid={selectors.container}>
<div className={styles.row}>
<FilterInput
placeholder="Search devices by IP address."
placeholder={t(
'admin.user-list-anonymous-devices-page-un-connected.placeholder-search-devices-by-ip-address',
'Search devices by IP address.'
)}
autoFocus={true}
value={query}
onChange={changeAnonQuery}
+4 -4
View File
@@ -69,20 +69,20 @@ export default function UserListPage() {
{showAdminAndOrgTabs ? (
<TabsBar className={styles.tabsMargin}>
<Tab
label="All users"
label={t('admin.user-list-page.label-all-users', 'All users')}
active={view === TabView.ADMIN}
onChangeTab={() => setView(TabView.ADMIN)}
data-testid={selectors.tabs.allUsers}
/>
<Tab
label="Organization users"
label={t('admin.user-list-page.label-organization-users', 'Organization users')}
active={view === TabView.ORG}
onChangeTab={() => setView(TabView.ORG)}
data-testid={selectors.tabs.orgUsers}
/>
{config.anonymousEnabled && (
<Tab
label="Anonymous devices"
label={t('admin.user-list-page.label-anonymous-devices', 'Anonymous devices')}
active={view === TabView.ANON}
onChangeTab={() => setView(TabView.ANON)}
data-testid={selectors.tabs.anonUserDevices}
@@ -94,7 +94,7 @@ export default function UserListPage() {
isEmailSharingEnabled() && (
<TabsBar className={styles.tabsMargin}>
<Tab
label="Users"
label={t('admin.user-list-page.label-users', 'Users')}
active={view === TabView.ORG}
onChangeTab={() => setView(TabView.ORG)}
data-testid={selectors.tabs.users}
+3 -3
View File
@@ -363,14 +363,14 @@ export class AddToOrgModal extends PureComponent<AddToOrgModalProps, AddToOrgMod
<Modal
className={styles.modal}
contentClassName={styles.modalContent}
title="Add to an organization"
title={t('admin.add-to-org-modal.title-add-to-an-organization', 'Add to an organization')}
isOpen={isOpen}
onDismiss={this.onCancel}
>
<Field label="Organization">
<Field label={t('admin.add-to-org-modal.label-organization', 'Organization')}>
<OrgPicker inputId="new-org-input" onSelected={this.onOrgSelect} excludeOrgs={userOrgs} autoFocus />
</Field>
<Field label="Role" disabled={selectedOrg === null}>
<Field label={t('admin.add-to-org-modal.label-role', 'Role')} disabled={selectedOrg === null}>
<UserRolePicker
userId={user?.id || 0}
orgId={selectedOrg?.id}
+11 -7
View File
@@ -90,30 +90,34 @@ export function UserProfile({
<div>
<table className="filter-table form-inline">
<tbody>
<UserProfileRow label="Numerical identifier" value={user.id.toString()} locked={true} />
<UserProfileRow
label="Name"
label={t('admin.user-profile.label-numerical-identifier', 'Numerical identifier')}
value={user.id.toString()}
locked={true}
/>
<UserProfileRow
label={t('admin.user-profile.label-name', 'Name')}
value={user.name}
locked={editLocked}
lockMessage={lockMessage}
onChange={onUserNameChange}
/>
<UserProfileRow
label="Email"
label={t('admin.user-profile.label-email', 'Email')}
value={user.email}
locked={editLocked}
lockMessage={lockMessage}
onChange={onUserEmailChange}
/>
<UserProfileRow
label="Username"
label={t('admin.user-profile.label-username', 'Username')}
value={user.login}
locked={editLocked}
lockMessage={lockMessage}
onChange={onUserLoginChange}
/>
<UserProfileRow
label="Password"
label={t('admin.user-profile.label-password', 'Password')}
value="********"
inputType="password"
locked={passwordChangeLocked}
@@ -131,7 +135,7 @@ export function UserProfile({
</Button>
<ConfirmModal
isOpen={showDeleteModal}
title="Delete user"
title={t('admin.user-profile.title-delete-user', 'Delete user')}
body="Are you sure you want to delete this user?"
confirmText="Delete user"
onConfirm={handleUserDelete}
@@ -151,7 +155,7 @@ export function UserProfile({
</Button>
<ConfirmModal
isOpen={showDisableModal}
title="Disable user"
title={t('admin.user-profile.title-disable-user', 'Disable user')}
body="Are you sure you want to disable this user?"
confirmText="Disable user"
onConfirm={handleUserDisable}
+1 -1
View File
@@ -114,7 +114,7 @@ class BaseUserSessions extends PureComponent<Props, State> {
)}
<ConfirmModal
isOpen={showLogoutModal}
title="Force logout from all devices"
title={t('admin.base-user-sessions.title-force-logout-from-all-devices', 'Force logout from all devices')}
body="Are you sure you want to force logout from all devices?"
confirmText="Force logout"
onConfirm={this.onAllSessionsRevoke}
@@ -24,7 +24,7 @@ import { fetchRoleOptions, updateUserRoles } from 'app/core/components/RolePicke
import { RolePickerBadges } from 'app/core/components/RolePickerDrawer/RolePickerBadges';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { AccessControlAction, OrgUser, Role } from 'app/types';
import { OrgRolePicker } from '../OrgRolePicker';
@@ -165,7 +165,7 @@ export const OrgUsersTable = ({
/>
) : (
<OrgRolePicker
aria-label="Role"
aria-label={t('admin.org-users-table.columns.aria-label-role', 'Role')}
value={value}
disabled={basicRoleDisabled}
onChange={(newRole) => onRoleChange(newRole, original)}
@@ -254,7 +254,7 @@ export const OrgUsersTable = ({
<ConfirmModal
body={`Are you sure you want to delete user ${userToRemove?.login}?`}
confirmText="Delete"
title="Delete"
title={t('admin.org-users-table.title-delete', 'Delete')}
onDismiss={() => {
setUserToRemove(null);
}}
@@ -16,7 +16,7 @@ import {
Tooltip,
} from '@grafana/ui';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { UserDTO } from 'app/types';
import { OrgUnits } from './OrgUnits';
@@ -55,7 +55,12 @@ export const UsersTable = ({
header: 'Login',
cell: ({ row: { original } }: Cell<'login'>) => {
return (
<TextLink color="primary" inline={false} href={`/admin/users/edit/${original.uid}`} title="Edit user">
<TextLink
color="primary"
inline={false}
href={`/admin/users/edit/${original.uid}`}
title={t('admin.users-table.columns.title-edit-user', 'Edit user')}
>
{original.login}
</TextLink>
);
@@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { Alert, CellProps, Column, Icon, InteractiveTable, Stack, Text, Tooltip } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types';
interface Props {
@@ -98,7 +98,10 @@ export const LdapErrorBox = ({ ldapConnectionInfo }: LdapConnectionErrorProps) =
));
return (
<Alert title="Connection error" severity={AppNotificationSeverity.Error}>
<Alert
title={t('admin.ldap-error-box.title-connection-error', 'Connection error')}
severity={AppNotificationSeverity.Error}
>
{errorElements}
</Alert>
);
@@ -144,6 +144,7 @@ export const LdapDrawerComponent = ({
>
<Input
id="port"
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="389"
type="number"
{...register(`${serverConfig}.port`, { valueAsNumber: true })}
@@ -158,6 +159,7 @@ export const LdapDrawerComponent = ({
>
<Input
id="timeout"
// eslint-disable-next-line @grafana/no-untranslated-strings
placeholder="10"
type="number"
{...register(`${serverConfig}.timeout`, { valueAsNumber: true })}
+2 -2
View File
@@ -7,7 +7,7 @@ import { featureEnabled } from '@grafana/runtime';
import { Alert, Button, Field, Input, Stack } from '@grafana/ui';
import { Page } from 'app/core/components/Page/Page';
import { contextSrv } from 'app/core/core';
import { Trans } from 'app/core/internationalization';
import { Trans, t } from 'app/core/internationalization';
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
import {
AppNotificationSeverity,
@@ -123,7 +123,7 @@ export const LdapPage = ({
<Trans i18nKey="admin.ldap.test-mapping-heading">Test user mapping</Trans>
</h3>
<form onSubmit={handleSubmit(search)}>
<Field label="Username">
<Field label={t('admin.ldap-page.label-username', 'Username')}>
<Input
{...register('username', { required: true })}
width={34}
@@ -143,7 +143,7 @@ export const LdapSettingsPage = () => {
*/
if (!config.featureToggles.ssoSettingsLDAP) {
return (
<Alert title="invalid configuration">
<Alert title={t('admin.ldap-settings-page.title-invalid-configuration', 'Invalid configuration')}>
<Trans i18nKey="ldap-settings-page.alert.feature-flag-disabled">
This page is only accessible by enabling the <strong>ssoSettingsLDAP</strong> feature flag.
</Trans>
@@ -421,14 +421,21 @@ export const LdapSettingsPage = () => {
<Dropdown
overlay={
<Menu>
<Menu.Item label="Reset to default values" icon="history-alt" onClick={deleteLDAPConfig} />
<Menu.Item
label={t(
'admin.ldap-settings-page.label-reset-to-default-values',
'Reset to default values'
)}
icon="history-alt"
onClick={deleteLDAPConfig}
/>
</Menu>
}
placement="bottom-start"
>
<IconButton
tooltip="More actions"
title="More actions"
tooltip={t('admin.ldap-settings-page.tooltip-more-actions', 'More actions')}
title={t('admin.ldap-settings-page.title-more-actions', 'More actions')}
size="md"
variant="secondary"
name="ellipsis-v"
@@ -1,6 +1,7 @@
import Skeleton from 'react-loading-skeleton';
import { Alert, Text } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { useGetAffectedItemsQuery } from '../../api/browseDashboardsAPI';
import { DashboardTreeSelection } from '../../types';
@@ -15,7 +16,13 @@ export const DescendantCount = ({ selectedItems }: Props) => {
const { data, isFetching, isLoading, error } = useGetAffectedItemsQuery(selectedItems);
return error ? (
<Alert severity="error" title="Unable to retrieve descendant information" />
<Alert
severity="error"
title={t(
'browse-dashboards.descendant-count.title-unable-to-retrieve-descendant-information',
'Unable to retrieve descendant information'
)}
/>
) : (
<Text element="p" color="secondary">
{data && buildBreakdownString(data.folder, data.dashboard, data.libraryPanel, data.alertRule)}
@@ -144,7 +144,13 @@ export function BrowseView({ folderUID, width, height, canSelect }: BrowseViewPr
)}
</EmptyState>
) : (
<CallToActionCard callToActionElement={<span>This folder is empty</span>} />
<CallToActionCard
callToActionElement={
<span>
<Trans i18nKey="browse-dashboards.browse-view.this-folder-is-empty">This folder is empty</Trans>
</span>
}
/>
)}
</div>
);
@@ -5,7 +5,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { reportInteraction } from '@grafana/runtime';
import { Icon, IconButton, Link, Spinner, useStyles2, Text } from '@grafana/ui';
import { getSvgSize } from '@grafana/ui/internal';
import { t } from 'app/core/internationalization';
import { t, Trans } from 'app/core/internationalization';
import { getIconForItem } from 'app/features/search/service/utils';
import { Indent } from '../../../core/components/Indent/Indent';
@@ -42,7 +42,7 @@ export function NameCell({ row: { original: data }, onFolderClick, treeID }: Nam
{item.uiKind === 'empty-folder' ? (
<em className={styles.emptyText}>
<Text variant="body" color="secondary" truncate>
No items
<Trans i18nKey="browse-dashboards.name-cell.no-items">No items</Trans>
</Text>
</em>
) : (
@@ -120,7 +120,11 @@ interface Props extends AddLibraryPanelContentsProps {
export const AddLibraryPanelModal = ({ isOpen = false, panel, initialFolderUid, ...props }: Props) => {
return (
<Modal title="Create library panel" isOpen={isOpen} onDismiss={props.onDismiss}>
<Modal
title={t('library-panels.add-library-panel-modal.title-create-library-panel', 'Create library panel')}
isOpen={isOpen}
onDismiss={props.onDismiss}
>
<AddLibraryPanelContents panel={panel} initialFolderUid={initialFolderUid} onDismiss={props.onDismiss} />
</Modal>
);
@@ -2,6 +2,7 @@ import { FC, useEffect, useMemo, useReducer } from 'react';
import { LoadingState } from '@grafana/data';
import { Button, Modal, useStyles2 } from '@grafana/ui';
import { t, Trans } from 'app/core/internationalization';
import { getModalStyles } from '../../styles';
import { LibraryElementDTO } from '../../types';
@@ -30,7 +31,13 @@ export const DeleteLibraryPanelModal: FC<Props> = ({ libraryPanel, onDismiss, on
const done = loadingState === LoadingState.Done;
return (
<Modal className={styles.modal} title="Delete library panel" icon="trash-alt" onDismiss={onDismiss} isOpen={true}>
<Modal
className={styles.modal}
title={t('library-panels.delete-library-panel-modal.title-delete-library-panel', 'Delete library panel')}
icon="trash-alt"
onDismiss={onDismiss}
isOpen={true}
>
{!done ? <LoadingIndicator /> : null}
{done ? (
<div>
@@ -39,10 +46,10 @@ export const DeleteLibraryPanelModal: FC<Props> = ({ libraryPanel, onDismiss, on
<Modal.ButtonRow>
<Button variant="secondary" onClick={onDismiss} fill="outline">
Cancel
<Trans i18nKey="library-panels.delete-library-panel-modal.cancel">Cancel</Trans>
</Button>
<Button variant="destructive" onClick={onConfirm} disabled={connected}>
Delete
<Trans i18nKey="library-panels.delete-library-panel-modal.delete">Delete</Trans>
</Button>
</Modal.ButtonRow>
</div>
@@ -51,12 +58,20 @@ export const DeleteLibraryPanelModal: FC<Props> = ({ libraryPanel, onDismiss, on
);
};
const LoadingIndicator = () => <span>Loading library panel...</span>;
const LoadingIndicator = () => (
<span>
<Trans i18nKey="library-panels.loading-indicator.loading-library-panel">Loading library panel...</Trans>
</span>
);
const Confirm = () => {
const styles = useStyles2(getModalStyles);
return <div className={styles.modalText}>Do you want to delete this panel?</div>;
return (
<div className={styles.modalText}>
<Trans i18nKey="library-panels.confirm.delete-panel">Do you want to delete this panel?</Trans>
</div>
);
};
const HasConnectedDashboards: FC<{ dashboardTitles: string[] }> = ({ dashboardTitles }) => {
@@ -77,7 +92,9 @@ const HasConnectedDashboards: FC<{ dashboardTitles: string[] }> = ({ dashboardTi
<table className={styles.myTable}>
<thead>
<tr>
<th>Dashboard name</th>
<th>
<Trans i18nKey="library-panels.has-connected-dashboards.dashboard-name">Dashboard name</Trans>
</th>
</tr>
</thead>
<tbody>
@@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { config } from '@grafana/runtime';
import { Icon, Link, useStyles2 } from '@grafana/ui';
import { SkeletonComponent, attachSkeleton } from '@grafana/ui/unstable';
import { Trans } from 'app/core/internationalization';
import { getPanelPluginNotFound } from 'app/features/panel/components/PanelPluginError';
import { PanelTypeCard } from 'app/features/panel/components/VizTypePicker/PanelTypeCard';
@@ -85,7 +86,9 @@ function FolderLink({ libraryPanel }: FolderLinkProps): ReactElement | null {
return (
<span className={styles.metaContainer}>
<Icon name={'folder'} size="sm" />
<span>Dashboards</span>
<span>
<Trans i18nKey="library-panels.folder-link.dashboards">Dashboards</Trans>
</span>
</span>
);
}
@@ -4,6 +4,7 @@ import { useDebounce } from 'react-use';
import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';
import { useStyles2, VerticalGroup, FilterInput } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { FolderInfo } from 'app/types';
import { FolderFilter } from '../../../../core/components/FolderFilter/FolderFilter';
@@ -66,7 +67,10 @@ export const LibraryPanelsSearch = ({
<FilterInput
value={searchQuery}
onChange={setSearchQuery}
placeholder="Search by name or description"
placeholder={t(
'library-panels.library-panels-search.placeholder-search-by-name-or-description',
'Search by name or description'
)}
width={0}
escapeRegex={false}
/>
@@ -3,6 +3,7 @@ import { useCallback, useState } from 'react';
import { PanelPluginMeta } from '@grafana/data';
import { Button, VerticalGroup } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { PanelModel } from 'app/features/dashboard/state/PanelModel';
import { changeToLibraryPanel } from 'app/features/panel/state/actions';
@@ -48,7 +49,9 @@ export const PanelLibraryOptionsGroup = ({ panel, searchQuery }: Props) => {
{!panel.libraryPanel && (
<VerticalGroup align="center">
<Button icon="plus" onClick={onAddToPanelLibrary} variant="secondary" fullWidth>
Create new library panel
<Trans i18nKey="library-panels.panel-library-options-group.create-new-library-panel">
Create new library panel
</Trans>
</Button>
</VerticalGroup>
)}
@@ -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 '../../state/api';
import { getModalStyles } from '../../styles';
@@ -72,17 +73,26 @@ export const SaveLibraryPanelModal = ({
<Input
className={styles.dashboardSearch}
prefix={<Icon name="search" />}
placeholder="Search affected dashboards"
placeholder={t(
'library-panels.save-library-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="library-panels.save-library-panel-modal.loading-connected-dashboards">
Loading connected dashboards...
</Trans>
</p>
) : (
<table className={styles.myTable}>
<thead>
<tr>
<th>Dashboard name</th>
<th>
<Trans i18nKey="library-panels.save-library-panel-modal.dashboard-name">Dashboard name</Trans>
</th>
</tr>
</thead>
<tbody>
@@ -96,11 +106,11 @@ export const SaveLibraryPanelModal = ({
)}
<Modal.ButtonRow>
<Button variant="secondary" onClick={onDismiss} fill="outline">
Cancel
<Trans i18nKey="library-panels.save-library-panel-modal.cancel">Cancel</Trans>
</Button>
{isUnsavedPrompt && (
<Button variant="destructive" onClick={discardAndClose}>
Discard
<Trans i18nKey="library-panels.save-library-panel-modal.discard">Discard</Trans>
</Button>
)}
<Button
@@ -110,7 +120,7 @@ export const SaveLibraryPanelModal = ({
});
}}
>
Update all
<Trans i18nKey="library-panels.save-library-panel-modal.update-all">Update all</Trans>
</Button>
</Modal.ButtonRow>
</div>
+10 -3
View File
@@ -5,6 +5,7 @@ import { Button, Input, Field, FieldSet } from '@grafana/ui';
import { Form } from 'app/core/components/Form/Form';
import { Page } from 'app/core/components/Page/Page';
import { getConfig } from 'app/core/config';
import { t, Trans } from 'app/core/internationalization';
import { createOrganization } from './state/actions';
@@ -46,16 +47,22 @@ export const NewOrgPage = ({ createOrganization }: Props) => {
return (
<>
<FieldSet>
<Field label="Organization name" invalid={!!errors.name} error={errors.name && errors.name.message}>
<Field
label={t('org.new-org-page.label-organization-name', 'Organization name')}
invalid={!!errors.name}
error={errors.name && errors.name.message}
>
<Input
placeholder="Org name"
placeholder={t('org.new-org-page.placeholder-org-name', 'Org name')}
{...register('name', {
required: 'Organization name is required',
})}
/>
</Field>
</FieldSet>
<Button type="submit">Create</Button>
<Button type="submit">
<Trans i18nKey="org.new-org-page.create">Create</Trans>
</Button>
</>
);
}}
+9 -3
View File
@@ -1,6 +1,7 @@
import { Input, Field, FieldSet, Button } from '@grafana/ui';
import { Form } from 'app/core/components/Form/Form';
import { contextSrv } from 'app/core/core';
import { t, Trans } from 'app/core/internationalization';
import { AccessControlAction } from 'app/types';
export interface Props {
@@ -18,12 +19,17 @@ const OrgProfile = ({ onSubmit, orgName }: Props) => {
return (
<Form defaultValues={{ orgName }} onSubmit={({ orgName }: FormDTO) => onSubmit(orgName)}>
{({ register }) => (
<FieldSet label="Organization profile" disabled={!canWriteOrg}>
<Field label="Organization name">
<FieldSet
label={t('org.org-profile.label-organization-profile', 'Organization profile')}
disabled={!canWriteOrg}
>
<Field label={t('org.org-profile.label-organization-name', 'Organization name')}>
<Input id="org-name-input" type="text" {...register('orgName', { required: true })} />
</Field>
<Button type="submit">Update organization name</Button>
<Button type="submit">
<Trans i18nKey="org.org-profile.update-organization-name">Update organization name</Trans>
</Button>
</FieldSet>
)}
</Form>
+16 -7
View File
@@ -17,6 +17,7 @@ import {
Stack,
} from '@grafana/ui';
import { getConfig } from 'app/core/config';
import { t, Trans } from 'app/core/internationalization';
import { OrgRole, useDispatch } from 'app/types';
import { Form } from '../../core/components/Form/Form';
@@ -74,19 +75,25 @@ export const UserInviteForm = () => {
<Field
invalid={!!errors.loginOrEmail}
error={!!errors.loginOrEmail ? 'Email or username is required' : undefined}
label="Email or username"
label={t('org.user-invite-form.label-email-or-username', 'Email or username')}
>
{/* eslint-disable-next-line @grafana/no-untranslated-strings */}
<Input {...register('loginOrEmail', { required: true })} placeholder="email@example.com" />
</Field>
<Field invalid={!!errors.name} label="Name">
<Input {...register('name')} placeholder="(optional)" />
<Field invalid={!!errors.name} label={t('org.user-invite-form.label-name', 'Name')}>
<Input
{...register('name')}
placeholder={t('org.user-invite-form.placeholder-optional', '(optional)')}
/>
</Field>
<Field
invalid={!!errors.role}
label={
<Label>
<Stack gap={0.5}>
<span>Role</span>
<span>
<Trans i18nKey="org.user-invite-form.role">Role</Trans>
</span>
{tooltipMessage && (
<Tooltip placement="right-end" interactive={true} content={tooltipMessage}>
<Icon name="info-circle" size="xs" />
@@ -102,14 +109,16 @@ export const UserInviteForm = () => {
name="role"
/>
</Field>
<Field label="Send invite email">
<Field label={t('org.user-invite-form.label-send-invite-email', 'Send invite email')}>
<Switch id="send-email-switch" {...register('sendEmail')} />
</Field>
</FieldSet>
<Stack>
<Button type="submit">Submit</Button>
<Button type="submit">
<Trans i18nKey="org.user-invite-form.submit">Submit</Trans>
</Button>
<LinkButton href={locationUtil.assureBaseUrl(getConfig().appSubUrl + '/admin/users')} variant="secondary">
Back
<Trans i18nKey="org.user-invite-form.back">Back</Trans>
</LinkButton>
</Stack>
</>
+23 -8
View File
@@ -3,6 +3,7 @@ import { useState } from 'react';
import { SelectableValue, UrlQueryMap, urlUtil } from '@grafana/data';
import { config, locationService, reportInteraction } from '@grafana/runtime';
import { Box, Button, Checkbox, Field, FieldSet, Modal, RadioButtonGroup, Stack } from '@grafana/ui';
import { t } from 'app/core/internationalization';
import { Playlist, PlaylistMode } from './types';
@@ -50,38 +51,52 @@ export const StartModal = ({ playlist, onDismiss }: Props) => {
};
return (
<Modal isOpen={true} icon="play" title="Start playlist" onDismiss={onDismiss}>
<Modal
isOpen={true}
icon="play"
title={t('playlist.start-modal.title-start-playlist', 'Start playlist')}
onDismiss={onDismiss}
>
<FieldSet>
<Field label="Mode">
<Field label={t('playlist.start-modal.label-mode', 'Mode')}>
<RadioButtonGroup value={mode} options={modes} onChange={setMode} />
</Field>
<Field>
<Checkbox
label="Autofit"
description="Panel heights will be adjusted to fit screen size"
label={t('playlist.start-modal.label-autofit', 'Autofit')}
description={t(
'playlist.start-modal.description-panel-heights-adjusted-screen',
'Panel heights will be adjusted to fit screen size'
)}
name="autofix"
value={autoFit}
onChange={(e) => setAutofit(e.currentTarget.checked)}
/>
</Field>
{config.featureToggles.dashboardScene && (
<Field label="Display dashboard controls" description="Customize dashboard elements visibility">
<Field
label={t('playlist.start-modal.label-display-dashboard-controls', 'Display dashboard controls')}
description={t(
'playlist.start-modal.description-customize-dashboard-elements-visibility',
'Customize dashboard elements visibility'
)}
>
<Box marginTop={2} marginBottom={2}>
<Stack direction="column" alignItems="start" justifyContent="left" gap={2}>
<Checkbox
label="Time and refresh"
label={t('playlist.start-modal.label-time-and-refresh', 'Time and refresh')}
name="displayTimePicker"
value={displayTimePicker}
onChange={(e) => setDisplayTimePicker(e.currentTarget.checked)}
/>
<Checkbox
label="Variables"
label={t('playlist.start-modal.label-variables', 'Variables')}
name="displayVariableControls"
value={displayVariables}
onChange={(e) => setDisplayVariables(e.currentTarget.checked)}
/>
<Checkbox
label="Dashboard links"
label={t('playlist.start-modal.label-dashboard-links', 'Dashboard links')}
name="displayLinks"
value={displayLinks}
onChange={(e) => setDisplayLinks(e.currentTarget.checked)}
+10 -3
View File
@@ -9,6 +9,7 @@ import { TeamRolePicker } from 'app/core/components/RolePicker/TeamRolePicker';
import { updateTeamRoles } from 'app/core/components/RolePicker/api';
import { useRoleOptions } from 'app/core/components/RolePicker/hooks';
import { contextSrv } from 'app/core/core';
import { t, Trans } from 'app/core/internationalization';
import { AccessControlAction, Role, TeamDTO } from 'app/types';
const pageNav: NavModelItem = {
@@ -51,11 +52,16 @@ export const CreateTeam = (): JSX.Element => {
<Page.Contents>
<form onSubmit={handleSubmit(createTeam)} style={{ maxWidth: '600px' }}>
<FieldSet>
<Field label="Name" required invalid={!!errors.name} error="Team name is required">
<Field
label={t('teams.create-team.label-name', 'Name')}
required
invalid={!!errors.name}
error="Team name is required"
>
<Input {...register('name', { required: true })} id="team-name" />
</Field>
{contextSrv.licensedAccessControlEnabled() && (
<Field label="Role">
<Field label={t('teams.create-team.label-role', 'Role')}>
<TeamRolePicker
teamId={0}
roleOptions={roleOptions}
@@ -71,12 +77,13 @@ export const CreateTeam = (): JSX.Element => {
label={'Email'}
description={'This is optional and is primarily used for allowing custom team avatars.'}
>
{/* eslint-disable-next-line @grafana/no-untranslated-strings */}
<Input {...register('email')} type="email" id="team-email" placeholder="email@test.com" />
</Field>
</FieldSet>
<Button type="submit" variant="primary">
Create
<Trans i18nKey="teams.create-team.create">Create</Trans>
</Button>
</form>
</Page.Contents>
+12 -4
View File
@@ -7,6 +7,7 @@ import { SlideDown } from 'app/core/components/Animations/SlideDown';
import { CloseButton } from 'app/core/components/CloseButton/CloseButton';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { UpgradeBox, UpgradeContent, UpgradeContentProps } from 'app/core/components/Upgrade/UpgradeBox';
import { Trans, t } from 'app/core/internationalization';
import { highlightTrial } from 'app/features/admin/utils';
import { StoreState, TeamGroup } from '../../types';
@@ -113,7 +114,9 @@ export class TeamGroupSync extends PureComponent<Props, State> {
<div className="page-action-bar">
{(!highlightTrial() || groups.length > 0) && (
<>
<h3 className="page-sub-heading">External group sync</h3>
<h3 className="page-sub-heading">
<Trans i18nKey="teams.team-group-sync.external-group-sync">External group sync</Trans>
</h3>
<Tooltip placement="auto" content={headerTooltip}>
<Icon className={cx(styles.icon, 'page-sub-heading-icon')} name="question-circle" />
</Tooltip>
@@ -146,7 +149,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
/>
</InlineField>
<Button type="submit" disabled={isReadOnly || !this.isNewGroupValid()} style={{ marginLeft: 4 }}>
Add group
<Trans i18nKey="teams.team-group-sync.add-group">Add group</Trans>
</Button>
</InlineFieldRow>
</form>
@@ -161,7 +164,10 @@ export class TeamGroupSync extends PureComponent<Props, State> {
<EmptyListCTA
onClick={this.onToggleAdding}
buttonIcon="users-alt"
title="There are no external groups to sync with"
title={t(
'teams.team-group-sync.title-there-external-groups',
'There are no external groups to sync with'
)}
buttonTitle="Add group"
proTip={headerTooltip}
proTipLinkTitle="Learn more"
@@ -176,7 +182,9 @@ export class TeamGroupSync extends PureComponent<Props, State> {
<table className="filter-table filter-table--hover form-inline">
<thead>
<tr>
<th>External Group ID</th>
<th>
<Trans i18nKey="teams.team-group-sync.external-group-id">External Group ID</Trans>
</th>
<th style={{ width: '1%' }} />
</tr>
</thead>
+12 -3
View File
@@ -103,7 +103,12 @@ export const TeamList = ({
}
return (
<TextLink color="primary" inline={false} href={`/org/teams/edit/${original.uid}`} title="Edit team">
<TextLink
color="primary"
inline={false}
href={`/org/teams/edit/${original.uid}`}
title={t('teams.team-list.columns.title-edit-team', 'Edit team')}
>
{value}
</TextLink>
);
@@ -209,7 +214,7 @@ export const TeamList = ({
actions={
!noTeams ? (
<LinkButton href={canCreate ? 'org/teams/new' : '#'} disabled={!canCreate}>
New Team
<Trans i18nKey="teams.team-list.new-team">New Team</Trans>
</LinkButton>
) : undefined
}
@@ -236,7 +241,11 @@ export const TeamList = ({
<>
<div className="page-action-bar">
<InlineField grow>
<FilterInput placeholder="Search teams" value={query} onChange={changeQuery} />
<FilterInput
placeholder={t('teams.team-list.placeholder-search-teams', 'Search teams')}
value={query}
onChange={changeQuery}
/>
</InlineField>
</div>
{hasFetched && teams.length === 0 ? (
+8 -6
View File
@@ -5,6 +5,7 @@ import { Button, Field, FieldSet, Input, Stack } from '@grafana/ui';
import { TeamRolePicker } from 'app/core/components/RolePicker/TeamRolePicker';
import { useRoleOptions } from 'app/core/components/RolePicker/hooks';
import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences';
import { t, Trans } from 'app/core/internationalization';
import { contextSrv } from 'app/core/services/context_srv';
import { AccessControlAction, Team } from 'app/types';
@@ -47,12 +48,12 @@ export const TeamSettings = ({ team, updateTeam }: Props) => {
return (
<Stack direction={'column'} gap={3}>
<form onSubmit={handleSubmit(onSubmit)} style={{ maxWidth: '600px' }}>
<FieldSet label="Team details">
<Field label="Numerical identifier" disabled={true}>
<FieldSet label={t('teams.team-settings.label-team-details', 'Team details')}>
<Field label={t('teams.team-settings.label-numerical-identifier', 'Numerical identifier')} disabled={true}>
<Input value={team.id} id="id-input" />
</Field>
<Field
label="Name"
label={t('teams.team-settings.label-name', 'Name')}
disabled={!canWriteTeamSettings}
required
invalid={!!errors.name}
@@ -62,20 +63,21 @@ export const TeamSettings = ({ team, updateTeam }: Props) => {
</Field>
{contextSrv.licensedAccessControlEnabled() && canListRoles && (
<Field label="Role">
<Field label={t('teams.team-settings.label-role', 'Role')}>
<TeamRolePicker teamId={team.id} roleOptions={roleOptions} disabled={!canUpdateRoles} maxWidth="100%" />
</Field>
)}
<Field
label="Email"
label={t('teams.team-settings.label-email', 'Email')}
description="This is optional and is primarily used to set the team profile avatar (via gravatar service)."
disabled={!canWriteTeamSettings}
>
{/* eslint-disable-next-line @grafana/no-untranslated-strings */}
<Input {...register('email')} placeholder="team@email.com" type="email" id="email-input" />
</Field>
<Button type="submit" disabled={!canWriteTeamSettings}>
Save
<Trans i18nKey="teams.team-settings.save">Save</Trans>
</Button>
</FieldSet>
</form>
+203 -1
View File
@@ -35,15 +35,57 @@
}
},
"admin": {
"add-to-org-modal": {
"label-organization": "Organization",
"label-role": "Role",
"title-add-to-an-organization": "Add to an organization"
},
"admin-edit-org-page": {
"label-name": "Name",
"render-missing-permission-message": {
"title-access-denied": "Access denied"
}
},
"admin-feature-toggles-table": {
"get-stage-cell": {
"beta": "Beta",
"deprecated": "Deprecated",
"ga": "GA"
},
"title-apply-feature-toggle-changes": "Apply feature toggle changes"
},
"admin-orgs-table": {
"aria-label-delete-org": "Delete org",
"title-delete": "Delete"
},
"anon-users": {
"not-found": "No anonymous users found."
},
"base-user-sessions": {
"title-force-logout-from-all-devices": "Force logout from all devices"
},
"edit-org": {
"access-denied": "You do not have permission to see users in this organization. To update this organization, contact your server administrator.",
"heading": "Edit Organization",
"update-button": "Update",
"users-heading": "Organization users"
},
"feature-listing": {
"title-auditing": "Auditing",
"title-dashboard-presence-indicators": "Dashboard presence indicators",
"title-dashboard-usage-stats-drawer": "Dashboard usage stats drawer",
"title-data-source-permissions": "Data source permissions",
"title-enhanced-ldap-integration": "Enhanced LDAP integration",
"title-enterprise-plugins": "Enterprise plugins",
"title-find-unused-dashboards": "Find unused dashboards",
"title-grafana-usage-insights": "Grafana usage insights",
"title-reporting": "Reporting",
"title-saml-authentication": "SAML authentication",
"title-settings-updates-at-runtime": "Settings updates at runtime",
"title-sort-dashboards-by-popularity-in-search": "Sort dashboards by popularity in search",
"title-team-sync": "Team Sync",
"title-white-labeling": "White labeling"
},
"feature-toggles": {
"sub-title": "View and edit feature toggles. Read more about feature toggles at <2>grafana.com</2>."
},
@@ -61,11 +103,23 @@
"test-mapping-heading": "Test user mapping",
"test-mapping-run-button": "Run"
},
"ldap-error-box": {
"title-connection-error": "Connection error"
},
"ldap-page": {
"label-username": "Username"
},
"ldap-permissions": {
"active": "<0></0> Active",
"admin": "<0></0> Yes",
"inactive": "<0></0> Inactive"
},
"ldap-settings-page": {
"label-reset-to-default-values": "Reset to default values",
"title-invalid-configuration": "Invalid configuration",
"title-more-actions": "More actions",
"tooltip-more-actions": "More actions"
},
"ldap-status": {
"title": "LDAP Connection"
},
@@ -87,12 +141,21 @@
"ldap-user-info": {
"no-team": "No teams found via LDAP"
},
"org-role-picker": {
"placeholder-choose-role": "Choose role..."
},
"org-uers": {
"last-seen-never": "Never"
},
"org-users": {
"not-editable": "This user's role is not editable because it is synchronized from your auth provider. Refer to the <1>Grafana authentication docs</1> for details."
},
"org-users-table": {
"columns": {
"aria-label-role": "Role"
},
"title-delete": "Delete"
},
"orgs": {
"delete-body": "Are you sure you want to delete '{{deleteOrgName}}'?<3></3> <5>All dashboards for this organization will be removed!</5>",
"id-header": "ID",
@@ -107,12 +170,38 @@
"title": "Instance statistics",
"users-button": "Manage users"
},
"service-info": {
"title-critical-sla-hours": "Critical SLA: 2 hours",
"title-enterprise-plugins": "Enterprise Plugins",
"title-unlimited-expert-support": "Unlimited Expert Support"
},
"settings": {
"info-description": "These system settings are defined in grafana.ini or custom.ini (or overridden in ENV variables). To change these you currently need to restart Grafana."
},
"upgrade-info": {
"title": "Enterprise license"
},
"user-create-page": {
"label-email": "Email",
"label-name": "Name",
"label-password": "Password",
"label-username": "Username"
},
"user-ldap-sync-info": {
"label-ldap": "LDAP"
},
"user-list-admin-page-un-connected": {
"placeholder-search-login-email": "Search user by login, email, or name."
},
"user-list-anonymous-devices-page-un-connected": {
"placeholder-search-devices-by-ip-address": "Search devices by IP address."
},
"user-list-page": {
"label-all-users": "All users",
"label-anonymous-devices": "Anonymous devices",
"label-organization-users": "Organization users",
"label-users": "Users"
},
"user-orgs": {
"add-button": "Add user to organization",
"change-role-button": "Change role",
@@ -137,7 +226,14 @@
"disable-button": "Disable user",
"edit-button": "Edit",
"enable-button": "Enable user",
"title": "User information"
"label-email": "Email",
"label-name": "Name",
"label-numerical-identifier": "Numerical identifier",
"label-password": "Password",
"label-username": "Username",
"title": "User information",
"title-delete-user": "Delete user",
"title-disable-user": "Disable user"
},
"user-sessions": {
"browser-column": "Browser and OS",
@@ -155,6 +251,9 @@
"create-button": "New user"
},
"users-table": {
"columns": {
"title-edit-user": "Edit user"
},
"last-seen-never": "Never",
"no-licensed-roles": "Not assigned"
}
@@ -819,6 +918,9 @@
"actions": {
"button-to-recently-deleted": "Recently deleted"
},
"browse-view": {
"this-folder-is-empty": "This folder is empty"
},
"counts": {
"alertRule_one": "{{count}} alert rule",
"alertRule_other": "{{count}} alert rule",
@@ -839,6 +941,9 @@
"select-checkbox": "Select",
"tags-column": "Tags"
},
"descendant-count": {
"title-unable-to-retrieve-descendant-information": "Unable to retrieve descendant information"
},
"empty-state": {
"button-title": "Create dashboard",
"pro-tip": "Add/move dashboards to your folder at <2>Browse dashboards</2>",
@@ -869,6 +974,9 @@
"dashboards": "Dashboards",
"panels": "Panels"
},
"name-cell": {
"no-items": "No items"
},
"new-folder-form": {
"cancel-label": "Cancel",
"create-label": "Create",
@@ -2428,9 +2536,32 @@
}
},
"library-panels": {
"add-library-panel-modal": {
"title-create-library-panel": "Create library panel"
},
"confirm": {
"delete-panel": "Do you want to delete this panel?"
},
"delete-library-panel-modal": {
"cancel": "Cancel",
"delete": "Delete",
"title-delete-library-panel": "Delete library panel"
},
"empty-state": {
"message": "No library panels found"
},
"folder-link": {
"dashboards": "Dashboards"
},
"has-connected-dashboards": {
"dashboard-name": "Dashboard name"
},
"library-panels-search": {
"placeholder-search-by-name-or-description": "Search by name or description"
},
"loading-indicator": {
"loading-library-panel": "Loading library panel..."
},
"loading-panel-text": "Loading library panel",
"modal": {
"body_one": "This panel is being used in {{count}} dashboard. Please choose which dashboard to view the panel in:",
@@ -2443,9 +2574,20 @@
"select-placeholder": "Start typing to search for dashboard",
"title": "View panel in dashboard"
},
"panel-library-options-group": {
"create-new-library-panel": "Create new library panel"
},
"save": {
"error": "Error saving library panel: \"{{errorMsg}}\"",
"success": "Library panel saved"
},
"save-library-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"
}
},
"link": {
@@ -3187,6 +3329,27 @@
"error": "Login provider denied login request"
}
},
"org": {
"new-org-page": {
"create": "Create",
"label-organization-name": "Organization name",
"placeholder-org-name": "Org name"
},
"org-profile": {
"label-organization-name": "Organization name",
"label-organization-profile": "Organization profile",
"update-organization-name": "Update organization name"
},
"user-invite-form": {
"back": "Back",
"label-email-or-username": "Email or username",
"label-name": "Name",
"label-send-invite-email": "Send invite email",
"placeholder-optional": "(optional)",
"role": "Role",
"submit": "Submit"
}
},
"panel": {
"header-menu": {
"copy": "Copy",
@@ -3217,6 +3380,19 @@
"panel-type-filter": {
"clear-button": "Clear types"
},
"playlist": {
"start-modal": {
"description-customize-dashboard-elements-visibility": "Customize dashboard elements visibility",
"description-panel-heights-adjusted-screen": "Panel heights will be adjusted to fit screen size",
"label-autofit": "Autofit",
"label-dashboard-links": "Dashboard links",
"label-display-dashboard-controls": "Display dashboard controls",
"label-mode": "Mode",
"label-time-and-refresh": "Time and refresh",
"label-variables": "Variables",
"title-start-playlist": "Start playlist"
}
},
"playlist-edit": {
"error-prefix": "Error loading playlist:",
"form": {
@@ -4038,11 +4214,37 @@
"placeholder": "Filter by tag"
},
"teams": {
"create-team": {
"create": "Create",
"label-name": "Name",
"label-role": "Role"
},
"empty-state": {
"button-title": "New team",
"message": "No teams found",
"pro-tip": "Assign folder and dashboard permissions to teams instead of users to ease administration. <2>Learn more</2>",
"title": "You haven't created any teams yet"
},
"team-group-sync": {
"add-group": "Add group",
"external-group-id": "External Group ID",
"external-group-sync": "External group sync",
"title-there-external-groups": "There are no external groups to sync with"
},
"team-list": {
"columns": {
"title-edit-team": "Edit team"
},
"new-team": "New Team",
"placeholder-search-teams": "Search teams"
},
"team-settings": {
"label-email": "Email",
"label-name": "Name",
"label-numerical-identifier": "Numerical identifier",
"label-role": "Role",
"label-team-details": "Team details",
"save": "Save"
}
},
"theme-preview": {