From e6ef149a03b37d74c7ebbf3a5f3a51e3c7341311 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sun, 5 Jun 2016 18:23:06 -0700 Subject: web: modernize flow table columns --- web/src/js/components/flowtable-columns.js | 293 +++++++++++------------------ web/src/js/components/flowtable.js | 78 ++++---- 2 files changed, 148 insertions(+), 223 deletions(-) (limited to 'web') 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 ; - } - }), - 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 ; - } -}); - - -var IconColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return ; - } - }) - }, - 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 -
- ; +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 Path; - } - }), - sortKeyFun: function(flow){ - return RequestUtils.pretty_url(flow.request); + return +} +TLSColumn.Title = ({className = "", ...props}) => +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 - {flow.request.is_replay ? : null} - {flow.intercepted ? : null} - { RequestUtils.pretty_url(flow.request) } - ; } -}); - - -var MethodColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return Method; - } - }), - sortKeyFun: function(flow){ - return flow.request.method; - } - }, - render: function () { - var flow = this.props.flow; - return {flow.request.method}; + if (!icon) { + icon = "resource-icon-plain" } -}); - - -var StatusColumn = React.createClass({ - statics: { - Title: React.createClass({ - render: function(){ - return Status; - } - }), - 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 {status}; + + icon += " resource-icon" + return +
+ +} +IconColumn.Title = ({className = "", ...props}) => + + +function PathColumn({flow}) { + return + {flow.request.is_replay ? : null} + {flow.intercepted ? : null} + { RequestUtils.pretty_url(flow.request) } + +} +PathColumn.Title = ({className = "", ...props}) => + Path +PathColumn.sortKeyFun = flow => RequestUtils.pretty_url(flow.request) + + +function MethodColumn({flow}) { + return {flow.request.method} +} +MethodColumn.Title = ({className = "", ...props}) => + Method +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 Size; - } - }), - 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 {status} - var total = flow.request.contentLength; - if (flow.response) { - total += flow.response.contentLength || 0; - } - var size = formatSize(total); - return {size}; +} +StatusColumn.Title = ({className = "", ...props}) => + Status +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 Time; - } - }), - 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 {time}; + let size = formatSize(total) + return {size} + +} +SizeColumn.Title = ({className = "", ...props}) => + Size +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 {time} +} +TimeColumn.Title = ({className = "", ...props}) => + Time +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 ( - props.selectFlow(flow)}> - {props.columns.map(Column => ( - + selectFlow(flow)}> + {columns.map(Column => ( + ))} ); @@ -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 { {this.props.columns.map(Column => ( this.onClick(Column)} - className={sortColumn === Column && sortType} + className={sortColumn === Column ? sortType : undefined} /> ))} @@ -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 {
- + - - {flows.map(flow => ( - - ))} - + + {flows.map(flow => ( + + ))} +
@@ -221,8 +217,6 @@ const parseFilter = _.memoize(Filt.parse) const FlowTableContainer = connect( state => ({ flows: state.flows.view, - }), - dispatch => ({ }) )(FlowTable) -- cgit v1.2.3