aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/ducks
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/js/ducks')
-rw-r--r--web/src/js/ducks/flows.js30
-rw-r--r--web/src/js/ducks/index.js2
-rw-r--r--web/src/js/ducks/settings.js9
-rw-r--r--web/src/js/ducks/ui.js292
-rw-r--r--web/src/js/ducks/ui/flow.js97
-rw-r--r--web/src/js/ducks/ui/header.js50
-rw-r--r--web/src/js/ducks/ui/index.js8
-rw-r--r--web/src/js/ducks/ui/keyboard.js122
8 files changed, 291 insertions, 319 deletions
diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js
index ffb7ac87..f18e48e6 100644
--- a/web/src/js/ducks/flows.js
+++ b/web/src/js/ducks/flows.js
@@ -67,56 +67,49 @@ 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) {
@@ -124,8 +117,7 @@ export function updateContent(flow, file, type) {
if (typeof file !== File)
file = new Blob([file], {type: 'plain/text'})
body.append('file', file)
- fetchApi(`/flows/${flow.id}/${type}/content`, {method: 'post', body} )
- return { type: REQUEST_ACTION }
+ return dispatch => fetchApi(`/flows/${flow.id}/${type}/content`, {method: 'post', body} )
}
@@ -133,8 +125,7 @@ export function updateContent(flow, file, type) {
* @public
*/
export function clear() {
- fetchApi('/clear', { method: 'POST' })
- return { type: REQUEST_ACTION }
+ return dispatch => fetchApi('/clear', { method: 'POST' })
}
/**
@@ -151,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 ccd17eb6..00000000
--- a/web/src/js/ducks/ui.js
+++ /dev/null
@@ -1,292 +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'
-export const OPEN_FLOW_EDITOR= 'UI_OPEN_FLOW_EDITOR'
-export const CLOSE_FLOW_EDITOR = 'UI_CLOSE_FLOW_EDITOR'
-export const SET_MODIFIED_FLOW_CONTENT = 'UI_SET_MODIFIED_FLOW'
-
-const defaultState = {
- activeMenu: 'Start',
- isFlowSelected: false,
- selectedInput: null,
- displayLarge: false,
- promptOpen: false,
- contentView: 'ViewAuto',
- query: {},
- panel: 'request',
- modifiedFlow: {headers: "", content: ""},
- isFlowEditorOpen: false
-}
-
-export default function reducer(state = defaultState, action) {
- switch (action.type) {
-
- case SET_ACTIVE_MENU:
- return {
- ...state,
- activeMenu: action.activeMenu,
- }
-
- case flowsActions.SELECT:
- let s = {...state, isFlowEditorOpen: false}
- if (action.flowIds.length && !state.isFlowSelected) {
- return {
- ...s,
- displayLarge: false,
- activeMenu: 'Flow',
- isFlowSelected: true,
- }
- }
-
- if (!action.flowIds.length && state.isFlowSelected) {
- let activeMenu = state.activeMenu
- if (activeMenu == 'Flow') {
- activeMenu = 'Start'
- }
- return {
- ...s,
- activeMenu,
- isFlowSelected: false,
- }
- }
-
- return {
- ...s,
- 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,
- isFlowEditorOpen: false,
- panel: action.panel
- }
-
- case SET_PROMPT:
- return {
- ...state,
- promptOpen: action.open,
- }
-
- case SET_DISPLAY_LARGE:
- return {
- ...state,
- displayLarge: action.displayLarge,
- }
- case OPEN_FLOW_EDITOR:
- return {
- ...state,
- isFlowEditorOpen: true
- }
- case CLOSE_FLOW_EDITOR:
- return {
- ...state,
- isFlowEditorOpen: false
- }
- case SET_MODIFIED_FLOW_CONTENT:
- return{
- ...state,
- modifiedFlow: {...state.modifiedFlow, content: action.content}
- }
- 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 openFlowEditor(){
- return { type: OPEN_FLOW_EDITOR }
-}
-
-export function closeFlowEditor(){
- return { type: CLOSE_FLOW_EDITOR }
-}
-
-export function setModifiedFlowContent(content) {
- return { type: SET_MODIFIED_FLOW_CONTENT, content }
-}
-
-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
+ }
+ }
+}