mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Mark up some content for translations (#96716)
* translate some of core * more * translate admin * fix count translations * update unit tests
This commit is contained in:
parent
4f8ab73a8c
commit
c2e1a405b9
@ -794,50 +794,12 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not re-export imported variable (\`notifyApp\`)", "2"],
|
||||
[0, 0, 0, "Do not re-export imported variable (\`hideAppNotification\`)", "3"]
|
||||
],
|
||||
"public/app/core/components/AccessControl/PermissionListItem.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/AccessControl/index.ts:5381": [
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"]
|
||||
],
|
||||
"public/app/core/components/AppChrome/AppChrome.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/AppChrome/TopBar/SignInLink.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/AppChrome/TopBar/TopSearchBarCommandPaletteTrigger.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/AppNotifications/AppNotificationItem.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/DynamicImports/SafeDynamicImport.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/core/components/EmptyListCTA/EmptyListCTA.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/FolderFilter/FolderFilter.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/ForgottenPassword/ChangePassword.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/core/components/ForgottenPassword/ForgottenPassword.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 />", "4"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
|
||||
],
|
||||
"public/app/core/components/FormPrompt/FormPrompt.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/core/components/GraphNG/GraphNG.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
@ -849,79 +811,14 @@ exports[`better eslint`] = {
|
||||
"public/app/core/components/LocalStorageValueProvider/index.tsx:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`./LocalStorageValueProvider\`)", "0"]
|
||||
],
|
||||
"public/app/core/components/Login/LoginLayout.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/Login/LoginServiceButtons.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/NestedFolderPicker/NestedFolderList.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/PageNotFound/EntityNotFound.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 />", "4"]
|
||||
],
|
||||
"public/app/core/components/PanelTypeFilter/PanelTypeFilter.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/PluginHelp/PluginHelp.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/core/components/RolePicker/BuiltinRoleSelector.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/RolePicker/RolePickerInput.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/RolePicker/RolePickerMenu.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"]
|
||||
],
|
||||
"public/app/core/components/RolePicker/RolePickerSubMenu.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/Select/OldFolderPicker.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/core/components/Signup/SignupPage.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/core/components/Signup/VerifyEmail.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 />", "4"]
|
||||
],
|
||||
"public/app/core/components/TagFilter/TagFilter.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "1"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/core/components/TimeSeries/utils.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"public/app/core/components/Upgrade/UpgradeBox.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 />", "4"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
|
||||
],
|
||||
"public/app/core/components/help/HelpModal.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/core/config.ts:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`config\`)", "0"],
|
||||
[0, 0, 0, "Do not re-export imported variable (\`Settings\`)", "1"]
|
||||
@ -936,15 +833,6 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not re-export imported variable (\`TimeSeries\`)", "6"],
|
||||
[0, 0, 0, "Do not re-export imported variable (\`updateLegendValues\`)", "7"]
|
||||
],
|
||||
"public/app/core/navigation/GrafanaRouteError.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/core/navigation/RouterDebugger.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/core/navigation/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
@ -1035,161 +923,18 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/features/actions/ActionEditorModalContent.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/actions/ActionsInlineEditor.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/actions/ParamsEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/admin/AdminEditOrgPage.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"]
|
||||
],
|
||||
"public/app/features/admin/AdminFeatureTogglesPage.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/admin/AdminFeatureTogglesTable.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/admin/AdminListOrgsPage.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/AdminOrgsTable.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 />", "4"]
|
||||
],
|
||||
"public/app/features/admin/AdminSettings.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/ServerStats.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 />", "4"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "5"]
|
||||
],
|
||||
"public/app/features/admin/UpgradePage.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 />", "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 />", "9"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"]
|
||||
],
|
||||
"public/app/features/admin/UserCreatePage.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/UserLdapSyncInfo.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 />", "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/admin/UserListAdminPage.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/UserListPublicDashboardPage/DashboardsListModalButton.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/UserListPublicDashboardPage/UserListPublicDashboardPage.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/UserOrgs.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 />", "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 />", "9"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "10"],
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "11"]
|
||||
],
|
||||
"public/app/features/admin/UserPermissions.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 />", "4"]
|
||||
],
|
||||
"public/app/features/admin/UserProfile.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 />", "4"]
|
||||
],
|
||||
"public/app/features/admin/UserSessions.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 />", "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/admin/Users/AnonUsersTable.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/Users/OrgUsersTable.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"]
|
||||
],
|
||||
"public/app/features/admin/Users/UsersTable.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/admin/ldap/LdapConnectionStatus.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/admin/ldap/LdapPage.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/admin/ldap/LdapSyncInfo.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/ldap/LdapUserGroups.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/ldap/LdapUserInfo.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "0"]
|
||||
],
|
||||
"public/app/features/admin/ldap/LdapUserPermissions.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/alerting/routes.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
|
@ -2,6 +2,7 @@ import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Box, Button, Icon, Select, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ResourcePermission } from './types';
|
||||
|
||||
@ -20,7 +21,13 @@ export const PermissionListItem = ({ item, permissionLevels, canSet, onRemove, o
|
||||
<tr>
|
||||
<td>{getAvatar(item)}</td>
|
||||
<td>{getDescription(item)}</td>
|
||||
<td>{item.isInherited && <em className={styles.inherited}>Inherited from folder</em>}</td>
|
||||
<td>
|
||||
{item.isInherited && (
|
||||
<em className={styles.inherited}>
|
||||
<Trans i18nKey="access-control.permission-list-item.inherited">Inherited from folder</Trans>
|
||||
</em>
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
<Select
|
||||
disabled={!canSet || !item.isManaged}
|
||||
|
@ -7,6 +7,7 @@ import { config, locationSearchToObject, locationService } from '@grafana/runtim
|
||||
import { useStyles2, LinkButton, useTheme2 } from '@grafana/ui';
|
||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||
import { useMediaQueryChange } from 'app/core/hooks/useMediaQueryChange';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import store from 'app/core/store';
|
||||
import { CommandPalette } from 'app/features/commandPalette/CommandPalette';
|
||||
import { ScopesDashboards, useScopesDashboardsState } from 'app/features/scopes';
|
||||
@ -95,7 +96,7 @@ export function AppChrome({ children }: Props) {
|
||||
{!state.chromeless && (
|
||||
<>
|
||||
<LinkButton className={styles.skipLink} href="#pageContent">
|
||||
Skip to main content
|
||||
<Trans i18nKey="app-chrome.skip-content-button">Skip to main content</Trans>
|
||||
</LinkButton>
|
||||
{isSingleTopNav && menuDockedAndOpen && (
|
||||
<MegaMenu className={styles.dockedMegaMenu} onClose={() => chrome.setMegaMenuOpen(false)} />
|
||||
|
@ -4,6 +4,7 @@ import { useLocation } from 'react-router-dom-v5-compat';
|
||||
import { GrafanaTheme2, locationUtil, textUtil } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export function SignInLink() {
|
||||
const location = useLocation();
|
||||
@ -17,7 +18,7 @@ export function SignInLink() {
|
||||
|
||||
return (
|
||||
<a className={styles.link} href={loginUrl} target="_self">
|
||||
Sign in
|
||||
<Trans i18nKey="app-chrome.top-bar.sign-in">Sign in</Trans>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ function PretendTextInput({ onClick }: PretendTextInputProps) {
|
||||
|
||||
<div className={styles.suffix}>
|
||||
<Icon name="keyboard" />
|
||||
<Text variant="bodySmall">{modKey}+k</Text>
|
||||
<Text variant="bodySmall">{`${modKey}+k`}</Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,7 @@ import { useEffectOnce } from 'react-use';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Alert, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { AppNotification, timeoutMap } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -20,6 +21,7 @@ export default function AppNotificationItem({ appNotification, onClearNotificati
|
||||
});
|
||||
|
||||
const hasBody = appNotification.component || appNotification.text || appNotification.traceId;
|
||||
const traceId = appNotification.traceId;
|
||||
|
||||
return (
|
||||
<Alert
|
||||
@ -31,7 +33,11 @@ export default function AppNotificationItem({ appNotification, onClearNotificati
|
||||
{hasBody && (
|
||||
<div className={styles.wrapper}>
|
||||
<span>{appNotification.component || appNotification.text}</span>
|
||||
{appNotification.traceId && <span className={styles.trace}>Trace ID: {appNotification.traceId}</span>}
|
||||
{traceId && (
|
||||
<span className={styles.trace}>
|
||||
<Trans i18nKey="app-notification.item.trace-id">Trace ID: {{ traceId }}</Trans>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Alert>
|
||||
|
@ -3,6 +3,7 @@ import { MouseEvent } from 'react';
|
||||
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { Alert, Button, CallToActionCard, Icon, IconName, LinkButton } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
@ -48,7 +49,7 @@ const EmptyListCTA = ({
|
||||
{proTip ? (
|
||||
<span key="proTipFooter">
|
||||
<Icon name="rocket" />
|
||||
<> ProTip: {proTip} </>
|
||||
<Trans i18nKey="empty-list-cta.pro-tip">ProTip: {{ proTip }}</Trans>
|
||||
{proTipLink && (
|
||||
<a href={proTipLink} target={proTipTarget} className="text-link">
|
||||
{proTipLinkTitle}
|
||||
|
@ -4,6 +4,7 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { AsyncMultiSelect, Icon, Button, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||
import { DashboardSearchItemType } from 'app/features/search/types';
|
||||
import { FolderInfo, PermissionLevelString } from 'app/types';
|
||||
@ -40,7 +41,7 @@ export function FolderFilter({ onChange, maxMenuHeight }: FolderFilterProps): JS
|
||||
onClick={() => onChange([])}
|
||||
aria-label="Clear folders"
|
||||
>
|
||||
Clear folders
|
||||
<Trans i18nKey="folder-filter.clear-folder-button">Clear folders</Trans>
|
||||
</Button>
|
||||
)}
|
||||
<AsyncMultiSelect
|
||||
|
@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { Tooltip, Field, Button, Alert, useStyles2, Stack } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { getStyles } from '../Login/LoginForm';
|
||||
import { PasswordField } from '../PasswordField/PasswordField';
|
||||
@ -83,7 +84,7 @@ export const ChangePassword = ({ onSubmit, onSkip, showDefaultPasswordWarning }:
|
||||
</Field>
|
||||
<Stack direction="column">
|
||||
<Button type="submit" className={styles.submitButton}>
|
||||
Submit
|
||||
<Trans i18nKey="forgot-password.change-password.submit-button">Submit</Trans>
|
||||
</Button>
|
||||
|
||||
{!config.auth.basicAuthStrongPasswordPolicy && onSkip && (
|
||||
@ -98,7 +99,7 @@ export const ChangePassword = ({ onSubmit, onSkip, showDefaultPasswordWarning }:
|
||||
type="button"
|
||||
data-testid={selectors.pages.Login.skip}
|
||||
>
|
||||
Skip
|
||||
<Trans i18nKey="forgot-password.change-password.skip-button">Skip</Trans>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Field, Input, Button, Legend, Container, useStyles2, LinkButton, Stack } from '@grafana/ui';
|
||||
import config from 'app/core/config';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
interface EmailDTO {
|
||||
userOrEmail: string;
|
||||
@ -40,17 +41,23 @@ export const ForgottenPassword = () => {
|
||||
if (emailSent) {
|
||||
return (
|
||||
<div>
|
||||
<p>An email with a reset link has been sent to the email address. You should receive it shortly.</p>
|
||||
<p>
|
||||
<Trans i18nKey="forgot-password.email-sent">
|
||||
An email with a reset link has been sent to the email address. You should receive it shortly.
|
||||
</Trans>
|
||||
</p>
|
||||
<Container margin="md" />
|
||||
<LinkButton variant="primary" href={loginHref}>
|
||||
Back to login
|
||||
<Trans i18nKey="forgot-password.back-button">Back to login</Trans>
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<form onSubmit={handleSubmit(sendEmail)}>
|
||||
<Legend>Reset password</Legend>
|
||||
<Legend>
|
||||
<Trans i18nKey="forgot-password.reset-password-header">Reset password</Trans>
|
||||
</Legend>
|
||||
<Field
|
||||
label="User"
|
||||
description="Enter your information to get a reset link sent to you"
|
||||
@ -64,13 +71,19 @@ export const ForgottenPassword = () => {
|
||||
/>
|
||||
</Field>
|
||||
<Stack>
|
||||
<Button type="submit">Send reset email</Button>
|
||||
<Button type="submit">
|
||||
<Trans i18nKey="forgot-password.send-email-button">Send reset email</Trans>
|
||||
</Button>
|
||||
<LinkButton fill="text" href={loginHref}>
|
||||
Back to login
|
||||
<Trans i18nKey="forgot-password.back-button">Back to login</Trans>
|
||||
</LinkButton>
|
||||
</Stack>
|
||||
|
||||
<p className={styles}>Did you forget your username or email? Contact your Grafana administrator.</p>
|
||||
<p className={styles}>
|
||||
<Trans i18nKey="forgot-password.contact-admin">
|
||||
Did you forget your username or email? Contact your Grafana administrator.
|
||||
</Trans>
|
||||
</p>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';
|
||||
import { Navigate } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { Button, Modal } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { Prompt } from './Prompt';
|
||||
|
||||
@ -103,13 +104,15 @@ const UnsavedChangesModal = ({ onDiscard, onBackToForm, isOpen }: UnsavedChanges
|
||||
icon="exclamation-triangle"
|
||||
className={css({ width: '500px' })}
|
||||
>
|
||||
<h5>Changes that you made may not be saved.</h5>
|
||||
<h5>
|
||||
<Trans i18nKey="form-prompt.description">Changes that you made may not be saved.</Trans>
|
||||
</h5>
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" onClick={onBackToForm} fill="outline">
|
||||
Continue editing
|
||||
<Trans i18nKey="form-prompt.continue-button">Continue editing</Trans>
|
||||
</Button>
|
||||
<Button variant="destructive" onClick={onDiscard}>
|
||||
Discard unsaved changes
|
||||
<Trans i18nKey="form-prompt.discard-button">Discard unsaved changes</Trans>
|
||||
</Button>
|
||||
</Modal.ButtonRow>
|
||||
</Modal>
|
||||
|
@ -4,6 +4,7 @@ import * as React from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { Branding } from '../Branding/Branding';
|
||||
import { BrandingSettings } from '../Branding/types';
|
||||
@ -44,7 +45,9 @@ export const LoginLayout = ({ children, branding, isChangingPassword }: React.Pr
|
||||
<Branding.LoginLogo className={loginStyles.loginLogo} logo={loginLogo} />
|
||||
<div className={loginStyles.titleWrapper}>
|
||||
{isChangingPassword ? (
|
||||
<h1 className={loginStyles.mainTitle}>Update your password</h1>
|
||||
<h1 className={loginStyles.mainTitle}>
|
||||
<Trans i18nKey="login.layout.update-password">Update your password</Trans>
|
||||
</h1>
|
||||
) : (
|
||||
<>
|
||||
<h1 className={loginStyles.mainTitle}>{loginTitle}</h1>
|
||||
|
@ -113,7 +113,7 @@ const LoginDivider = () => {
|
||||
<div className={styles.divider.line} />
|
||||
</div>
|
||||
<div>
|
||||
<span>{!config.disableLoginForm && <span>or</span>}</span>
|
||||
<span>{!config.disableLoginForm && <Trans i18nKey="login.divider.connecting-text">or</Trans>}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div className={styles.divider.line} />
|
||||
|
@ -160,9 +160,13 @@ function Row({ index, style: virtualStyles, data }: RowProps) {
|
||||
}
|
||||
|
||||
if (item.kind !== 'folder') {
|
||||
const itemKind = item.kind;
|
||||
const itemUID = item.uid;
|
||||
return process.env.NODE_ENV !== 'production' ? (
|
||||
<span style={virtualStyles} className={styles.row}>
|
||||
Non-folder {item.kind} {item.uid}
|
||||
<Trans i18nKey="browse-dashboards.folder-picker.non-folder-item">
|
||||
Non-folder {{ itemKind }} {{ itemUID }}
|
||||
</Trans>
|
||||
</span>
|
||||
) : null;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { EmptyState, TextLink, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
export interface Props {
|
||||
/**
|
||||
@ -13,15 +14,18 @@ export interface Props {
|
||||
|
||||
export function EntityNotFound({ entity = 'Page' }: Props) {
|
||||
const styles = useStyles2(getStyles);
|
||||
const lowerCaseEntity = entity.toLowerCase();
|
||||
|
||||
return (
|
||||
<div className={styles.container} data-testid={selectors.components.EntityNotFound.container}>
|
||||
<EmptyState message={`${entity} not found`} variant="not-found">
|
||||
We're looking but can't seem to find this {entity.toLowerCase()}. Try returning{' '}
|
||||
<TextLink href="/">home</TextLink> or seeking help on the{' '}
|
||||
<TextLink href="https://community.grafana.com" external>
|
||||
community site.
|
||||
</TextLink>
|
||||
<Trans i18nKey="entity-not-found.description">
|
||||
We're looking but can't seem to find this {{ lowerCaseEntity }}. Try returning{' '}
|
||||
<TextLink href="/">home</TextLink> or seeking help on the{' '}
|
||||
<TextLink href="https://community.grafana.com" external>
|
||||
community site.
|
||||
</TextLink>
|
||||
</Trans>
|
||||
</EmptyState>
|
||||
</div>
|
||||
);
|
||||
|
@ -3,6 +3,7 @@ import { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import { GrafanaTheme2, PanelPluginMeta, SelectableValue } from '@grafana/data';
|
||||
import { Icon, Button, MultiSelect, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { getAllPanelPluginMeta } from 'app/features/panel/state/util';
|
||||
|
||||
export interface Props {
|
||||
@ -53,7 +54,7 @@ export const PanelTypeFilter = ({ onChange: propsOnChange, maxMenuHeight }: Prop
|
||||
onClick={() => onChange([])}
|
||||
aria-label="Clear types"
|
||||
>
|
||||
Clear types
|
||||
<Trans i18nKey="panel-type-filter.clear-button">Clear types</Trans>
|
||||
</Button>
|
||||
)}
|
||||
<MultiSelect<PanelPluginMeta> {...selectOptions} prefix={<Icon name="filter" />} aria-label="Panel Type filter" />
|
||||
|
@ -3,6 +3,7 @@ import { useAsync } from 'react-use';
|
||||
import { renderMarkdown } from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { LoadingPlaceholder } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
interface Props {
|
||||
pluginId: string;
|
||||
@ -20,11 +21,19 @@ export function PluginHelp({ pluginId }: Props) {
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return <h3>An error occurred when loading help.</h3>;
|
||||
return (
|
||||
<h3>
|
||||
<Trans i18nKey="plugins.plugin-help.error">An error occurred when loading help.</Trans>
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
if (value === '') {
|
||||
return <h3>No query help could be found.</h3>;
|
||||
return (
|
||||
<h3>
|
||||
<Trans i18nKey="plugins.plugin-help.not-found">No query help could be found.</Trans>
|
||||
</h3>
|
||||
);
|
||||
}
|
||||
|
||||
return <div className="markdown-html" dangerouslySetInnerHTML={{ __html: renderedMarkdown }} />;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Icon, RadioButtonList, Tooltip, useStyles2, useTheme2, PopoverContent } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { OrgRole } from 'app/types';
|
||||
|
||||
import { getStyles } from './styles';
|
||||
@ -24,7 +25,9 @@ export const BuiltinRoleSelector = ({ value, onChange, disabled, disabledMesssag
|
||||
return (
|
||||
<>
|
||||
<div className={styles.groupHeader}>
|
||||
<span style={{ marginRight: theme.spacing(1) }}>Basic roles</span>
|
||||
<span style={{ marginRight: theme.spacing(1) }}>
|
||||
<Trans i18nKey="role-picker.built-in.basic-roles">Basic roles</Trans>
|
||||
</span>
|
||||
{disabled && disabledMesssage && (
|
||||
<Tooltip placement="right-end" interactive={true} content={<div>{disabledMesssage}</div>}>
|
||||
<Icon name="question-circle" />
|
||||
|
@ -5,6 +5,7 @@ import * as React from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useStyles2, getInputStyles, sharedInputStyle, Tooltip, Icon, Spinner } from '@grafana/ui';
|
||||
import { getFocusStyles } from '@grafana/ui/src/themes/mixins';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { Role } from '../../../types';
|
||||
|
||||
@ -125,7 +126,11 @@ export const RolesLabel = ({ showBuiltInRole, numberOfRoles, appliedRoles }: Rol
|
||||
}`}</ValueContainer>
|
||||
</Tooltip>
|
||||
) : (
|
||||
!showBuiltInRole && <ValueContainer>No roles assigned</ValueContainer>
|
||||
!showBuiltInRole && (
|
||||
<ValueContainer>
|
||||
<Trans i18nKey="role-picker.input.no-roles">No roles assigned</Trans>
|
||||
</ValueContainer>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
@ -3,6 +3,7 @@ import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { Button, ScrollContainer, Stack, TextLink, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { getSelectStyles } from '@grafana/ui/src/components/Select/getSelectStyles';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { OrgRole, Role } from 'app/types';
|
||||
|
||||
import { BuiltinRoleSelector } from './BuiltinRoleSelector';
|
||||
@ -35,7 +36,7 @@ const fixedRoleGroupNames: Record<string, string> = {
|
||||
};
|
||||
|
||||
const tooltipMessage = (
|
||||
<>
|
||||
<Trans i18nKey="role-picker.menu.tooltip">
|
||||
You can now select the "No basic role" option and add permissions to your custom needs. You can find more
|
||||
information in
|
||||
<TextLink
|
||||
@ -46,7 +47,7 @@ const tooltipMessage = (
|
||||
our documentation
|
||||
</TextLink>
|
||||
.
|
||||
</>
|
||||
</Trans>
|
||||
);
|
||||
|
||||
interface RolePickerMenuProps {
|
||||
@ -275,7 +276,7 @@ export const RolePickerMenu = ({
|
||||
<div className={customStyles.menuButtonRow}>
|
||||
<Stack justifyContent="flex-end">
|
||||
<Button size="sm" fill="text" onClick={onClearInternal} disabled={updateDisabled}>
|
||||
Clear all
|
||||
<Trans i18nKey="role-picker.menu.clear-button">Clear all</Trans>
|
||||
</Button>
|
||||
<Button size="sm" onClick={onUpdateInternal} disabled={updateDisabled}>
|
||||
{apply ? `Apply` : `Update`}
|
||||
|
@ -2,6 +2,7 @@ import { cx } from '@emotion/css';
|
||||
|
||||
import { Button, ScrollContainer, Stack, useStyles2, useTheme2 } from '@grafana/ui';
|
||||
import { getSelectStyles } from '@grafana/ui/src/components/Select/getSelectStyles';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { Role } from 'app/types';
|
||||
|
||||
import { RoleMenuOption } from './RoleMenuOption';
|
||||
@ -67,7 +68,7 @@ export const RolePickerSubMenu = ({
|
||||
<div className={customStyles.subMenuButtonRow}>
|
||||
<Stack justifyContent="flex-end">
|
||||
<Button size="sm" fill="text" onClick={onClearInternal}>
|
||||
Clear
|
||||
<Trans i18nKey="role-picker.sub-menu.clear-button">Clear</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
</div>
|
||||
|
@ -9,7 +9,7 @@ import { selectors } from '@grafana/e2e-selectors';
|
||||
import { reportInteraction } from '@grafana/runtime';
|
||||
import { ActionMeta, AsyncVirtualizedSelect, Input, InputActionMeta, useStyles2 } from '@grafana/ui';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { createFolder, getFolderByUid, searchFolders } from 'app/features/manage-dashboards/state/actions';
|
||||
import { DashboardSearchHit } from 'app/features/search/types';
|
||||
@ -323,7 +323,9 @@ export function OldFolderPicker(props: Props) {
|
||||
return (
|
||||
<>
|
||||
<FolderWarningWhenCreating />
|
||||
<div className={styles.newFolder}>Press enter to create the new folder.</div>
|
||||
<div className={styles.newFolder}>
|
||||
<Trans i18nKey="folder-picker.create-instructions">Press enter to create the new folder.</Trans>
|
||||
</div>
|
||||
<Input
|
||||
width={30}
|
||||
autoFocus={true}
|
||||
|
@ -4,6 +4,7 @@ import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Field, Input, Button, LinkButton, Stack } from '@grafana/ui';
|
||||
import { getConfig } from 'app/core/config';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { w3cStandardEmailValidator } from 'app/features/admin/utils';
|
||||
|
||||
@ -113,9 +114,11 @@ export const SignupPage = ({ queryParams }: Props) => {
|
||||
</Field>
|
||||
|
||||
<Stack>
|
||||
<Button type="submit">Submit</Button>
|
||||
<Button type="submit">
|
||||
<Trans i18nKey="sign-up.submit-button">Submit</Trans>
|
||||
</Button>
|
||||
<LinkButton fill="text" href={getConfig().appSubUrl + '/login'}>
|
||||
Back to login
|
||||
<Trans i18nKey="sign-up.back-button">Back to login</Trans>
|
||||
</LinkButton>
|
||||
</Stack>
|
||||
</form>
|
||||
|
@ -5,6 +5,7 @@ import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Field, Input, Button, Legend, Container, LinkButton, Stack } from '@grafana/ui';
|
||||
import { getConfig } from 'app/core/config';
|
||||
import { useAppNotification } from 'app/core/copy/appNotification';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { w3cStandardEmailValidator } from 'app/features/admin/utils';
|
||||
|
||||
interface EmailDTO {
|
||||
@ -35,10 +36,14 @@ export const VerifyEmail = () => {
|
||||
if (emailSent) {
|
||||
return (
|
||||
<div>
|
||||
<p>An email with a verification link has been sent to the email address. You should receive it shortly.</p>
|
||||
<p>
|
||||
<Trans i18nKey="sign-up.verify.info">
|
||||
An email with a verification link has been sent to the email address. You should receive it shortly.
|
||||
</Trans>
|
||||
</p>
|
||||
<Container margin="md" />
|
||||
<LinkButton variant="primary" href={getConfig().appSubUrl + '/signup'}>
|
||||
Complete Signup
|
||||
<Trans i18nKey="sign-up.verify.complete-button">Complete signup</Trans>
|
||||
</LinkButton>
|
||||
</div>
|
||||
);
|
||||
@ -46,7 +51,9 @@ export const VerifyEmail = () => {
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Legend>Verify Email</Legend>
|
||||
<Legend>
|
||||
<Trans i18nKey="sign-up.verify.header">Verify email</Trans>
|
||||
</Legend>
|
||||
<Field
|
||||
label="Email"
|
||||
description="Enter your email address to get a verification link sent to you"
|
||||
@ -66,9 +73,11 @@ export const VerifyEmail = () => {
|
||||
/>
|
||||
</Field>
|
||||
<Stack>
|
||||
<Button type="submit">Send verification email</Button>
|
||||
<Button type="submit">
|
||||
<Trans i18nKey="sign-up.verify.send-button">Send verification email</Trans>
|
||||
</Button>
|
||||
<LinkButton fill="text" href={getConfig().appSubUrl + '/login'}>
|
||||
Back to login
|
||||
<Trans i18nKey="sign-up.verify.back-button">Back to login</Trans>
|
||||
</LinkButton>
|
||||
</Stack>
|
||||
</form>
|
||||
|
@ -28,7 +28,7 @@ jest.mock('@grafana/runtime', () => ({
|
||||
describe('VerifyEmail Page', () => {
|
||||
it('renders correctly', () => {
|
||||
render(<VerifyEmailPage />);
|
||||
expect(screen.getByText('Verify Email')).toBeInTheDocument();
|
||||
expect(screen.getByText('Verify email')).toBeInTheDocument();
|
||||
expect(screen.getByRole('textbox', { name: /Email/i })).toBeInTheDocument();
|
||||
|
||||
expect(screen.getByRole('button', { name: 'Send verification email' })).toBeInTheDocument();
|
||||
@ -60,7 +60,7 @@ describe('VerifyEmail Page', () => {
|
||||
email: 'test@gmail.com',
|
||||
})
|
||||
);
|
||||
expect(screen.getByRole('link', { name: 'Complete Signup' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: 'Complete Signup' })).toHaveAttribute('href', '/signup');
|
||||
expect(screen.getByRole('link', { name: 'Complete signup' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('link', { name: 'Complete signup' })).toHaveAttribute('href', '/signup');
|
||||
});
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ import { components, MultiValueRemoveProps } from 'react-select';
|
||||
|
||||
import { escapeStringForRegex, GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import { Icon, MultiSelect, useStyles2 } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { TagBadge, getStyles as getTagBadgeStyles } from './TagBadge';
|
||||
import { TagOption, TagSelectOption } from './TagOption';
|
||||
@ -156,7 +156,7 @@ export const TagFilter = ({
|
||||
<div className={styles.tagFilter}>
|
||||
{isClearable && tags.length > 0 && (
|
||||
<button className={styles.clear} onClick={() => onTagChange([])}>
|
||||
Clear tags
|
||||
<Trans i18nKey="tag-filter.clear-button">Clear tags</Trans>
|
||||
</button>
|
||||
)}
|
||||
<MultiSelect key={selectKey} {...selectOptions} prefix={<Icon name="tag-alt" />} aria-label="Tag filter" />
|
||||
|
@ -4,6 +4,7 @@ import { HTMLAttributes, useEffect } from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { reportExperimentView } from '@grafana/runtime/src';
|
||||
import { Button, Icon, LinkButton, useStyles2 } from '@grafana/ui';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
type ComponentSize = 'sm' | 'md';
|
||||
|
||||
@ -36,7 +37,11 @@ export const UpgradeBox = ({
|
||||
<Icon name={'rocket'} className={styles.icon} />
|
||||
<div className={styles.inner}>
|
||||
<p className={styles.text}>
|
||||
You’ve discovered a Pro feature! {text || `Get the Grafana Pro plan to access ${featureName}.`}
|
||||
<Trans i18nKey="upgrade-box.discovery-text">You’ve discovered a Pro feature!</Trans>{' '}
|
||||
{text ||
|
||||
t('upgrade-box.discovery-text-continued', 'Get the Grafana Pro plan to access {{featureName}}.', {
|
||||
featureName,
|
||||
})}
|
||||
</p>
|
||||
<LinkButton
|
||||
variant="secondary"
|
||||
@ -46,7 +51,7 @@ export const UpgradeBox = ({
|
||||
target="__blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Upgrade
|
||||
<Trans i18nKey="upgrade-box.upgrade-button">Upgrade</Trans>
|
||||
</LinkButton>
|
||||
</div>
|
||||
</div>
|
||||
@ -130,7 +135,9 @@ export const UpgradeContent = ({
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<h3 className={styles.title}>Get started with {featureName}</h3>
|
||||
<h3 className={styles.title}>
|
||||
<Trans i18nKey="upgrade-box.get-started">Get started with {{ featureName }}</Trans>
|
||||
</h3>
|
||||
{description && <h6 className={styles.description}>{description}</h6>}
|
||||
<ul className={styles.list}>
|
||||
{listItems.map((item, index) => (
|
||||
@ -151,7 +158,7 @@ export const UpgradeContent = ({
|
||||
)}
|
||||
{featureUrl && (
|
||||
<LinkButton fill={'text'} href={featureUrl} className={styles.link} target="_blank" rel="noreferrer noopener">
|
||||
Learn more
|
||||
<Trans i18nKey="upgrade-box.learn-more">Learn more</Trans>
|
||||
</LinkButton>
|
||||
)}
|
||||
</div>
|
||||
@ -221,10 +228,12 @@ export const UpgradeContentVertical = ({
|
||||
const styles = useStyles2(getContentVerticalStyles);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<h3 className={styles.title}>Get started with {featureName}</h3>
|
||||
<h3 className={styles.title}>
|
||||
<Trans i18nKey="upgrade-box.get-started">Get started with {{ featureName }}</Trans>
|
||||
</h3>
|
||||
{description && <h6 className={styles.description}>{description}</h6>}
|
||||
<LinkButton fill={'text'} href={featureUrl} target="_blank" rel="noreferrer noopener">
|
||||
Learn more
|
||||
<Trans i18nKey="upgrade-box.learn-more">Learn more</Trans>
|
||||
</LinkButton>
|
||||
<div className={styles.media}>
|
||||
<img src={getImgUrl(image)} alt={'Feature screenshot'} />
|
||||
|
@ -3,7 +3,7 @@ import { useMemo } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Grid, Modal, useStyles2, Text } from '@grafana/ui';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { getModKey } from 'app/core/utils/browser';
|
||||
|
||||
const getShortcuts = (modKey: string) => {
|
||||
@ -165,8 +165,12 @@ export const HelpModal = ({ onDismiss }: HelpModalProps): JSX.Element => {
|
||||
</caption>
|
||||
<thead className="sr-only">
|
||||
<tr>
|
||||
<th>Keys</th>
|
||||
<th>Description</th>
|
||||
<th>
|
||||
<Trans i18nKey="help-modal.column-headers.keys">Keys</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="help-modal.column-headers.description">Description</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -6,6 +6,7 @@ import { GrafanaTheme2, locationUtil, PageLayoutType } from '@grafana/data';
|
||||
import { Button, ErrorWithStack, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { Page } from '../components/Page/Page';
|
||||
import { Trans } from '../internationalization';
|
||||
|
||||
interface Props {
|
||||
error: Error | null;
|
||||
@ -31,12 +32,18 @@ export function GrafanaRouteError({ error, errorInfo }: Props) {
|
||||
<div className={styles.container}>
|
||||
{isChunkLoadingError && (
|
||||
<div>
|
||||
<h2>Unable to find application file</h2>
|
||||
<h2>
|
||||
<Trans i18nKey="route-error.title">Unable to find application file</Trans>
|
||||
</h2>
|
||||
<br />
|
||||
<h2 className="page-heading">Grafana has likely been updated. Please try reloading the page.</h2>
|
||||
<h2 className="page-heading">
|
||||
<Trans i18nKey="route-error.description">
|
||||
Grafana has likely been updated. Please try reloading the page.
|
||||
</Trans>
|
||||
</h2>
|
||||
<br />
|
||||
<Button size="md" variant="secondary" icon="repeat" onClick={() => window.location.reload()}>
|
||||
Reload
|
||||
<Trans i18nKey="route-error.reload-button">Reload</Trans>
|
||||
</Button>
|
||||
<ErrorWithStack title={'Error details'} error={error} errorInfo={errorInfo} />
|
||||
</div>
|
||||
|
@ -1,46 +0,0 @@
|
||||
import { Link } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { getAppRoutes } from '../../routes/routes';
|
||||
import { PageContents } from '../components/Page/PageContents';
|
||||
|
||||
import { RouteDescriptor } from './types';
|
||||
|
||||
export const RouterDebugger = () => {
|
||||
const manualRoutes: RouteDescriptor[] = [];
|
||||
return (
|
||||
<PageContents>
|
||||
<h1>Static routes</h1>
|
||||
<ul>
|
||||
{getAppRoutes().map((r, i) => {
|
||||
if (r.path.indexOf(':') > -1 || r.path.indexOf('test') > -1) {
|
||||
if (r.path.indexOf('test') === -1) {
|
||||
manualRoutes.push(r);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<li key={i}>
|
||||
<Link target="_blank" to={r.path}>
|
||||
{r.path}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
|
||||
<h1>Dynamic routes - check those manually</h1>
|
||||
<ul>
|
||||
{manualRoutes.map((r, i) => {
|
||||
return (
|
||||
<li key={i}>
|
||||
<Link key={`${i}-${r.path}`} target="_blank" to={r.path}>
|
||||
{r.path}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</PageContents>
|
||||
);
|
||||
};
|
@ -3,6 +3,7 @@ import { useState } from 'react';
|
||||
import { Action, DataFrame, VariableSuggestion } from '@grafana/data';
|
||||
import { Button } from '@grafana/ui/src/components/Button';
|
||||
import { Modal } from '@grafana/ui/src/components/Modal/Modal';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ActionEditor } from './ActionEditor';
|
||||
|
||||
@ -36,7 +37,7 @@ export const ActionEditorModalContent = ({
|
||||
/>
|
||||
<Modal.ButtonRow>
|
||||
<Button variant="secondary" onClick={() => onCancel(index)} fill="outline">
|
||||
Cancel
|
||||
<Trans i18nKey="action-editor.modal.cancel-button">Cancel</Trans>
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
@ -44,7 +45,7 @@ export const ActionEditorModalContent = ({
|
||||
}}
|
||||
disabled={dirtyAction.title.trim() === '' || dirtyAction.fetch.url.trim() === ''}
|
||||
>
|
||||
Save
|
||||
<Trans i18nKey="action-editor.modal.save-button">Save</Trans>
|
||||
</Button>
|
||||
</Modal.ButtonRow>
|
||||
</>
|
||||
|
@ -7,6 +7,7 @@ import { Action, DataFrame, GrafanaTheme2, defaultActionConfig, VariableSuggesti
|
||||
import { Button } from '@grafana/ui/src/components/Button';
|
||||
import { Modal } from '@grafana/ui/src/components/Modal/Modal';
|
||||
import { useStyles2 } from '@grafana/ui/src/themes';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { ActionEditorModalContent } from './ActionEditorModalContent';
|
||||
import { ActionListItem } from './ActionsListItem';
|
||||
@ -95,7 +96,9 @@ export const ActionsInlineEditor = ({
|
||||
{/* one-link placeholder */}
|
||||
{showOneClick && actionsSafe.length > 0 && (
|
||||
<div className={styles.oneClickOverlay}>
|
||||
<span className={styles.oneClickSpan}>One-click link</span>
|
||||
<span className={styles.oneClickSpan}>
|
||||
<Trans i18nKey="actions-editor.inline.one-click-link">One-click link</Trans>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -151,7 +154,7 @@ export const ActionsInlineEditor = ({
|
||||
)}
|
||||
|
||||
<Button size="sm" icon="plus" onClick={onActionAdd} variant="secondary" className={styles.button}>
|
||||
Add action
|
||||
<Trans i18nKey="actions-editor.inline.add-button">Add action</Trans>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
@ -7,6 +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 { OrgUser, AccessControlAction, OrgRole } from 'app/types';
|
||||
|
||||
import { OrgUsersTable } from './Users/OrgUsersTable';
|
||||
@ -56,8 +57,10 @@ const AdminEditOrgPage = () => {
|
||||
|
||||
const renderMissingPermissionMessage = () => (
|
||||
<Alert severity="info" title="Access denied">
|
||||
You do not have permission to see users in this organization. To update this organization, contact your server
|
||||
administrator.
|
||||
<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.
|
||||
</Trans>
|
||||
</Alert>
|
||||
);
|
||||
|
||||
@ -85,7 +88,9 @@ const AdminEditOrgPage = () => {
|
||||
<Page navId="global-orgs" pageNav={pageNav} subTitle="Manage settings for this specific org.">
|
||||
<Page.Contents>
|
||||
<>
|
||||
<Legend>Edit organization</Legend>
|
||||
<Legend>
|
||||
<Trans i18nKey="admin.edit-org.heading">Edit Organization</Trans>
|
||||
</Legend>
|
||||
{orgState.value && (
|
||||
<form onSubmit={handleSubmit(onUpdateOrgName)} style={{ maxWidth: '600px' }}>
|
||||
<Field label="Name" invalid={!!errors.orgName} error="Name is required" disabled={!canWriteOrg}>
|
||||
@ -96,13 +101,15 @@ const AdminEditOrgPage = () => {
|
||||
/>
|
||||
</Field>
|
||||
<Button type="submit" disabled={!canWriteOrg}>
|
||||
Update
|
||||
<Trans i18nKey="admin.edit-org.update-button">Update</Trans>
|
||||
</Button>
|
||||
</form>
|
||||
)}
|
||||
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
<Legend>Organization users</Legend>
|
||||
<Legend>
|
||||
<Trans i18nKey="admin.edit-org.users-heading">Organization users</Trans>
|
||||
</Legend>
|
||||
{!canReadUsers && renderMissingPermissionMessage()}
|
||||
{canReadUsers && !!users.length && (
|
||||
<OrgUsersTable
|
||||
|
@ -5,6 +5,7 @@ import { useAsync } from 'react-use';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { useStyles2, Icon } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { getTogglesAPI } from './AdminFeatureTogglesAPI';
|
||||
import { AdminFeatureTogglesTable } from './AdminFeatureTogglesTable';
|
||||
@ -36,15 +37,17 @@ export default function AdminFeatureTogglesPage() {
|
||||
|
||||
const subTitle = (
|
||||
<div>
|
||||
View and edit feature toggles. Read more about feature toggles at{' '}
|
||||
<a
|
||||
className="external-link"
|
||||
target="_new"
|
||||
href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/"
|
||||
>
|
||||
grafana.com
|
||||
</a>
|
||||
.
|
||||
<Trans i18nKey="admin.feature-toggles.sub-title">
|
||||
View and edit feature toggles. Read more about feature toggles at{' '}
|
||||
<a
|
||||
className="external-link"
|
||||
target="_new"
|
||||
href="https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/"
|
||||
>
|
||||
grafana.com
|
||||
</a>
|
||||
.
|
||||
</Trans>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
@ -4,6 +4,7 @@ import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||
import { getBackendSrv, isFetchError } from '@grafana/runtime';
|
||||
import { LinkButton } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import { AccessControlAction, Organization } from 'app/types';
|
||||
|
||||
@ -34,7 +35,7 @@ export default function AdminListOrgsPages() {
|
||||
navId="global-orgs"
|
||||
actions={
|
||||
<LinkButton icon="plus" href="org/new" disabled={!canCreateOrg}>
|
||||
New org
|
||||
<Trans i18nKey="admin.orgs.new-org-button">New org</Trans>
|
||||
</LinkButton>
|
||||
}
|
||||
>
|
||||
|
@ -6,6 +6,7 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Button, ConfirmModal, useStyles2 } from '@grafana/ui';
|
||||
import { SkeletonComponent, attachSkeleton } from '@grafana/ui/src/unstable';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { AccessControlAction, Organization } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -16,8 +17,12 @@ interface Props {
|
||||
const getTableHeader = () => (
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>
|
||||
<Trans i18nKey="admin.orgs.id-header">ID</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="admin.orgs.name-header">Name</Trans>
|
||||
</th>
|
||||
<th style={{ width: '1%' }}></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -27,6 +32,7 @@ function AdminOrgsTableComponent({ orgs, onDelete }: Props) {
|
||||
const canDeleteOrgs = contextSrv.hasPermission(AccessControlAction.OrgsDelete);
|
||||
|
||||
const [deleteOrg, setDeleteOrg] = useState<Organization>();
|
||||
const deleteOrgName = deleteOrg?.name;
|
||||
return (
|
||||
<table className="filter-table form-inline filter-table--hover">
|
||||
{getTableHeader()}
|
||||
@ -59,8 +65,10 @@ function AdminOrgsTableComponent({ orgs, onDelete }: Props) {
|
||||
title="Delete"
|
||||
body={
|
||||
<div>
|
||||
Are you sure you want to delete '{deleteOrg.name}'?
|
||||
<br /> <small>All dashboards for this organization will be removed!</small>
|
||||
<Trans i18nKey="admin.orgs.delete-body">
|
||||
Are you sure you want to delete '{{ deleteOrgName }}'?
|
||||
<br /> <small>All dashboards for this organization will be removed!</small>
|
||||
</Trans>
|
||||
</div>
|
||||
}
|
||||
confirmText="Delete"
|
||||
|
@ -3,6 +3,7 @@ import { useAsync } from 'react-use';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Alert } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { AdminSettingsTable } from './AdminSettingsTable';
|
||||
|
||||
@ -15,8 +16,10 @@ function AdminSettings() {
|
||||
<Page navId="server-settings">
|
||||
<Page.Contents>
|
||||
<Alert severity="info" title="">
|
||||
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.
|
||||
<Trans i18nKey="admin.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.
|
||||
</Trans>
|
||||
</Alert>
|
||||
|
||||
{loading && <AdminSettingsTable.Skeleton />}
|
||||
|
@ -4,6 +4,7 @@ import { useEffect, useState } from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { config, GrafanaBootConfig } from '@grafana/runtime';
|
||||
import { LinkButton, useStyles2 } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
import { contextSrv } from '../../core/services/context_srv';
|
||||
@ -34,9 +35,13 @@ export const ServerStats = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className={styles.title}>Instance statistics</h2>
|
||||
<h2 className={styles.title}>
|
||||
<Trans i18nKey="admin.server-settings.title">Instance statistics</Trans>
|
||||
</h2>
|
||||
{!isLoading && !stats ? (
|
||||
<p className={styles.notFound}>No stats found.</p>
|
||||
<p className={styles.notFound}>
|
||||
<Trans i18nKey="admin.server-settings.not-found">No stats found.</Trans>
|
||||
</p>
|
||||
) : (
|
||||
<div className={styles.row}>
|
||||
<ServerStatsCard
|
||||
@ -49,7 +54,7 @@ export const ServerStats = () => {
|
||||
]}
|
||||
footer={
|
||||
<LinkButton href={'/dashboards'} variant={'secondary'}>
|
||||
Manage dashboards
|
||||
<Trans i18nKey="admin.server-settings.dashboards-button">Manage dashboards</Trans>
|
||||
</LinkButton>
|
||||
}
|
||||
/>
|
||||
@ -61,7 +66,7 @@ export const ServerStats = () => {
|
||||
footer={
|
||||
hasAccessToDataSources && (
|
||||
<LinkButton href={'/datasources'} variant={'secondary'}>
|
||||
Manage data sources
|
||||
<Trans i18nKey="admin.server-settings.data-sources-button">Manage data sources</Trans>
|
||||
</LinkButton>
|
||||
)
|
||||
}
|
||||
@ -71,7 +76,7 @@ export const ServerStats = () => {
|
||||
content={[{ name: 'Alerts', value: stats?.alerts }]}
|
||||
footer={
|
||||
<LinkButton href={'/alerting/list'} variant={'secondary'}>
|
||||
Manage alerts
|
||||
<Trans i18nKey="admin.server-settings.alerts-button">Manage alerts</Trans>
|
||||
</LinkButton>
|
||||
}
|
||||
/>
|
||||
@ -88,7 +93,7 @@ export const ServerStats = () => {
|
||||
footer={
|
||||
hasAccessToAdminUsers && (
|
||||
<LinkButton href={'/admin/users'} variant={'secondary'}>
|
||||
Manage users
|
||||
<Trans i18nKey="admin.server-settings.users-button">Manage users</Trans>
|
||||
</LinkButton>
|
||||
)
|
||||
}
|
||||
|
@ -5,6 +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 { getNavModel } from '../../core/selectors/navModel';
|
||||
import { StoreState } from '../../types';
|
||||
@ -41,7 +42,9 @@ export const UpgradeInfo = ({ editionNotice }: UpgradeInfoProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2 className={styles.title}>Enterprise license</h2>
|
||||
<h2 className={styles.title}>
|
||||
<Trans i18nKey="admin.upgrade-info.title">Enterprise license</Trans>
|
||||
</h2>
|
||||
<LicenseChrome header="Grafana Enterprise" subheader="Get your free trial" editionNotice={editionNotice}>
|
||||
<div className={styles.column}>
|
||||
<FeatureInfo />
|
||||
@ -73,11 +76,15 @@ const getStyles = (theme: GrafanaTheme2) => {
|
||||
const GetEnterprise = () => {
|
||||
return (
|
||||
<div style={{ marginTop: '40px', marginBottom: '30px' }}>
|
||||
<h2 style={titleStyles}>Get Grafana Enterprise</h2>
|
||||
<h2 style={titleStyles}>
|
||||
<Trans i18nKey="admin.get-enterprise.title">Get Grafana Enterprise</Trans>
|
||||
</h2>
|
||||
<CallToAction />
|
||||
<p style={{ paddingTop: '12px' }}>
|
||||
You can use the trial version for free for 30 days. We will remind you about it five days before the trial
|
||||
period ends.
|
||||
<Trans i18nKey="admin.get-enterprise.description">
|
||||
You can use the trial version for free for 30 days. We will remind you about it five days before the trial
|
||||
period ends.
|
||||
</Trans>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
@ -90,7 +97,7 @@ const CallToAction = () => {
|
||||
size="lg"
|
||||
href="https://grafana.com/contact?about=grafana-enterprise&utm_source=grafana-upgrade-page"
|
||||
>
|
||||
Contact us and get a free trial
|
||||
<Trans i18nKey="admin.get-enterprise.contact-us">Contact us and get a free trial</Trans>
|
||||
</LinkButton>
|
||||
);
|
||||
};
|
||||
@ -98,7 +105,9 @@ const CallToAction = () => {
|
||||
const ServiceInfo = () => {
|
||||
return (
|
||||
<div>
|
||||
<h4>At your service</h4>
|
||||
<h4>
|
||||
<Trans i18nKey="admin.get-enterprise.service-title">At your service</Trans>
|
||||
</h4>
|
||||
|
||||
<List>
|
||||
<Item title="Enterprise Plugins" image="public/img/licensing/plugin_enterprise.svg" />
|
||||
@ -117,9 +126,13 @@ const ServiceInfo = () => {
|
||||
</List>
|
||||
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
<strong>Also included:</strong>
|
||||
<strong>
|
||||
<Trans i18nKey="admin.get-enterprise.included-heading">Also included:</Trans>
|
||||
</strong>
|
||||
<br />
|
||||
Indemnification, working with Grafana Labs on future prioritization, and training from the core Grafana team.
|
||||
<Trans i18nKey="admin.get-enterprise.included-description">
|
||||
Indemnification, working with Grafana Labs on future prioritization, and training from the core Grafana team.
|
||||
</Trans>
|
||||
</div>
|
||||
|
||||
<GetEnterprise />
|
||||
@ -130,7 +143,9 @@ const ServiceInfo = () => {
|
||||
const FeatureInfo = () => {
|
||||
return (
|
||||
<div style={{ paddingRight: '11px' }}>
|
||||
<h4>Enhanced functionality</h4>
|
||||
<h4>
|
||||
<Trans i18nKey="admin.get-enterprise.features-heading">Enhanced functionality</Trans>
|
||||
</h4>
|
||||
<FeatureListing />
|
||||
</div>
|
||||
);
|
||||
@ -143,7 +158,9 @@ const FeatureListing = () => {
|
||||
<Item title="Reporting" />
|
||||
<Item title="SAML authentication" />
|
||||
<Item title="Enhanced LDAP integration" />
|
||||
<Item title="Team Sync">LDAP, GitHub OAuth, Auth Proxy, Okta</Item>
|
||||
<Item title="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" />
|
||||
|
@ -6,6 +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';
|
||||
|
||||
interface UserDTO {
|
||||
name: string;
|
||||
@ -69,7 +70,9 @@ const UserCreatePage = () => {
|
||||
type="password"
|
||||
/>
|
||||
</Field>
|
||||
<Button type="submit">Create user</Button>
|
||||
<Button type="submit">
|
||||
<Trans i18nKey="admin.users-create.create-button">Create user</Trans>
|
||||
</Button>
|
||||
</form>
|
||||
</Page.Contents>
|
||||
</Page>
|
||||
|
@ -3,6 +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 { AccessControlAction, SyncInfo, UserDTO } from 'app/types';
|
||||
|
||||
import { TagBadge } from '../../core/components/TagFilter/TagBadge';
|
||||
@ -33,30 +34,37 @@ export class UserLdapSyncInfo extends PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 className="page-heading">LDAP Synchronisation</h3>
|
||||
<h3 className="page-heading">
|
||||
<Trans i18nKey="admin.ldap-sync.title">LDAP Synchronisation</Trans>
|
||||
</h3>
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<table className="filter-table form-inline">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>External sync</td>
|
||||
<td>User synced via LDAP. Some changes must be done in LDAP or mappings.</td>
|
||||
<td>
|
||||
<Trans i18nKey="admin.ldap-sync.external-sync-label">External sync</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<Trans i18nKey="admin.ldap-sync.external-sync-description">
|
||||
User synced via LDAP. Some changes must be done in LDAP or mappings.
|
||||
</Trans>
|
||||
</td>
|
||||
<td>
|
||||
<TagBadge label="LDAP" removeIcon={false} count={0} onClick={undefined} />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
{ldapSyncInfo.enabled ? (
|
||||
<>
|
||||
<td>Next scheduled synchronization</td>
|
||||
<td colSpan={2}>{nextSyncTime}</td>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<td>Next scheduled synchronization</td>
|
||||
<td colSpan={2}>Not enabled</td>
|
||||
</>
|
||||
)}
|
||||
<td>
|
||||
<Trans i18nKey="admin.ldap-sync.next-sync-label">Next scheduled synchronization</Trans>
|
||||
</td>
|
||||
<td colSpan={2}>
|
||||
{ldapSyncInfo.enabled ? (
|
||||
nextSyncTime
|
||||
) : (
|
||||
<Trans i18nKey="admin.ldap-sync.not-enabled">Not enabled</Trans>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -64,12 +72,12 @@ export class UserLdapSyncInfo extends PureComponent<Props, State> {
|
||||
<div className="gf-form-button-row">
|
||||
{canSyncLDAPUser && (
|
||||
<Button variant="secondary" onClick={this.onUserSync}>
|
||||
Sync user
|
||||
<Trans i18nKey="admin.ldap-sync.sync-button">Sync user</Trans>
|
||||
</Button>
|
||||
)}
|
||||
{canReadLDAPUser && (
|
||||
<LinkButton variant="secondary" href={debugLDAPMappingURL}>
|
||||
Debug LDAP Mapping
|
||||
<Trans i18nKey="admin.ldap-sync.debug-button">Debug LDAP Mapping</Trans>
|
||||
</LinkButton>
|
||||
)}
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@ import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
|
||||
import { LinkButton, RadioButtonGroup, useStyles2, FilterInput, EmptyState } from '@grafana/ui';
|
||||
import { Page } from 'app/core/components/Page/Page';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
|
||||
import { AccessControlAction, StoreState, UserFilter } from '../../types';
|
||||
|
||||
@ -94,7 +94,7 @@ const UserListAdminPageUnConnected = ({
|
||||
))}
|
||||
{contextSrv.hasPermission(AccessControlAction.UsersCreate) && (
|
||||
<LinkButton href="admin/users/create" variant="primary">
|
||||
New user
|
||||
<Trans i18nKey="admin.users-list.create-button">New user</Trans>
|
||||
</LinkButton>
|
||||
)}
|
||||
</div>
|
||||
|
@ -57,7 +57,7 @@ export const DashboardsListModal = ({ email, onDismiss }: { email: string; onDis
|
||||
</Trans>
|
||||
)}
|
||||
</a>
|
||||
<span className={styles.urlsDivider}>•</span>
|
||||
<span className={styles.urlsDivider}>{'•'}</span>
|
||||
<a
|
||||
className={cx('external-link', styles.url)}
|
||||
href={generatePublicDashboardConfigUrl(dash.dashboardUid, dash.slug)}
|
||||
|
@ -59,7 +59,14 @@ export const UserListPublicDashboardPage = () => {
|
||||
<td className="max-width-10">{user.lastSeenAtAge}</td>
|
||||
<td className="max-width-10">
|
||||
<Stack gap={2}>
|
||||
<span>{user.totalDashboards} dashboard(s)</span>
|
||||
<span>
|
||||
<Trans
|
||||
i18nKey="public-dashboard-users-access-list.table-body.dashboard-count"
|
||||
count={user.totalDashboards}
|
||||
>
|
||||
{{ count: user.totalDashboards }} dashboards
|
||||
</Trans>
|
||||
</span>
|
||||
<DashboardsListModalButton email={user.email} />
|
||||
</Stack>
|
||||
</td>
|
||||
|
@ -19,6 +19,7 @@ import { UserRolePicker } from 'app/core/components/RolePicker/UserRolePicker';
|
||||
import { fetchRoleOptions, updateUserRoles } from 'app/core/components/RolePicker/api';
|
||||
import { OrgPicker, OrgSelectItem } from 'app/core/components/Select/OrgPicker';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { AccessControlAction, Organization, OrgRole, Role, UserDTO, UserOrg } from 'app/types';
|
||||
|
||||
import { OrgRolePicker } from './OrgRolePicker';
|
||||
@ -60,7 +61,9 @@ export class UserOrgs extends PureComponent<Props, State> {
|
||||
const canAddToOrg = contextSrv.hasPermission(AccessControlAction.OrgUsersAdd) && !isExternalUser;
|
||||
return (
|
||||
<div>
|
||||
<h3 className="page-heading">Organizations</h3>
|
||||
<h3 className="page-heading">
|
||||
<Trans i18nKey="admin.user-orgs.title">Organizations</Trans>
|
||||
</h3>
|
||||
<Stack gap={1.5} direction="column">
|
||||
<table className="filter-table form-inline">
|
||||
<tbody>
|
||||
@ -80,7 +83,7 @@ export class UserOrgs extends PureComponent<Props, State> {
|
||||
<div>
|
||||
{canAddToOrg && (
|
||||
<Button variant="secondary" onClick={this.showOrgAddModal} ref={this.addToOrgButtonRef}>
|
||||
Add user to organization
|
||||
<Trans i18nKey="admin.user-orgs.add-button">Add user to organization</Trans>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@ -242,7 +245,7 @@ class UnThemedOrgRow extends PureComponent<OrgRowProps> {
|
||||
onCancel={this.onCancelClick}
|
||||
onConfirm={this.onOrgRemove}
|
||||
>
|
||||
Remove from organization
|
||||
{t('admin.user-orgs.remove-button', 'Remove from organization')}
|
||||
</ConfirmButton>
|
||||
)}
|
||||
</td>
|
||||
@ -383,10 +386,10 @@ export class AddToOrgModal extends PureComponent<AddToOrgModalProps, AddToOrgMod
|
||||
<Modal.ButtonRow>
|
||||
<Stack gap={2} justifyContent="center">
|
||||
<Button variant="secondary" fill="outline" onClick={this.onCancel}>
|
||||
Cancel
|
||||
<Trans i18nKey="admin.user-orgs-modal.cancel-button">Cancel</Trans>
|
||||
</Button>
|
||||
<Button variant="primary" disabled={selectedOrg === null} onClick={this.onAddUserToOrg}>
|
||||
Add to organization
|
||||
<Trans i18nKey="admin.user-orgs-modal.add-button">Add to organization</Trans>
|
||||
</Button>
|
||||
</Stack>
|
||||
</Modal.ButtonRow>
|
||||
@ -438,17 +441,19 @@ export function ChangeOrgButton({
|
||||
interactive={true}
|
||||
content={
|
||||
<div>
|
||||
This user's role is not editable because it is synchronized from your auth provider. Refer to
|
||||
the
|
||||
<a
|
||||
className={styles.tooltipItemLink}
|
||||
href={'https://grafana.com/docs/grafana/latest/auth'}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Grafana authentication docs
|
||||
</a>
|
||||
for details.
|
||||
<Trans i18nKey="admin.user-orgs.role-not-editable">
|
||||
This user's role is not editable because it is synchronized from your auth provider. Refer to
|
||||
the
|
||||
<a
|
||||
className={styles.tooltipItemLink}
|
||||
href={'https://grafana.com/docs/grafana/latest/auth'}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Grafana authentication docs
|
||||
</a>
|
||||
for details.
|
||||
</Trans>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
@ -465,7 +470,7 @@ export function ChangeOrgButton({
|
||||
onConfirm={onOrgRoleSave}
|
||||
disabled={isExternalUser}
|
||||
>
|
||||
Change role
|
||||
{t('admin.user-orgs.change-role-button', 'Change role')}
|
||||
</ConfirmButton>
|
||||
)}
|
||||
</div>
|
||||
@ -486,17 +491,19 @@ export const ExternalUserTooltip = ({ lockMessage }: ExternalUserTooltipProps) =
|
||||
interactive={true}
|
||||
content={
|
||||
<div>
|
||||
This user's built-in role is not editable because it is synchronized from your auth provider. Refer to
|
||||
the
|
||||
<a
|
||||
className={styles.tooltipItemLink}
|
||||
href={'https://grafana.com/docs/grafana/latest/auth'}
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Grafana authentication docs
|
||||
</a>
|
||||
for details.
|
||||
<Trans i18nKey="admin.user-orgs.external-user-tooltip">
|
||||
This user's built-in role is not editable because it is synchronized from your auth provider. Refer
|
||||
to the
|
||||
<a
|
||||
className={styles.tooltipItemLink}
|
||||
href={'https://grafana.com/docs/grafana/latest/auth'}
|
||||
rel="noreferrer noopener"
|
||||
target="_blank"
|
||||
>
|
||||
Grafana authentication docs
|
||||
</a>
|
||||
for details.
|
||||
</Trans>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
@ -4,6 +4,7 @@ import { useState } from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { ConfirmButton, RadioButtonGroup, Icon, useStyles2 } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { ExternalUserTooltip } from 'app/features/admin/UserOrgs';
|
||||
import { AccessControlAction } from 'app/types';
|
||||
|
||||
@ -39,11 +40,15 @@ export function UserPermissions({ isGrafanaAdmin, isExternalUser, lockMessage, o
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="page-heading">Permissions</h3>
|
||||
<h3 className="page-heading">
|
||||
<Trans i18nKey="admin.user-permissions.title">Permissions</Trans>
|
||||
</h3>
|
||||
<table className="filter-table form-inline">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="width-16">Grafana Admin</td>
|
||||
<td className="width-16">
|
||||
<Trans i18nKey="admin.user-permissions.grafana-admin-key">Grafana Admin</Trans>
|
||||
</td>
|
||||
{isEditing ? (
|
||||
<td colSpan={2}>
|
||||
<RadioButtonGroup
|
||||
@ -57,10 +62,10 @@ export function UserPermissions({ isGrafanaAdmin, isExternalUser, lockMessage, o
|
||||
<td colSpan={2}>
|
||||
{isGrafanaAdmin ? (
|
||||
<>
|
||||
<Icon name="shield" /> Yes
|
||||
<Icon name="shield" /> <Trans i18nKey="admin.user-permissions.grafana-admin-yes">Yes</Trans>
|
||||
</>
|
||||
) : (
|
||||
<>No</>
|
||||
<Trans i18nKey="admin.user-permissions.grafana-admin-no">No</Trans>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
@ -72,7 +77,7 @@ export function UserPermissions({ isGrafanaAdmin, isExternalUser, lockMessage, o
|
||||
onCancel={onCancelClick}
|
||||
confirmText="Change"
|
||||
>
|
||||
Change
|
||||
{t('admin.user-permissions.change-button', 'Change')}
|
||||
</ConfirmButton>
|
||||
)}
|
||||
{isExternalUser && (
|
||||
|
@ -4,6 +4,7 @@ import * as React from 'react';
|
||||
|
||||
import { Button, ConfirmButton, ConfirmModal, Input, LegacyInputStatus, Stack } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { AccessControlAction, UserDTO } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -82,7 +83,9 @@ export function UserProfile({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="page-heading">User information</h3>
|
||||
<h3 className="page-heading">
|
||||
<Trans i18nKey="admin.user-profile.title">User information</Trans>
|
||||
</h3>
|
||||
<Stack direction="column" gap={1.5}>
|
||||
<div>
|
||||
<table className="filter-table form-inline">
|
||||
@ -124,7 +127,7 @@ export function UserProfile({
|
||||
{canDelete && (
|
||||
<>
|
||||
<Button variant="destructive" onClick={showDeleteUserModal(true)} ref={deleteUserRef}>
|
||||
Delete user
|
||||
<Trans i18nKey="admin.user-profile.delete-button">Delete user</Trans>
|
||||
</Button>
|
||||
<ConfirmModal
|
||||
isOpen={showDeleteModal}
|
||||
@ -138,13 +141,13 @@ export function UserProfile({
|
||||
)}
|
||||
{user.isDisabled && canEnable && (
|
||||
<Button variant="secondary" onClick={handleUserEnable}>
|
||||
Enable user
|
||||
<Trans i18nKey="admin.user-profile.enable-button">Enable user</Trans>
|
||||
</Button>
|
||||
)}
|
||||
{!user.isDisabled && canDisable && (
|
||||
<>
|
||||
<Button variant="secondary" onClick={showDisableUserModal(true)} ref={disableUserRef}>
|
||||
Disable user
|
||||
<Trans i18nKey="admin.user-profile.disable-button">Disable user</Trans>
|
||||
</Button>
|
||||
<ConfirmModal
|
||||
isOpen={showDisableModal}
|
||||
@ -282,7 +285,7 @@ export class UserProfileRow extends PureComponent<UserProfileRowProps, UserProfi
|
||||
onConfirm={this.onSave}
|
||||
onCancel={this.onCancelClick}
|
||||
>
|
||||
Edit
|
||||
{t('admin.user-profile.edit-button', 'Edit')}
|
||||
</ConfirmButton>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -3,7 +3,7 @@ import { createRef, PureComponent } from 'react';
|
||||
import { ConfirmButton, ConfirmModal, Button, Stack } from '@grafana/ui';
|
||||
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { formatDate } from 'app/core/internationalization/dates';
|
||||
import { AccessControlAction, UserSession } from 'app/types';
|
||||
|
||||
@ -53,16 +53,26 @@ class BaseUserSessions extends PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h3 className="page-heading">Sessions</h3>
|
||||
<h3 className="page-heading">
|
||||
<Trans i18nKey="admin.user-sessions.title">Sessions</Trans>
|
||||
</h3>
|
||||
<Stack direction="column" gap={1.5}>
|
||||
<div>
|
||||
<table className="filter-table form-inline">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Last seen</th>
|
||||
<th>Logged on</th>
|
||||
<th>IP address</th>
|
||||
<th>Browser and OS</th>
|
||||
<th>
|
||||
<Trans i18nKey="admin.user-sessions.last-seen-column">Last seen</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="admin.user-sessions.logged-on-column">Logged on</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="admin.user-sessions.ip-column">IP address</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="admin.user-sessions.browser-column">Browser and OS</Trans>
|
||||
</th>
|
||||
<th colSpan={2}>
|
||||
<Trans i18nKey="user-session.auth-module-column">Identity Provider</Trans>
|
||||
</th>
|
||||
@ -86,7 +96,7 @@ class BaseUserSessions extends PureComponent<Props, State> {
|
||||
confirmVariant="destructive"
|
||||
onConfirm={this.onSessionRevoke(session.id)}
|
||||
>
|
||||
Force logout
|
||||
{t('admin.user-sessions.force-logout-button', 'Force logout')}
|
||||
</ConfirmButton>
|
||||
)}
|
||||
</td>
|
||||
@ -99,7 +109,7 @@ class BaseUserSessions extends PureComponent<Props, State> {
|
||||
<div>
|
||||
{canLogout && sessions.length > 0 && (
|
||||
<Button variant="secondary" onClick={this.showLogoutConfirmationModal} ref={this.forceAllLogoutButton}>
|
||||
Force logout from all devices
|
||||
<Trans i18nKey="admin.user-sessions.force-logout-all-button">Force logout from all devices</Trans>
|
||||
</Button>
|
||||
)}
|
||||
<ConfirmModal
|
||||
|
@ -11,6 +11,7 @@ import {
|
||||
Pagination,
|
||||
FetchDataFunc,
|
||||
} from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { EmptyArea } from 'app/features/alerting/unified/components/EmptyArea';
|
||||
import { UserAnonymousDeviceDTO } from 'app/types';
|
||||
|
||||
@ -117,7 +118,9 @@ export const AnonUsersDevicesTable = ({
|
||||
)}
|
||||
{devices.length === 0 && (
|
||||
<EmptyArea>
|
||||
<span>No anonymous users found.</span>
|
||||
<span>
|
||||
<Trans i18nKey="admin.anon-users.not-found">No anonymous users found.</Trans>
|
||||
</span>
|
||||
</EmptyArea>
|
||||
)}
|
||||
</Stack>
|
||||
|
@ -24,6 +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 { AccessControlAction, OrgUser, Role } from 'app/types';
|
||||
|
||||
import { OrgRolePicker } from '../OrgRolePicker';
|
||||
@ -113,7 +114,21 @@ export const OrgUsersTable = ({
|
||||
id: 'lastSeenAtAge',
|
||||
header: 'Last active',
|
||||
cell: ({ cell: { value } }: Cell<'lastSeenAtAge'>) => {
|
||||
return <>{value && <>{value === '10 years' ? <Text color={'disabled'}>Never</Text> : value}</>}</>;
|
||||
return (
|
||||
<>
|
||||
{value && (
|
||||
<>
|
||||
{value === '10 years' ? (
|
||||
<Text color={'disabled'}>
|
||||
<Trans i18nKey="admin.org-uers.last-seen-never">Never</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
value
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
},
|
||||
sortType: (a, b) => new Date(a.original.lastSeenAt).getTime() - new Date(b.original.lastSeenAt).getTime(),
|
||||
},
|
||||
@ -170,18 +185,20 @@ export const OrgUsersTable = ({
|
||||
interactive={true}
|
||||
content={
|
||||
<div>
|
||||
This user's role is not editable because it is synchronized from your auth provider. Refer to
|
||||
the
|
||||
<a
|
||||
href={
|
||||
'https://grafana.com/docs/grafana/latest/administration/user-management/manage-org-users/#change-a-users-organization-permissions'
|
||||
}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Grafana authentication docs
|
||||
</a>
|
||||
for details.
|
||||
<Trans i18nKey="admin.org-users.not-editable">
|
||||
This user's role is not editable because it is synchronized from your auth provider. Refer
|
||||
to the
|
||||
<a
|
||||
href={
|
||||
'https://grafana.com/docs/grafana/latest/administration/user-management/manage-org-users/#change-a-users-organization-permissions'
|
||||
}
|
||||
rel="noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Grafana authentication docs
|
||||
</a>
|
||||
for details.
|
||||
</Trans>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
Tooltip,
|
||||
} from '@grafana/ui';
|
||||
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { UserDTO } from 'app/types';
|
||||
|
||||
import { OrgUnits } from './OrgUnits';
|
||||
@ -101,10 +102,12 @@ export const UsersTable = ({
|
||||
cell: ({ cell: { value } }: Cell<'licensedRole'>) => {
|
||||
return value === 'None' ? (
|
||||
<Text color={'disabled'}>
|
||||
Not assigned{' '}
|
||||
<Tooltip placement="top" content="A licensed role will be assigned when this user signs in">
|
||||
<Icon name="question-circle" />
|
||||
</Tooltip>
|
||||
<Trans i18nKey="admin.users-table.no-licensed-role">
|
||||
Not assigned{' '}
|
||||
<Tooltip placement="top" content="A licensed role will be assigned when this user signs in">
|
||||
<Icon name="question-circle" />
|
||||
</Tooltip>
|
||||
</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
value
|
||||
@ -121,7 +124,21 @@ export const UsersTable = ({
|
||||
iconName: 'question-circle',
|
||||
},
|
||||
cell: ({ cell: { value } }: Cell<'lastSeenAtAge'>) => {
|
||||
return <>{value && <>{value === '10 years' ? <Text color={'disabled'}>Never</Text> : value}</>}</>;
|
||||
return (
|
||||
<>
|
||||
{value && (
|
||||
<>
|
||||
{value === '10 years' ? (
|
||||
<Text color={'disabled'}>
|
||||
<Trans i18nKey="admin.users-table.last-seen-never">Never</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
value
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
},
|
||||
sortType: (a, b) => new Date(a.original.lastSeenAt!).getTime() - new Date(b.original.lastSeenAt!).getTime(),
|
||||
},
|
||||
|
@ -1,6 +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 { AppNotificationSeverity, LdapConnectionInfo, LdapServerInfo } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -54,7 +55,7 @@ export const LdapConnectionStatus = ({ ldapConnectionInfo }: Props) => {
|
||||
<section>
|
||||
<Stack direction="column" gap={2}>
|
||||
<Text color="primary" element="h3">
|
||||
LDAP Connection
|
||||
<Trans i18nKey="admin.ldap-status.title">LDAP Connection</Trans>
|
||||
</Text>
|
||||
<InteractiveTable data={data} columns={columns} getRowId={(serverInfo) => serverInfo.host + serverInfo.port} />
|
||||
<LdapErrorBox ldapConnectionInfo={ldapConnectionInfo} />
|
||||
@ -83,7 +84,7 @@ export const LdapErrorBox = ({ ldapConnectionInfo }: LdapConnectionErrorProps) =
|
||||
const errorElements = connectionErrors.map((info, index) => (
|
||||
<div key={index}>
|
||||
<span style={{ fontWeight: 500 }}>
|
||||
{info.host}:{info.port}
|
||||
{`${info.host}:${info.port}`}
|
||||
<br />
|
||||
</span>
|
||||
<span>{info.error}</span>
|
||||
|
@ -7,6 +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 { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import {
|
||||
AppNotificationSeverity,
|
||||
@ -118,7 +119,9 @@ export const LdapPage = ({
|
||||
|
||||
{canReadLDAPUser && (
|
||||
<section>
|
||||
<h3>Test user mapping</h3>
|
||||
<h3>
|
||||
<Trans i18nKey="admin.ldap.test-mapping-heading">Test user mapping</Trans>
|
||||
</h3>
|
||||
<form onSubmit={handleSubmit(search)}>
|
||||
<Field label="Username">
|
||||
<Input
|
||||
@ -129,7 +132,7 @@ export const LdapPage = ({
|
||||
defaultValue={queryParams.username}
|
||||
addonAfter={
|
||||
<Button variant="primary" type="submit">
|
||||
Run
|
||||
<Trans i18nKey="admin.ldap.test-mapping-run-button">Run</Trans>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { dateTimeFormat } from '@grafana/data';
|
||||
import { InteractiveTable, Text } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { SyncInfo } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -29,7 +30,9 @@ export const LdapSyncInfo = ({ ldapSyncInfo }: Props) => {
|
||||
|
||||
return (
|
||||
<section>
|
||||
<Text element="h3">LDAP Synchronization</Text>
|
||||
<Text element="h3">
|
||||
<Trans i18nKey="admin.ldap-sync-info.title">LDAP Synchronization</Trans>
|
||||
</Text>
|
||||
<InteractiveTable data={data} columns={columns} getRowId={(sync) => sync.syncAttribute} />
|
||||
</section>
|
||||
);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { Tooltip, Icon, InteractiveTable, type CellProps, Column } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { LdapRole } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -28,10 +29,12 @@ export const LdapUserGroups = ({ groups }: Props) => {
|
||||
cell: (props: CellProps<LdapRole, string | undefined>) =>
|
||||
props.value || (
|
||||
<>
|
||||
No match{' '}
|
||||
<Tooltip content="No matching organizations found">
|
||||
<Icon name="info-circle" />
|
||||
</Tooltip>
|
||||
<Trans i18nKey="admin.ldap-user-groups.no-org-found">
|
||||
No match{' '}
|
||||
<Tooltip content="No matching organizations found">
|
||||
<Icon name="info-circle" />
|
||||
</Tooltip>
|
||||
</Trans>
|
||||
</>
|
||||
),
|
||||
},
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Box, Stack, Text } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { LdapUser } from 'app/types';
|
||||
|
||||
import { LdapUserGroups } from './LdapUserGroups';
|
||||
@ -21,7 +22,9 @@ export const LdapUserInfo = ({ ldapUser }: Props) => {
|
||||
<LdapUserTeams teams={ldapUser.teams} />
|
||||
) : (
|
||||
<Box>
|
||||
<Text>No teams found via LDAP</Text>
|
||||
<Text>
|
||||
<Trans i18nKey="admin.ldap-user-info.no-team">No teams found via LDAP</Trans>
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Stack>
|
||||
|
@ -2,6 +2,7 @@ import { useMemo } from 'react';
|
||||
import * as React from 'react';
|
||||
|
||||
import { Column, Icon, InteractiveTable } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { LdapPermissions } from 'app/types';
|
||||
|
||||
interface Props {
|
||||
@ -33,9 +34,9 @@ export const LdapUserPermissions = ({ permissions }: Props) => {
|
||||
{
|
||||
permission: 'Grafana admin',
|
||||
value: permissions.isGrafanaAdmin ? (
|
||||
<>
|
||||
<Trans i18nKey="admin.ldap-permissions.admin">
|
||||
<Icon name="shield" /> Yes
|
||||
</>
|
||||
</Trans>
|
||||
) : (
|
||||
'No'
|
||||
),
|
||||
@ -43,13 +44,13 @@ export const LdapUserPermissions = ({ permissions }: Props) => {
|
||||
{
|
||||
permission: 'Status',
|
||||
value: permissions.isDisabled ? (
|
||||
<>
|
||||
<Trans i18nKey="admin.ldap-permissions.inactive">
|
||||
<Icon name="times" /> Inactive
|
||||
</>
|
||||
</Trans>
|
||||
) : (
|
||||
<>
|
||||
<Trans i18nKey="admin.ldap-permissions.active">
|
||||
<Icon name="check" /> Active
|
||||
</>
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
],
|
||||
|
@ -14,6 +14,9 @@
|
||||
"permission-list": {
|
||||
"permission": "Permission"
|
||||
},
|
||||
"permission-list-item": {
|
||||
"inherited": "Inherited from folder"
|
||||
},
|
||||
"permissions": {
|
||||
"add-label": "Add a permission",
|
||||
"no-permissions": "There are no permissions",
|
||||
@ -25,6 +28,143 @@
|
||||
"user": "User"
|
||||
}
|
||||
},
|
||||
"action-editor": {
|
||||
"modal": {
|
||||
"cancel-button": "Cancel",
|
||||
"save-button": "Save"
|
||||
}
|
||||
},
|
||||
"actions-editor": {
|
||||
"inline": {
|
||||
"add-button": "Add action",
|
||||
"one-click-link": "One-click link"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"anon-users": {
|
||||
"not-found": "No anonymous users found."
|
||||
},
|
||||
"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-toggles": {
|
||||
"sub-title": "View and edit feature toggles. Read more about feature toggles at <2>grafana.com</2>."
|
||||
},
|
||||
"get-enterprise": {
|
||||
"contact-us": "Contact us and get a free trial",
|
||||
"description": "You can use the trial version for free for 30 days. We will remind you about it five days before the trial period ends.",
|
||||
"features-heading": "Enhanced functionality",
|
||||
"included-description": "Indemnification, working with Grafana Labs on future prioritization, and training from the core Grafana team.",
|
||||
"included-heading": "Also included:",
|
||||
"service-title": "At your service",
|
||||
"team-sync-details": "LDAP, GitHub OAuth, Auth Proxy, Okta",
|
||||
"title": "Get Grafana Enterprise"
|
||||
},
|
||||
"ldap": {
|
||||
"test-mapping-heading": "Test user mapping",
|
||||
"test-mapping-run-button": "Run"
|
||||
},
|
||||
"ldap-permissions": {
|
||||
"active": "<0></0> Active",
|
||||
"admin": "<0></0> Yes",
|
||||
"inactive": "<0></0> Inactive"
|
||||
},
|
||||
"ldap-status": {
|
||||
"title": "LDAP Connection"
|
||||
},
|
||||
"ldap-sync": {
|
||||
"debug-button": "Debug LDAP Mapping",
|
||||
"external-sync-description": "User synced via LDAP. Some changes must be done in LDAP or mappings.",
|
||||
"external-sync-label": "External sync",
|
||||
"next-sync-label": "Next scheduled synchronization",
|
||||
"not-enabled": "Not enabled",
|
||||
"sync-button": "Sync user",
|
||||
"title": "LDAP Synchronisation"
|
||||
},
|
||||
"ldap-sync-info": {
|
||||
"title": "LDAP Synchronization"
|
||||
},
|
||||
"ldap-user-groups": {
|
||||
"no-org-found": "No match <2><0></0></2>"
|
||||
},
|
||||
"ldap-user-info": {
|
||||
"no-team": "No teams found via LDAP"
|
||||
},
|
||||
"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."
|
||||
},
|
||||
"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",
|
||||
"name-header": "Name",
|
||||
"new-org-button": "New org"
|
||||
},
|
||||
"server-settings": {
|
||||
"alerts-button": "Manage alerts",
|
||||
"dashboards-button": "Manage dashboards",
|
||||
"data-sources-button": "Manage data sources",
|
||||
"not-found": "No stats found.",
|
||||
"title": "Instance statistics",
|
||||
"users-button": "Manage users"
|
||||
},
|
||||
"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-orgs": {
|
||||
"add-button": "Add user to organization",
|
||||
"change-role-button": "Change role",
|
||||
"external-user-tooltip": "This user's built-in role is not editable because it is synchronized from your auth provider. Refer to the <1>Grafana authentication docs</1> for details.",
|
||||
"remove-button": "Remove from organization",
|
||||
"role-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.",
|
||||
"title": "Organizations"
|
||||
},
|
||||
"user-orgs-modal": {
|
||||
"add-button": "Add to organization",
|
||||
"cancel-button": "Cancel"
|
||||
},
|
||||
"user-permissions": {
|
||||
"change-button": "Change",
|
||||
"grafana-admin-key": "Grafana Admin",
|
||||
"grafana-admin-no": "No",
|
||||
"grafana-admin-yes": "Yes",
|
||||
"title": "Permissions"
|
||||
},
|
||||
"user-profile": {
|
||||
"delete-button": "Delete user",
|
||||
"disable-button": "Disable user",
|
||||
"edit-button": "Edit",
|
||||
"enable-button": "Enable user",
|
||||
"title": "User information"
|
||||
},
|
||||
"user-sessions": {
|
||||
"browser-column": "Browser and OS",
|
||||
"force-logout-all-button": "Force logout from all devices",
|
||||
"force-logout-button": "Force logout",
|
||||
"ip-column": "IP address",
|
||||
"last-seen-column": "Last seen",
|
||||
"logged-on-column": "Logged on",
|
||||
"title": "Sessions"
|
||||
},
|
||||
"users-create": {
|
||||
"create-button": "Create user"
|
||||
},
|
||||
"users-list": {
|
||||
"create-button": "New user"
|
||||
},
|
||||
"users-table": {
|
||||
"last-seen-never": "Never",
|
||||
"no-licensed-role": "Not assigned <2><0></0></2>"
|
||||
}
|
||||
},
|
||||
"alert-labels": {
|
||||
"button": {
|
||||
"hide": "Hide common labels",
|
||||
@ -371,6 +511,17 @@
|
||||
"message": "No API keys found"
|
||||
}
|
||||
},
|
||||
"app-chrome": {
|
||||
"skip-content-button": "Skip to main content",
|
||||
"top-bar": {
|
||||
"sign-in": "Sign in"
|
||||
}
|
||||
},
|
||||
"app-notification": {
|
||||
"item": {
|
||||
"trace-id": "Trace ID: {{traceId}}"
|
||||
}
|
||||
},
|
||||
"bookmarks-page": {
|
||||
"empty": {
|
||||
"message": "It looks like you haven’t created any bookmarks yet",
|
||||
@ -406,15 +557,15 @@
|
||||
},
|
||||
"counts": {
|
||||
"alertRule_one": "{{count}} alert rule",
|
||||
"alertRule_other": "{{count}} alert rule",
|
||||
"alertRule_other": "{{count}} alert rules",
|
||||
"dashboard_one": "{{count}} dashboard",
|
||||
"dashboard_other": "{{count}} dashboard",
|
||||
"dashboard_other": "{{count}} dashboards",
|
||||
"folder_one": "{{count}} folder",
|
||||
"folder_other": "{{count}} folder",
|
||||
"folder_other": "{{count}} folders",
|
||||
"libraryPanel_one": "{{count}} library panel",
|
||||
"libraryPanel_other": "{{count}} library panel",
|
||||
"libraryPanel_other": "{{count}} library panels",
|
||||
"total_one": "{{count}} item",
|
||||
"total_other": "{{count}} item"
|
||||
"total_other": "{{count}} items"
|
||||
},
|
||||
"dashboards-tree": {
|
||||
"collapse-folder-button": "Collapse folder {{title}}",
|
||||
@ -442,6 +593,7 @@
|
||||
"clear-selection": "Clear selection",
|
||||
"empty-message": "No folders found",
|
||||
"error-title": "Error loading folders",
|
||||
"non-folder-item": "Non-folder {{itemKind}} {{itemUID}}",
|
||||
"search-placeholder": "Search folders",
|
||||
"unknown-error": "Unknown error"
|
||||
},
|
||||
@ -883,6 +1035,12 @@
|
||||
"time-range-label": "Lock time range"
|
||||
}
|
||||
},
|
||||
"empty-list-cta": {
|
||||
"pro-tip": "ProTip: {{proTip}}"
|
||||
},
|
||||
"entity-not-found": {
|
||||
"description": "We're looking but can't seem to find this {{lowerCaseEntity}}. Try returning <4>home</4> or seeking help on the <7>community site.</7>"
|
||||
},
|
||||
"errors": {
|
||||
"dashboard-settings": {
|
||||
"annotations": {
|
||||
@ -1103,9 +1261,29 @@
|
||||
"export-as-json-tooltip": "Export"
|
||||
}
|
||||
},
|
||||
"folder-filter": {
|
||||
"clear-folder-button": "Clear folders"
|
||||
},
|
||||
"folder-picker": {
|
||||
"create-instructions": "Press enter to create the new folder.",
|
||||
"loading": "Loading folders..."
|
||||
},
|
||||
"forgot-password": {
|
||||
"back-button": "Back to login",
|
||||
"change-password": {
|
||||
"skip-button": "Skip",
|
||||
"submit-button": "Submit"
|
||||
},
|
||||
"contact-admin": "Did you forget your username or email? Contact your Grafana administrator.",
|
||||
"email-sent": "An email with a reset link has been sent to the email address. You should receive it shortly.",
|
||||
"reset-password-header": "Reset password",
|
||||
"send-email-button": "Send reset email"
|
||||
},
|
||||
"form-prompt": {
|
||||
"continue-button": "Continue editing",
|
||||
"description": "Changes that you made may not be saved.",
|
||||
"discard-button": "Discard unsaved changes"
|
||||
},
|
||||
"gen-ai": {
|
||||
"apply-suggestion": "Apply",
|
||||
"incomplete-request-error": "Sorry, I was unable to complete your request. Please try again.",
|
||||
@ -1225,6 +1403,10 @@
|
||||
}
|
||||
},
|
||||
"help-modal": {
|
||||
"column-headers": {
|
||||
"description": "Description",
|
||||
"keys": "Keys"
|
||||
},
|
||||
"shortcuts-category": {
|
||||
"dashboard": "Dashboard",
|
||||
"focused-panel": "Focused panel",
|
||||
@ -1475,6 +1657,9 @@
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"divider": {
|
||||
"connecting-text": "or"
|
||||
},
|
||||
"error": {
|
||||
"blocked": "You have exceeded the number of login attempts for this user. Please try again later.",
|
||||
"invalid-user-or-password": "Invalid username or password",
|
||||
@ -1502,6 +1687,9 @@
|
||||
"verify-email-label": "Send a verification email",
|
||||
"verify-email-loading-label": "Sending email..."
|
||||
},
|
||||
"layout": {
|
||||
"update-password": "Update your password"
|
||||
},
|
||||
"services": {
|
||||
"sing-in-with-prefix": "Sign in with {{serviceName}}"
|
||||
},
|
||||
@ -2147,6 +2335,9 @@
|
||||
"no-matches": "No matches found",
|
||||
"unsupported-layout": "Unsupported layout"
|
||||
},
|
||||
"panel-type-filter": {
|
||||
"clear-button": "Clear types"
|
||||
},
|
||||
"playlist-edit": {
|
||||
"error-prefix": "Error loading playlist:",
|
||||
"form": {
|
||||
@ -2240,6 +2431,10 @@
|
||||
},
|
||||
"empty-state": {
|
||||
"message": "No plugins found"
|
||||
},
|
||||
"plugin-help": {
|
||||
"error": "An error occurred when loading help.",
|
||||
"not-found": "No query help could be found."
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
@ -2433,6 +2628,10 @@
|
||||
"dashboard-modal-title": "Public dashboards",
|
||||
"shared-dashboard-modal-title": "Shared dashboards"
|
||||
},
|
||||
"table-body": {
|
||||
"dashboard-count_one": "{{count}} dashboard",
|
||||
"dashboard-count_other": "{{count}} dashboards"
|
||||
},
|
||||
"table-header": {
|
||||
"activated-label": "Activated",
|
||||
"activated-tooltip": "Earliest time user has been an active user to a dashboard",
|
||||
@ -2527,6 +2726,19 @@
|
||||
"dismissable-button": "Close"
|
||||
},
|
||||
"role-picker": {
|
||||
"built-in": {
|
||||
"basic-roles": "Basic roles"
|
||||
},
|
||||
"input": {
|
||||
"no-roles": "No roles assigned"
|
||||
},
|
||||
"menu": {
|
||||
"clear-button": "Clear all",
|
||||
"tooltip": "You can now select the \"No basic role\" option and add permissions to your custom needs. You can find more information in <1>our documentation</1>."
|
||||
},
|
||||
"sub-menu": {
|
||||
"clear-button": "Clear"
|
||||
},
|
||||
"title": {
|
||||
"description": "Assign roles to users to ensure granular control over access to Grafana‘s features and resources. Find out more in our <2>documentation</2>."
|
||||
}
|
||||
@ -2536,6 +2748,11 @@
|
||||
"label": "Basic Roles"
|
||||
}
|
||||
},
|
||||
"route-error": {
|
||||
"description": "Grafana has likely been updated. Please try reloading the page.",
|
||||
"reload-button": "Reload",
|
||||
"title": "Unable to find application file"
|
||||
},
|
||||
"save-dashboards": {
|
||||
"name-exists": {
|
||||
"message-info": "A dashboard with the same name in the selected folder already exists, including recently deleted dashboards.",
|
||||
@ -2808,6 +3025,17 @@
|
||||
},
|
||||
"title": "Preferences"
|
||||
},
|
||||
"sign-up": {
|
||||
"back-button": "Back to login",
|
||||
"submit-button": "Submit",
|
||||
"verify": {
|
||||
"back-button": "Back to login",
|
||||
"complete-button": "Complete signup",
|
||||
"header": "Verify email",
|
||||
"info": "An email with a verification link has been sent to the email address. You should receive it shortly.",
|
||||
"send-button": "Send verification email"
|
||||
}
|
||||
},
|
||||
"silences": {
|
||||
"empty-state": {
|
||||
"button-title": "Create silence",
|
||||
@ -2860,6 +3088,7 @@
|
||||
"view-button": "View"
|
||||
},
|
||||
"tag-filter": {
|
||||
"clear-button": "Clear tags",
|
||||
"loading": "Loading...",
|
||||
"no-tags": "No tags found",
|
||||
"placeholder": "Filter by tag"
|
||||
@ -2980,6 +3209,13 @@
|
||||
"add-transformation-header": "Start transforming data"
|
||||
}
|
||||
},
|
||||
"upgrade-box": {
|
||||
"discovery-text": "You’ve discovered a Pro feature!",
|
||||
"discovery-text-continued": "Get the Grafana Pro plan to access {{featureName}}.",
|
||||
"get-started": "Get started with {{featureName}}",
|
||||
"learn-more": "Learn more",
|
||||
"upgrade-button": "Upgrade"
|
||||
},
|
||||
"user-orgs": {
|
||||
"current-org-button": "Current",
|
||||
"name-column": "Name",
|
||||
|
@ -14,6 +14,9 @@
|
||||
"permission-list": {
|
||||
"permission": "Pęřmįşşįőʼn"
|
||||
},
|
||||
"permission-list-item": {
|
||||
"inherited": "Ĩʼnĥęřįŧęđ ƒřőm ƒőľđęř"
|
||||
},
|
||||
"permissions": {
|
||||
"add-label": "Åđđ ä pęřmįşşįőʼn",
|
||||
"no-permissions": "Ŧĥęřę äřę ʼnő pęřmįşşįőʼnş",
|
||||
@ -25,6 +28,143 @@
|
||||
"user": "Ůşęř"
|
||||
}
|
||||
},
|
||||
"action-editor": {
|
||||
"modal": {
|
||||
"cancel-button": "Cäʼnčęľ",
|
||||
"save-button": "Ŝävę"
|
||||
}
|
||||
},
|
||||
"actions-editor": {
|
||||
"inline": {
|
||||
"add-button": "Åđđ äčŧįőʼn",
|
||||
"one-click-link": "Øʼnę-čľįčĸ ľįʼnĸ"
|
||||
}
|
||||
},
|
||||
"admin": {
|
||||
"anon-users": {
|
||||
"not-found": "Ńő äʼnőʼnymőūş ūşęřş ƒőūʼnđ."
|
||||
},
|
||||
"edit-org": {
|
||||
"access-denied": "Ÿőū đő ʼnőŧ ĥävę pęřmįşşįőʼn ŧő şęę ūşęřş įʼn ŧĥįş őřģäʼnįžäŧįőʼn. Ŧő ūpđäŧę ŧĥįş őřģäʼnįžäŧįőʼn, čőʼnŧäčŧ yőūř şęřvęř äđmįʼnįşŧřäŧőř.",
|
||||
"heading": "Ēđįŧ Øřģäʼnįžäŧįőʼn",
|
||||
"update-button": "Ůpđäŧę",
|
||||
"users-heading": "Øřģäʼnįžäŧįőʼn ūşęřş"
|
||||
},
|
||||
"feature-toggles": {
|
||||
"sub-title": "Vįęŵ äʼnđ ęđįŧ ƒęäŧūřę ŧőģģľęş. Ŗęäđ mőřę äþőūŧ ƒęäŧūřę ŧőģģľęş äŧ <2>ģřäƒäʼnä.čőm</2>."
|
||||
},
|
||||
"get-enterprise": {
|
||||
"contact-us": "Cőʼnŧäčŧ ūş äʼnđ ģęŧ ä ƒřęę ŧřįäľ",
|
||||
"description": "Ÿőū čäʼn ūşę ŧĥę ŧřįäľ vęřşįőʼn ƒőř ƒřęę ƒőř 30 đäyş. Ŵę ŵįľľ řęmįʼnđ yőū äþőūŧ įŧ ƒįvę đäyş þęƒőřę ŧĥę ŧřįäľ pęřįőđ ęʼnđş.",
|
||||
"features-heading": "Ēʼnĥäʼnčęđ ƒūʼnčŧįőʼnäľįŧy",
|
||||
"included-description": "Ĩʼnđęmʼnįƒįčäŧįőʼn, ŵőřĸįʼnģ ŵįŧĥ Ğřäƒäʼnä Ŀäþş őʼn ƒūŧūřę přįőřįŧįžäŧįőʼn, äʼnđ ŧřäįʼnįʼnģ ƒřőm ŧĥę čőřę Ğřäƒäʼnä ŧęäm.",
|
||||
"included-heading": "Åľşő įʼnčľūđęđ:",
|
||||
"service-title": "Åŧ yőūř şęřvįčę",
|
||||
"team-sync-details": "ĿĐÅP, ĞįŧĦūþ ØÅūŧĥ, Åūŧĥ Přőχy, Øĸŧä",
|
||||
"title": "Ğęŧ Ğřäƒäʼnä Ēʼnŧęřpřįşę"
|
||||
},
|
||||
"ldap": {
|
||||
"test-mapping-heading": "Ŧęşŧ ūşęř mäppįʼnģ",
|
||||
"test-mapping-run-button": "Ŗūʼn"
|
||||
},
|
||||
"ldap-permissions": {
|
||||
"active": "<0></0> Åčŧįvę",
|
||||
"admin": "<0></0> Ÿęş",
|
||||
"inactive": "<0></0> Ĩʼnäčŧįvę"
|
||||
},
|
||||
"ldap-status": {
|
||||
"title": "ĿĐÅP Cőʼnʼnęčŧįőʼn"
|
||||
},
|
||||
"ldap-sync": {
|
||||
"debug-button": "Đęþūģ ĿĐÅP Mäppįʼnģ",
|
||||
"external-sync-description": "Ůşęř şyʼnčęđ vįä ĿĐÅP. Ŝőmę čĥäʼnģęş mūşŧ þę đőʼnę įʼn ĿĐÅP őř mäppįʼnģş.",
|
||||
"external-sync-label": "Ēχŧęřʼnäľ şyʼnč",
|
||||
"next-sync-label": "Ńęχŧ şčĥęđūľęđ şyʼnčĥřőʼnįžäŧįőʼn",
|
||||
"not-enabled": "Ńőŧ ęʼnäþľęđ",
|
||||
"sync-button": "Ŝyʼnč ūşęř",
|
||||
"title": "ĿĐÅP Ŝyʼnčĥřőʼnįşäŧįőʼn"
|
||||
},
|
||||
"ldap-sync-info": {
|
||||
"title": "ĿĐÅP Ŝyʼnčĥřőʼnįžäŧįőʼn"
|
||||
},
|
||||
"ldap-user-groups": {
|
||||
"no-org-found": "Ńő mäŧčĥ <2><0></0></2>"
|
||||
},
|
||||
"ldap-user-info": {
|
||||
"no-team": "Ńő ŧęämş ƒőūʼnđ vįä ĿĐÅP"
|
||||
},
|
||||
"org-uers": {
|
||||
"last-seen-never": "Ńęvęř"
|
||||
},
|
||||
"org-users": {
|
||||
"not-editable": "Ŧĥįş ūşęř'ş řőľę įş ʼnőŧ ęđįŧäþľę þęčäūşę įŧ įş şyʼnčĥřőʼnįžęđ ƒřőm yőūř äūŧĥ přővįđęř. Ŗęƒęř ŧő ŧĥę <1>Ğřäƒäʼnä äūŧĥęʼnŧįčäŧįőʼn đőčş</1> ƒőř đęŧäįľş."
|
||||
},
|
||||
"orgs": {
|
||||
"delete-body": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő đęľęŧę '{{deleteOrgName}}'?<3></3> <5>Åľľ đäşĥþőäřđş ƒőř ŧĥįş őřģäʼnįžäŧįőʼn ŵįľľ þę řęmővęđ!</5>",
|
||||
"id-header": "ĨĐ",
|
||||
"name-header": "Ńämę",
|
||||
"new-org-button": "Ńęŵ őřģ"
|
||||
},
|
||||
"server-settings": {
|
||||
"alerts-button": "Mäʼnäģę äľęřŧş",
|
||||
"dashboards-button": "Mäʼnäģę đäşĥþőäřđş",
|
||||
"data-sources-button": "Mäʼnäģę đäŧä şőūřčęş",
|
||||
"not-found": "Ńő şŧäŧş ƒőūʼnđ.",
|
||||
"title": "Ĩʼnşŧäʼnčę şŧäŧįşŧįčş",
|
||||
"users-button": "Mäʼnäģę ūşęřş"
|
||||
},
|
||||
"settings": {
|
||||
"info-description": "Ŧĥęşę şyşŧęm şęŧŧįʼnģş äřę đęƒįʼnęđ įʼn ģřäƒäʼnä.įʼnį őř čūşŧőm.įʼnį (őř ővęřřįđđęʼn įʼn ĒŃV väřįäþľęş). Ŧő čĥäʼnģę ŧĥęşę yőū čūřřęʼnŧľy ʼnęęđ ŧő řęşŧäřŧ Ğřäƒäʼnä."
|
||||
},
|
||||
"upgrade-info": {
|
||||
"title": "Ēʼnŧęřpřįşę ľįčęʼnşę"
|
||||
},
|
||||
"user-orgs": {
|
||||
"add-button": "Åđđ ūşęř ŧő őřģäʼnįžäŧįőʼn",
|
||||
"change-role-button": "Cĥäʼnģę řőľę",
|
||||
"external-user-tooltip": "Ŧĥįş ūşęř'ş þūįľŧ-įʼn řőľę įş ʼnőŧ ęđįŧäþľę þęčäūşę įŧ įş şyʼnčĥřőʼnįžęđ ƒřőm yőūř äūŧĥ přővįđęř. Ŗęƒęř ŧő ŧĥę <1>Ğřäƒäʼnä äūŧĥęʼnŧįčäŧįőʼn đőčş</1> ƒőř đęŧäįľş.",
|
||||
"remove-button": "Ŗęmővę ƒřőm őřģäʼnįžäŧįőʼn",
|
||||
"role-not-editable": "Ŧĥįş ūşęř'ş řőľę įş ʼnőŧ ęđįŧäþľę þęčäūşę įŧ įş şyʼnčĥřőʼnįžęđ ƒřőm yőūř äūŧĥ přővįđęř. Ŗęƒęř ŧő ŧĥę <1>Ğřäƒäʼnä äūŧĥęʼnŧįčäŧįőʼn đőčş</1> ƒőř đęŧäįľş.",
|
||||
"title": "Øřģäʼnįžäŧįőʼnş"
|
||||
},
|
||||
"user-orgs-modal": {
|
||||
"add-button": "Åđđ ŧő őřģäʼnįžäŧįőʼn",
|
||||
"cancel-button": "Cäʼnčęľ"
|
||||
},
|
||||
"user-permissions": {
|
||||
"change-button": "Cĥäʼnģę",
|
||||
"grafana-admin-key": "Ğřäƒäʼnä Åđmįʼn",
|
||||
"grafana-admin-no": "Ńő",
|
||||
"grafana-admin-yes": "Ÿęş",
|
||||
"title": "Pęřmįşşįőʼnş"
|
||||
},
|
||||
"user-profile": {
|
||||
"delete-button": "Đęľęŧę ūşęř",
|
||||
"disable-button": "Đįşäþľę ūşęř",
|
||||
"edit-button": "Ēđįŧ",
|
||||
"enable-button": "Ēʼnäþľę ūşęř",
|
||||
"title": "Ůşęř įʼnƒőřmäŧįőʼn"
|
||||
},
|
||||
"user-sessions": {
|
||||
"browser-column": "ßřőŵşęř äʼnđ ØŜ",
|
||||
"force-logout-all-button": "Főřčę ľőģőūŧ ƒřőm äľľ đęvįčęş",
|
||||
"force-logout-button": "Főřčę ľőģőūŧ",
|
||||
"ip-column": "ĨP äđđřęşş",
|
||||
"last-seen-column": "Ŀäşŧ şęęʼn",
|
||||
"logged-on-column": "Ŀőģģęđ őʼn",
|
||||
"title": "Ŝęşşįőʼnş"
|
||||
},
|
||||
"users-create": {
|
||||
"create-button": "Cřęäŧę ūşęř"
|
||||
},
|
||||
"users-list": {
|
||||
"create-button": "Ńęŵ ūşęř"
|
||||
},
|
||||
"users-table": {
|
||||
"last-seen-never": "Ńęvęř",
|
||||
"no-licensed-role": "Ńőŧ äşşįģʼnęđ <2><0></0></2>"
|
||||
}
|
||||
},
|
||||
"alert-labels": {
|
||||
"button": {
|
||||
"hide": "Ħįđę čőmmőʼn ľäþęľş",
|
||||
@ -371,6 +511,17 @@
|
||||
"message": "Ńő ÅPĨ ĸęyş ƒőūʼnđ"
|
||||
}
|
||||
},
|
||||
"app-chrome": {
|
||||
"skip-content-button": "Ŝĸįp ŧő mäįʼn čőʼnŧęʼnŧ",
|
||||
"top-bar": {
|
||||
"sign-in": "Ŝįģʼn įʼn"
|
||||
}
|
||||
},
|
||||
"app-notification": {
|
||||
"item": {
|
||||
"trace-id": "Ŧřäčę ĨĐ: {{traceId}}"
|
||||
}
|
||||
},
|
||||
"bookmarks-page": {
|
||||
"empty": {
|
||||
"message": "Ĩŧ ľőőĸş ľįĸę yőū ĥävęʼn’ŧ čřęäŧęđ äʼny þőőĸmäřĸş yęŧ",
|
||||
@ -406,15 +557,15 @@
|
||||
},
|
||||
"counts": {
|
||||
"alertRule_one": "{{count}} äľęřŧ řūľę",
|
||||
"alertRule_other": "{{count}} äľęřŧ řūľę",
|
||||
"alertRule_other": "{{count}} äľęřŧ řūľęş",
|
||||
"dashboard_one": "{{count}} đäşĥþőäřđ",
|
||||
"dashboard_other": "{{count}} đäşĥþőäřđ",
|
||||
"dashboard_other": "{{count}} đäşĥþőäřđş",
|
||||
"folder_one": "{{count}} ƒőľđęř",
|
||||
"folder_other": "{{count}} ƒőľđęř",
|
||||
"folder_other": "{{count}} ƒőľđęřş",
|
||||
"libraryPanel_one": "{{count}} ľįþřäřy päʼnęľ",
|
||||
"libraryPanel_other": "{{count}} ľįþřäřy päʼnęľ",
|
||||
"libraryPanel_other": "{{count}} ľįþřäřy päʼnęľş",
|
||||
"total_one": "{{count}} įŧęm",
|
||||
"total_other": "{{count}} įŧęm"
|
||||
"total_other": "{{count}} įŧęmş"
|
||||
},
|
||||
"dashboards-tree": {
|
||||
"collapse-folder-button": "Cőľľäpşę ƒőľđęř {{title}}",
|
||||
@ -442,6 +593,7 @@
|
||||
"clear-selection": "Cľęäř şęľęčŧįőʼn",
|
||||
"empty-message": "Ńő ƒőľđęřş ƒőūʼnđ",
|
||||
"error-title": "Ēřřőř ľőäđįʼnģ ƒőľđęřş",
|
||||
"non-folder-item": "Ńőʼn-ƒőľđęř {{itemKind}} {{itemUID}}",
|
||||
"search-placeholder": "Ŝęäřčĥ ƒőľđęřş",
|
||||
"unknown-error": "Ůʼnĸʼnőŵʼn ęřřőř"
|
||||
},
|
||||
@ -883,6 +1035,12 @@
|
||||
"time-range-label": "Ŀőčĸ ŧįmę řäʼnģę"
|
||||
}
|
||||
},
|
||||
"empty-list-cta": {
|
||||
"pro-tip": "PřőŦįp: {{proTip}}"
|
||||
},
|
||||
"entity-not-found": {
|
||||
"description": "Ŵę'řę ľőőĸįʼnģ þūŧ čäʼn'ŧ şęęm ŧő ƒįʼnđ ŧĥįş {{lowerCaseEntity}}. Ŧřy řęŧūřʼnįʼnģ <4>ĥőmę</4> őř şęęĸįʼnģ ĥęľp őʼn ŧĥę <7>čőmmūʼnįŧy şįŧę.</7>"
|
||||
},
|
||||
"errors": {
|
||||
"dashboard-settings": {
|
||||
"annotations": {
|
||||
@ -1103,9 +1261,29 @@
|
||||
"export-as-json-tooltip": "Ēχpőřŧ"
|
||||
}
|
||||
},
|
||||
"folder-filter": {
|
||||
"clear-folder-button": "Cľęäř ƒőľđęřş"
|
||||
},
|
||||
"folder-picker": {
|
||||
"create-instructions": "Přęşş ęʼnŧęř ŧő čřęäŧę ŧĥę ʼnęŵ ƒőľđęř.",
|
||||
"loading": "Ŀőäđįʼnģ ƒőľđęřş..."
|
||||
},
|
||||
"forgot-password": {
|
||||
"back-button": "ßäčĸ ŧő ľőģįʼn",
|
||||
"change-password": {
|
||||
"skip-button": "Ŝĸįp",
|
||||
"submit-button": "Ŝūþmįŧ"
|
||||
},
|
||||
"contact-admin": "Đįđ yőū ƒőřģęŧ yőūř ūşęřʼnämę őř ęmäįľ? Cőʼnŧäčŧ yőūř Ğřäƒäʼnä äđmįʼnįşŧřäŧőř.",
|
||||
"email-sent": "Åʼn ęmäįľ ŵįŧĥ ä řęşęŧ ľįʼnĸ ĥäş þęęʼn şęʼnŧ ŧő ŧĥę ęmäįľ äđđřęşş. Ÿőū şĥőūľđ řęčęįvę įŧ şĥőřŧľy.",
|
||||
"reset-password-header": "Ŗęşęŧ päşşŵőřđ",
|
||||
"send-email-button": "Ŝęʼnđ řęşęŧ ęmäįľ"
|
||||
},
|
||||
"form-prompt": {
|
||||
"continue-button": "Cőʼnŧįʼnūę ęđįŧįʼnģ",
|
||||
"description": "Cĥäʼnģęş ŧĥäŧ yőū mäđę mäy ʼnőŧ þę şävęđ.",
|
||||
"discard-button": "Đįşčäřđ ūʼnşävęđ čĥäʼnģęş"
|
||||
},
|
||||
"gen-ai": {
|
||||
"apply-suggestion": "Åppľy",
|
||||
"incomplete-request-error": "Ŝőřřy, Ĩ ŵäş ūʼnäþľę ŧő čőmpľęŧę yőūř řęqūęşŧ. Pľęäşę ŧřy äģäįʼn.",
|
||||
@ -1225,6 +1403,10 @@
|
||||
}
|
||||
},
|
||||
"help-modal": {
|
||||
"column-headers": {
|
||||
"description": "Đęşčřįpŧįőʼn",
|
||||
"keys": "Ķęyş"
|
||||
},
|
||||
"shortcuts-category": {
|
||||
"dashboard": "Đäşĥþőäřđ",
|
||||
"focused-panel": "Főčūşęđ päʼnęľ",
|
||||
@ -1475,6 +1657,9 @@
|
||||
}
|
||||
},
|
||||
"login": {
|
||||
"divider": {
|
||||
"connecting-text": "őř"
|
||||
},
|
||||
"error": {
|
||||
"blocked": "Ÿőū ĥävę ęχčęęđęđ ŧĥę ʼnūmþęř őƒ ľőģįʼn äŧŧęmpŧş ƒőř ŧĥįş ūşęř. Pľęäşę ŧřy äģäįʼn ľäŧęř.",
|
||||
"invalid-user-or-password": "Ĩʼnväľįđ ūşęřʼnämę őř päşşŵőřđ",
|
||||
@ -1502,6 +1687,9 @@
|
||||
"verify-email-label": "Ŝęʼnđ ä vęřįƒįčäŧįőʼn ęmäįľ",
|
||||
"verify-email-loading-label": "Ŝęʼnđįʼnģ ęmäįľ..."
|
||||
},
|
||||
"layout": {
|
||||
"update-password": "Ůpđäŧę yőūř päşşŵőřđ"
|
||||
},
|
||||
"services": {
|
||||
"sing-in-with-prefix": "Ŝįģʼn įʼn ŵįŧĥ {{serviceName}}"
|
||||
},
|
||||
@ -2147,6 +2335,9 @@
|
||||
"no-matches": "Ńő mäŧčĥęş ƒőūʼnđ",
|
||||
"unsupported-layout": "Ůʼnşūppőřŧęđ ľäyőūŧ"
|
||||
},
|
||||
"panel-type-filter": {
|
||||
"clear-button": "Cľęäř ŧypęş"
|
||||
},
|
||||
"playlist-edit": {
|
||||
"error-prefix": "Ēřřőř ľőäđįʼnģ pľäyľįşŧ:",
|
||||
"form": {
|
||||
@ -2240,6 +2431,10 @@
|
||||
},
|
||||
"empty-state": {
|
||||
"message": "Ńő pľūģįʼnş ƒőūʼnđ"
|
||||
},
|
||||
"plugin-help": {
|
||||
"error": "Åʼn ęřřőř őččūřřęđ ŵĥęʼn ľőäđįʼnģ ĥęľp.",
|
||||
"not-found": "Ńő qūęřy ĥęľp čőūľđ þę ƒőūʼnđ."
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
@ -2433,6 +2628,10 @@
|
||||
"dashboard-modal-title": "Pūþľįč đäşĥþőäřđş",
|
||||
"shared-dashboard-modal-title": "Ŝĥäřęđ đäşĥþőäřđş"
|
||||
},
|
||||
"table-body": {
|
||||
"dashboard-count_one": "{{count}} đäşĥþőäřđ",
|
||||
"dashboard-count_other": "{{count}} đäşĥþőäřđş"
|
||||
},
|
||||
"table-header": {
|
||||
"activated-label": "Åčŧįväŧęđ",
|
||||
"activated-tooltip": "Ēäřľįęşŧ ŧįmę ūşęř ĥäş þęęʼn äʼn äčŧįvę ūşęř ŧő ä đäşĥþőäřđ",
|
||||
@ -2527,6 +2726,19 @@
|
||||
"dismissable-button": "Cľőşę"
|
||||
},
|
||||
"role-picker": {
|
||||
"built-in": {
|
||||
"basic-roles": "ßäşįč řőľęş"
|
||||
},
|
||||
"input": {
|
||||
"no-roles": "Ńő řőľęş äşşįģʼnęđ"
|
||||
},
|
||||
"menu": {
|
||||
"clear-button": "Cľęäř äľľ",
|
||||
"tooltip": "Ÿőū čäʼn ʼnőŵ şęľęčŧ ŧĥę \"Ńő þäşįč řőľę\" őpŧįőʼn äʼnđ äđđ pęřmįşşįőʼnş ŧő yőūř čūşŧőm ʼnęęđş. Ÿőū čäʼn ƒįʼnđ mőřę įʼnƒőřmäŧįőʼn įʼn <1>őūř đőčūmęʼnŧäŧįőʼn</1>."
|
||||
},
|
||||
"sub-menu": {
|
||||
"clear-button": "Cľęäř"
|
||||
},
|
||||
"title": {
|
||||
"description": "Åşşįģʼn řőľęş ŧő ūşęřş ŧő ęʼnşūřę ģřäʼnūľäř čőʼnŧřőľ ővęř äččęşş ŧő Ğřäƒäʼnä&ľşqūő;ş ƒęäŧūřęş äʼnđ řęşőūřčęş. Fįʼnđ őūŧ mőřę įʼn őūř <2>đőčūmęʼnŧäŧįőʼn</2>."
|
||||
}
|
||||
@ -2536,6 +2748,11 @@
|
||||
"label": "ßäşįč Ŗőľęş"
|
||||
}
|
||||
},
|
||||
"route-error": {
|
||||
"description": "Ğřäƒäʼnä ĥäş ľįĸęľy þęęʼn ūpđäŧęđ. Pľęäşę ŧřy řęľőäđįʼnģ ŧĥę päģę.",
|
||||
"reload-button": "Ŗęľőäđ",
|
||||
"title": "Ůʼnäþľę ŧő ƒįʼnđ äppľįčäŧįőʼn ƒįľę"
|
||||
},
|
||||
"save-dashboards": {
|
||||
"name-exists": {
|
||||
"message-info": "Å đäşĥþőäřđ ŵįŧĥ ŧĥę şämę ʼnämę įʼn ŧĥę şęľęčŧęđ ƒőľđęř äľřęäđy ęχįşŧş, įʼnčľūđįʼnģ řęčęʼnŧľy đęľęŧęđ đäşĥþőäřđş.",
|
||||
@ -2808,6 +3025,17 @@
|
||||
},
|
||||
"title": "Přęƒęřęʼnčęş"
|
||||
},
|
||||
"sign-up": {
|
||||
"back-button": "ßäčĸ ŧő ľőģįʼn",
|
||||
"submit-button": "Ŝūþmįŧ",
|
||||
"verify": {
|
||||
"back-button": "ßäčĸ ŧő ľőģįʼn",
|
||||
"complete-button": "Cőmpľęŧę şįģʼnūp",
|
||||
"header": "Vęřįƒy ęmäįľ",
|
||||
"info": "Åʼn ęmäįľ ŵįŧĥ ä vęřįƒįčäŧįőʼn ľįʼnĸ ĥäş þęęʼn şęʼnŧ ŧő ŧĥę ęmäįľ äđđřęşş. Ÿőū şĥőūľđ řęčęįvę įŧ şĥőřŧľy.",
|
||||
"send-button": "Ŝęʼnđ vęřįƒįčäŧįőʼn ęmäįľ"
|
||||
}
|
||||
},
|
||||
"silences": {
|
||||
"empty-state": {
|
||||
"button-title": "Cřęäŧę şįľęʼnčę",
|
||||
@ -2860,6 +3088,7 @@
|
||||
"view-button": "Vįęŵ"
|
||||
},
|
||||
"tag-filter": {
|
||||
"clear-button": "Cľęäř ŧäģş",
|
||||
"loading": "Ŀőäđįʼnģ...",
|
||||
"no-tags": "Ńő ŧäģş ƒőūʼnđ",
|
||||
"placeholder": "Fįľŧęř þy ŧäģ"
|
||||
@ -2980,6 +3209,13 @@
|
||||
"add-transformation-header": "Ŝŧäřŧ ŧřäʼnşƒőřmįʼnģ đäŧä"
|
||||
}
|
||||
},
|
||||
"upgrade-box": {
|
||||
"discovery-text": "Ÿőū’vę đįşčővęřęđ ä Přő ƒęäŧūřę!",
|
||||
"discovery-text-continued": "Ğęŧ ŧĥę Ğřäƒäʼnä Přő pľäʼn ŧő äččęşş {{featureName}}.",
|
||||
"get-started": "Ğęŧ şŧäřŧęđ ŵįŧĥ {{featureName}}",
|
||||
"learn-more": "Ŀęäřʼn mőřę",
|
||||
"upgrade-button": "Ůpģřäđę"
|
||||
},
|
||||
"user-orgs": {
|
||||
"current-org-button": "Cūřřęʼnŧ",
|
||||
"name-column": "Ńämę",
|
||||
|
Loading…
Reference in New Issue
Block a user