Skip to content

Commit

Permalink
Add status filter and buttons to pause and export (#134)
Browse files Browse the repository at this point in the history
* add status filter dropdown and action buttons to pause and export

* update test snapshots

* use entry.connection as index
  • Loading branch information
yuyi-sl authored Jul 31, 2024
1 parent d8de327 commit e73668b
Show file tree
Hide file tree
Showing 36 changed files with 2,683 additions and 1,154 deletions.
34 changes: 34 additions & 0 deletions src/Components/Actions/ExportHarButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import FileSaver from 'file-saver';
import PropTypes from 'prop-types';

import Button from '../Common/Button';
import Styles from './IconButton.styles.scss';
import IconDownload from '../../icons/IconDownload';

const ExportHarButton = ({ rawData }) => {
const downloadHar = () => {
const formattedHar = JSON.stringify(rawData, null, 4);

FileSaver.saveAs(new Blob([formattedHar]), 'network.har');
};

return (
<Button
className={Styles['icon-button']}
onClick={downloadHar}
>
<IconDownload className={Styles['action-icon']} />
</Button>
);
};

ExportHarButton.propTypes = {
rawData: PropTypes.string,
};

ExportHarButton.defaultProps = {
rawData: '',
};

export default ExportHarButton;
12 changes: 12 additions & 0 deletions src/Components/Actions/IconButton.styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
@import "./../../styles/variables";

.icon-button {
padding: $size-xs $size-xs-s;
height: $filter-button-height;

.action-icon {
fill: $brand-primary-dark-gray;
height: $size-s;
width: $size-s;
}
}
13 changes: 13 additions & 0 deletions src/Components/Actions/ImportHarButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

import Button from '../Common/Button';
import Styles from './IconButton.styles.scss';
import IconUpload from '../../icons/IconImport';

const ImportHarButton = () => (
<Button className={Styles['icon-button']}>
<IconUpload className={Styles['action-icon']} />
</Button>
);

export default ImportHarButton;
35 changes: 35 additions & 0 deletions src/Components/Actions/PauseResumeButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useState } from 'react';

import Button from '../Common/Button';
import Styles from './IconButton.styles.scss';
import IconPause from '../../icons/IconPause';
import { useNetwork } from '../../state/network/Context';
import IconResume from '../../icons/IconResume';

const PauseResumeButton = () => {
const { callbacks } = useNetwork();
const [isPaused, setIsPaused] = useState(false);

const pause = () => {
setIsPaused(true);
callbacks.onPause();
};

const resume = () => {
setIsPaused(false);
callbacks.onResume();
};

return (
<Button
className={Styles['icon-button']}
onClick={isPaused ? resume : pause}
>
{isPaused ?
<IconResume className={Styles['action-icon']} /> :
<IconPause className={Styles['action-icon']} />}
</Button>
);
};

export default PauseResumeButton;
27 changes: 27 additions & 0 deletions src/Components/Actions/ResetButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

import Button from '../Common/Button';
import IconReset from '../../icons/IconReset';
import Styles from './IconButton.styles.scss';
import { useNetwork } from '../../state/network/Context';

const ResetButton = () => {
const { actions, callbacks } = useNetwork();

const handleReset = () => {
window.history.pushState({}, document.title, '/');
actions.resetState();
callbacks.onReset();
};

return (
<Button
className={Styles['icon-button']}
onClick={handleReset}
>
<IconReset className={Styles['action-icon']} />
</Button>
);
};

export default ResetButton;
27 changes: 0 additions & 27 deletions src/Components/Filters/ErrorFilter.jsx

This file was deleted.

20 changes: 20 additions & 0 deletions src/Components/Filters/StatusFilter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';

import Dropdown from '../Common/Dropdown';
import { useNetwork } from '../../state/network/Context';
import { STATUS_FILTERS } from '../../constants';

const StatusFilter = () => {
const { state, actions } = useNetwork();
const filter = state.get('statusFilter');

return (
<Dropdown
items={STATUS_FILTERS}
onChange={actions.updateStatusFilter}
selected={filter}
/>
);
};

export default StatusFilter;
31 changes: 31 additions & 0 deletions src/Components/Filters/TypeFilter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import classNames from 'classnames/bind';

import { useNetwork } from '../../state/network/Context';
import Button from '../Common/Button';
import { TYPE_FILTERS } from '../../constants';
import Styles from '../../Containers/FilterContainer.styles.scss';

const context = classNames.bind(Styles);

const TypeFilter = () => {
const { state, actions } = useNetwork();
const filter = state.get('typeFilter');

return TYPE_FILTERS.map(({ name, filterBy }) => {
const selectedFilter = filterBy.value === filter.value;

return (
<Button
key={name}
className={context({ active: selectedFilter })}
onClick={() => actions.updateTypeFilter(filterBy)}
variant="text"
>
{name}
</Button>
);
});
};

export default TypeFilter;
12 changes: 5 additions & 7 deletions src/Components/Import/ImportHAR.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useDropzone } from 'react-dropzone';
import { useNetwork } from './../../state/network/Context';
import Styles from './ImportHAR.styles.scss';
import Button from './../Common/Button';
import IconUpload from '../../icons/IconImport';
import ImportHarButton from '../Actions/ImportHarButton';

const DROP_FILE_CONFIG = {
accept: '.har',
Expand Down Expand Up @@ -45,13 +47,9 @@ const ImportHar = ({ showButton, className }) => {
return (
<div {...getRootProps()}>
<input {...getInputProps()} />
{showButton ? (
<Button className={className}>
Import HAR
</Button>
) : (
<p className={Styles['drag-drop']}>Drag and drop HAR file here, or click to select file</p>
)}
{showButton ?
(<ImportHarButton />) :
(<p className={Styles['drag-drop']}>Drag and drop HAR file here, or click to select file</p>)}
</div>
);
};
Expand Down
35 changes: 0 additions & 35 deletions src/Components/Import/Reset.jsx

This file was deleted.

6 changes: 4 additions & 2 deletions src/Components/NetworkTable/NetworkTableFooter.styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
position: absolute;
bottom: 0;
width: 100%;
background: $white-97;
padding: $size-xs * 2;
background: $bg-gray-90;
padding: $size-xs-s $size-s;
display: inline-flex;
vertical-align: middle;

Expand All @@ -16,6 +16,8 @@
display: inline-flex;
align-items: center;
border-right: 1px solid $white-80;
padding: 0 $size-xs;
overflow: hidden;

&:last-child {
border-right: none;
Expand Down
60 changes: 15 additions & 45 deletions src/Containers/FilterContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,35 @@
import React from 'react';
import classNames from 'classnames/bind';

import ImportHar from './../Components/Import/ImportHAR';
import Search from './../Components/Filters/Search';
import { useNetwork } from './../state/network/Context';
import { FILTERS } from './../constants';
import Styles from './FilterContainer.styles.scss';
import Button from './../Components/Common/Button';
import ResetButton from '../Components/Actions/ResetButton';
import StatusFilter from '../Components/Filters/StatusFilter';
import ExportHarButton from '../Components/Actions/ExportHarButton';
import PauseResumeButton from '../Components/Actions/PauseResumeButton';
import TypeFilter from '../Components/Filters/TypeFilter';
import ImportHAR from '../Components/Import/ImportHAR';
import { useTheme } from '../state/theme/Context';
import ErrorFilter from '../Components/Filters/ErrorFilter';
import Reset from '../Components/Import/Reset';

const context = classNames.bind(Styles);
import { useNetwork } from '../state/network/Context';

const FilterContainer = () => {
const { state, actions } = useNetwork();
const { showImportHAR } = useTheme();
const filter = state.get('filter');
const filterByError = state.get('errorFilter');
const { state } = useNetwork();
const { showImportHar, showExportHar, showPauseResume } = useTheme();

return (
<section className={Styles['filters-container']}>
<div className={Styles['filter-row']}>
<StatusFilter />
<Search {...state.get('search')} />
{showPauseResume && <PauseResumeButton {...state.get('rawData')} />}
<ResetButton />
{showExportHar && <ExportHarButton />}
{showImportHar && <ImportHAR />}
</div>

<div className={Styles['type-filter-row']}>
<>
{FILTERS.map(({ name, filterBy }) => {
const selectedFilter = filterBy.value === filter.value;
const buttonStyle = context('filter-button', {
'selected-filter': selectedFilter,
});
return (
<Button
key={name}
className={buttonStyle}
onClick={() => actions.updateFilter(filterBy)}
size="sm"
>
{name}
</Button>
);
})}
<ErrorFilter
isError={filterByError}
onChange={actions.updateErrorFilter}
/>
{showImportHAR && (
<>
<ImportHar className={Styles['addon-action-button']} />
<Reset
className={Styles['addon-action-button']}
onReset={actions.resetState}
/>
</>
)}
</>
<TypeFilter />
</div>
</section>

);
};

Expand Down
6 changes: 3 additions & 3 deletions src/Containers/NetworkTableContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
import NetworkTableHeader from './../Components/NetworkTable/NetworkTableHeader';
import NetworkTableRow from './../Components/NetworkTable/NetworkTableRow';
import { useNetwork } from './../state/network/Context';
import ImportHar from './../Components/Import/ImportHAR';
import ImportHar from '../Components/Import/ImportHAR';
import Styles from './NetworkTableContainer.styles.scss';
import ErrorMessage from './../Components/ErrorMessage';
import { useTheme } from '../state/theme/Context';
Expand All @@ -15,7 +15,7 @@ const context = classNames.bind(Styles);

const NetworkTableContainer = ({ onRequestSelect }) => {
const { state, actions } = useNetwork();
const { showImportHAR } = useTheme();
const { showImportHar } = useTheme();
const actualData = state.get('actualData');
const data = state.get('data');
const totalNetworkTime = state.get('totalNetworkTime');
Expand All @@ -40,7 +40,7 @@ const NetworkTableContainer = ({ onRequestSelect }) => {
if (!actualData.size) {
return (
<section className={Styles['table-container']}>
{showImportHAR && (
{showImportHar && (
<>
<ImportHar showButton={false} />
<InputHAR />
Expand Down
Loading

0 comments on commit e73668b

Please sign in to comment.