mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-29 02:57:19 +00:00
make columns configurable and customizable
This commit is contained in:
parent
c996f1ee74
commit
1efe44745b
@ -137,6 +137,7 @@ def mitmweb(opts):
|
||||
opts.make_parser(group, "web_open_browser")
|
||||
opts.make_parser(group, "web_port", metavar="PORT")
|
||||
opts.make_parser(group, "web_host", metavar="HOST")
|
||||
opts.make_parser(group, "web_columns")
|
||||
|
||||
common_options(parser, opts)
|
||||
group = parser.add_argument_group(
|
||||
|
2
mitmproxy/tools/web/static/app.css
vendored
2
mitmproxy/tools/web/static/app.css
vendored
File diff suppressed because one or more lines are too long
8
mitmproxy/tools/web/static/app.js
vendored
8
mitmproxy/tools/web/static/app.js
vendored
@ -47,13 +47,13 @@
|
||||
"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&(t[o]=e[o]);return t.default=e,t}function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.PureFlowTable=void 0;var _createClass=function(){function e(e,t){for(var o=0;o<t.length;o++){var l=t[o];l.enumerable=l.enumerable||!1,l.configurable=!0,"value"in l&&(l.writable=!0),Object.defineProperty(e,l.key,l)}}return function(t,o,l){return o&&e(t.prototype,o),l&&e(t,l),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_reactRedux=require("react-redux"),_shallowequal=require("shallowequal"),_shallowequal2=_interopRequireDefault(_shallowequal),_AutoScroll=require("./helpers/AutoScroll"),_AutoScroll2=_interopRequireDefault(_AutoScroll),_VirtualScroll=require("./helpers/VirtualScroll"),_FlowTableHead=require("./FlowTable/FlowTableHead"),_FlowTableHead2=_interopRequireDefault(_FlowTableHead),_FlowRow=require("./FlowTable/FlowRow"),_FlowRow2=_interopRequireDefault(_FlowRow),_filt=require("../filt/filt"),_filt2=_interopRequireDefault(_filt),_flows=require("../ducks/flows"),flowsActions=_interopRequireWildcard(_flows),FlowTable=function(e){function t(e,o){_classCallCheck(this,t);var l=_possibleConstructorReturn(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,o));return l.state={vScroll:(0,_VirtualScroll.calcVScroll)()},l.onViewportUpdate=l.onViewportUpdate.bind(l),l}return _inherits(t,_react2.default.Component),_createClass(t,[{key:"componentWillMount",value:function(){window.addEventListener("resize",this.onViewportUpdate)}},{key:"componentWillUnmount",value:function(){window.removeEventListener("resize",this.onViewportUpdate)}},{key:"componentDidUpdate",value:function(){if(this.onViewportUpdate(),this.shouldScrollIntoView){this.shouldScrollIntoView=!1;var e=this.props,t=e.rowHeight,o=e.flows,l=e.selected,r=_reactDom2.default.findDOMNode(this),i=_reactDom2.default.findDOMNode(this.refs.head),a=i?i.offsetHeight:0,n=o.indexOf(l)*t+a,u=n+t,s=r.scrollTop,c=r.offsetHeight;n-a<s?r.scrollTop=n-a:u>s+c&&(r.scrollTop=u-c)}}},{key:"componentWillReceiveProps",value:function(e){e.selected&&e.selected!==this.props.selected&&(this.shouldScrollIntoView=!0)}},{key:"onViewportUpdate",value:function(){var e=_reactDom2.default.findDOMNode(this),t=e.scrollTop,o=(0,_VirtualScroll.calcVScroll)({viewportTop:t,viewportHeight:e.offsetHeight,itemCount:this.props.flows.length,rowHeight:this.props.rowHeight});this.state.viewportTop===t&&(0,_shallowequal2.default)(this.state.vScroll,o)||this.setState({vScroll:o,viewportTop:t})}},{key:"render",value:function(){var e=this,t=this.state,o=t.vScroll,l=t.viewportTop,r=this.props,i=r.flows,a=r.selected,n=r.highlight,u=n?_filt2.default.parse(n):function(){return!1};return _react2.default.createElement("div",{className:"flow-table",onScroll:this.onViewportUpdate},_react2.default.createElement("table",null,_react2.default.createElement("thead",{ref:"head",style:{transform:"translateY("+l+"px)"}},_react2.default.createElement(_FlowTableHead2.default,null)),_react2.default.createElement("tbody",null,_react2.default.createElement("tr",{style:{height:o.paddingTop}}),i.slice(o.start,o.end).map(function(t){return _react2.default.createElement(_FlowRow2.default,{key:t.id,flow:t,selected:t===a,highlighted:u(t),onSelect:e.props.selectFlow})}),_react2.default.createElement("tr",{style:{height:o.paddingBottom}}))))}}]),t}();FlowTable.propTypes={selectFlow:_propTypes2.default.func.isRequired,flows:_propTypes2.default.array.isRequired,rowHeight:_propTypes2.default.number,highlight:_propTypes2.default.string,selected:_propTypes2.default.object},FlowTable.defaultProps={rowHeight:32};var PureFlowTable=exports.PureFlowTable=(0,_AutoScroll2.default)(FlowTable);exports.default=(0,_reactRedux.connect)(function(e){return{flows:e.flows.view,highlight:e.flows.highlight,selected:e.flows.byId[e.flows.selected[0]]}},{selectFlow:flowsActions.select})(PureFlowTable);
|
||||
|
||||
},{"../ducks/flows":56,"../filt/filt":67,"./FlowTable/FlowRow":18,"./FlowTable/FlowTableHead":19,"./helpers/AutoScroll":52,"./helpers/VirtualScroll":53,"prop-types":"prop-types","react":"react","react-dom":"react-dom","react-redux":"react-redux","shallowequal":"shallowequal"}],17:[function(require,module,exports){
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function TLSColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:(0,_classnames2.default)("col-tls","https"===t.request.scheme?"col-tls-https":"col-tls-http")})}function IconColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-icon"},_react2.default.createElement("div",{className:(0,_classnames2.default)("resource-icon",IconColumn.getIcon(t))}))}function PathColumn(e){var t=e.flow,s=void 0;return t.error&&(s="Connection killed."===t.error.msg?_react2.default.createElement("i",{className:"fa fa-fw fa-times pull-right"}):_react2.default.createElement("i",{className:"fa fa-fw fa-exclamation pull-right"})),_react2.default.createElement("td",{className:"col-path"},t.request.is_replay&&_react2.default.createElement("i",{className:"fa fa-fw fa-repeat pull-right"}),t.intercepted&&_react2.default.createElement("i",{className:"fa fa-fw fa-pause pull-right"}),s,_utils.RequestUtils.pretty_url(t.request))}function MethodColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-method"},t.request.method)}function StatusColumn(e){var t=e.flow,s="darkred";return t.response&&100<=t.response.status_code&&t.response.status_code<200?s="green":t.response&&200<=t.response.status_code&&t.response.status_code<300?s="darkgreen":t.response&&300<=t.response.status_code&&t.response.status_code<400?s="lightblue":t.response&&400<=t.response.status_code&&t.response.status_code<500?s="lightred":t.response&&500<=t.response.status_code&&t.response.status_code<600&&(s="lightred"),_react2.default.createElement("td",{className:"col-status",style:{color:s}},t.response&&t.response.status_code)}function SizeColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-size"},(0,_utils2.formatSize)(SizeColumn.getTotalSize(t)))}function TimeColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-time"},t.response?(0,_utils2.formatTimeDelta)(1e3*(t.response.timestamp_end-t.request.timestamp_start)):"...")}Object.defineProperty(exports,"__esModule",{value:!0}),exports.TLSColumn=TLSColumn,exports.IconColumn=IconColumn,exports.PathColumn=PathColumn,exports.MethodColumn=MethodColumn,exports.StatusColumn=StatusColumn,exports.SizeColumn=SizeColumn,exports.TimeColumn=TimeColumn;var _react=require("react"),_react2=_interopRequireDefault(_react),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_utils=require("../../flow/utils.js"),_utils2=require("../../utils.js");TLSColumn.headerClass="col-tls",TLSColumn.headerName="",IconColumn.headerClass="col-icon",IconColumn.headerName="",IconColumn.getIcon=function(e){if(!e.response)return"resource-icon-plain";var t=_utils.ResponseUtils.getContentType(e.response)||"";return 304===e.response.status_code?"resource-icon-not-modified":300<=e.response.status_code&&e.response.status_code<400?"resource-icon-redirect":t.indexOf("image")>=0?"resource-icon-image":t.indexOf("javascript")>=0?"resource-icon-js":t.indexOf("css")>=0?"resource-icon-css":t.indexOf("html")>=0?"resource-icon-document":"resource-icon-plain"},PathColumn.headerClass="col-path",PathColumn.headerName="Path",MethodColumn.headerClass="col-method",MethodColumn.headerName="Method",StatusColumn.headerClass="col-status",StatusColumn.headerName="Status",SizeColumn.getTotalSize=function(e){var t=e.request.contentLength;return e.response&&(t+=e.response.contentLength||0),t},SizeColumn.headerClass="col-size",SizeColumn.headerName="Size",TimeColumn.headerClass="col-time",TimeColumn.headerName="Time",exports.default=[TLSColumn,IconColumn,PathColumn,MethodColumn,StatusColumn,SizeColumn,TimeColumn];
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function TLSColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:(0,_classnames2.default)("col-tls","https"===t.request.scheme?"col-tls-https":"col-tls-http")})}function IconColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-icon"},_react2.default.createElement("div",{className:(0,_classnames2.default)("resource-icon",IconColumn.getIcon(t))}))}function PathColumn(e){var t=e.flow,s=void 0;return t.error&&(s="Connection killed."===t.error.msg?_react2.default.createElement("i",{className:"fa fa-fw fa-times pull-right"}):_react2.default.createElement("i",{className:"fa fa-fw fa-exclamation pull-right"})),_react2.default.createElement("td",{className:"col-path"},t.request.is_replay&&_react2.default.createElement("i",{className:"fa fa-fw fa-repeat pull-right"}),t.intercepted&&_react2.default.createElement("i",{className:"fa fa-fw fa-pause pull-right"}),s,_utils.RequestUtils.pretty_url(t.request))}function MethodColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-method"},t.request.method)}function StatusColumn(e){var t=e.flow,s="darkred";return t.response&&100<=t.response.status_code&&t.response.status_code<200?s="green":t.response&&200<=t.response.status_code&&t.response.status_code<300?s="darkgreen":t.response&&300<=t.response.status_code&&t.response.status_code<400?s="lightblue":t.response&&400<=t.response.status_code&&t.response.status_code<500?s="lightred":t.response&&500<=t.response.status_code&&t.response.status_code<600&&(s="lightred"),_react2.default.createElement("td",{className:"col-status",style:{color:s}},t.response&&t.response.status_code)}function SizeColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-size"},(0,_utils2.formatSize)(SizeColumn.getTotalSize(t)))}function TimeColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-time"},t.response?(0,_utils2.formatTimeDelta)(1e3*(t.response.timestamp_end-t.request.timestamp_start)):"...")}function TimeStampColumn(e){var t=e.flow;return _react2.default.createElement("td",{className:"col-start"},t.request.timestamp_start?(0,_utils2.formatTimeStamp)(t.request.timestamp_start):"...")}Object.defineProperty(exports,"__esModule",{value:!0}),exports.defaultColumnNames=void 0,exports.TLSColumn=TLSColumn,exports.IconColumn=IconColumn,exports.PathColumn=PathColumn,exports.MethodColumn=MethodColumn,exports.StatusColumn=StatusColumn,exports.SizeColumn=SizeColumn,exports.TimeColumn=TimeColumn,exports.TimeStampColumn=TimeStampColumn;var _react=require("react"),_react2=_interopRequireDefault(_react),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_utils=require("../../flow/utils.js"),_utils2=require("../../utils.js"),defaultColumnNames=exports.defaultColumnNames=["tls","icon","path","method","status","size","time"];TLSColumn.headerClass="col-tls",TLSColumn.headerName="",IconColumn.headerClass="col-icon",IconColumn.headerName="",IconColumn.getIcon=function(e){if(!e.response)return"resource-icon-plain";var t=_utils.ResponseUtils.getContentType(e.response)||"";return 304===e.response.status_code?"resource-icon-not-modified":300<=e.response.status_code&&e.response.status_code<400?"resource-icon-redirect":t.indexOf("image")>=0?"resource-icon-image":t.indexOf("javascript")>=0?"resource-icon-js":t.indexOf("css")>=0?"resource-icon-css":t.indexOf("html")>=0?"resource-icon-document":"resource-icon-plain"},PathColumn.headerClass="col-path",PathColumn.headerName="Path",MethodColumn.headerClass="col-method",MethodColumn.headerName="Method",StatusColumn.headerClass="col-status",StatusColumn.headerName="Status",SizeColumn.getTotalSize=function(e){var t=e.request.contentLength;return e.response&&(t+=e.response.contentLength||0),t},SizeColumn.headerClass="col-size",SizeColumn.headerName="Size",TimeColumn.headerClass="col-time",TimeColumn.headerName="Time",TimeStampColumn.headerClass="col-timestamp",TimeStampColumn.headerName="TimeStamp",exports.default=[TLSColumn,IconColumn,PathColumn,MethodColumn,StatusColumn,TimeStampColumn,SizeColumn,TimeColumn];
|
||||
|
||||
},{"../../flow/utils.js":68,"../../utils.js":70,"classnames":"classnames","react":"react"}],18:[function(require,module,exports){
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function FlowRow(e){var t=e.flow,r=e.selected,l=e.highlighted,s=e.onSelect,o=(0,_classnames2.default)({selected:r,highlighted:l,intercepted:t.intercepted,"has-request":t.request,"has-response":t.response});return _react2.default.createElement("tr",{className:o,onClick:function(){return s(t.id)}},_FlowColumns2.default.map(function(e){return _react2.default.createElement(e,{key:e.name,flow:t})}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_FlowColumns=require("./FlowColumns"),_FlowColumns2=_interopRequireDefault(_FlowColumns),_utils=require("../../utils");FlowRow.propTypes={onSelect:_propTypes2.default.func.isRequired,flow:_propTypes2.default.object.isRequired,highlighted:_propTypes2.default.bool,selected:_propTypes2.default.bool},exports.default=(0,_utils.pure)(FlowRow);
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function FlowRow(e){var t=e.flow,r=e.selected,l=e.highlighted,o=e.onSelect,s=e.displayColumnNames,u=(0,_classnames2.default)({selected:r,highlighted:l,intercepted:t.intercepted,"has-request":t.request,"has-response":t.response}),a=(0,_FlowTableHead.getDisplayColumns)(s);return _react2.default.createElement("tr",{className:u,onClick:function(){return o(t.id)}},a.map(function(e){return _react2.default.createElement(e,{key:e.name,flow:t})}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_FlowColumns=require("./FlowColumns"),_utils=require("../../utils"),_FlowTableHead=require("./FlowTableHead"),_reactRedux=require("react-redux");FlowRow.propTypes={onSelect:_propTypes2.default.func.isRequired,flow:_propTypes2.default.object.isRequired,highlighted:_propTypes2.default.bool,selected:_propTypes2.default.bool},exports.default=(0,_reactRedux.connect)(function(e){return{displayColumnNames:e.options.web_columns?e.options.web_columns.value:_FlowColumns.defaultColumnNames}})((0,_utils.pure)(FlowRow));
|
||||
|
||||
},{"../../utils":70,"./FlowColumns":17,"classnames":"classnames","prop-types":"prop-types","react":"react"}],19:[function(require,module,exports){
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function FlowTableHead(e){var r=e.sortColumn,t=e.sortDesc,s=e.setSort,o=t?"sort-desc":"sort-asc";return _react2.default.createElement("tr",null,_FlowColumns2.default.map(function(e){return _react2.default.createElement("th",{className:(0,_classnames2.default)(e.headerClass,r===e.name&&o),key:e.name,onClick:function(){return s(e.name,e.name===r&&!t)}},e.headerName)}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.FlowTableHead=FlowTableHead;var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_FlowColumns=require("./FlowColumns"),_FlowColumns2=_interopRequireDefault(_FlowColumns),_flows=require("../../ducks/flows");FlowTableHead.propTypes={setSort:_propTypes2.default.func.isRequired,sortDesc:_propTypes2.default.bool.isRequired,sortColumn:_propTypes2.default.string},exports.default=(0,_reactRedux.connect)(function(e){return{sortDesc:e.flows.sort.desc,sortColumn:e.flows.sort.column}},{setSort:_flows.setSort})(FlowTableHead);
|
||||
},{"../../utils":70,"./FlowColumns":17,"./FlowTableHead":19,"classnames":"classnames","prop-types":"prop-types","react":"react","react-redux":"react-redux"}],19:[function(require,module,exports){
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getDisplayColumns(e){var r=[];if(void 0===e)return _FlowColumns2.default;var o=!0,s=!1,t=void 0;try{for(var l,a=_FlowColumns2.default[Symbol.iterator]();!(o=(l=a.next()).done);o=!0){var u=l.value;e.includes(u.name.slice(0,-6).toLowerCase())&&r.push(u)}}catch(e){s=!0,t=e}finally{try{!o&&a.return&&a.return()}finally{if(s)throw t}}return r}function FlowTableHead(e){var r=e.sortColumn,o=e.sortDesc,s=e.setSort,t=e.displayColumnNames,l=o?"sort-desc":"sort-asc",a=getDisplayColumns(t);return _react2.default.createElement("tr",null,a.map(function(e){return _react2.default.createElement("th",{className:(0,_classnames2.default)(e.headerClass,r===e.name&&l),key:e.name,onClick:function(){return s(e.name,e.name===r&&!o)}},e.headerName)}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.getDisplayColumns=getDisplayColumns,exports.FlowTableHead=FlowTableHead;var _react=require("react"),_react2=_interopRequireDefault(_react),_propTypes=require("prop-types"),_propTypes2=_interopRequireDefault(_propTypes),_reactRedux=require("react-redux"),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_FlowColumns=require("./FlowColumns"),_FlowColumns2=_interopRequireDefault(_FlowColumns),_flows=require("../../ducks/flows");FlowTableHead.propTypes={setSort:_propTypes2.default.func.isRequired,sortDesc:_propTypes2.default.bool.isRequired,sortColumn:_propTypes2.default.string,displayColumnNames:_propTypes2.default.array},exports.default=(0,_reactRedux.connect)(function(e){return{sortDesc:e.flows.sort.desc,sortColumn:e.flows.sort.column,displayColumnNames:e.options.web_columns?e.options.web_columns.value:_FlowColumns.defaultColumnNames}},{setSort:_flows.setSort})(FlowTableHead);
|
||||
|
||||
},{"../../ducks/flows":56,"./FlowColumns":17,"classnames":"classnames","prop-types":"prop-types","react":"react","react-redux":"react-redux"}],20:[function(require,module,exports){
|
||||
"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function FlowView(e){var r=e.flow,a=e.tabName,t=e.selectTab,s=["request","response","error"].filter(function(e){return r[e]});s.push("details"),s.indexOf(a)<0&&(a="response"===a&&r.error?"error":"error"===a&&r.response?"response":s[0]);var l=allTabs[_lodash2.default.capitalize(a)];return _react2.default.createElement("div",{className:"flow-detail"},_react2.default.createElement(_Nav2.default,{tabs:s,active:a,onSelectTab:t}),_react2.default.createElement(l,{flow:r}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.allTabs=void 0;var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_Nav=require("./FlowView/Nav"),_Nav2=_interopRequireDefault(_Nav),_Messages=require("./FlowView/Messages"),_Details=require("./FlowView/Details"),_Details2=_interopRequireDefault(_Details),_flow=require("../ducks/ui/flow"),allTabs=exports.allTabs={Request:_Messages.Request,Response:_Messages.Response,Error:_Messages.ErrorView,Details:_Details2.default};exports.default=(0,_reactRedux.connect)(function(e){return{flow:e.flows.byId[e.flows.selected[0]],tabName:e.ui.flow.tab}},{selectTab:_flow.selectTab})(FlowView);
|
||||
|
@ -1,6 +1,8 @@
|
||||
import webbrowser
|
||||
|
||||
from mitmproxy import ctx
|
||||
from typing import Sequence
|
||||
|
||||
|
||||
|
||||
class WebAddon:
|
||||
@ -21,6 +23,10 @@ class WebAddon:
|
||||
"web_host", str, "127.0.0.1",
|
||||
"Web UI host."
|
||||
)
|
||||
loader.add_option(
|
||||
"web_columns", Sequence[str], ["tls", "icon", "path", "method", "status", "size", "time"],
|
||||
"Columns to show in the flow list"
|
||||
)
|
||||
|
||||
def running(self):
|
||||
if hasattr(ctx.options, "web_open_browser") and ctx.options.web_open_browser:
|
||||
|
@ -125,6 +125,9 @@
|
||||
.col-time {
|
||||
width: 50px;
|
||||
}
|
||||
.col-timestamp {
|
||||
width: auto;
|
||||
}
|
||||
td.col-time, td.col-size {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -1,12 +1,17 @@
|
||||
import React from 'react'
|
||||
import renderer from 'react-test-renderer'
|
||||
import FlowRow from '../../../components/FlowTable/FlowRow'
|
||||
import { TFlow } from '../../ducks/tutils'
|
||||
import { TFlow, TStore } from '../../ducks/tutils'
|
||||
import { Provider } from 'react-redux'
|
||||
|
||||
describe('FlowRow Component', () => {
|
||||
let tFlow = new TFlow(),
|
||||
selectFn = jest.fn(),
|
||||
flowRow = renderer.create(<FlowRow flow={tFlow} onSelect={selectFn}/>),
|
||||
store = TStore(),
|
||||
flowRow = renderer.create(
|
||||
<Provider store={store} >
|
||||
<FlowRow flow={tFlow} onSelect={selectFn}/>
|
||||
</Provider>),
|
||||
tree = flowRow.toJSON()
|
||||
|
||||
it('should render correctly', () => {
|
||||
|
@ -7,7 +7,11 @@ import { TStore } from '../../ducks/tutils'
|
||||
|
||||
describe('FlowTableHead Component', () => {
|
||||
let sortFn = jest.fn(),
|
||||
flowTableHead = renderer.create(<FlowTableHead setSort={sortFn} sortDesc={true}/>),
|
||||
store = TStore(),
|
||||
flowTableHead = renderer.create(
|
||||
<Provider store={store}>
|
||||
<FlowTableHead setSort={sortFn} sortDesc={true}/>
|
||||
</Provider>),
|
||||
tree =flowTableHead.toJSON()
|
||||
|
||||
it('should render correctly', () => {
|
||||
|
@ -79,6 +79,12 @@ exports[`FlowTableHead Component should render correctly 1`] = `
|
||||
>
|
||||
Status
|
||||
</th>
|
||||
<th
|
||||
className="col-timestamp"
|
||||
onClick={[Function]}
|
||||
>
|
||||
TimeStamp
|
||||
</th>
|
||||
<th
|
||||
className="col-size"
|
||||
onClick={[Function]}
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React, { Component } from 'react'
|
||||
import classnames from 'classnames'
|
||||
import { RequestUtils, ResponseUtils } from '../../flow/utils.js'
|
||||
import { formatSize, formatTimeDelta } from '../../utils.js'
|
||||
import { formatSize, formatTimeDelta, formatTimeStamp } from '../../utils.js'
|
||||
|
||||
export const defaultColumnNames = ["tls", "icon", "path", "method", "status", "size", "time"]
|
||||
|
||||
export function TLSColumn({ flow }) {
|
||||
return (
|
||||
@ -148,12 +150,28 @@ export function TimeColumn({ flow }) {
|
||||
TimeColumn.headerClass = 'col-time'
|
||||
TimeColumn.headerName = 'Time'
|
||||
|
||||
export function TimeStampColumn({ flow }) {
|
||||
return (
|
||||
<td className="col-start">
|
||||
{flow.request.timestamp_start ? (
|
||||
formatTimeStamp(flow.request.timestamp_start)
|
||||
) : (
|
||||
'...'
|
||||
)}
|
||||
</td>
|
||||
)
|
||||
}
|
||||
|
||||
TimeStampColumn.headerClass = 'col-timestamp'
|
||||
TimeStampColumn.headerName = 'TimeStamp'
|
||||
|
||||
export default [
|
||||
TLSColumn,
|
||||
IconColumn,
|
||||
PathColumn,
|
||||
MethodColumn,
|
||||
StatusColumn,
|
||||
TimeStampColumn,
|
||||
SizeColumn,
|
||||
TimeColumn,
|
||||
]
|
||||
|
@ -1,8 +1,10 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import columns from './FlowColumns'
|
||||
import {defaultColumnNames} from './FlowColumns'
|
||||
import { pure } from '../../utils'
|
||||
import {getDisplayColumns} from './FlowTableHead'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
FlowRow.propTypes = {
|
||||
onSelect: PropTypes.func.isRequired,
|
||||
@ -11,7 +13,7 @@ FlowRow.propTypes = {
|
||||
selected: PropTypes.bool,
|
||||
}
|
||||
|
||||
function FlowRow({ flow, selected, highlighted, onSelect }) {
|
||||
function FlowRow({ flow, selected, highlighted, onSelect, displayColumnNames }) {
|
||||
const className = classnames({
|
||||
'selected': selected,
|
||||
'highlighted': highlighted,
|
||||
@ -20,13 +22,19 @@ function FlowRow({ flow, selected, highlighted, onSelect }) {
|
||||
'has-response': flow.response,
|
||||
})
|
||||
|
||||
const displayColumns = getDisplayColumns(displayColumnNames)
|
||||
|
||||
return (
|
||||
<tr className={className} onClick={() => onSelect(flow.id)}>
|
||||
{columns.map(Column => (
|
||||
{displayColumns.map(Column => (
|
||||
<Column key={Column.name} flow={flow}/>
|
||||
))}
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
export default pure(FlowRow)
|
||||
export default connect(
|
||||
state => ({
|
||||
displayColumnNames: state.options["web_columns"] ? state.options["web_columns"].value : defaultColumnNames,
|
||||
})
|
||||
)(pure(FlowRow))
|
||||
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import classnames from 'classnames'
|
||||
import columns from './FlowColumns'
|
||||
import columns, {defaultColumnNames} from './FlowColumns'
|
||||
|
||||
import { setSort } from '../../ducks/flows'
|
||||
|
||||
@ -10,14 +10,30 @@ FlowTableHead.propTypes = {
|
||||
setSort: PropTypes.func.isRequired,
|
||||
sortDesc: PropTypes.bool.isRequired,
|
||||
sortColumn: PropTypes.string,
|
||||
displayColumnNames: PropTypes.array,
|
||||
}
|
||||
|
||||
export function FlowTableHead({ sortColumn, sortDesc, setSort }) {
|
||||
export function getDisplayColumns(displayColumnNames) {
|
||||
let displayColumns = []
|
||||
if (typeof displayColumnNames == "undefined") {
|
||||
return columns
|
||||
}
|
||||
for (const column of columns) {
|
||||
if (displayColumnNames.includes(column.name.slice(0,-6).toLowerCase())) {
|
||||
displayColumns.push(column)
|
||||
}
|
||||
}
|
||||
return displayColumns
|
||||
}
|
||||
|
||||
export function FlowTableHead({ sortColumn, sortDesc, setSort, displayColumnNames}) {
|
||||
const sortType = sortDesc ? 'sort-desc' : 'sort-asc'
|
||||
|
||||
const displayColumns = getDisplayColumns(displayColumnNames)
|
||||
|
||||
return (
|
||||
<tr>
|
||||
{columns.map(Column => (
|
||||
{displayColumns.map(Column => (
|
||||
<th className={classnames(Column.headerClass, sortColumn === Column.name && sortType)}
|
||||
key={Column.name}
|
||||
onClick={() => setSort(Column.name, Column.name !== sortColumn ? false : !sortDesc)}>
|
||||
@ -32,6 +48,7 @@ export default connect(
|
||||
state => ({
|
||||
sortDesc: state.flows.sort.desc,
|
||||
sortColumn: state.flows.sort.column,
|
||||
displayColumnNames: state.options["web_columns"] ? state.options["web_columns"].value : defaultColumnNames,
|
||||
}),
|
||||
{
|
||||
setSort
|
||||
|
Loading…
Reference in New Issue
Block a user