[web] rewrite ProxyApp and MainView with es6
This commit is contained in:
parent
7707d096d2
commit
851bb4bf68
|
@ -0,0 +1,5 @@
|
|||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
|
@ -1,33 +1,41 @@
|
|||
import React from "react"
|
||||
import {render} from 'react-dom'
|
||||
import {applyMiddleware, createStore} from 'redux'
|
||||
import {Provider} from 'react-redux'
|
||||
import { render } from 'react-dom'
|
||||
import { applyMiddleware, createStore } from 'redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import createLogger from 'redux-logger'
|
||||
import thunkMiddleware from 'redux-thunk'
|
||||
|
||||
import { Route, Router as ReactRouter, hashHistory, Redirect } from "react-router"
|
||||
|
||||
import Connection from "./connection"
|
||||
import {App} from "./components/proxyapp.js"
|
||||
import rootReducer from './ducks/index';
|
||||
import {addLogEntry} from "./ducks/eventLog";
|
||||
import ProxyApp from "./components/ProxyApp"
|
||||
import MainView from './components/MainView'
|
||||
import rootReducer from './ducks/index'
|
||||
import { addLogEntry } from "./ducks/eventLog"
|
||||
|
||||
// logger must be last
|
||||
const logger = createLogger();
|
||||
const store = createStore(
|
||||
rootReducer,
|
||||
applyMiddleware(thunkMiddleware, logger)
|
||||
);
|
||||
applyMiddleware(thunkMiddleware, createLogger())
|
||||
)
|
||||
|
||||
window.onerror = function (msg) {
|
||||
store.dispatch(addLogEntry(msg));
|
||||
};
|
||||
window.addEventListener('error', msg => {
|
||||
store.dispatch(addLogEntry(msg))
|
||||
})
|
||||
|
||||
// @todo remove this
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.ws = new Connection("/updates", store.dispatch);
|
||||
window.ws = new Connection("/updates", store.dispatch)
|
||||
|
||||
render(
|
||||
<Provider store={store}>{App}</Provider>,
|
||||
<Provider store={store}>
|
||||
<ReactRouter history={hashHistory}>
|
||||
<Redirect from="/" to="/flows" />
|
||||
<Route path="/" component={ProxyApp}>
|
||||
<Route path="flows" component={MainView}/>
|
||||
<Route path="flows/:flowId/:detailTab" component={MainView}/>
|
||||
</Route>
|
||||
</ReactRouter>
|
||||
</Provider>,
|
||||
document.getElementById("mitmproxy")
|
||||
);
|
||||
|
||||
});
|
||||
)
|
||||
})
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
import React, { Component } from "react"
|
||||
|
||||
import { FlowActions } from "../actions.js"
|
||||
import { Query } from "../actions.js"
|
||||
import { Key } from "../utils.js"
|
||||
import { Splitter } from "./common.js"
|
||||
import FlowTable from "./flowtable.js"
|
||||
import FlowView from "./flowview/index.js"
|
||||
import { connect } from 'react-redux'
|
||||
import { selectFlow, setFilter, setHighlight } from "../ducks/flows"
|
||||
|
||||
class MainView extends Component {
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
* @todo replace with mapStateToProps
|
||||
*/
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// Update redux store with route changes
|
||||
if (nextProps.routeParams.flowId !== (nextProps.selectedFlow || {}).id) {
|
||||
this.props.selectFlow(nextProps.routeParams.flowId)
|
||||
}
|
||||
if (nextProps.location.query[Query.SEARCH] !== nextProps.filter) {
|
||||
this.props.setFilter(nextProps.location.query[Query.SEARCH], false)
|
||||
}
|
||||
if (nextProps.location.query[Query.HIGHLIGHT] !== nextProps.highlight) {
|
||||
this.props.setHighlight(nextProps.location.query[Query.HIGHLIGHT], false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
*/
|
||||
selectFlow(flow) {
|
||||
if (flow) {
|
||||
this.props.updateLocation(`/flows/${flow.id}/${this.props.routeParams.detailTab || "request"}`)
|
||||
} else {
|
||||
this.props.updateLocation("/flows")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
*/
|
||||
selectFlowRelative(shift) {
|
||||
const { flows, routeParams, selectedFlow } = this.props
|
||||
let index = 0
|
||||
if (!routeParams.flowId) {
|
||||
if (shift < 0) {
|
||||
index = flows.length - 1
|
||||
}
|
||||
} else {
|
||||
index = Math.min(
|
||||
Math.max(0, flows.indexOf(selectedFlow) + shift),
|
||||
flows.length - 1
|
||||
)
|
||||
}
|
||||
this.selectFlow(flows[index])
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
*/
|
||||
onMainKeyDown(e) {
|
||||
var flow = this.props.selectedFlow
|
||||
if (e.ctrlKey) {
|
||||
return
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
case Key.K:
|
||||
case Key.UP:
|
||||
this.selectFlowRelative(-1)
|
||||
break
|
||||
case Key.J:
|
||||
case Key.DOWN:
|
||||
this.selectFlowRelative(+1)
|
||||
break
|
||||
case Key.SPACE:
|
||||
case Key.PAGE_DOWN:
|
||||
this.selectFlowRelative(+10)
|
||||
break
|
||||
case Key.PAGE_UP:
|
||||
this.selectFlowRelative(-10)
|
||||
break
|
||||
case Key.END:
|
||||
this.selectFlowRelative(+1e10)
|
||||
break
|
||||
case Key.HOME:
|
||||
this.selectFlowRelative(-1e10)
|
||||
break
|
||||
case Key.ESC:
|
||||
this.selectFlow(null)
|
||||
break
|
||||
case Key.H:
|
||||
case Key.LEFT:
|
||||
if (this.refs.flowDetails) {
|
||||
this.refs.flowDetails.nextTab(-1)
|
||||
}
|
||||
break
|
||||
case Key.L:
|
||||
case Key.TAB:
|
||||
case Key.RIGHT:
|
||||
if (this.refs.flowDetails) {
|
||||
this.refs.flowDetails.nextTab(+1)
|
||||
}
|
||||
break
|
||||
case Key.C:
|
||||
if (e.shiftKey) {
|
||||
FlowActions.clear()
|
||||
}
|
||||
break
|
||||
case Key.D:
|
||||
if (flow) {
|
||||
if (e.shiftKey) {
|
||||
FlowActions.duplicate(flow)
|
||||
} else {
|
||||
FlowActions.delete(flow)
|
||||
}
|
||||
}
|
||||
break
|
||||
case Key.A:
|
||||
if (e.shiftKey) {
|
||||
FlowActions.accept_all()
|
||||
} else if (flow && flow.intercepted) {
|
||||
FlowActions.accept(flow)
|
||||
}
|
||||
break
|
||||
case Key.R:
|
||||
if (!e.shiftKey && flow) {
|
||||
FlowActions.replay(flow)
|
||||
}
|
||||
break
|
||||
case Key.V:
|
||||
if (e.shiftKey && flow && flow.modified) {
|
||||
FlowActions.revert(flow)
|
||||
}
|
||||
break
|
||||
case Key.E:
|
||||
if (this.refs.flowDetails) {
|
||||
this.refs.flowDetails.promptEdit()
|
||||
}
|
||||
break
|
||||
case Key.SHIFT:
|
||||
break
|
||||
default:
|
||||
console.debug("keydown", e.keyCode)
|
||||
return
|
||||
}
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectedFlow } = this.props
|
||||
return (
|
||||
<div className="main-view">
|
||||
<FlowTable
|
||||
ref="flowTable"
|
||||
selectFlow={this.selectFlow}
|
||||
selected={selectedFlow}
|
||||
/>
|
||||
{selectedFlow && [
|
||||
<Splitter key="splitter"/>,
|
||||
<FlowView
|
||||
key="flowDetails"
|
||||
ref="flowDetails"
|
||||
tab={this.props.routeParams.detailTab}
|
||||
query={this.props.query}
|
||||
updateLocation={this.props.updateLocation}
|
||||
flow={selectedFlow}
|
||||
/>
|
||||
]}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(
|
||||
state => ({
|
||||
flows: state.flows.view,
|
||||
filter: state.flows.filter,
|
||||
highlight: state.flows.highlight,
|
||||
selectedFlow: state.flows.all.byId[state.flows.selected[0]]
|
||||
}),
|
||||
dispatch => ({
|
||||
selectFlow: flowId => dispatch(selectFlow(flowId)),
|
||||
setFilter: filter => dispatch(setFilter(filter)),
|
||||
setHighlight: highlight => dispatch(setHighlight(highlight))
|
||||
}),
|
||||
undefined,
|
||||
{ withRef: true }
|
||||
)(MainView)
|
|
@ -0,0 +1,163 @@
|
|||
import React, { Component, PropTypes } from "react"
|
||||
import ReactDOM from "react-dom"
|
||||
import _ from "lodash"
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import { Splitter } from "./common.js"
|
||||
import { Header, MainMenu } from "./header.js"
|
||||
import EventLog from "./eventlog.js"
|
||||
import Footer from "./footer.js"
|
||||
import { SettingsStore } from "../store/store.js"
|
||||
import { Key } from "../utils.js"
|
||||
|
||||
class ProxyAppMain extends Component {
|
||||
|
||||
static childContextTypes = {
|
||||
returnFocus: PropTypes.func.isRequired,
|
||||
location: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.settingsStore = new SettingsStore()
|
||||
|
||||
// Default Settings before fetch
|
||||
_.extend(this.settingsStore.dict, {})
|
||||
|
||||
this.state = { settings: this.settingsStore.dict }
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
*/
|
||||
updateLocation(pathname, queryUpdate) {
|
||||
if (pathname === undefined) {
|
||||
pathname = this.props.location.pathname
|
||||
}
|
||||
const query = this.props.location.query
|
||||
for (const key of Object.keys(queryUpdate || {})) {
|
||||
query[i] = queryUpdate[i] || undefined
|
||||
}
|
||||
this.context.router.replace({pathname, query})
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo pass in with props
|
||||
*/
|
||||
getQuery() {
|
||||
// For whatever reason, react-router always returns the same object, which makes comparing
|
||||
// the current props with nextProps impossible. As a workaround, we just clone the query object.
|
||||
return _.clone(this.props.location.query)
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo remove settings store
|
||||
* @todo connect websocket here
|
||||
* @todo listen to window's key events
|
||||
*/
|
||||
componentDidMount() {
|
||||
this.focus()
|
||||
this.settingsStore.addListener("recalculate", this.onSettingsChange)
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo remove settings store
|
||||
* @todo disconnect websocket here
|
||||
* @todo stop listening to window's key events
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
this.settingsStore.removeListener("recalculate", this.onSettingsChange)
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
*/
|
||||
onSettingsChange() {
|
||||
this.setState({ settings: this.settingsStore.dict })
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo use props
|
||||
*/
|
||||
getChildContext() {
|
||||
return {
|
||||
returnFocus: this.focus,
|
||||
location: this.props.location
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo remove it
|
||||
*/
|
||||
focus() {
|
||||
document.activeElement.blur()
|
||||
window.getSelection().removeAllRanges()
|
||||
ReactDOM.findDOMNode(this).focus()
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo move to actions
|
||||
*/
|
||||
onKeydown(e) {
|
||||
let name = null
|
||||
|
||||
switch (e.keyCode) {
|
||||
case Key.I:
|
||||
name = "intercept"
|
||||
break
|
||||
case Key.L:
|
||||
name = "search"
|
||||
break
|
||||
case Key.H:
|
||||
name = "highlight"
|
||||
break
|
||||
default:
|
||||
let main = this.refs.view
|
||||
if (this.refs.view.getWrappedInstance) {
|
||||
main = this.refs.view.getWrappedInstance()
|
||||
}
|
||||
if (main.onMainKeyDown) {
|
||||
main.onMainKeyDown(e)
|
||||
}
|
||||
return // don't prevent default then
|
||||
}
|
||||
|
||||
if (name) {
|
||||
const headerComponent = this.refs.header
|
||||
headerComponent.setState({active: MainMenu}, function () {
|
||||
headerComponent.refs.active.refs[name].select()
|
||||
})
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { showEventLog, location, children } = this.props
|
||||
const { settings } = this.state
|
||||
const query = this.getQuery()
|
||||
return (
|
||||
<div id="container" tabIndex="0" onKeyDown={this.onKeydown}>
|
||||
<Header ref="header" settings={settings} updateLocation={this.updateLocation} query={query} />
|
||||
{React.cloneElement(
|
||||
children,
|
||||
{ ref: "view", location, query, updateLocation: this.updateLocation }
|
||||
)}
|
||||
{showEventLog && [
|
||||
<Splitter key="splitter" axis="y"/>,
|
||||
<EventLog key="eventlog"/>
|
||||
]}
|
||||
<Footer settings={settings}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(
|
||||
state => ({
|
||||
showEventLog: state.eventLog.visible
|
||||
})
|
||||
)(ProxyAppMain)
|
|
@ -1,184 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
import {FlowActions} from "../actions.js";
|
||||
import {Query} from "../actions.js";
|
||||
import {Key} from "../utils.js";
|
||||
import {Splitter} from "./common.js"
|
||||
import FlowTable from "./flowtable.js";
|
||||
import FlowView from "./flowview/index.js";
|
||||
import {connect} from 'react-redux'
|
||||
import {selectFlow, setFilter, setHighlight} from "../ducks/flows";
|
||||
|
||||
|
||||
var MainView = React.createClass({
|
||||
componentWillReceiveProps: function (nextProps) {
|
||||
// Update redux store with route changes
|
||||
if(nextProps.routeParams.flowId !== (nextProps.selectedFlow || {}).id) {
|
||||
this.props.selectFlow(nextProps.routeParams.flowId)
|
||||
}
|
||||
if(nextProps.location.query[Query.SEARCH] !== nextProps.filter) {
|
||||
this.props.setFilter(nextProps.location.query[Query.SEARCH], false)
|
||||
}
|
||||
if (nextProps.location.query[Query.HIGHLIGHT] !== nextProps.highlight) {
|
||||
this.props.setHighlight(nextProps.location.query[Query.HIGHLIGHT], false)
|
||||
}
|
||||
},
|
||||
selectFlow: function (flow) {
|
||||
// TODO: This belongs into redux
|
||||
if (flow) {
|
||||
let tab = this.props.routeParams.detailTab || "request";
|
||||
this.props.updateLocation(`/flows/${flow.id}/${tab}`);
|
||||
} else {
|
||||
this.props.updateLocation("/flows");
|
||||
}
|
||||
},
|
||||
selectFlowRelative: function (shift) {
|
||||
// TODO: This belongs into redux
|
||||
let flows = this.props.flows,
|
||||
index
|
||||
if (!this.props.routeParams.flowId) {
|
||||
if (shift < 0) {
|
||||
index = flows.length - 1
|
||||
} else {
|
||||
index = 0
|
||||
}
|
||||
} else {
|
||||
index = flows.indexOf(this.props.selectedFlow)
|
||||
index = Math.min(
|
||||
Math.max(0, index + shift),
|
||||
flows.length - 1
|
||||
)
|
||||
}
|
||||
this.selectFlow(flows[index])
|
||||
},
|
||||
onMainKeyDown: function (e) {
|
||||
var flow = this.props.selectedFlow;
|
||||
if (e.ctrlKey) {
|
||||
return;
|
||||
}
|
||||
switch (e.keyCode) {
|
||||
case Key.K:
|
||||
case Key.UP:
|
||||
this.selectFlowRelative(-1);
|
||||
break;
|
||||
case Key.J:
|
||||
case Key.DOWN:
|
||||
this.selectFlowRelative(+1);
|
||||
break;
|
||||
case Key.SPACE:
|
||||
case Key.PAGE_DOWN:
|
||||
this.selectFlowRelative(+10);
|
||||
break;
|
||||
case Key.PAGE_UP:
|
||||
this.selectFlowRelative(-10);
|
||||
break;
|
||||
case Key.END:
|
||||
this.selectFlowRelative(+1e10);
|
||||
break;
|
||||
case Key.HOME:
|
||||
this.selectFlowRelative(-1e10);
|
||||
break;
|
||||
case Key.ESC:
|
||||
this.selectFlow(null);
|
||||
break;
|
||||
case Key.H:
|
||||
case Key.LEFT:
|
||||
if (this.refs.flowDetails) {
|
||||
this.refs.flowDetails.nextTab(-1);
|
||||
}
|
||||
break;
|
||||
case Key.L:
|
||||
case Key.TAB:
|
||||
case Key.RIGHT:
|
||||
if (this.refs.flowDetails) {
|
||||
this.refs.flowDetails.nextTab(+1);
|
||||
}
|
||||
break;
|
||||
case Key.C:
|
||||
if (e.shiftKey) {
|
||||
FlowActions.clear();
|
||||
}
|
||||
break;
|
||||
case Key.D:
|
||||
if (flow) {
|
||||
if (e.shiftKey) {
|
||||
FlowActions.duplicate(flow);
|
||||
} else {
|
||||
FlowActions.delete(flow);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Key.A:
|
||||
if (e.shiftKey) {
|
||||
FlowActions.accept_all();
|
||||
} else if (flow && flow.intercepted) {
|
||||
FlowActions.accept(flow);
|
||||
}
|
||||
break;
|
||||
case Key.R:
|
||||
if (!e.shiftKey && flow) {
|
||||
FlowActions.replay(flow);
|
||||
}
|
||||
break;
|
||||
case Key.V:
|
||||
if (e.shiftKey && flow && flow.modified) {
|
||||
FlowActions.revert(flow);
|
||||
}
|
||||
break;
|
||||
case Key.E:
|
||||
if (this.refs.flowDetails) {
|
||||
this.refs.flowDetails.promptEdit();
|
||||
}
|
||||
break;
|
||||
case Key.SHIFT:
|
||||
break;
|
||||
default:
|
||||
console.debug("keydown", e.keyCode);
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
},
|
||||
render: function () {
|
||||
|
||||
var details = null;
|
||||
if (this.props.selectedFlow) {
|
||||
details = [
|
||||
<Splitter key="splitter"/>,
|
||||
<FlowView
|
||||
key="flowDetails"
|
||||
ref="flowDetails"
|
||||
tab={this.props.routeParams.detailTab}
|
||||
query={this.props.query}
|
||||
updateLocation={this.props.updateLocation}
|
||||
flow={this.props.selectedFlow}/>
|
||||
]
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="main-view">
|
||||
<FlowTable ref="flowTable"
|
||||
selectFlow={this.selectFlow}
|
||||
selected={this.props.selectedFlow} />
|
||||
{details}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const MainViewContainer = connect(
|
||||
state => ({
|
||||
flows: state.flows.view,
|
||||
filter: state.flows.filter,
|
||||
highlight: state.flows.highlight,
|
||||
selectedFlow: state.flows.all.byId[state.flows.selected[0]]
|
||||
}),
|
||||
dispatch => ({
|
||||
selectFlow: flowId => dispatch(selectFlow(flowId)),
|
||||
setFilter: filter => dispatch(setFilter(filter)),
|
||||
setHighlight: highlight => dispatch(setHighlight(highlight))
|
||||
}),
|
||||
undefined,
|
||||
{withRef: true}
|
||||
)(MainView);
|
||||
|
||||
export default MainViewContainer;
|
|
@ -1,154 +0,0 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import _ from "lodash";
|
||||
import {connect} from 'react-redux'
|
||||
import { Route, Router as ReactRouter, hashHistory, Redirect} from "react-router"
|
||||
|
||||
import {Splitter} from "./common.js"
|
||||
import MainView from "./mainview.js";
|
||||
import Footer from "./footer.js";
|
||||
import {Header, MainMenu} from "./header.js";
|
||||
import EventLog from "./eventlog.js"
|
||||
import {SettingsStore} from "../store/store.js";
|
||||
import {Key} from "../utils.js";
|
||||
|
||||
|
||||
//TODO: Move out of here, just a stub.
|
||||
var Reports = React.createClass({
|
||||
render: function () {
|
||||
return <div>ReportEditor</div>;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var ProxyAppMain = React.createClass({
|
||||
childContextTypes: {
|
||||
returnFocus: React.PropTypes.func.isRequired,
|
||||
location: React.PropTypes.object.isRequired,
|
||||
},
|
||||
contextTypes: {
|
||||
router: React.PropTypes.object.isRequired
|
||||
},
|
||||
updateLocation: function (pathname, queryUpdate) {
|
||||
if (pathname === undefined) {
|
||||
pathname = this.props.location.pathname;
|
||||
}
|
||||
var query = this.props.location.query;
|
||||
if (queryUpdate !== undefined) {
|
||||
for (var i in queryUpdate) {
|
||||
if (queryUpdate.hasOwnProperty(i)) {
|
||||
query[i] = queryUpdate[i] || undefined; //falsey values shall be removed.
|
||||
}
|
||||
}
|
||||
}
|
||||
this.context.router.replace({pathname, query});
|
||||
},
|
||||
getQuery: function () {
|
||||
// For whatever reason, react-router always returns the same object, which makes comparing
|
||||
// the current props with nextProps impossible. As a workaround, we just clone the query object.
|
||||
return _.clone(this.props.location.query);
|
||||
},
|
||||
componentDidMount: function () {
|
||||
this.focus();
|
||||
this.settingsStore.addListener("recalculate", this.onSettingsChange);
|
||||
},
|
||||
componentWillUnmount: function () {
|
||||
this.settingsStore.removeListener("recalculate", this.onSettingsChange);
|
||||
},
|
||||
onSettingsChange: function () {
|
||||
this.setState({ settings: this.settingsStore.dict });
|
||||
},
|
||||
getChildContext: function () {
|
||||
return {
|
||||
returnFocus: this.focus,
|
||||
location: this.props.location
|
||||
};
|
||||
},
|
||||
getInitialState: function () {
|
||||
var settingsStore = new SettingsStore();
|
||||
|
||||
this.settingsStore = settingsStore;
|
||||
// Default Settings before fetch
|
||||
_.extend(settingsStore.dict, {});
|
||||
return {
|
||||
settings: settingsStore.dict,
|
||||
};
|
||||
},
|
||||
focus: function () {
|
||||
document.activeElement.blur();
|
||||
window.getSelection().removeAllRanges();
|
||||
ReactDOM.findDOMNode(this).focus();
|
||||
},
|
||||
getMainComponent: function () {
|
||||
return this.refs.view.getWrappedInstance ? this.refs.view.getWrappedInstance() : this.refs.view;
|
||||
},
|
||||
onKeydown: function (e) {
|
||||
|
||||
var selectFilterInput = function (name) {
|
||||
var headerComponent = this.refs.header;
|
||||
headerComponent.setState({active: MainMenu}, function () {
|
||||
headerComponent.refs.active.refs[name].select();
|
||||
});
|
||||
}.bind(this);
|
||||
|
||||
switch (e.keyCode) {
|
||||
case Key.I:
|
||||
selectFilterInput("intercept");
|
||||
break;
|
||||
case Key.L:
|
||||
selectFilterInput("search");
|
||||
break;
|
||||
case Key.H:
|
||||
selectFilterInput("highlight");
|
||||
break;
|
||||
default:
|
||||
var main = this.getMainComponent();
|
||||
if (main.onMainKeyDown) {
|
||||
main.onMainKeyDown(e);
|
||||
}
|
||||
return; // don't prevent default then
|
||||
}
|
||||
e.preventDefault();
|
||||
},
|
||||
render: function () {
|
||||
var query = this.getQuery();
|
||||
var eventlog;
|
||||
if (this.props.showEventLog) {
|
||||
eventlog = [
|
||||
<Splitter key="splitter" axis="y"/>,
|
||||
<EventLog key="eventlog"/>
|
||||
];
|
||||
} else {
|
||||
eventlog = null;
|
||||
}
|
||||
return (
|
||||
<div id="container" tabIndex="0" onKeyDown={this.onKeydown}>
|
||||
<Header ref="header" settings={this.state.settings} updateLocation={this.updateLocation} query={query} />
|
||||
{React.cloneElement(
|
||||
this.props.children,
|
||||
{ ref: "view", location: this.props.location , updateLocation: this.updateLocation, query }
|
||||
)}
|
||||
{eventlog}
|
||||
<Footer settings={this.state.settings}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const AppContainer = connect(
|
||||
state => ({
|
||||
showEventLog: state.eventLog.visible
|
||||
})
|
||||
)(ProxyAppMain);
|
||||
|
||||
|
||||
export var App = (
|
||||
<ReactRouter history={hashHistory}>
|
||||
<Redirect from="/" to="/flows" />
|
||||
<Route path="/" component={AppContainer}>
|
||||
<Route path="flows" component={MainView}/>
|
||||
<Route path="flows/:flowId/:detailTab" component={MainView}/>
|
||||
<Route path="reports" component={Reports}/>
|
||||
</Route>
|
||||
</ReactRouter>
|
||||
);
|
Loading…
Reference in New Issue