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 6da357e..77ead1b 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}` /* @@ -97,110 +107,128 @@ export function updateDomain(domain) { } } -export function fetchEvents (events) { + +export function fetchSelected(selected) { + if (!selected || !selected.length || selected.length === 0) { + console.log('hitting base') + return updateSelected([]) + } 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 - }) + dispatch(updateSelected(selected)) + if (!SOURCES_URL) { + dispatch(fetchSourceError('No source extension specified.')) + } else { + dispatch(toggleFetchingSources()) + } + } } 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_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 + } +} + +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' +export function fetchSourceError(msg) { + return { + type: FETCH_SOURCE_ERROR, + msg + } } diff --git a/src/components/CardStack.jsx b/src/components/CardStack.jsx index 8408f54..f5bc36e 100644 --- a/src/components/CardStack.jsx +++ b/src/components/CardStack.jsx @@ -22,7 +22,6 @@ class CardStack extends React.Component { event={event} language={this.props.language} tools={this.props.tools} - isLoading={this.props.isLoading} getNarrativeLinks={this.props.getNarrativeLinks} getCategoryGroup={this.props.getCategoryGroup} getCategoryColor={this.props.getCategoryColor} @@ -54,15 +53,12 @@ class CardStack extends React.Component {
this.props.onToggle('TOGGLE_CARDSTACK')} + onClick={() => this.props.onToggleCardstack()} >

- {(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 +67,7 @@ class CardStack extends React.Component { return (
); @@ -99,7 +92,7 @@ function mapStateToProps(state) { language: state.app.language, tools: state.ui.tools, isCardstack: state.ui.flags.isCardstack, - isLoading: state.ui.flags.isFetchingEvents + isFetchingSources: state.ui.flags.isFetchingSources } } diff --git a/src/components/Dashboard.jsx b/src/components/Dashboard.jsx index 344cc8e..783fd78 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); @@ -46,32 +46,11 @@ 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)) - 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); - }); - } else { - this.props.actions.updateSelected([]); + this.props.actions.fetchSelected(eventsToSelect) } } @@ -83,23 +62,6 @@ 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; - } - } - } - getCategoryColor(category='other') { return this.props.ui.style.categories[category] || this.props.style.categories['other'] } @@ -113,41 +75,39 @@ class Dashboard extends React.Component { render() { return (
- this.getCategoryColor(category) }} /> 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)} + methods={{ + onSelect: this.handleSelect, + onUpdateTimerange: this.updateTimerange, + getCategoryColor: category => this.getCategoryColor(category) + }} /> this.handleToggle('TOGGLE_INFOPOPUP')} + toggle={() => this.props.actions.toggleInfoPopup()} /> this.handleToggle('TOGGLE_NOTIFICATIONS')} + onToggle={this.props.actions.markNotificationsRead} /> !('isRead' in n && n.isRead)) + if (notificationsToRender.length > 0) { return (
{this.props.notifications.map((notification) => { @@ -52,7 +52,7 @@ export default class Notification extends React.Component{ return (
this.toggleDetails() }>