Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DCJ-691] Add filter for primary data use #2687

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions src/components/data_search/DatasetFilterList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import ListItemText from '@mui/material/ListItemText';
import Divider from '@mui/material/Divider';
import { Typography } from '@mui/material';
import { Checkbox } from '@mui/material';
import { flatten, uniq, compact, capitalize } from 'lodash';

export const DatasetFilterList = (props) => {
const { datasets, filters, filterHandler, searchRef } = props;
const { datasets, filters, filterHandler, isFiltered, searchRef } = props;

const accessManagementFilters = ['Controlled', 'Open', 'External'];

const isFiltered = (filter) => filters.indexOf(filter) > -1;
const accessManagementFilters = uniq(compact(datasets.map((dataset) => dataset.accessManagement)));
const dataUseFilters = uniq(compact(flatten(datasets.map((dataset) => dataset.dataUse?.primary))).map((dataUse) => dataUse.code));

return (
<Box sx={{ bgcolor: 'background.paper' }}>
Expand All @@ -27,13 +27,35 @@ export const DatasetFilterList = (props) => {
</Typography>
<List sx={{ margin: '-0.5em -0.5em'}}>
{
accessManagementFilters.map((filterName) => {
const filter = filterName.toLowerCase();
accessManagementFilters.map((filter) => {
const filterName = capitalize(filter);
const category = 'accessManagement';
return (
<ListItem disablePadding key={filter}>
<ListItemButton sx={{ padding: '0' }} onClick={(event) => filterHandler(event, datasets, category, filter, searchRef.current.value)}>
<ListItemIcon>
<Checkbox checked={isFiltered(filter, category)} />
</ListItemIcon>
<ListItemText primary={filterName} sx={{ fontFamily: 'Montserrat', transform: 'scale(1.2)' }} />
</ListItemButton>
</ListItem>
);
})
}
</List>
<Typography variant="h6" gutterBottom component="div" sx={{ fontFamily: 'Montserrat', fontWeight: '600' }} marginTop="1em">
Primary Data Use
</Typography>
<List sx={{ margin: '-0.5em -0.5em'}}>
{
dataUseFilters.map((filter) => {
const filterName = filter.toUpperCase();
const category = 'dataUse';
return (
<ListItem disablePadding key={filter}>
<ListItemButton sx={{ padding: '0' }} onClick={(event) => filterHandler(event, datasets, filter, searchRef.current.value)}>
<ListItemButton sx={{ padding: '0' }} onClick={(event) => filterHandler(event, datasets, category, filter, searchRef.current.value)}>
<ListItemIcon>
<Checkbox checked={isFiltered(filter)} />
<Checkbox checked={isFiltered(filter, category)} />
</ListItemIcon>
<ListItemText primary={filterName} sx={{ fontFamily: 'Montserrat', transform: 'scale(1.2)' }} />
</ListItemButton>
Expand Down
37 changes: 26 additions & 11 deletions src/components/data_search/DatasetSearchTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@ const datasetTableHeader = [
'Export to Terra',
];

const defaultFilters = {
accessManagement: [],
dataUse: [],
}

export const DatasetSearchTable = (props) => {
const { datasets, history, icon, title } = props;
const [filters, setFilters] = useState([]);
const [filters, setFilters] = useState(defaultFilters);
const [filtered, setFiltered] = useState([]);
const [tableData, setTableData] = useState({});
const [selected, setSelected] = useState([]);
Expand All @@ -52,7 +57,9 @@ export const DatasetSearchTable = (props) => {
const [showTranslatedDULModal, setShowTranslatedDULModal] = useState(false);
const [dataUse, setDataUse] = useState();
const searchRef = useRef('');
const isFiltered = (filter) => filters.indexOf(filter) > -1;

const isFiltered = (filter, category) => (filters[category]).indexOf(filter) > -1;
const numSelectedFilters = (filters) => Object.values(filters).reduce((sum, array) => sum + array.length, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not super familiar with the lodash reduce function, would you mind explaining what is happening here? Why couldn't we just the length of the array of filters?

Copy link
Contributor Author

@fboulnois fboulnois Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can definitely do something like filters.accessManagement.length + filters.dataUse.length, but this mechanism avoids having to remember to add new filters to this function. reduce is a Javascript built-in, it runs a callback over each element of the array with an accumulator, with 0 (in this case) set as the initial value.

Object.values(filters) transforms { f1: ['a', 'b', 'c'], f2: ['d', 'e', 'f'] } into [ ['a', 'b', 'c'], ['d', 'e', 'f'] ]
then reduce loops over each item in the array (which are subarrays), adds the length of the subarrays to the sum (which starts at zero), and so ultimately returns the total number of selected filters.

Copy link
Contributor Author

@fboulnois fboulnois Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RE: lodash, that was also my understanding, moving specifically away from the fp version of lodash, not the regular version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank for explaining that!


const assembleFullQuery = (searchTerm, filters) => {
const queryChunks = [
Expand Down Expand Up @@ -96,17 +103,25 @@ export const DatasetSearchTable = (props) => {
}

var filterQuery = {};
if (filters.length > 0) {
if (numSelectedFilters(filters) > 0) {
const shouldTerms = [];

filters.forEach(term => {
filters.accessManagement.forEach(term => {
shouldTerms.push({
'term': {
'accessManagement': term
}
});
});

filters.dataUse.forEach(term => {
shouldTerms.push({
'match': {
'dataUse.primary.code': term
}
});
});

if (shouldTerms.length > 0) {
filterQuery = [
{
Expand All @@ -119,7 +134,7 @@ export const DatasetSearchTable = (props) => {
}

// do not add filter subquery if no filters are applied
if (filters.length > 0) {
if (numSelectedFilters(filters) > 0) {
return {
'from': 0,
'size': 10000,
Expand All @@ -143,12 +158,12 @@ export const DatasetSearchTable = (props) => {
}
};

const filterHandler = (event, data, filter, searchTerm) => {
var newFilters = [];
if (!isFiltered(filter) && filter !== '') {
newFilters = filters.concat(filter);
const filterHandler = (event, data, category, filter, searchTerm) => {
var newFilters = defaultFilters;
if (!isFiltered(filter, category) && filter !== '') {
newFilters[category] = filters[category].concat(filter);
} else {
newFilters = filters.filter((f) => f !== filter);
newFilters[category] = filters[category].filter((f) => f !== filter);
}
setFilters(newFilters);

Expand Down Expand Up @@ -419,7 +434,7 @@ export const DatasetSearchTable = (props) => {
</Box>
<Box sx={{display: 'flex', flexDirection: 'row', paddingTop: '2em'}}>
<Box sx={{width: '14%', padding: '0 1em'}}>
<DatasetFilterList datasets={datasets} filters={filters} filterHandler={filterHandler} searchRef={searchRef}/>
<DatasetFilterList datasets={datasets} filters={filters} filterHandler={filterHandler} isFiltered={isFiltered} searchRef={searchRef}/>
</Box>
<Box sx={{width: '85%', padding: '0 1em'}}>
{(() => {
Expand Down
Loading