Skip to content

Commit

Permalink
feature(frontend): Adding a way to customize Tracetest header (#3087)
Browse files Browse the repository at this point in the history
* feature(frontend): Adding a way to customize Tracetest header

* moving the store setup elsewhere

* moving the store setup elsewhere

* fixing test

* fixing variable set selector position for test suite runs

* updating redux toolkit
  • Loading branch information
xoscar committed Aug 23, 2023
1 parent 71957c4 commit de48920
Show file tree
Hide file tree
Showing 28 changed files with 195 additions and 186 deletions.
62 changes: 31 additions & 31 deletions web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/package.json
Expand Up @@ -13,7 +13,7 @@
"@dnd-kit/sortable": "7.0.1",
"@lezer/highlight": "1.0.0",
"@opentelemetry/semantic-conventions": "1.3.0",
"@reduxjs/toolkit": "1.9.1",
"@reduxjs/toolkit": "1.9.5",
"@segment/analytics-next": "1.51.2",
"@sentry/react": "6.19.7",
"@sentry/tracing": "6.19.7",
Expand Down
9 changes: 7 additions & 2 deletions web/src/BaseApp.tsx
@@ -1,9 +1,14 @@
import Router from 'components/Router';
import SettingsValuesProvider from 'providers/SettingsValues';
import {TCustomHeader} from 'components/Layout/Layout';

const BaseApp = () => (
interface IProps {
customHeader?: TCustomHeader;
}

const BaseApp = ({customHeader}: IProps) => (
<SettingsValuesProvider>
<Router />
<Router customHeader={customHeader} />
</SettingsValuesProvider>
);

Expand Down
11 changes: 9 additions & 2 deletions web/src/components/Header/Header.styled.tsx
Expand Up @@ -12,6 +12,7 @@ export const Header = styled(Layout.Header)`
line-height: 48px;
padding: 0;
padding-left: 24px;
padding-right: 24px;
.ant-dropdown-trigger {
display: block;
Expand All @@ -29,13 +30,12 @@ export const Header = styled(Layout.Header)`

export const Logo = styled.img`
height: 24px;
margin-right: 24px;
margin-right: 12px;
`;

export const QuestionIcon = styled(QuestionCircleOutlined)`
color: ${({theme}) => theme.color.primary};
font-size: ${({theme}) => theme.size.lg};
margin: 0 24px;
`;

export const AppVersion = styled(Typography.Text)`
Expand All @@ -44,3 +44,10 @@ export const AppVersion = styled(Typography.Text)`
font-size: ${({theme}) => theme.size.sm};
}
`;

export const MenuContainer = styled.div`
display: flex;
gap: 12px;
flex-direction: row;
align-items: center;
`;
8 changes: 2 additions & 6 deletions web/src/components/Header/Header.tsx
@@ -1,7 +1,4 @@
import {Space} from 'antd';

import Logo from 'assets/Logo.svg';
import VariableSetSelector from 'components/VariableSetSelector';
import Link from 'components/Link';
import NoTracingPopover from 'components/NoTracingPopover';
import * as S from './Header.styled';
Expand All @@ -22,11 +19,10 @@ const Header = ({hasLogo = false, isNoTracingMode}: IProps) => (
)}
</div>

<Space>
<S.MenuContainer>
{isNoTracingMode && <NoTracingPopover />}
<VariableSetSelector />
<HelpMenu />
</Space>
</S.MenuContainer>
</S.Header>
);

Expand Down
5 changes: 5 additions & 0 deletions web/src/components/Header/index.ts
@@ -1,2 +1,7 @@
import HelpMenu from './HelpMenu';
import * as HeaderStyled from './Header.styled';

// eslint-disable-next-line no-restricted-exports
export {default} from './Header';

export {HelpMenu, HeaderStyled};
19 changes: 11 additions & 8 deletions web/src/components/Layout/Layout.tsx
@@ -1,7 +1,6 @@
import {ClusterOutlined, GlobalOutlined, SettingOutlined} from '@ant-design/icons';
import {AppstoreAddOutlined, ClusterOutlined, GlobalOutlined, SettingOutlined} from '@ant-design/icons';
import {Menu} from 'antd';
import React from 'react';
import {useLocation} from 'react-router-dom';
import {Outlet, useLocation} from 'react-router-dom';

import logoAsset from 'assets/logo-white.svg';
import FileViewerModalProvider from 'components/FileViewerModal/FileViewerModal.provider';
Expand All @@ -16,8 +15,10 @@ import NotificationProvider from 'providers/Notification/Notification.provider';
import {ConfigMode} from 'types/DataStore.types';
import * as S from './Layout.styled';

export type TCustomHeader = typeof Header;

interface IProps {
children?: React.ReactNode;
customHeader?: TCustomHeader;
hasMenu?: boolean;
}

Expand All @@ -30,7 +31,7 @@ const menuItems = [
},
{
key: '1',
icon: <ClusterOutlined />,
icon: <AppstoreAddOutlined />,
label: <Link to="/testsuites">Test Suites</Link>,
path: '/testsuites',
},
Expand All @@ -51,7 +52,7 @@ const footerMenuItems = [
},
];

const Layout = ({children, hasMenu = false}: IProps) => {
const Layout = ({hasMenu = false, customHeader: CustomHeader = Header}: IProps) => {
useRouterSync();
const {dataStoreConfig, isLoading} = useSettingsValues();
const pathname = useLocation().pathname;
Expand Down Expand Up @@ -99,8 +100,10 @@ const Layout = ({children, hasMenu = false}: IProps) => {
)}

<S.Layout>
<Header hasLogo={!hasMenu} isNoTracingMode={isNoTracingMode && !isLoading} />
<S.Content $hasMenu={hasMenu}>{children}</S.Content>
<CustomHeader hasLogo={!hasMenu} isNoTracingMode={isNoTracingMode && !isLoading} />
<S.Content $hasMenu={hasMenu}>
<Outlet />
</S.Content>
</S.Layout>
</S.Layout>
</VariableSetProvider>
Expand Down
7 changes: 1 addition & 6 deletions web/src/components/Layout/__tests__/Layout.test.tsx
Expand Up @@ -2,12 +2,7 @@ import {render} from 'test-utils';
import Layout from '../Layout';

it('Layout', async () => {
const {getByText, getByTestId} = render(
<Layout>
<h2>This</h2>
</Layout>
);
const {getByTestId} = render(<Layout />);

expect(getByTestId('menu-link')).toBeInTheDocument();
expect(getByText('This')).toBeTruthy();
});
Expand Up @@ -58,7 +58,7 @@ export const Trigger = styled.div`
gap: 6px;
align-items: center;
cursor: pointer;
margin-right: 24px;
margin-right: 8px;
border-radius: 12px;
padding: 4px 7px;
background: ${({theme}) => theme.color.backgroundDark};
Expand Down
41 changes: 24 additions & 17 deletions web/src/components/Router/Router.tsx
Expand Up @@ -10,25 +10,32 @@ import TestSuite from 'pages/TestSuite';
import TestSuiteRunOverview from 'pages/TestSuiteRunOverview';
import TestSuiteRunAutomate from 'pages/TestSuiteRunAutomate';
import AutomatedTestRun from 'pages/AutomatedTestRun';
import Layout, {TCustomHeader} from 'components/Layout/Layout';

const Router = () => (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/testsuites" element={<TestSuites />} />

<Route path="/variablesets" element={<VariableSet />} />

<Route path="/settings" element={<Settings />} />
interface IProps {
customHeader?: TCustomHeader;
}

<Route path="/test/:testId" element={<Test />} />
<Route path="/test/:testId/run/:runId" element={<RunDetail />} />
<Route path="/test/:testId/run/:runId/:mode" element={<RunDetail />} />
<Route path="/test/:testId/run" element={<AutomatedTestRun />} />

<Route path="/testsuite/:testSuiteId" element={<TestSuite />} />
<Route path="/testsuite/:testSuiteId/run/:runId" element={<TestSuiteRunOverview />} />
<Route path="/testsuite/:testSuiteId/run/:runId/overview" element={<TestSuiteRunOverview />} />
<Route path="/testsuite/:testSuiteId/run/:runId/automate" element={<TestSuiteRunAutomate />} />
const Router = ({customHeader}: IProps) => (
<Routes>
<Route element={<Layout hasMenu customHeader={customHeader} />}>
<Route path="/" element={<Home />} />
<Route path="/testsuites" element={<TestSuites />} />
<Route path="/variablesets" element={<VariableSet />} />
<Route path="/settings" element={<Settings />} />
</Route>

<Route element={<Layout customHeader={customHeader} />}>
<Route path="/test/:testId" element={<Test />} />
<Route path="/test/:testId/run/:runId" element={<RunDetail />} />
<Route path="/test/:testId/run/:runId/:mode" element={<RunDetail />} />
<Route path="/test/:testId/run" element={<AutomatedTestRun />} />

<Route path="/testsuite/:testSuiteId" element={<TestSuite />} />
<Route path="/testsuite/:testSuiteId/run/:runId" element={<TestSuiteRunOverview />} />
<Route path="/testsuite/:testSuiteId/run/:runId/overview" element={<TestSuiteRunOverview />} />
<Route path="/testsuite/:testSuiteId/run/:runId/automate" element={<TestSuiteRunAutomate />} />
</Route>

<Route path="*" element={<Navigate to="/" />} />
</Routes>
Expand Down
2 changes: 2 additions & 0 deletions web/src/components/RunDetailLayout/HeaderRight.tsx
Expand Up @@ -12,6 +12,7 @@ import {useTestOutput} from 'providers/TestOutput/TestOutput.provider';
import * as S from './RunDetailLayout.styled';
import EventLogPopover from '../EventLogPopover/EventLogPopover';
import RunStatusIcon from '../RunStatusIcon/RunStatusIcon';
import VariableSetSelector from '../VariableSetSelector/VariableSetSelector';

interface IProps {
testId: string;
Expand Down Expand Up @@ -55,6 +56,7 @@ const HeaderRight = ({testId}: IProps) => {
{(isRunStateSucceeded(state) || isRunStateStopped(state)) && (
<RunStatusIcon state={state} requiredGatesResult={requiredGatesResult} />
)}
<VariableSetSelector />
{!isDraftMode && state && isRunStateFinished(state) && (
<Button data-cy="run-test-button" ghost onClick={() => onRun()} type="primary">
Run Test
Expand Down
2 changes: 2 additions & 0 deletions web/src/components/TestHeader/TestHeader.tsx
@@ -1,6 +1,7 @@
import ResourceCardActions from 'components/ResourceCard/ResourceCardActions';
import {useDashboard} from 'providers/Dashboard/Dashboard.provider';
import * as S from './TestHeader.styled';
import VariableSetSelector from '../VariableSetSelector/VariableSetSelector';

interface IProps {
description: string;
Expand All @@ -27,6 +28,7 @@ const TestHeader = ({description, id, shouldEdit, onEdit, onDelete, title, runBu
</div>
</S.Section>
<S.Section>
<VariableSetSelector />
{runButton}
<ResourceCardActions id={id} onDelete={onDelete} onEdit={onEdit} shouldEdit={shouldEdit} />
</S.Section>
Expand Down

0 comments on commit de48920

Please sign in to comment.