Skip to content

Commit

Permalink
Add Tabs to Domain Page (#572)
Browse files Browse the repository at this point in the history
- Add tabs with config to Domain Page Layout
- Rename decodeURLParams to decodeUrlParams to be consistent with the actual util name
  • Loading branch information
adhityamamallan committed May 17, 2024
1 parent 70f9a00 commit 83c9829
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 6 deletions.
9 changes: 9 additions & 0 deletions src/views/domain-page/config/domain-page-tabs.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { DomainPageTabs } from '../domain-page-tabs/domain-page-tabs.types';

const domainPageTabsConfig = [
{ key: 'workflows', title: 'Workflows' },
{ key: 'metadata', title: 'Metadata' },
{ key: 'settings', title: 'Settings' },
] as const satisfies DomainPageTabs;

export default domainPageTabsConfig;
17 changes: 15 additions & 2 deletions src/views/domain-page/domain-page-content/domain-page-content.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import React from 'react';
import decodeUrlParams from '@/utils/decode-url-params';

export default async function DomainPageContent() {
import {
type DomainPageContentParams,
type Props,
} from './domain-page-content.types';

export default async function DomainPageContent(props: Props) {
const decodedParams = decodeUrlParams(
props.params
) as DomainPageContentParams;
// Add a switch case here, and depending on what domainTab is, return the corresponding page content
// Otherwise just throw a 404: https://nextjs.org/docs/pages/api-reference/functions/get-server-side-props#notfound
return <div>Placeholder for Domain Page content</div>;
return (
<section>
<div>Selected tab: {decodedParams.domainTab}</div>
</section>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import domainPageTabsConfig from '../config/domain-page-tabs.config';

export type DomainPageContentParams = {
domain: string;
cluster: string;
domainTab: (typeof domainPageTabsConfig)[number]['key'];
};

export type Props = {
params: DomainPageContentParams;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import { render, screen, act, fireEvent } from '@/test-utils/rtl';

import DomainPageTabs from '../domain-page-tabs';
import domainPageTabsConfig from '../../config/domain-page-tabs.config';
import { type PageTab } from '@/components/page-tabs/page-tabs.types';

const mockPushFn = jest.fn();
jest.mock('next/navigation', () => ({
...jest.requireActual('next/navigation'),
useRouter: () => ({
push: mockPushFn,
back: () => {},
replace: () => {},
forward: () => {},
prefetch: () => {},
refresh: () => {},
}),
useParams: () => ({
domain: 'mock-domain',
cluster: 'cluster_1',
domainTab: 'workflows',
}),
}));

jest.mock('../../config/domain-page-tabs.config', () => [
{
key: 'workflows',
title: 'Workflows',
artwork: () => <div data-testid="workflows-artwork" />,
},
{
key: 'page-2',
title: 'Page 2',
},
]);

describe('DomainPageTabs', () => {
afterEach(() => {
jest.clearAllMocks();
});

it('renders tabs titles correctly', () => {
render(<DomainPageTabs />);

domainPageTabsConfig.forEach(({ title }) => {
expect(screen.getByText(title)).toBeInTheDocument();
});
});

it('reroutes when new tab is clicked', () => {
render(<DomainPageTabs />);

const page2Tab = screen.getByText('Page 2');
act(() => {
fireEvent.click(page2Tab);
});

expect(mockPushFn).toHaveBeenCalledWith('page-2');
});

it('renders tabs artworks correctly', () => {
render(<DomainPageTabs />);

domainPageTabsConfig.forEach(({ key, artwork }: PageTab) => {
if (typeof artwork !== 'undefined')
expect(screen.getByTestId(`${key}-artwork`)).toBeInTheDocument();
else
expect(screen.queryByTestId(`${key}-artwork`)).not.toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { styled as createStyled, type Theme } from 'baseui';

export const styled = {
PageTabsContainer: createStyled('div', ({ $theme }: { $theme: Theme }) => ({
marginTop: $theme.sizing.scale950,
})),
};
27 changes: 27 additions & 0 deletions src/views/domain-page/domain-page-tabs/domain-page-tabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use client';
import React from 'react';
import { useRouter, useParams } from 'next/navigation';
import PageTabs from '@/components/page-tabs/page-tabs';
import decodeUrlParams from '@/utils/decode-url-params';

import { styled } from './domain-page-tabs.styles';
import type { DomainPageTabsParams } from './domain-page-tabs.types';
import domainPageTabsConfig from '../config/domain-page-tabs.config';

export default function DomainPageTabs() {
const router = useRouter();
const params = useParams<DomainPageTabsParams>();
const decodedParams = decodeUrlParams(params) as DomainPageTabsParams;

return (
<styled.PageTabsContainer>
<PageTabs
selectedTab={decodedParams.domainTab}
tabList={domainPageTabsConfig}
setSelectedTab={(newTab) => {
router.push(encodeURIComponent(newTab.toString()));
}}
/>
</styled.PageTabsContainer>
);
}
10 changes: 10 additions & 0 deletions src/views/domain-page/domain-page-tabs/domain-page-tabs.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { PageTab } from '@/components/page-tabs/page-tabs.types';
import domainPageTabsConfig from '../config/domain-page-tabs.config';

export type DomainPageTabs = Array<PageTab>;

export type DomainPageTabsParams = {
domain: string;
cluster: string;
domainTab: (typeof domainPageTabsConfig)[number]['key'];
};
9 changes: 5 additions & 4 deletions src/views/domain-page/domain-page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React, { Suspense } from 'react';

import AsyncPropsLoader from '@/components/async-props-loader/async-props-loader';
import decodeURLParams from '@/utils/decode-url-params';
import decodeUrlParams from '@/utils/decode-url-params';

import { Props } from './domain-page.types';
import { getCachedDomainInfo } from './helpers/get-domain-info';
import DomainPageHeader from './domain-page-header/domain-page-header';
import DomainPageHeaderInfo from './domain-page-header-info/domain-page-header-info';
import { getCachedDomainInfo } from './helpers/get-domain-info';
import DomainPageTabs from './domain-page-tabs/domain-page-tabs';

export default async function DomainPage(props: Props) {
const decodedParams = decodeURLParams(props.params);
const decodedParams = decodeUrlParams(props.params);
return (
<>
<DomainPageHeader
Expand All @@ -32,7 +33,7 @@ export default async function DomainPage(props: Props) {
</Suspense>
}
/>
{/* TODO: Add Tabs here */}
<DomainPageTabs />
{/* props.children is injected here by the Next router, loading domain-page-content.tsx */}
{props.children}
</>
Expand Down

0 comments on commit 83c9829

Please sign in to comment.