mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 07:08:10 +00:00
[web] style flow menu
This commit is contained in:
parent
6540aedaab
commit
d1c7b203f0
@ -3,7 +3,6 @@
|
||||
|
||||
@menu-height: 85px;
|
||||
|
||||
|
||||
header {
|
||||
padding-top: 6px;
|
||||
background-color: white;
|
||||
@ -18,35 +17,62 @@ header {
|
||||
}
|
||||
}
|
||||
|
||||
@menu-legend-height: 16px;
|
||||
@menu-group-hmargin: 3px;
|
||||
.menu-group {
|
||||
@description-height: 16px;
|
||||
margin: 0 @menu-group-hmargin;
|
||||
display: inline-block;
|
||||
height: @menu-height;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.entry {
|
||||
height: (@menu-height - @description-height)/3;
|
||||
line-height: 1;
|
||||
padding: 0.5rem 1rem;
|
||||
.menu-content {
|
||||
height: @menu-height - @menu-legend-height;
|
||||
text-align: center;
|
||||
|
||||
label {
|
||||
font-size: 1.2rem;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
margin: 0 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
.description {
|
||||
height: @description-height;
|
||||
> .btn {
|
||||
height: @menu-height - @menu-legend-height;
|
||||
text-align: center;
|
||||
font-size: 0.9rem;
|
||||
margin: 0 1px;
|
||||
padding: 12px 5px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
i {
|
||||
font-size: 20px;
|
||||
display: block;
|
||||
margin: 0 auto 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-entry {
|
||||
height: (@menu-height - @menu-legend-height)/3;
|
||||
line-height: 1;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
label {
|
||||
font-size: 1.2rem;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
}
|
||||
input[type=checkbox] {
|
||||
margin: 0 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.menu-legend {
|
||||
height: @menu-legend-height;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.menu-group + .menu-group:before {
|
||||
@space: 10px;
|
||||
margin-left: -@menu-group-hmargin;
|
||||
content: " ";
|
||||
border-left: solid 1px lighten(grey, 40%);
|
||||
margin-top: @space;
|
||||
@ -68,11 +94,11 @@ header {
|
||||
|
||||
padding: 2px 2.5px;
|
||||
|
||||
>.form-control,> .input-group-addon, > .input-group-btn>.btn {
|
||||
height: 23.5px;
|
||||
padding: 1px 5px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
> .form-control, > .input-group-addon, > .input-group-btn > .btn {
|
||||
height: 23.5px;
|
||||
padding: 1px 5px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import Button from '../common/Button'
|
||||
import { MessageUtils } from '../../flow/utils.js'
|
||||
import * as flowsActions from '../../ducks/flows'
|
||||
import React, { PropTypes } from "react"
|
||||
import { connect } from "react-redux"
|
||||
import Button from "../common/Button"
|
||||
import { MessageUtils } from "../../flow/utils.js"
|
||||
import * as flowsActions from "../../ducks/flows"
|
||||
|
||||
FlowMenu.title = 'Flow'
|
||||
|
||||
FlowMenu.propTypes = {
|
||||
flow: PropTypes.object.isRequired,
|
||||
flow: PropTypes.object,
|
||||
acceptFlow: PropTypes.func.isRequired,
|
||||
replayFlow: PropTypes.func.isRequired,
|
||||
duplicateFlow: PropTypes.func.isRequired,
|
||||
@ -16,14 +16,52 @@ FlowMenu.propTypes = {
|
||||
}
|
||||
|
||||
function FlowMenu({ flow, acceptFlow, replayFlow, duplicateFlow, removeFlow, revertFlow }) {
|
||||
if (!flow)
|
||||
return <div/>
|
||||
return (
|
||||
<div>
|
||||
<Button disabled={!flow || !flow.intercepted} title="[a]ccept intercepted flow" text="Accept" icon="fa-play" onClick={() => acceptFlow(flow)} />
|
||||
<Button title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={() => replayFlow(flow)} />
|
||||
<Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={() => duplicateFlow(flow)} />
|
||||
<Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={() => removeFlow(flow)}/>
|
||||
<Button disabled={!flow || !flow.modified} title="revert changes to flow [V]" text="Revert" icon="fa-history" onClick={() => revertFlow(flow)} />
|
||||
<Button title="download" text="Download" icon="fa-download" onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}/>
|
||||
<div className="menu-group">
|
||||
<div className="menu-content">
|
||||
<Button title="[r]eplay flow" icon="fa-repeat text-primary" onClick={() => replayFlow(flow)}>
|
||||
Replay
|
||||
</Button>
|
||||
<Button title="[D]uplicate flow" icon="fa-copy text-info"
|
||||
onClick={() => duplicateFlow(flow)}>
|
||||
Duplicate
|
||||
</Button>
|
||||
<Button disabled={!flow || !flow.modified} title="revert changes to flow [V]"
|
||||
icon="fa-history text-warning" onClick={() => revertFlow(flow)}>
|
||||
Revert
|
||||
</Button>
|
||||
<Button title="[d]elete flow" icon="fa-trash text-danger" onClick={() => removeFlow(flow)}>
|
||||
Delete
|
||||
</Button>
|
||||
</div>
|
||||
<div className="menu-legend">Flow Modification</div>
|
||||
</div>
|
||||
<div className="menu-group">
|
||||
<div className="menu-content">
|
||||
<Button title="download" icon="fa-download"
|
||||
onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}>
|
||||
Download
|
||||
</Button>
|
||||
</div>
|
||||
<div className="menu-legend">Export</div>
|
||||
</div>
|
||||
<div className="menu-group">
|
||||
<div className="menu-content">
|
||||
<Button disabled={!flow || !flow.intercepted} title="[a]ccept intercepted flow"
|
||||
icon="fa-play text-success" onClick={() => acceptFlow(flow)}
|
||||
>
|
||||
Resume
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
<div className="menu-legend">Interception</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ MenuToggle.propTypes = {
|
||||
|
||||
export function MenuToggle({ value, onChange, children }) {
|
||||
return (
|
||||
<div className="entry">
|
||||
<div className="menu-entry">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
value={value}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import {SettingsToggle, EventlogToggle} from './MenuToggle'
|
||||
import DocsLink from '../common/DocsLink'
|
||||
import React, { PropTypes } from "react"
|
||||
import { connect } from "react-redux"
|
||||
import { SettingsToggle, EventlogToggle } from "./MenuToggle"
|
||||
import DocsLink from "../common/DocsLink"
|
||||
|
||||
OptionMenu.title = 'Options'
|
||||
|
||||
@ -9,51 +9,57 @@ export default function OptionMenu() {
|
||||
return (
|
||||
<div>
|
||||
<div className="menu-group">
|
||||
<SettingsToggle setting="http2">HTTP/2.0</SettingsToggle>
|
||||
<SettingsToggle setting="websocket">WebSockets</SettingsToggle>
|
||||
<SettingsToggle setting="rawtcp">Raw TCP</SettingsToggle>
|
||||
<div className="description">Protocol Support</div>
|
||||
<div className="menu-content">
|
||||
<SettingsToggle setting="http2">HTTP/2.0</SettingsToggle>
|
||||
<SettingsToggle setting="websocket">WebSockets</SettingsToggle>
|
||||
<SettingsToggle setting="rawtcp">Raw TCP</SettingsToggle>
|
||||
</div>
|
||||
<div className="menu-legend">Protocol Support</div>
|
||||
</div>
|
||||
<div className="menu-group">
|
||||
<SettingsToggle setting="anticache">
|
||||
Disable Caching <DocsLink resource="features/anticache.html"/>
|
||||
</SettingsToggle>
|
||||
<SettingsToggle setting="anticomp">
|
||||
Disable Compression <i className="fa fa-question-circle" title="Do not forward Accept-Encoding headers to the server to force an uncompressed response."></i>
|
||||
</SettingsToggle>
|
||||
<div className="entry"/>
|
||||
<div className="description">HTTP Options</div>
|
||||
<div className="menu-content">
|
||||
<SettingsToggle setting="anticache">
|
||||
Disable Caching <DocsLink resource="features/anticache.html"/>
|
||||
</SettingsToggle>
|
||||
<SettingsToggle setting="anticomp">
|
||||
Disable Compression <i className="fa fa-question-circle"
|
||||
title="Do not forward Accept-Encoding headers to the server to force an uncompressed response."></i>
|
||||
</SettingsToggle>
|
||||
</div>
|
||||
<div className="menu-legend">HTTP Options</div>
|
||||
</div>
|
||||
<div className="menu-group">
|
||||
<SettingsToggle setting="showhost">
|
||||
Use Host Header <i className="fa fa-question-circle" title="Use the Host header to construct URLs for display."></i>
|
||||
</SettingsToggle>
|
||||
<EventlogToggle/>
|
||||
<div className="entry"/>
|
||||
<div className="description">View Options</div>
|
||||
<div className="menu-content">
|
||||
<SettingsToggle setting="showhost">
|
||||
Use Host Header <i className="fa fa-question-circle"
|
||||
title="Use the Host header to construct URLs for display."></i>
|
||||
</SettingsToggle>
|
||||
<EventlogToggle/>
|
||||
</div>
|
||||
<div className="menu-legend">View Options</div>
|
||||
</div>
|
||||
{ /*
|
||||
<ToggleButton text="no_upstream_cert"
|
||||
checked={settings.no_upstream_cert}
|
||||
onToggle={() => updateSettings({ no_upstream_cert: !settings.no_upstream_cert })}
|
||||
/>
|
||||
<ToggleInputButton name="stickyauth" placeholder="Sticky auth filter"
|
||||
checked={!!settings.stickyauth}
|
||||
txt={settings.stickyauth}
|
||||
onToggleChanged={txt => updateSettings({ stickyauth: !settings.stickyauth ? txt : null })}
|
||||
/>
|
||||
<ToggleInputButton name="stickycookie" placeholder="Sticky cookie filter"
|
||||
checked={!!settings.stickycookie}
|
||||
txt={settings.stickycookie}
|
||||
onToggleChanged={txt => updateSettings({ stickycookie: !settings.stickycookie ? txt : null })}
|
||||
/>
|
||||
<ToggleInputButton name="stream_large_bodies" placeholder="stream..."
|
||||
checked={!!settings.stream_large_bodies}
|
||||
txt={settings.stream_large_bodies}
|
||||
inputType="number"
|
||||
onToggleChanged={txt => updateSettings({ stream_large_bodies: !settings.stream_large_bodies ? txt : null })}
|
||||
/>
|
||||
*/}
|
||||
<ToggleButton text="no_upstream_cert"
|
||||
checked={settings.no_upstream_cert}
|
||||
onToggle={() => updateSettings({ no_upstream_cert: !settings.no_upstream_cert })}
|
||||
/>
|
||||
<ToggleInputButton name="stickyauth" placeholder="Sticky auth filter"
|
||||
checked={!!settings.stickyauth}
|
||||
txt={settings.stickyauth}
|
||||
onToggleChanged={txt => updateSettings({ stickyauth: !settings.stickyauth ? txt : null })}
|
||||
/>
|
||||
<ToggleInputButton name="stickycookie" placeholder="Sticky cookie filter"
|
||||
checked={!!settings.stickycookie}
|
||||
txt={settings.stickycookie}
|
||||
onToggleChanged={txt => updateSettings({ stickycookie: !settings.stickycookie ? txt : null })}
|
||||
/>
|
||||
<ToggleInputButton name="stream_large_bodies" placeholder="stream..."
|
||||
checked={!!settings.stream_large_bodies}
|
||||
txt={settings.stream_large_bodies}
|
||||
inputType="number"
|
||||
onToggleChanged={txt => updateSettings({ stream_large_bodies: !settings.stream_large_bodies ? txt : null })}
|
||||
/>
|
||||
*/}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,19 +1,21 @@
|
||||
import React, { PropTypes } from 'react'
|
||||
import classnames from 'classnames'
|
||||
import React, { PropTypes } from "react"
|
||||
import classnames from "classnames"
|
||||
|
||||
Button.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
text: PropTypes.string,
|
||||
icon: PropTypes.string
|
||||
children: PropTypes.node.isRequired,
|
||||
icon: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
}
|
||||
|
||||
export default function Button({ onClick, text, icon, disabled, className }) {
|
||||
export default function Button({ onClick, children, icon, disabled, className, title }) {
|
||||
return (
|
||||
<div className={classnames(className, 'btn btn-default')}
|
||||
onClick={onClick}
|
||||
disabled={disabled}>
|
||||
disabled={disabled}
|
||||
title={title}>
|
||||
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
||||
{text && text}
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user