From c624c027d9be865701c85913d79580b8d93af76e Mon Sep 17 00:00:00 2001 From: Oskar Jiang Date: Fri, 23 Jan 2026 01:26:07 +0100 Subject: [PATCH 1/2] feat(global-header): support multiple support links Signed-off-by: Oskar Jiang --- .../SupportButton/SupportButton.test.tsx | 47 +++++++++++++++++ .../SupportButton/SupportButton.tsx | 52 +++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.test.tsx b/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.test.tsx index 7ff0438c35..e6457e0846 100644 --- a/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.test.tsx +++ b/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.test.tsx @@ -52,6 +52,37 @@ const configWithoutSupportUrl = mockApis.config({ }, }); +const configWithSupportItems = mockApis.config({ + data: { + app: { + support: { + items: [ + { + title: 'Issues', + icon: 'github', + links: [ + { + url: 'https://github.com/backstage/backstage/issues', + title: 'GitHub Issues', + }, + ], + }, + { + title: 'Discord Chatroom', + icon: 'chat', + links: [ + { + url: 'https://discord.gg/backstage-687207715902193673', + title: '#backstage', + }, + ], + }, + ], + }, + }, + }, +}); + describe('SupportButton', () => { it('renders a button when the support url is defined', async () => { const { getByTestId } = await renderInTestApp( @@ -104,4 +135,20 @@ describe('SupportButton', () => { '_blank', ); }); + + it('renders multiple buttons when support items are defined in config', async () => { + const { getAllByTestId } = await renderInTestApp( + + + , + ); + const buttons = getAllByTestId('support-button'); + expect(buttons).toHaveLength(2); + expect(buttons[0].getAttribute('href')).toEqual( + 'https://github.com/backstage/backstage/issues', + ); + expect(buttons[1].getAttribute('href')).toEqual( + 'https://discord.gg/backstage-687207715902193673', + ); + }); }); diff --git a/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.tsx b/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.tsx index 0fa42684cc..7d29b9f0db 100644 --- a/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.tsx +++ b/workspaces/global-header/plugins/global-header/src/components/SupportButton/SupportButton.tsx @@ -22,6 +22,17 @@ import { CSSProperties } from 'react'; import { useTranslation } from '../../hooks/useTranslation'; import { translateWithFallback } from '../../utils/translationUtils'; +interface SupportLink { + url: string; + title: string; +} + +interface SupportItem { + title: string; + icon?: string; + links: SupportLink[]; +} + /** * @public */ @@ -30,6 +41,7 @@ export interface SupportButtonProps { title?: string; titleKey?: string; to?: string; + items?: SupportItem[]; tooltip?: string; style?: CSSProperties; onClick?: () => void; @@ -41,6 +53,7 @@ export const SupportButton = ({ title = 'Support', titleKey = 'help.supportTitle', to, + items, icon = 'support', tooltip, style, @@ -53,6 +66,45 @@ export const SupportButton = ({ const displayTitle = translateWithFallback(t, titleKey, title); const supportUrl = to ?? config?.getOptionalString('app.support.url'); + const supportItems = + items ?? + (config + ?.getOptionalConfigArray('app.support.items') + ?.map(item => ({ + title: item.getString('title'), + icon: item.getOptionalString('icon'), + links: item.getConfigArray('links').map(link => ({ + url: link.getString('url'), + title: link.getString('title'), + })), + })) as SupportItem[] | undefined); + + if (supportItems && supportItems.length > 0) { + return ( + <> + {supportItems.map((item: SupportItem) => + item.links.map((link: SupportLink) => ( + + + + )), + )} + + ); + } + if (!supportUrl) { return null; } From 2cd2666bfc204cfd20fd22c2900563794b21e787 Mon Sep 17 00:00:00 2001 From: Oskar Jiang Date: Fri, 23 Jan 2026 01:29:53 +0100 Subject: [PATCH 2/2] chore(global-header): add changeset Signed-off-by: Oskar Jiang --- workspaces/global-header/.changeset/selfish-gorillas-bake.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 workspaces/global-header/.changeset/selfish-gorillas-bake.md diff --git a/workspaces/global-header/.changeset/selfish-gorillas-bake.md b/workspaces/global-header/.changeset/selfish-gorillas-bake.md new file mode 100644 index 0000000000..eaf46ae280 --- /dev/null +++ b/workspaces/global-header/.changeset/selfish-gorillas-bake.md @@ -0,0 +1,5 @@ +--- +'@red-hat-developer-hub/backstage-plugin-global-header': minor +--- + +Support multiple support links