mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 00:01:36 +00:00
[web] style flow menu
This commit is contained in:
parent
6540aedaab
commit
d1c7b203f0
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
@menu-height: 85px;
|
@menu-height: 85px;
|
||||||
|
|
||||||
|
|
||||||
header {
|
header {
|
||||||
padding-top: 6px;
|
padding-top: 6px;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -18,14 +17,37 @@ header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@menu-legend-height: 16px;
|
||||||
|
@menu-group-hmargin: 3px;
|
||||||
.menu-group {
|
.menu-group {
|
||||||
@description-height: 16px;
|
margin: 0 @menu-group-hmargin;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: @menu-height;
|
height: @menu-height;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
.entry {
|
.menu-content {
|
||||||
height: (@menu-height - @description-height)/3;
|
height: @menu-height - @menu-legend-height;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
> .btn {
|
||||||
|
height: @menu-height - @menu-legend-height;
|
||||||
|
text-align: center;
|
||||||
|
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;
|
line-height: 1;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
|
|
||||||
@ -38,15 +60,19 @@ header {
|
|||||||
margin: 0 2px;
|
margin: 0 2px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.description {
|
|
||||||
height: @description-height;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.menu-legend {
|
||||||
|
height: @menu-legend-height;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
.menu-group + .menu-group:before {
|
.menu-group + .menu-group:before {
|
||||||
@space: 10px;
|
@space: 10px;
|
||||||
|
margin-left: -@menu-group-hmargin;
|
||||||
content: " ";
|
content: " ";
|
||||||
border-left: solid 1px lighten(grey, 40%);
|
border-left: solid 1px lighten(grey, 40%);
|
||||||
margin-top: @space;
|
margin-top: @space;
|
||||||
@ -68,7 +94,7 @@ header {
|
|||||||
|
|
||||||
padding: 2px 2.5px;
|
padding: 2px 2.5px;
|
||||||
|
|
||||||
>.form-control,> .input-group-addon, > .input-group-btn>.btn {
|
> .form-control, > .input-group-addon, > .input-group-btn > .btn {
|
||||||
height: 23.5px;
|
height: 23.5px;
|
||||||
padding: 1px 5px;
|
padding: 1px 5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from "react"
|
||||||
import { connect } from 'react-redux'
|
import { connect } from "react-redux"
|
||||||
import Button from '../common/Button'
|
import Button from "../common/Button"
|
||||||
import { MessageUtils } from '../../flow/utils.js'
|
import { MessageUtils } from "../../flow/utils.js"
|
||||||
import * as flowsActions from '../../ducks/flows'
|
import * as flowsActions from "../../ducks/flows"
|
||||||
|
|
||||||
FlowMenu.title = 'Flow'
|
FlowMenu.title = 'Flow'
|
||||||
|
|
||||||
FlowMenu.propTypes = {
|
FlowMenu.propTypes = {
|
||||||
flow: PropTypes.object.isRequired,
|
flow: PropTypes.object,
|
||||||
acceptFlow: PropTypes.func.isRequired,
|
acceptFlow: PropTypes.func.isRequired,
|
||||||
replayFlow: PropTypes.func.isRequired,
|
replayFlow: PropTypes.func.isRequired,
|
||||||
duplicateFlow: PropTypes.func.isRequired,
|
duplicateFlow: PropTypes.func.isRequired,
|
||||||
@ -16,14 +16,52 @@ FlowMenu.propTypes = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function FlowMenu({ flow, acceptFlow, replayFlow, duplicateFlow, removeFlow, revertFlow }) {
|
function FlowMenu({ flow, acceptFlow, replayFlow, duplicateFlow, removeFlow, revertFlow }) {
|
||||||
|
if (!flow)
|
||||||
|
return <div/>
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button disabled={!flow || !flow.intercepted} title="[a]ccept intercepted flow" text="Accept" icon="fa-play" onClick={() => acceptFlow(flow)} />
|
<div className="menu-group">
|
||||||
<Button title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={() => replayFlow(flow)} />
|
<div className="menu-content">
|
||||||
<Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={() => duplicateFlow(flow)} />
|
<Button title="[r]eplay flow" icon="fa-repeat text-primary" onClick={() => replayFlow(flow)}>
|
||||||
<Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={() => removeFlow(flow)}/>
|
Replay
|
||||||
<Button disabled={!flow || !flow.modified} title="revert changes to flow [V]" text="Revert" icon="fa-history" onClick={() => revertFlow(flow)} />
|
</Button>
|
||||||
<Button title="download" text="Download" icon="fa-download" onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}/>
|
<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>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ MenuToggle.propTypes = {
|
|||||||
|
|
||||||
export function MenuToggle({ value, onChange, children }) {
|
export function MenuToggle({ value, onChange, children }) {
|
||||||
return (
|
return (
|
||||||
<div className="entry">
|
<div className="menu-entry">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
value={value}
|
value={value}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from "react"
|
||||||
import { connect } from 'react-redux'
|
import { connect } from "react-redux"
|
||||||
import {SettingsToggle, EventlogToggle} from './MenuToggle'
|
import { SettingsToggle, EventlogToggle } from "./MenuToggle"
|
||||||
import DocsLink from '../common/DocsLink'
|
import DocsLink from "../common/DocsLink"
|
||||||
|
|
||||||
OptionMenu.title = 'Options'
|
OptionMenu.title = 'Options'
|
||||||
|
|
||||||
@ -9,28 +9,34 @@ export default function OptionMenu() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="menu-group">
|
<div className="menu-group">
|
||||||
|
<div className="menu-content">
|
||||||
<SettingsToggle setting="http2">HTTP/2.0</SettingsToggle>
|
<SettingsToggle setting="http2">HTTP/2.0</SettingsToggle>
|
||||||
<SettingsToggle setting="websocket">WebSockets</SettingsToggle>
|
<SettingsToggle setting="websocket">WebSockets</SettingsToggle>
|
||||||
<SettingsToggle setting="rawtcp">Raw TCP</SettingsToggle>
|
<SettingsToggle setting="rawtcp">Raw TCP</SettingsToggle>
|
||||||
<div className="description">Protocol Support</div>
|
</div>
|
||||||
|
<div className="menu-legend">Protocol Support</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="menu-group">
|
<div className="menu-group">
|
||||||
|
<div className="menu-content">
|
||||||
<SettingsToggle setting="anticache">
|
<SettingsToggle setting="anticache">
|
||||||
Disable Caching <DocsLink resource="features/anticache.html"/>
|
Disable Caching <DocsLink resource="features/anticache.html"/>
|
||||||
</SettingsToggle>
|
</SettingsToggle>
|
||||||
<SettingsToggle setting="anticomp">
|
<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>
|
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>
|
</SettingsToggle>
|
||||||
<div className="entry"/>
|
</div>
|
||||||
<div className="description">HTTP Options</div>
|
<div className="menu-legend">HTTP Options</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="menu-group">
|
<div className="menu-group">
|
||||||
|
<div className="menu-content">
|
||||||
<SettingsToggle setting="showhost">
|
<SettingsToggle setting="showhost">
|
||||||
Use Host Header <i className="fa fa-question-circle" title="Use the Host header to construct URLs for display."></i>
|
Use Host Header <i className="fa fa-question-circle"
|
||||||
|
title="Use the Host header to construct URLs for display."></i>
|
||||||
</SettingsToggle>
|
</SettingsToggle>
|
||||||
<EventlogToggle/>
|
<EventlogToggle/>
|
||||||
<div className="entry"/>
|
</div>
|
||||||
<div className="description">View Options</div>
|
<div className="menu-legend">View Options</div>
|
||||||
</div>
|
</div>
|
||||||
{ /*
|
{ /*
|
||||||
<ToggleButton text="no_upstream_cert"
|
<ToggleButton text="no_upstream_cert"
|
||||||
|
@ -1,19 +1,21 @@
|
|||||||
import React, { PropTypes } from 'react'
|
import React, { PropTypes } from "react"
|
||||||
import classnames from 'classnames'
|
import classnames from "classnames"
|
||||||
|
|
||||||
Button.propTypes = {
|
Button.propTypes = {
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
text: PropTypes.string,
|
children: PropTypes.node.isRequired,
|
||||||
icon: PropTypes.string
|
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 (
|
return (
|
||||||
<div className={classnames(className, 'btn btn-default')}
|
<div className={classnames(className, 'btn btn-default')}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
disabled={disabled}>
|
disabled={disabled}
|
||||||
|
title={title}>
|
||||||
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
||||||
{text && text}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user