-
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 determines the sort field and direction of a filter and allows to change both via a returned function. The hook can be used to implement the filter changes when clicking on the different header columns of a entities list.
- Loading branch information
1 parent
2bf49dc
commit 3af32a4
Showing
2 changed files
with
116 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,67 @@ | ||
/* 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 useFilterSortBy from '../useFilterSortBy'; | ||
|
||
const TestComponent = ({filter, changeFilter}) => { | ||
const [sortBy, sortDir, sortChange] = useFilterSortBy(filter, changeFilter); | ||
return ( | ||
<> | ||
<span data-testid="sortBy">{sortBy}</span> | ||
<span data-testid="sortDir">{sortDir}</span> | ||
<button onClick={() => sortChange('field')} data-testid="sortDirChange" /> | ||
<button | ||
onClick={() => sortChange('other-field')} | ||
data-testid="sortFieldChange" | ||
/> | ||
</> | ||
); | ||
}; | ||
|
||
describe('useFilterSortBy', () => { | ||
test('should return the sort by field and direction', () => { | ||
const changeFilter = testing.fn(); | ||
const filter = Filter.fromString('sort=field'); | ||
|
||
render(<TestComponent filter={filter} changeFilter={changeFilter} />); | ||
|
||
expect(screen.getByTestId('sortBy')).toHaveTextContent('field'); | ||
expect(screen.getByTestId('sortDir')).toHaveTextContent('asc'); | ||
}); | ||
|
||
test('should change the sort direction', () => { | ||
const filter = Filter.fromString('sort=field'); | ||
let currentFilter = filter; | ||
const changeFilter = testing.fn().mockImplementation(filter => { | ||
currentFilter = filter; | ||
}); | ||
|
||
const {rerender} = render( | ||
<TestComponent filter={currentFilter} changeFilter={changeFilter} />, | ||
); | ||
|
||
fireEvent.click(screen.getByTestId('sortDirChange')); | ||
|
||
expect(changeFilter).toHaveBeenCalledWith( | ||
Filter.fromString('first=1 sort-reverse=field'), | ||
); | ||
|
||
// the filter is not in the state. so a rerender with the new filter is needed | ||
rerender( | ||
<TestComponent filter={currentFilter} changeFilter={changeFilter} />, | ||
); | ||
|
||
expect(screen.getByTestId('sortBy')).toHaveTextContent('field'); | ||
expect(screen.getByTestId('sortDir')).toHaveTextContent('desc'); | ||
}); | ||
}); |
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,49 @@ | ||
/* SPDX-FileCopyrightText: 2024 Greenbone AG | ||
* | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
import {useCallback} from 'react'; | ||
|
||
import {isDefined} from 'gmp/utils/identity'; | ||
|
||
const ASC = 'asc'; | ||
const DESC = 'desc'; | ||
|
||
/** | ||
* Hook to get the sort by field and direction from a filter | ||
* | ||
* @param {Filter} filter The current filter | ||
* @param {Function} changeFilter Function to call when the filter changes | ||
* @returns Array of the sort by field, sort direction and a function to change the sort by field | ||
*/ | ||
const useFilterSortBy = (filter, changeFilter) => { | ||
const reverseField = isDefined(filter) | ||
? filter.get('sort-reverse') | ||
: undefined; | ||
const reverse = isDefined(reverseField); | ||
const sortBy = | ||
reverse || !isDefined(filter) ? reverseField : filter.get('sort'); | ||
const sortDir = reverse ? DESC : ASC; | ||
|
||
const sortChange = useCallback( | ||
field => { | ||
let sort = 'sort'; | ||
const newFilter = filter.copy().first(); | ||
const sortField = filter.getSortBy(); | ||
|
||
if (sortField && sortField === field) { | ||
sort = filter.getSortOrder() === 'sort' ? 'sort-reverse' : 'sort'; | ||
} | ||
|
||
newFilter.set(sort, field); | ||
|
||
changeFilter(newFilter); | ||
}, | ||
[changeFilter, filter], | ||
); | ||
|
||
return [sortBy, sortDir, sortChange]; | ||
}; | ||
|
||
export default useFilterSortBy; |