From 1b327f34c30e490e6f26ec1ee4e6cfe7b40a47eb Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 3 Jun 2016 18:38:03 -0700 Subject: web: add redux list views --- web/src/js/ducks/eventLog.js | 16 +++++++++--- web/src/js/ducks/utils/list.js | 6 ++--- web/src/js/ducks/utils/view.js | 58 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 web/src/js/ducks/utils/view.js (limited to 'web') diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js index 081a2276..883f537c 100644 --- a/web/src/js/ducks/eventLog.js +++ b/web/src/js/ducks/eventLog.js @@ -1,4 +1,5 @@ import makeList, {ADD} from "./utils/list" +import {updateViewFilter, updateViewList} from "./utils/view" const TOGGLE_FILTER = 'TOGGLE_EVENTLOG_FILTER' const TOGGLE_VISIBILITY = 'TOGGLE_EVENTLOG_VISIBILITY' @@ -11,7 +12,6 @@ const { fetchList, } = makeList(UPDATE_LOG, "/events"); -export {updateList as updateLogEntries, fetchList as fetchLogEntries} const defaultState = { visible: false, @@ -34,7 +34,10 @@ export default function reducer(state = defaultState, action) { return { ...state, filter, - filteredEvents: state.events.list.filter(x => filter[x.level]) + filteredEvents: updateViewFilter( + state.events.list, + x => filter[x.level] + ) } case TOGGLE_VISIBILITY: return { @@ -46,7 +49,11 @@ export default function reducer(state = defaultState, action) { return { ...state, events, - filteredEvents: events.list.filter(x => state.filter[x.level]) + filteredEvents: updateViewList( + state.filteredEvents, + events, action, + x => state.filter[x.level] + ) } default: return state @@ -67,4 +74,5 @@ export function addLogEntry(message, level = "web") { level, id: `log-${id++}` }) -} \ No newline at end of file +} +export {updateList as updateLogEntries, fetchList as fetchLogEntries} \ No newline at end of file diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js index 37b2ae3a..b750982e 100644 --- a/web/src/js/ducks/utils/list.js +++ b/web/src/js/ducks/utils/list.js @@ -1,8 +1,8 @@ import {fetchApi} from "../../utils"; -const ADD = "ADD" -const REQUEST_LIST = "REQUEST_LIST" -const RECEIVE_LIST = "RECEIVE_LIST" +export const ADD = "ADD" +export const REQUEST_LIST = "REQUEST_LIST" +export const RECEIVE_LIST = "RECEIVE_LIST" const defaultState = { diff --git a/web/src/js/ducks/utils/view.js b/web/src/js/ducks/utils/view.js new file mode 100644 index 00000000..4b265f89 --- /dev/null +++ b/web/src/js/ducks/utils/view.js @@ -0,0 +1,58 @@ +import {ADD, REQUEST_LIST, RECEIVE_LIST} from "./list" + +const defaultFilterFn = x => true +const defaultSortFn = false + +const makeCompareFn = sortFn => { + let compareFn = (a, b) => { + let akey = sortFn(a), + bkey = sortFn(b); + if (akey < bkey) { + return -1; + } else if (akey > bkey) { + return 1; + } else { + return 0; + } + } + if (sortFn.reverse) + return (a, b) => compareFn(b, a) + return compareFn +} + +const sortedInsert = (list, sortFn, item) => { + let l = [...list, item] + let compareFn = makeCompareFn(sortFn) + + // only sort if sorting order is not correct yet + if (sortFn && compareFn(list[list.length - 1], item) > 0) { + // TODO: This is untested + console.debug("sorting view...") + l.sort(compareFn) + } + return l +} + +// for when the list changes +export function updateViewList(state, nextList, action, filterFn = defaultFilterFn, sortFn = defaultSortFn) { + switch (action.cmd) { + case REQUEST_LIST: + return state + case RECEIVE_LIST: + return updateViewFilter(nextList.list, filterFn, sortFn) + case ADD: + if (filterFn(action.item)) + return sortedInsert(state, sortFn, action.item) + return state + default: + console.error("Unknown list action: ", action); + return state + } +} + +export function updateViewFilter(list, filterFn = defaultFilterFn, sortFn = defaultSortFn) { + let filtered = list.filter(filterFn) + if (sortFn) + filtered.sort(makeCompareFn(sortFn)) + return filtered +} \ No newline at end of file -- cgit v1.2.3