From f546e38c5bee2434068b5080b560faffb86be54e Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Thu, 14 Mar 2024 11:24:55 +0530 Subject: [PATCH 01/10] fix issue in entitypage tabs with nav link tabs Signed-off-by: npiyush97 --- .changeset/wicked-bugs-joke.md | 5 +++ .../src/layout/HeaderTabs/HeaderTabs.tsx | 32 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 .changeset/wicked-bugs-joke.md diff --git a/.changeset/wicked-bugs-joke.md b/.changeset/wicked-bugs-joke.md new file mode 100644 index 0000000000..3d1b866411 --- /dev/null +++ b/.changeset/wicked-bugs-joke.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': minor +--- + +Added `LinkTab` and `href` attributes to `nav` tabs for proper navigation. diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 799eab1eb5..1089c1632f 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -17,6 +17,7 @@ import Box from '@material-ui/core/Box'; import { makeStyles } from '@material-ui/core/styles'; import TabUI, { TabProps } from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; +import Tab from '@material-ui/core/Tab'; import React, { useCallback, useEffect, useState } from 'react'; // TODO(blam): Remove this implementation when the Tabs are ready @@ -57,18 +58,42 @@ const useStyles = makeStyles( { name: 'BackstageHeaderTabs' }, ); -export type Tab = { +export type TabProp = { id: string; label: string; tabProps?: TabProps; }; type HeaderTabsProps = { - tabs: Tab[]; + tabs: TabProp[]; onChange?: (index: number) => void; selectedIndex?: number; }; +function a11yProps(index: any) { + return { + id: `nav-tab-${index}`, + 'aria-controls': `nav-tabpanel-${index}`, + }; +} + +interface LinkTabProps { + label?: string; + href?: string; +} + +function LinkTab(props: LinkTabProps) { + return ( + ) => { + event.preventDefault(); + }} + {...props} + /> + ); +} + /** * Horizontal Tabs component * @@ -108,7 +133,7 @@ export function HeaderTabs(props: HeaderTabsProps) { value={selectedTab} > {tabs.map((tab, index) => ( - ))} From dd8de35586db3c5ab0f379939b8a10e09b555823 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Thu, 14 Mar 2024 11:27:36 +0530 Subject: [PATCH 02/10] changeset change Signed-off-by: npiyush97 --- .changeset/wicked-bugs-joke.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/wicked-bugs-joke.md b/.changeset/wicked-bugs-joke.md index 3d1b866411..ef60258037 100644 --- a/.changeset/wicked-bugs-joke.md +++ b/.changeset/wicked-bugs-joke.md @@ -1,5 +1,5 @@ --- -'@backstage/core-components': minor +'@backstage/core-components': patch --- Added `LinkTab` and `href` attributes to `nav` tabs for proper navigation. From 85c0ebe4b650db942bc129d3f2c9fdd11a99e266 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Thu, 14 Mar 2024 11:30:23 +0530 Subject: [PATCH 03/10] href to tab Signed-off-by: npiyush97 --- packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 1089c1632f..f6a6027e98 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -135,6 +135,7 @@ export function HeaderTabs(props: HeaderTabsProps) { {tabs.map((tab, index) => ( Date: Sun, 17 Mar 2024 21:52:01 +0530 Subject: [PATCH 04/10] added suggested changes Signed-off-by: npiyush97 --- .../src/layout/HeaderTabs/HeaderTabs.tsx | 54 ++++++++----------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index f6a6027e98..458a00f5e1 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -17,8 +17,9 @@ import Box from '@material-ui/core/Box'; import { makeStyles } from '@material-ui/core/styles'; import TabUI, { TabProps } from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; -import Tab from '@material-ui/core/Tab'; import React, { useCallback, useEffect, useState } from 'react'; +import { LinkProps } from '../../components'; +import { Link } from '@backstage/core-components'; // TODO(blam): Remove this implementation when the Tabs are ready // This is just a temporary solution to implementing tabs for now @@ -58,42 +59,27 @@ const useStyles = makeStyles( { name: 'BackstageHeaderTabs' }, ); -export type TabProp = { +export type Tab = { id: string; label: string; - tabProps?: TabProps; + tabProps?: { + component?: React.ElementType; + to: string; + value?: number; + className?: string; + classes?: { + selected: string; + root: string; + }; + }; }; type HeaderTabsProps = { - tabs: TabProp[]; + tabs: Tab[]; onChange?: (index: number) => void; selectedIndex?: number; }; -function a11yProps(index: any) { - return { - id: `nav-tab-${index}`, - 'aria-controls': `nav-tabpanel-${index}`, - }; -} - -interface LinkTabProps { - label?: string; - href?: string; -} - -function LinkTab(props: LinkTabProps) { - return ( - ) => { - event.preventDefault(); - }} - {...props} - /> - ); -} - /** * Horizontal Tabs component * @@ -120,7 +106,11 @@ export function HeaderTabs(props: HeaderTabsProps) { setSelectedTab(selectedIndex); } }, [selectedIndex]); - + function clean(path: string) { + let newPath = path; + newPath = path.replace(/^\//, ''); + return newPath; + } return ( {tabs.map((tab, index) => ( - ))} From 5f3f7b37ffab054c913ddf960f2d229eabedfb4e Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Sun, 17 Mar 2024 21:55:05 +0530 Subject: [PATCH 05/10] function name change Signed-off-by: npiyush97 --- packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 458a00f5e1..e21a47f2b9 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -106,7 +106,7 @@ export function HeaderTabs(props: HeaderTabsProps) { setSelectedTab(selectedIndex); } }, [selectedIndex]); - function clean(path: string) { + function removeLeadingSlash(path: string) { let newPath = path; newPath = path.replace(/^\//, ''); return newPath; @@ -129,7 +129,7 @@ export function HeaderTabs(props: HeaderTabsProps) { label={tab.label} key={tab.id} component={Link} - to={clean(tab.id)} + to={removeLeadingSlash(tab.id)} value={index} className={styles.defaultTab} classes={{ selected: styles.selected, root: styles.tabRoot }} From 955e51879a1df5e7a58965d26a5bd2df2bd1e22c Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Sun, 17 Mar 2024 22:39:21 +0530 Subject: [PATCH 06/10] additional props added Signed-off-by: npiyush97 --- .../src/components/TabbedLayout/types.ts | 11 ++++++++++- .../src/layout/HeaderTabs/HeaderTabs.tsx | 3 +-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/core-components/src/components/TabbedLayout/types.ts b/packages/core-components/src/components/TabbedLayout/types.ts index 59e26305bd..6901c3051c 100644 --- a/packages/core-components/src/components/TabbedLayout/types.ts +++ b/packages/core-components/src/components/TabbedLayout/types.ts @@ -21,5 +21,14 @@ export type SubRoute = { path: string; title: string; children: JSX.Element; - tabProps?: TabProps; + tabProps?: { + component?: React.ElementType; + to: string; + value?: number; + className?: string; + classes?: { + selected: string; + root: string; + }; + }; }; diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index e21a47f2b9..34acdda08c 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -18,7 +18,6 @@ import { makeStyles } from '@material-ui/core/styles'; import TabUI, { TabProps } from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; import React, { useCallback, useEffect, useState } from 'react'; -import { LinkProps } from '../../components'; import { Link } from '@backstage/core-components'; // TODO(blam): Remove this implementation when the Tabs are ready @@ -63,7 +62,7 @@ export type Tab = { id: string; label: string; tabProps?: { - component?: React.ElementType; + component?: React.ElementType; to: string; value?: number; className?: string; From c34bf3c135b99178f3b0b3b25607c83eefb547f5 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Tue, 19 Mar 2024 09:45:26 +0530 Subject: [PATCH 07/10] props fix Signed-off-by: npiyush97 --- .../src/components/TabbedLayout/types.ts | 11 +---------- .../src/layout/HeaderTabs/HeaderTabs.tsx | 13 ++----------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/packages/core-components/src/components/TabbedLayout/types.ts b/packages/core-components/src/components/TabbedLayout/types.ts index 6901c3051c..59e26305bd 100644 --- a/packages/core-components/src/components/TabbedLayout/types.ts +++ b/packages/core-components/src/components/TabbedLayout/types.ts @@ -21,14 +21,5 @@ export type SubRoute = { path: string; title: string; children: JSX.Element; - tabProps?: { - component?: React.ElementType; - to: string; - value?: number; - className?: string; - classes?: { - selected: string; - root: string; - }; - }; + tabProps?: TabProps; }; diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 34acdda08c..a87d024469 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -61,16 +61,7 @@ const useStyles = makeStyles( export type Tab = { id: string; label: string; - tabProps?: { - component?: React.ElementType; - to: string; - value?: number; - className?: string; - classes?: { - selected: string; - root: string; - }; - }; + tabProps?: TabProps; }; type HeaderTabsProps = { @@ -123,7 +114,6 @@ export function HeaderTabs(props: HeaderTabsProps) { > {tabs.map((tab, index) => ( ))} From 119c566d49ad6bee8a9287a7348ab2feac83e4df Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Tue, 19 Mar 2024 11:10:20 +0530 Subject: [PATCH 08/10] test fix Signed-off-by: npiyush97 --- .../DefaultSettingsPage/DefaultSettingsPage.test.tsx | 6 +++--- .../src/components/SettingsPage/SettingsPage.test.tsx | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx index 243e348319..e31c9f26fd 100644 --- a/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx +++ b/plugins/user-settings/src/components/DefaultSettingsPage/DefaultSettingsPage.test.tsx @@ -34,7 +34,7 @@ describe('', () => { it('should render the settings page with 3 tabs', async () => { const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(3); }); @@ -48,7 +48,7 @@ describe('', () => { , ); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); }); @@ -63,7 +63,7 @@ describe('', () => { , ); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); }); diff --git a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx index 8f2efa73f4..f6be87f14f 100644 --- a/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx +++ b/plugins/user-settings/src/components/SettingsPage/SettingsPage.test.tsx @@ -36,7 +36,7 @@ describe('', () => { it('should render the default settings page with 3 tabs', async () => { const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(3); }); @@ -49,7 +49,7 @@ describe('', () => { (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); }); @@ -63,7 +63,7 @@ describe('', () => { (useOutlet as jest.Mock).mockReturnValue(advancedTabRoute); const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(4); expect(tabs[3].textContent).toEqual('Advanced'); const user = userEvent.setup(); @@ -86,7 +86,7 @@ describe('', () => { (useOutlet as jest.Mock).mockReturnValue(customLayout); const { container } = await renderInTestApp(); - const tabs = container.querySelectorAll('[class*=MuiTabs-root] button'); + const tabs = container.querySelectorAll('[class*=MuiTabs-root] a'); expect(tabs).toHaveLength(2); expect(tabs[0].textContent).toEqual('General'); expect(tabs[1].textContent).toEqual('Advanced'); From 47418403a45052d6e7d7f505556aac4e38866bae Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Tue, 19 Mar 2024 11:44:06 +0530 Subject: [PATCH 09/10] changeset change Signed-off-by: npiyush97 --- .changeset/wicked-bugs-joke.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/wicked-bugs-joke.md b/.changeset/wicked-bugs-joke.md index ef60258037..94fc77a213 100644 --- a/.changeset/wicked-bugs-joke.md +++ b/.changeset/wicked-bugs-joke.md @@ -2,4 +2,4 @@ '@backstage/core-components': patch --- -Added `LinkTab` and `href` attributes to `nav` tabs for proper navigation. +Added Link component in `TabUI` providing functionality like copy link or open in new tab. From c77dff47f61aa060b033809652e3ac88ad31bd53 Mon Sep 17 00:00:00 2001 From: npiyush97 Date: Thu, 28 Mar 2024 00:32:02 +0530 Subject: [PATCH 10/10] added test Signed-off-by: npiyush97 --- .../src/layout/HeaderTabs/HeaderTabs.test.tsx | 9 +++++++++ .../core-components/src/layout/HeaderTabs/HeaderTabs.tsx | 4 +--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx index 5aec83bc2b..dad40c4615 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.test.tsx @@ -95,4 +95,13 @@ describe('', () => { await user.click(rendered.getByText('Docs')); expect(mockOnChange).toHaveBeenCalledTimes(1); }); + + it('should render 2 nav tabs', async () => { + const rendered = await renderInTestApp(); + const tabs = rendered.queryAllByTestId(id => id.startsWith('header-tab')); + expect(tabs).toHaveLength(2); + tabs.forEach(tab => { + expect(tab.tagName.toLocaleLowerCase('en-US')).toBe('a'); + }); + }); }); diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index a87d024469..852622c741 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -97,9 +97,7 @@ export function HeaderTabs(props: HeaderTabsProps) { } }, [selectedIndex]); function removeLeadingSlash(path: string) { - let newPath = path; - newPath = path.replace(/^\//, ''); - return newPath; + return path.replace(/^\//, ''); } return (