2016-03-20 04:47:43 +00:00
|
|
|
import React, {Component, PropTypes} from 'react'
|
2016-06-19 00:08:14 +00:00
|
|
|
import ReactDOM from 'react-dom'
|
2016-03-20 04:47:43 +00:00
|
|
|
import {connect} from 'react-redux'
|
|
|
|
import {bindActionCreators} from 'redux'
|
|
|
|
|
2016-04-23 06:16:23 +00:00
|
|
|
import Prompts from './Prompts'
|
|
|
|
import EnvironmentEditModal from '../components/EnvironmentEditModal'
|
2016-05-07 17:29:24 +00:00
|
|
|
import SettingsModal from '../components/SettingsModal'
|
2016-04-26 07:29:24 +00:00
|
|
|
import RequestPane from '../components/RequestPane'
|
|
|
|
import ResponsePane from '../components/ResponsePane'
|
|
|
|
import Sidebar from '../components/Sidebar'
|
2016-05-11 05:43:51 +00:00
|
|
|
import {PREVIEW_MODE_FRIENDLY} from '../lib/previewModes'
|
2016-06-20 06:14:51 +00:00
|
|
|
import {MAX_PANE_WIDTH, MIN_PANE_WIDTH, MAX_SIDEBAR_REMS, MIN_SIDEBAR_REMS} from '../lib/constants'
|
2016-03-20 04:47:43 +00:00
|
|
|
|
2016-04-23 06:16:23 +00:00
|
|
|
import * as GlobalActions from '../redux/modules/global'
|
|
|
|
import * as RequestGroupActions from '../redux/modules/requestGroups'
|
|
|
|
import * as RequestActions from '../redux/modules/requests'
|
|
|
|
import * as ModalActions from '../redux/modules/modals'
|
2016-04-16 23:24:57 +00:00
|
|
|
|
|
|
|
import * as db from '../database'
|
2016-03-20 04:47:43 +00:00
|
|
|
|
|
|
|
class App extends Component {
|
2016-04-18 04:39:15 +00:00
|
|
|
constructor (props) {
|
|
|
|
super(props);
|
|
|
|
this.state = {
|
|
|
|
activeResponse: null,
|
2016-06-19 00:08:14 +00:00
|
|
|
activeRequest: null,
|
|
|
|
draggingSidebar: false,
|
|
|
|
draggingPane: false,
|
2016-06-19 00:40:14 +00:00
|
|
|
paneWidth: 0.5, // % (fr)
|
|
|
|
sidebarWidth: 19 // rem
|
2016-04-18 04:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-26 07:29:24 +00:00
|
|
|
_generateSidebarTree (parentId, entities) {
|
|
|
|
const children = entities.filter(e => e.parentId === parentId);
|
2016-05-01 19:56:30 +00:00
|
|
|
|
2016-04-26 07:29:24 +00:00
|
|
|
if (children.length > 0) {
|
|
|
|
return children.map(c => ({
|
|
|
|
doc: c,
|
|
|
|
children: this._generateSidebarTree(c._id, entities)
|
|
|
|
}));
|
|
|
|
} else {
|
|
|
|
return children;
|
2016-03-22 03:22:45 +00:00
|
|
|
}
|
2016-04-17 20:35:35 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 00:08:14 +00:00
|
|
|
_startDragSidebar () {
|
2016-06-19 00:40:14 +00:00
|
|
|
console.log('-- Start Sidebar Drag --');
|
2016-06-20 06:05:40 +00:00
|
|
|
|
2016-06-19 00:08:14 +00:00
|
|
|
this.setState({
|
|
|
|
draggingSidebar: true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
_startDragPane () {
|
2016-06-19 00:40:14 +00:00
|
|
|
console.log('-- Start Pane Drag --');
|
|
|
|
|
2016-06-19 00:08:14 +00:00
|
|
|
this.setState({
|
|
|
|
draggingPane: true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount () {
|
2016-06-20 06:05:40 +00:00
|
|
|
document.addEventListener('mouseup', () => {
|
|
|
|
if (this.state.draggingSidebar || this.state.draggingPane) {
|
|
|
|
console.log('-- End Pane or Sidebar Drag --');
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
draggingSidebar: false,
|
|
|
|
draggingPane: false
|
|
|
|
})
|
|
|
|
}
|
2016-06-19 00:08:14 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
document.addEventListener('mousemove', e => {
|
|
|
|
if (this.state.draggingPane) {
|
|
|
|
const requestPane = ReactDOM.findDOMNode(this.refs.requestPane);
|
|
|
|
const responsePane = ReactDOM.findDOMNode(this.refs.responsePane);
|
|
|
|
|
|
|
|
const requestPaneWidth = requestPane.offsetWidth;
|
|
|
|
const responsePaneWidth = responsePane.offsetWidth;
|
|
|
|
const pixelOffset = e.clientX - requestPane.offsetLeft;
|
2016-06-19 00:17:20 +00:00
|
|
|
let paneWidth = pixelOffset / (requestPaneWidth + responsePaneWidth);
|
|
|
|
|
2016-06-20 06:14:51 +00:00
|
|
|
paneWidth = Math.min(Math.max(paneWidth, MIN_PANE_WIDTH), MAX_PANE_WIDTH);
|
2016-06-19 00:17:20 +00:00
|
|
|
|
2016-06-19 00:08:14 +00:00
|
|
|
this.setState({paneWidth});
|
|
|
|
} else if (this.state.draggingSidebar) {
|
2016-06-19 00:40:14 +00:00
|
|
|
const currentPixelWidth = ReactDOM.findDOMNode(this.refs.sidebar).offsetWidth;
|
|
|
|
const ratio = e.clientX / currentPixelWidth;
|
2016-06-20 06:14:51 +00:00
|
|
|
const width = this.state.sidebarWidth * ratio;
|
|
|
|
const sidebarWidth = Math.max(Math.min(width, MAX_SIDEBAR_REMS), MIN_SIDEBAR_REMS);
|
2016-06-19 00:40:14 +00:00
|
|
|
this.setState({sidebarWidth})
|
2016-06-19 00:08:14 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount () {
|
|
|
|
console.log('hello');
|
|
|
|
}
|
|
|
|
|
2016-04-26 07:29:24 +00:00
|
|
|
render () {
|
|
|
|
const {actions, modals, workspaces, requests, entities} = this.props;
|
2016-05-01 19:56:30 +00:00
|
|
|
|
2016-04-26 07:29:24 +00:00
|
|
|
// TODO: Factor this out into a selector
|
|
|
|
let workspace = entities.workspaces[workspaces.activeId];
|
|
|
|
if (!workspace) {
|
|
|
|
workspace = entities.workspaces[Object.keys(entities.workspaces)[0]];
|
2016-04-17 20:35:35 +00:00
|
|
|
}
|
|
|
|
|
2016-06-19 07:21:43 +00:00
|
|
|
let activeRequestId = workspace.activeRequestId;
|
2016-04-26 07:29:24 +00:00
|
|
|
const activeRequest = activeRequestId ? entities.requests[activeRequestId] : null;
|
2016-03-22 05:01:58 +00:00
|
|
|
|
2016-06-19 07:21:43 +00:00
|
|
|
// Request doesn't actually exist anymore :(
|
|
|
|
if (!activeRequest) {
|
|
|
|
activeRequestId = null;
|
|
|
|
}
|
|
|
|
|
2016-04-26 07:29:24 +00:00
|
|
|
const responses = Object.keys(entities.responses).map(id => entities.responses[id]);
|
|
|
|
const allRequests = Object.keys(entities.requests).map(id => entities.requests[id]);
|
|
|
|
const allRequestGroups = Object.keys(entities.requestGroups).map(id => entities.requestGroups[id]);
|
|
|
|
|
|
|
|
const activeResponse = responses.sort(
|
|
|
|
(a, b) => a._id > b._id ? -1 : 1
|
|
|
|
).find(r => r.parentId === activeRequestId);
|
|
|
|
|
|
|
|
const children = this._generateSidebarTree(
|
|
|
|
workspace._id,
|
|
|
|
allRequests.concat(allRequestGroups)
|
|
|
|
);
|
2016-03-22 03:22:45 +00:00
|
|
|
|
2016-06-19 00:40:14 +00:00
|
|
|
const {sidebarWidth, paneWidth} = this.state;
|
|
|
|
const gridTemplateColumns = `${sidebarWidth}rem 0 ${paneWidth}fr 0 ${1 - paneWidth}fr`;
|
|
|
|
|
2016-03-20 04:47:43 +00:00
|
|
|
return (
|
2016-06-19 00:08:14 +00:00
|
|
|
<div className="wrapper"
|
2016-06-19 00:40:14 +00:00
|
|
|
style={{gridTemplateColumns: gridTemplateColumns}}>
|
2016-04-17 22:46:17 +00:00
|
|
|
<Sidebar
|
2016-06-19 00:08:14 +00:00
|
|
|
ref="sidebar"
|
2016-04-26 07:29:24 +00:00
|
|
|
workspaceId={workspace._id}
|
2016-04-27 03:17:05 +00:00
|
|
|
activateRequest={r => db.workspaceUpdate(workspace, {activeRequestId: r._id})}
|
2016-04-17 22:46:17 +00:00
|
|
|
changeFilter={actions.requests.changeFilter}
|
2016-04-26 07:29:24 +00:00
|
|
|
addRequestToRequestGroup={requestGroup => db.requestCreate({parentId: requestGroup._id})}
|
2016-04-27 03:17:05 +00:00
|
|
|
toggleRequestGroup={requestGroup => db.requestGroupUpdate(requestGroup, {collapsed: !requestGroup.collapsed})}
|
2016-04-26 07:29:24 +00:00
|
|
|
activeRequestId={activeRequest ? activeRequest._id : null}
|
|
|
|
filter={requests.filter}
|
|
|
|
children={children}
|
|
|
|
/>
|
2016-05-07 17:29:24 +00:00
|
|
|
|
2016-06-19 00:08:14 +00:00
|
|
|
<div className="drag drag--sidebar">
|
|
|
|
<div onMouseDown={e => this._startDragSidebar(e)}></div>
|
|
|
|
</div>
|
|
|
|
|
2016-05-01 19:56:30 +00:00
|
|
|
<RequestPane
|
2016-06-19 00:08:14 +00:00
|
|
|
ref="requestPane"
|
2016-05-01 19:56:30 +00:00
|
|
|
request={activeRequest}
|
|
|
|
sendRequest={actions.requests.send}
|
|
|
|
updateRequestBody={body => db.requestUpdate(activeRequest, {body})}
|
|
|
|
updateRequestUrl={url => db.requestUpdate(activeRequest, {url})}
|
|
|
|
updateRequestMethod={method => db.requestUpdate(activeRequest, {method})}
|
|
|
|
updateRequestParams={params => db.requestUpdate(activeRequest, {params})}
|
|
|
|
updateRequestAuthentication={authentication => db.requestUpdate(activeRequest, {authentication})}
|
|
|
|
updateRequestHeaders={headers => db.requestUpdate(activeRequest, {headers})}
|
|
|
|
updateRequestContentType={contentType => db.requestUpdate(activeRequest, {contentType})}
|
|
|
|
/>
|
2016-05-07 17:29:24 +00:00
|
|
|
|
2016-06-19 00:08:14 +00:00
|
|
|
<div className="drag drag--pane">
|
|
|
|
<div onMouseDown={e => this._startDragPane(e)}></div>
|
|
|
|
</div>
|
|
|
|
|
2016-05-01 19:56:30 +00:00
|
|
|
<ResponsePane
|
2016-06-19 00:08:14 +00:00
|
|
|
ref="responsePane"
|
2016-05-01 19:56:30 +00:00
|
|
|
response={activeResponse}
|
2016-05-11 05:43:51 +00:00
|
|
|
previewMode={activeRequest ? activeRequest.previewMode : PREVIEW_MODE_FRIENDLY}
|
2016-05-01 19:56:30 +00:00
|
|
|
updatePreviewMode={previewMode => db.requestUpdate(activeRequest, {previewMode})}
|
|
|
|
/>
|
2016-04-26 07:29:24 +00:00
|
|
|
|
2016-04-15 05:23:54 +00:00
|
|
|
<Prompts />
|
2016-04-26 07:29:24 +00:00
|
|
|
|
2016-04-17 01:52:10 +00:00
|
|
|
{modals.map(m => {
|
2016-05-07 17:29:24 +00:00
|
|
|
if (m.id === SettingsModal.defaultProps.id) {
|
|
|
|
return (
|
|
|
|
<SettingsModal
|
|
|
|
key={m.id}
|
|
|
|
onClose={() => actions.modals.hide(m.id)}
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
} else if (m.id === EnvironmentEditModal.defaultProps.id) {
|
2016-04-17 01:52:10 +00:00
|
|
|
return (
|
|
|
|
<EnvironmentEditModal
|
|
|
|
key={m.id}
|
|
|
|
requestGroup={m.data.requestGroup}
|
|
|
|
onClose={() => actions.modals.hide(m.id)}
|
2016-04-27 03:17:05 +00:00
|
|
|
onChange={rg => db.requestGroupUpdate(m.data.requestGroup, {environment: rg.environment})}
|
2016-04-17 01:52:10 +00:00
|
|
|
/>
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
})}
|
2016-03-20 04:47:43 +00:00
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
App.propTypes = {
|
2016-03-22 05:01:58 +00:00
|
|
|
actions: PropTypes.shape({
|
2016-04-16 23:24:57 +00:00
|
|
|
requests: PropTypes.shape({
|
|
|
|
send: PropTypes.func.isRequired,
|
|
|
|
changeFilter: PropTypes.func.isRequired
|
|
|
|
}),
|
|
|
|
requestGroups: PropTypes.shape({
|
|
|
|
toggle: PropTypes.func.isRequired
|
|
|
|
}),
|
2016-04-17 01:52:10 +00:00
|
|
|
modals: PropTypes.shape({
|
|
|
|
hide: PropTypes.func.isRequired
|
2016-04-16 23:24:57 +00:00
|
|
|
})
|
2016-03-22 05:01:58 +00:00
|
|
|
}).isRequired,
|
2016-04-26 07:29:24 +00:00
|
|
|
entities: PropTypes.shape({
|
|
|
|
requests: PropTypes.object.isRequired,
|
|
|
|
requestGroups: PropTypes.object.isRequired,
|
|
|
|
responses: PropTypes.object.isRequired
|
|
|
|
}).isRequired,
|
|
|
|
workspaces: PropTypes.shape({
|
|
|
|
activeId: PropTypes.string
|
2016-04-09 21:08:55 +00:00
|
|
|
}).isRequired,
|
2016-03-22 05:01:58 +00:00
|
|
|
requests: PropTypes.shape({
|
2016-04-26 07:29:24 +00:00
|
|
|
filter: PropTypes.string.isRequired
|
2016-03-22 05:01:58 +00:00
|
|
|
}).isRequired,
|
2016-04-15 05:23:54 +00:00
|
|
|
modals: PropTypes.array.isRequired
|
2016-03-20 04:47:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
function mapStateToProps (state) {
|
|
|
|
return {
|
|
|
|
actions: state.actions,
|
2016-04-26 07:29:24 +00:00
|
|
|
workspaces: state.workspaces,
|
2016-03-22 05:01:58 +00:00
|
|
|
requests: state.requests,
|
2016-04-26 07:29:24 +00:00
|
|
|
entities: state.entities,
|
2016-04-15 05:23:54 +00:00
|
|
|
modals: state.modals
|
2016-03-20 04:47:43 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapDispatchToProps (dispatch) {
|
|
|
|
return {
|
2016-04-16 23:24:57 +00:00
|
|
|
actions: {
|
|
|
|
global: bindActionCreators(GlobalActions, dispatch),
|
2016-04-17 01:52:10 +00:00
|
|
|
modals: bindActionCreators(ModalActions, dispatch),
|
2016-04-16 23:24:57 +00:00
|
|
|
requestGroups: bindActionCreators(RequestGroupActions, dispatch),
|
|
|
|
requests: bindActionCreators(RequestActions, dispatch)
|
|
|
|
}
|
2016-03-20 04:47:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(
|
|
|
|
mapStateToProps,
|
|
|
|
mapDispatchToProps
|
|
|
|
)(App);
|
|
|
|
|