Skip to content

Commit

Permalink
Merge pull request #12 from Pearson-Advance/vue/PADV-706
Browse files Browse the repository at this point in the history
PADV-706  Add filters to instructors table
  • Loading branch information
AuraAlba authored Oct 11, 2023
2 parents b9ed373 + 0813967 commit 7ba165f
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 4 deletions.
81 changes: 81 additions & 0 deletions src/features/Instructors/InstructorsFilters/_test_/index.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react';
import { render, fireEvent, act } from '@testing-library/react';
import InstructorsFilters from 'features/Instructors/InstructorsFilters';
import '@testing-library/jest-dom/extend-expect';

describe('InstructorsFilters Component', () => {
test('call service when apply filters', async () => {
const fetchData = jest.fn();
const resetPagination = jest.fn();
const { getByPlaceholderText, getByText } = render(
<InstructorsFilters fetchData={fetchData} resetPagination={resetPagination} />,
);

const button = getByText('Filters');
await act(async () => {
fireEvent.click(button);
});

const nameInput = getByPlaceholderText('Enter Instructor Name');
const emailInput = getByPlaceholderText('Enter Instructor Email');
const classNameInput = getByPlaceholderText('Enter Class Name');
const buttonApplyFilters = getByText('Apply Filters');

expect(nameInput).toBeInTheDocument();
expect(emailInput).toBeInTheDocument();
expect(classNameInput).toBeInTheDocument();

fireEvent.change(nameInput, { target: { value: 'Name' } });
fireEvent.change(emailInput, { target: { value: '[email protected]' } });
fireEvent.change(classNameInput, { target: { value: 'CCX01' } });

expect(nameInput).toHaveValue('Name');
expect(emailInput).toHaveValue('[email protected]');
expect(classNameInput).toHaveValue('CCX01');

await act(async () => {
fireEvent.click(buttonApplyFilters);
});

expect(fetchData).toHaveBeenCalledTimes(1);
});

test('clear filters', async () => {
const fetchData = jest.fn();
const resetPagination = jest.fn();
const { getByPlaceholderText, getByText } = render(
<InstructorsFilters fetchData={fetchData} resetPagination={resetPagination} />,
);

const button = getByText('Filters');
await act(async () => {
fireEvent.click(button);
});

const nameInput = getByPlaceholderText('Enter Instructor Name');
const emailInput = getByPlaceholderText('Enter Instructor Email');
const classNameInput = getByPlaceholderText('Enter Class Name');
const buttonClearFilters = getByText('Clear');

expect(nameInput).toBeInTheDocument();
expect(emailInput).toBeInTheDocument();
expect(classNameInput).toBeInTheDocument();

fireEvent.change(nameInput, { target: { value: 'Name' } });
fireEvent.change(emailInput, { target: { value: '[email protected]' } });
fireEvent.change(classNameInput, { target: { value: 'CCX01' } });

expect(nameInput).toHaveValue('Name');
expect(emailInput).toHaveValue('[email protected]');
expect(classNameInput).toHaveValue('CCX01');

await act(async () => {
fireEvent.click(buttonClearFilters);
});

expect(nameInput).toHaveValue('');
expect(emailInput).toHaveValue('');
expect(classNameInput).toHaveValue('');
expect(resetPagination).toHaveBeenCalledTimes(1);
});
});
79 changes: 79 additions & 0 deletions src/features/Instructors/InstructorsFilters/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useState } from 'react';
import {
DropdownButton, Form, Col, Button,
} from '@edx/paragon';
import PropTypes from 'prop-types';

const initialFilterFormValues = {
instructorName: '',
instructorEmail: '',
ccxId: '',
};

const InstructorsFilters = ({ fetchData, resetPagination }) => {
const [filters, setFilters] = useState(initialFilterFormValues);

const handleInputChange = (e) => {
setFilters({
...filters,
[e.target.name]: e.target.value.trim(),
});
};

const handleApplyFilters = async () => {
fetchData(filters);
};

const handleCleanFilters = () => {
setFilters(initialFilterFormValues);
fetchData();
resetPagination();
};

return (
<DropdownButton title="Filters" variant="outline-primary">
<Form className="row justify-content-center px-3 py-2">
<Form.Group as={Col} className="mb-0">
<Form.Control
type="text"
floatingLabel="Name"
name="instructorName"
placeholder="Enter Instructor Name"
value={filters.instructorName}
onChange={handleInputChange}
className="mb-3 mr-0"
/>
<Form.Control
type="text"
floatingLabel="Email"
name="instructorEmail"
placeholder="Enter Instructor Email"
value={filters.instructorEmail}
onChange={handleInputChange}
className="mb-3 mr-0"
/>
<Form.Control
type="text"
floatingLabel="Class Name"
name="ccxId"
placeholder="Enter Class Name"
value={filters.ccxId}
onChange={handleInputChange}
className="mb-4 mr-0"
/>
<div className="d-flex justify-content-between">
<Button onClick={handleApplyFilters}>Apply Filters</Button>
<Button onClick={handleCleanFilters} variant="outline-primary">Clear</Button>
</div>
</Form.Group>
</Form>
</DropdownButton>
);
};

InstructorsFilters.propTypes = {
fetchData: PropTypes.func.isRequired,
resetPagination: PropTypes.func.isRequired,
};

export default InstructorsFilters;
13 changes: 11 additions & 2 deletions src/features/Instructors/InstructorsPage/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Pagination,
} from '@edx/paragon';
import InstructorsTable from 'features/Instructors/InstructorsTable';
import InstructorsFilters from 'features/Instructors/InstructorsFilters';

import { getInstructorData } from 'features/Instructors/data/api';
import {
Expand All @@ -30,11 +31,11 @@ const InstructorsPage = () => {
const [state, dispatch] = useReducer(reducer, initialState);
const [currentPage, setCurrentPage] = useState(1);

const fetchData = async () => {
const fetchData = async (filters) => {
dispatch({ type: FETCH_INSTRUCTOR_DATA_REQUEST });

try {
const response = camelCaseObject(await getInstructorData(currentPage));
const response = camelCaseObject(await getInstructorData(currentPage, filters));
dispatch({ type: FETCH_INSTRUCTOR_DATA_SUCCESS, payload: response.data });
} catch (error) {
dispatch({ type: FETCH_INSTRUCTOR_DATA_FAILURE, payload: error });
Expand All @@ -52,9 +53,17 @@ const InstructorsPage = () => {
fetchData();
};

const resetPagination = () => {
setCurrentPage(1);
};

return (
<Container size="xl" className="px-3">
<h2>Instructors</h2>
<div className="d-flex justify-content-end">
<InstructorsFilters fetchData={fetchData} resetPagination={resetPagination} />
</div>

<InstructorsTable
data={state.data}
count={state.count}
Expand Down
2 changes: 1 addition & 1 deletion src/features/Instructors/InstructorsTable/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const InstructorsTable = ({

return (
<IntlProvider locale="en">
<Row lassName="justify-content-center my-4 border-gray-300 bg-light-100 my-3">
<Row className="justify-content-center my-4 border-gray-300 bg-light-100 my-3">
<Col xs={11}>
<DataTable
isSortable
Expand Down
3 changes: 2 additions & 1 deletion src/features/Instructors/data/api.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { getConfig } from '@edx/frontend-platform';

function getInstructorData(page) {
function getInstructorData(page, filters) {
const apiV2BaseUrl = getConfig().COURSE_OPERATIONS_API_V2_BASE_URL;
const params = {
page,
...filters,
};

return getAuthenticatedHttpClient().get(
Expand Down

0 comments on commit 7ba165f

Please sign in to comment.