Refactored filter list for display; converting filter paths to node, child objects that are toggleable

This commit is contained in:
efarooqui
2020-09-01 09:33:05 -07:00
parent 2aaf7c09ff
commit 6492be18d9
5 changed files with 48 additions and 29 deletions

View File

@@ -3,57 +3,73 @@ import Checkbox from '../presentational/Checkbox'
import copy from '../../common/data/copy.json'
/** recursively get an array of node keys to toggle */
function childrenToToggle (node, activeFilters, parentOn) {
const isOn = activeFilters.includes(node.key)
if (!node.children) {
return [node.key]
function childrenToToggle (filter, activeFilters, parentOn) {
const [key, children] = filter
const isOn = activeFilters.includes(key)
if (children === {}) {
return [key]
}
const childKeys = Object.values(node.children)
.flatMap(n => childrenToToggle(n, activeFilters, isOn))
const childKeys = Object.entries(children)
.flatMap(filter => childrenToToggle(filter, activeFilters, isOn))
// NB: if turning a parent off, don't toggle off children on.
// likewise if turning a parent on, don't toggle on children off
if (!((!parentOn && isOn) || (parentOn && !isOn))) {
childKeys.push(node.key)
childKeys.push(key)
}
return childKeys
}
function aggregatePaths (filters) {
const aggregated = {}
filters.forEach(item => {
let currentDepth = aggregated
item.filter_paths.forEach(path => {
if (!(path in aggregated)) {
currentDepth[path] = {}
}
currentDepth = currentDepth[path]
})
})
return aggregated
}
function FilterListPanel ({
filters,
activeFilters,
onSelectFilter,
language
}) {
function createNodeComponent (node, depth) {
const matchingKeys = childrenToToggle(node, activeFilters, activeFilters.includes(node.key))
const children = Object.values(node.children)
function createNodeComponent (filter, depth) {
const [key, children] = filter
const matchingKeys = childrenToToggle(filter, activeFilters, activeFilters.includes(key))
return (
<li
key={node.key.replace(/ /g, '_')}
key={key.replace(/ /g, '_')}
className={'filter-filter'}
style={{ marginLeft: `${depth * 20}px` }}
>
{/* <svg width='10' height='10'> */}
{/* <g className='filter-inline'> */}
{/* <path d='M0,-7.847549217020565L6.796176979388489,3.9237746085102825L-6.796176979388489,3.9237746085102825Z' transform='rotate(270)' /> */}
{/* </g> */}
{/* </svg> */}
<Checkbox
label={node.key}
isActive={activeFilters.includes(node.key)}
label={key}
isActive={activeFilters.includes(key)}
onClickCheckbox={() => onSelectFilter(matchingKeys)}
/>
{children.length > 0
? children.map(filter => createNodeComponent(filter, depth + 1))
{Object.keys(children).length > 0
? Object.entries(children).map(filter => createNodeComponent(filter, depth + 1))
: null}
</li>
)
}
function renderTree (children) {
function renderTree (filters) {
const aggregatedFilterPaths = aggregatePaths(filters)
console.info(aggregatedFilterPaths)
return (
<div>
{Object.values(children).map(filter => createNodeComponent(filter, 1))}
{Object.entries(aggregatedFilterPaths).map(filter => createNodeComponent(filter, 1))}
</div>
)
}
@@ -62,7 +78,7 @@ function FilterListPanel ({
<div className='react-innertabpanel'>
<h2>{copy[language].toolbar.filters}</h2>
<p>{copy[language].toolbar.explore_by_filter__description}</p>
{renderTree(filters.children)}
{renderTree(filters)}
</div>
)
}

View File

@@ -197,7 +197,7 @@ class Toolbar extends React.Component {
function mapStateToProps (state) {
return {
filters: selectors.getFilterTree(state),
filters: selectors.getFilters(state),
categories: selectors.getCategories(state),
narratives: selectors.selectNarratives(state),
language: state.app.language,