diff options
author | Maximilian Hils <git@maximilianhils.com> | 2016-06-05 18:23:06 -0700 |
---|---|---|
committer | Maximilian Hils <git@maximilianhils.com> | 2016-06-05 18:23:06 -0700 |
commit | e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311 (patch) | |
tree | e548dee881cf372eaa9944ff98bce4b4c329d085 /web/src | |
parent | efed5ab967e2d416aec1c6b437063841436fa3da (diff) | |
download | mitmproxy-e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311.tar.gz mitmproxy-e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311.tar.bz2 mitmproxy-e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311.zip |
web: modernize flow table columns
Diffstat (limited to 'web/src')
-rw-r--r-- | web/src/js/components/flowtable-columns.js | 293 | ||||
-rw-r--r-- | web/src/js/components/flowtable.js | 78 |
2 files changed, 148 insertions, 223 deletions
diff --git a/web/src/js/components/flowtable-columns.js b/web/src/js/components/flowtable-columns.js index dbbe8847..1eae6409 100644 --- a/web/src/js/components/flowtable-columns.js +++ b/web/src/js/components/flowtable-columns.js @@ -1,190 +1,121 @@ -import React from "react"; -import {RequestUtils, ResponseUtils} from "../flow/utils.js"; -import {formatSize, formatTimeDelta} from "../utils.js"; - -var TLSColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-tls " + (this.props.className || "") }></th>; - } - }), - sortKeyFun: function(flow){ - return flow.request.scheme; - } - }, - render: function () { - var flow = this.props.flow; - var ssl = (flow.request.scheme === "https"); - var classes; - if (ssl) { - classes = "col-tls col-tls-https"; - } else { - classes = "col-tls col-tls-http"; - } - return <td className={classes}></td>; - } -}); - - -var IconColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-icon " + (this.props.className || "") }></th>; - } - }) - }, - render: function () { - var flow = this.props.flow; - - var icon; - if (flow.response) { - var contentType = ResponseUtils.getContentType(flow.response); - - //TODO: We should assign a type to the flow somewhere else. - if (flow.response.status_code === 304) { - icon = "resource-icon-not-modified"; - } else if (300 <= flow.response.status_code && flow.response.status_code < 400) { - icon = "resource-icon-redirect"; - } else if (contentType && contentType.indexOf("image") >= 0) { - icon = "resource-icon-image"; - } else if (contentType && contentType.indexOf("javascript") >= 0) { - icon = "resource-icon-js"; - } else if (contentType && contentType.indexOf("css") >= 0) { - icon = "resource-icon-css"; - } else if (contentType && contentType.indexOf("html") >= 0) { - icon = "resource-icon-document"; - } - } - if (!icon) { - icon = "resource-icon-plain"; - } - - - icon += " resource-icon"; - return <td className="col-icon"> - <div className={icon}></div> - </td>; +import React from "react" +import {RequestUtils, ResponseUtils} from "../flow/utils.js" +import {formatSize, formatTimeDelta} from "../utils.js" + + +function TLSColumn({flow}) { + let ssl = (flow.request.scheme === "https") + let classes + if (ssl) { + classes = "col-tls col-tls-https" + } else { + classes = "col-tls col-tls-http" } -}); - -var PathColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-path " + (this.props.className || "") }>Path</th>; - } - }), - sortKeyFun: function(flow){ - return RequestUtils.pretty_url(flow.request); + return <td className={classes}></td> +} +TLSColumn.Title = ({className = "", ...props}) => <th {...props} className={"col-tls " + className }></th> +TLSColumn.sortKeyFun = flow => flow.request.scheme + + +function IconColumn({flow}) { + let icon + if (flow.response) { + var contentType = ResponseUtils.getContentType(flow.response) + + //TODO: We should assign a type to the flow somewhere else. + if (flow.response.status_code === 304) { + icon = "resource-icon-not-modified" + } else if (300 <= flow.response.status_code && flow.response.status_code < 400) { + icon = "resource-icon-redirect" + } else if (contentType && contentType.indexOf("image") >= 0) { + icon = "resource-icon-image" + } else if (contentType && contentType.indexOf("javascript") >= 0) { + icon = "resource-icon-js" + } else if (contentType && contentType.indexOf("css") >= 0) { + icon = "resource-icon-css" + } else if (contentType && contentType.indexOf("html") >= 0) { + icon = "resource-icon-document" } - }, - render: function () { - var flow = this.props.flow; - return <td className="col-path"> - {flow.request.is_replay ? <i className="fa fa-fw fa-repeat pull-right"></i> : null} - {flow.intercepted ? <i className="fa fa-fw fa-pause pull-right"></i> : null} - { RequestUtils.pretty_url(flow.request) } - </td>; } -}); - - -var MethodColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-method " + (this.props.className || "") }>Method</th>; - } - }), - sortKeyFun: function(flow){ - return flow.request.method; - } - }, - render: function () { - var flow = this.props.flow; - return <td className="col-method">{flow.request.method}</td>; + if (!icon) { + icon = "resource-icon-plain" } -}); - - -var StatusColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-status " + (this.props.className || "") }>Status</th>; - } - }), - sortKeyFun: function(flow){ - return flow.response ? flow.response.status_code : undefined; - } - }, - render: function () { - var flow = this.props.flow; - var status; - if (flow.response) { - status = flow.response.status_code; - } else { - status = null; - } - return <td className="col-status">{status}</td>; + + icon += " resource-icon" + return <td className="col-icon"> + <div className={icon}></div> + </td> +} +IconColumn.Title = ({className = "", ...props}) => <th {...props} className={"col-icon " + className }></th> + + +function PathColumn({flow}) { + return <td className="col-path"> + {flow.request.is_replay ? <i className="fa fa-fw fa-repeat pull-right"></i> : null} + {flow.intercepted ? <i className="fa fa-fw fa-pause pull-right"></i> : null} + { RequestUtils.pretty_url(flow.request) } + </td> +} +PathColumn.Title = ({className = "", ...props}) => + <th {...props} className={"col-path " + className }>Path</th> +PathColumn.sortKeyFun = flow => RequestUtils.pretty_url(flow.request) + + +function MethodColumn({flow}) { + return <td className="col-method">{flow.request.method}</td> +} +MethodColumn.Title = ({className = "", ...props}) => + <th {...props} className={"col-method " + className }>Method</th> +MethodColumn.sortKeyFun = flow => flow.request.method + + +function StatusColumn({flow}) { + let status + if (flow.response) { + status = flow.response.status_code + } else { + status = null } -}); - - -var SizeColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-size " + (this.props.className || "") }>Size</th>; - } - }), - sortKeyFun: function(flow){ - var total = flow.request.contentLength; - if (flow.response) { - total += flow.response.contentLength || 0; - } - return total; - } - }, - render: function () { - var flow = this.props.flow; + return <td className="col-status">{status}</td> - var total = flow.request.contentLength; - if (flow.response) { - total += flow.response.contentLength || 0; - } - var size = formatSize(total); - return <td className="col-size">{size}</td>; +} +StatusColumn.Title = ({className = "", ...props}) => + <th {...props} className={"col-status " + className }>Status</th> +StatusColumn.sortKeyFun = flow => flow.response ? flow.response.status_code : undefined + + +function SizeColumn({flow}) { + let total = flow.request.contentLength + if (flow.response) { + total += flow.response.contentLength || 0 } -}); - - -var TimeColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return <th {...this.props} className={"col-time " + (this.props.className || "") }>Time</th>; - } - }), - sortKeyFun: function(flow){ - if(flow.response) { - return flow.response.timestamp_end - flow.request.timestamp_start; - } - } - }, - render: function () { - var flow = this.props.flow; - var time; - if (flow.response) { - time = formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start)); - } else { - time = "..."; - } - return <td className="col-time">{time}</td>; + let size = formatSize(total) + return <td className="col-size">{size}</td> + +} +SizeColumn.Title = ({className = "", ...props}) => + <th {...props} className={"col-size " + className }>Size</th> +SizeColumn.sortKeyFun = flow => { + let total = flow.request.contentLength + if (flow.response) { + total += flow.response.contentLength || 0 + } + return total +} + + +function TimeColumn({flow}) { + let time + if (flow.response) { + time = formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start)) + } else { + time = "..." } -}); + return <td className="col-time">{time}</td> +} +TimeColumn.Title = ({className = "", ...props}) => + <th {...props} className={"col-time " + className }>Time</th> +TimeColumn.sortKeyFun = flow => flow.response.timestamp_end - flow.request.timestamp_start var all_columns = [ @@ -195,6 +126,6 @@ var all_columns = [ StatusColumn, SizeColumn, TimeColumn -]; +] -export default all_columns; +export default all_columns diff --git a/web/src/js/components/flowtable.js b/web/src/js/components/flowtable.js index 0241cd78..d621387c 100644 --- a/web/src/js/components/flowtable.js +++ b/web/src/js/components/flowtable.js @@ -19,21 +19,20 @@ FlowRow.propTypes = { selected: React.PropTypes.bool, }; -function FlowRow(props) { - const flow = props.flow; +function FlowRow({flow, selected, highlight, columns, selectFlow}) { const className = classNames({ - "selected": props.selected, - "highlighted": props.highlight && parseFilter(props.highlight)(flow), + "selected": selected, + "highlighted": highlight && parseFilter(highlight)(flow), "intercepted": flow.intercepted, "has-request": flow.request, "has-response": flow.response, }); return ( - <tr className={className} onClick={() => props.selectFlow(flow)}> - {props.columns.map(Column => ( - <Column key={Column.displayName} flow={flow}/> + <tr className={className} onClick={() => selectFlow(flow)}> + {columns.map(Column => ( + <Column key={Column.name} flow={flow}/> ))} </tr> ); @@ -44,11 +43,8 @@ const FlowRowContainer = connect( flow: state.flows.all.byId[ownProps.flowId], highlight: state.flows.highlight, selected: state.flows.selected.indexOf(ownProps.flowId) >= 0 - }), - (dispatch, ownProps) => ({ - }) -)(FlowRow); +)(FlowRow) class FlowTableHead extends React.Component { @@ -59,7 +55,7 @@ class FlowTableHead extends React.Component { constructor(props, context) { super(props, context); - this.state = { sortColumn: undefined, sortDesc: false }; + this.state = {sortColumn: undefined, sortDesc: false}; } onClick(Column) { @@ -69,20 +65,20 @@ class FlowTableHead extends React.Component { if (Column === this.state.sortColumn) { sortDesc = !sortDesc; - this.setState({ sortDesc }); + this.setState({sortDesc}); } else { - this.setState({ sortColumn: hasSort && Column, sortDesc: false }); + this.setState({sortColumn: hasSort && Column, sortDesc: false}); } let sortKeyFun = Column.sortKeyFun; if (sortDesc) { - sortKeyFun = hasSort && function() { - const k = Column.sortKeyFun.apply(this, arguments); - if (_.isString(k)) { - return reverseString("" + k); - } - return -k; - }; + sortKeyFun = hasSort && function () { + const k = Column.sortKeyFun.apply(this, arguments); + if (_.isString(k)) { + return reverseString("" + k); + } + return -k; + }; } this.props.setSortKeyFun(sortKeyFun); @@ -95,9 +91,9 @@ class FlowTableHead extends React.Component { <tr> {this.props.columns.map(Column => ( <Column.Title - key={Column.displayName} + key={Column.name} onClick={() => this.onClick(Column)} - className={sortColumn === Column && sortType} + className={sortColumn === Column ? sortType : undefined} /> ))} </tr> @@ -118,7 +114,7 @@ class FlowTable extends React.Component { constructor(props, context) { super(props, context); - this.state = { vScroll: calcVScroll() }; + this.state = {vScroll: calcVScroll()}; this.onViewportUpdate = this.onViewportUpdate.bind(this); } @@ -132,7 +128,7 @@ class FlowTable extends React.Component { } componentWillReceiveProps(nextProps) { - if(nextProps.selected && nextProps.selected !== this.props.selected){ + if (nextProps.selected && nextProps.selected !== this.props.selected) { window.setTimeout(() => this.scrollIntoView(nextProps.selected), 1) } } @@ -154,7 +150,7 @@ class FlowTable extends React.Component { if (!shallowEqual(this.state.vScroll, vScroll) || this.state.viewportTop !== viewportTop) { - this.setState({ vScroll, viewportTop }); + this.setState({vScroll, viewportTop}); } } @@ -190,22 +186,22 @@ class FlowTable extends React.Component { <div className="flow-table" onScroll={this.onViewportUpdate}> <table> <thead ref="head" style={{ transform }}> - <FlowTableHead - columns={flowtable_columns} - setSortKeyFun={this.props.setSortKeyFun} - /> + <FlowTableHead + columns={flowtable_columns} + setSortKeyFun={this.props.setSortKeyFun} + /> </thead> <tbody> - <tr style={{ height: vScroll.paddingTop }}></tr> - {flows.map(flow => ( - <FlowRowContainer - key={flow.id} - flowId={flow.id} - columns={flowtable_columns} - selectFlow={this.props.selectFlow} - /> - ))} - <tr style={{ height: vScroll.paddingBottom }}></tr> + <tr style={{ height: vScroll.paddingTop }}></tr> + {flows.map(flow => ( + <FlowRowContainer + key={flow.id} + flowId={flow.id} + columns={flowtable_columns} + selectFlow={this.props.selectFlow} + /> + ))} + <tr style={{ height: vScroll.paddingBottom }}></tr> </tbody> </table> </div> @@ -221,8 +217,6 @@ const parseFilter = _.memoize(Filt.parse) const FlowTableContainer = connect( state => ({ flows: state.flows.view, - }), - dispatch => ({ }) )(FlowTable) |