aboutsummaryrefslogtreecommitdiffstats
path: root/web/src
diff options
context:
space:
mode:
authorClemens <cle1000.cb@gmail.com>2016-07-19 12:23:20 +0200
committerClemens <cle1000.cb@gmail.com>2016-07-19 12:23:20 +0200
commit48728af43ad746d70ef3e251dc28b75028dea1e6 (patch)
tree77b8b1eef4845c5bcc641d748435a32558c5d089 /web/src
parent87797d7ac07108ce5fd00902918e4900907b94b6 (diff)
downloadmitmproxy-48728af43ad746d70ef3e251dc28b75028dea1e6.tar.gz
mitmproxy-48728af43ad746d70ef3e251dc28b75028dea1e6.tar.bz2
mitmproxy-48728af43ad746d70ef3e251dc28b75028dea1e6.zip
moved flow editor state to redux
Diffstat (limited to 'web/src')
-rw-r--r--web/src/css/codemirror.less4
-rw-r--r--web/src/css/flowview.less9
-rw-r--r--web/src/js/components/ContentView.jsx32
-rw-r--r--web/src/js/components/ContentView/ContentEditor.jsx36
-rw-r--r--web/src/js/components/FlowView/FlowEditorButton.jsx48
-rw-r--r--web/src/js/components/FlowView/Messages.jsx15
-rw-r--r--web/src/js/components/common/CodeEditor.jsx12
-rw-r--r--web/src/js/components/common/Splitter.jsx1
-rw-r--r--web/src/js/ducks/flows.js19
9 files changed, 118 insertions, 58 deletions
diff --git a/web/src/css/codemirror.less b/web/src/css/codemirror.less
index 47c766f4..6504db50 100644
--- a/web/src/css/codemirror.less
+++ b/web/src/css/codemirror.less
@@ -2,4 +2,8 @@
border: 1px solid #ccc;
}
+.CodeMirror{
+ height: auto !important;
+ max-height: 1000px !important;
+}
@import (inline) "../../node_modules/codemirror/lib/codemirror.css";
diff --git a/web/src/css/flowview.less b/web/src/css/flowview.less
index 328e3a26..419739a4 100644
--- a/web/src/css/flowview.less
+++ b/web/src/css/flowview.less
@@ -8,13 +8,18 @@
}
}
+.edit-flow-container {
+ position: relative;
+}
+
.edit-flow {
position: absolute;
- right: 25px;
- top: 140px;
+ right: 0px;
+ top: 5px;
height: 40px;
width: 40px;
border-radius: 20px;
+ z-index: 10000;
background-color: white;
border: solid 2px rgba(248, 145, 59, 0.7);
diff --git a/web/src/js/components/ContentView.jsx b/web/src/js/components/ContentView.jsx
index 70bca249..3cd9990c 100644
--- a/web/src/js/components/ContentView.jsx
+++ b/web/src/js/components/ContentView.jsx
@@ -1,12 +1,15 @@
import React, { Component, PropTypes } from 'react'
+import { connect } from 'react-redux'
import { MessageUtils } from '../flow/utils.js'
import { ViewAuto, ViewImage } from './ContentView/ContentViews'
import * as MetaViews from './ContentView/MetaViews'
import ContentLoader from './ContentView/ContentLoader'
import ViewSelector from './ContentView/ViewSelector'
-import ContentEditor from './ContentView/ContentEditor'
+import CodeEditor from './common/CodeEditor'
+import {setModifiedFlowContent} from '../ducks/flows'
-export default class ContentView extends Component {
+
+class ContentView extends Component {
static propTypes = {
// It may seem a bit weird at the first glance:
@@ -19,8 +22,7 @@ export default class ContentView extends Component {
constructor(props, context) {
super(props, context)
-
- this.state = { displayLarge: false, View: ViewAuto, contentEditorClosed: true }
+ this.state = { displayLarge: false, View: ViewAuto}
this.selectView = this.selectView.bind(this)
}
@@ -50,7 +52,7 @@ export default class ContentView extends Component {
}
render() {
- const { flow, message } = this.props
+ const { flow, message, setModifiedFlowContent, isFlowEditorOpen } = this.props
const { displayLarge, View } = this.state
if (message.contentLength === 0) {
@@ -67,15 +69,11 @@ export default class ContentView extends Component {
return (
<div>
- <ContentLoader flow={flow} message={message}>
- <ContentEditor
- onSave={content => {this.props.onContentChange(content);this.setState({contentEditorClosed : true});}}
- onOpen={() => this.setState({contentEditorClosed : false})}
- isClosed={this.state.contentEditorClosed}
- content=""
- />
- </ContentLoader>
- {this.state.contentEditorClosed && (<div>
+ {isFlowEditorOpen ? (
+ <ContentLoader flow={flow} message={message}>
+ <CodeEditor content="" onChange={content =>{setModifiedFlowContent(content)}}/>
+ </ContentLoader>
+ ): (<div>
{View.textView ? (
<ContentLoader flow={flow} message={message}>
<this.state.View content="" />
@@ -115,3 +113,9 @@ export default class ContentView extends Component {
)
}
}
+export default connect(
+ state => (
+ {isFlowEditorOpen : state.ui.isFlowEditorOpen}
+ ), {
+ setModifiedFlowContent
+ })(ContentView)
diff --git a/web/src/js/components/ContentView/ContentEditor.jsx b/web/src/js/components/ContentView/ContentEditor.jsx
deleted file mode 100644
index ca2f3370..00000000
--- a/web/src/js/components/ContentView/ContentEditor.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React, { Component, PropTypes } from 'react'
-import CodeEditor from '../common/CodeEditor'
-
-export default class ContentEditor extends Component {
-
- static propTypes = {
- content: PropTypes.string.isRequired,
- onSave: PropTypes.func.isRequired,
- onOpen: PropTypes.func.isRequired,
- isClosed: PropTypes.bool.isRequired
- }
-
- constructor(props){
- super(props)
- this.state = {content: this.props.content}
- }
-
- render() {
- return (
- <div>
- {this.props.isClosed ?
- <a className="edit-flow" onClick={this.props.onOpen}>
- <i className="fa fa-pencil"/>
- </a> :
- <a className="edit-flow" onClick={() => this.props.onSave(this.state.content)}>
- <i className="fa fa-check"/>
- </a>
- }
- {!this.props.isClosed &&
- <CodeEditor value={this.state.content} onChange={content => this.setState({content: content})}/>
- }
- </div>
-
- )
- }
-}
diff --git a/web/src/js/components/FlowView/FlowEditorButton.jsx b/web/src/js/components/FlowView/FlowEditorButton.jsx
new file mode 100644
index 00000000..e9c75535
--- /dev/null
+++ b/web/src/js/components/FlowView/FlowEditorButton.jsx
@@ -0,0 +1,48 @@
+import React, { PropTypes, Component } from 'react'
+import { connect } from 'react-redux'
+
+import {closeFlowEditor} from '../../ducks/ui.js'
+import {openFlowEditor} from '../../ducks/ui.js'
+
+// FlowEditorButton.propTypes = {
+// isFlowEditorOpen: PropTypes.bool.isRequired,
+// content: PropTypes.string.isRequired,
+// onContentChange: PropTypes.func.isRequired
+// }
+
+class FlowEditorButton extends Component{
+ static propTypes = {
+ isFlowEditorOpen: PropTypes.bool.isRequired,
+ content: PropTypes.string.isRequired,
+ onContentChange: PropTypes.func.isRequired
+ }
+
+ render(){
+ let { isFlowEditorOpen, closeFlowEditor, openFlowEditor, onContentChange, content } = this.props
+ return (
+ <div className="edit-flow-container">
+ {isFlowEditorOpen ?
+ <a className="edit-flow" onClick={() => {onContentChange(content); closeFlowEditor()}}>
+ <i className="fa fa-check"/>
+ </a>
+ :
+ <a className="edit-flow" onClick={() => openFlowEditor()}>
+ <i className="fa fa-pencil"/>
+ </a>
+ }
+ </div>
+ )
+ }
+}
+
+export default connect(
+ state => ({
+ isFlowEditorOpen: state.ui.isFlowEditorOpen,
+ content: state.flows.modifiedFlow.content
+ }),
+ {
+ closeFlowEditor,
+ openFlowEditor
+
+ }
+)(FlowEditorButton)
diff --git a/web/src/js/components/FlowView/Messages.jsx b/web/src/js/components/FlowView/Messages.jsx
index 27e18c05..8cb918a8 100644
--- a/web/src/js/components/FlowView/Messages.jsx
+++ b/web/src/js/components/FlowView/Messages.jsx
@@ -7,6 +7,8 @@ import ContentView from '../ContentView'
import ValueEditor from '../ValueEditor'
import Headers from './Headers'
import * as flowActions from '../../ducks/flows'
+import FlowEditorButton from './FlowEditorButton.jsx'
+
class RequestLine extends Component {
@@ -77,21 +79,23 @@ class ResponseLine extends Component {
}
export class Request extends Component {
-
- render() {
+ render() {
const { flow, updateFlow } = this.props
+ let onContentChange = content => flowActions.updateContent(this.props.flow, content, "request")
return (
<section className="request">
+ <FlowEditorButton onContentChange={onContentChange}/>
<RequestLine ref="requestLine" flow={flow} updateFlow={updateFlow} />
<Headers
ref="headers"
message={flow.request}
onChange={headers => updateFlow({ request: { headers } })}
/>
+
<hr/>
<ContentView flow={flow}
- onContentChange={content => flowActions.updateContent(this.props.flow, content, "request") }
+ onContentChange={onContentChange}
message={flow.request}
/>
</section>
@@ -120,11 +124,14 @@ export class Request extends Component {
export class Response extends Component {
+
render() {
const { flow, updateFlow } = this.props
+ let onContentChange = content => flowActions.updateContent(this.props.flow, content, "response")
return (
<section className="response">
+ <FlowEditorButton onContentChange={onContentChange}/>
<ResponseLine ref="responseLine" flow={flow} updateFlow={updateFlow} />
<Headers
ref="headers"
@@ -133,7 +140,7 @@ export class Response extends Component {
/>
<hr/>
<ContentView flow={flow}
- onContentChange={content => flowActions.updateContent(this.props.flow, content, "response") }
+ onContentChange={onContentChange}
message={flow.response}
/>
</section>
diff --git a/web/src/js/components/common/CodeEditor.jsx b/web/src/js/components/common/CodeEditor.jsx
index c122cf94..5b2305a8 100644
--- a/web/src/js/components/common/CodeEditor.jsx
+++ b/web/src/js/components/common/CodeEditor.jsx
@@ -5,17 +5,25 @@ import Codemirror from 'react-codemirror';
export default class CodeEditor extends Component{
static propTypes = {
- value: PropTypes.string.isRequired,
+ content: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
}
+ constructor(props){
+ super(props)
+ }
+
+ componentWillMount(){
+ this.props.onChange(this.props.content)
+ }
+
render() {
let options = {
lineNumbers: true
};
return (
<div onKeyDown={e => e.stopPropagation()}>
- <Codemirror value={this.props.value} onChange={this.props.onChange} options={options}/>
+ <Codemirror value={this.props.content} onChange={this.props.onChange} options={options}/>
</div>
)
}
diff --git a/web/src/js/components/common/Splitter.jsx b/web/src/js/components/common/Splitter.jsx
index 9d22b6fd..bd4fb3d2 100644
--- a/web/src/js/components/common/Splitter.jsx
+++ b/web/src/js/components/common/Splitter.jsx
@@ -12,6 +12,7 @@ export default class Splitter extends Component {
this.state = { applied: false, startX: false, startY: false }
this.onMouseMove = this.onMouseMove.bind(this)
+ this.onMouseDown = this.onMouseDown.bind(this)
this.onMouseUp = this.onMouseUp.bind(this)
this.onDragEnd = this.onDragEnd.bind(this)
}
diff --git a/web/src/js/ducks/flows.js b/web/src/js/ducks/flows.js
index 3dd21016..eea91924 100644
--- a/web/src/js/ducks/flows.js
+++ b/web/src/js/ducks/flows.js
@@ -14,10 +14,12 @@ 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'
+export const SET_MODIFIED_FLOW_CONTENT = "FLOWS_SET_MODIFIED_FLOW"
const defaultState = {
list: undefined,
views: undefined,
+ modifiedFlow: {headers: "", content: ""}
}
export default function reduce(state = defaultState, action) {
@@ -51,6 +53,12 @@ export default function reduce(state = defaultState, action) {
list,
views: reduceViews(state.views, viewsActions.receive(list)),
}
+ case SET_MODIFIED_FLOW_CONTENT:
+ return{
+ ...state,
+ modifiedFlow: {...state.modifiedFlow, content: action.content}
+ }
+
default:
return {
@@ -64,6 +72,17 @@ export default function reduce(state = defaultState, action) {
/**
* @public
*/
+export function setModifiedFlowContent(content) {
+ return {
+ type: SET_MODIFIED_FLOW_CONTENT,
+ content
+ }
+}
+
+
+/**
+ * @public
+ */
export function accept(flow) {
fetchApi(`/flows/${flow.id}/accept`, { method: 'POST' })
return { type: REQUEST_ACTION }