From 53deaab164be526ad8f02cc746dcd0cec5edcf9e Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Tue, 4 Dec 2018 13:03:23 +0000 Subject: [PATCH 01/11] rm async query from Dashboard --- src/actions/index.js | 21 +++++++++++++++++++++ src/components/Dashboard.jsx | 19 +------------------ 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 6da357e..7602c49 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -113,6 +113,27 @@ export function fetchEvents (events) { } } +export function fetchSources(event) { + return dispatch => { + console.log('TODO: fetch sources') + // TODO: fetch sources + // Now fetch detail data for each event + // Add transmitter and receiver data for coevents + // this.props.actions.fetchEvents(selected) + // .then((events) => { + // let eventsSelected = events.map(ev => { + // return Object.assign({}, ev, this.getEventById(ev.id)); + // }); + + // eventsSelected = eventsSelected.sort((a, b) => { + // return parser(a.timestamp) - parser(b.timestamp); + // }); + + // this.props.actions.updateSelected(eventsSelected); + // }); + } +} + export const UPDATE_HIGHLIGHTED = 'UPDATE_HIGHLIGHTED' export function updateHighlighted(highlighted) { return { diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index 344cc8e..a663d60 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -52,24 +52,7 @@ class Dashboard extends React.Component { return parser(a.timestamp) - parser(b.timestamp); }); - if (eventsToSelect.every(event => (event))) { - this.props.actions.updateSelected(eventsToSelect); - } - - // Now fetch detail data for each event - // Add transmitter and receiver data for coevents - this.props.actions.fetchEvents(selected) - .then((events) => { - let eventsSelected = events.map(ev => { - return Object.assign({}, ev, this.getEventById(ev.id)); - }); - - eventsSelected = eventsSelected.sort((a, b) => { - return parser(a.timestamp) - parser(b.timestamp); - }); - - this.props.actions.updateSelected(eventsSelected); - }); + this.props.actions.updateSelected(eventsToSelect) } else { this.props.actions.updateSelected([]); } From 577ae7421fd6f7e2ad83a55b2be14262892c987d Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Tue, 4 Dec 2018 16:35:42 +0000 Subject: [PATCH 02/11] zoomed to 3yrs by default --- src/components/Dashboard.jsx | 2 +- src/store/initial.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index a663d60..721aa73 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -96,7 +96,7 @@ class Dashboard extends React.Component { render() { return (
- Date: Tue, 4 Dec 2018 16:48:17 +0000 Subject: [PATCH 03/11] add toggleFetchingSources --- src/actions/index.js | 145 ++++++++++++++++++++--------------- src/components/Dashboard.jsx | 4 +- 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 7602c49..fe63e0b 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -97,25 +97,41 @@ export function updateDomain(domain) { } } -export function fetchEvents (events) { - return dispatch => { - dispatch(toggleFetchingEvents()) - const urls = events.map(eventUrlMap) - return Promise.all( - urls.map(url => fetch(url) - .then(response => response.json()) - ) - ) - .then(json => { - dispatch(toggleFetchingEvents()) - return json - }) - } -} +// export function fetchEvents (events) { +// return dispatch => { +// dispatch(toggleFetchingEvents()) +// const urls = events.map(eventUrlMap) +// return Promise.all( +// urls.map(url => fetch(url) +// .then(response => response.json()) +// ) +// ) +// .then(json => { +// dispatch(toggleFetchingEvents()) +// return json +// }) +// } +// } -export function fetchSources(event) { +export function fetchSelected(selected) { + if (!selected || !selected.length || selected.length === 0) { + console.log('hitting base') + return updateSelected([]) + } return dispatch => { - console.log('TODO: fetch sources') + dispatch(updateSelected(selected)) + dispatch(toggleFetchingSources()) + + // const urls = events.map(eventUrlMap) + // return Promise.all( + // urls.map(url => fetch(url) + // .then(response => response.json()) + // ) + // ) + // .then(json => { + // dispatch(toggleFetchingEvents()) + // return json + // }) // TODO: fetch sources // Now fetch detail data for each event // Add transmitter and receiver data for coevents @@ -136,92 +152,99 @@ export function fetchSources(event) { export const UPDATE_HIGHLIGHTED = 'UPDATE_HIGHLIGHTED' export function updateHighlighted(highlighted) { - return { - type: UPDATE_HIGHLIGHTED, - highlighted: highlighted - } + return { + type: UPDATE_HIGHLIGHTED, + highlighted: highlighted + } } export const UPDATE_SELECTED = 'UPDATE_SELECTED' export function updateSelected(selected) { - return { - type: UPDATE_SELECTED, - selected: selected - } + return { + type: UPDATE_SELECTED, + selected: selected + } } export const UPDATE_DISTRICT = 'UPDATE_DISTRICT' export function updateDistrict(district) { - return { - type: UPDATE_DISTRICT, - district - } + return { + type: UPDATE_DISTRICT, + district + } } export const UPDATE_TAGFILTERS = 'UPDATE_TIMEFILTERS' export function updateTagFilters(tag) { - return { - type: UPDATE_TAGFILTERS, - tag - } + return { + type: UPDATE_TAGFILTERS, + tag + } } export const UPDATE_TIMERANGE = 'UPDATE_TIMERANGE'; export function updateTimeRange(timerange) { - return { - type: UPDATE_TIMERANGE, - timerange - }; + return { + type: UPDATE_TIMERANGE, + timerange + } } export const RESET_ALLFILTERS = 'RESET_ALLFILTERS' export function resetAllFilters() { - return { - type: RESET_ALLFILTERS - } + return { + type: RESET_ALLFILTERS + } } // UI export const TOGGLE_FETCHING_DOMAIN = 'TOGGLE_FETCHING_DOMAIN' export function toggleFetchingDomain() { - return { - type: TOGGLE_FETCHING_DOMAIN - } + return { + type: TOGGLE_FETCHING_DOMAIN + } } -export const TOGGLE_FETCHING_EVENTS = 'TOGGLE_FETCHING_EVENTS' -export function toggleFetchingEvents() { - return { - type: TOGGLE_FETCHING_EVENTS - } +export const TOGGLE_FETCHING_SOURCES = 'TOGGLE_FETCHING_SOURCES' +export function toggleFetchingSources() { + return { + type: TOGGLE_FETCHING_SOURCES + } } +// export const TOGGLE_FETCHING_EVENTS = 'TOGGLE_FETCHING_EVENTS' +// export function toggleFetchingEvents() { +// return { +// type: TOGGLE_FETCHING_EVENTS +// } +// } + export const TOGGLE_LANGUAGE = 'TOGGLE_LANGUAGE'; export function toggleLanguage(language) { - return { - type: TOGGLE_LANGUAGE, - language, - } + return { + type: TOGGLE_LANGUAGE, + language, + } } export const CLOSE_TOOLBAR = 'CLOSE_TOOLBAR'; export function closeToolbar() { - return { - type: CLOSE_TOOLBAR - } + return { + type: CLOSE_TOOLBAR + } } export const TOGGLE_INFOPOPUP = 'TOGGLE_INFOPOPUP'; export function toggleInfoPopup() { - return { - type: TOGGLE_INFOPOPUP - } + return { + type: TOGGLE_INFOPOPUP + } } export const TOGGLE_NOTIFICATIONS = 'TOGGLE_NOTIFICATIONS' export function toggleNotifications() { - return { - type: TOGGLE_NOTIFICATIONS - } + return { + type: TOGGLE_NOTIFICATIONS + } } diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index 721aa73..ea3c331 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -52,9 +52,7 @@ class Dashboard extends React.Component { return parser(a.timestamp) - parser(b.timestamp); }); - this.props.actions.updateSelected(eventsToSelect) - } else { - this.props.actions.updateSelected([]); + this.props.actions.fetchSelected(eventsToSelect) } } From 1c700876fa9d03916982b38fa485c540f9e20df8 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Tue, 4 Dec 2018 16:52:07 +0000 Subject: [PATCH 04/11] change nomenclature: isFetchingEvents -> isFetchingSources --- src/components/CardStack.jsx | 2 +- src/components/Dashboard.jsx | 6 ++---- src/reducers/ui.js | 10 +++++----- src/store/initial.js | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/components/CardStack.jsx b/src/components/CardStack.jsx index 8408f54..b9e3697 100644 --- a/src/components/CardStack.jsx +++ b/src/components/CardStack.jsx @@ -99,7 +99,7 @@ function mapStateToProps(state) { language: state.app.language, tools: state.ui.tools, isCardstack: state.ui.flags.isCardstack, - isLoading: state.ui.flags.isFetchingEvents + isLoading: state.ui.flags.isFetchingSources } } diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index ea3c331..a0ebc67 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -46,11 +46,9 @@ class Dashboard extends React.Component { handleSelect(selected) { if (selected) { let eventsToSelect = selected.map(event => this.getEventById(event.id)); - const parser = this.props.ui.tools.parser; + const p = this.props.ui.tools.parser; - eventsToSelect = eventsToSelect.sort((a, b) => { - return parser(a.timestamp) - parser(b.timestamp); - }); + eventsToSelect = eventsToSelect.sort((a, b) => p(a.timestamp) - p(b.timestamp)) this.props.actions.fetchSelected(eventsToSelect) } diff --git a/src/reducers/ui.js b/src/reducers/ui.js index 8ead656..162102f 100644 --- a/src/reducers/ui.js +++ b/src/reducers/ui.js @@ -2,7 +2,7 @@ import initial from '../store/initial.js'; import { TOGGLE_FETCHING_DOMAIN, - TOGGLE_FETCHING_EVENTS, + TOGGLE_FETCHING_SOURCES, TOGGLE_VIEW, TOGGLE_TIMELINE, TOGGLE_INFOPOPUP, @@ -17,10 +17,10 @@ function toggleFetchingDomain(uiState, action) { }); } -function toggleFetchingEvents(uiState, action) { +function toggleFetchingSources(uiState, action) { return Object.assign({}, uiState, { flags: Object.assign({}, uiState.flags, { - isFetchingEvents: !uiState.flags.isFetchingEvents + isFetchingSources: !uiState.flags.isFetchingSources }) }); } @@ -45,8 +45,8 @@ function ui(uiState = initial.ui, action) { switch (action.type) { case TOGGLE_FETCHING_DOMAIN: return toggleFetchingDomain(uiState, action); - case TOGGLE_FETCHING_EVENTS: - return toggleFetchingEvents(uiState, action); + case TOGGLE_FETCHING_SOURCES: + return toggleFetchingSources(uiState, action); case TOGGLE_INFOPOPUP: return toggleInfoPopup(uiState, action); case TOGGLE_NOTIFICATIONS: diff --git a/src/store/initial.js b/src/store/initial.js index 509df37..5a3c03d 100644 --- a/src/store/initial.js +++ b/src/store/initial.js @@ -139,7 +139,7 @@ const initial = { }, flags: { isFetchingDomain: false, - isFetchingEvents: false, + isFetchingSources: false, isCardstack: true, isInfopopup: false, From d80e39c6988c378ab0ed9b2d705af575dc4da799 Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Tue, 4 Dec 2018 17:06:15 +0000 Subject: [PATCH 05/11] rm loading icon from CardStack --- src/components/CardStack.jsx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/components/CardStack.jsx b/src/components/CardStack.jsx index b9e3697..8c5071e 100644 --- a/src/components/CardStack.jsx +++ b/src/components/CardStack.jsx @@ -22,7 +22,7 @@ class CardStack extends React.Component { event={event} language={this.props.language} tools={this.props.tools} - isLoading={this.props.isLoading} + // isLoading={this.props.isLoading} getNarrativeLinks={this.props.getNarrativeLinks} getCategoryGroup={this.props.getCategoryGroup} getCategoryColor={this.props.getCategoryColor} @@ -58,11 +58,8 @@ class CardStack extends React.Component { >

- {(this.props.isLoading) - ? copy[this.props.language].loading - : `${this.props.selected.length} ${header_lang}`} + {`${this.props.selected.length} ${header_lang}`}

- {(this.props.isLoading) ? '' : this.renderLocation()}
) } @@ -71,10 +68,7 @@ class CardStack extends React.Component { return (
    - {(this.props.isLoading) - ? - : this.renderCards() - } + {this.renderCards()}
); @@ -99,7 +93,7 @@ function mapStateToProps(state) { language: state.app.language, tools: state.ui.tools, isCardstack: state.ui.flags.isCardstack, - isLoading: state.ui.flags.isFetchingSources + isFetchingSources: state.ui.flags.isFetchingSources } } From be4eca83521bbbae7e02d59f1edb081cef0a018b Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Tue, 4 Dec 2018 18:01:32 +0000 Subject: [PATCH 06/11] refmt source URL and reducers to use ES6 spread syntax --- example.config.js | 4 ++-- src/actions/index.js | 41 +++++++++++++++++++++++++++++------------ src/reducers/ui.js | 40 ++++++++++++++++++++++++---------------- src/store/initial.js | 6 +++--- 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/example.config.js b/example.config.js index 92de30c..222355e 100644 --- a/example.config.js +++ b/example.config.js @@ -3,8 +3,8 @@ module.exports = { SERVER_ROOT: 'http://localhost:4040', EVENT_EXT: '/api/example/export_events/rows', CATEGORY_EXT: '/api/example/export_categories/rows', - EVENT_DESC_ROOT: '/api/example/export_events/ids', - TAG_TREE_EXT: '/api/example/export_tags/tree', + SOURCES_EXT: '/api/example/export_events/ids', + TAGS_EXT: '/api/example/export_tags/tree', SITES_EXT: '/api/example/export_sites/rows', MAP_ANCHOR: [31.356397, 34.784818], INCOMING_DATETIME_FORMAT: '%m/%d/%YT%H:%M', diff --git a/src/actions/index.js b/src/actions/index.js index fe63e0b..865612e 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,8 +1,18 @@ +// TODO: move to util lib +function urlFromEnv(ext) { + if (process.env[ext]) { + return `${process.env.SERVER_ROOT}${process.env[ext]}` + } else { + return null + } +} + // TODO: relegate these URLs entirely to environment variables -const EVENT_DATA_URL = `${process.env.SERVER_ROOT}${process.env.EVENT_EXT}` -const CATEGORY_URL = `${process.env.SERVER_ROOT}${process.env.CATEGORY_EXT}` -const TAG_TREE_URL = `${process.env.SERVER_ROOT}${process.env.TAG_TREE_EXT}` -const SITES_URL = `${process.env.SERVER_ROOT}${process.env.SITES_EXT}` +const EVENT_DATA_URL = urlFromEnv('EVENT_EXT') +const CATEGORY_URL = urlFromEnv('CATEGORY_EXT') +const TAG_URL = urlFromEnv('TAGS_EXT') +const SOURCES_URL = urlFromEnv('SOURCES_EXT') +const SITES_URL = urlFromEnv('SITES_EXT') const eventUrlMap = (event) => `${process.env.SERVER_ROOT}${process.env.EVENT_DESC_ROOT}/${(event.id) ? event.id : event}` /* @@ -120,7 +130,11 @@ export function fetchSelected(selected) { } return dispatch => { dispatch(updateSelected(selected)) - dispatch(toggleFetchingSources()) + if (!SOURCES_URL) { + dispatch(fetchSourceError('No source extension specified.')) + } else { + dispatch(toggleFetchingSources()) + } // const urls = events.map(eventUrlMap) // return Promise.all( @@ -213,13 +227,6 @@ export function toggleFetchingSources() { } } -// export const TOGGLE_FETCHING_EVENTS = 'TOGGLE_FETCHING_EVENTS' -// export function toggleFetchingEvents() { -// return { -// type: TOGGLE_FETCHING_EVENTS -// } -// } - export const TOGGLE_LANGUAGE = 'TOGGLE_LANGUAGE'; export function toggleLanguage(language) { return { @@ -248,3 +255,13 @@ export function toggleNotifications() { type: TOGGLE_NOTIFICATIONS } } + +// ERRORS + +export const FETCH_SOURCE_ERROR = 'FETCH_SOURCE_ERROR' +export function fetchSourceError(msg) { + return { + type: FETCH_SOURCE_ERROR, + msg + } +} diff --git a/src/reducers/ui.js b/src/reducers/ui.js index 162102f..0a643c3 100644 --- a/src/reducers/ui.js +++ b/src/reducers/ui.js @@ -10,35 +10,43 @@ import { } from '../actions' function toggleFetchingDomain(uiState, action) { - return Object.assign({}, uiState, { - flags: Object.assign({}, uiState.flags, { + return { + ...uiState, + flags: { + ...uiState.flags, isFetchingDomain: !uiState.flags.isFetchingDomain - }) - }); + } + } } function toggleFetchingSources(uiState, action) { - return Object.assign({}, uiState, { - flags: Object.assign({}, uiState.flags, { + return { + ...uiState, + flags: { + ...uiState.flags, isFetchingSources: !uiState.flags.isFetchingSources - }) - }); + } + } } function toggleInfoPopup(uiState, action) { - return Object.assign({}, uiState, { - flags: Object.assign({}, uiState.flags, { + return { + ...uiState, + flags: { + ...uiState.flags, isInfopopup: !uiState.flags.isInfopopup - }) - }); + } + } } function toggleNotifications(uiState, action) { - return Object.assign({}, uiState, { - flags: Object.assign({}, uiState.flags, { + return { + ...uiState, + flags: { + ...uiState.flags, isNotification: !uiState.flags.isNotification - }) - }); + } + } } function ui(uiState = initial.ui, action) { diff --git a/src/store/initial.js b/src/store/initial.js index 5a3c03d..4d1912a 100644 --- a/src/store/initial.js +++ b/src/store/initial.js @@ -119,10 +119,10 @@ const initial = { narratives: { default: { - style: 'dotted', // ['dotted', 'solid'] - opacity: 0.4, // range between 0 and 1 + style: 'solid', // ['dotted', 'solid'] + opacity: 0.9, // range between 0 and 1 stroke: 'red', // Any hex or rgb code - strokeWidth: 2 + strokeWidth: 5 }, narrative_1: { style: 'solid', // ['dotted', 'solid'] From 3d09eb4543c5120dd1361b9c2f8520e9fdbaee5a Mon Sep 17 00:00:00 2001 From: Lachlan Kermode Date: Wed, 5 Dec 2018 11:17:19 +0000 Subject: [PATCH 07/11] clean handler semantics in Dashboard.jsx, add markNotificationsRead --- src/actions/index.js | 7 +++++ src/components/CardStack.jsx | 2 +- src/components/Dashboard.jsx | 47 ++++++++++++++++---------------- src/components/Notification.jsx | 2 +- src/components/Toolbar.jsx | 4 +-- src/reducers/domain.js | 19 +++++++++++-- src/reducers/utils/validators.js | 2 +- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 865612e..bbbccf9 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -256,6 +256,13 @@ export function toggleNotifications() { } } +export const MARK_NOTIFICATIONS_READ = 'MARK_NOTIFICATIONS_READ' +export function markNotificationsRead() { + return { + type: MARK_NOTIFICATIONS_READ + } +} + // ERRORS export const FETCH_SOURCE_ERROR = 'FETCH_SOURCE_ERROR' diff --git a/src/components/CardStack.jsx b/src/components/CardStack.jsx index 8c5071e..05fbddf 100644 --- a/src/components/CardStack.jsx +++ b/src/components/CardStack.jsx @@ -54,7 +54,7 @@ class CardStack extends React.Component {
this.props.onToggle('TOGGLE_CARDSTACK')} + onClick={() => this.props.onToggleCardstack()} >

diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index a0ebc67..a92bcb8 100644 --- a/src/components/Dashboard.jsx +++ b/src/components/Dashboard.jsx @@ -19,7 +19,7 @@ class Dashboard extends React.Component { this.handleHighlight = this.handleHighlight.bind(this); this.handleSelect = this.handleSelect.bind(this); - this.handleToggle = this.handleToggle.bind(this); + // this.handleToggle = this.handleToggle.bind(this); this.handleTagFilter = this.handleTagFilter.bind(this); this.updateTimerange = this.updateTimerange.bind(this); @@ -62,22 +62,22 @@ class Dashboard extends React.Component { this.props.actions.updateTimeRange(timeRange); } - handleToggle( key ) { - switch( key ) { - case 'TOGGLE_CARDSTACK': { - this.props.actions.updateSelected([]); - break; - } - case 'TOGGLE_INFOPOPUP': { - this.props.actions.toggleInfoPopup(); - break; - } - case 'TOGGLE_NOTIFICATIONS': { - this.props.actions.toggleNotifications(); - break; - } - } - } + // handleToggle( key ) { + // switch( key ) { + // case 'TOGGLE_CARDSTACK': { + // this.props.actions.updateSelected([]); + // break; + // } + // case 'TOGGLE_INFOPOPUP': { + // this.props.actions.toggleInfoPopup(); + // break; + // } + // case 'TOGGLE_NOTIFICATIONS': { + // this.props.actions.toggleNotifications(); + // break; + // } + // } + // } getCategoryColor(category='other') { return this.props.ui.style.categories[category] || this.props.style.categories['other'] @@ -100,33 +100,32 @@ class Dashboard extends React.Component { }} /> this.handleToggle(key) } + onFilter={this.handleTagFilter} actions={this.props.actions} /> this.props.actions.updateSelected([])} getNarrativeLinks={event => this.getNarrativeLinks(event)} getCategoryColor={category => this.getCategoryColor(category)} /> this.handleToggle('TOGGLE_CARDSTACK')} getCategoryColor={category => this.getCategoryColor(category)} /> this.handleToggle('TOGGLE_INFOPOPUP')} + toggle={() => this.props.actions.toggleInfoPopup()} /> this.handleToggle('TOGGLE_NOTIFICATIONS')} + onToggle={() => { + this.props.actions.toggleNotifications(); + }} /> this.toggleDetails() }>