[web] style flow menu

This commit is contained in:
Maximilian Hils 2016-12-11 19:59:54 +01:00
parent 6540aedaab
commit d1c7b203f0
5 changed files with 159 additions and 87 deletions

View File

@ -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,35 +17,62 @@ 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;
line-height: 1; text-align: center;
padding: 0.5rem 1rem;
label { > .btn {
font-size: 1.2rem; height: @menu-height - @menu-legend-height;
font-weight: normal;
margin: 0;
}
input[type=checkbox] {
margin: 0 2px;
vertical-align: middle;
}
}
.description {
height: @description-height;
text-align: center; 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 { .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,11 +94,11 @@ 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;
line-height: 1.5; line-height: 1.5;
} }
} }
} }

View File

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

View File

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

View File

@ -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,51 +9,57 @@ export default function OptionMenu() {
return ( return (
<div> <div>
<div className="menu-group"> <div className="menu-group">
<SettingsToggle setting="http2">HTTP/2.0</SettingsToggle> <div className="menu-content">
<SettingsToggle setting="websocket">WebSockets</SettingsToggle> <SettingsToggle setting="http2">HTTP/2.0</SettingsToggle>
<SettingsToggle setting="rawtcp">Raw TCP</SettingsToggle> <SettingsToggle setting="websocket">WebSockets</SettingsToggle>
<div className="description">Protocol Support</div> <SettingsToggle setting="rawtcp">Raw TCP</SettingsToggle>
</div>
<div className="menu-legend">Protocol Support</div>
</div> </div>
<div className="menu-group"> <div className="menu-group">
<SettingsToggle setting="anticache"> <div className="menu-content">
Disable Caching <DocsLink resource="features/anticache.html"/> <SettingsToggle setting="anticache">
</SettingsToggle> Disable Caching <DocsLink resource="features/anticache.html"/>
<SettingsToggle setting="anticomp"> </SettingsToggle>
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 setting="anticomp">
</SettingsToggle> Disable Compression <i className="fa fa-question-circle"
<div className="entry"/> title="Do not forward Accept-Encoding headers to the server to force an uncompressed response."></i>
<div className="description">HTTP Options</div> </SettingsToggle>
</div>
<div className="menu-legend">HTTP Options</div>
</div> </div>
<div className="menu-group"> <div className="menu-group">
<SettingsToggle setting="showhost"> <div className="menu-content">
Use Host Header <i className="fa fa-question-circle" title="Use the Host header to construct URLs for display."></i> <SettingsToggle setting="showhost">
</SettingsToggle> Use Host Header <i className="fa fa-question-circle"
<EventlogToggle/> title="Use the Host header to construct URLs for display."></i>
<div className="entry"/> </SettingsToggle>
<div className="description">View Options</div> <EventlogToggle/>
</div>
<div className="menu-legend">View Options</div>
</div> </div>
{ /* { /*
<ToggleButton text="no_upstream_cert" <ToggleButton text="no_upstream_cert"
checked={settings.no_upstream_cert} checked={settings.no_upstream_cert}
onToggle={() => updateSettings({ no_upstream_cert: !settings.no_upstream_cert })} onToggle={() => updateSettings({ no_upstream_cert: !settings.no_upstream_cert })}
/> />
<ToggleInputButton name="stickyauth" placeholder="Sticky auth filter" <ToggleInputButton name="stickyauth" placeholder="Sticky auth filter"
checked={!!settings.stickyauth} checked={!!settings.stickyauth}
txt={settings.stickyauth} txt={settings.stickyauth}
onToggleChanged={txt => updateSettings({ stickyauth: !settings.stickyauth ? txt : null })} onToggleChanged={txt => updateSettings({ stickyauth: !settings.stickyauth ? txt : null })}
/> />
<ToggleInputButton name="stickycookie" placeholder="Sticky cookie filter" <ToggleInputButton name="stickycookie" placeholder="Sticky cookie filter"
checked={!!settings.stickycookie} checked={!!settings.stickycookie}
txt={settings.stickycookie} txt={settings.stickycookie}
onToggleChanged={txt => updateSettings({ stickycookie: !settings.stickycookie ? txt : null })} onToggleChanged={txt => updateSettings({ stickycookie: !settings.stickycookie ? txt : null })}
/> />
<ToggleInputButton name="stream_large_bodies" placeholder="stream..." <ToggleInputButton name="stream_large_bodies" placeholder="stream..."
checked={!!settings.stream_large_bodies} checked={!!settings.stream_large_bodies}
txt={settings.stream_large_bodies} txt={settings.stream_large_bodies}
inputType="number" inputType="number"
onToggleChanged={txt => updateSettings({ stream_large_bodies: !settings.stream_large_bodies ? txt : null })} onToggleChanged={txt => updateSettings({ stream_large_bodies: !settings.stream_large_bodies ? txt : null })}
/> />
*/} */}
</div> </div>
) )
} }

View File

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