diff options
Diffstat (limited to 'web/src/js/ducks')
-rw-r--r-- | web/src/js/ducks/flows.js | 37 | ||||
-rw-r--r-- | web/src/js/ducks/index.js | 2 | ||||
-rw-r--r-- | web/src/js/ducks/settings.js | 9 | ||||
-rw-r--r-- | web/src/js/ducks/ui.js | 259 | ||||
-rw-r--r-- | web/src/js/ducks/ui/flow.js | 97 | ||||
-rw-r--r-- | web/src/js/ducks/ui/header.js | 50 | ||||
-rw-r--r-- | web/src/js/ducks/ui/index.js | 8 | ||||
-rw-r--r-- | web/src/js/ducks/ui/keyboard.js | 122 |
8 files changed, 300 insertions, 284 deletions
diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index dfcd5ba9..f18e48e6 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -16,6 +16,7 @@ export const UNKNOWN_CMD = 'FLOWS_UNKNOWN_CMD' export const FETCH_ERROR = 'FLOWS_FETCH_ERROR' export const SELECT = 'FLOWS_SELECT' + const defaultState = { selected: [], ...reduceList(undefined, {}), @@ -66,64 +67,65 @@ export default function reduce(state = defaultState, action) { * @public */ export function accept(flow) { - fetchApi(`/flows/${flow.id}/accept`, { method: 'POST' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi(`/flows/${flow.id}/accept`, { method: 'POST' }) } /** * @public */ export function acceptAll() { - fetchApi('/flows/accept', { method: 'POST' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi('/flows/accept', { method: 'POST' }) } /** * @public */ export function remove(flow) { - fetchApi(`/flows/${flow.id}`, { method: 'DELETE' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi(`/flows/${flow.id}`, { method: 'DELETE' }) } /** * @public */ export function duplicate(flow) { - fetchApi(`/flows/${flow.id}/duplicate`, { method: 'POST' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi(`/flows/${flow.id}/duplicate`, { method: 'POST' }) } /** * @public */ export function replay(flow) { - fetchApi(`/flows/${flow.id}/replay`, { method: 'POST' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi(`/flows/${flow.id}/replay`, { method: 'POST' }) } /** * @public */ export function revert(flow) { - fetchApi(`/flows/${flow.id}/revert`, { method: 'POST' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi(`/flows/${flow.id}/revert`, { method: 'POST' }) } /** * @public */ export function update(flow, data) { - fetchApi.put(`/flows/${flow.id}`, data) - return { type: REQUEST_ACTION } + return dispatch => fetchApi.put(`/flows/${flow.id}`, data) } +export function updateContent(flow, file, type) { + const body = new FormData() + if (typeof file !== File) + file = new Blob([file], {type: 'plain/text'}) + body.append('file', file) + return dispatch => fetchApi(`/flows/${flow.id}/${type}/content`, {method: 'post', body} ) +} + + /** * @public */ export function clear() { - fetchApi('/clear', { method: 'POST' }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi('/clear', { method: 'POST' }) } /** @@ -140,8 +142,7 @@ export function download() { export function upload(file) { const body = new FormData() body.append('file', file) - fetchApi('/flows/dump', { method: 'post', body }) - return { type: REQUEST_ACTION } + return dispatch => fetchApi('/flows/dump', { method: 'post', body }) } diff --git a/web/src/js/ducks/index.js b/web/src/js/ducks/index.js index 16193530..b90b24ff 100644 --- a/web/src/js/ducks/index.js +++ b/web/src/js/ducks/index.js @@ -4,7 +4,7 @@ import websocket from './websocket' import flows from './flows' import flowView from './flowView' import settings from './settings' -import ui from './ui' +import ui from './ui/index' import msgQueue from './msgQueue' export default combineReducers({ diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 7ad97b87..6b21baec 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -11,22 +11,19 @@ export const REQUEST_UPDATE = 'REQUEST_UPDATE' export const UNKNOWN_CMD = 'SETTINGS_UNKNOWN_CMD' const defaultState = { - settings: {}, + } export default function reducer(state = defaultState, action) { switch (action.type) { case RECEIVE: - return { - ...state, - settings: action.settings, - } + return action.settings case UPDATE: return { ...state, - settings: { ...state.settings, ...action.settings }, + ...action.settings, } default: diff --git a/web/src/js/ducks/ui.js b/web/src/js/ducks/ui.js deleted file mode 100644 index f745f0af..00000000 --- a/web/src/js/ducks/ui.js +++ /dev/null @@ -1,259 +0,0 @@ -import { selectRelative as selectFlowRelative } from './flowView' -import { Key } from '../utils.js' -import * as flowsActions from './flows' - -export const SET_ACTIVE_MENU = 'UI_SET_ACTIVE_MENU' -export const SET_CONTENT_VIEW = 'UI_SET_CONTENT_VIEW' -export const SET_SELECTED_INPUT = 'UI_SET_SELECTED_INPUT' -export const UPDATE_QUERY = 'UI_UPDATE_QUERY' -export const SELECT_TAB = 'UI_SELECT_TAB' -export const SET_PROMPT = 'UI_SET_PROMPT' -export const SET_DISPLAY_LARGE = 'UI_SET_DISPLAY_LARGE' - -const defaultState = { - activeMenu: 'Start', - isFlowSelected: false, - selectedInput: null, - displayLarge: false, - promptOpen: false, - contentView: 'ViewAuto', - query: {}, - panel: 'request' -} - -export default function reducer(state = defaultState, action) { - switch (action.type) { - - case SET_ACTIVE_MENU: - return { - ...state, - activeMenu: action.activeMenu, - } - - case flowsActions.SELECT: - if (action.flowIds.length && !state.isFlowSelected) { - return { - ...state, - displayLarge: false, - activeMenu: 'Flow', - isFlowSelected: true, - } - } - - if (!action.flowIds.length && state.isFlowSelected) { - let activeMenu = state.activeMenu - if (activeMenu == 'Flow') { - activeMenu = 'Start' - } - return { - ...state, - activeMenu, - isFlowSelected: false, - } - } - - return { - ...state, - displayLarge: false, - } - - case SET_CONTENT_VIEW: - return { - ...state, - contentView: action.contentView, - } - - case SET_SELECTED_INPUT: - return { - ...state, - selectedInput: action.input - } - - case UPDATE_QUERY: - return { - ...state, - query: { ...state.query, ...action.query } - } - - case SELECT_TAB: - return { - ...state, - panel: action.panel - } - - case SET_PROMPT: - return { - ...state, - promptOpen: action.open, - } - - case SET_DISPLAY_LARGE: - return { - ...state, - displayLarge: action.displayLarge, - } - - default: - return state - } -} - -export function setActiveMenu(activeMenu) { - return { type: SET_ACTIVE_MENU, activeMenu } -} - -export function setContentView(contentView) { - return { type: SET_CONTENT_VIEW, contentView } -} - -export function setSelectedInput(input) { - return { type: SET_SELECTED_INPUT, input } -} - -export function updateQuery(query) { - return { type: UPDATE_QUERY, query } -} - -export function selectTab(panel) { - return { type: SELECT_TAB, panel } -} - -export function setPrompt(open) { - return { type: SET_PROMPT, open } -} - -export function setDisplayLarge(displayLarge) { - return { type: SET_DISPLAY_LARGE, displayLarge } -} - -export function onKeyDown(e) { - if (e.ctrlKey) { - return () => { - } - } - var key = e.keyCode - var shiftKey = e.shiftKey - e.preventDefault() - return (dispatch, getState) => { - - const flow = getState().flows.byId[getState().flows.selected[0]] - - switch (key) { - - case Key.I: - dispatch(setSelectedInput('intercept')) - break - - case Key.L: - dispatch(setSelectedInput('search')) - break - - case Key.H: - dispatch(setSelectedInput('highlight')) - break - - case Key.K: - case Key.UP: - dispatch(selectFlowRelative(-1)) - break - - case Key.J: - case Key.DOWN: - dispatch(selectFlowRelative(+1)) - break - - case Key.SPACE: - case Key.PAGE_DOWN: - dispatch(selectFlowRelative(+10)) - break - - case Key.PAGE_UP: - dispatch(selectFlowRelative(-10)) - break - - case Key.END: - dispatch(selectFlowRelative(+1e10)) - break - - case Key.HOME: - dispatch(selectFlowRelative(-1e10)) - break - - case Key.ESC: - dispatch(flowsActions.select(null)) - break - - case Key.LEFT: - { - let tabs = ['request', 'response', 'error'].filter(k => flow[k]).concat(['details']), - currentTab = getState().ui.panel, - nextTab = tabs[(tabs.indexOf(currentTab) - 1 + tabs.length) % tabs.length] - dispatch(selectTab(nextTab)) - break - } - - case Key.TAB: - case Key.RIGHT: - { - let tabs = ['request', 'response', 'error'].filter(k => flow[k]).concat(['details']), - currentTab = getState().ui.panel, - nextTab = tabs[(tabs.indexOf(currentTab) + 1) % tabs.length] - dispatch(selectTab(nextTab)) - break - } - - case Key.C: - if (shiftKey) { - dispatch(flowsActions.clear()) - } - break - - case Key.D: - { - if (!flow) { - return - } - if (shiftKey) { - dispatch(flowsActions.duplicate(flow)) - } else { - dispatch(flowsActions.remove(flow)) - } - break - } - - case Key.A: - { - if (shiftKey) { - dispatch(flowsActions.acceptAll()) - } else if (flow && flow.intercepted) { - dispatch(flowsActions.accept(flow)) - } - break - } - - case Key.R: - { - if (!shiftKey && flow) { - dispatch(flowsActions.replay(flow)) - } - break - } - - case Key.V: - { - if (!shiftKey && flow && flow.modified) { - dispatch(flowsActions.revert(flow)) - } - break - } - - case Key.E: - dispatch(setPrompt(true)) - break - - default: - return () => { - } - } - } -} diff --git a/web/src/js/ducks/ui/flow.js b/web/src/js/ducks/ui/flow.js new file mode 100644 index 00000000..b1fe535f --- /dev/null +++ b/web/src/js/ducks/ui/flow.js @@ -0,0 +1,97 @@ +import * as flowsActions from '../flows' +import _ from 'lodash' + +export const SET_CONTENT_VIEW = 'UI_FLOWVIEW_SET_CONTENT_VIEW', + DISPLAY_LARGE = 'UI_FLOWVIEW_DISPLAY_LARGE', + SET_TAB = "UI_FLOWVIEW_SET_TAB", + START_EDIT = 'UI_FLOWVIEW_START_EDIT', + UPDATE_EDIT = 'UI_FLOWVIEW_UPDATE_EDIT', + STOP_EDIT = 'UI_FLOWVIEW_STOP_EDIT' + + +const defaultState = { + displayLarge: false, + modifiedFlow: false, + contentView: 'ViewAuto', + tab: 'request', +} + +export default function reducer(state = defaultState, action) { + switch (action.type) { + + case START_EDIT: + return { + ...state, + modifiedFlow: action.flow + } + + case UPDATE_EDIT: + return { + ...state, + modifiedFlow: _.merge({}, state.modifiedFlow, action.update) + } + + case STOP_EDIT: + return { + ...state, + modifiedFlow: false + } + + case flowsActions.SELECT: + return { + ...state, + modifiedFlow: false, + displayLarge: false, + } + + case SET_TAB: + return { + ...state, + tab: action.tab, + displayLarge: false, + } + + case SET_CONTENT_VIEW: + return { + ...state, + contentView: action.contentView, + } + + case DISPLAY_LARGE: + return { + ...state, + displayLarge: true, + } + default: + return state + } +} + +export function setContentView(contentView) { + return { type: SET_CONTENT_VIEW, contentView } +} + +export function displayLarge() { + return { type: DISPLAY_LARGE } +} + +export function selectTab(tab) { + return { type: SET_TAB, tab } +} + +export function startEdit(flow) { + return { type: START_EDIT, flow } +} + +export function updateEdit(update) { + return { type: UPDATE_EDIT, update } +} + +export function stopEdit(flow) { + return (dispatch) => { + dispatch(flowsActions.update(flow, flow)).then(() => { + dispatch(flowsActions.updateFlow(flow)) + dispatch({ type: STOP_EDIT }) + }) + } +} diff --git a/web/src/js/ducks/ui/header.js b/web/src/js/ducks/ui/header.js new file mode 100644 index 00000000..25dfe602 --- /dev/null +++ b/web/src/js/ducks/ui/header.js @@ -0,0 +1,50 @@ +import * as flowsActions from '../flows' + +export const SET_ACTIVE_MENU = 'UI_SET_ACTIVE_MENU' + + +const defaultState = { + activeMenu: 'Start', + isFlowSelected: false, +} + +export default function reducer(state = defaultState, action) { + switch (action.type) { + + case SET_ACTIVE_MENU: + return { + ...state, + activeMenu: action.activeMenu, + } + + case flowsActions.SELECT: + // First Select + if (action.flowIds.length && !state.isFlowSelected) { + return { + ...state, + activeMenu: 'Flow', + isFlowSelected: true, + } + } + + // Deselect + if (!action.flowIds.length && state.isFlowSelected) { + let activeMenu = state.activeMenu + if (activeMenu == 'Flow') { + activeMenu = 'Start' + } + return { + ...state, + activeMenu, + isFlowSelected: false, + } + } + return state + default: + return state + } +} + +export function setActiveMenu(activeMenu) { + return { type: SET_ACTIVE_MENU, activeMenu } +} diff --git a/web/src/js/ducks/ui/index.js b/web/src/js/ducks/ui/index.js new file mode 100644 index 00000000..f3c5f59e --- /dev/null +++ b/web/src/js/ducks/ui/index.js @@ -0,0 +1,8 @@ +import { combineReducers } from 'redux' +import flow from './flow' +import header from './header' + +export default combineReducers({ + flow, + header, +}) diff --git a/web/src/js/ducks/ui/keyboard.js b/web/src/js/ducks/ui/keyboard.js new file mode 100644 index 00000000..10c69853 --- /dev/null +++ b/web/src/js/ducks/ui/keyboard.js @@ -0,0 +1,122 @@ +import { Key } from '../../utils' +import { selectRelative as selectFlowRelative } from '../flowView' +import { selectTab } from './flow' +import * as flowsActions from '../flows' + + +export function onKeyDown(e) { + console.debug("onKeyDown", e) + if (e.ctrlKey) { + return () => { + } + } + var key = e.keyCode + var shiftKey = e.shiftKey + e.preventDefault() + return (dispatch, getState) => { + + const flow = getState().flows.byId[getState().flows.selected[0]] + + switch (key) { + case Key.K: + case Key.UP: + dispatch(selectFlowRelative(-1)) + break + + case Key.J: + case Key.DOWN: + dispatch(selectFlowRelative(+1)) + break + + case Key.SPACE: + case Key.PAGE_DOWN: + dispatch(selectFlowRelative(+10)) + break + + case Key.PAGE_UP: + dispatch(selectFlowRelative(-10)) + break + + case Key.END: + dispatch(selectFlowRelative(+1e10)) + break + + case Key.HOME: + dispatch(selectFlowRelative(-1e10)) + break + + case Key.ESC: + dispatch(flowsActions.select(null)) + break + + case Key.LEFT: + { + if(!flow) break + let tabs = ['request', 'response', 'error'].filter(k => flow[k]).concat(['details']), + currentTab = getState().ui.flow.tab, + nextTab = tabs[(tabs.indexOf(currentTab) - 1 + tabs.length) % tabs.length] + dispatch(selectTab(nextTab)) + break + } + + case Key.TAB: + case Key.RIGHT: + { + if(!flow) break + let tabs = ['request', 'response', 'error'].filter(k => flow[k]).concat(['details']), + currentTab = getState().ui.flow.tab, + nextTab = tabs[(tabs.indexOf(currentTab) + 1) % tabs.length] + dispatch(selectTab(nextTab)) + break + } + + case Key.C: + if (shiftKey) { + dispatch(flowsActions.clear()) + } + break + + case Key.D: + { + if (!flow) { + return + } + if (shiftKey) { + dispatch(flowsActions.duplicate(flow)) + } else { + dispatch(flowsActions.remove(flow)) + } + break + } + + case Key.A: + { + if (shiftKey) { + dispatch(flowsActions.acceptAll()) + } else if (flow && flow.intercepted) { + dispatch(flowsActions.accept(flow)) + } + break + } + + case Key.R: + { + if (!shiftKey && flow) { + dispatch(flowsActions.replay(flow)) + } + break + } + + case Key.V: + { + if (!shiftKey && flow && flow.modified) { + dispatch(flowsActions.revert(flow)) + } + break + } + + default: + return + } + } +} |