diff options
Diffstat (limited to 'web/src/js/ducks/flows.js')
-rw-r--r-- | web/src/js/ducks/flows.js | 274 |
1 files changed, 195 insertions, 79 deletions
diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index b877d3e4..f732f536 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -1,114 +1,230 @@ -import makeList from "./utils/list" -import Filt from "../filt/filt" -import {updateViewFilter, updateViewList, updateViewSort} from "./utils/view" -import {reverseString} from "../utils.js"; -import * as columns from "../components/FlowTable/FlowColumns"; +import { fetchApi } from '../utils' +import reduceList, * as listActions from './utils/list' +import reduceViews, * as viewsActions from './views' +import * as websocketActions from './websocket' -export const UPDATE_FLOWS = "UPDATE_FLOWS" -export const SET_FILTER = "SET_FLOW_FILTER" -export const SET_HIGHLIGHT = "SET_FLOW_HIGHLIGHT" -export const SET_SORT = "SET_FLOW_SORT" -export const SELECT_FLOW = "SELECT_FLOW" - -const { - reduceList, - updateList, - fetchList, -} = makeList(UPDATE_FLOWS, "/flows") +export const WS_MSG_TYPE = 'UPDATE_FLOWS' +export const ADD = 'FLOWS_ADD' +export const UPDATE = 'FLOWS_UPDATE' +export const REMOVE = 'FLOWS_REMOVE' +export const REQUEST = 'FLOWS_REQUEST' +export const RECEIVE = 'FLOWS_RECEIVE' +export const REQUEST_ACTION = 'FLOWS_REQUEST_ACTION' +export const UNKNOWN_CMD = 'FLOWS_UNKNOWN_CMD' +export const FETCH_ERROR = 'FLOWS_FETCH_ERROR' const defaultState = { - all: reduceList(), - selected: [], - view: [], - filter: undefined, - highlight: undefined, - sort: {sortColumn: undefined, sortDesc: false}, -} - -function makeFilterFn(filter) { - return filter ? Filt.parse(filter) : () => true; -} - - -function makeSortFn(sort){ - let column = columns[sort.sortColumn]; - if (!column) return; - - let sortKeyFun = column.sortKeyFun; - if (sort.sortDesc) { - sortKeyFun = sortKeyFun && function (flow) { - const k = column.sortKeyFun(flow); - return _.isString(k) ? reverseString("" + k) : -k; - }; - } - return sortKeyFun; + list: undefined, + views: undefined, } -export default function reducer(state = defaultState, action) { +export default function reduce(state = defaultState, action) { switch (action.type) { - case UPDATE_FLOWS: - let all = reduceList(state.all, action) + + case ADD: return { ...state, - all, - view: updateViewList(state.view, state.all, all, action, makeFilterFn(action.filter), makeSortFn(state.sort)) + list: reduceList(state.list, listActions.add(action.item)), + views: reduceViews(state.views, viewsActions.add(action.item)), } - case SET_FILTER: + + case UPDATE: return { ...state, - filter: action.filter, - view: updateViewFilter(state.all, makeFilterFn(action.filter), makeSortFn(state.sort)) + list: reduceList(state.list, listActions.update(action.id, action.item)), + views: reduceViews(state.views, viewsActions.update(action.id, action.item)), } - case SET_HIGHLIGHT: + + case REMOVE: return { ...state, - highlight: action.highlight + list: reduceList(state.list, listActions.remove(action.item.id)), + views: reduceViews(state.views, viewsActions.remove(action.item.id)), } - case SET_SORT: + + case REQUEST: return { ...state, - sort: action.sort, - view: updateViewSort(state.view, makeSortFn(action.sort)) + list: reduceList(state.list, listActions.request()), } - case SELECT_FLOW: + + case RECEIVE: + const list = reduceList(state.list, listActions.receive(action.list)) return { ...state, - selected: [action.flowId] + list, + views: reduceViews(state.views, viewsActions.receive(list)), } + default: - return state + return { + ...state, + list: reduceList(state.list, action), + views: reduceViews(state.views, action), + } } } +/** + * @public + */ +export function accept(flow) { + fetchApi(`/flows/${flow.id}/accept`, { method: 'POST' }) + return { type: REQUEST_ACTION } +} -export function setFilter(filter) { - return { - type: SET_FILTER, - filter - } +/** + * @public + */ +export function acceptAll() { + fetchApi('/flows/accept', { method: 'POST' }) + return { type: REQUEST_ACTION } } -export function setHighlight(highlight) { - return { - type: SET_HIGHLIGHT, - highlight - } + +/** + * @public + */ +export function remove(flow) { + fetchApi(`/flows/${flow.id}`, { method: 'DELETE' }) + return { type: REQUEST_ACTION } +} + +/** + * @public + */ +export function duplicate(flow) { + fetchApi(`/flows/${flow.id}/duplicate`, { method: 'POST' }) + return { type: REQUEST_ACTION } +} + +/** + * @public + */ +export function replay(flow) { + fetchApi(`/flows/${flow.id}/replay`, { method: 'POST' }) + return { type: REQUEST_ACTION } +} + +/** + * @public + */ +export function revert(flow) { + fetchApi(`/flows/${flow.id}/revert`, { method: 'POST' }) + return { type: REQUEST_ACTION } } -export function setSort(sort){ - return { - type: SET_SORT, - sort + +/** + * @public + */ +export function update(flow, body) { + fetchApi(`/flows/${flow.id}`, { method: 'PUT', body }) + return { type: REQUEST_ACTION } +} + +/** + * @public + */ +export function clear() { + fetchApi('/clear', { method: 'POST' }) + return { type: REQUEST_ACTION } +} + +/** + * @public + */ +export function download() { + window.location = '/flows/dump' + return { type: REQUEST_ACTION } +} + +/** + * @public + */ +export function upload(file) { + const body = new FormData() + body.append('file', file) + fetchApi('/flows/dump', { method: 'post', body }) + return { type: REQUEST_ACTION } +} + +/** + * This action creater takes all WebSocket events + * + * @public websocket + */ +export function handleWsMsg(msg) { + switch (msg.cmd) { + + case websocketActions.CMD_ADD: + return add(msg.data) + + case websocketActions.CMD_UPDATE: + return update(msg.data.id, msg.data) + + case websocketActions.CMD_REMOVE: + return remove(msg.data.id) + + case websocketActions.CMD_RESET: + return fetchData() + + default: + return { type: UNKNOWN_CMD, msg } } } -export function selectFlow(flowId) { - return (dispatch, getState) => { - dispatch({ - type: SELECT_FLOW, - currentSelection: getState().flows.selected[0], - flowId - }) + +/** + * @public websocket + */ +export function fetchData() { + return dispatch => { + dispatch(request()) + + return fetchApi('/flows') + .then(res => res.json()) + .then(json => dispatch(receive(json.data))) + .catch(error => dispatch(fetchError(error))) } } +/** + * @private + */ +export function add(item) { + return { type: ADD, item } +} -export {updateList as updateFlows, fetchList as fetchFlows} +/** + * @private + */ +export function update(id, item) { + return { type: UPDATE, id, item } +} + +/** + * @private + */ +export function remove(id) { + return { type: REMOVE, id } +} + +/** + * @private + */ +export function request() { + return { type: REQUEST } +} + +/** + * @private + */ +export function receive(list) { + return { type: RECEIVE, list } +} + +/** + * @private + */ +export function fetchError(error) { + return { type: FETCH_ERROR, error } +} |