Skip to content

Commit

Permalink
Add: Add hooks for handling the filter dialog state
Browse files Browse the repository at this point in the history
Using the new hooks allows to rewrite all filter dialogs to function
components more easily.
  • Loading branch information
bjoernricks committed Jun 6, 2024
1 parent 53b033e commit 9cea0cf
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
86 changes: 86 additions & 0 deletions src/web/components/powerfilter/useFilterDialog.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* SPDX-FileCopyrightText: 2024 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {useCallback, useState} from 'react';

import Filter from 'gmp/models/filter';

import {isDefined} from 'gmp/utils/identity';

/**
* React hook for handling filter dialog state
*
* @param {Filter} initialFilter
* @returns Object
*/
const useFilterDialog = initialFilter => {
const [originalFilter] = useState(initialFilter);
const [filter, setFilter] = useState(() =>
isDefined(initialFilter) ? initialFilter.copy() : new Filter(),
);
const [filterDialogState, setFilterDialogState] = useState({});

const [filterString, setFilterString] = useState(() =>
isDefined(initialFilter) ? initialFilter.toFilterCriteriaString() : '',
);

// eslint-disable-next-line no-shadow
const handleFilterChange = useCallback(filter => {
setFilter(filter);
}, []);

const handleFilterValueChange = useCallback((value, name, relation = '=') => {
setFilter(filter => filter.copy().set(name, value, relation)); // eslint-disable-line no-shadow
}, []);

const handleSearchTermChange = useCallback((value, name, relation = '~') => {
setFilter(filter => filter.copy().set(name, `"${value}"`, relation)); // eslint-disable-line no-shadow
}, []);

const handleFilterStringChange = useCallback(value => {
setFilterString(value);
}, []);

const handleSortByChange = useCallback(value => {
setFilter(filter => filter.copy().setSortBy(value)); // eslint-disable-line no-shadow
}, []);

const handleSortOrderChange = useCallback(value => {
setFilter(filter => filter.copy().setSortOrder(value)); // eslint-disable-line no-shadow
}, []);

const handleChange = useCallback((value, name) => {
setFilterDialogState(state => ({...state, [name]: value}));
}, []);

const {filterName, saveNamedFilter, ...other} = filterDialogState;

return {
...other,
filter,
filterString,
filterName,
originalFilter,
saveNamedFilter,
handleFilterChange,
handleFilterValueChange,
handleSearchTermChange,
handleFilterStringChange,
handleSortByChange,
handleSortOrderChange,
handleChange,
// provide old names
filterstring: filterString,
onFilterChange: handleFilterChange,
onFilterValueChange: handleFilterValueChange,
onSearchTermChange: handleSearchTermChange,
onFilterStringChange: handleFilterStringChange,
onSortOrderChange: handleSortOrderChange,
onSortByChange: handleSortByChange,
onValueChange: handleChange,
};
};

export default useFilterDialog;
87 changes: 87 additions & 0 deletions src/web/components/powerfilter/useFilterDialogSave.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/* SPDX-FileCopyrightText: 2024 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {useCallback} from 'react';

import Filter from 'gmp/models/filter';

import {apiType} from 'gmp/utils/entitytype';
import {isDefined} from 'gmp/utils/identity';

import useTranslation from 'web/hooks/useTranslation';
import useGmp from 'web/utils/useGmp';

const useFilterDialogSave = (
createFilterType,
{onClose, onFilterChanged, onFilterCreated},
{filterName, filter, filterString, originalFilter, saveNamedFilter},
) => {
const [_] = useTranslation();
const gmp = useGmp();

const createFilter = useCallback(
newFilter => {
return gmp.filter
.create({
term: newFilter.toFilterString(),
type: apiType(createFilterType),
name: filterName,
})
.then(response => {
const {data} = response;
// load new filter
return gmp.filter.get(data);
})
.then(response => {
const {data: f} = response;

if (isDefined(onFilterCreated)) {
onFilterCreated(f);
}
});
},
[gmp, createFilterType, filterName, onFilterCreated],
);

const handleSave = useCallback(() => {
const newFilter = filter
.copy()
.mergeKeywords(Filter.fromString(filterString));

if (saveNamedFilter) {
if (isDefined(filterName) && filterName.trim().length > 0) {
return createFilter(newFilter).then(onClose);
}
return Promise.reject(
new Error(_('Please insert a name for the new filter')),
);
}

if (isDefined(onFilterChanged) && !newFilter.equals(originalFilter)) {
onFilterChanged(newFilter);
}

if (isDefined(onClose)) {
onClose();
}
return Promise.resolve();
}, [
onClose,
onFilterChanged,
createFilter,
filter,
filterString,
filterName,
originalFilter,
saveNamedFilter,
_,
]);

const ret = [handleSave];
ret.handleSave = handleSave;
return ret;
};

export default useFilterDialogSave;

0 comments on commit 9cea0cf

Please sign in to comment.