diff options
author | Jason <jason.daurus@gmail.com> | 2016-06-25 02:18:52 +0800 |
---|---|---|
committer | Jason <jason.daurus@gmail.com> | 2016-06-25 02:18:52 +0800 |
commit | 2b7923b4f41ec6f8d08c17b2c4a4930e95387e1c (patch) | |
tree | d576bb9705f7c3eeaa98ecfa6b829101b180fbf9 /web/src/js | |
parent | 8da623c60389bffc76dd3c1b6d8055dd19f97607 (diff) | |
download | mitmproxy-2b7923b4f41ec6f8d08c17b2c4a4930e95387e1c.tar.gz mitmproxy-2b7923b4f41ec6f8d08c17b2c4a4930e95387e1c.tar.bz2 mitmproxy-2b7923b4f41ec6f8d08c17b2c4a4930e95387e1c.zip |
[web] fix actions
Diffstat (limited to 'web/src/js')
-rw-r--r-- | web/src/js/components/FlowView.jsx | 4 | ||||
-rw-r--r-- | web/src/js/components/FlowView/Messages.jsx | 44 | ||||
-rw-r--r-- | web/src/js/components/FlowView/Nav.jsx | 31 | ||||
-rw-r--r-- | web/src/js/components/Header.jsx | 8 | ||||
-rw-r--r-- | web/src/js/components/Header/FileMenu.jsx | 20 | ||||
-rw-r--r-- | web/src/js/components/Header/FlowMenu.jsx | 25 | ||||
-rw-r--r-- | web/src/js/components/Header/MainMenu.jsx | 6 | ||||
-rw-r--r-- | web/src/js/components/Header/OptionMenu.jsx | 2 | ||||
-rw-r--r-- | web/src/js/components/MainView.jsx | 26 | ||||
-rwxr-xr-x | web/src/js/components/Prompt.jsx | 6 | ||||
-rw-r--r-- | web/src/js/components/ProxyApp.jsx | 9 | ||||
-rw-r--r-- | web/src/js/ducks/flows.js | 18 | ||||
-rw-r--r-- | web/src/js/ducks/settings.js | 11 |
13 files changed, 127 insertions, 83 deletions
diff --git a/web/src/js/components/FlowView.jsx b/web/src/js/components/FlowView.jsx index 23f8b3ea..a94458a1 100644 --- a/web/src/js/components/FlowView.jsx +++ b/web/src/js/components/FlowView.jsx @@ -75,7 +75,7 @@ export default class FlowView extends Component { render() { const tabs = this.getTabs() - let { flow, tab: active } = this.props + let { flow, tab: active, onUpdate } = 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}/> + <Tab ref="tab" flow={flow} onUpdate={onUpdate} /> {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 ba6a5f2b..5321edd6 100644 --- a/web/src/js/components/FlowView/Messages.jsx +++ b/web/src/js/components/FlowView/Messages.jsx @@ -1,7 +1,6 @@ -import React, { Component } from 'react' +import React, { Component, PropTypes } from 'react' import _ from 'lodash' -import { FlowActions } from '../../actions.js' import { RequestUtils, isValidHttpVersion, parseUrl, parseHttpVersion } from '../../flow/utils.js' import { Key, formatTimeStamp } from '../../utils.js' import ContentView from '../ContentView' @@ -11,21 +10,21 @@ import Headers from './Headers' class RequestLine extends Component { render() { - const { flow } = this.props + const { flow, onUpdate } = this.props return ( <div className="first-line request-line"> <ValueEditor ref="method" content={flow.request.method} - onDone={method => FlowActions.update(flow, { request: { method } })} + onDone={method => onUpdate({ request: { method } })} inline /> <ValueEditor ref="url" content={RequestUtils.pretty_url(flow.request)} - onDone={url => FlowActions.update(flow, { request: Object.assign({ path: '' }, parseUrl(url)) })} + onDone={url => onUpdate({ request: Object.assign({ path: '' }, parseUrl(url)) })} isValid={url => !!parseUrl(url).host} inline /> @@ -33,7 +32,7 @@ class RequestLine extends Component { <ValueEditor ref="httpVersion" content={flow.request.http_version} - onDone={ver => FlowActions.update(flow, { request: { http_version: parseHttpVersion(ver) } })} + onDone={ver => onUpdate({ request: { http_version: parseHttpVersion(ver) } })} isValid={isValidHttpVersion} inline /> @@ -45,14 +44,14 @@ class RequestLine extends Component { class ResponseLine extends Component { render() { - const { flow } = this.props + const { flow, onUpdate } = this.props return ( <div className="first-line response-line"> <ValueEditor ref="httpVersion" content={flow.response.http_version} - onDone={nextVer => FlowActions.update(flow, { response: { http_version: parseHttpVersion(nextVer) } })} + onDone={nextVer => onUpdate({ response: { http_version: parseHttpVersion(nextVer) } })} isValid={isValidHttpVersion} inline /> @@ -60,7 +59,7 @@ class ResponseLine extends Component { <ValueEditor ref="code" content={flow.response.status_code + ''} - onDone={code => FlowActions.update(flow, { response: { code: parseInt(code) } })} + onDone={code => onUpdate({ response: { code: parseInt(code) } })} isValid={code => /^\d+$/.test(code)} inline /> @@ -68,7 +67,7 @@ class ResponseLine extends Component { <ValueEditor ref="msg" content={flow.response.reason} - onDone={msg => FlowActions.update(flow, { response: { msg } })} + onDone={msg => onUpdate({ response: { msg } })} inline /> </div> @@ -79,15 +78,15 @@ class ResponseLine extends Component { export class Request extends Component { render() { - const { flow } = this.props + const { flow, onUpdate } = this.props return ( <section className="request"> - <RequestLine ref="requestLine" flow={flow}/> + <RequestLine ref="requestLine" flow={flow} onUpdate={onUpdate} /> <Headers ref="headers" message={flow.request} - onChange={headers => FlowActions.update(flow, { request: { headers } })} + onChange={headers => onUpdate({ request: { headers } })} /> <hr/> <ContentView flow={flow} message={flow.request}/> @@ -118,15 +117,15 @@ export class Request extends Component { export class Response extends Component { render() { - const { flow } = this.props + const { flow, onUpdate } = this.props return ( <section className="response"> - <ResponseLine ref="responseLine" flow={flow}/> + <ResponseLine ref="responseLine" flow={flow} onUpdate={onUpdate} /> <Headers ref="headers" message={flow.response} - onChange={headers => FlowActions.update(flow, { response: { headers } })} + onChange={headers => onUpdate({ response: { headers } })} /> <hr/> <ContentView flow={flow} message={flow.response}/> @@ -153,16 +152,3 @@ export class Response extends Component { } } } - -export function Error({ flow }) { - return ( - <section> - <div className="alert alert-warning"> - {flow.error.msg} - <div> - <small>{formatTimeStamp(flow.error.timestamp)}</small> - </div> - </div> - </section> - ) -} diff --git a/web/src/js/components/FlowView/Nav.jsx b/web/src/js/components/FlowView/Nav.jsx index 386c3a6c..b9e15d92 100644 --- a/web/src/js/components/FlowView/Nav.jsx +++ b/web/src/js/components/FlowView/Nav.jsx @@ -1,6 +1,7 @@ import React, { PropTypes } from 'react' +import { connect } from 'react-redux' import classnames from 'classnames' -import { FlowActions } from '../../actions.js' +import * as flowsActions from '../../ducks/flows' NavAction.propTypes = { icon: PropTypes.string.isRequired, @@ -27,9 +28,14 @@ Nav.propTypes = { 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, } -export default function Nav({ flow, active, tabs, onSelectTab }) { +function Nav({ flow, active, tabs, onSelectTab, onRemove, onDuplicate, onReplay, onAccept, onRevert }) { return ( <nav className="nav-tabs nav-tabs-sm"> {tabs.map(tab => ( @@ -43,15 +49,26 @@ export default function Nav({ flow, active, tabs, onSelectTab }) { {_.capitalize(tab)} </a> ))} - <NavAction title="[d]elete flow" icon="fa-trash" onClick={() => FlowActions.delete(flow)} /> - <NavAction title="[D]uplicate flow" icon="fa-copy" onClick={() => FlowActions.duplicate(flow)} /> - <NavAction disabled title="[r]eplay flow" icon="fa-repeat" onClick={() => FlowActions.replay(flow)} /> + <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={() => FlowActions.accept(flow)} /> + <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={() => FlowActions.revert(flow)} /> + <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.jsx b/web/src/js/components/Header.jsx index 545684bb..b6ef1cc7 100644 --- a/web/src/js/components/Header.jsx +++ b/web/src/js/components/Header.jsx @@ -14,8 +14,6 @@ class Header extends Component { handleClick(active, e) { e.preventDefault() this.props.setActiveMenu(active.title) - // this.props.updateLocation(active.route) - // this.setState({ active }) } render() { @@ -42,6 +40,7 @@ class Header extends Component { </nav> <div className="menu"> <Active + ref="active" updateLocation={updateLocation} query={query} /> @@ -50,6 +49,7 @@ class Header extends Component { ) } } + export default connect( state => ({ selectedFlow: state.flows.views.main.selected[0], @@ -57,5 +57,9 @@ export default connect( }), { setActiveMenu, + }, + null, + { + withRef: true, } )(Header) diff --git a/web/src/js/components/Header/FileMenu.jsx b/web/src/js/components/Header/FileMenu.jsx index e1c62e28..a4466784 100644 --- a/web/src/js/components/Header/FileMenu.jsx +++ b/web/src/js/components/Header/FileMenu.jsx @@ -1,8 +1,9 @@ import React, { Component } from 'react' +import { connect } from 'react-redux' import classnames from 'classnames' -import * as flowActions from '../../ducks/flows' +import * as flowsActions from '../../ducks/flows' -export default class FileMenu extends Component { +class FileMenu extends Component { constructor(props, context) { super(props, context) @@ -35,7 +36,7 @@ export default class FileMenu extends Component { onNewClick(e) { e.preventDefault() if (confirm('Delete all flows?')) { - flowActions.clear() + this.props.onClear() } } @@ -47,14 +48,14 @@ export default class FileMenu extends Component { onOpenFile(e) { e.preventDefault() if (e.target.files.length > 0) { - flowActions.upload(e.target.files[0]) + this.props.onUpload(e.target.files[0]) this.fileInput.value = '' } } onSaveClick(e) { e.preventDefault() - flowActions.download() + this.props.onDownload() } render() { @@ -98,3 +99,12 @@ export default class FileMenu extends Component { ) } } + +export default connect( + null, + { + onClear: flowsActions.clear, + onUpload: flowsActions.upload, + onDownload: flowsActions.download, + } +)(FileMenu) diff --git a/web/src/js/components/Header/FlowMenu.jsx b/web/src/js/components/Header/FlowMenu.jsx index 1fa7037f..ba1dcbcb 100644 --- a/web/src/js/components/Header/FlowMenu.jsx +++ b/web/src/js/components/Header/FlowMenu.jsx @@ -1,8 +1,8 @@ import React, { PropTypes } from 'react' +import { connect } from 'react-redux' import Button from '../common/Button' -import { FlowActions } from '../../actions.js' import { MessageUtils } from '../../flow/utils.js' -import { connect } from 'react-redux' +import * as flowsActions from '../../ducks/flows' FlowMenu.title = 'Flow' @@ -10,16 +10,16 @@ FlowMenu.propTypes = { flow: PropTypes.object.isRequired, } -function FlowMenu({ flow }) { +function FlowMenu({ flow, onAccept, onReplay, onDuplicate, onRemove, onRevert }) { return ( <div> <div className="menu-row"> - <Button disabled={!flow.intercepted} title="[a]ccept intercepted flow" text="Accept" icon="fa-play" onClick={() => FlowActions.accept(flow)} /> - <Button title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={FlowActions.replay.bind(null, flow)} /> - <Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={FlowActions.duplicate.bind(null, flow)} /> - <Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={FlowActions.delete.bind(null, flow)}/> - <Button disabled={!flow.modified} title="revert changes to flow [V]" text="Revert" icon="fa-history" onClick={() => FlowActions.revert(flow)} /> + <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 title="download" text="Download" icon="fa-download" onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}/> </div> <div className="clearfix"/> @@ -30,5 +30,12 @@ function FlowMenu({ flow }) { export default connect( state => ({ 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, + } )(FlowMenu) diff --git a/web/src/js/components/Header/MainMenu.jsx b/web/src/js/components/Header/MainMenu.jsx index a466a980..1eb0acf2 100644 --- a/web/src/js/components/Header/MainMenu.jsx +++ b/web/src/js/components/Header/MainMenu.jsx @@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react' import { connect } from 'react-redux' import FilterInput from './FilterInput' import { Query } from '../../actions.js' -import { updateSettings } from '../../ducks/settings' +import { update as updateSettings } from '../../ducks/settings' class MainMenu extends Component { @@ -73,5 +73,9 @@ export default connect( }), { onSettingsChange: updateSettings, + }, + null, + { + withRef: true, } )(MainMenu); diff --git a/web/src/js/components/Header/OptionMenu.jsx b/web/src/js/components/Header/OptionMenu.jsx index f871ec92..4a487cc9 100644 --- a/web/src/js/components/Header/OptionMenu.jsx +++ b/web/src/js/components/Header/OptionMenu.jsx @@ -2,7 +2,7 @@ import React, { PropTypes } from 'react' import { connect } from 'react-redux' import ToggleButton from '../common/ToggleButton' import ToggleInputButton from '../common/ToggleInputButton' -import { updateSettings } from '../../ducks/settings' +import { update as updateSettings } from '../../ducks/settings' OptionMenu.title = 'Options' diff --git a/web/src/js/components/MainView.jsx b/web/src/js/components/MainView.jsx index 847223d2..5066d263 100644 --- a/web/src/js/components/MainView.jsx +++ b/web/src/js/components/MainView.jsx @@ -1,11 +1,11 @@ import React, { Component, PropTypes } from 'react' import { connect } from 'react-redux' -import { FlowActions } from '../actions.js' import { Query } from '../actions.js' import { Key } from '../utils.js' import Splitter from './common/Splitter' import FlowTable from './FlowTable' import FlowView from './FlowView' +import * as flowsActions from '../ducks/flows' import { select as selectFlow, updateFilter, updateHighlight } from '../ducks/views/main' class MainView extends Component { @@ -110,33 +110,33 @@ class MainView extends Component { break case Key.C: if (e.shiftKey) { - FlowActions.clear() + this.props.onClear() } break case Key.D: if (flow) { if (e.shiftKey) { - FlowActions.duplicate(flow) + this.props.onDuplicate(flow) } else { - FlowActions.delete(flow) + this.props.onRemove(flow) } } break case Key.A: if (e.shiftKey) { - FlowActions.accept_all() + this.props.onAcceptAll() } else if (flow && flow.intercepted) { - FlowActions.accept(flow) + this.props.onAccept(flow) } break case Key.R: if (!e.shiftKey && flow) { - FlowActions.replay(flow) + this.props.onReplay(flow) } break case Key.V: if (e.shiftKey && flow && flow.modified) { - FlowActions.revert(flow) + this.props.onRevert(flow) } break case Key.E: @@ -147,7 +147,6 @@ class MainView extends Component { case Key.SHIFT: break default: - console.debug('keydown', e.keyCode) return } e.preventDefault() @@ -172,6 +171,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)} flow={selectedFlow} /> ]} @@ -191,6 +191,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, }, undefined, { withRef: true } diff --git a/web/src/js/components/Prompt.jsx b/web/src/js/components/Prompt.jsx index 6b19b3b3..701a0b85 100755 --- a/web/src/js/components/Prompt.jsx +++ b/web/src/js/components/Prompt.jsx @@ -37,7 +37,7 @@ export default function Prompt({ prompt, done, options }, context) { } return ( - <div tabIndex="0" onKeyDown={onKeyDown} onClick={onClick} className="prompt-dialog"> + <div tabIndex="0" onKeyDown={onKeyDown} className="prompt-dialog"> <div className="prompt-content"> {prompt || <strong>Select: </strong> } {opts.map(opt => { @@ -49,7 +49,7 @@ export default function Prompt({ prompt, done, options }, context) { return ( <span key={opt.key} className="option" onClick={onClick}> {idx !== -1 ? opt.text.substring(0, idx) : opt.text + '('} - {prefix}<strong className="text-primary">{opt.key}</strong> + <strong className="text-primary">{opt.key}</strong> {idx !== -1 ? opt.text.substring(idx + 1) : ')'} </span> ) @@ -65,7 +65,7 @@ export default function Prompt({ prompt, done, options }, context) { if (!key && event.keyCode !== Key.ESC && event.keyCode !== Key.ENTER) { return } - done(k || false) + done(key.key || false) context.returnFocus() } } diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx index 84564c32..1ac979bc 100644 --- a/web/src/js/components/ProxyApp.jsx +++ b/web/src/js/components/ProxyApp.jsx @@ -77,8 +77,8 @@ class ProxyAppMain extends Component { break default: let main = this.refs.view - if (this.refs.view.getWrappedInstance) { - main = this.refs.view.getWrappedInstance() + if (this.refs.view.refs.wrappedInstance) { + main = this.refs.view.refs.wrappedInstance } if (main.onMainKeyDown) { main.onMainKeyDown(e) @@ -87,9 +87,10 @@ class ProxyAppMain extends Component { } if (name) { - const headerComponent = this.refs.header + const headerComponent = this.refs.header.refs.wrappedInstance || this.refs.header headerComponent.setState({ active: Header.entries[0] }, () => { - headerComponent.refs.active.refs[name].select() + const active = headerComponent.refs.active.refs.wrappedInstance || headerComponent.refs.active + active.refs[name].select() }) } diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js index e9ac38f6..fc6b3f8c 100644 --- a/web/src/js/ducks/flows.js +++ b/web/src/js/ducks/flows.js @@ -40,8 +40,8 @@ export default function reduce(state = defaultState, action) { case REMOVE: return { ...state, - list: reduceList(state.list, listActions.remove(action.item.id)), - views: reduceViews(state.views, viewsActions.remove(action.item.id)), + list: reduceList(state.list, listActions.remove(action.id)), + views: reduceViews(state.views, viewsActions.remove(action.id)), } case RECEIVE: @@ -113,7 +113,7 @@ export function revert(flow) { * @public */ export function update(flow, body) { - fetchApi(`/flows/${flow.id}`, { method: 'PUT', body }) + fetchApi.put(`/flows/${flow.id}`, body) return { type: REQUEST_ACTION } } @@ -152,13 +152,13 @@ export function handleWsMsg(msg) { switch (msg.cmd) { case websocketActions.CMD_ADD: - return add(msg.data) + return addItem(msg.data) case websocketActions.CMD_UPDATE: - return update(msg.data.id, msg.data) + return updateItem(msg.data.id, msg.data) case websocketActions.CMD_REMOVE: - return remove(msg.data.id) + return removeItem(msg.data.id) case websocketActions.CMD_RESET: return fetchData() @@ -185,20 +185,20 @@ export function receiveData(list) { /** * @private */ -export function add(item) { +export function addItem(item) { return { type: ADD, item } } /** * @private */ -export function update(id, item) { +export function updateItem(id, item) { return { type: UPDATE, id, item } } /** * @private */ -export function remove(id) { +export function removeItem(id) { return { type: REMOVE, id } } diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 7101aa1e..b2ce9085 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -40,7 +40,7 @@ export function handleWsMsg(msg) { switch (msg.cmd) { case websocketActions.CMD_UPDATE: - return { type: UPDATE, settings: msg.data } + return updateSettings(msg.data) default: console.error('unknown settings update', msg) @@ -51,7 +51,7 @@ export function handleWsMsg(msg) { /** * @public */ -export function updateSettings(settings) { +export function update(settings) { fetchApi.put('/settings', settings) return { type: REQUEST_UPDATE } } @@ -69,3 +69,10 @@ export function fetchData() { export function receiveData(settings) { return { type: RECEIVE, settings } } + +/** + * @private + */ +export function updateSettings(settings) { + return { type: UPDATE, settings } +} |