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.js121
1 files changed, 121 insertions, 0 deletions
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