Skip to content

Commit

Permalink
John conroy/reset all filters (#3598)
Browse files Browse the repository at this point in the history
* Add reset method to store

* Add reset filters button

* Fix styles

* Dedupe single valued hierarchical parents/children (#3599)

Co-authored-by: John Conroy <john-conroy@users.noreply.github.com>

---------

Co-authored-by: John Conroy <john-conroy@users.noreply.github.com>
  • Loading branch information
john-conroy and john-conroy authored Nov 6, 2024
1 parent 0948358 commit d33b369
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 6 deletions.
37 changes: 32 additions & 5 deletions context/app/static/js/components/search/Facets/FilterChips.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { useCallback } from 'react';
import React, { ReactElement, useCallback } from 'react';
import Box from '@mui/material/Box';
import Chip, { ChipProps } from '@mui/material/Chip';
import Button from '@mui/material/Button';
import Stack from '@mui/material/Stack';

import { trackEvent } from 'js/helpers/trackers';
Expand Down Expand Up @@ -49,16 +51,27 @@ const HierarchichalTermChip = React.memo(function HierarchicalTermChip({
return <FilterChip label={`${getFieldLabel(parentField)}: ${value}`} key={value} onDelete={filter} />;
});

function ResetFiltersButton() {
const resetFilters = useSearchStore((state) => state.resetFilters);
return (
<Box flexShrink={0}>
<Button variant="outlined" onClick={resetFilters}>
Clear Filters
</Button>
</Box>
);
}

function FilterChips() {
const filters = useSearchStore((state) => state.filters);
const facets = useSearchStore((state) => state.facets);
const filterTerm = useSearchStore((state) => state.filterTerm);
const filterRange = useSearchStore((state) => state.filterRange);

return (
<Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap>
const chips: ReactElement<{ children: (ReactElement | null)[] }> = (
<>
{Object.entries(filters).map(([field, v]: [string, RangeValues | HierarchicalTermValues | TermValues]) => {
if (isTermFilter(v)) {
if (isTermFilter(v) && v.values.size) {
return [...v.values].map((val) => (
<FilterChip
label={`${getFieldLabel(field)}: ${getTransformedFieldValue({ field, value: val })}`}
Expand All @@ -84,7 +97,12 @@ function FilterChips() {
}

if (isHierarchicalFilter(v) && isHierarchicalFacet(facetConfig)) {
return Object.entries(v.values).map(([parent, children]) => {
const parentValues = Object.entries(v.values);

if (!parentValues.length) {
return null;
}
return parentValues.map(([parent, children]) => {
return [...children].map((child) => (
<HierarchichalTermChip
key={`${parent}-${child}`}
Expand All @@ -97,6 +115,15 @@ function FilterChips() {
}
return null;
})}
</>
);

return (
<Stack direction="row" spacing={2} justifyContent="space-between" sx={{ width: '100%' }}>
<Stack direction="row" spacing={1} flexWrap="wrap" useFlexGap>
{chips}
</Stack>
{Boolean(chips?.props?.children.filter((c) => c).length) && <ResetFiltersButton />}
</Stack>
);
}
Expand Down
17 changes: 17 additions & 0 deletions context/app/static/js/components/search/Facets/TermFacet.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState, useCallback } from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import IndeterminateCheckBoxOutlinedIcon from '@mui/icons-material/IndeterminateCheckBoxOutlined';
import Accordion from '@mui/material/Accordion';
Expand Down Expand Up @@ -231,6 +232,22 @@ export const HierarchicalTermFacetItem = React.memo(function HierarchicalTermFac
const hasChildBuckets = childBuckets?.length;
const childValues = childBuckets.map((b) => b.key);

if (childValues.length === 1 && childBuckets[0].key === label) {
return (
// 26px is the width of the Accordion's expand icon.
<Box pr="26px">
<HierarchicalFacetParent
childValues={childValues}
label={label}
field={field}
title={title}
{...rest}
indeterminate={childState?.size > 0 && !childValues.every((v) => childState?.has(v))}
/>
</Box>
);
}

return (
<Accordion
sx={{
Expand Down
1 change: 1 addition & 0 deletions context/app/static/js/components/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ function SearchWrapper({ config }: { config: Omit<SearchConfig, 'endpoint' | 'an
const initialState = {
...merge({ search, sortField, filters }, initialUrlState, options),
...rest,
initialFilters: filters,
};

return (
Expand Down
8 changes: 8 additions & 0 deletions context/app/static/js/components/search/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type SourceFields = Record<string, string[]>;

export interface SearchState<V> {
filters: FiltersType<V>;
initialFilters: FiltersType<V>;
facets: FacetsType;
defaultQuery?: esb.Query;
search: string;
Expand Down Expand Up @@ -134,6 +135,7 @@ export type SearchStoreState = SearchState<Set<string>>;
export type SearchURLState = Partial<SearchState<string[]>>;

export interface SearchStoreActions {
resetFilters: () => void;
setSearch: (search: string) => void;
setView: (view: string) => void;
setSortField: (sortField: SortField) => void;
Expand Down Expand Up @@ -237,6 +239,12 @@ function replaceURLSearchParams(state: SearchStoreState) {
export const createStore = ({ initialState }: { initialState: SearchStoreState }) =>
createStoreImmer<SearchStore>((set) => ({
...initialState,
resetFilters: () => {
set((state) => {
state.filters = state.initialFilters;
replaceURLSearchParams(state);
});
},
setSearch: (search) => {
set((state) => {
state.search = search;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function useScrollSearchHits<Doc, Aggs>({
endpoint,
swrConfig,
...rest
}: Omit<SearchStoreState, 'view' | 'type' | 'analyticsCategory'>) {
}: Omit<SearchStoreState, 'view' | 'type' | 'analyticsCategory' | 'initialFilters'>) {
const authHeader = useAuthHeader();

const getKey: SWRInfiniteKeyLoader = useCallback(
Expand Down

0 comments on commit d33b369

Please sign in to comment.