aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/ducks/utils/list.js
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/js/ducks/utils/list.js')
-rw-r--r--web/src/js/ducks/utils/list.js209
1 files changed, 67 insertions, 142 deletions
diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js
index a830fe99..e66a8549 100644
--- a/web/src/js/ducks/utils/list.js
+++ b/web/src/js/ducks/utils/list.js
@@ -1,166 +1,91 @@
-import {fetchApi} from "../../utils"
-
-export const ADD = "ADD"
-export const UPDATE = "UPDATE"
-export const REMOVE = "REMOVE"
-export const REQUEST_LIST = "REQUEST_LIST"
-export const RECEIVE_LIST = "RECEIVE_LIST"
+import _ from 'lodash'
+export const SET = 'LIST_SET'
+export const CLEAR = 'LIST_CLEAR'
+export const REQUEST = 'LIST_REQUEST'
+export const RECEIVE = 'LIST_RECEIVE'
const defaultState = {
- list: [],
- isFetching: false,
- actionsDuringFetch: [],
- byId: {},
- indexOf: {},
+ data: {},
+ pendingActions: null,
}
-export default function makeList(actionType, fetchURL) {
- function reduceList(state = defaultState, action = {}) {
-
- if (action.type !== actionType) {
- return state
- }
+export default function reduce(state = defaultState, action) {
+ switch (action.type) {
- // 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)
+ case SET:
+ if (state.pendingActions) {
+ return {
+ ...state,
+ pendingActions: [...state.pendingActions, action]
+ }
}
- return s
- } else if (state.isFetching) {
return {
...state,
- actionsDuringFetch: [...state.actionsDuringFetch, action]
+ data: { ...state.data, [action.id]: null, [action.item.id]: action.item }
}
- }
-
- let list, itemIndex
- 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 UPDATE:
- list = [...state.list]
- itemIndex = state.indexOf[action.item.id]
- list[itemIndex] = action.item
+ case CLEAR:
+ if (state.pendingActions) {
return {
...state,
- list,
- byId: {...state.byId, [action.item.id]: action.item},
+ pendingActions: [...state.pendingActions, action]
}
+ }
+ return {
+ ...state,
+ data: { ...state.data, [action.id]: null }
+ }
- case REMOVE:
- list = [...state.list]
- itemIndex = state.indexOf[action.item.id]
- list.splice(itemIndex, 1)
- return {
- ...state,
- list,
- byId: {...state.byId, [action.item.id]: undefined},
- indexOf: {...state.indexOf, [action.item.id]: undefined},
- }
-
- case REQUEST_LIST:
- return {
- ...state,
- isFetching: true
- }
-
- default:
- console.debug("unknown action", action)
- return state
- }
- }
-
- function addItem(item) {
- return {
- type: actionType,
- cmd: ADD,
- item
- }
- }
-
- function updateItem(item) {
- return {
- type: actionType,
- cmd: UPDATE,
- item
- }
- }
-
- function removeItem(item) {
- return {
- type: actionType,
- cmd: REMOVE,
- item
- }
- }
-
-
- function updateList(event) {
- /* This action creater takes all WebSocket events */
- return dispatch => {
- switch (event.cmd) {
- case "add":
- return dispatch(addItem(event.data))
- case "update":
- return dispatch(updateItem(event.data))
- case "remove":
- return dispatch(removeItem(event.data))
- case "reset":
- return dispatch(fetchList())
- default:
- console.error("unknown list update", event)
+ case REQUEST:
+ return {
+ ...state,
+ pendingActions: []
}
- }
- }
- function requestList() {
- return {
- type: actionType,
- cmd: REQUEST_LIST,
- }
- }
+ case RECEIVE:
+ return state.pendingActions.reduce(reduce, {
+ ...state,
+ pendingActions: null,
+ data: _.fromPairs(action.list.map(item => [item.id, item])),
+ })
- function receiveList(list) {
- return {
- type: actionType,
- cmd: RECEIVE_LIST,
- list
- }
+ default:
+ return state
}
+}
- function fetchList() {
- return dispatch => {
+/**
+ * @public
+ */
+export function add(item) {
+ return { type: SET, id: item.id, item }
+}
- dispatch(requestList())
+/**
+ * @public
+ */
+export function update(id, item) {
+ return { type: SET, id, item }
+}
- return fetchApi(fetchURL).then(response => {
- return response.json().then(json => {
- dispatch(receiveList(json.data))
- })
- })
- }
- }
+/**
+ * @public
+ */
+export function remove(id) {
+ return { type: CLEAR, id }
+}
+/**
+ * @public
+ */
+export function request() {
+ return { type: REQUEST }
+}
- return {reduceList, updateList, fetchList, addItem, updateItem, removeItem,}
-} \ No newline at end of file
+/**
+ * @public
+ */
+export function receive(list) {
+ return { type: RECEIVE, list }
+}