Skip to content

Commit

Permalink
fix: filters params for searching coruses
Browse files Browse the repository at this point in the history
  • Loading branch information
johnvente committed Feb 21, 2024
1 parent de45775 commit d01912a
Show file tree
Hide file tree
Showing 11 changed files with 129 additions and 38 deletions.
15 changes: 4 additions & 11 deletions src/studio-home/data/slice.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ const slice = createSlice({
currentPage: 1,
search: undefined,
order: 'display_name',
archivedOnly: false,
activeOnly: false,
archivedOnly: undefined,
activeOnly: undefined,
isFiltered: false,
cleanFilters: false,
},
},
reducers: {
Expand All @@ -50,15 +51,7 @@ const slice = createSlice({
state.studioHomeData.libraries = libraries;
},
updateStudioHomeCoursesCustomParams: (state, { payload }) => {
const {
currentPage, isFiltered, search, order, archivedOnly, activeOnly,
} = payload;
state.studioHomeCoursesCustomParams.currentPage = currentPage;
state.studioHomeCoursesCustomParams.isFiltered = isFiltered;
state.studioHomeCoursesCustomParams.search = search;
state.studioHomeCoursesCustomParams.order = order;
state.studioHomeCoursesCustomParams.archivedOnly = archivedOnly;
state.studioHomeCoursesCustomParams.activeOnly = activeOnly;
state.studioHomeCoursesCustomParams = { ...payload };
},
},
});
Expand Down
9 changes: 6 additions & 3 deletions src/studio-home/data/slice.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ describe('updateStudioHomeCoursesCustomParams action', () => {
currentPage: 1,
search: undefined,
order: 'display_name',
archivedOnly: false,
activeOnly: false,
archivedOnly: undefined,
activeOnly: undefined,
isFiltered: false,
cleanFilters: false,
},
};

Expand All @@ -40,16 +41,18 @@ describe('updateStudioHomeCoursesCustomParams action', () => {
archivedOnly: true,
activeOnly: true,
isFiltered: true,
cleanFilters: true,
},
};

const payload = {
currentPage: 2,
isFiltered: true,
search: 'test',
order: 'display_name',
archivedOnly: true,
activeOnly: true,
isFiltered: true,
cleanFilters: true,
};

const result = reducer(initialState, updateStudioHomeCoursesCustomParams(payload));
Expand Down
7 changes: 2 additions & 5 deletions src/studio-home/hooks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ const useStudioHome = () => {
setShowNewCourseContainer(false);
}, [location.search]);

useEffect(() => {
const { currentPage, search, order } = studioHomeCoursesParams;
dispatch(fetchStudioHomeData(location.search ?? '', false, { page: currentPage, order, search }));
}, [studioHomeCoursesParams.currentPage, isFiltered]);

useEffect(() => {
const {
currentPage,
Expand All @@ -60,10 +55,12 @@ const useStudioHome = () => {
}));
}
}, [
studioHomeCoursesParams.currentPage,
studioHomeCoursesParams.search,
studioHomeCoursesParams.order,
studioHomeCoursesParams.archivedOnly,
studioHomeCoursesParams.activeOnly,
isFiltered,
]);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useState } from 'react';
import { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { Icon, Dropdown } from '@openedx/paragon';
import { Check } from '@openedx/paragon/icons';
import { getStudioHomeCoursesParams } from '../../../../data/selectors';

const CoursesFilterMenu = ({
id: idProp,
Expand All @@ -10,6 +12,7 @@ const CoursesFilterMenu = ({
defaultItemSelectedText,
}) => {
const [itemMenuSelected, setItemMenuSelected] = useState(defaultItemSelectedText);
const { cleanFilters } = useSelector(getStudioHomeCoursesParams);
const handleCourseTypeSelected = (name, value) => {
setItemMenuSelected(name);
onItemMenuSelected(value);
Expand All @@ -19,6 +22,12 @@ const CoursesFilterMenu = ({
<Icon src={Check} className="ml-2" data-testid="menu-item-icon" />
) : null);

useEffect(() => {
if (cleanFilters) {
setItemMenuSelected(defaultItemSelectedText);

Check warning on line 27 in src/studio-home/tabs-section/courses-tab/courses-filters/courses-filter-menu/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/studio-home/tabs-section/courses-tab/courses-filters/courses-filter-menu/index.jsx#L27

Added line #L27 was not covered by tests
}
}, [cleanFilters]);

return (
<Dropdown id={`dropdown-toggle-${idProp}`}>
<Dropdown.Toggle
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { screen, fireEvent, render } from '@testing-library/react';

import CoursesFilterMenu from '.';

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
}));

describe('CoursesFilterMenu', () => {
const onCourseTypeSelectedMock = jest.fn();

Expand Down Expand Up @@ -35,6 +41,14 @@ describe('CoursesFilterMenu', () => {

beforeEach(() => {
jest.clearAllMocks();
useSelector.mockReturnValue({
currentPage: 1,
order: 'display_name',
search: '',
activeOnly: false,
archivedOnly: false,
cleanFilters: false,
});
});

it('snapshot', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { screen, fireEvent, render } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';

import CoursesOrderFilterMenu from '.';
import message from './messages';

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
}));
describe('CoursesTypesFilterMenu', () => {
// eslint-disable-next-line react/prop-types
const IntlProviderWrapper = ({ children }) => (
Expand All @@ -26,6 +31,14 @@ describe('CoursesTypesFilterMenu', () => {

beforeEach(() => {
jest.clearAllMocks();
useSelector.mockReturnValue({
currentPage: 1,
order: 'display_name',
search: '',
activeOnly: false,
archivedOnly: false,
cleanFilters: false,
});
});

it('snapshot', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { screen, fireEvent, render } from '@testing-library/react';
import { IntlProvider } from '@edx/frontend-platform/i18n';

import CoursesTypesFilterMenu from '.';
import message from './messages';

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useSelector: jest.fn(),
}));

describe('CoursesTypesFilterMenu', () => {
// eslint-disable-next-line react/prop-types
const IntlProviderWrapper = ({ children }) => (
Expand All @@ -26,6 +32,14 @@ describe('CoursesTypesFilterMenu', () => {

beforeEach(() => {
jest.clearAllMocks();
useSelector.mockReturnValue({
currentPage: 1,
order: 'display_name',
search: '',
activeOnly: false,
archivedOnly: false,
cleanFilters: false,
});
});

it('snapshot', () => {
Expand Down
51 changes: 36 additions & 15 deletions src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@ import CoursesOrderFilterMenu from './courses-order-filter-menu';

const CoursesFilters = ({ dispatch }) => {
const {
currentPage,
order,
search,
activeOnly,
archivedOnly,
cleanFilters,
} = useSelector(getStudioHomeCoursesParams);
const [inputSearchValue, setInputSearchValue] = useState('');
const searchValueDebounced = useDebounce(inputSearchValue);

const handleSearchCourses = (value) => setInputSearchValue(value);
const handleSearchCourses = (value) => {
setInputSearchValue(value);
};

const getFilterTypeData = (baseFilters) => ({
archivedCourses: { ...baseFilters, archivedOnly: true },
activeCourses: { ...baseFilters, activeOnly: true },
allCourses: { ...baseFilters },
archivedCourses: { ...baseFilters, archivedOnly: true, activeOnly: undefined },
activeCourses: { ...baseFilters, activeOnly: true, archivedOnly: undefined },
allCourses: { ...baseFilters, archivedOnly: undefined, activeOnly: undefined },
azCourses: { ...baseFilters, order: 'display_name' },
zaCourses: { ...baseFilters, order: '-display_name' },
newestCourses: { ...baseFilters, order: '-created' },
Expand All @@ -33,10 +35,13 @@ const CoursesFilters = ({ dispatch }) => {

const handleMenuFilterItemSelected = (filterType) => {
const baseFilters = {
page: currentPage,
currentPage: 1,
search,
order,
isFiltered: true,
archivedOnly,
activeOnly,
cleanFilters: false,
};

const filterParams = getFilterTypeData(baseFilters);
Expand All @@ -47,28 +52,44 @@ const CoursesFilters = ({ dispatch }) => {
useEffect(() => {
const loadCoursesSearched = () => {
const valueFormatted = searchValueDebounced.trim();
const isSearchEmpty = !valueFormatted.length;

const params = {
page: isSearchEmpty ? 1 : currentPage,
search: isSearchEmpty ? undefined : valueFormatted,
dispatch(updateStudioHomeCoursesCustomParams({

Check warning on line 55 in src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx#L54-L55

Added lines #L54 - L55 were not covered by tests
page: 1,
search: valueFormatted,
activeOnly,
archivedOnly,
order,
isFiltered: true,
};

dispatch(updateStudioHomeCoursesCustomParams(params));
cleanFilters: false,
}));
};

loadCoursesSearched();
const hasSearchValueDebouncedValue = searchValueDebounced.trim().length;

if (hasSearchValueDebouncedValue) {
loadCoursesSearched();

Check warning on line 69 in src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx#L69

Added line #L69 was not covered by tests
}
}, [searchValueDebounced]);

useEffect(() => {
const isInputSearchEmpty = inputSearchValue.trim().length;
if (!isInputSearchEmpty) {
dispatch(updateStudioHomeCoursesCustomParams({
page: 1,
activeOnly,
archivedOnly,
order,
isFiltered: true,
cleanFilters: false,
}));
}
}, [inputSearchValue]);

return (
<div className="d-flex">
<SearchField
onSubmit={() => null}

Check warning on line 90 in src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/studio-home/tabs-section/courses-tab/courses-filters/index.jsx#L90

Added line #L90 was not covered by tests
onChange={handleSearchCourses}
value={cleanFilters ? '' : inputSearchValue}
className="mr-4"
data-testid="input-filter-courses-search"
placeholder="Search"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ describe('CoursesFilters', () => {
search: '',
activeOnly: false,
archivedOnly: false,
cleanFilters: false,
});
});

Expand Down
26 changes: 24 additions & 2 deletions src/studio-home/tabs-section/courses-tab/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Row,
Pagination,
Alert,
Button,
} from '@openedx/paragon';
import { Error, WarningFilled } from '@openedx/paragon/icons';

Expand Down Expand Up @@ -43,6 +44,8 @@ const CoursesTab = ({
search,
order,
isFiltered,
archivedOnly,
activeOnly,
} = useSelector(getStudioHomeCoursesParams);
const hasAbilityToCreateCourse = courseCreatorStatus === COURSE_CREATOR_STATES.granted;
const showCollapsible = [
Expand All @@ -53,9 +56,25 @@ const CoursesTab = ({

const handlePageSelected = (page) => {
dispatch(updateStudioHomeCoursesCustomParams({

Check warning on line 58 in src/studio-home/tabs-section/courses-tab/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/studio-home/tabs-section/courses-tab/index.jsx#L58

Added line #L58 was not covered by tests
currentPage: page, search, order, isFiltered,
currentPage: page,
search,
order,
isFiltered: true,
archivedOnly,
activeOnly,
}));
};

const handleCleanFilters = () => {
dispatch(updateStudioHomeCoursesCustomParams({

Check warning on line 69 in src/studio-home/tabs-section/courses-tab/index.jsx

View check run for this annotation

Codecov / codecov/patch

src/studio-home/tabs-section/courses-tab/index.jsx#L69

Added line #L69 was not covered by tests
currentPage: 1,
search: undefined,
order: 'display_name',
isFiltered: true,
cleanFilters: true,
}));
};

const hasCourses = coursesDataItems?.length;

const isNotFilteringCourses = !isFiltered && !isLoading;
Expand All @@ -69,7 +88,7 @@ const CoursesTab = ({
}

return (
isFailed ? (
isFailed && !isFiltered ? (
<AlertMessage
variant="danger"
description={(
Expand Down Expand Up @@ -155,6 +174,9 @@ const CoursesTab = ({
<p>
{intl.formatMessage(messages.coursesTabCourseNotFoundAlertMessage)}
</p>
<Button variant="primary" onClick={handleCleanFilters}>
{intl.formatMessage(messages.coursesTabCourseNotFoundAlertCleanFiltersButton)}
</Button>
</Alert>
)}
{showCollapsible && (
Expand Down
6 changes: 5 additions & 1 deletion src/studio-home/tabs-section/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ const messages = defineMessages({
},
coursesTabCourseNotFoundAlertMessage: {
id: 'course-authoring.studio-home.courses.tab.course.not.found.alert.message',
defaultMessage: 'Sorry, the course you are trying to search was not found',
defaultMessage: 'Sorry, the course(s) you are trying to search was not found',
},
coursesTabCourseNotFoundAlertCleanFiltersButton: {
id: 'course-authoring.studio-home.courses.tab.course.not.found.alert.clean.filters.button',
defaultMessage: 'Clean filters',
},
});

Expand Down

0 comments on commit d01912a

Please sign in to comment.