return hierarchical tags

This commit is contained in:
Lachlan Kermode
2020-05-26 17:59:33 +02:00
parent b187daceaa
commit 64087bf1e5
3 changed files with 31 additions and 11 deletions

View File

@@ -2,6 +2,14 @@ import React from 'react'
import Checkbox from '../presentational/Checkbox'
import copy from '../../common/data/copy.json'
/** recursively get an array of node keys */
function allAssociatedKeys (node) {
if (!node.children) return [node.key]
const childKeys = Object.values(node.children).flatMap(n => allAssociatedKeys(n))
childKeys.push(node.key)
return childKeys
}
function TagListPanel ({
tags,
activeTags,
@@ -9,26 +17,31 @@ function TagListPanel ({
language
}) {
function createNodeComponent (node, depth) {
const matchingKeys = allAssociatedKeys(node)
const children = Object.values(node.children)
return (
<li
key={node.key.replace(/ /g, '_')}
className={'tag-filter active'}
className={'tag-filter'}
style={{ marginLeft: `${depth * 20}px` }}
>
<Checkbox
label={node.key}
isActive={activeTags.includes(node.key)}
onClickCheckbox={() => onTagFilter(node.key)}
onClickCheckbox={() => onTagFilter(matchingKeys)}
/>
{children.length > 0
? children.map(tag => createNodeComponent(tag, depth + 1))
: null}
</li>
)
}
function renderTree () {
function renderTree (children) {
/* NOTE: only render first layer of tags */
return (
<div>
{Object.values(tags.children).map(tag => createNodeComponent(tag, 1))}
{Object.values(children).map(tag => createNodeComponent(tag, 1))}
</div>
)
}
@@ -37,7 +50,7 @@ function TagListPanel ({
<div className='react-innertabpanel'>
<h2>{copy[language].toolbar.tags}</h2>
<p>{copy[language].toolbar.explore_by_tag__description}</p>
{renderTree()}
{renderTree(tags.children)}
</div>
)
}

View File

@@ -33,7 +33,7 @@ export default ({
className='event'
x={x}
y={y - sectionHeight + (idx * sectionHeight)}
style={{ ...styleProps, opacity: h ? 0.3 : 0.05 }}
style={{ ...styleProps, opacity: h ? 0.5 : 0.1 }}
width={width}
height={sectionHeight}
/>

View File

@@ -118,12 +118,19 @@ function decrementNarrativeCurrent (appState, action) {
}
function toggleFilter (appState, action) {
let newTags = appState.filters[action.filter].slice(0)
if (newTags.includes(action.value)) {
newTags = newTags.filter(s => s !== action.value)
} else {
newTags.push(action.value)
if (!(action.value instanceof Array)) {
action.value = [action.value]
}
let newTags = appState.filters[action.filter].slice(0)
action.value.forEach(vl => {
if (newTags.includes(vl)) {
newTags = newTags.filter(s => s !== vl)
} else {
newTags.push(vl)
}
})
return {
...appState,
filters: {