Merge branch 'such-redux'

This commit is contained in:
Maximilian Hils 2016-06-05 18:23:46 -07:00
commit b6ebde3b1d
6 changed files with 1401 additions and 1310 deletions

View File

@ -1212,251 +1212,221 @@ var _utils2 = require("../utils.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var TLSColumn = _react2.default.createClass({
displayName: "TLSColumn",
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
statics: {
Title: _react2.default.createClass({
displayName: "Title",
function TLSColumn(_ref) {
var flow = _ref.flow;
render: function render() {
return _react2.default.createElement("th", _extends({}, this.props, { className: "col-tls " + (this.props.className || "") }));
}
}),
sortKeyFun: function sortKeyFun(flow) {
return flow.request.scheme;
}
},
render: function render() {
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 _react2.default.createElement("td", { className: classes });
var ssl = flow.request.scheme === "https";
var classes = void 0;
if (ssl) {
classes = "col-tls col-tls-https";
} else {
classes = "col-tls col-tls-http";
}
});
return _react2.default.createElement("td", { className: classes });
}
TLSColumn.Title = function (_ref2) {
var _ref2$className = _ref2.className;
var className = _ref2$className === undefined ? "" : _ref2$className;
var IconColumn = _react2.default.createClass({
displayName: "IconColumn",
var props = _objectWithoutProperties(_ref2, ["className"]);
statics: {
Title: _react2.default.createClass({
displayName: "Title",
return _react2.default.createElement("th", _extends({}, props, { className: "col-tls " + className }));
};
TLSColumn.sortKeyFun = function (flow) {
return flow.request.scheme;
};
render: function render() {
return _react2.default.createElement("th", _extends({}, this.props, { className: "col-icon " + (this.props.className || "") }));
}
})
},
render: function render() {
var flow = this.props.flow;
function IconColumn(_ref3) {
var flow = _ref3.flow;
var icon;
if (flow.response) {
var contentType = _utils.ResponseUtils.getContentType(flow.response);
var icon = void 0;
if (flow.response) {
var contentType = _utils.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";
}
//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 _react2.default.createElement(
"td",
{ className: "col-icon" },
_react2.default.createElement("div", { className: icon })
);
}
});
var PathColumn = _react2.default.createClass({
displayName: "PathColumn",
statics: {
Title: _react2.default.createClass({
displayName: "Title",
render: function render() {
return _react2.default.createElement(
"th",
_extends({}, this.props, { className: "col-path " + (this.props.className || "") }),
"Path"
);
}
}),
sortKeyFun: function sortKeyFun(flow) {
return _utils.RequestUtils.pretty_url(flow.request);
}
},
render: function render() {
var flow = this.props.flow;
return _react2.default.createElement(
"td",
{ className: "col-path" },
flow.request.is_replay ? _react2.default.createElement("i", { className: "fa fa-fw fa-repeat pull-right" }) : null,
flow.intercepted ? _react2.default.createElement("i", { className: "fa fa-fw fa-pause pull-right" }) : null,
_utils.RequestUtils.pretty_url(flow.request)
);
if (!icon) {
icon = "resource-icon-plain";
}
});
var MethodColumn = _react2.default.createClass({
displayName: "MethodColumn",
icon += " resource-icon";
return _react2.default.createElement(
"td",
{ className: "col-icon" },
_react2.default.createElement("div", { className: icon })
);
}
IconColumn.Title = function (_ref4) {
var _ref4$className = _ref4.className;
var className = _ref4$className === undefined ? "" : _ref4$className;
statics: {
Title: _react2.default.createClass({
displayName: "Title",
var props = _objectWithoutProperties(_ref4, ["className"]);
render: function render() {
return _react2.default.createElement(
"th",
_extends({}, this.props, { className: "col-method " + (this.props.className || "") }),
"Method"
);
}
}),
sortKeyFun: function sortKeyFun(flow) {
return flow.request.method;
}
},
render: function render() {
var flow = this.props.flow;
return _react2.default.createElement(
"td",
{ className: "col-method" },
flow.request.method
);
return _react2.default.createElement("th", _extends({}, props, { className: "col-icon " + className }));
};
function PathColumn(_ref5) {
var flow = _ref5.flow;
return _react2.default.createElement(
"td",
{ className: "col-path" },
flow.request.is_replay ? _react2.default.createElement("i", { className: "fa fa-fw fa-repeat pull-right" }) : null,
flow.intercepted ? _react2.default.createElement("i", { className: "fa fa-fw fa-pause pull-right" }) : null,
_utils.RequestUtils.pretty_url(flow.request)
);
}
PathColumn.Title = function (_ref6) {
var _ref6$className = _ref6.className;
var className = _ref6$className === undefined ? "" : _ref6$className;
var props = _objectWithoutProperties(_ref6, ["className"]);
return _react2.default.createElement(
"th",
_extends({}, props, { className: "col-path " + className }),
"Path"
);
};
PathColumn.sortKeyFun = function (flow) {
return _utils.RequestUtils.pretty_url(flow.request);
};
function MethodColumn(_ref7) {
var flow = _ref7.flow;
return _react2.default.createElement(
"td",
{ className: "col-method" },
flow.request.method
);
}
MethodColumn.Title = function (_ref8) {
var _ref8$className = _ref8.className;
var className = _ref8$className === undefined ? "" : _ref8$className;
var props = _objectWithoutProperties(_ref8, ["className"]);
return _react2.default.createElement(
"th",
_extends({}, props, { className: "col-method " + className }),
"Method"
);
};
MethodColumn.sortKeyFun = function (flow) {
return flow.request.method;
};
function StatusColumn(_ref9) {
var flow = _ref9.flow;
var status = void 0;
if (flow.response) {
status = flow.response.status_code;
} else {
status = null;
}
});
return _react2.default.createElement(
"td",
{ className: "col-status" },
status
);
}
StatusColumn.Title = function (_ref10) {
var _ref10$className = _ref10.className;
var className = _ref10$className === undefined ? "" : _ref10$className;
var StatusColumn = _react2.default.createClass({
displayName: "StatusColumn",
var props = _objectWithoutProperties(_ref10, ["className"]);
statics: {
Title: _react2.default.createClass({
displayName: "Title",
return _react2.default.createElement(
"th",
_extends({}, props, { className: "col-status " + className }),
"Status"
);
};
StatusColumn.sortKeyFun = function (flow) {
return flow.response ? flow.response.status_code : undefined;
};
render: function render() {
return _react2.default.createElement(
"th",
_extends({}, this.props, { className: "col-status " + (this.props.className || "") }),
"Status"
);
}
}),
sortKeyFun: function sortKeyFun(flow) {
return flow.response ? flow.response.status_code : undefined;
}
},
render: function render() {
var flow = this.props.flow;
var status;
if (flow.response) {
status = flow.response.status_code;
} else {
status = null;
}
return _react2.default.createElement(
"td",
{ className: "col-status" },
status
);
function SizeColumn(_ref11) {
var flow = _ref11.flow;
var total = flow.request.contentLength;
if (flow.response) {
total += flow.response.contentLength || 0;
}
});
var size = (0, _utils2.formatSize)(total);
return _react2.default.createElement(
"td",
{ className: "col-size" },
size
);
}
SizeColumn.Title = function (_ref12) {
var _ref12$className = _ref12.className;
var className = _ref12$className === undefined ? "" : _ref12$className;
var SizeColumn = _react2.default.createClass({
displayName: "SizeColumn",
var props = _objectWithoutProperties(_ref12, ["className"]);
statics: {
Title: _react2.default.createClass({
displayName: "Title",
render: function render() {
return _react2.default.createElement(
"th",
_extends({}, this.props, { className: "col-size " + (this.props.className || "") }),
"Size"
);
}
}),
sortKeyFun: function sortKeyFun(flow) {
var total = flow.request.contentLength;
if (flow.response) {
total += flow.response.contentLength || 0;
}
return total;
}
},
render: function render() {
var flow = this.props.flow;
var total = flow.request.contentLength;
if (flow.response) {
total += flow.response.contentLength || 0;
}
var size = (0, _utils2.formatSize)(total);
return _react2.default.createElement(
"td",
{ className: "col-size" },
size
);
return _react2.default.createElement(
"th",
_extends({}, props, { className: "col-size " + className }),
"Size"
);
};
SizeColumn.sortKeyFun = function (flow) {
var total = flow.request.contentLength;
if (flow.response) {
total += flow.response.contentLength || 0;
}
});
return total;
};
var TimeColumn = _react2.default.createClass({
displayName: "TimeColumn",
function TimeColumn(_ref13) {
var flow = _ref13.flow;
statics: {
Title: _react2.default.createClass({
displayName: "Title",
render: function render() {
return _react2.default.createElement(
"th",
_extends({}, this.props, { className: "col-time " + (this.props.className || "") }),
"Time"
);
}
}),
sortKeyFun: function sortKeyFun(flow) {
if (flow.response) {
return flow.response.timestamp_end - flow.request.timestamp_start;
}
}
},
render: function render() {
var flow = this.props.flow;
var time;
if (flow.response) {
time = (0, _utils2.formatTimeDelta)(1000 * (flow.response.timestamp_end - flow.request.timestamp_start));
} else {
time = "...";
}
return _react2.default.createElement(
"td",
{ className: "col-time" },
time
);
var time = void 0;
if (flow.response) {
time = (0, _utils2.formatTimeDelta)(1000 * (flow.response.timestamp_end - flow.request.timestamp_start));
} else {
time = "...";
}
});
return _react2.default.createElement(
"td",
{ className: "col-time" },
time
);
}
TimeColumn.Title = function (_ref14) {
var _ref14$className = _ref14.className;
var className = _ref14$className === undefined ? "" : _ref14$className;
var props = _objectWithoutProperties(_ref14, ["className"]);
return _react2.default.createElement(
"th",
_extends({}, props, { className: "col-time " + className }),
"Time"
);
};
TimeColumn.sortKeyFun = function (flow) {
return flow.response.timestamp_end - flow.request.timestamp_start;
};
var all_columns = [TLSColumn, IconColumn, PathColumn, MethodColumn, StatusColumn, SizeColumn, TimeColumn];
@ -1525,12 +1495,17 @@ FlowRow.propTypes = {
selected: _react2.default.PropTypes.bool
};
function FlowRow(props) {
var flow = props.flow;
function FlowRow(_ref) {
var flow = _ref.flow;
var selected = _ref.selected;
var highlight = _ref.highlight;
var columns = _ref.columns;
var selectFlow = _ref.selectFlow;
var className = (0, _classnames2.default)({
"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
@ -1539,10 +1514,10 @@ function FlowRow(props) {
return _react2.default.createElement(
"tr",
{ className: className, onClick: function onClick() {
return props.selectFlow(flow);
return selectFlow(flow);
} },
props.columns.map(function (Column) {
return _react2.default.createElement(Column, { key: Column.displayName, flow: flow });
columns.map(function (Column) {
return _react2.default.createElement(Column, { key: Column.name, flow: flow });
})
);
}
@ -1553,8 +1528,6 @@ var FlowRowContainer = (0, _reactRedux.connect)(function (state, ownProps) {
highlight: state.flows.highlight,
selected: state.flows.selected.indexOf(ownProps.flowId) >= 0
};
}, function (dispatch, ownProps) {
return {};
})(FlowRow);
var FlowTableHead = function (_React$Component) {
@ -1608,11 +1581,11 @@ var FlowTableHead = function (_React$Component) {
null,
this.props.columns.map(function (Column) {
return _react2.default.createElement(Column.Title, {
key: Column.displayName,
key: Column.name,
onClick: function onClick() {
return _this2.onClick(Column);
},
className: sortColumn === Column && sortType
className: sortColumn === Column ? sortType : undefined
});
})
);
@ -1769,8 +1742,6 @@ var FlowTableContainer = (0, _reactRedux.connect)(function (state) {
return {
flows: state.flows.view
};
}, function (dispatch) {
return {};
})(FlowTable);
exports.default = FlowTableContainer;
@ -3831,7 +3802,7 @@ var MainView = _react2.default.createClass({
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
// Update redux store with route changes
if (nextProps.routeParams.flowId !== (nextProps.selectedFlow || {}).id) {
this.props.selectFlow(nextProps.routeParams.flowId);
// FIXME this.props.selectFlow(nextProps.routeParams.flowId)
}
if (nextProps.location.query[_actions.Query.SEARCH] !== nextProps.filter) {
this.props.setFilter(nextProps.location.query[_actions.Query.SEARCH], false);
@ -3844,6 +3815,7 @@ var MainView = _react2.default.createClass({
// FIXME: Move to redux. This requires that sortKeyFun is not a function anymore.
},
selectFlow: function selectFlow(flow) {
return this.props.selectFlow(flow.id);
// TODO: This belongs into redux
if (flow) {
var tab = this.props.routeParams.detailTab || "request";
@ -4145,7 +4117,7 @@ exports.default = Prompt;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.App = undefined;
exports.history = exports.App = undefined;
var _react = require("react");
@ -4326,6 +4298,7 @@ var App = exports.App = _react2.default.createElement(
_react2.default.createElement(_reactRouter.Route, { path: "reports", component: Reports })
)
);
exports.history = _reactRouter.hashHistory;
},{"../store/store.js":31,"../utils.js":32,"./common.js":4,"./eventlog.js":6,"./footer.js":14,"./header.js":15,"./mainview.js":18,"lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux","react-router":"react-router"}],21:[function(require,module,exports){
"use strict";
@ -4544,6 +4517,8 @@ var _filt2 = _interopRequireDefault(_filt);
var _view = require("./utils/view");
var _proxyapp = require("../components/proxyapp");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var UPDATE_FLOWS = exports.UPDATE_FLOWS = "UPDATE_FLOWS";
@ -4614,6 +4589,23 @@ function setHighlight(highlight) {
};
}
function selectFlow(flowId) {
var detailTab = arguments.length <= 1 || arguments[1] === undefined ? "request" : arguments[1];
var pathname = void 0;
if (flowId) {
pathname = "/flows/" + flowId + "/" + detailTab;
} else {
pathname = "/flows";
}
/*
let location
history.listen(l => {location = l})()
history.replace({
...location,
pathname
})
*/
return {
type: SELECT_FLOW,
flowId: flowId
@ -4623,7 +4615,7 @@ function selectFlow(flowId) {
exports.updateFlows = updateList;
exports.fetchFlows = fetchList;
},{"../filt/filt":29,"./utils/list":26,"./utils/view":27}],25:[function(require,module,exports){
},{"../components/proxyapp":20,"../filt/filt":29,"./utils/list":26,"./utils/view":27}],25:[function(require,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
@ -4757,7 +4749,7 @@ function makeList(actionType, fetchURL) {
list = [].concat(_toConsumableArray(state.list));
itemIndex = state.indexOf[action.item.id];
list[itemIndex] = action.item;
return _extends({}, defaultState, {
return _extends({}, state, {
list: list
});
@ -4765,14 +4757,14 @@ function makeList(actionType, fetchURL) {
list = [].concat(_toConsumableArray(state.list));
itemIndex = state.indexOf[action.item.id];
list.splice(itemIndex, 1);
return _extends({}, defaultState, {
return _extends({}, state, {
list: list,
byId: _extends({}, state.byId, _defineProperty({}, action.item.id, undefined)),
indexOf: _extends({}, state.indexOf, _defineProperty({}, action.item.id, undefined))
});
case REQUEST_LIST:
return _extends({}, defaultState, {
return _extends({}, state, {
isFetching: true
});

File diff suppressed because it is too large Load Diff

View File

@ -21,8 +21,8 @@
"flux": "^2.1.1",
"jquery": "^2.2.3",
"lodash": "^4.11.2",
"react": "^15.0.2",
"react-dom": "^15.0.2",
"react": "^15.1.0",
"react-dom": "^15.1.0",
"react-redux": "^4.4.5",
"react-router": "^2.4.0",
"redux": "^3.5.2",
@ -53,7 +53,6 @@
"gulp-sourcemaps": "^1.6.0",
"gulp-util": "^3.0.7",
"jest": "^0.1.40",
"redux-thunk": "^2.1.0",
"uglifyify": "^3.0.1",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",

View File

@ -1,190 +1,121 @@
import React from "react";
import {RequestUtils, ResponseUtils} from "../flow/utils.js";
import {formatSize, formatTimeDelta} from "../utils.js";
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>;
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"
}
});
return <td className={classes}></td>
}
TLSColumn.Title = ({className = "", ...props}) => <th {...props} className={"col-tls " + className }></th>
TLSColumn.sortKeyFun = flow => flow.request.scheme
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;
function IconColumn({flow}) {
let icon
if (flow.response) {
var contentType = ResponseUtils.getContentType(flow.response)
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";
}
//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>;
}
});
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);
}
},
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>;
if (!icon) {
icon = "resource-icon-plain"
}
});
icon += " resource-icon"
return <td className="col-icon">
<div className={icon}></div>
</td>
}
IconColumn.Title = ({className = "", ...props}) => <th {...props} className={"col-icon " + className }></th>
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>;
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
}
});
return <td className="col-status">{status}</td>
}
StatusColumn.Title = ({className = "", ...props}) =>
<th {...props} className={"col-status " + className }>Status</th>
StatusColumn.sortKeyFun = flow => flow.response ? flow.response.status_code : undefined
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>;
function SizeColumn({flow}) {
let total = flow.request.contentLength
if (flow.response) {
total += flow.response.contentLength || 0
}
});
let size = formatSize(total)
return <td className="col-size">{size}</td>
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;
var total = flow.request.contentLength;
if (flow.response) {
total += flow.response.contentLength || 0;
}
var 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
}
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>;
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

View File

@ -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)

View File

@ -62,7 +62,7 @@ export default function makeList(actionType, fetchURL) {
itemIndex = state.indexOf[action.item.id]
list[itemIndex] = action.item
return {
...defaultState,
...state,
list
}
@ -71,7 +71,7 @@ export default function makeList(actionType, fetchURL) {
itemIndex = state.indexOf[action.item.id]
list.splice(itemIndex, 1)
return {
...defaultState,
...state,
list,
byId: {...state.byId, [action.item.id]: undefined},
indexOf: {...state.indexOf, [action.item.id]: undefined},
@ -79,7 +79,7 @@ export default function makeList(actionType, fetchURL) {
case REQUEST_LIST:
return {
...defaultState,
...state,
isFetching: true
}