aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2016-06-05 18:23:06 -0700
committerMaximilian Hils <git@maximilianhils.com>2016-06-05 18:23:06 -0700
commite6ef149a03b37d74c7ebbf3a5f3a51e3c7341311 (patch)
treee548dee881cf372eaa9944ff98bce4b4c329d085 /web
parentefed5ab967e2d416aec1c6b437063841436fa3da (diff)
downloadmitmproxy-e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311.tar.gz
mitmproxy-e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311.tar.bz2
mitmproxy-e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311.zip
web: modernize flow table columns
Diffstat (limited to 'web')
-rw-r--r--web/src/js/components/flowtable-columns.js293
-rw-r--r--web/src/js/components/flowtable.js78
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)