-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The hook returns functions the update a filter for getting the next, previous, first and last page for a list of entities.
- Loading branch information
1 parent
3af32a4
commit c2f9047
Showing
2 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* SPDX-FileCopyrightText: 2024 Greenbone AG | ||
* | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
/* eslint-disable react/prop-types */ | ||
|
||
import {describe, test, expect, testing} from '@gsa/testing'; | ||
|
||
import {fireEvent, render, screen} from 'web/utils/testing'; | ||
|
||
import Filter from 'gmp/models/filter'; | ||
|
||
import usePagination from '../usePagination'; | ||
|
||
const TestComponent = ({filter, counts, changeFilter}) => { | ||
const [first, last, next, previous] = usePagination( | ||
filter, | ||
counts, | ||
changeFilter, | ||
); | ||
return ( | ||
<> | ||
<button data-testid="first" onClick={first} /> | ||
<button data-testid="last" onClick={last} /> | ||
<button data-testid="next" onClick={next} /> | ||
<button data-testid="previous" onClick={previous} /> | ||
</> | ||
); | ||
}; | ||
|
||
describe('usePageFilter', () => { | ||
test('should change the filter for the first page', () => { | ||
const filter = Filter.fromString('first=10'); | ||
const counts = {filtered: 100, rows: 10}; | ||
const changeFilter = testing.fn(); | ||
|
||
render( | ||
<TestComponent | ||
filter={filter} | ||
counts={counts} | ||
changeFilter={changeFilter} | ||
/>, | ||
); | ||
|
||
fireEvent.click(screen.getByTestId('first')); | ||
|
||
expect(changeFilter).toHaveBeenCalledWith(Filter.fromString('first=1')); | ||
}); | ||
|
||
test('should change the filter for the last page', () => { | ||
const filter = Filter.fromString('first=10'); | ||
const counts = {filtered: 100, rows: 10}; | ||
const changeFilter = testing.fn(); | ||
|
||
render( | ||
<TestComponent | ||
filter={filter} | ||
counts={counts} | ||
changeFilter={changeFilter} | ||
/>, | ||
); | ||
|
||
fireEvent.click(screen.getByTestId('last')); | ||
|
||
expect(changeFilter).toHaveBeenCalledWith(Filter.fromString('first=91')); | ||
}); | ||
|
||
test('should change the filter for the next page', () => { | ||
const filter = Filter.fromString('first=10'); | ||
const counts = {filtered: 100, rows: 10}; | ||
const changeFilter = testing.fn(); | ||
|
||
render( | ||
<TestComponent | ||
filter={filter} | ||
counts={counts} | ||
changeFilter={changeFilter} | ||
/>, | ||
); | ||
|
||
fireEvent.click(screen.getByTestId('next')); | ||
|
||
expect(changeFilter).toHaveBeenCalledWith( | ||
Filter.fromString('first=20 rows=10'), | ||
); | ||
}); | ||
|
||
test('should change the filter for the previous page', () => { | ||
const filter = Filter.fromString('first=10'); | ||
const counts = {filtered: 100, rows: 10}; | ||
const changeFilter = testing.fn(); | ||
|
||
render( | ||
<TestComponent | ||
filter={filter} | ||
counts={counts} | ||
changeFilter={changeFilter} | ||
/>, | ||
); | ||
|
||
fireEvent.click(screen.getByTestId('previous')); | ||
|
||
expect(changeFilter).toHaveBeenCalledWith( | ||
Filter.fromString('first=1 rows=10'), | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* SPDX-FileCopyrightText: 2024 Greenbone AG | ||
* | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
import {useCallback} from 'react'; | ||
|
||
/** | ||
* Hook to to get the filter for the next, previous, last and first page for a | ||
* list of entities | ||
* | ||
* @example | ||
* | ||
* const gmp = useGmp(); | ||
* const [filter, setFilter] = useState(new Filter()); | ||
* const [entities, setEntities] = useState([]); | ||
* const [counts, setCounts] = useState({}); | ||
* const updateFilter = useCallback(filter => { | ||
* setFilter(filter); | ||
* gmp.tasks.get(filter).then(response => {setEntities(response.data);setCounts(response.meta.counts)}); | ||
* }, [gmp.tasks]); | ||
* const [first, last, next, previous] = usePagination(filter, counts, updateFilter) | ||
* | ||
* @param {Filter} filter Current applied filter | ||
* @param {Object} counts Current entities counts. Required for calculating the | ||
* last page. | ||
* @param {Function} changeFilter Function to call when the new filter is applied | ||
* @returns {Array} Tuple of functions to update the filter for the first, last, | ||
* next and previous page. | ||
*/ | ||
const usePagination = (filter, counts, changeFilter) => { | ||
const getNext = useCallback(() => { | ||
changeFilter(filter.next()); | ||
}, [filter, changeFilter]); | ||
|
||
const getPrevious = useCallback(() => { | ||
changeFilter(filter.previous()); | ||
}, [filter, changeFilter]); | ||
|
||
const getFirst = useCallback(() => { | ||
changeFilter(filter.first()); | ||
}, [filter, changeFilter]); | ||
|
||
const getLast = useCallback(() => { | ||
const last = | ||
Math.floor((counts.filtered - 1) / counts.rows) * counts.rows + 1; | ||
const newFilter = filter.first(last); | ||
changeFilter(newFilter); | ||
}, [filter, counts, changeFilter]); | ||
|
||
return [getFirst, getLast, getNext, getPrevious]; | ||
}; | ||
|
||
export default usePagination; |