web: add file menu stub

This commit is contained in:
Maximilian Hils 2014-12-10 17:44:45 +01:00
parent 7e40b8ab09
commit 93e928dec4
3 changed files with 2494 additions and 46 deletions

View File

@ -72,28 +72,6 @@ var formatTimeStamp = function (seconds) {
};
function listToDict(list, propKey, propVal) {
var dict = {};
for (var i = 0; i < list.length; i++) {
var e = list[i];
dict[e[propKey]] = e[propVal];
}
return dict;
}
function dictToList(dict, propKey, propVal) {
var list = [];
for (var key in dict) {
if (dict.hasOwnProperty(key)) {
var elem = {};
elem[propKey] = key;
elem[propVal] = dict[key];
list.push(elem);
}
}
return list;
}
function EventEmitter() {
this.listeners = {};
}
@ -165,14 +143,9 @@ var ActionTypes = {
CONNECTION_CLOSE: "connection_close",
CONNECTION_ERROR: "connection_error",
// Settings
// Stores
SETTINGS_STORE: "settings",
UPDATE_SETTINGS: "update_settings",
// EventLog
EVENT_STORE: "events",
// Flow
FLOW_STORE: "flows",
};
@ -206,6 +179,7 @@ var SettingsActions = {
//TODO: Update server.
//Facebook Flux: We do an optimistic update on the client already.
AppDispatcher.dispatchViewAction({
type: ActionTypes.SETTINGS_STORE,
cmd: StoreCmds.UPDATE,
@ -429,6 +403,9 @@ function EventLogStore() {
_.extend(EventLogStore.prototype, LiveListStore.prototype, {
fetch: function(){
LiveListStore.prototype.fetch.apply(this, arguments);
// Make sure to display updates even if fetching all events failed.
// This way, we can send "fetch failed" log messages to the log.
if(this._fetchxhr){
this._fetchxhr.fail(function(){
this.handle_fetch(null);
@ -774,17 +751,20 @@ var MainMenu = React.createClass({displayName: 'MainMenu',
showEventLog: !this.props.settings.showEventLog
});
},
clearFlows: function(){
clearFlows: function () {
$.post("/flows/clear");
},
render: function () {
return (
React.createElement("div", null,
React.createElement("button", {className: "btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default"), onClick: this.toggleEventLog},
React.createElement("i", {className: "fa fa-database"}), " Display Event Log"
), " ",
React.createElement("i", {className: "fa fa-database"}),
" Display Event Log"
),
" ",
React.createElement("button", {className: "btn btn-default", onClick: this.clearFlows},
React.createElement("i", {className: "fa fa-eraser"}), " Clear Flows"
React.createElement("i", {className: "fa fa-eraser"}),
" Clear Flows"
)
)
);
@ -813,6 +793,80 @@ var ReportsMenu = React.createClass({displayName: 'ReportsMenu',
}
});
var FileMenu = React.createClass({displayName: 'FileMenu',
getInitialState: function () {
return {
showFileMenu: false
};
},
handleFileClick: function (e) {
e.preventDefault();
if (!this.state.showFileMenu) {
var close = function () {
this.setState({showFileMenu: false});
document.removeEventListener("click", close);
}.bind(this);
document.addEventListener("click", close);
this.setState({
showFileMenu: true
});
}
},
handleNewClick: function(e){
e.preventDefault();
console.error("unimplemented: handleNewClick");
},
handleOpenClick: function(e){
e.preventDefault();
console.error("unimplemented: handleOpenClick");
},
handleSaveClick: function(e){
e.preventDefault();
console.error("unimplemented: handleSaveClick");
},
handleShutdownClick: function(e){
e.preventDefault();
console.error("unimplemented: handleShutdownClick");
},
render: function () {
var fileMenuClass = "dropdown pull-left" + (this.state.showFileMenu ? " open" : "");
return (
React.createElement("div", {className: fileMenuClass},
React.createElement("a", {href: "#", className: "special", onClick: this.handleFileClick}, " File "),
React.createElement("ul", {className: "dropdown-menu", role: "menu"},
React.createElement("li", null,
React.createElement("a", {href: "#", onClick: this.handleNewClick},
React.createElement("i", {className: "fa fa-fw fa-file"}),
"New"
)
),
React.createElement("li", null,
React.createElement("a", {href: "#", onClick: this.handleOpenClick},
React.createElement("i", {className: "fa fa-fw fa-folder-open"}),
"Open"
)
),
React.createElement("li", null,
React.createElement("a", {href: "#", onClick: this.handleSaveClick},
React.createElement("i", {className: "fa fa-fw fa-save"}),
"Save"
)
),
React.createElement("li", {role: "presentation", className: "divider"}),
React.createElement("li", null,
React.createElement("a", {href: "#", onClick: this.handleShutdownClick},
React.createElement("i", {className: "fa fa-fw fa-plug"}),
"Shutdown"
)
)
)
)
);
}
});
var header_entries = [MainMenu, ToolsMenu, ReportsMenu];
@ -829,9 +883,6 @@ var Header = React.createClass({displayName: 'Header',
this.transitionTo(active.route);
this.setState({active: active});
},
handleFileClick: function () {
console.log("File click");
},
render: function () {
var header = header_entries.map(function (entry, i) {
var classes = React.addons.classSet({
@ -851,10 +902,10 @@ var Header = React.createClass({displayName: 'Header',
return (
React.createElement("header", null,
React.createElement("div", {className: "title-bar"},
"mitmproxy ", this.props.settings.version
"mitmproxy ", this.props.settings.version
),
React.createElement("nav", {className: "nav-tabs nav-tabs-lg"},
React.createElement("a", {href: "#", className: "special", onClick: this.handleFileClick}, " File "),
React.createElement(FileMenu, null),
header
),
React.createElement("div", {className: "menu"},
@ -1798,6 +1849,8 @@ var ProxyAppMain = React.createClass({displayName: 'ProxyAppMain',
var eventStore = new EventLogStore();
var flowStore = new FlowStore();
var settings = new SettingsStore();
// Default Settings before fetch
_.extend(settings.dict,{
showEventLog: true
});

File diff suppressed because it is too large Load Diff

View File

@ -8,17 +8,20 @@ var MainMenu = React.createClass({
showEventLog: !this.props.settings.showEventLog
});
},
clearFlows: function(){
clearFlows: function () {
$.post("/flows/clear");
},
render: function () {
return (
<div>
<button className={"btn " + (this.props.settings.showEventLog ? "btn-primary" : "btn-default")} onClick={this.toggleEventLog}>
<i className="fa fa-database"></i>&nbsp;Display Event Log
</button>&nbsp;
<i className="fa fa-database"></i>
&nbsp;Display Event Log
</button>
&nbsp;
<button className="btn btn-default" onClick={this.clearFlows}>
<i className="fa fa-eraser"></i>&nbsp;Clear Flows
<i className="fa fa-eraser"></i>
&nbsp;Clear Flows
</button>
</div>
);
@ -47,6 +50,80 @@ var ReportsMenu = React.createClass({
}
});
var FileMenu = React.createClass({
getInitialState: function () {
return {
showFileMenu: false
};
},
handleFileClick: function (e) {
e.preventDefault();
if (!this.state.showFileMenu) {
var close = function () {
this.setState({showFileMenu: false});
document.removeEventListener("click", close);
}.bind(this);
document.addEventListener("click", close);
this.setState({
showFileMenu: true
});
}
},
handleNewClick: function(e){
e.preventDefault();
console.error("unimplemented: handleNewClick");
},
handleOpenClick: function(e){
e.preventDefault();
console.error("unimplemented: handleOpenClick");
},
handleSaveClick: function(e){
e.preventDefault();
console.error("unimplemented: handleSaveClick");
},
handleShutdownClick: function(e){
e.preventDefault();
console.error("unimplemented: handleShutdownClick");
},
render: function () {
var fileMenuClass = "dropdown pull-left" + (this.state.showFileMenu ? " open" : "");
return (
<div className={fileMenuClass}>
<a href="#" className="special" onClick={this.handleFileClick}> File </a>
<ul className="dropdown-menu" role="menu">
<li>
<a href="#" onClick={this.handleNewClick}>
<i className="fa fa-fw fa-file"></i>
New
</a>
</li>
<li>
<a href="#" onClick={this.handleOpenClick}>
<i className="fa fa-fw fa-folder-open"></i>
Open
</a>
</li>
<li>
<a href="#" onClick={this.handleSaveClick}>
<i className="fa fa-fw fa-save"></i>
Save
</a>
</li>
<li role="presentation" className="divider"></li>
<li>
<a href="#" onClick={this.handleShutdownClick}>
<i className="fa fa-fw fa-plug"></i>
Shutdown
</a>
</li>
</ul>
</div>
);
}
});
var header_entries = [MainMenu, ToolsMenu, ReportsMenu];
@ -63,9 +140,6 @@ var Header = React.createClass({
this.transitionTo(active.route);
this.setState({active: active});
},
handleFileClick: function () {
console.log("File click");
},
render: function () {
var header = header_entries.map(function (entry, i) {
var classes = React.addons.classSet({
@ -85,10 +159,10 @@ var Header = React.createClass({
return (
<header>
<div className="title-bar">
mitmproxy { this.props.settings.version }
mitmproxy { this.props.settings.version }
</div>
<nav className="nav-tabs nav-tabs-lg">
<a href="#" className="special" onClick={this.handleFileClick}> File </a>
<FileMenu/>
{header}
</nav>
<div className="menu">