- {renderTitle ? renderTitle(text) : renderHeaderTitle(text, main.breadcrumbs ?? [], main.highlightText)}
+ {renderTitle
+ ? renderTitle(main.text)
+ : renderHeaderTitle(main.text, main.breadcrumbs ?? [], main.highlightText)}
{info &&
}
{sub &&
{sub}
}
{actions &&
{actions}
}
diff --git a/public/app/core/components/PageNew/PageHeader.tsx b/public/app/core/components/PageNew/PageHeader.tsx
index beaabaac0ce..55fcdd552d4 100644
--- a/public/app/core/components/PageNew/PageHeader.tsx
+++ b/public/app/core/components/PageNew/PageHeader.tsx
@@ -4,7 +4,6 @@ import React from 'react';
import { NavModelItem, GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '@grafana/ui';
-import { getNavSubTitle, getNavTitle } from '../NavBar/navBarItem-translations';
import { PageInfoItem } from '../Page/types';
import { PageInfo } from '../PageInfo/PageInfo';
@@ -18,10 +17,9 @@ export interface Props {
export function PageHeader({ navItem, renderTitle, actions, info, subTitle }: Props) {
const styles = useStyles2(getStyles);
- const sub = subTitle ?? getNavSubTitle(navItem.id) ?? navItem.subTitle;
+ const sub = subTitle ?? navItem.subTitle;
- const title = getNavTitle(navItem.id) ?? navItem.text;
- const titleElement = renderTitle ? renderTitle(title) :
{title}
;
+ const titleElement = renderTitle ? renderTitle(navItem.text) :
{navItem.text}
;
return (
diff --git a/public/app/core/components/PageNew/SectionNavItem.tsx b/public/app/core/components/PageNew/SectionNavItem.tsx
index 0a54d12dd3e..7abf0634e6a 100644
--- a/public/app/core/components/PageNew/SectionNavItem.tsx
+++ b/public/app/core/components/PageNew/SectionNavItem.tsx
@@ -6,8 +6,6 @@ import { selectors } from '@grafana/e2e-selectors';
import { reportInteraction } from '@grafana/runtime';
import { useStyles2, Icon } from '@grafana/ui';
-import { getNavTitle } from '../NavBar/navBarItem-translations';
-
export interface Props {
item: NavModelItem;
isSectionRoot?: boolean;
@@ -55,7 +53,7 @@ export function SectionNavItem({ item, isSectionRoot = false }: Props) {
aria-selected={item.active}
>
{isSectionRoot && icon}
- {getNavTitle(item.id) ?? item.text}
+ {item.text}
{item.tabSuffix && }
{children?.map((child, index) => (
diff --git a/public/app/core/internationalization/index.tsx b/public/app/core/internationalization/index.tsx
index fa9c0d2988c..87f7c06fa37 100644
--- a/public/app/core/internationalization/index.tsx
+++ b/public/app/core/internationalization/index.tsx
@@ -22,7 +22,14 @@ const loadTranslations: BackendModule = {
export function initializeI18n(language: string) {
const validLocale = VALID_LANGUAGES.includes(language) ? language : DEFAULT_LANGUAGE;
- i18n
+ // This is a placeholder so we can put a 'comment' in the message json files.
+ // Starts with an underscore so it's sorted to the top of the file
+ t(
+ '_comment',
+ 'Do not manually edit this file, or update these source phrases in Crowdin. The source of truth for English strings are in the code source'
+ );
+
+ return i18n
.use(loadTranslations)
.use(initReactI18next) // passes i18n down to react-i18next
.init({
@@ -37,13 +44,6 @@ export function initializeI18n(language: string) {
pluralSeparator: '__',
});
-
- // This is a placeholder so we can put a 'comment' in the message json files.
- // Starts with an underscore so it's sorted to the top of the file
- t(
- '_comment',
- 'Do not manually edit this file, or update these source phrases in Crowdin. The source of truth for English strings are in the code source'
- );
}
export function changeLanguage(locale: string) {
diff --git a/public/app/core/reducers/navBarTree.ts b/public/app/core/reducers/navBarTree.ts
index bd47059bf3c..49951bd181b 100644
--- a/public/app/core/reducers/navBarTree.ts
+++ b/public/app/core/reducers/navBarTree.ts
@@ -3,14 +3,30 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { NavModelItem } from '@grafana/data';
import { config } from '@grafana/runtime';
+import { getNavSubTitle, getNavTitle } from '../components/NavBar/navBarItem-translations';
+
export const initialState: NavModelItem[] = config.bootData?.navTree ?? [];
+function translateNav(navTree: NavModelItem[]): NavModelItem[] {
+ return navTree.map((navItem) => {
+ const children = navItem.children && translateNav(navItem.children);
+
+ return {
+ ...navItem,
+ children: children,
+ text: getNavTitle(navItem.id) ?? navItem.text,
+ subTitle: getNavSubTitle(navItem.id) ?? navItem.subTitle,
+ emptyMessage: getNavTitle(navItem.emptyMessageId),
+ };
+ });
+}
+
// this matches the prefix set in the backend navtree
export const ID_PREFIX = 'starred/';
const navTreeSlice = createSlice({
name: 'navBarTree',
- initialState,
+ initialState: () => translateNav(config.bootData?.navTree ?? []),
reducers: {
setStarred: (state, action: PayloadAction<{ id: string; title: string; url: string; isStarred: boolean }>) => {
const starredItems = state.find((navItem) => navItem.id === 'starred');
diff --git a/public/app/core/reducers/navModel.ts b/public/app/core/reducers/navModel.ts
index 5110af5c7af..18f0699d461 100644
--- a/public/app/core/reducers/navModel.ts
+++ b/public/app/core/reducers/navModel.ts
@@ -4,6 +4,8 @@ import { cloneDeep } from 'lodash';
import { NavIndex, NavModel, NavModelItem } from '@grafana/data';
import config from 'app/core/config';
+import { getNavSubTitle, getNavTitle } from '../components/NavBar/navBarItem-translations';
+
export const HOME_NAV_ID = 'home';
export function buildInitialState(): NavIndex {
@@ -16,22 +18,37 @@ export function buildInitialState(): NavIndex {
buildNavIndex(navIndex, [homeNav]);
}
// set home as parent for the other rootNodes
- buildNavIndex(navIndex, otherRootNodes, homeNav);
+ // need to use the translated home node from the navIndex
+ buildNavIndex(navIndex, otherRootNodes, navIndex[HOME_NAV_ID]);
return navIndex;
}
function buildNavIndex(navIndex: NavIndex, children: NavModelItem[], parentItem?: NavModelItem) {
+ const translatedChildren: NavModelItem[] = [];
+
for (const node of children) {
- node.parentItem = parentItem;
+ const translatedNode: NavModelItem = {
+ ...node,
+ text: getNavTitle(node.id) ?? node.text,
+ subTitle: getNavSubTitle(node.id) ?? node.subTitle,
+ emptyMessage: getNavTitle(node.emptyMessageId),
+ parentItem: parentItem,
+ };
- if (node.id) {
- navIndex[node.id] = node;
+ if (translatedNode.id) {
+ navIndex[translatedNode.id] = translatedNode;
}
- if (node.children) {
- buildNavIndex(navIndex, node.children, node);
+ if (translatedNode.children) {
+ buildNavIndex(navIndex, translatedNode.children, translatedNode);
}
+ translatedChildren.push(translatedNode);
+ }
+
+ // need to update the parentItem children with the new translated children
+ if (parentItem) {
+ parentItem.children = translatedChildren;
}
navIndex['not-found'] = { ...buildWarningNav('Page not found', '404 Error').node };
diff --git a/public/locales/de-DE/grafana.json b/public/locales/de-DE/grafana.json
index c0625a4f533..63ae38fc535 100644
--- a/public/locales/de-DE/grafana.json
+++ b/public/locales/de-DE/grafana.json
@@ -287,6 +287,9 @@
"title": "Einstellungen"
},
"profile/switch-org": "Organisation wechseln",
+ "public": {
+ "title": ""
+ },
"scenes": {
"title": "Szenen"
},
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index 19c2e183523..719ab734af0 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -287,6 +287,9 @@
"title": "Profile"
},
"profile/switch-org": "Switch organization",
+ "public": {
+ "title": "Public dashboards"
+ },
"scenes": {
"title": "Scenes"
},
diff --git a/public/locales/es-ES/grafana.json b/public/locales/es-ES/grafana.json
index ed9234f94f3..10d633316f6 100644
--- a/public/locales/es-ES/grafana.json
+++ b/public/locales/es-ES/grafana.json
@@ -287,6 +287,9 @@
"title": "Preferencias"
},
"profile/switch-org": "Cambiar de organización",
+ "public": {
+ "title": ""
+ },
"scenes": {
"title": "Escenas"
},
diff --git a/public/locales/fr-FR/grafana.json b/public/locales/fr-FR/grafana.json
index baf901bae6f..419493a9ce8 100644
--- a/public/locales/fr-FR/grafana.json
+++ b/public/locales/fr-FR/grafana.json
@@ -287,6 +287,9 @@
"title": "Préférences"
},
"profile/switch-org": "Passer à une autre organisation",
+ "public": {
+ "title": ""
+ },
"scenes": {
"title": "Scènes"
},
diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json
index 1c18fcd1207..14c6f1cc369 100644
--- a/public/locales/pseudo-LOCALE/grafana.json
+++ b/public/locales/pseudo-LOCALE/grafana.json
@@ -287,6 +287,9 @@
"title": "Přőƒįľę"
},
"profile/switch-org": "Ŝŵįŧčĥ őřģäʼnįžäŧįőʼn",
+ "public": {
+ "title": "Pūþľįč đäşĥþőäřđş"
+ },
"scenes": {
"title": "Ŝčęʼnęş"
},
diff --git a/public/locales/zh-Hans/grafana.json b/public/locales/zh-Hans/grafana.json
index 5b37684294f..30b70a7c70d 100644
--- a/public/locales/zh-Hans/grafana.json
+++ b/public/locales/zh-Hans/grafana.json
@@ -287,6 +287,9 @@
"title": "首选项"
},
"profile/switch-org": "切换组织",
+ "public": {
+ "title": ""
+ },
"scenes": {
"title": "场景"
},