diff options
Diffstat (limited to 'web/src')
-rw-r--r-- | web/src/js/components/EventLog.jsx | 14 | ||||
-rw-r--r-- | web/src/js/components/FlowTable/FlowTableHead.jsx | 2 | ||||
-rw-r--r-- | web/src/js/components/FlowView.jsx | 8 | ||||
-rw-r--r-- | web/src/js/components/FlowView/Messages.jsx | 28 | ||||
-rw-r--r-- | web/src/js/components/FlowView/Nav.jsx | 29 | ||||
-rw-r--r-- | web/src/js/components/Header/FileMenu.jsx | 12 | ||||
-rw-r--r-- | web/src/js/components/Header/FlowMenu.jsx | 22 | ||||
-rw-r--r-- | web/src/js/components/Header/MainMenu.jsx | 8 | ||||
-rw-r--r-- | web/src/js/components/Header/ViewMenu.jsx | 12 | ||||
-rw-r--r-- | web/src/js/components/MainView.jsx | 33 | ||||
-rw-r--r-- | web/src/js/ducks/eventLog.js | 15 | ||||
-rw-r--r-- | web/src/js/ducks/flows.js | 6 | ||||
-rw-r--r-- | web/src/js/ducks/utils/list.js | 5 | ||||
-rw-r--r-- | web/src/js/ducks/websocket.js | 4 |
14 files changed, 84 insertions, 114 deletions
diff --git a/web/src/js/components/EventLog.jsx b/web/src/js/components/EventLog.jsx index e426672a..636e3e9a 100644 --- a/web/src/js/components/EventLog.jsx +++ b/web/src/js/components/EventLog.jsx @@ -9,8 +9,8 @@ class EventLog extends Component { static propTypes = { filters: PropTypes.object.isRequired, events: PropTypes.array.isRequired, - onToggleFilter: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, + toggleFilter: PropTypes.func.isRequired, + close: PropTypes.func.isRequired, defaultHeight: PropTypes.number, } @@ -48,7 +48,7 @@ class EventLog extends Component { render() { const { height } = this.state - const { filters, events, onToggleFilter, onClose } = this.props + const { filters, events, toggleFilter, close } = this.props return ( <div className="eventlog" style={{ height }}> @@ -56,9 +56,9 @@ class EventLog extends Component { Eventlog <div className="pull-right"> {['debug', 'info', 'web'].map(type => ( - <ToggleButton key={type} text={type} checked={filters[type]} onToggle={() => onToggleFilter(type)}/> + <ToggleButton key={type} text={type} checked={filters[type]} onToggle={() => toggleFilter(type)}/> ))} - <i onClick={onClose} className="fa fa-close"></i> + <i onClick={close} className="fa fa-close"></i> </div> </div> <EventList events={events} /> @@ -73,7 +73,7 @@ export default connect( events: state.eventLog.view.data, }), { - onClose: toggleVisibility, - onToggleFilter: toggleFilter, + close: toggleVisibility, + toggleFilter: toggleFilter, } )(EventLog) diff --git a/web/src/js/components/FlowTable/FlowTableHead.jsx b/web/src/js/components/FlowTable/FlowTableHead.jsx index 2cd32524..f65369bd 100644 --- a/web/src/js/components/FlowTable/FlowTableHead.jsx +++ b/web/src/js/components/FlowTable/FlowTableHead.jsx @@ -6,7 +6,7 @@ import columns from './FlowColumns' import { updateSort } from '../../ducks/views/main' FlowTableHead.propTypes = { - onSort: PropTypes.func.isRequired, + updateSort: PropTypes.func.isRequired, sortDesc: React.PropTypes.bool.isRequired, sortColumn: React.PropTypes.string, } diff --git a/web/src/js/components/FlowView.jsx b/web/src/js/components/FlowView.jsx index 83cc57e8..0ef6e5cd 100644 --- a/web/src/js/components/FlowView.jsx +++ b/web/src/js/components/FlowView.jsx @@ -35,8 +35,8 @@ export default class FlowView extends Component { closePrompt(edit) { this.setState({ prompt: false }) - if (edit) { - this.refs.tab.edit(edit) + if (edit && this.tabComponent) { + this.tabComponent.edit(edit) } } @@ -75,7 +75,7 @@ export default class FlowView extends Component { render() { const tabs = this.getTabs() - let { flow, tab: active, onUpdate } = this.props + let { flow, tab: active, updateFlow } = this.props if (tabs.indexOf(active) < 0) { if (active === 'response' && flow.error) { @@ -97,7 +97,7 @@ export default class FlowView extends Component { active={active} onSelectTab={this.selectTab} /> - <Tab ref="tab" flow={flow} onUpdate={onUpdate} /> + <Tab ref={ tab => this.tabComponent = tab } flow={flow} updateFlow={updateFlow} /> {this.state.prompt && ( <Prompt {...this.state.prompt}/> )} diff --git a/web/src/js/components/FlowView/Messages.jsx b/web/src/js/components/FlowView/Messages.jsx index f866776f..9295f97c 100644 --- a/web/src/js/components/FlowView/Messages.jsx +++ b/web/src/js/components/FlowView/Messages.jsx @@ -10,21 +10,21 @@ import Headers from './Headers' class RequestLine extends Component { render() { - const { flow, onUpdate } = this.props + const { flow, updateFlow } = this.props return ( <div className="first-line request-line"> <ValueEditor ref="method" content={flow.request.method} - onDone={method => onUpdate({ request: { method } })} + onDone={method => updateFlow({ request: { method } })} inline /> <ValueEditor ref="url" content={RequestUtils.pretty_url(flow.request)} - onDone={url => onUpdate({ request: Object.assign({ path: '' }, parseUrl(url)) })} + onDone={url => updateFlow({ request: Object.assign({ path: '' }, parseUrl(url)) })} isValid={url => !!parseUrl(url).host} inline /> @@ -32,7 +32,7 @@ class RequestLine extends Component { <ValueEditor ref="httpVersion" content={flow.request.http_version} - onDone={ver => onUpdate({ request: { http_version: parseHttpVersion(ver) } })} + onDone={ver => updateFlow({ request: { http_version: parseHttpVersion(ver) } })} isValid={isValidHttpVersion} inline /> @@ -44,14 +44,14 @@ class RequestLine extends Component { class ResponseLine extends Component { render() { - const { flow, onUpdate } = this.props + const { flow, updateFlow } = this.props return ( <div className="first-line response-line"> <ValueEditor ref="httpVersion" content={flow.response.http_version} - onDone={nextVer => onUpdate({ response: { http_version: parseHttpVersion(nextVer) } })} + onDone={nextVer => updateFlow({ response: { http_version: parseHttpVersion(nextVer) } })} isValid={isValidHttpVersion} inline /> @@ -59,7 +59,7 @@ class ResponseLine extends Component { <ValueEditor ref="code" content={flow.response.status_code + ''} - onDone={code => onUpdate({ response: { code: parseInt(code) } })} + onDone={code => updateFlow({ response: { code: parseInt(code) } })} isValid={code => /^\d+$/.test(code)} inline /> @@ -67,7 +67,7 @@ class ResponseLine extends Component { <ValueEditor ref="msg" content={flow.response.reason} - onDone={msg => onUpdate({ response: { msg } })} + onDone={msg => updateFlow({ response: { msg } })} inline /> </div> @@ -78,15 +78,15 @@ class ResponseLine extends Component { export class Request extends Component { render() { - const { flow, onUpdate } = this.props + const { flow, updateFlow } = this.props return ( <section className="request"> - <RequestLine ref="requestLine" flow={flow} onUpdate={onUpdate} /> + <RequestLine ref="requestLine" flow={flow} updateFlow={updateFlow} /> <Headers ref="headers" message={flow.request} - onChange={headers => onUpdate({ request: { headers } })} + onChange={headers => updateFlow({ request: { headers } })} /> <hr/> <ContentView flow={flow} message={flow.request}/> @@ -117,15 +117,15 @@ export class Request extends Component { export class Response extends Component { render() { - const { flow, onUpdate } = this.props + const { flow, updateFlow } = this.props return ( <section className="response"> - <ResponseLine ref="responseLine" flow={flow} onUpdate={onUpdate} /> + <ResponseLine ref="responseLine" flow={flow} updateFlow={updateFlow} /> <Headers ref="headers" message={flow.response} - onChange={headers => onUpdate({ response: { headers } })} + onChange={headers => updateFlow({ response: { headers } })} /> <hr/> <ContentView flow={flow} message={flow.response}/> diff --git a/web/src/js/components/FlowView/Nav.jsx b/web/src/js/components/FlowView/Nav.jsx index b9e15d92..37c073ce 100644 --- a/web/src/js/components/FlowView/Nav.jsx +++ b/web/src/js/components/FlowView/Nav.jsx @@ -1,7 +1,6 @@ import React, { PropTypes } from 'react' import { connect } from 'react-redux' import classnames from 'classnames' -import * as flowsActions from '../../ducks/flows' NavAction.propTypes = { icon: PropTypes.string.isRequired, @@ -24,18 +23,12 @@ function NavAction({ icon, title, onClick }) { } Nav.propTypes = { - flow: PropTypes.object.isRequired, active: PropTypes.string.isRequired, tabs: PropTypes.array.isRequired, onSelectTab: PropTypes.func.isRequired, - onRemove: PropTypes.func.isRequired, - onDuplicate: PropTypes.func.isRequired, - onReplay: PropTypes.func.isRequired, - onAccept: PropTypes.func.isRequired, - onRevert: PropTypes.func.isRequired, } -function Nav({ flow, active, tabs, onSelectTab, onRemove, onDuplicate, onReplay, onAccept, onRevert }) { +export default function Nav({ active, tabs, onSelectTab }) { return ( <nav className="nav-tabs nav-tabs-sm"> {tabs.map(tab => ( @@ -49,26 +42,6 @@ function Nav({ flow, active, tabs, onSelectTab, onRemove, onDuplicate, onReplay, {_.capitalize(tab)} </a> ))} - <NavAction title="[d]elete flow" icon="fa-trash" onClick={() => onRemove(flow)} /> - <NavAction title="[D]uplicate flow" icon="fa-copy" onClick={() => onDuplicate(flow)} /> - <NavAction disabled title="[r]eplay flow" icon="fa-repeat" onClick={() => onReplay(flow)} /> - {flow.intercepted && ( - <NavAction title="[a]ccept intercepted flow" icon="fa-play" onClick={() => onAccept(flow)} /> - )} - {flow.modified && ( - <NavAction title="revert changes to flow [V]" icon="fa-history" onClick={() => onRevert(flow)} /> - )} </nav> ) } - -export default connect( - null, - { - onRemove: flowsActions.remove, - onDuplicate: flowsActions.duplicate, - onReplay: flowsActions.replay, - onAccept: flowsActions.accept, - onRevert: flowsActions.revert, - } -)(Nav) diff --git a/web/src/js/components/Header/FileMenu.jsx b/web/src/js/components/Header/FileMenu.jsx index a4466784..d3786475 100644 --- a/web/src/js/components/Header/FileMenu.jsx +++ b/web/src/js/components/Header/FileMenu.jsx @@ -36,7 +36,7 @@ class FileMenu extends Component { onNewClick(e) { e.preventDefault() if (confirm('Delete all flows?')) { - this.props.onClear() + this.props.clearFlows() } } @@ -48,14 +48,14 @@ class FileMenu extends Component { onOpenFile(e) { e.preventDefault() if (e.target.files.length > 0) { - this.props.onUpload(e.target.files[0]) + this.props.loadFlows(e.target.files[0]) this.fileInput.value = '' } } onSaveClick(e) { e.preventDefault() - this.props.onDownload() + this.props.saveFlows() } render() { @@ -103,8 +103,8 @@ class FileMenu extends Component { export default connect( null, { - onClear: flowsActions.clear, - onUpload: flowsActions.upload, - onDownload: flowsActions.download, + clearFlows: flowsActions.clear, + loadFlows: flowsActions.upload, + saveFlows: flowsActions.download, } )(FileMenu) diff --git a/web/src/js/components/Header/FlowMenu.jsx b/web/src/js/components/Header/FlowMenu.jsx index ba1dcbcb..8d13dd6a 100644 --- a/web/src/js/components/Header/FlowMenu.jsx +++ b/web/src/js/components/Header/FlowMenu.jsx @@ -10,16 +10,16 @@ FlowMenu.propTypes = { flow: PropTypes.object.isRequired, } -function FlowMenu({ flow, onAccept, onReplay, onDuplicate, onRemove, onRevert }) { +function FlowMenu({ flow, acceptFlow, replayFlow, duplicateFlow, removeFlow, revertFlow }) { return ( <div> <div className="menu-row"> - <Button disabled={!flow.intercepted} title="[a]ccept intercepted flow" text="Accept" icon="fa-play" onClick={() => onAccept(flow)} /> - <Button title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={() => onReplay(flow)} /> - <Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={() => onDuplicate(flow)} /> - <Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={() => onRemove(flow)}/> - <Button disabled={!flow.modified} title="revert changes to flow [V]" text="Revert" icon="fa-history" onClick={() => onRevert(flow)} /> + <Button disabled={!flow.intercepted} title="[a]ccept intercepted flow" text="Accept" icon="fa-play" onClick={() => acceptFlow(flow)} /> + <Button title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={() => replayFlow(flow)} /> + <Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={() => duplicateFlow(flow)} /> + <Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={() => removeFlow(flow)}/> + <Button disabled={!flow.modified} title="revert changes to flow [V]" text="Revert" icon="fa-history" onClick={() => revertFlow(flow)} /> <Button title="download" text="Download" icon="fa-download" onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}/> </div> <div className="clearfix"/> @@ -32,10 +32,10 @@ export default connect( flow: state.flows.list.byId[state.flows.views.main.selected[0]], }), { - onAccept: flowsActions.accept, - onReplay: flowsActions.replay, - onDuplicate: flowsActions.duplicate, - onRemove: flowsActions.remove, - onRevert: flowsActions.revert, + acceptFlow: flowsActions.accept, + replayFlow: flowsActions.replay, + duplicateFlow: flowsActions.duplicate, + removeFlow: flowsActions.remove, + revertFlow: flowsActions.revert, } )(FlowMenu) diff --git a/web/src/js/components/Header/MainMenu.jsx b/web/src/js/components/Header/MainMenu.jsx index 1eb0acf2..48fea5a2 100644 --- a/web/src/js/components/Header/MainMenu.jsx +++ b/web/src/js/components/Header/MainMenu.jsx @@ -13,7 +13,7 @@ class MainMenu extends Component { query: PropTypes.object.isRequired, settings: PropTypes.object.isRequired, updateLocation: PropTypes.func.isRequired, - onSettingsChange: PropTypes.func.isRequired, + updateSettings: PropTypes.func.isRequired, } constructor(props, context) { @@ -31,7 +31,7 @@ class MainMenu extends Component { } render() { - const { query, settings, onSettingsChange } = this.props + const { query, settings, updateSettings } = this.props return ( <div> @@ -58,7 +58,7 @@ class MainMenu extends Component { type="pause" color="hsl(208, 56%, 53%)" value={settings.intercept || ''} - onChange={intercept => onSettingsChange({ intercept })} + onChange={intercept => updateSettings({ intercept })} /> </div> <div className="clearfix"></div> @@ -72,7 +72,7 @@ export default connect( settings: state.settings.settings, }), { - onSettingsChange: updateSettings, + updateSettings, }, null, { diff --git a/web/src/js/components/Header/ViewMenu.jsx b/web/src/js/components/Header/ViewMenu.jsx index 894fa71a..22b370d1 100644 --- a/web/src/js/components/Header/ViewMenu.jsx +++ b/web/src/js/components/Header/ViewMenu.jsx @@ -7,15 +7,15 @@ ViewMenu.title = 'View' ViewMenu.route = 'flows' ViewMenu.propTypes = { - visible: PropTypes.bool.isRequired, - onToggle: PropTypes.func.isRequired, + eventLogVisible: PropTypes.bool.isRequired, + toggleEventLog: PropTypes.func.isRequired, } -function ViewMenu({ visible, onToggle }) { +function ViewMenu({ eventLogVisible, toggleEventLog }) { return ( <div> <div className="menu-row"> - <ToggleButton text="Show Event Log" checked={visible} onToggle={onToggle} /> + <ToggleButton text="Show Event Log" checked={eventLogVisible} onToggle={toggleEventLog} /> </div> <div className="clearfix"></div> </div> @@ -24,9 +24,9 @@ function ViewMenu({ visible, onToggle }) { export default connect( state => ({ - visible: state.eventLog.visible, + eventLogVisible: state.eventLog.visible, }), { - onToggle: toggleVisibility, + toggleEventLog: toggleVisibility, } )(ViewMenu) diff --git a/web/src/js/components/MainView.jsx b/web/src/js/components/MainView.jsx index 5066d263..93f7b299 100644 --- a/web/src/js/components/MainView.jsx +++ b/web/src/js/components/MainView.jsx @@ -110,33 +110,33 @@ class MainView extends Component { break case Key.C: if (e.shiftKey) { - this.props.onClear() + this.props.clearFlows() } break case Key.D: if (flow) { if (e.shiftKey) { - this.props.onDuplicate(flow) + this.props.duplicateFlow(flow) } else { - this.props.onRemove(flow) + this.props.removeFlow(flow) } } break case Key.A: if (e.shiftKey) { - this.props.onAcceptAll() + this.props.acceptAllFlows() } else if (flow && flow.intercepted) { - this.props.onAccept(flow) + this.props.acceptFlow(flow) } break case Key.R: if (!e.shiftKey && flow) { - this.props.onReplay(flow) + this.props.replayFlow(flow) } break case Key.V: if (e.shiftKey && flow && flow.modified) { - this.props.onRevert(flow) + this.props.revertFlow(flow) } break case Key.E: @@ -147,6 +147,7 @@ class MainView extends Component { case Key.SHIFT: break default: + console.debug('keydown', e.keyCode) return } e.preventDefault() @@ -171,7 +172,7 @@ class MainView extends Component { tab={this.props.routeParams.detailTab} query={this.props.query} updateLocation={this.props.updateLocation} - onUpdate={attrs => this.props.onUpdate(selectedFlow, attrs)} + updateFlow={data => this.props.updateFlow(selectedFlow, data)} flow={selectedFlow} /> ]} @@ -191,14 +192,14 @@ export default connect( selectFlow, updateFilter, updateHighlight, - onUpdate: flowsActions.update, - onClear: flowsActions.clear, - onDuplicate: flowsActions.duplicate, - onRemove: flowsActions.remove, - onAcceptAll: flowsActions.acceptAll, - onAccept: flowsActions.accept, - onReplay: flowsActions.replay, - onRevert: flowsActions.revert, + updateFlow: flowsActions.update, + clearFlows: flowsActions.clear, + duplicateFlow: flowsActions.duplicate, + removeFlow: flowsActions.remove, + acceptAllFlows: flowsActions.acceptAll, + acceptFlow: flowsActions.accept, + replayFlow: flowsActions.replay, + revertFlow: flowsActions.revert, }, undefined, { withRef: true } diff --git a/web/src/js/ducks/eventLog.js b/web/src/js/ducks/eventLog.js index 50b24cd6..52eec1cd 100644 --- a/web/src/js/ducks/eventLog.js +++ b/web/src/js/ducks/eventLog.js @@ -17,8 +17,8 @@ const defaultState = { logId: 0, visible: false, filters: { debug: false, info: true, web: true }, - list: undefined, - view: undefined, + list: reduceList(undefined, {}), + view: reduceView(undefined, {}), } export default function reduce(state = defaultState, action) { @@ -40,7 +40,7 @@ export default function reduce(state = defaultState, action) { case ADD: const item = { - id: `log-${state.logId}`, + id: state.logId, message: action.message, level: action.level, } @@ -52,19 +52,14 @@ export default function reduce(state = defaultState, action) { } case RECEIVE: - const list = reduceList(state.list, listActions.receive(action.list)) return { ...state, - list, + list: reduceList(state.list, listActions.receive(action.list)), view: reduceView(state.view, viewActions.receive(list, log => state.filters[log.level])), } default: - return { - ...state, - list: reduceList(state.list, action), - view: reduceView(state.view, action), - } + return state } } diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index fc6b3f8c..f0b09530 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -112,8 +112,8 @@ export function revert(flow) { /** * @public */ -export function update(flow, body) { - fetchApi.put(`/flows/${flow.id}`, body) +export function update(flow, data) { + fetchApi.put(`/flows/${flow.id}`, data) return { type: REQUEST_ACTION } } @@ -139,7 +139,7 @@ export function download() { export function upload(file) { const body = new FormData() body.append('file', file) - fetchApi('/flows/dump', { method: 'post', body }) + fetchApi('/flows/dump', { method: 'post', body }) return { type: REQUEST_ACTION } } diff --git a/web/src/js/ducks/utils/list.js b/web/src/js/ducks/utils/list.js index a93b2d45..71042d91 100644 --- a/web/src/js/ducks/utils/list.js +++ b/web/src/js/ducks/utils/list.js @@ -26,6 +26,7 @@ export default function reduce(state = defaultState, action) { const data = [...state.data] const index = state.indexOf[action.id] + // FIXME: We should just swallow this if (index == null) { throw new Error('Item not found') } @@ -35,8 +36,7 @@ export default function reduce(state = defaultState, action) { return { ...state, data, - byId: { ...state.byId, [action.id]: null, [action.item.id]: action.item }, - indexOf: { ...state.indexOf, [action.id]: null, [action.item.id]: index }, + byId: { ...state.byId, [action.item.id]: action.item }, } } @@ -45,6 +45,7 @@ export default function reduce(state = defaultState, action) { const indexOf = { ...state.indexOf } const index = indexOf[action.id] + // FIXME: We should just swallow this if (index == null) { throw new Error('Item not found') } diff --git a/web/src/js/ducks/websocket.js b/web/src/js/ducks/websocket.js index aa0d7f7d..5ba7baef 100644 --- a/web/src/js/ducks/websocket.js +++ b/web/src/js/ducks/websocket.js @@ -79,7 +79,7 @@ export function onMessage(msg) { export function onDisconnect() { return dispatch => { - dispatch(eventLogActions.addLogEntry('WebSocket connection closed.')) + dispatch(eventLogActions.add('WebSocket connection closed.')) dispatch({ type: DISCONNECTED }) } } @@ -87,7 +87,7 @@ export function onDisconnect() { export function onError(error) { // @todo let event log subscribe WebSocketActions.ERROR return dispatch => { - dispatch(eventLogActions.addLogEntry('WebSocket connection error.')) + dispatch(eventLogActions.add('WebSocket connection error.')) dispatch({ type: ERROR, error }) } } |