From d6fcd7e06d24ce75a17b82290ce54a802bc5e868 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 3 Jun 2016 17:11:23 -0700 Subject: web: implement redux store fetching --- web/src/js/ducks/eventLog.js | 29 ++++++---- web/src/js/ducks/list.js | 21 ------- web/src/js/ducks/utils/list.js | 121 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+), 31 deletions(-) delete mode 100644 web/src/js/ducks/list.js create mode 100644 web/src/js/ducks/utils/list.js (limited to 'web/src/js/ducks') diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js index 2040711c..081a2276 100644 --- a/web/src/js/ducks/eventLog.js +++ b/web/src/js/ducks/eventLog.js @@ -1,8 +1,17 @@ -import getList, {ADD} from "./list" +import makeList, {ADD} from "./utils/list" + const TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER' const TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY' -const UPDATE_LIST = "UPDATE_EVENTLOG" +export const UPDATE_LOG = "UPDATE_EVENTLOG" + +const { + reduceList, + addToList, + updateList, + fetchList, +} = makeList(UPDATE_LOG, "/events"); +export {updateList as updateLogEntries, fetchList as fetchLogEntries} const defaultState = { visible: false, @@ -11,7 +20,7 @@ const defaultState = { "info": true, "web": true }, - events: getList(), + events: reduceList(), filteredEvents: [], } @@ -32,8 +41,8 @@ export default function reducer(state = defaultState, action) { ...state, visible: !state.visible } - case UPDATE_LIST: - const events = getList(state.events, action) + case UPDATE_LOG: + const events = reduceList(state.events, action) return { ...state, events, @@ -53,9 +62,9 @@ export function toggleEventLogVisibility() { } let id = 0; export function addLogEntry(message, level = "web") { - return { - type: UPDATE_LIST, - cmd: ADD, - data: {message, level, id: `log-${id++}`} - } + return addToList({ + message, + level, + id: `log-${id++}` + }) } \ No newline at end of file diff --git a/web/src/js/ducks/list.js b/web/src/js/ducks/list.js deleted file mode 100644 index 0b3771e2..00000000 --- a/web/src/js/ducks/list.js +++ /dev/null @@ -1,21 +0,0 @@ -export const ADD = 'add' - -const defaultState = { - list: [], - //isFetching: false, - //updateBeforeFetch: [], - indexOf: {}, - //views: {} -}; - -export default function getList(state = defaultState, action = {}) { - switch (action.cmd) { - case ADD: - return { - list: [...state.list, action.data], - indexOf: {...state.indexOf, [action.data.id]: state.list.length}, - } - default: - return state - } -} \ No newline at end of file diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js new file mode 100644 index 00000000..37b2ae3a --- /dev/null +++ b/web/src/js/ducks/utils/list.js @@ -0,0 +1,121 @@ +import {fetchApi} from "../../utils"; + +const ADD = "ADD" +const REQUEST_LIST = "REQUEST_LIST" +const RECEIVE_LIST = "RECEIVE_LIST" + + +const defaultState = { + list: [], + isFetching: false, + actionsDuringFetch: [], + byId: {}, + indexOf: {}, +}; + +export default function makeList(actionType, fetchURL) { + function reduceList(state = defaultState, action = {}) { + + if (action.type !== actionType) { + return state + } + + // Handle cases where we finished fetching or are still fetching. + if (action.cmd === RECEIVE_LIST) { + let s = { + isFetching: false, + actionsDuringFetch: [], + list: action.list, + byId: {}, + indexOf: {} + } + for (let i = 0; i < action.list.length; i++) { + let item = action.list[i] + s.byId[item.id] = item + s.indexOf[item.id] = i + } + for (action of state.actionsDuringFetch) { + s = reduceList(s, action) + } + return s + } else if (state.isFetching) { + return { + ...state, + actionsDuringFetch: [...state.actionsDuringFetch, action] + } + } + + switch (action.cmd) { + case ADD: + return { + list: [...state.list, action.item], + byId: {...state.byId, [action.item.id]: action.item}, + indexOf: {...state.indexOf, [action.item.id]: state.list.length}, + } + + case REQUEST_LIST: + return { + ...defaultState, + isFetching: true + } + + default: + console.debug("unknown action", action.type) + return state + } + } + + function addToList(item) { + return { + type: actionType, + cmd: ADD, + item + } + } + + + function updateList(action) { + /* This action creater takes all WebSocket events */ + return dispatch => { + switch (action.cmd) { + case "add": + return dispatch(addToList(action.data)) + case "reset": + return dispatch(fetchList()) + default: + console.error("unknown list update", action) + } + } + } + + function requestList() { + return { + type: actionType, + cmd: REQUEST_LIST, + } + } + + function receiveList(list) { + return { + type: actionType, + cmd: RECEIVE_LIST, + list + } + } + + function fetchList() { + return dispatch => { + + dispatch(requestList()) + + fetchApi(fetchURL).then(response => { + return response.json().then(json => { + dispatch(receiveList(json.data)) + }) + }) + } + } + + + return {reduceList, addToList, updateList, fetchList} +} \ No newline at end of file -- cgit v1.2.3