mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-11 21:08:36 +03:00
add support for showing filter descriptions in narrativised mode
This commit is contained in:
@@ -198,3 +198,16 @@ export function binarySearch (ar, el, compareFn) {
|
||||
}
|
||||
return -m - 1
|
||||
}
|
||||
|
||||
export const isFilterLeaf = node => (Object.keys(node.children).length === 0)
|
||||
export const isFilterDuplicate = (node, set) => { return (set.has(node.key)) }
|
||||
|
||||
export function findDescriptionInFilterTree (key, node) {
|
||||
if (node.key === key) return node.description
|
||||
if (isFilterLeaf(node)) return false
|
||||
const descs = Object.keys(node.children)
|
||||
.map(c => findDescriptionInFilterTree(key, node.children[c]))
|
||||
.filter(v => !!v)
|
||||
if (descs.length !== 1) return false
|
||||
return descs[0]
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import StaticPage from './StaticPage'
|
||||
import TemplateCover from './TemplateCover'
|
||||
|
||||
import colors from '../common/global'
|
||||
import { binarySearch, insetSourceFrom } from '../common/utilities'
|
||||
import { binarySearch, insetSourceFrom, findDescriptionInFilterTree } from '../common/utilities'
|
||||
import { isMobile } from 'react-device-detect'
|
||||
|
||||
class Dashboard extends React.Component {
|
||||
@@ -133,18 +133,30 @@ class Dashboard extends React.Component {
|
||||
|
||||
setNarrativeFromFilters (withSteps) {
|
||||
const { app, domain } = this.props
|
||||
const activeFilters = app.filters.filters
|
||||
let activeFilters = app.filters.filters
|
||||
|
||||
if (activeFilters.length === 0) {
|
||||
alert('No filters selected, cant narrativise')
|
||||
return
|
||||
}
|
||||
|
||||
if (this.props.features.USE_FILTER_DESCRIPTIONS) {
|
||||
activeFilters = activeFilters.reduce((acc, vl) => {
|
||||
acc.push({
|
||||
name: vl,
|
||||
description: findDescriptionInFilterTree(vl, domain.filters)
|
||||
})
|
||||
return acc
|
||||
}, [])
|
||||
} else {
|
||||
activeFilters = activeFilters.map(f => ({ name: f }))
|
||||
}
|
||||
|
||||
const evs = domain.events.filter(ev => {
|
||||
let hasOne = false
|
||||
// add event if it has at least one matching filter
|
||||
for (let i = 0; i < activeFilters.length; i++) {
|
||||
if (ev.filters.includes(activeFilters[i])) {
|
||||
if (ev.filters.includes(activeFilters[i].name)) {
|
||||
hasOne = true
|
||||
break
|
||||
}
|
||||
@@ -153,11 +165,12 @@ class Dashboard extends React.Component {
|
||||
return false
|
||||
})
|
||||
|
||||
const name = activeFilters.join('-')
|
||||
const name = activeFilters.map(f => f.name).join('-')
|
||||
const desc = activeFilters.map(f => f.description).join('\n\n')
|
||||
this.setNarrative({
|
||||
id: name,
|
||||
label: name,
|
||||
description: '',
|
||||
description: desc,
|
||||
withLines: withSteps,
|
||||
steps: evs.map(insetSourceFrom(domain.sources))
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ import narrativeSchema from './narrativeSchema'
|
||||
import sourceSchema from './sourceSchema'
|
||||
import shapeSchema from './shapeSchema'
|
||||
|
||||
import { calcDatetime, capitalize } from '../../common/utilities'
|
||||
import { calcDatetime, capitalize, isFilterLeaf, isFilterDuplicate } from '../../common/utilities'
|
||||
|
||||
/*
|
||||
* Create an error notification object
|
||||
@@ -25,9 +25,6 @@ function isValidDate (d) {
|
||||
return d instanceof Date && !isNaN(d)
|
||||
}
|
||||
|
||||
const isLeaf = node => (Object.keys(node.children).length === 0)
|
||||
const isDuplicate = (node, set) => { return (set.has(node.key)) }
|
||||
|
||||
/*
|
||||
* Traverse a filter tree and check its duplicates. Also recompose as
|
||||
* description if `features.USE_FILTER_DESCRIPTIONS` is true.
|
||||
@@ -47,7 +44,7 @@ function validateFilterTree (node, parent, set, duplicates, hasFilterDescription
|
||||
parent.children = node.children
|
||||
delete parent.isDescription
|
||||
}
|
||||
if (isLeaf(node)) {
|
||||
if (isFilterLeaf(node)) {
|
||||
delete parent.isDescription
|
||||
}
|
||||
}
|
||||
@@ -56,8 +53,8 @@ function validateFilterTree (node, parent, set, duplicates, hasFilterDescription
|
||||
return
|
||||
}
|
||||
// If it's a leaf, check that it's not duplicate
|
||||
if (isLeaf(node)) {
|
||||
if (isDuplicate(node, set)) {
|
||||
if (isFilterLeaf(node)) {
|
||||
if (isFilterDuplicate(node, set)) {
|
||||
duplicates.push({
|
||||
id: node.key,
|
||||
error: makeError('Filters', node.key, 'filter was found more than once in hierarchy. Ignoring duplicate.')
|
||||
|
||||
@@ -6,7 +6,6 @@ NARRATIVE INFO
|
||||
top: 30px;
|
||||
left: auto;
|
||||
right: $card-right; // looks a bit better due to the 1px border on other elements.
|
||||
height: $narrative-info-height;
|
||||
width: $card-width;
|
||||
box-sizing: border-box;
|
||||
max-height: calc(100% - 250px);
|
||||
@@ -35,13 +34,14 @@ NARRATIVE INFO
|
||||
}
|
||||
|
||||
.narrative-info-desc {
|
||||
height: $narrative-info-desc-height;
|
||||
max-height: $narrative-info-desc-height;
|
||||
overflow-y: auto;
|
||||
white-space: pre-line;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0 15px;
|
||||
padding: 0 15px 15px 15px;
|
||||
}
|
||||
|
||||
h3, h6 {
|
||||
|
||||
Reference in New Issue
Block a user