aboutsummaryrefslogtreecommitdiffstats
path: root/web/src
diff options
context:
space:
mode:
Diffstat (limited to 'web/src')
-rw-r--r--web/src/css/flowdetail.less31
-rw-r--r--web/src/js/components/ContentView.jsx18
-rw-r--r--web/src/js/components/ContentView/ContentViewOptions.jsx31
-rw-r--r--web/src/js/components/ContentView/ContentViews.jsx13
-rw-r--r--web/src/js/components/FlowView.jsx2
-rw-r--r--web/src/js/components/FlowView/Messages.jsx96
6 files changed, 121 insertions, 70 deletions
diff --git a/web/src/css/flowdetail.less b/web/src/css/flowdetail.less
index b4c7047b..421630eb 100644
--- a/web/src/css/flowdetail.less
+++ b/web/src/css/flowdetail.less
@@ -5,8 +5,7 @@
.flow-detail {
width: 100%;
- overflow-x: auto;
- overflow-y: scroll;
+ overflow:hidden;
nav {
background-color: #F2F2F2;
@@ -41,6 +40,28 @@
}
+.flowview-container{
+ display: flex;
+ flex-direction: column;
+ padding: 0 !important;
+ height:95%;
+}
+
+.flowview-body{
+ position:relative;
+ flex: 1 1 auto;
+ overflow: auto;
+ padding: 5px 12px 0;
+}
+
+.flowview-footer{
+ flex: 0 0 auto;
+ box-shadow: 0 0 3px gray;
+ padding: 2px;
+ margin: 0;
+ height:23px;
+}
+
.inline-input {
display: inline;
margin: 0 -3px;
@@ -64,13 +85,9 @@
}
}
-.view-options {
- margin-bottom: 10px;
- margin-top: 10px;
-}
-
.view-all-content-btn{
float: right;
+ margin-bottom: 12px;
}
.flow-detail table {
diff --git a/web/src/js/components/ContentView.jsx b/web/src/js/components/ContentView.jsx
index 128d8e81..398438ab 100644
--- a/web/src/js/components/ContentView.jsx
+++ b/web/src/js/components/ContentView.jsx
@@ -2,12 +2,10 @@ import React, { Component, PropTypes } from 'react'
import { connect } from 'react-redux'
import * as ContentViews from './ContentView/ContentViews'
import * as MetaViews from './ContentView/MetaViews'
-import ViewSelector from './ContentView/ViewSelector'
-import UploadContentButton from './ContentView/UploadContentButton'
-import DownloadContentButton from './ContentView/DownloadContentButton'
import ShowFullContentButton from './ContentView/ShowFullContentButton'
-import { setContentView, displayLarge, updateEdit } from '../ducks/ui/flow'
+
+import { displayLarge, updateEdit } from '../ducks/ui/flow'
ContentView.propTypes = {
// It may seem a bit weird at the first glance:
@@ -20,7 +18,7 @@ ContentView.propTypes = {
ContentView.isContentTooLarge = msg => msg.contentLength > 1024 * 1024 * (ContentViews.ViewImage.matches(msg) ? 10 : 0.2)
function ContentView(props) {
- const { flow, message, contentView, isDisplayLarge, displayLarge, uploadContent, onContentChange, readonly, contentViewDescription } = props
+ const { flow, message, contentView, isDisplayLarge, displayLarge, onContentChange, readonly } = props
if (message.contentLength === 0 && readonly) {
return <MetaViews.ContentEmpty {...props}/>
@@ -39,15 +37,6 @@ function ContentView(props) {
<div className="contentview">
<View flow={flow} message={message} contentView={contentView} readonly={readonly} onChange={onContentChange}/>
<ShowFullContentButton/>
- <div className="view-options footer navbar-fixed-bottom">
- <ViewSelector message={message}/>
- &nbsp;
- <DownloadContentButton flow={flow} message={message}/>
- &nbsp;
- <UploadContentButton uploadContent={uploadContent}/>
- &nbsp;
- <span>{contentViewDescription}</span>
- </div>
</div>
)
}
@@ -56,7 +45,6 @@ export default connect(
state => ({
contentView: state.ui.flow.contentView,
isDisplayLarge: state.ui.flow.displayLarge,
- contentViewDescription: state.ui.flow.viewDescription
}),
{
displayLarge,
diff --git a/web/src/js/components/ContentView/ContentViewOptions.jsx b/web/src/js/components/ContentView/ContentViewOptions.jsx
new file mode 100644
index 00000000..fed3a088
--- /dev/null
+++ b/web/src/js/components/ContentView/ContentViewOptions.jsx
@@ -0,0 +1,31 @@
+import React, { PropTypes } from 'react'
+import { connect } from 'react-redux'
+import ViewSelector from './ViewSelector'
+import UploadContentButton from './UploadContentButton'
+import DownloadContentButton from './DownloadContentButton'
+
+ContentViewOptions.propTypes = {
+ flow: React.PropTypes.object.isRequired,
+ message: React.PropTypes.object.isRequired,
+}
+
+function ContentViewOptions(props) {
+ const { flow, message, uploadContent, readonly, contentViewDescription } = props
+ return (
+ <div className="view-options">
+ <ViewSelector message={message}/>
+ &nbsp;
+ <DownloadContentButton flow={flow} message={message}/>
+ &nbsp;
+ <UploadContentButton uploadContent={uploadContent}/>
+ &nbsp;
+ <span>{contentViewDescription}</span>
+ </div>
+ )
+}
+
+export default connect(
+ state => ({
+ contentViewDescription: state.ui.flow.viewDescription
+ })
+)(ContentViewOptions)
diff --git a/web/src/js/components/ContentView/ContentViews.jsx b/web/src/js/components/ContentView/ContentViews.jsx
index 43aece46..3db77af4 100644
--- a/web/src/js/components/ContentView/ContentViews.jsx
+++ b/web/src/js/components/ContentView/ContentViews.jsx
@@ -30,9 +30,8 @@ function Edit({ content, onChange }) {
Edit = ContentLoader(Edit)
class ViewServer extends Component {
- constructor(props){
- super(props)
- this.maxLines = 80
+ static defaultProps = {
+ maxLines: 80,
}
componentWillMount(){
@@ -50,14 +49,12 @@ class ViewServer extends Component {
props.setContentViewDescription(props.contentView != this.data.description ? this.data.description : '')
- let isFullContentShown = this.data.lines.length < this.maxLines
+ let isFullContentShown = this.data.lines.length < props.maxLines
if (isFullContentShown) props.setShowFullContent(true)
}
render() {
- const {content, contentView, message} = this.props
-
- let lines = this.props.showFullContent ? this.data.lines : this.data.lines.slice(0, this.maxLines)
-
+ const {content, contentView, message, maxLines} = this.props
+ let lines = this.props.showFullContent ? this.data.lines : this.data.lines.slice(0, maxLines)
return <div>
<pre>
{lines.map((line, i) =>
diff --git a/web/src/js/components/FlowView.jsx b/web/src/js/components/FlowView.jsx
index a80dc040..72cffdfe 100644
--- a/web/src/js/components/FlowView.jsx
+++ b/web/src/js/components/FlowView.jsx
@@ -71,7 +71,7 @@ export default class FlowView extends Component {
const Tab = FlowView.allTabs[_.capitalize(active)]
return (
- <div className="flow-detail" onScroll={this.adjustHead}>
+ <div className="flow-detail">
<Nav
flow={flow}
tabs={tabs}
diff --git a/web/src/js/components/FlowView/Messages.jsx b/web/src/js/components/FlowView/Messages.jsx
index 9de25b5b..27644823 100644
--- a/web/src/js/components/FlowView/Messages.jsx
+++ b/web/src/js/components/FlowView/Messages.jsx
@@ -5,6 +5,7 @@ import { connect } from 'react-redux'
import { RequestUtils, isValidHttpVersion, parseUrl } from '../../flow/utils.js'
import { formatTimeStamp } from '../../utils.js'
import ContentView from '../ContentView'
+import ContentViewOptions from '../ContentView/ContentViewOptions'
import ValidateEditor from '../ValueEditor/ValidateEditor'
import ValueEditor from '../ValueEditor/ValueEditor'
@@ -81,27 +82,35 @@ const Message = connect(
export class Request extends Component {
render() {
const { flow, isEdit, updateFlow, uploadContent } = this.props
-
+ let noContent = !isEdit && (flow.request.contentLength == 0 || flow.request.contentLength == null)
return (
- <section className="request">
- <ToggleEdit/>
- <RequestLine
- flow={flow}
- readonly={!isEdit}
- updateFlow={updateFlow}/>
- <Headers
- message={flow.request}
- readonly={!isEdit}
- onChange={headers => updateFlow({ request: { headers } })}
- />
-
- <hr/>
- <ContentView
- readonly={!isEdit}
- flow={flow}
- onContentChange={content => updateFlow({ request: {content}})}
- uploadContent={content => uploadContent(flow, content, "request")}
- message={flow.request}/>
+ <section className="request flowview-container">
+ <div className="flowview-body">
+ <ToggleEdit/>
+ <RequestLine
+ flow={flow}
+ readonly={!isEdit}
+ updateFlow={updateFlow}/>
+ <Headers
+ message={flow.request}
+ readonly={!isEdit}
+ onChange={headers => updateFlow({ request: { headers } })}
+ />
+
+ <hr/>
+ <ContentView
+ readonly={!isEdit}
+ flow={flow}
+ onContentChange={content => updateFlow({ request: {content}})}
+ message={flow.request}/>
+ </div>
+ <div hidden={noContent} className="flowview-footer">
+ <ContentViewOptions
+ flow={flow}
+ readonly={!isEdit}
+ message={flow.request}
+ uploadContent={content => uploadContent(flow, content, "request")}/>
+ </div>
</section>
)
}
@@ -137,27 +146,36 @@ Request = Message(Request)
export class Response extends Component {
render() {
const { flow, isEdit, updateFlow, uploadContent } = this.props
+ let noContent = !isEdit && (flow.response.contentLength == 0 || flow.response.contentLength == null)
return (
- <section className="response">
- <ToggleEdit/>
- <ResponseLine
- flow={flow}
- readonly={!isEdit}
- updateFlow={updateFlow}/>
- <Headers
- message={flow.response}
- readonly={!isEdit}
- onChange={headers => updateFlow({ response: { headers } })}
- />
- <hr/>
- <ContentView
- readonly={!isEdit}
- flow={flow}
- onContentChange={content => updateFlow({ response: {content}})}
- uploadContent={content => uploadContent(flow, content, "response")}
- message={flow.response}
- />
+ <section className="response flowview-container">
+ <div className="flowview-body">
+ <ToggleEdit/>
+ <ResponseLine
+ flow={flow}
+ readonly={!isEdit}
+ updateFlow={updateFlow}/>
+ <Headers
+ message={flow.response}
+ readonly={!isEdit}
+ onChange={headers => updateFlow({ response: { headers } })}
+ />
+ <hr/>
+ <ContentView
+ readonly={!isEdit}
+ flow={flow}
+ onContentChange={content => updateFlow({ response: {content}})}
+ message={flow.response}
+ />
+ </div>
+ <div hidden={noContent} className="flowview-footer">
+ <ContentViewOptions
+ flow={flow}
+ message={flow.response}
+ uploadContent={content => uploadContent(flow, content, "response")}
+ readonly={!isEdit}/>
+ </div>
</section>
)
}