diff --git a/docs/configuration.md b/docs/configuration.md index 561f6f0..db6b268 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -18,7 +18,7 @@ The URLs for these endpoints, as well as other configurable settings in your tim | SITES_EXT | Endpoint for sites, concatenated with SERVER_ROOT | String | Yes | | MAP_ANCHOR | Geographic coordinates for original map anchor | Array of numbers | No | | MAPBOX_TOKEN | Access token for Mapbox satellite imagery | String | No | -| features.USE_FILTERS | Enable / Disable filters | boolean | No | +| features.USE_ASSOCIATIONS | Enable / Disable filters | boolean | No | | features.USE_SEARCH | Enable / Disable search | boolean | No | | features.USE_SITES | Enable / Disable sites | boolean | No | diff --git a/src/actions/index.js b/src/actions/index.js index f1541bc..7850dc7 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -60,7 +60,6 @@ export function fetchDomain () { } } - let sourcesPromise = Promise.resolve([]) if (features.USE_SOURCES) { if (!SOURCES_URL) { diff --git a/src/components/Layout.js b/src/components/Layout.js index 2edd211..4e493f3 100644 --- a/src/components/Layout.js +++ b/src/components/Layout.js @@ -4,6 +4,7 @@ import React from 'react' import { bindActionCreators } from 'redux' import { connect } from 'react-redux' import * as actions from '../actions' +import * as selectors from '../selectors' import MediaOverlay from './Overlay/Media' import LoadingOverlay from './Overlay/Loading' @@ -42,9 +43,9 @@ class Dashboard extends React.Component { this.props.actions.fetchDomain() .then(domain => this.props.actions.updateDomain({ - domain, - features: this.props.features - })) + domain, + features: this.props.features + })) } // NOTE: hack to get the timeline to always show. Not entirely sure why // this is necessary. @@ -134,7 +135,7 @@ class Dashboard extends React.Component { setNarrativeFromFilters (withSteps) { const { app, domain } = this.props - let activeFilters = app.filters.filters + let activeFilters = app.associations.filters if (activeFilters.length === 0) { alert('No filters selected, cant narrativise') @@ -182,8 +183,8 @@ class Dashboard extends React.Component { if (typeof idx !== 'number') { let e = idx[0] || idx - if (this.props.app.narrative) { - const { steps } = this.props.app.narrative + if (this.props.app.associations.narrative) { + const { steps } = this.props.app.associations.narrative // choose the first event at a given location const locationEventId = e.id const narrativeIdxObj = steps.find(s => s.id === locationEventId) @@ -213,14 +214,14 @@ class Dashboard extends React.Component { if (narrative === null) { this.handleSelect(events[idx - 1], 0) } else { - this.selectNarrativeStep(this.props.app.narrativeState.current - 1) + this.selectNarrativeStep(this.props.narrativeIdx - 1) } } const next = idx => { if (narrative === null) { this.handleSelect(events[idx + 1], 0) } else { - this.selectNarrativeStep(this.props.app.narrativeState.current + 1) + this.selectNarrativeStep(this.props.narrativeIdx + 1) } } if (selected.length > 0) { @@ -266,7 +267,7 @@ class Dashboard extends React.Component { return (
actions.toggleFilter('filters', filter), @@ -279,13 +280,13 @@ class Dashboard extends React.Component { methods={{ onSelectNarrative: this.setNarrative, getCategoryColor: this.getCategoryColor, - onSelect: app.narrative ? this.selectNarrativeStep : ev => this.handleSelect(ev, 1) + onSelect: app.associations.narrative ? this.selectNarrativeStep : ev => this.handleSelect(ev, 1) }} /> this.handleSelect(ev, 0), + onSelect: app.associations.narrative ? this.selectNarrativeStep : ev => this.handleSelect(ev, 0), onUpdateTimerange: actions.updateTimeRange, getCategoryColor: this.getCategoryColor }} @@ -293,25 +294,25 @@ class Dashboard extends React.Component { actions.updateSelected([])} getNarrativeLinks={event => this.getNarrativeLinks(event)} getCategoryColor={this.getCategoryColor} /> 0} + showing={features.FILTERS_AS_NARRATIVES && !app.associations.narrative && app.associations.filters.length > 0} timelineDims={app.timeline.dimensions} onClickHandler={this.setNarrativeFromFilters} /> this.selectNarrativeStep(this.props.app.narrativeState.current + 1), - onPrev: () => this.selectNarrativeStep(this.props.app.narrativeState.current - 1), + onNext: () => this.selectNarrativeStep(this.props.narrativeIdx + 1), + onPrev: () => this.selectNarrativeStep(this.props.narrativeIdx - 1), onSelectNarrative: this.setNarrative }} /> @@ -360,6 +361,9 @@ function mapDispatchToProps (dispatch) { } export default connect( - state => state, + state => ({ + ...state, + narrativeIdx: selectors.selectNarrativeIdx(state) + }), mapDispatchToProps )(Dashboard) diff --git a/src/components/Map.jsx b/src/components/Map.jsx index b40baa5..4022f88 100644 --- a/src/components/Map.jsx +++ b/src/components/Map.jsx @@ -275,11 +275,11 @@ function mapStateToProps (state) { shapes: selectors.selectShapes(state) }, app: { - views: state.app.filters.views, + views: state.app.associations.views, selected: selectors.selectSelected(state), highlighted: state.app.highlighted, map: state.app.map, - narrative: state.app.narrative, + narrative: state.app.associations.narrative, flags: { isShowingSites: state.app.flags.isShowingSites } diff --git a/src/components/Timeline.jsx b/src/components/Timeline.jsx index bd34538..11b9d87 100644 --- a/src/components/Timeline.jsx +++ b/src/components/Timeline.jsx @@ -398,7 +398,7 @@ class Timeline extends React.Component { function mapStateToProps (state) { return { dimensions: selectors.selectDimensions(state), - isNarrative: !!state.app.narrative, + isNarrative: !!state.app.associations.narrative, domain: { events: selectors.selectStackedEvents(state), projects: selectors.selectProjects(state), @@ -409,7 +409,7 @@ function mapStateToProps (state) { selected: state.app.selected, language: state.app.language, timeline: state.app.timeline, - narrative: state.app.narrative + narrative: state.app.associations.narrative }, ui: { dom: state.ui.dom, diff --git a/src/components/Toolbar/Layout.js b/src/components/Toolbar/Layout.js index feaa8e0..ce551f1 100644 --- a/src/components/Toolbar/Layout.js +++ b/src/components/Toolbar/Layout.js @@ -121,7 +121,7 @@ class Toolbar extends React.Component { {features.USE_NARRATIVES ? this.renderToolbarNarrativePanel() : null} {features.CATEGORIES_AS_FILTERS ? this.renderToolbarCategoriesPanel() : null} - {features.USE_FILTERS ? this.renderToolbarFilterPanel() : null} + {features.USE_ASSOCIATIONS ? this.renderToolbarFilterPanel() : null}
) @@ -163,7 +163,7 @@ class Toolbar extends React.Component {
{features.USE_NARRATIVES ? this.renderToolbarTab(narrativesIdx, narrativesLabel, 'timeline') : null} {features.CATEGORIES_AS_FILTERS ? this.renderToolbarTab(categoriesIdx, categoriesLabel, 'widgets') : null} - {features.USE_FILTERS ? this.renderToolbarTab(filtersIdx, filtersLabel, 'filter_list') : null} + {features.USE_ASSOCIATIONS ? this.renderToolbarTab(filtersIdx, filtersLabel, 'filter_list') : null}
state.domain.events export const getCategories = state => state.domain.categories export const getNarratives = state => state.domain.narratives -export const getActiveNarrative = state => state.app.narrative -export const getActiveStep = state => state.app.narrativeState.current +export const getActiveNarrative = state => state.app.associations.narrative export const getSelected = state => state.app.selected export const getSites = state => state.domain.sites export const getSources = state => state.domain.sources export const getShapes = state => state.domain.shapes export const getNotifications = state => state.domain.notifications export const getFilterTree = state => state.domain.filters -export const getActiveFilters = state => state.app.filters.filters -export const getActiveCategories = state => state.app.filters.categories +export const getActiveFilters = state => state.app.associations.filters +export const getActiveCategories = state => state.app.associations.categories export const getTimeRange = state => state.app.timeline.range export const getTimelineDimensions = state => state.app.timeline.dimensions -export const selectNarrative = state => state.app.narrative +export const selectNarrative = state => state.app.associations.narrative export const getFeatures = state => state.features export const getEventRadius = state => state.ui.eventRadius @@ -113,11 +112,30 @@ export const selectNarratives = createSelector( return narrativesMeta.map(n => narratives[n.id]).filter(d => d) }) +/** We iterate through narrative.steps and check the idx there against the selected array and we return the idx */ +export const selectNarrativeIdx = createSelector( + [getSelected, getActiveNarrative], + (selected, narrative) => { + // Only one event selected in narrative mode + if (narrative === null) return -1 + + const selectedEvent = selected[0] + let selectedIdx + + narrative.steps.forEach((step, idx) => { + if (selectedEvent.id === step.id) { + selectedIdx = idx + } + }) + return selectedIdx + } +) + /** Aggregate information about the narrative and the current step into * a single object. If narrative is null, the whole object is null. */ export const selectActiveNarrative = createSelector( - [getActiveNarrative, getActiveStep], + [getActiveNarrative, selectNarrativeIdx], (narrative, current) => narrative ? { ...narrative, current } : null diff --git a/src/store/initial.js b/src/store/initial.js index 8b6d345..bb130ed 100644 --- a/src/store/initial.js +++ b/src/store/initial.js @@ -34,12 +34,9 @@ const initial = { highlighted: null, selected: [], source: null, - narrative: null, - narrativeState: { - current: null - }, - filters: { + associations: { filters: [], + narrative: null, categories: [], views: { events: true,