diff --git a/src/actions/index.js b/src/actions/index.js index ce86367..9df2fe0 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -58,7 +58,7 @@ export function fetchDomain () { return Promise.all([ eventPromise, catPromise, sitesPromise, tagsPromise]) .then(response => { - dispatch(toggleFetchingDomain()); + dispatch(toggleFetchingDomain()) const result = { events: response[0], categories: response[1], @@ -70,12 +70,12 @@ export function fetchDomain () { }) .catch(err => { dispatch(fetchError(err.message)) - dispatch(toggleFetchingDomain()); + dispatch(toggleFetchingDomain()) }) }; } -export const FETCH_ERROR = 'FETCH_ERROR'; +export const FETCH_ERROR = 'FETCH_ERROR' export function fetchError(message) { return { type: FETCH_ERROR, @@ -83,113 +83,114 @@ export function fetchError(message) { } } -export const UPDATE_DOMAIN = 'UPDATE_DOMAIN'; +export const UPDATE_DOMAIN = 'UPDATE_DOMAIN' export function updateDomain(domain) { - return { - type: UPDATE_DOMAIN, - domain: { - events: domain.events, - categories: domain.categories, - tags: domain.tags, - sites: domain.sites, - notifications: domain.notifications - } - }; + return { + type: UPDATE_DOMAIN, + domain: { + events: domain.events, + categories: domain.categories, + tags: domain.tags, + sites: domain.sites, + notifications: domain.notifications + } + } } -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 const UPDATE_HIGHLIGHTED = 'UPDATE_HIGHLIGHTED'; +export const UPDATE_HIGHLIGHTED = 'UPDATE_HIGHLIGHTED' export function updateHighlighted(highlighted) { return { type: UPDATE_HIGHLIGHTED, highlighted: highlighted - }; + } } -export const UPDATE_SELECTED = 'UPDATE_SELECTED'; +export const UPDATE_SELECTED = 'UPDATE_SELECTED' export function updateSelected(selected) { return { type: UPDATE_SELECTED, selected: selected - }; + } } -export const UPDATE_DISTRICT = 'UPDATE_DISTRICT'; +export const UPDATE_DISTRICT = 'UPDATE_DISTRICT' export function updateDistrict(district) { return { type: UPDATE_DISTRICT, district - }; + } } -export const UPDATE_TAGFILTERS = 'UPDATE_TIMEFILTERS'; +export const UPDATE_TAGFILTERS = 'UPDATE_TIMEFILTERS' export function updateTagFilters(tag) { return { type: UPDATE_TAGFILTERS, tag - }; + } } -export const UPDATE_TIMERANGE = 'UPDATE_TIMERANGE'; +export const UPDATE_TIMERANGE = 'UPDATE_TIMERANGE' export function updateTimeRange(range) { return { type: UPDATE_TIMERANGE, range - }; + } } -export const RESET_ALLFILTERS = 'RESET_ALLFILTERS'; +export const RESET_ALLFILTERS = 'RESET_ALLFILTERS' export function resetAllFilters() { return { type: RESET_ALLFILTERS - }; + } } // UI -export const TOGGLE_FETCHING_DOMAIN = 'TOGGLE_FETCHING_DOMAIN'; +export const TOGGLE_FETCHING_DOMAIN = 'TOGGLE_FETCHING_DOMAIN' export function toggleFetchingDomain() { return { type: TOGGLE_FETCHING_DOMAIN - }; + } } -export const TOGGLE_FETCHING_EVENTS = 'TOGGLE_FETCHING_EVENTS'; +export const TOGGLE_FETCHING_EVENTS = 'TOGGLE_FETCHING_EVENTS' export function toggleFetchingEvents() { return { type: TOGGLE_FETCHING_EVENTS - }; + } } -export const TOGGLE_VIEW = 'TOGGLE_VIEW'; +export const TOGGLE_VIEW = 'TOGGLE_VIEW' export function toggleView() { return { type: TOGGLE_VIEW - }; + } } -export const TOGGLE_TIMELINE = 'TOGGLE_TIMELINE'; +export const TOGGLE_TIMELINE = 'TOGGLE_TIMELINE' export function toggleTimeline() { return { type: TOGGLE_TIMELINE - }; + } } -export const TOGGLE_LANGUAGE = 'TOGGLE_LANGUAGE'; +export const TOGGLE_LANGUAGE = 'TOGGLE_LANGUAGE' export function toggleLanguage(language) { return { type: TOGGLE_LANGUAGE, @@ -197,46 +198,46 @@ export function toggleLanguage(language) { } } -export const OPEN_TOOLBAR = 'OPEN_TOOLBAR'; +export const OPEN_TOOLBAR = 'OPEN_TOOLBAR' export function openToolbar(toolbarTab = 0) { return { type: OPEN_TOOLBAR, toolbarTab: toolbarTab, - }; + } } -export const CLOSE_TOOLBAR = 'CLOSE_TOOLBAR'; +export const CLOSE_TOOLBAR = 'CLOSE_TOOLBAR' export function closeToolbar() { return { type: CLOSE_TOOLBAR - }; + } } -export const OPEN_CABINET = 'OPEN_CABINET'; +export const OPEN_CABINET = 'OPEN_CABINET' export function openCabinet(tabNum) { return { type: OPEN_CABINET, tabNum: tabNum, - }; + } } -export const CLOSE_CABINET = 'CLOSE_CABINET'; +export const CLOSE_CABINET = 'CLOSE_CABINET' export function closeCabinet() { return { type: CLOSE_CABINET - }; + } } -export const TOGGLE_INFOPOPUP = 'TOGGLE_INFOPOPUP'; +export const TOGGLE_INFOPOPUP = 'TOGGLE_INFOPOPUP' export function toggleInfoPopup() { return { type: TOGGLE_INFOPOPUP - }; + } } -export const TOGGLE_NOTIFICATIONS = 'TOGGLE_NOTIFICATIONS'; +export const TOGGLE_NOTIFICATIONS = 'TOGGLE_NOTIFICATIONS' export function toggleNotifications() { return { type: TOGGLE_NOTIFICATIONS - }; + } } diff --git a/src/reducers/domain.js b/src/reducers/domain.js index 11a64d9..4e56634 100644 --- a/src/reducers/domain.js +++ b/src/reducers/domain.js @@ -1,25 +1,22 @@ -import initial from '../store/initial.js'; +import initial from '../store/initial.js' -import { - UPDATE_DOMAIN, -} from '../actions'; +import { UPDATE_DOMAIN } from '../actions' +import { parseDateTimes } from './utils/helpers.js' +import { validate } from './utils/validators.js' -import { parseDateTimes } from './utils/helpers.js'; -import { validate } from './utils/validators.js'; +function updateDomain (domainState, action) { + action.domain.events = parseDateTimes(action.domain.events) -function updateDomain(domainState, action) { - action.domain.events = parseDateTimes(action.domain.events); - - return Object.assign({}, domainState, validate(action.domain)); + return Object.assign({}, domainState, validate(action.domain)) } -function domain(domainState = initial.domain, action) { +function domain (domainState = initial.domain, action) { switch (action.type) { case UPDATE_DOMAIN: - return updateDomain(domainState, action); + return updateDomain(domainState, action) default: - return domainState; + return domainState } } -export default domain; +export default domain diff --git a/src/selectors/index.js b/src/selectors/index.js index cd0bb46..5a8f00b 100644 --- a/src/selectors/index.js +++ b/src/selectors/index.js @@ -3,60 +3,60 @@ import { } from 'reselect' // Input selectors -export const getEvents = state => state.domain.events; -export const getLocations = state => state.domain.locations; -export const getCategories = state => state.domain.categories; +export const getEvents = state => state.domain.events +export const getLocations = state => state.domain.locations +export const getCategories = state => state.domain.categories export const getSites = (state) => { - if (process.env.features.USE_SITES) return state.domain.sites; - return []; + if (process.env.features.USE_SITES) return state.domain.sites + return [] } -export const getAllTags = state => state.domain.tags; +export const getAllTags = state => state.domain.tags -export const getCategoriesFilter = state => state.app.filters.categories; -export const getTagsFilter = state => state.app.filters.tags; -export const getRangeFilter = state => state.app.filters.range; +export const getCategoriesFilter = state => state.app.filters.categories +export const getTagsFilter = state => state.app.filters.tags +export const getRangeFilter = state => state.app.filters.range // NB: should we stick with the default semantics and name these as selectors? // e.g. 'selectEvents', 'selectCoevents'. // Filter events -function isTaggedIn(event, tagFilters) { +function isTaggedIn (event, tagFilters) { if (event.tags) { - const tagsArray = event.tags.split(","); + const tagsArray = event.tags.split(',') const isTagged = tagsArray.some((tag) => { return tagFilters.find((tagFilter) => { - return (tagFilter.key === tag && tagFilter.active); + return (tagFilter.key === tag && tagFilter.active) }) - }); - return isTagged; + }) + return isTagged } else { - return false; + return false } } - /** * Of all available events, selects those that fall within the time range, * and if TAGS are being used, select them if their tags are enabled */ export const getFilteredEvents = createSelector( - [getEvents, getTagsFilter, getRangeFilter], - (events, tagFilters, rangeFilter) => { + [getEvents, getTagsFilter, getRangeFilter], + (events, tagFilters, rangeFilter) => { + return events.reduce((acc, value) => { + const noTags = (tagFilters.length === 0 || !process.env.features.USE_TAGS || tagFilters.every(t => !t.active)) - return events.reduce((acc, value) => { - const noTags = (tagFilters.length === 0 || !process.env.features.USE_TAGS || tagFilters.every(t => !t.active)); + const isTagged = (noTags) || isTaggedIn(value, tagFilters) - const isTagged = (noTags) || isTaggedIn(value, tagFilters); + // TODO: put this datetime format as a constant + const isRange = (rangeFilter[0] < d3.timeParse('%Y-%m-%dT%H:%M:%S')(value.timestamp)) && + (d3.timeParse('%Y-%m-%dT%H:%M:%S')(value.timestamp) < rangeFilter[1]) - const isRange = (rangeFilter[0] < d3.timeParse("%Y-%m-%dT%H:%M:%S")(value.timestamp)) && - (d3.timeParse("%Y-%m-%dT%H:%M:%S")(value.timestamp) < rangeFilter[1]); - - if (isRange && isTagged) { - const event = Object.assign({}, value); - acc[event.id] = event; - } - return acc; - }, []); -}); + if (isRange && isTagged) { + const event = Object.assign({}, value) + acc[event.id] = event + } + return acc + }, []) + } +) /** * Of all the filtered events, group them by location and return a list of @@ -65,12 +65,11 @@ export const getFilteredEvents = createSelector( export const getFilteredLocations = createSelector( [getFilteredEvents], (events) => { - - const filteredLocations = {}; + const filteredLocations = {} events.forEach(event => { - const location = event.location; + const location = event.location if (filteredLocations[location]) { - filteredLocations[location].events.push(event); + filteredLocations[location].events.push(event) } else { filteredLocations[location] = { label: location, @@ -81,17 +80,15 @@ export const getFilteredLocations = createSelector( } }) - // Make locations an array are remove if any are undefined - return Object.values(filteredLocations).filter(item => item); -}); + // Make locations an array are remove if any are undefined + return Object.values(filteredLocations).filter(item => item) + } +) // Filter categories export const getFilteredCategories = createSelector( [getCategories], - (categories) => { - - return Object.values(categories); - }); + (categories) => Object.values(categories)) /** * Return categories by group @@ -99,13 +96,12 @@ export const getFilteredCategories = createSelector( export const getCategoryGroups = createSelector( [getFilteredCategories], (categories) => { - const groups = {}; - categories.forEach((t) => { if (t.group && !groups[t.group]) { groups[t.group] = t.group_label } }); - return Object.keys(groups).concat(['other']); + const groups = {} + categories.forEach((t) => { if (t.group && !groups[t.group]) { groups[t.group] = t.group_label } }) + return Object.keys(groups).concat(['other']) } ) - /** * Given a tree of tags, return those tags as a list, where each node has been * aware of its depth, and given an 'active' flag @@ -113,22 +109,22 @@ export const getCategoryGroups = createSelector( export const getTagFilters = createSelector( [getAllTags], (tags) => { - const allTagFilters = []; - let depth = 0; - function traverseNode(node, depth) { - node.active = (!node.hasOwnProperty('active')) ? false : node.active; - node.depth = depth; + const allTagFilters = [] + let depth = 0 + function traverseNode (node, depth) { + node.active = (!node.hasOwnProperty('active')) ? false : node.active + node.depth = depth if (node.active) allTagFilters.push(node) - depth = depth + 1; + depth = depth + 1 if (Object.keys(node.children).length > 0) { Object.values(node.children).forEach((childNode) => { - traverseNode(childNode, depth); - }); + traverseNode(childNode, depth) + }) } } - if (tags.key && tags.children) traverseNode(tags, depth) - return allTagFilters; + if (tags && tags.key && tags.children) traverseNode(tags, depth) + return allTagFilters } )