mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-11 21:08:36 +03:00
return hierarchical tags
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user