Refactor course list and empty state (#308)
Co-authored-by: Maxwell Frank <mfrank@2u.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`CourseList collapsed with multiple courses and pages snapshot 1`] = `
|
||||
<Fragment>
|
||||
<div
|
||||
id="course-list-active-filters-container"
|
||||
>
|
||||
<ActiveCourseFilters />
|
||||
</div>
|
||||
<div
|
||||
className="d-flex flex-column flex-grow-1"
|
||||
>
|
||||
<CourseCard
|
||||
cardId="foo"
|
||||
key="foo"
|
||||
/>
|
||||
<CourseCard
|
||||
cardId="bar"
|
||||
key="bar"
|
||||
/>
|
||||
<CourseCard
|
||||
cardId="baz"
|
||||
key="baz"
|
||||
/>
|
||||
<Pagination
|
||||
className="mx-auto mb-2"
|
||||
pageCount={3}
|
||||
paginationLabel="Course List"
|
||||
variant="reduced"
|
||||
/>
|
||||
</div>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CourseList no courses or filters snapshot 1`] = `
|
||||
<Fragment>
|
||||
<div
|
||||
className="d-flex flex-column flex-grow-1"
|
||||
/>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`CourseList with filters snapshot 1`] = `undefined`;
|
||||
|
||||
exports[`CourseList with multiple courses and pages snapshot 1`] = `
|
||||
<Fragment>
|
||||
<div
|
||||
className="d-flex flex-column flex-grow-1"
|
||||
>
|
||||
<CourseCard
|
||||
cardId="foo"
|
||||
key="foo"
|
||||
/>
|
||||
<CourseCard
|
||||
cardId="bar"
|
||||
key="bar"
|
||||
/>
|
||||
<CourseCard
|
||||
cardId="baz"
|
||||
key="baz"
|
||||
/>
|
||||
<Pagination
|
||||
className="mx-auto mb-2"
|
||||
pageCount={3}
|
||||
paginationLabel="Course List"
|
||||
variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
</Fragment>
|
||||
`;
|
||||
8
src/containers/CoursesPanel/CourseList/hooks.js
Normal file
8
src/containers/CoursesPanel/CourseList/hooks.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { useWindowSize, breakpoints } from '@openedx/paragon';
|
||||
|
||||
export const useIsCollapsed = () => {
|
||||
const { width } = useWindowSize();
|
||||
return width < breakpoints.medium.maxWidth;
|
||||
};
|
||||
|
||||
export default useIsCollapsed;
|
||||
51
src/containers/CoursesPanel/CourseList/index.jsx
Normal file
51
src/containers/CoursesPanel/CourseList/index.jsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { Pagination } from '@openedx/paragon';
|
||||
import {
|
||||
ActiveCourseFilters,
|
||||
} from 'containers/CourseFilterControls';
|
||||
import CourseCard from 'containers/CourseCard';
|
||||
|
||||
import { useIsCollapsed } from './hooks';
|
||||
|
||||
export const CourseList = ({
|
||||
filterOptions, setPageNumber, numPages, showFilters, visibleList,
|
||||
}) => {
|
||||
const isCollapsed = useIsCollapsed();
|
||||
return (
|
||||
<>
|
||||
{showFilters && (
|
||||
<div id="course-list-active-filters-container">
|
||||
<ActiveCourseFilters {...filterOptions} />
|
||||
</div>
|
||||
)}
|
||||
<div className="d-flex flex-column flex-grow-1">
|
||||
{visibleList.map(({ cardId }) => (
|
||||
<CourseCard key={cardId} cardId={cardId} />
|
||||
))}
|
||||
{numPages > 1 && (
|
||||
<Pagination
|
||||
variant={isCollapsed ? 'reduced' : 'secondary'}
|
||||
paginationLabel="Course List"
|
||||
className="mx-auto mb-2"
|
||||
pageCount={numPages}
|
||||
onPageSelect={setPageNumber}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
CourseList.propTypes = {
|
||||
showFilters: PropTypes.bool.isRequired,
|
||||
// eslint-disable-next-line react/forbid-prop-types
|
||||
visibleList: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
// eslint-disable-next-line react/forbid-prop-types
|
||||
filterOptions: PropTypes.object.isRequired,
|
||||
numPages: PropTypes.number.isRequired,
|
||||
setPageNumber: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default CourseList;
|
||||
64
src/containers/CoursesPanel/CourseList/index.test.jsx
Normal file
64
src/containers/CoursesPanel/CourseList/index.test.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { shallow } from '@edx/react-unit-test-utils';
|
||||
|
||||
import { useIsCollapsed } from './hooks';
|
||||
import CourseList from '.';
|
||||
|
||||
jest.mock('./hooks', () => ({
|
||||
useIsCollapsed: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('containers/CourseCard', () => 'CourseCard');
|
||||
jest.mock('containers/CourseFilterControls', () => ({
|
||||
ActiveCourseFilters: 'ActiveCourseFilters',
|
||||
}));
|
||||
|
||||
describe('CourseList', () => {
|
||||
const defaultCourseListData = {
|
||||
filterOptions: {},
|
||||
numPages: 1,
|
||||
setPageNumber: jest.fn().mockName('setPageNumber'),
|
||||
showFilters: false,
|
||||
visibleList: [],
|
||||
};
|
||||
useIsCollapsed.mockReturnValue(false);
|
||||
|
||||
const createWrapper = (courseListData = defaultCourseListData) => (
|
||||
shallow(<CourseList {...courseListData} />)
|
||||
);
|
||||
|
||||
describe('no courses or filters', () => {
|
||||
test('snapshot', () => {
|
||||
const wrapper = createWrapper();
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('with filters', () => {
|
||||
test('snapshot', () => {
|
||||
const wrapper = createWrapper({
|
||||
filterOptions: { abitary: 'filter' },
|
||||
showFilters: true,
|
||||
});
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('with multiple courses and pages', () => {
|
||||
test('snapshot', () => {
|
||||
const wrapper = createWrapper({
|
||||
visibleList: [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }],
|
||||
numPages: 3,
|
||||
});
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('collapsed with multiple courses and pages', () => {
|
||||
test('snapshot', () => {
|
||||
useIsCollapsed.mockReturnValueOnce(true);
|
||||
const wrapper = createWrapper({
|
||||
visibleList: [{ cardId: 'foo' }, { cardId: 'bar' }, { cardId: 'baz' }],
|
||||
numPages: 3,
|
||||
showFilters: true,
|
||||
});
|
||||
expect(wrapper.snapshot).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user