Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,17 @@ Example of JSON translation file, where the top-level key is the plugin translat
}
```

### Translation priority order

Translations are resolved in this order (highest priority first):

1. **app-config overrides** — Paths listed in `i18n.overrides` in `app-config.yaml`. This is the only level users should change for custom labels.
2. **`/translations` JSON files** — Files under `translations/` (e.g. in the repo or mounted at `/src/translations/`). **RHDH override files (`rhdh-<locale>.json`) must win over Backstage defaults (`backstage-<locale>.json`)** when the same key exists in both. For 1.9 this is ensured by processing files in order: `backstage-*.json`, then `community-plugins-*.json`, then `rhdh-*.json`. Going forward, the i18n CLI or build pipeline should enforce this order.
3. **Locale TS files** — App sources under `app/src/.../<locale>.ts` (e.g. `packages/app/src/translations/scaffolder/ja.ts`). Left as-is for 1.9.
4. **Fallback English** — Default messages in `app/src/.../ref.ts` (e.g. `rhdhMessages` in `packages/app/src/translations/rhdh/ref.ts`).

Levels 2–4 are for internal management only; only level 1 is user-configurable.

### Customizing Translations

In a translation override JSON file, you can:
Expand Down
7 changes: 1 addition & 6 deletions packages/app/src/components/AppBase/AppBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,7 @@ const AppBase = () => {
>
{entityPage(entityTabOverrides)}
</Route>
<Route
path="/create"
element={
<ScaffolderPage headerOptions={{ title: 'Self-service' }} />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ciiay, I believe that your failing test has to do with the removal of the Self-service header. The test is expecting it on this page only to find that it has been replaced with Create a new component.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR adds 'templateListPage.title' translation string, and it needs to be updated in the all-v1.8_s3281-en.json test file as well.

Update Create a new component to Self-service in the /test directory here -

https://github.com/redhat-developer/rhdh/blob/main/translations/test/all-v1.8_s3281-en.json#L969

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @karthikjeeyar for the help 🥇

}
>
<Route path="/create" element={<ScaffolderPage />}>
<ScaffolderFieldExtensions>
{scaffolderFieldExtensions.map(
({ scope, module, importName, Component }) => (
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ export const Root = ({ children }: PropsWithChildren<{}>) => {
{showAdministration && (
<>
<SidebarDivider />
<SidebarGroup label="Administration">
<SidebarGroup label={t('menuItem.administration')}>
{renderMenuItems(true, true)}
</SidebarGroup>
</>
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/translations/rhdh/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ export default createTranslationMessages({
'signIn.providers.saml.message': 'Mit SAML anmelden',

// App translations
'app.scaffolder.title': 'Self-Service',
'app.search.title': 'Suchen',
'app.search.resultType': 'Ergebnistyp',
'app.search.softwareCatalog': 'Software-Katalog',
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/translations/rhdh/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export default createTranslationMessages({
'signIn.providers.saml.message': 'Iniciar sesión con SAML',

// App translations
'app.scaffolder.title': 'Autoservicio',
'app.search.title': 'Buscar',
'app.search.resultType': 'Tipo de resultado',
'app.search.softwareCatalog': 'Catálogo de software',
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/translations/rhdh/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export default createTranslationMessages({
'catalog.entityPage.definition.title': 'Définition',
'catalog.entityPage.diagram.title': 'Diagramme du système',
'catalog.entityPage.workflows.title': 'Flux de travail',
'app.scaffolder.title': 'Self-service',
'app.search.title': 'Recherche',
'app.search.resultType': 'Type de résultat',
'app.search.softwareCatalog': 'Catalogue de logiciels',
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/translations/rhdh/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export default createTranslationMessages({
'catalog.entityPage.definition.title': 'Definizione',
'catalog.entityPage.diagram.title': 'Diagramma di sistema',
'catalog.entityPage.workflows.title': 'Flussi di lavoro',
'app.scaffolder.title': 'Self-service',
'app.search.title': 'Ricerca',
'app.search.resultType': 'Tipo di risultato',
'app.search.softwareCatalog': 'Catalogo software',
Expand Down
1 change: 0 additions & 1 deletion packages/app/src/translations/rhdh/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export default createTranslationMessages({
'catalog.entityPage.definition.title': '定義',
'catalog.entityPage.diagram.title': 'システム図',
'catalog.entityPage.workflows.title': 'ワークフロー',
'app.scaffolder.title': 'セルフサービス',
'app.search.title': '検索',
'app.search.resultType': '結果タイプ',
'app.search.softwareCatalog': 'ソフトウェアカタログ',
Expand Down
3 changes: 0 additions & 3 deletions packages/app/src/translations/rhdh/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,6 @@ export const rhdhMessages = {
},
},
app: {
scaffolder: {
title: 'Self-service',
},
search: {
title: 'Search',
resultType: 'Result Type',
Expand Down
250 changes: 4 additions & 246 deletions packages/app/src/translations/scaffolder/fr.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions packages/app/src/translations/scaffolder/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export default createTranslationMessages({
ref: scaffolderTranslationRef,
full: false,
messages: {
'templateListPage.title': 'Self-service',
'templateListPage.pageTitle': 'Self-service',
'templateWizardPage.title': 'Self-service',
'templateWizardPage.pageTitle': 'Self-service',
'templateListPage.contentHeader.registerExistingButtonTitle':
'Importa un repository Git esistente',
},
Expand Down
4 changes: 4 additions & 0 deletions packages/app/src/translations/scaffolder/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export default createTranslationMessages({
ref: scaffolderTranslationRef,
full: false,
messages: {
'templateListPage.title': 'セルフサービス',
'templateListPage.pageTitle': 'セルフサービス',
'templateWizardPage.title': 'セルフサービス',
'templateWizardPage.pageTitle': 'セルフサービス',
'templateListPage.contentHeader.registerExistingButtonTitle':
'既存の Git リポジトリーのインポート',
},
Expand Down
4 changes: 4 additions & 0 deletions packages/app/src/translations/scaffolder/scaffolder-en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ const en = createTranslationMessages({
ref: scaffolderTranslationRef,
full: false, // False means that this is a partial translation
messages: {
'templateListPage.title': 'Self-service',
'templateListPage.pageTitle': 'Self-service',
'templateWizardPage.title': 'Self-service',
'templateWizardPage.pageTitle': 'Self-service',
'templateListPage.contentHeader.registerExistingButtonTitle':
'Import an existing Git repository',
},
Expand Down
2 changes: 2 additions & 0 deletions packages/app/src/utils/dynamicUI/extractDynamicConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export type DynamicRouteMenuItem =
export type MenuItemConfig = {
icon?: string;
title?: string;
titleKey?: string;
textKey?: string;
priority?: number;
parent?: string;
};
Expand Down
18 changes: 10 additions & 8 deletions packages/app/src/utils/dynamicUI/extractDynamicConfigFrontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,16 @@ export function compareMenuItems(a: MenuItem, b: MenuItem) {
function convertMenuItemsRecordToArray(
menuItemsRecord: Record<string, MenuItemConfig>,
): MenuItem[] {
return Object.keys(menuItemsRecord).map(
key =>
({
...menuItemsRecord[key],
children: [],
name: key,
}) as MenuItem,
);
return Object.keys(menuItemsRecord).map(key => {
const config = menuItemsRecord[key];
const { textKey, titleKey: configTitleKey, ...rest } = config;
return {
...rest,
name: key,
children: [],
titleKey: textKey ?? configTitleKey,
} as MenuItem;
});
}

export function buildTree(menuItemsArray: MenuItem[]): MenuItem[] {
Expand Down
16 changes: 8 additions & 8 deletions translations/backstage-fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@
"catalog-import": {
"fr": {
"buttons.back": "Retour",
"defaultImportPage.headerTitle": "Enregistrer un composant existant",
"defaultImportPage.headerTitle": "Importer un dépôt Git existant",
"defaultImportPage.contentHeaderTitle": "Commencez à suivre votre composant dans {{appTitle}}",
"defaultImportPage.supportTitle": "Commencez à suivre votre composant dans {{appTitle}} en l'ajoutant au catalogue de logiciels.",
"importInfoCard.title": "Enregistrer un composant existant",
"importInfoCard.title": "Importer un dépôt Git existant",
"importInfoCard.deepLinkTitle": "En savoir plus sur le catalogue de logiciels",
"importInfoCard.linkDescription": "Saisissez l'URL de votre référentiel de code source pour l'ajouter à {{appTitle}}.",
"importInfoCard.fileLinkTitle": "Lien vers un fichier d'entité existant",
Expand Down Expand Up @@ -469,17 +469,17 @@
"templateEditorPage.templateEditorTextArea.refreshIconTooltip": "Recharger le fichier",
"templateEditorPage.templateEditorTextArea.emptyStateParagraph": "Veuillez sélectionner une action dans le menu fichier.",
"templateEditorPage.templateFormPreviewer.title": "Charger le modèle existant",
"templateListPage.title": "Créer un nouveau composant",
"templateListPage.title": "Self-service",
"templateListPage.subtitle": "Créer de nouveaux composants logiciels à l'aide de modèles standard dans votre organisation",
"templateListPage.pageTitle": "Créer un nouveau composant",
"templateListPage.pageTitle": "Self-service",
"templateListPage.templateGroups.defaultTitle": "Modèles",
"templateListPage.templateGroups.otherTitle": "Autres modèles",
"templateListPage.contentHeader.registerExistingButtonTitle": "Enregistrer un composant existant",
"templateListPage.contentHeader.registerExistingButtonTitle": "Importer un dépôt Git existant",
"templateListPage.contentHeader.supportButtonTitle": "Créer de nouveaux composants logiciels à l'aide de modèles standard. Différents modèles créent différents types de composants (services, sites Web, documentation, ...).",
"templateListPage.additionalLinksForEntity.viewTechDocsTitle": "Voir TechDocs",
"templateWizardPage.title": "Créer un nouveau composant",
"templateWizardPage.title": "Self-service",
"templateWizardPage.subtitle": "Créer de nouveaux composants logiciels à l'aide de modèles standard dans votre organisation",
"templateWizardPage.pageTitle": "Créer un nouveau composant",
"templateWizardPage.pageTitle": "Self-service",
"templateWizardPage.pageContextMenu.editConfigurationTitle": "Modifier la configuration",
"templateEditorToolbar.customFieldExplorerTooltip": "Explorateur de champs personnalisés",
"templateEditorToolbar.installedActionsDocumentationTooltip": "Documentation des actions installées",
Expand Down Expand Up @@ -585,7 +585,7 @@
"catalog": {
"fr": {
"indexPage.title": "Catalogue {{orgName}}",
"indexPage.createButtonTitle": "Créer",
"indexPage.createButtonTitle": "Self-service",
"indexPage.supportButtonContent": "Toutes les entités de votre catalogue de logiciels",
"aboutCard.title": "À propos",
"aboutCard.refreshButtonTitle": "Actualisation de l'entité de planification",
Expand Down
16 changes: 8 additions & 8 deletions translations/backstage-it.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@
"catalog-import": {
"it": {
"buttons.back": "Indietro",
"defaultImportPage.headerTitle": "Registra un componente esistente",
"defaultImportPage.headerTitle": "Importa un repository Git esistente",
"defaultImportPage.contentHeaderTitle": "Inizia a monitorare il tuo componente in {{appTitle}}",
"defaultImportPage.supportTitle": "Inizia a monitorare il tuo componente in {{appTitle}} aggiungendolo al catalogo software.",
"importInfoCard.title": "Registra un componente esistente",
"importInfoCard.title": "Importa un repository Git esistente",
"importInfoCard.deepLinkTitle": "Scopri di più sul catalogo software",
"importInfoCard.linkDescription": "Inserisci l'URL del tuo repository del codice sorgente per aggiungerlo a {{appTitle}}.",
"importInfoCard.fileLinkTitle": "Collegamento a un file di entità esistente",
Expand Down Expand Up @@ -469,17 +469,17 @@
"templateEditorPage.templateEditorTextArea.refreshIconTooltip": "Ricarica file",
"templateEditorPage.templateEditorTextArea.emptyStateParagraph": "Seleziona un'azione nel menu file.",
"templateEditorPage.templateFormPreviewer.title": "Carica modello esistente",
"templateListPage.title": "Crea un nuovo componente",
"templateListPage.title": "Self-service",
"templateListPage.subtitle": "Crea nuovi componenti software utilizzando modelli standard nella tua organizzazione",
"templateListPage.pageTitle": "Crea un nuovo componente",
"templateListPage.pageTitle": "Self-service",
"templateListPage.templateGroups.defaultTitle": "Modelli",
"templateListPage.templateGroups.otherTitle": "Altri modelli",
"templateListPage.contentHeader.registerExistingButtonTitle": "Registra componente esistente",
"templateListPage.contentHeader.registerExistingButtonTitle": "Importa un repository Git esistente",
"templateListPage.contentHeader.supportButtonTitle": "Crea nuovi componenti software utilizzando modelli standard. Modelli diversi creano tipi diversi di componenti (servizi, siti web, documentazione, ...).",
"templateListPage.additionalLinksForEntity.viewTechDocsTitle": "Visualizza TechDocs",
"templateWizardPage.title": "Crea un nuovo componente",
"templateWizardPage.title": "Self-service",
"templateWizardPage.subtitle": "Crea nuovi componenti software utilizzando modelli standard nella tua organizzazione",
"templateWizardPage.pageTitle": "Crea un nuovo componente",
"templateWizardPage.pageTitle": "Self-service",
"templateWizardPage.pageContextMenu.editConfigurationTitle": "Modifica configurazione",
"templateEditorToolbar.customFieldExplorerTooltip": "Esplora campi personalizzati",
"templateEditorToolbar.installedActionsDocumentationTooltip": "Documentazione delle azioni installate",
Expand Down Expand Up @@ -585,7 +585,7 @@
"catalog": {
"it": {
"indexPage.title": "Catalogo {{orgName}}",
"indexPage.createButtonTitle": "Crea",
"indexPage.createButtonTitle": "Self-service",
"indexPage.supportButtonContent": "Tutte le entità del catalogo software",
"aboutCard.title": "Informazioni",
"aboutCard.refreshButtonTitle": "Pianifica aggiornamento entità",
Expand Down
16 changes: 8 additions & 8 deletions translations/backstage-ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@
"catalog-import": {
"ja": {
"buttons.back": "戻る",
"defaultImportPage.headerTitle": "既存のコンポーネントの登録",
"defaultImportPage.headerTitle": "既存の Git リポジトリーのインポート",
"defaultImportPage.contentHeaderTitle": "{{appTitle}} でのコンポーネントの追跡開始",
"defaultImportPage.supportTitle": "{{appTitle}} でコンポーネントの追跡を開始するには、コンポーネントをソフトウェアカタログに追加してください。",
"importInfoCard.title": "既存のコンポーネントの登録",
"importInfoCard.title": "既存の Git リポジトリーのインポート",
"importInfoCard.deepLinkTitle": "ソフトウェアカタログの詳細",
"importInfoCard.linkDescription": "{{appTitle}} に追加するソースコードリポジトリーの URL を入力してください。",
"importInfoCard.fileLinkTitle": "既存のエンティティーファイルへのリンク",
Expand Down Expand Up @@ -469,17 +469,17 @@
"templateEditorPage.templateEditorTextArea.refreshIconTooltip": "ファイルを再読み込みする",
"templateEditorPage.templateEditorTextArea.emptyStateParagraph": "ファイルメニューでアクションを選択してください。",
"templateEditorPage.templateFormPreviewer.title": "既存のテンプレートの読み込み",
"templateListPage.title": "新しいコンポーネントの作成",
"templateListPage.title": "セルフサービス",
"templateListPage.subtitle": "組織内の標準テンプレートを使用して新しいソフトウェアコンポーネントを作成する",
"templateListPage.pageTitle": "新しいコンポーネントの作成",
"templateListPage.pageTitle": "セルフサービス",
"templateListPage.templateGroups.defaultTitle": "テンプレート",
"templateListPage.templateGroups.otherTitle": "その他のテンプレート",
"templateListPage.contentHeader.registerExistingButtonTitle": "既存のコンポーネントの登録",
"templateListPage.contentHeader.registerExistingButtonTitle": "既存の Git リポジトリーのインポート",
"templateListPage.contentHeader.supportButtonTitle": "標準テンプレートを使用して新しいソフトウェアコンポーネントを作成します。テンプレートごとに異なる種類のコンポーネント (サービス、Web サイト、ドキュメント...) が作成されます。",
"templateListPage.additionalLinksForEntity.viewTechDocsTitle": "TechDocs の表示",
"templateWizardPage.title": "新しいコンポーネントの作成",
"templateWizardPage.title": "セルフサービス",
"templateWizardPage.subtitle": "組織内の標準テンプレートを使用して新しいソフトウェアコンポーネントを作成する",
"templateWizardPage.pageTitle": "新しいコンポーネントの作成",
"templateWizardPage.pageTitle": "セルフサービス",
"templateWizardPage.pageContextMenu.editConfigurationTitle": "設定の編集",
"templateEditorToolbar.customFieldExplorerTooltip": "カスタムフィールドエクスプローラー",
"templateEditorToolbar.installedActionsDocumentationTooltip": "インストール済みアクションのドキュメント",
Expand Down Expand Up @@ -585,7 +585,7 @@
"catalog": {
"ja": {
"indexPage.title": "{{orgName}} のカタログ",
"indexPage.createButtonTitle": "作成",
"indexPage.createButtonTitle": "セルフサービス",
"indexPage.supportButtonContent": "すべてのソフトウェアカタログエンティティー",
"aboutCard.title": "概要",
"aboutCard.refreshButtonTitle": "エンティティー更新のスケジューリング",
Expand Down
Loading
Loading