mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-08 03:18:36 +03:00
Merge pull request #208 from forensic-architecture/feature/move-copy-for-panels-into-config
Feature/move copy for panels into config
This commit is contained in:
@@ -3,3 +3,11 @@ export const ASSOCIATION_MODES = {
|
||||
NARRATIVE: "NARRATIVE",
|
||||
FILTER: "FILTER",
|
||||
};
|
||||
|
||||
export const TIMELINE_ONLY = "TIMELINE_ONLY";
|
||||
|
||||
export const DEFAULT_TAB_ICONS = {
|
||||
CATEGORY: "widgets",
|
||||
NARRATIVE: "timeline",
|
||||
FILTER: "filter_list",
|
||||
};
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
"panels": {
|
||||
"mentions": {
|
||||
"title": "Mentions",
|
||||
"overview": "Selecting the names of people/organisation will show events in which these have been mentioned in their own testistimony and by others. The number in the parentheses shows how many events contain a mention of a person or organisation, e.g. (34)"
|
||||
"overview": "Selecting the names of people/organisation will show events in which these have been mentioned in their own testimony and by others. The number in the parentheses shows how many events contain a mention of a person or organisation, e.g. (34)"
|
||||
},
|
||||
"categories": {
|
||||
"title": "Testimonies",
|
||||
@@ -134,13 +134,16 @@
|
||||
"placeholder": "Search"
|
||||
}
|
||||
},
|
||||
"narratives": "Narratives",
|
||||
"narratives_label": "Narratives",
|
||||
"narrative_summary": "Follow a path through the data, from one key event to the next.",
|
||||
"categories": "Categories",
|
||||
"explore_by_narrative__title": "Explore events by narrative",
|
||||
"explore_by_narrative__description": "Follow a path through the data, from one key event to the next.",
|
||||
"filters": "Filters",
|
||||
"filters_label": "Filters",
|
||||
"explore_by_filter__title": "Explore by filter",
|
||||
"explore_by_filter__description": "'Filters' refer to the types of incident. Select multiple filters to introduce colour-coding, up to a maximum of four filters.<br><br>If no filters are selected, all datapoints are displayed.",
|
||||
"categories": "Categories",
|
||||
"categories_label": "Categories",
|
||||
"explore_by_category__title": "Explore events by category",
|
||||
"explore_by_category__description": "‘Categories’ refer to the victims of a given incident.<br><br>If no categories are selected, all datapoints are displayed."
|
||||
},
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
addToColoringSet,
|
||||
removeFromColoringSet,
|
||||
} from "../common/utilities.js";
|
||||
import { DEFAULT_TAB_ICONS } from "../common/constants";
|
||||
|
||||
class Toolbar extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -83,10 +84,18 @@ class Toolbar extends React.Component {
|
||||
}
|
||||
|
||||
renderToolbarNarrativePanel() {
|
||||
const { panels } = this.props.toolbarCopy;
|
||||
const panelTitle = panels.narratives.label
|
||||
? panels.narratives.label
|
||||
: copy[this.props.language].toolbar.narratives;
|
||||
const panelDescription = panels.narratives.description
|
||||
? panels.narratives.description
|
||||
: copy[this.props.language].toolbar.explore_by_narrative__description;
|
||||
|
||||
return (
|
||||
<TabPanel>
|
||||
<h2>{copy[this.props.language].toolbar.narrative_panel_title}</h2>
|
||||
<p>{copy[this.props.language].toolbar.narrative_summary}</p>
|
||||
<h2>{panelTitle}</h2>
|
||||
<p>{panelDescription}</p>
|
||||
{this.props.narratives.map((narr) => {
|
||||
return (
|
||||
<div className="panel-action action">
|
||||
@@ -108,7 +117,15 @@ class Toolbar extends React.Component {
|
||||
}
|
||||
|
||||
renderToolbarCategoriesPanel() {
|
||||
if (this.props.features.CATEGORIES_AS_FILTERS) {
|
||||
const { panels } = this.props.toolbarCopy;
|
||||
const panelTitle = panels.categories.label
|
||||
? panels.categories.label
|
||||
: copy[this.props.language].toolbar.categories;
|
||||
const panelDescription = panels.categories.description
|
||||
? panels.categories.description
|
||||
: copy[this.props.language].toolbar.explore_by_category__description;
|
||||
|
||||
if (this.props.features.USE_CATEGORIES) {
|
||||
return (
|
||||
<TabPanel>
|
||||
<CategoriesListPanel
|
||||
@@ -116,6 +133,8 @@ class Toolbar extends React.Component {
|
||||
activeCategories={this.props.activeCategories}
|
||||
onCategoryFilter={this.props.methods.onCategoryFilter}
|
||||
language={this.props.language}
|
||||
title={panelTitle}
|
||||
description={panelDescription}
|
||||
/>
|
||||
</TabPanel>
|
||||
);
|
||||
@@ -123,6 +142,14 @@ class Toolbar extends React.Component {
|
||||
}
|
||||
|
||||
renderToolbarFilterPanel() {
|
||||
const { panels } = this.props.toolbarCopy;
|
||||
const panelTitle = panels.filters.label
|
||||
? panels.filters.label
|
||||
: copy[this.props.language].toolbar.filters;
|
||||
const panelDescription = panels.filters.description
|
||||
? panels.filters.description
|
||||
: copy[this.props.language].toolbar.explore_by_filter__description;
|
||||
|
||||
return (
|
||||
<TabPanel>
|
||||
<FilterListPanel
|
||||
@@ -132,6 +159,8 @@ class Toolbar extends React.Component {
|
||||
language={this.props.language}
|
||||
coloringSet={this.props.coloringSet}
|
||||
filterColors={this.props.filterColors}
|
||||
title={panelTitle}
|
||||
description={panelDescription}
|
||||
/>
|
||||
</TabPanel>
|
||||
);
|
||||
@@ -165,9 +194,7 @@ class Toolbar extends React.Component {
|
||||
{narratives && narratives.length !== 0
|
||||
? this.renderToolbarNarrativePanel()
|
||||
: null}
|
||||
{features.CATEGORIES_AS_FILTERS
|
||||
? this.renderToolbarCategoriesPanel()
|
||||
: null}
|
||||
{features.USE_CATEGORIES ? this.renderToolbarCategoriesPanel() : null}
|
||||
{features.USE_ASSOCIATIONS ? this.renderToolbarFilterPanel() : null}
|
||||
</Tabs>
|
||||
</div>
|
||||
@@ -197,13 +224,26 @@ class Toolbar extends React.Component {
|
||||
}
|
||||
|
||||
renderToolbarTabs() {
|
||||
const { features, narratives } = this.props;
|
||||
const { features, narratives, toolbarCopy } = this.props;
|
||||
const narrativesExist = narratives && narratives.length !== 0;
|
||||
let title = copy[this.props.language].toolbar.title;
|
||||
if (process.env.display_title) title = process.env.display_title;
|
||||
|
||||
const { panels } = toolbarCopy;
|
||||
const narrativesLabel = copy[this.props.language].toolbar.narratives_label;
|
||||
const filtersLabel = copy[this.props.language].toolbar.filters_label;
|
||||
const categoriesLabel = "Categories"; // TODO:
|
||||
const filtersLabel = panels.filters.label
|
||||
? panels.filters.label
|
||||
: copy[this.props.language].toolbar.filters_label;
|
||||
const categoriesLabel = panels.categories.label
|
||||
? panels.categories.label
|
||||
: copy[this.props.language].toolbar.categories_label;
|
||||
|
||||
const filterIcon = panels.filters.icon
|
||||
? panels.filters.icon
|
||||
: DEFAULT_TAB_ICONS.FILTER;
|
||||
const categoriesIcon = panels.categories.icon
|
||||
? panels.categories.icon
|
||||
: DEFAULT_TAB_ICONS.CATEGORY;
|
||||
|
||||
const narrativesIdx = 0;
|
||||
const categoriesIdx = narrativesExist ? 1 : 0;
|
||||
@@ -223,10 +263,14 @@ class Toolbar extends React.Component {
|
||||
? this.renderToolbarTab(narrativesIdx, narrativesLabel, "timeline")
|
||||
: null}
|
||||
{features.CATEGORIES_AS_FILTERS
|
||||
? this.renderToolbarTab(categoriesIdx, categoriesLabel, "widgets")
|
||||
? this.renderToolbarTab(
|
||||
categoriesIdx,
|
||||
categoriesLabel,
|
||||
categoriesIcon
|
||||
)
|
||||
: null}
|
||||
{features.USE_ASSOCIATIONS
|
||||
? this.renderToolbarTab(filtersIdx, filtersLabel, "filter_list")
|
||||
? this.renderToolbarTab(filtersIdx, filtersLabel, filterIcon)
|
||||
: null}
|
||||
</div>
|
||||
<BottomActions
|
||||
@@ -268,6 +312,7 @@ function mapStateToProps(state) {
|
||||
categories: selectors.getCategories(state),
|
||||
narratives: selectors.selectNarratives(state),
|
||||
language: state.app.language,
|
||||
toolbarCopy: state.app.toolbar,
|
||||
activeFilters: selectors.getActiveFilters(state),
|
||||
activeCategories: selectors.getActiveCategories(state),
|
||||
viewFilters: state.app.associations.views,
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React from "react";
|
||||
import marked from "marked";
|
||||
import Checkbox from "../atoms/Checkbox";
|
||||
import copy from "../../common/data/copy.json";
|
||||
|
||||
const CategoriesListPanel = ({
|
||||
categories,
|
||||
activeCategories,
|
||||
onCategoryFilter,
|
||||
language,
|
||||
title,
|
||||
description,
|
||||
}) => {
|
||||
function renderCategoryTree() {
|
||||
return (
|
||||
@@ -33,12 +34,10 @@ const CategoriesListPanel = ({
|
||||
|
||||
return (
|
||||
<div className="react-innertabpanel">
|
||||
<h2>{copy[language].toolbar.categories}</h2>
|
||||
<h2>{title}</h2>
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(
|
||||
copy[language].toolbar.explore_by_category__description
|
||||
),
|
||||
__html: marked(description),
|
||||
}}
|
||||
/>
|
||||
{renderCategoryTree()}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from "react";
|
||||
import Checkbox from "../atoms/Checkbox";
|
||||
import marked from "marked";
|
||||
import copy from "../../common/data/copy.json";
|
||||
import {
|
||||
aggregateFilterPaths,
|
||||
getFilterIdxFromColorSet,
|
||||
@@ -30,6 +29,8 @@ function FilterListPanel({
|
||||
language,
|
||||
coloringSet,
|
||||
filterColors,
|
||||
title,
|
||||
description,
|
||||
}) {
|
||||
function createNodeComponent(filter, depth) {
|
||||
const [key, children] = filter;
|
||||
@@ -81,10 +82,10 @@ function FilterListPanel({
|
||||
|
||||
return (
|
||||
<div className="react-innertabpanel">
|
||||
<h2>{copy[language].toolbar.filters}</h2>
|
||||
<h2>{title}</h2>
|
||||
<p
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: marked(copy[language].toolbar.explore_by_filter__description),
|
||||
__html: marked(description),
|
||||
}}
|
||||
/>
|
||||
{renderTree(filters)}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
createFilterPathString,
|
||||
} from "../common/utilities";
|
||||
import { isTimeRangedIn } from "./helpers";
|
||||
import { ASSOCIATION_MODES } from "../common/constants";
|
||||
import { ASSOCIATION_MODES, TIMELINE_ONLY } from "../common/constants";
|
||||
|
||||
// Input selectors
|
||||
export const getEvents = (state) => state.domain.events;
|
||||
@@ -95,9 +95,10 @@ export const selectEvents = createSelector(
|
||||
isActiveTime = features.GRAPH_NONLOCATED
|
||||
? (!event.latitude && !event.longitude) || isActiveTime
|
||||
: isActiveTime;
|
||||
|
||||
if (isActiveTime && isActiveFilter && isActiveCategory) {
|
||||
acc[event.id] = { ...event };
|
||||
if (isActiveTime && isActiveCategory) {
|
||||
if (event.type === TIMELINE_ONLY || isActiveFilter) {
|
||||
acc[event.id] = { ...event };
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
@@ -3,6 +3,7 @@ import { mergeDeepLeft } from "ramda";
|
||||
import global, { colors } from "../common/global";
|
||||
import copy from "../common/data/copy.json";
|
||||
import { language } from "../common/utilities";
|
||||
import { DEFAULT_TAB_ICONS } from "../common/constants";
|
||||
|
||||
const isSmallLaptop = window.innerHeight < 800;
|
||||
const mapIniital = {
|
||||
@@ -105,6 +106,28 @@ const initial = {
|
||||
"A description of the project goes here.\n\nThis description may contain markdown.\n\n# This is a large title, for example.\n\n## Whereas this is a slightly smaller title.\n\nCheck out docs/custom-covers.md in the [Timemap GitHub repo](https://github.com/forensic-architecture/timemap) for more information around how to specify custom covers.",
|
||||
exploreButton: "EXPLORE",
|
||||
},
|
||||
toolbar: {
|
||||
panels: {
|
||||
categories: {
|
||||
icon: DEFAULT_TAB_ICONS.CATEGORY,
|
||||
label: copy[language].toolbar.categories_label,
|
||||
title: copy[language].toolbar.explore_by_category__title,
|
||||
description: copy[language].toolbar.explore_by_category__description,
|
||||
},
|
||||
filters: {
|
||||
icon: DEFAULT_TAB_ICONS.FILTER,
|
||||
label: copy[language].toolbar.filters_label,
|
||||
title: copy[language].toolbar.explore_by_filter__title,
|
||||
description: copy[language].toolbar.explore_by_filter__description,
|
||||
},
|
||||
narratives: {
|
||||
icon: DEFAULT_TAB_ICONS.NARRATIVE,
|
||||
label: copy[language].toolbar.narratives_label,
|
||||
title: copy[language].toolbar.explore_by_narrative__title,
|
||||
description: copy[language].toolbar.explore_by_narrative__description,
|
||||
},
|
||||
},
|
||||
},
|
||||
loading: false,
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user