diff options
Diffstat (limited to 'web/src/js/ducks/flowView.js')
-rw-r--r-- | web/src/js/ducks/flowView.js | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/web/src/js/ducks/flowView.js b/web/src/js/ducks/flowView.js new file mode 100644 index 00000000..dd5bea41 --- /dev/null +++ b/web/src/js/ducks/flowView.js @@ -0,0 +1,195 @@ +import reduceView, * as viewActions from './utils/view' +import * as flowActions from './flows' +import Filt from '../filt/filt' +import { RequestUtils } from '../flow/utils' + +export const UPDATE_FILTER = 'FLOWVIEW_UPDATE_FILTER' +export const UPDATE_SORT = 'FLOWVIEW_UPDATE_SORT' +export const UPDATE_HIGHLIGHT = 'FLOWVIEW_UPDATE_HIGHLIGHT' + + +const sortKeyFuns = { + + TLSColumn: flow => flow.request.scheme, + + PathColumn: flow => RequestUtils.pretty_url(flow.request), + + MethodColumn: flow => flow.request.method, + + StatusColumn: flow => flow.response && flow.response.status_code, + + TimeColumn: flow => flow.response && flow.response.timestamp_end - flow.request.timestamp_start, + + SizeColumn: flow => { + let total = flow.request.contentLength + if (flow.response) { + total += flow.response.contentLength || 0 + } + return total + }, +} + +export function makeFilter(filter) { + if (!filter) { + return + } + return Filt.parse(filter) +} + +export function makeSort({ column, desc }) { + const sortKeyFun = sortKeyFuns[column] + if (!sortKeyFun) { + return + } + return (a, b) => { + const ka = sortKeyFun(a) + const kb = sortKeyFun(b) + if (ka > kb) { + return desc ? -1 : 1 + } + if (ka < kb) { + return desc ? 1 : -1 + } + return 0 + } +} + + +const defaultState = { + highlight: null, + filter: null, + sort: { column: null, desc: false }, + ...reduceView(undefined, {}) +} + +export default function reduce(state = defaultState, action) { + switch (action.type) { + + case UPDATE_HIGHLIGHT: + return { + ...state, + highlight: action.highlight, + } + + case UPDATE_FILTER: + return { + ...reduceView( + state, + viewActions.updateFilter( + action.flows, + makeFilter(action.filter), + makeSort(state.sort) + ) + ), + filter: action.filter, + } + + case UPDATE_SORT: + const sort = { column: action.column, desc: action.desc } + return { + ...reduceView( + state, + viewActions.updateSort( + makeSort(sort) + ) + ), + sort, + } + + case flowActions.ADD: + return { + ...reduceView( + state, + viewActions.add( + action.item, + makeFilter(state.filter), + makeSort(state.sort) + ) + ), + } + + case flowActions.UPDATE: + return { + ...reduceView( + state, + viewActions.update( + action.item, + makeFilter(state.filter), + makeSort(state.sort) + ) + ), + } + + case flowActions.REMOVE: + return { + ...reduceView( + state, + viewActions.remove( + action.id + ) + ), + } + + case flowActions.RECEIVE: + return { + ...reduceView( + state, + viewActions.receive( + action.list, + makeFilter(state.filter), + makeSort(state.sort) + ) + ), + } + + default: + return { + ...reduceView(state, action), + } + } +} + +/** + * @public + */ +export function updateFilter(filter) { + return (dispatch, getState) => { + dispatch({ type: UPDATE_FILTER, filter, flows: getState().flows.data }) + } +} + +/** + * @public + */ +export function updateHighlight(highlight) { + return { type: UPDATE_HIGHLIGHT, highlight } +} + +/** + * @public + */ +export function updateSort(column, desc) { + return { type: UPDATE_SORT, column, desc } +} + + +/** + * @public + */ +export function selectRelative(shift) { + return (dispatch, getState) => { + let currentSelectionIndex = getState().flowView.indexOf[getState().flows.selected[0]] + let minIndex = 0 + let maxIndex = getState().flowView.data.length - 1 + let newIndex + if (currentSelectionIndex === undefined) { + newIndex = (shift < 0) ? minIndex : maxIndex + } else { + newIndex = currentSelectionIndex + shift + newIndex = Math.max(newIndex, minIndex) + newIndex = Math.min(newIndex, maxIndex) + } + let flow = getState().flowView.data[newIndex] + dispatch(flowActions.select(flow ? flow.id : undefined)) + } +} |