diff --git a/.changeset/empty-games-hug.md b/.changeset/empty-games-hug.md
new file mode 100644
index 0000000000..e5bb0b4a95
--- /dev/null
+++ b/.changeset/empty-games-hug.md
@@ -0,0 +1,9 @@
+---
+'@backstage/plugin-catalog': patch
+---
+
+Add missing translation entries for catalog UI text.
+
+This change adds translation keys and updates relevant UI components to use the correct localized labels and text in the catalog plugin. It ensures that catalog screens such as entity layout, tabs, search result items, table labels, and other UI elements correctly reference the i18n system for translation.
+
+No functional behavior is changed aside from the improved internationalization support.
diff --git a/plugins/catalog/report-alpha.api.md b/plugins/catalog/report-alpha.api.md
index 4ad9f94206..ebea4f4617 100644
--- a/plugins/catalog/report-alpha.api.md
+++ b/plugins/catalog/report-alpha.api.md
@@ -43,11 +43,16 @@ export const catalogTranslationRef: TranslationRef<
readonly 'indexPage.title': '{{orgName}} Catalog';
readonly 'indexPage.createButtonTitle': 'Create';
readonly 'indexPage.supportButtonContent': 'All your software catalog entities';
+ readonly 'entityPage.notFoundMessage': 'There is no {{kind}} with the requested {{link}}.';
+ readonly 'entityPage.notFoundLinkText': 'kind, namespace, and name';
readonly 'aboutCard.title': 'About';
+ readonly 'aboutCard.unknown': 'unknown';
readonly 'aboutCard.refreshButtonTitle': 'Schedule entity refresh';
readonly 'aboutCard.editButtonTitle': 'Edit Metadata';
+ readonly 'aboutCard.editButtonAriaLabel': 'Edit';
readonly 'aboutCard.createSimilarButtonTitle': 'Create something similar';
readonly 'aboutCard.refreshScheduledMessage': 'Refresh scheduled';
+ readonly 'aboutCard.refreshButtonAriaLabel': 'Refresh';
readonly 'aboutCard.launchTemplate': 'Launch Template';
readonly 'aboutCard.viewTechdocs': 'View TechDocs';
readonly 'aboutCard.viewSource': 'View Source';
@@ -66,8 +71,11 @@ export const catalogTranslationRef: TranslationRef<
readonly 'aboutCard.tagsField.value': 'No Tags';
readonly 'aboutCard.tagsField.label': 'Tags';
readonly 'aboutCard.targetsField.label': 'Targets';
+ readonly 'searchResultItem.type': 'Type';
+ readonly 'searchResultItem.kind': 'Kind';
readonly 'searchResultItem.lifecycle': 'Lifecycle';
- readonly 'searchResultItem.Owner': 'Owner';
+ readonly 'searchResultItem.owner': 'Owner';
+ readonly 'catalogTable.allFilters': 'All';
readonly 'catalogTable.warningPanelTitle': 'Could not fetch catalog entities.';
readonly 'catalogTable.viewActionTitle': 'View';
readonly 'catalogTable.editActionTitle': 'Edit';
@@ -84,6 +92,7 @@ export const catalogTranslationRef: TranslationRef<
readonly 'entityContextMenu.inspectMenuTitle': 'Inspect entity';
readonly 'entityContextMenu.copyURLMenuTitle': 'Copy entity URL';
readonly 'entityContextMenu.unregisterMenuTitle': 'Unregister entity';
+ readonly 'entityContextMenu.moreButtonAriaLabel': 'more';
readonly 'entityLabelsCard.title': 'Labels';
readonly 'entityLabelsCard.emptyDescription': 'No labels defined for this entity. You can add labels to your entity YAML as shown in the highlighted example below:';
readonly 'entityLabelsCard.readMoreButtonTitle': 'Read more';
@@ -96,6 +105,7 @@ export const catalogTranslationRef: TranslationRef<
readonly 'entityNotFound.title': 'Entity was not found';
readonly 'entityNotFound.description': 'Want to help us build this? Check out our Getting Started documentation.';
readonly 'entityNotFound.docButtonTitle': 'DOCS';
+ readonly 'entityTabs.tabsAriaLabel': 'Tabs';
readonly entityProcessingErrorsDescription: 'The error below originates from';
readonly entityRelationWarningDescription: "This entity has relations to other entities, which can't be found in the catalog.\n Entities not found are: ";
readonly 'hasComponentsCard.title': 'Has components';
diff --git a/plugins/catalog/src/alpha/components/EntityLayout/EntityLayout.tsx b/plugins/catalog/src/alpha/components/EntityLayout/EntityLayout.tsx
index dbe25e9401..ee6e2fc012 100644
--- a/plugins/catalog/src/alpha/components/EntityLayout/EntityLayout.tsx
+++ b/plugins/catalog/src/alpha/components/EntityLayout/EntityLayout.tsx
@@ -180,11 +180,14 @@ export const EntityLayout = (props: EntityLayoutProps) => {
NotFoundComponent
) : (
- There is no {kind} with the requested{' '}
-
- kind, namespace, and name
-
- .
+ {t('entityPage.notFoundMessage', {
+ kind,
+ link: (
+
+ {t('entityPage.notFoundLinkText')}
+
+ ),
+ })}
)}
diff --git a/plugins/catalog/src/alpha/components/EntityTabs/EntityTabsList.tsx b/plugins/catalog/src/alpha/components/EntityTabs/EntityTabsList.tsx
index dae400ce5d..d77cc5e444 100644
--- a/plugins/catalog/src/alpha/components/EntityTabs/EntityTabsList.tsx
+++ b/plugins/catalog/src/alpha/components/EntityTabs/EntityTabsList.tsx
@@ -18,9 +18,12 @@ import { ReactElement, useMemo } from 'react';
import Box from '@material-ui/core/Box';
import Tabs from '@material-ui/core/Tabs';
import { makeStyles } from '@material-ui/core/styles';
-import { EntityTabsGroup } from './EntityTabsGroup';
+import { useTranslationRef } from '@backstage/core-plugin-api/alpha';
import { EntityContentGroupDefinitions } from '@backstage/plugin-catalog-react/alpha';
+import { EntityTabsGroup } from './EntityTabsGroup';
+import { catalogTranslationRef } from '../../translation';
+
/** @public */
export type HeaderTabsClassKey =
| 'tabsWrapper'
@@ -81,6 +84,7 @@ type EntityTabsListProps = {
export function EntityTabsList(props: EntityTabsListProps) {
const styles = useStyles();
+ const { t } = useTranslationRef(catalogTranslationRef);
const { tabs: items, selectedIndex = 0, showIcons, groupDefinitions } = props;
@@ -108,7 +112,7 @@ export function EntityTabsList(props: EntityTabsListProps) {
textColor="inherit"
variant="scrollable"
scrollButtons="auto"
- aria-label="tabs"
+ aria-label={t('entityTabs.tabsAriaLabel')}
value={selectedItem?.group ?? selectedItem?.id}
>
{Object.entries(groups).map(([id, tabGroup]) => (
diff --git a/plugins/catalog/src/alpha/translation.ts b/plugins/catalog/src/alpha/translation.ts
index 498104db45..f346c408b9 100644
--- a/plugins/catalog/src/alpha/translation.ts
+++ b/plugins/catalog/src/alpha/translation.ts
@@ -25,15 +25,22 @@ export const catalogTranslationRef = createTranslationRef({
createButtonTitle: 'Create',
supportButtonContent: 'All your software catalog entities',
},
+ entityPage: {
+ notFoundMessage: 'There is no {{kind}} with the requested {{link}}.',
+ notFoundLinkText: 'kind, namespace, and name',
+ },
aboutCard: {
title: 'About',
refreshButtonTitle: 'Schedule entity refresh',
editButtonTitle: 'Edit Metadata',
+ editButtonAriaLabel: 'Edit',
createSimilarButtonTitle: 'Create something similar',
refreshScheduledMessage: 'Refresh scheduled',
+ refreshButtonAriaLabel: 'Refresh',
launchTemplate: 'Launch Template',
viewTechdocs: 'View TechDocs',
viewSource: 'View Source',
+ unknown: 'unknown',
descriptionField: {
label: 'Description',
value: 'No description',
@@ -69,8 +76,10 @@ export const catalogTranslationRef = createTranslationRef({
},
},
searchResultItem: {
+ kind: 'Kind',
+ type: 'Type',
lifecycle: 'Lifecycle',
- Owner: 'Owner',
+ owner: 'Owner',
},
catalogTable: {
warningPanelTitle: 'Could not fetch catalog entities.',
@@ -78,6 +87,7 @@ export const catalogTranslationRef = createTranslationRef({
editActionTitle: 'Edit',
starActionTitle: 'Add to favorites',
unStarActionTitle: 'Remove from favorites',
+ allFilters: 'All',
},
dependencyOfComponentsCard: {
title: 'Dependency of components',
@@ -97,6 +107,7 @@ export const catalogTranslationRef = createTranslationRef({
inspectMenuTitle: 'Inspect entity',
copyURLMenuTitle: 'Copy entity URL',
unregisterMenuTitle: 'Unregister entity',
+ moreButtonAriaLabel: 'more',
},
entityLabelsCard: {
title: 'Labels',
@@ -121,6 +132,9 @@ export const catalogTranslationRef = createTranslationRef({
'Want to help us build this? Check out our Getting Started documentation.',
docButtonTitle: 'DOCS',
},
+ entityTabs: {
+ tabsAriaLabel: 'Tabs',
+ },
deleteEntity: {
dialogTitle: 'Are you sure you want to delete this entity?',
deleteButtonTitle: 'Delete',
diff --git a/plugins/catalog/src/components/AboutCard/AboutCard.tsx b/plugins/catalog/src/components/AboutCard/AboutCard.tsx
index fd1c05ba5f..8e90659520 100644
--- a/plugins/catalog/src/components/AboutCard/AboutCard.tsx
+++ b/plugins/catalog/src/components/AboutCard/AboutCard.tsx
@@ -241,7 +241,7 @@ export function InternalAboutCard(props: InternalAboutCardProps) {
<>
{allowRefresh && canRefresh && (
@@ -250,7 +250,7 @@ export function InternalAboutCard(props: InternalAboutCardProps) {
)}
({
value: {
@@ -55,6 +57,7 @@ export interface AboutFieldProps {
export function AboutField(props: AboutFieldProps) {
const { label, value, gridSizes, children, className } = props;
const classes = useStyles();
+ const { t } = useTranslationRef(catalogTranslationRef);
const childElements = useElementFilter(children, c => c.getElements());
@@ -64,7 +67,7 @@ export function AboutField(props: AboutFieldProps) {
childElements
) : (
- {value || `unknown`}
+ {value || t('aboutCard.unknown')}
);
return (
diff --git a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx
index f33c9cd412..0e604f2d5b 100644
--- a/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx
+++ b/plugins/catalog/src/components/CatalogSearchResultListItem/CatalogSearchResultListItem.tsx
@@ -127,8 +127,18 @@ export function CatalogSearchResultListItem(
}
/>
- {result.kind && }
- {result.type && }
+ {result.kind && (
+
+ )}
+ {result.type && (
+
+ )}
{result.lifecycle && (
)}
diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx
index 464688c590..7875431246 100644
--- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx
+++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx
@@ -186,7 +186,9 @@ export const CatalogTable = (props: CatalogTableProps) => {
const currentType = filters.type?.value || '';
const currentCount = typeof totalItems === 'number' ? `(${totalItems})` : '';
// TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar
- const titlePreamble = capitalize(filters.user?.value ?? 'all');
+ const titlePreamble = capitalize(
+ filters.user?.value ?? t('catalogTable.allFilters'),
+ );
const title =
props.title ||
[titlePreamble, currentType, pluralize(currentKind), currentCount]
diff --git a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx
index 2d9c392322..23dc9c1efb 100644
--- a/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx
+++ b/plugins/catalog/src/components/EntityContextMenu/EntityContextMenu.tsx
@@ -161,7 +161,7 @@ export function EntityContextMenu(props: EntityContextMenuProps) {
<>
{
NotFoundComponent
) : (
- There is no {kind} with the requested{' '}
-
- kind, namespace, and name
-
- .
+ {t('entityPage.notFoundMessage', {
+ kind,
+ link: (
+
+ {t('entityPage.notFoundLinkText')}
+
+ ),
+ })}
)}