Split variant analysis header component

This commit is contained in:
Koen Vlaswinkel
2022-09-16 12:10:13 +02:00
parent 1b0077a115
commit 3079d7f285
7 changed files with 172 additions and 56 deletions

View File

@@ -60,6 +60,7 @@
"@storybook/testing-library": "^0.0.13",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^14.4.3",
"@types/chai": "^4.1.7",
"@types/chai-as-promised": "~7.1.2",
"@types/child-process-promise": "^2.2.1",
@@ -12106,6 +12107,22 @@
"ts-dedent": "^2.2.0"
}
},
"node_modules/@storybook/testing-library/node_modules/@testing-library/user-event": {
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz",
"integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"engines": {
"node": ">=10",
"npm": ">=6"
},
"peerDependencies": {
"@testing-library/dom": ">=7.21.4"
}
},
"node_modules/@storybook/theming": {
"version": "6.5.10",
"resolved": "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.10.tgz",
@@ -12493,15 +12510,12 @@
}
},
"node_modules/@testing-library/user-event": {
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz",
"integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==",
"version": "14.4.3",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz",
"integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==",
"dev": true,
"dependencies": {
"@babel/runtime": "^7.12.5"
},
"engines": {
"node": ">=10",
"node": ">=12",
"npm": ">=6"
},
"peerDependencies": {
@@ -48560,6 +48574,17 @@
"@testing-library/dom": "^8.3.0",
"@testing-library/user-event": "^13.2.1",
"ts-dedent": "^2.2.0"
},
"dependencies": {
"@testing-library/user-event": {
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz",
"integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==",
"dev": true,
"requires": {
"@babel/runtime": "^7.12.5"
}
}
}
},
"@storybook/theming": {
@@ -48879,13 +48904,10 @@
}
},
"@testing-library/user-event": {
"version": "13.5.0",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz",
"integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==",
"dev": true,
"requires": {
"@babel/runtime": "^7.12.5"
}
"version": "14.4.3",
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.4.3.tgz",
"integrity": "sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==",
"dev": true
},
"@tootallnate/once": {
"version": "1.1.2",

View File

@@ -1252,6 +1252,7 @@
"@storybook/testing-library": "^0.0.13",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.5",
"@testing-library/user-event": "^14.4.3",
"@types/chai": "^4.1.7",
"@types/chai-as-promised": "~7.1.2",
"@types/child-process-promise": "^2.2.1",

View File

@@ -0,0 +1,44 @@
import * as React from 'react';
import styled from 'styled-components';
import ViewTitle from '../remote-queries/ViewTitle';
import { LinkIconButton } from './LinkIconButton';
type Props = {
queryName: string;
queryFileName: string;
onOpenQueryFileClick: () => void;
onViewQueryTextClick: () => void;
};
const Container = styled.div`
max-width: 100%;
`;
const QueryActions = styled.div`
display: flex;
gap: 1em;
`;
export const QueryDetails = ({
queryName,
queryFileName,
onOpenQueryFileClick,
onViewQueryTextClick,
}: Props) => {
return (
<Container>
<ViewTitle>{queryName}</ViewTitle>
<QueryActions>
<LinkIconButton onClick={onOpenQueryFileClick}>
<span slot="start" className="codicon codicon-file-code"></span>
{queryFileName}
</LinkIconButton>
<LinkIconButton onClick={onViewQueryTextClick}>
<span slot="start" className="codicon codicon-code"></span>
View query
</LinkIconButton>
</QueryActions>
</Container>
);
};

View File

@@ -3,7 +3,7 @@ import styled from 'styled-components';
import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
import { VariantAnalysisStatus } from '../../remote-queries/shared/variant-analysis';
export type Props = {
type Props = {
variantAnalysisStatus: VariantAnalysisStatus;
onStopQueryClick: () => void;
@@ -22,7 +22,7 @@ const Button = styled(VSCodeButton)`
white-space: nowrap;
`;
export const VariantAnalysisHeaderActions = ({
export const VariantAnalysisActions = ({
variantAnalysisStatus,
onStopQueryClick,
onCopyRepositoryListClick,
@@ -31,9 +31,9 @@ export const VariantAnalysisHeaderActions = ({
return (
<Container>
{variantAnalysisStatus === VariantAnalysisStatus.InProgress && (
<VSCodeButton appearance="secondary" onClick={onStopQueryClick}>
<Button appearance="secondary" onClick={onStopQueryClick}>
Stop query
</VSCodeButton>
</Button>
)}
{variantAnalysisStatus === VariantAnalysisStatus.Succeeded && (
<>

View File

@@ -1,9 +1,8 @@
import * as React from 'react';
import styled from 'styled-components';
import { VariantAnalysisStatus } from '../../remote-queries/shared/variant-analysis';
import ViewTitle from '../remote-queries/ViewTitle';
import { LinkIconButton } from './LinkIconButton';
import { VariantAnalysisHeaderActions } from './VariantAnalysisHeaderActions';
import { QueryDetails } from './QueryDetails';
import { VariantAnalysisActions } from './VariantAnalysisActions';
export type VariantAnalysisHeaderProps = {
queryName: string;
@@ -24,15 +23,6 @@ const Container = styled.div`
align-items: center;
`;
const QueryDetails = styled.div`
max-width: 100%;
`;
const QueryActions = styled.div`
display: flex;
gap: 1em;
`;
export const VariantAnalysisHeader = ({
queryName,
queryFileName,
@@ -45,20 +35,13 @@ export const VariantAnalysisHeader = ({
}: VariantAnalysisHeaderProps) => {
return (
<Container>
<QueryDetails>
<ViewTitle>{queryName}</ViewTitle>
<QueryActions>
<LinkIconButton onClick={onOpenQueryFileClick}>
<span slot="start" className="codicon codicon-file-code"></span>
{queryFileName}
</LinkIconButton>
<LinkIconButton onClick={onViewQueryTextClick}>
<span slot="start" className="codicon codicon-code"></span>
View query
</LinkIconButton>
</QueryActions>
</QueryDetails>
<VariantAnalysisHeaderActions
<QueryDetails
queryName={queryName}
queryFileName={queryFileName}
onOpenQueryFileClick={onOpenQueryFileClick}
onViewQueryTextClick={onViewQueryTextClick}
/>
<VariantAnalysisActions
variantAnalysisStatus={variantAnalysisStatus}
onStopQueryClick={onStopQueryClick}
onCopyRepositoryListClick={onCopyRepositoryListClick}

View File

@@ -0,0 +1,66 @@
import * as React from 'react';
import { render as reactRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { VariantAnalysisStatus } from '../../../remote-queries/shared/variant-analysis';
import { VariantAnalysisActions } from '../VariantAnalysisActions';
describe(VariantAnalysisActions.name, () => {
const onStopQueryClick = jest.fn();
const onCopyRepositoryListClick = jest.fn();
const onExportResultsClick = jest.fn();
afterEach(() => {
onStopQueryClick.mockReset();
onCopyRepositoryListClick.mockReset();
onExportResultsClick.mockReset();
});
const render = (variantAnalysisStatus: VariantAnalysisStatus) =>
reactRender(
<VariantAnalysisActions
variantAnalysisStatus={variantAnalysisStatus}
onStopQueryClick={onStopQueryClick}
onCopyRepositoryListClick={onCopyRepositoryListClick}
onExportResultsClick={onExportResultsClick}
/>
);
it('renders 1 button when in progress', async () => {
const { container } = render(VariantAnalysisStatus.InProgress);
expect(container.querySelectorAll('vscode-button').length).toEqual(1);
});
it('renders the stop query button when in progress', async () => {
render(VariantAnalysisStatus.InProgress);
await userEvent.click(screen.getByText('Stop query'));
expect(onStopQueryClick).toHaveBeenCalledTimes(1);
});
it('renders 2 buttons when succeeded', async () => {
const { container } = render(VariantAnalysisStatus.Succeeded);
expect(container.querySelectorAll('vscode-button').length).toEqual(2);
});
it('renders the copy repository list button when succeeded', async () => {
render(VariantAnalysisStatus.Succeeded);
await userEvent.click(screen.getByText('Copy repository list'));
expect(onCopyRepositoryListClick).toHaveBeenCalledTimes(1);
});
it('renders the export results button when succeeded', async () => {
render(VariantAnalysisStatus.Succeeded);
await userEvent.click(screen.getByText('Export results'));
expect(onExportResultsClick).toHaveBeenCalledTimes(1);
});
it('does not render any buttons when failed', () => {
const { container } = render(VariantAnalysisStatus.Failed);
expect(container.querySelectorAll('vscode-button').length).toEqual(0);
});
});

View File

@@ -1,8 +1,8 @@
import * as React from 'react';
import { VariantAnalysisHeader, VariantAnalysisHeaderProps } from '../VariantAnalysisHeader';
import { render as reactRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { VariantAnalysisStatus } from '../../../remote-queries/shared/variant-analysis';
import { userEvent } from '@storybook/testing-library';
describe(VariantAnalysisHeader.name, () => {
const onOpenQueryFileClick = jest.fn();
@@ -40,42 +40,42 @@ describe(VariantAnalysisHeader.name, () => {
expect(screen.getByText('Query name')).toBeInTheDocument();
});
it('renders the query file name as a button', () => {
it('renders the query file name as a button', async () => {
render();
userEvent.click(screen.getByText('example.ql'));
await userEvent.click(screen.getByText('example.ql'));
expect(onOpenQueryFileClick).toHaveBeenCalledTimes(1);
});
it('renders a view query button', () => {
it('renders a view query button', async () => {
render();
userEvent.click(screen.getByText('View query'));
await userEvent.click(screen.getByText('View query'));
expect(onViewQueryTextClick).toHaveBeenCalledTimes(1);
});
it('renders the stop query button when in progress', () => {
it('renders the stop query button when in progress', async () => {
render({ variantAnalysisStatus: VariantAnalysisStatus.InProgress });
userEvent.click(screen.getByText('Stop query'));
await userEvent.click(screen.getByText('Stop query'));
expect(onStopQueryClick).toHaveBeenCalledTimes(1);
});
it('renders the copy repository list button when succeeded', () => {
it('renders the copy repository list button when succeeded', async () => {
render({ variantAnalysisStatus: VariantAnalysisStatus.Succeeded });
userEvent.click(screen.getByText('Copy repository list'));
await userEvent.click(screen.getByText('Copy repository list'));
expect(onCopyRepositoryListClick).toHaveBeenCalledTimes(1);
});
it('renders the export results button when succeeded', () => {
it('renders the export results button when succeeded', async () => {
render({ variantAnalysisStatus: VariantAnalysisStatus.Succeeded });
userEvent.click(screen.getByText('Export results'));
await userEvent.click(screen.getByText('Export results'));
expect(onExportResultsClick).toHaveBeenCalledTimes(1);
});
it('does not render any buttons when failed', () => {
it('does not render any buttons when failed', async () => {
const { container } = render({ variantAnalysisStatus: VariantAnalysisStatus.Failed });
expect(container.querySelectorAll('vscode-button').length).toEqual(0);