Merge pull request #170 from forensic-architecture/fix/recursive-corner-case

Fix/recursive corner case
This commit is contained in:
Ebrahem Farooqui
2020-10-27 08:13:29 -07:00
committed by GitHub
4 changed files with 36 additions and 8 deletions

View File

@@ -116,10 +116,30 @@ export function getImmediateFilterParent (associations, filter) {
return parents[parents.length - 1]
}
/**
* Grab a meta filter's siblings, by way of the the `filter_path` hierarcy.
*/
export function getMetaFilterSiblings (allFilters, filterParent, filterKey) {
const idxParent = allFilters.map(f => {
return f.filter_paths.reduceRight((acc, path, idx) => {
if (path === filterParent) return f.filter_paths[idx + 1]
return acc
}, null)
})
.filter(metaFilter => !!metaFilter && metaFilter !== filterKey)
return [ ...(new Set(idxParent)) ]
}
/**
* Grabs a given filter's siblings: the set of associations that share the same immediate filter parent.
*/
export function getFilterSiblings (allFilters, filterParent, filterKey) {
const isMetaFilter = !allFilters.map(filt => filt.id).includes(filterKey)
if (isMetaFilter) {
return getMetaFilterSiblings(allFilters, filterParent, filterKey)
}
return allFilters.reduce((acc, val) => {
const valParent = getImmediateFilterParent(allFilters, val.id)
if (valParent === filterParent && val.id !== filterKey) acc.push(val.id)

View File

@@ -1,9 +1,13 @@
import React from 'react'
import Checkbox from '../presentational/Checkbox'
import copy from '../../common/data/copy.json'
import { getFilterIdxFromColorSet } from '../../common/utilities'
import { getFilterIdxFromColorSet, getFilterParents } from '../../common/utilities'
import { colors } from '../../common/global'
function hasOnParent (filters, activeFilters, filterKey) {
return getFilterParents(filters, filterKey).some(r => activeFilters.indexOf(r) >= 0)
}
/** recursively get an array of node keys to toggle */
function childrenToToggle (filter, activeFilters, parentOn) {
const [key, children] = filter
@@ -12,7 +16,7 @@ function childrenToToggle (filter, activeFilters, parentOn) {
return [key]
}
const childKeys = Object.entries(children)
.flatMap(filter => childrenToToggle(filter, activeFilters, isOn))
.flatMap(filter => childrenToToggle(filter, activeFilters, isOn || parentOn))
// 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))) {
@@ -46,7 +50,9 @@ function FilterListPanel ({
}) {
function createNodeComponent (filter, depth) {
const [key, children] = filter
const matchingKeys = childrenToToggle(filter, activeFilters, activeFilters.includes(key))
const anyParentOn = activeFilters.includes(key) || hasOnParent(filters, activeFilters, key)
const matchingKeys = childrenToToggle(filter, activeFilters, anyParentOn)
const idxFromColorSet = getFilterIdxFromColorSet(key, coloringSet)
const assignedColor = idxFromColorSet !== -1 && activeFilters.includes(key) ? filterColors[idxFromColorSet] : colors.white
@@ -65,7 +71,7 @@ function FilterListPanel ({
<Checkbox
label={key}
isActive={activeFilters.includes(key)}
onClickCheckbox={() => onSelectFilter(key, matchingKeys)}
onClickCheckbox={() => { onSelectFilter(key, matchingKeys) }}
backgroundColor={assignedColor}
/>
{Object.keys(children).length > 0

View File

@@ -9,7 +9,7 @@ import FilterListPanel from './FilterListPanel'
import CategoriesListPanel from './CategoriesListPanel'
import BottomActions from './BottomActions'
import copy from '../../common/data/copy.json'
import { trimAndEllipse, getImmediateFilterParent, getFilterSiblings } from '../../common/utilities.js'
import { trimAndEllipse, getImmediateFilterParent, getFilterSiblings, getFilterParents } from '../../common/utilities.js'
class Toolbar extends React.Component {
constructor (props) {
@@ -59,10 +59,12 @@ class Toolbar extends React.Component {
}
if (siblingsOff && isTurningOff) {
matchingKeys.push(parent)
const grandparentsOn = getFilterParents(filters, key).filter(filt => activeFilters.includes(filt))
matchingKeys = matchingKeys.concat(grandparentsOn)
}
}
}
this.props.methods.onSelectFilter(matchingKeys)
}

View File

@@ -8,8 +8,8 @@ export default ({ label, isActive, onClickCheckbox, backgroundColor }) => {
return (
<div className={(isActive) ? 'item active' : 'item'}>
<span onClick={() => onClickCheckbox()}>{label}</span>
<button onClick={() => onClickCheckbox()}>
<span>{label}</span>
<button onClick={onClickCheckbox}>
<div className='checkbox' style={styles} />
</button>
</div>