feat: override filter status component
fix: review modal test failure chore: update unit test chore: update hook and test chore: add unit test for set all filter chore: update use callback mock
This commit is contained in:
committed by
leangseu-edx
parent
59c57028a0
commit
278ac101a7
65
src/containers/ListView/FilterStatusComponent.jsx
Normal file
65
src/containers/ListView/FilterStatusComponent.jsx
Normal file
@@ -0,0 +1,65 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Button, DataTableContext } from '@edx/paragon';
|
||||
|
||||
import * as module from './FilterStatusComponent';
|
||||
|
||||
export const filterHooks = () => {
|
||||
const { state, setAllFilters, headers } = React.useContext(DataTableContext);
|
||||
if (!setAllFilters || !state.filters) {
|
||||
return {};
|
||||
}
|
||||
const clearFilters = React.useCallback(() => setAllFilters([]), []);
|
||||
const headerMap = headers.reduce(
|
||||
(obj, cur) => ({ ...obj, [cur.id]: cur.Header }),
|
||||
{},
|
||||
);
|
||||
const filterNames = state.filters.map((filter) => headerMap[filter.id]);
|
||||
return { clearFilters, filterNames };
|
||||
};
|
||||
|
||||
export const FilterStatusComponent = ({
|
||||
className,
|
||||
variant,
|
||||
size,
|
||||
clearFiltersText,
|
||||
buttonClassName,
|
||||
showFilteredFields,
|
||||
}) => {
|
||||
const { clearFilters, filterNames } = module.filterHooks();
|
||||
if (!clearFilters) {
|
||||
return null;
|
||||
}
|
||||
const filterTexts = <p>Filtered by {filterNames.join(', ')}</p>;
|
||||
return (
|
||||
<div className={className}>
|
||||
{showFilteredFields && filterTexts}
|
||||
<Button
|
||||
className={buttonClassName}
|
||||
variant={variant}
|
||||
size={size}
|
||||
onClick={clearFilters}
|
||||
>
|
||||
{clearFiltersText}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
FilterStatusComponent.defaultProps = {
|
||||
className: '',
|
||||
buttonClassName: 'pgn__smart-status-button',
|
||||
variant: 'link',
|
||||
size: 'inline',
|
||||
clearFiltersText: 'Clear Filters',
|
||||
showFilteredFields: true,
|
||||
};
|
||||
|
||||
FilterStatusComponent.propTypes = {
|
||||
className: PropTypes.string,
|
||||
buttonClassName: PropTypes.string,
|
||||
variant: PropTypes.string,
|
||||
size: PropTypes.string,
|
||||
clearFiltersText: PropTypes.string,
|
||||
showFilteredFields: PropTypes.bool,
|
||||
};
|
||||
80
src/containers/ListView/FilterStatusComponent.test.jsx
Normal file
80
src/containers/ListView/FilterStatusComponent.test.jsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import * as module from './FilterStatusComponent';
|
||||
|
||||
const mockFilterHooks = {
|
||||
clearFilters: jest.fn().mockName('clearFilters'),
|
||||
filterNames: ['some abitary', 'column'],
|
||||
};
|
||||
|
||||
const mockSetAllFilters = jest.fn().mockName('setAllFilters');
|
||||
|
||||
describe('FilterStatusComponent component', () => {
|
||||
const props = {
|
||||
className: 'css-class-name',
|
||||
variant: 'button-variant',
|
||||
size: 'button-size',
|
||||
clearFiltersText: 'clear-filter-text',
|
||||
buttonClassName: 'css-class-name-for-button',
|
||||
showFilteredFields: true,
|
||||
};
|
||||
|
||||
const contextProps = {
|
||||
state: {
|
||||
filters: [
|
||||
{
|
||||
id: 'filter-column',
|
||||
value: 'abitary',
|
||||
},
|
||||
],
|
||||
},
|
||||
setAllFilters: () => mockSetAllFilters,
|
||||
headers: [
|
||||
{
|
||||
id: 'filter-column',
|
||||
Header: 'Formatted Filter Column',
|
||||
},
|
||||
{
|
||||
id: 'dummy-column',
|
||||
Header: 'Not showing column',
|
||||
},
|
||||
],
|
||||
};
|
||||
const { FilterStatusComponent } = module;
|
||||
describe('snapshot', () => {
|
||||
test('with filter', () => {
|
||||
jest.spyOn(module, 'filterHooks').mockImplementationOnce(() => mockFilterHooks);
|
||||
const el = shallow(<FilterStatusComponent {...props} />);
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('with filter but do not show filterd field', () => {
|
||||
jest.spyOn(module, 'filterHooks').mockImplementationOnce(() => mockFilterHooks);
|
||||
const el = shallow(<FilterStatusComponent {...props} showFilteredFields={false} />);
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('without filter', () => {
|
||||
jest.spyOn(module, 'filterHooks').mockImplementationOnce(() => ({}));
|
||||
const el = shallow(<FilterStatusComponent {...props} />);
|
||||
expect(el).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
describe('component', () => {
|
||||
test('clear filter click', () => {
|
||||
jest.spyOn(module, 'filterHooks').mockImplementationOnce(() => mockFilterHooks);
|
||||
const el = shallow(<FilterStatusComponent {...props} />);
|
||||
el.find('Button').simulate('click');
|
||||
expect(mockFilterHooks.clearFilters).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('on clear filter, set all filter get called with empty array', () => {
|
||||
jest.spyOn(React, 'useContext').mockImplementationOnce(() => ({ ...contextProps }));
|
||||
jest.spyOn(React, 'useCallback').mockImplementationOnce(cb => cb());
|
||||
const el = shallow(<FilterStatusComponent {...props} />);
|
||||
el.find('Button').simulate('click');
|
||||
expect(mockSetAllFilters).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -15,6 +15,7 @@ import lmsMessages from 'data/services/lms/messages';
|
||||
import { selectors, thunkActions } from 'data/redux';
|
||||
|
||||
import StatusBadge from 'components/StatusBadge';
|
||||
import FilterStatusComponent from './FilterStatusComponent';
|
||||
|
||||
import messages from './messages';
|
||||
|
||||
@@ -89,6 +90,7 @@ export class SubmissionsTable extends React.Component {
|
||||
return (
|
||||
<DataTable
|
||||
isFilterable
|
||||
FilterStatusComponent={FilterStatusComponent}
|
||||
numBreakoutFilters={2}
|
||||
defaultColumnValues={{ Filter: TextFilter }}
|
||||
isSelectable
|
||||
|
||||
@@ -19,6 +19,8 @@ import {
|
||||
mapDispatchToProps,
|
||||
} from './SubmissionsTable';
|
||||
|
||||
jest.mock('./FilterStatusComponent', () => jest.fn().mockName('FilterStatusComponent'));
|
||||
|
||||
jest.mock('data/redux', () => ({
|
||||
selectors: {
|
||||
app: {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FilterStatusComponent component snapshot with filter 1`] = `
|
||||
<div
|
||||
className="css-class-name"
|
||||
>
|
||||
<p>
|
||||
Filtered by
|
||||
some abitary, column
|
||||
</p>
|
||||
<Button
|
||||
className="css-class-name-for-button"
|
||||
onClick={[MockFunction clearFilters]}
|
||||
size="button-size"
|
||||
variant="button-variant"
|
||||
>
|
||||
clear-filter-text
|
||||
</Button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FilterStatusComponent component snapshot with filter but do not show filterd field 1`] = `
|
||||
<div
|
||||
className="css-class-name"
|
||||
>
|
||||
<Button
|
||||
className="css-class-name-for-button"
|
||||
onClick={[MockFunction clearFilters]}
|
||||
size="button-size"
|
||||
variant="button-variant"
|
||||
>
|
||||
clear-filter-text
|
||||
</Button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`FilterStatusComponent component snapshot without filter 1`] = `""`;
|
||||
@@ -4,6 +4,7 @@ exports[`SubmissionsTable component component render tests snapshots snapshot: e
|
||||
|
||||
exports[`SubmissionsTable component component render tests snapshots snapshot: happy path 1`] = `
|
||||
<DataTable
|
||||
FilterStatusComponent={[MockFunction FilterStatusComponent]}
|
||||
bulkActions={
|
||||
Array [
|
||||
[MockFunction this.selectedBulkAction],
|
||||
@@ -124,6 +125,7 @@ exports[`SubmissionsTable component component render tests snapshots snapshot: h
|
||||
|
||||
exports[`SubmissionsTable component component render tests snapshots snapshot: team happy path 1`] = `
|
||||
<DataTable
|
||||
FilterStatusComponent={[MockFunction FilterStatusComponent]}
|
||||
bulkActions={
|
||||
Array [
|
||||
[MockFunction this.selectedBulkAction],
|
||||
|
||||
@@ -118,7 +118,7 @@ export const mapStateToProps = (state) => ({
|
||||
export const mapDispatchToProps = {
|
||||
setShowReview: actions.app.setShowReview,
|
||||
stopGrading: thunkActions.grading.cancelGrading,
|
||||
reloadSubmissions: thunkActions.app.reloadSubmissions,
|
||||
reloadSubmissions: thunkActions.app.initialize,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ReviewModal);
|
||||
|
||||
Reference in New Issue
Block a user