make columns configurable and customizable

This commit is contained in:
gorogoroumaru 2020-08-30 13:10:11 +00:00 committed by Maximilian Hils
parent c996f1ee74
commit 1efe44745b
11 changed files with 79 additions and 11 deletions

View File

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

Binary file not shown.

Binary file not shown.

View File

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

View File

@ -125,6 +125,9 @@
.col-time {
width: 50px;
}
.col-timestamp {
width: auto;
}
td.col-time, td.col-size {
text-align: right;
}

View File

@ -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', () => {

View File

@ -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', () => {

View File

@ -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]}

View File

@ -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,
]

View File

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

View File

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