mirror of
https://github.com/Kong/insomnia.git
synced 2026-04-20 22:27:24 -04:00
Split up some components
This commit is contained in:
@@ -3,18 +3,17 @@ import Editor from './base/Editor'
|
||||
|
||||
class RequestBodyEditor extends Component {
|
||||
render () {
|
||||
const {request, onChange, className} = this.props;
|
||||
const mode = request.contentType || 'text/plain';
|
||||
const {body, contentType, requestId, onChange, className} = this.props;
|
||||
|
||||
return (
|
||||
<Editor
|
||||
value={request.body}
|
||||
value={body}
|
||||
className={className}
|
||||
debounceMillis={400}
|
||||
onChange={onChange}
|
||||
uniquenessKey={request._id}
|
||||
uniquenessKey={requestId}
|
||||
options={{
|
||||
mode: mode,
|
||||
mode: contentType,
|
||||
placeholder: 'request body here...'
|
||||
}}
|
||||
/>
|
||||
@@ -23,10 +22,13 @@ class RequestBodyEditor extends Component {
|
||||
}
|
||||
|
||||
RequestBodyEditor.propTypes = {
|
||||
request: PropTypes.shape({
|
||||
body: PropTypes.string.isRequired
|
||||
}).isRequired,
|
||||
onChange: PropTypes.func.isRequired
|
||||
// Functions
|
||||
onChange: PropTypes.func.isRequired,
|
||||
|
||||
// Other
|
||||
requestId: PropTypes.string.isRequired,
|
||||
body: PropTypes.string.isRequired,
|
||||
contentType: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default RequestBodyEditor;
|
||||
|
||||
132
app/components/RequestPane.js
Normal file
132
app/components/RequestPane.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs'
|
||||
|
||||
import KeyValueEditor from '../components/base/KeyValueEditor'
|
||||
import Dropdown from '../components/base/Dropdown'
|
||||
|
||||
import RequestBodyEditor from '../components/RequestBodyEditor'
|
||||
import RequestAuthEditor from '../components/RequestAuthEditor'
|
||||
import RequestUrlBar from '../components/RequestUrlBar'
|
||||
|
||||
class RequestPane extends Component {
|
||||
render () {
|
||||
const {
|
||||
request,
|
||||
sendRequest,
|
||||
updateRequestUrl,
|
||||
updateRequestMethod,
|
||||
updateRequestBody,
|
||||
updateRequestParams,
|
||||
updateRequestAuthentication,
|
||||
updateRequestHeaders
|
||||
} = this.props;
|
||||
|
||||
if (!request) {
|
||||
return (
|
||||
<section className="grid__cell section section--bordered grid--v grid--start">
|
||||
<header className="header bg-super-light section__header"></header>
|
||||
<div className="section__body grid__cell"></div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="grid__cell section section--bordered">
|
||||
<div className="grid--v wide">
|
||||
<div className="header section__header">
|
||||
<RequestUrlBar
|
||||
uniquenessKey={request._id}
|
||||
sendRequest={() => sendRequest(request)}
|
||||
onUrlChange={updateRequestUrl}
|
||||
onMethodChange={updateRequestMethod}
|
||||
url={request.url}
|
||||
method={request.method}
|
||||
/>
|
||||
</div>
|
||||
<Tabs className="grid__cell grid--v section__body">
|
||||
<TabList className="grid grid--start">
|
||||
<Tab className="no-wrap grid grid--center">
|
||||
<button>JSON</button>
|
||||
<Dropdown>
|
||||
<button> <i className="fa fa-caret-down"></i></button>
|
||||
<ul>
|
||||
<li><button><i className="fa fa-file-text"></i> Plain Text</button></li>
|
||||
<li><button><i className="fa fa-picture-o"></i> File Upload</button></li>
|
||||
<li><button><i className="fa fa-bars"></i> Form Data</button></li>
|
||||
<li><button><i className="fa fa-code"></i> HTML/XML</button></li>
|
||||
</ul>
|
||||
</Dropdown>
|
||||
</Tab>
|
||||
<Tab>
|
||||
<button className="no-wrap">
|
||||
Params {request.params.length ? `(${request.params.length})` : ''}
|
||||
</button>
|
||||
</Tab>
|
||||
<Tab>
|
||||
<button className="no-wrap">
|
||||
Headers {request.headers.length ? `(${request.headers.length})` : ''}
|
||||
</button>
|
||||
</Tab>
|
||||
</TabList>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<RequestBodyEditor
|
||||
onChange={updateRequestBody}
|
||||
requestId={request._id}
|
||||
contentType={request.contentType}
|
||||
body={request.body}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div>
|
||||
<KeyValueEditor
|
||||
className="pad"
|
||||
namePlaceholder="name"
|
||||
valuePlaceholder="value"
|
||||
uniquenessKey={request._id}
|
||||
pairs={request.params}
|
||||
onChange={updateRequestParams}
|
||||
/>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div>
|
||||
<div className="pad">
|
||||
<label>Basic Authentication</label>
|
||||
<RequestAuthEditor
|
||||
request={request}
|
||||
onChange={updateRequestAuthentication}
|
||||
/>
|
||||
<br/>
|
||||
<label>Other Headers</label>
|
||||
<KeyValueEditor
|
||||
namePlaceholder="My-Header"
|
||||
valuePlaceholder="Value"
|
||||
uniquenessKey={request._id}
|
||||
pairs={request.headers}
|
||||
onChange={updateRequestHeaders}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
RequestPane.propTypes = {
|
||||
// Functions
|
||||
sendRequest: PropTypes.func.isRequired,
|
||||
updateRequestUrl: PropTypes.func.isRequired,
|
||||
updateRequestMethod: PropTypes.func.isRequired,
|
||||
updateRequestBody: PropTypes.func.isRequired,
|
||||
updateRequestParams: PropTypes.func.isRequired,
|
||||
updateRequestAuthentication: PropTypes.func.isRequired,
|
||||
updateRequestHeaders: PropTypes.func.isRequired,
|
||||
|
||||
// Other
|
||||
request: PropTypes.object
|
||||
};
|
||||
|
||||
export default RequestPane;
|
||||
@@ -4,36 +4,40 @@ import Dropdown from './base/Dropdown';
|
||||
import {METHODS} from '../lib/constants';
|
||||
|
||||
class UrlInput extends Component {
|
||||
_handleFormSubmit (e) {
|
||||
e.preventDefault();
|
||||
this.props.sendRequest();
|
||||
}
|
||||
|
||||
render () {
|
||||
const {sendRequest, onUrlChange, onMethodChange, request} = this.props;
|
||||
const {onUrlChange, onMethodChange, uniquenessKey, url, method} = this.props;
|
||||
return (
|
||||
<div className="tall grid grid--center wide bg-super-light">
|
||||
<Dropdown className="tall">
|
||||
<button className="pad tall txt-md">
|
||||
{request.method} <i className="fa fa-caret-down"></i>
|
||||
{method}
|
||||
<i className="fa fa-caret-down"></i>
|
||||
</button>
|
||||
<ul>
|
||||
{METHODS.map((method) => (
|
||||
<li key={method}>
|
||||
<button onClick={onMethodChange.bind(null, method)}>
|
||||
{method}
|
||||
</button>
|
||||
{METHODS.map(m => (
|
||||
<li key={m}>
|
||||
<button onClick={onMethodChange.bind(null, m)}>{m}</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Dropdown>
|
||||
<form className="tall grid__cell form-control form-control--wide"
|
||||
onSubmit={e => {e.preventDefault(); sendRequest(request)}}>
|
||||
onSubmit={this._handleFormSubmit.bind(this)}>
|
||||
<DebouncingInput
|
||||
type="text"
|
||||
className="txt-md"
|
||||
placeholder="http://echo.insomnia.rest/status/200"
|
||||
value={request.url}
|
||||
value={url}
|
||||
debounceMillis={1000}
|
||||
uniquenessKey={request._id}
|
||||
uniquenessKey={uniquenessKey}
|
||||
onChange={onUrlChange}/>
|
||||
</form>
|
||||
<button className="btn btn--compact txt-lg" onClick={sendRequest.bind(null, request)}>
|
||||
<button className="btn btn--compact txt-lg" onClick={this._handleFormSubmit.bind(this)}>
|
||||
Send
|
||||
</button>
|
||||
</div>
|
||||
@@ -45,10 +49,9 @@ UrlInput.propTypes = {
|
||||
sendRequest: PropTypes.func.isRequired,
|
||||
onUrlChange: PropTypes.func.isRequired,
|
||||
onMethodChange: PropTypes.func.isRequired,
|
||||
request: PropTypes.shape({
|
||||
url: PropTypes.string.isRequired,
|
||||
method: PropTypes.string.isRequired
|
||||
}).isRequired
|
||||
uniquenessKey: PropTypes.string.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
method: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default UrlInput;
|
||||
|
||||
91
app/components/ResponsePane.js
Normal file
91
app/components/ResponsePane.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs'
|
||||
|
||||
import StatusTag from '../components/StatusTag'
|
||||
import Editor from '../components/base/Editor'
|
||||
import SizeTag from '../components/SizeTag'
|
||||
import TimeTag from '../components/TimeTag'
|
||||
|
||||
class ResponsePane extends Component {
|
||||
render () {
|
||||
const {
|
||||
response
|
||||
} = this.props;
|
||||
|
||||
if (!response) {
|
||||
return (
|
||||
<section className="grid__cell section grid--v grid--start">
|
||||
<header className="header bg-light section__header"></header>
|
||||
<div className="section__body grid__cell"></div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="grid__cell section">
|
||||
<div className="grid--v wide">
|
||||
<header
|
||||
className="grid grid--center header text-center bg-super-light txt-sm section__header">
|
||||
{!response ? null : (
|
||||
<div>
|
||||
<StatusTag
|
||||
statusCode={response.statusCode}
|
||||
statusMessage={response.statusMessage}
|
||||
/>
|
||||
<TimeTag milliseconds={response.millis}/>
|
||||
<SizeTag bytes={response.bytes}/>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
<Tabs className="grid__cell grid--v section__body">
|
||||
<TabList className="grid grid--start">
|
||||
<Tab><button>Preview</button></Tab>
|
||||
<Tab><button>Raw</button></Tab>
|
||||
<Tab><button>Headers</button></Tab>
|
||||
</TabList>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<Editor
|
||||
value={response && response.body || ''}
|
||||
prettify={true}
|
||||
options={{
|
||||
mode: response && response.contentType || 'text/plain',
|
||||
readOnly: true,
|
||||
placeholder: 'nothing yet...'
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<Editor
|
||||
value={response && response.body || ''}
|
||||
options={{
|
||||
lineWrapping: true,
|
||||
mode: 'text/plain',
|
||||
readOnly: true,
|
||||
placeholder: 'nothing yet...'
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div className="wide">
|
||||
<div className="grid--v grid--start pad">
|
||||
{!response ? null : response.headers.map((h, i) => (
|
||||
<div className="grid grid__cell grid__cell--no-flex selectable" key={i}>
|
||||
<div className="grid__cell">{h.name}</div>
|
||||
<div className="grid__cell">{h.value}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ResponsePane.propTypes = {
|
||||
response: PropTypes.object
|
||||
};
|
||||
|
||||
export default ResponsePane;
|
||||
@@ -1,10 +1,9 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import WorkspaceDropdown from './../containers/WorkspaceDropdown'
|
||||
import RequestActionsDropdown from './../containers/RequestActionsDropdown'
|
||||
import RequestGroupActionsDropdown from './../containers/RequestGroupActionsDropdown'
|
||||
import DebouncingInput from './base/DebouncingInput'
|
||||
import MethodTag from './MethodTag'
|
||||
import SidebarRequestRow from './SidebarRequestRow'
|
||||
|
||||
class Sidebar extends Component {
|
||||
onFilterChange (value) {
|
||||
@@ -13,25 +12,25 @@ class Sidebar extends Component {
|
||||
|
||||
renderRequestGroupRow (requestGroup = null) {
|
||||
const {
|
||||
activeFilter,
|
||||
activeRequest,
|
||||
filter,
|
||||
activeRequestId,
|
||||
addRequestToRequestGroup,
|
||||
toggleRequestGroup,
|
||||
requests,
|
||||
workspace
|
||||
workspaceId
|
||||
} = this.props;
|
||||
|
||||
let filteredRequests = requests.filter(
|
||||
r => {
|
||||
// TODO: Move this to a lib file
|
||||
|
||||
if (!activeFilter) {
|
||||
if (!filter) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const requestGroupName = requestGroup ? requestGroup.name : '';
|
||||
const toMatch = `${requestGroupName}✌${r.method}✌${r.name}`.toLowerCase();
|
||||
const matchTokens = activeFilter.toLowerCase().split(' ');
|
||||
const matchTokens = filter.toLowerCase().split(' ');
|
||||
for (let i = 0; i < matchTokens.length; i++) {
|
||||
let token = `${matchTokens[i]}`;
|
||||
if (toMatch.indexOf(token) === -1) {
|
||||
@@ -44,7 +43,7 @@ class Sidebar extends Component {
|
||||
);
|
||||
|
||||
if (!requestGroup) {
|
||||
filteredRequests = filteredRequests.filter(r => r.parentId === workspace._id);
|
||||
filteredRequests = filteredRequests.filter(r => r.parentId === workspaceId);
|
||||
return filteredRequests.map(request => this.renderRequestRow(request));
|
||||
}
|
||||
|
||||
@@ -52,11 +51,11 @@ class Sidebar extends Component {
|
||||
filteredRequests = filteredRequests.filter(r => r.parentId === requestGroup._id);
|
||||
|
||||
// Don't show folder if it was not in the filter
|
||||
if (activeFilter && !filteredRequests.length) {
|
||||
if (filter && !filteredRequests.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isActive = activeRequest && filteredRequests.find(r => r._id == activeRequest._id);
|
||||
const isActive = activeRequestId && filteredRequests.find(r => r._id == activeRequestId);
|
||||
|
||||
let folderIconClass = 'fa-folder';
|
||||
let expanded = !requestGroup.collapsed;
|
||||
@@ -97,36 +96,22 @@ class Sidebar extends Component {
|
||||
}
|
||||
|
||||
renderRequestRow (request = null, requestGroup = null) {
|
||||
const {activeRequest, activateRequest} = this.props;
|
||||
const isActive = request && activeRequest && request._id === activeRequest._id;
|
||||
|
||||
const {activeRequestId, activateRequest} = this.props;
|
||||
const isActive = request && activeRequestId && request._id === activeRequestId;
|
||||
|
||||
return (
|
||||
<li key={request ? request._id : 'none'}>
|
||||
<div className={'sidebar__item ' + (isActive ? 'sidebar__item--active' : '')}>
|
||||
<div className="sidebar__item__row">
|
||||
{request ? (
|
||||
<button onClick={() => {activateRequest(request)}}>
|
||||
<MethodTag method={request.method}/> {request.name}
|
||||
</button>
|
||||
) : (
|
||||
<button className="italic">No Requests</button>
|
||||
)}
|
||||
</div>
|
||||
{request ? (
|
||||
<RequestActionsDropdown
|
||||
className="sidebar__item__btn"
|
||||
right={true}
|
||||
request={request}
|
||||
requestGroup={requestGroup}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
<SidebarRequestRow
|
||||
key={request._id}
|
||||
activateRequest={activateRequest}
|
||||
isActive={isActive}
|
||||
request={request}
|
||||
requestGroup={requestGroup}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const {activeFilter, requestGroups} = this.props;
|
||||
const {filter, requestGroups} = this.props;
|
||||
|
||||
return (
|
||||
<section className="sidebar bg-dark grid--v section section--bordered">
|
||||
@@ -145,7 +130,7 @@ class Sidebar extends Component {
|
||||
type="text"
|
||||
placeholder="Filter Items"
|
||||
debounceMillis={300}
|
||||
value={activeFilter}
|
||||
value={filter}
|
||||
onChange={this.onFilterChange.bind(this)}/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -156,15 +141,20 @@ class Sidebar extends Component {
|
||||
}
|
||||
|
||||
Sidebar.propTypes = {
|
||||
// Functions
|
||||
activateRequest: PropTypes.func.isRequired,
|
||||
toggleRequestGroup: PropTypes.func.isRequired,
|
||||
addRequestToRequestGroup: PropTypes.func.isRequired,
|
||||
changeFilter: PropTypes.func.isRequired,
|
||||
toggleRequestGroup: PropTypes.func.isRequired,
|
||||
activeFilter: PropTypes.string,
|
||||
|
||||
// Other
|
||||
requests: PropTypes.array.isRequired,
|
||||
requestGroups: PropTypes.array.isRequired,
|
||||
workspace: PropTypes.object.isRequired,
|
||||
activeRequest: PropTypes.object
|
||||
workspaceId: PropTypes.string.isRequired,
|
||||
|
||||
// Optional
|
||||
filter: PropTypes.string,
|
||||
activeRequestId: PropTypes.string
|
||||
};
|
||||
|
||||
export default Sidebar;
|
||||
|
||||
47
app/components/SidebarRequestRow.js
Normal file
47
app/components/SidebarRequestRow.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import RequestActionsDropdown from './../containers/RequestActionsDropdown'
|
||||
import MethodTag from './MethodTag'
|
||||
|
||||
class SidebarRequestRow extends Component {
|
||||
render () {
|
||||
const {request, requestGroup, isActive, activateRequest} = this.props;
|
||||
|
||||
return (
|
||||
<li key={request ? request._id : 'none'}>
|
||||
<div className={'sidebar__item ' + (isActive ? 'sidebar__item--active' : '')}>
|
||||
<div className="sidebar__item__row">
|
||||
{request ? (
|
||||
<button onClick={() => {activateRequest(request)}}>
|
||||
<MethodTag method={request.method}/> {request.name}
|
||||
</button>
|
||||
) : (
|
||||
<button className="italic">No Requests</button>
|
||||
)}
|
||||
</div>
|
||||
{request ? (
|
||||
<RequestActionsDropdown
|
||||
className="sidebar__item__btn"
|
||||
right={true}
|
||||
request={request}
|
||||
requestGroup={requestGroup}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SidebarRequestRow.propTypes = {
|
||||
// Functions
|
||||
activateRequest: PropTypes.func.isRequired,
|
||||
|
||||
// Other
|
||||
request: PropTypes.object.isRequired,
|
||||
isActive: PropTypes.bool.isRequired,
|
||||
|
||||
// Optional
|
||||
requestGroup: PropTypes.object
|
||||
};
|
||||
|
||||
export default SidebarRequestRow;
|
||||
@@ -1,32 +1,20 @@
|
||||
import React, {Component, PropTypes} from 'react'
|
||||
import {connect} from 'react-redux'
|
||||
import {bindActionCreators} from 'redux'
|
||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs'
|
||||
|
||||
import Editor from '../components/base/Editor'
|
||||
import Prompts from './Prompts'
|
||||
import KeyValueEditor from '../components/base/KeyValueEditor'
|
||||
import Dropdown from '../components/base/Dropdown'
|
||||
import RequestBodyEditor from '../components/RequestBodyEditor'
|
||||
import RequestAuthEditor from '../components/RequestAuthEditor'
|
||||
import RequestUrlBar from '../components/RequestUrlBar'
|
||||
import StatusTag from '../components/StatusTag'
|
||||
import SizeTag from '../components/SizeTag'
|
||||
import TimeTag from '../components/TimeTag'
|
||||
import Sidebar from '../components/Sidebar'
|
||||
import EnvironmentEditModal from '../components/EnvironmentEditModal'
|
||||
import RequestPane from '../components/RequestPane'
|
||||
import ResponsePane from '../components/ResponsePane'
|
||||
import Sidebar from '../components/Sidebar'
|
||||
|
||||
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'
|
||||
import * as TabActions from '../redux/modules/tabs'
|
||||
|
||||
import * as db from '../database'
|
||||
|
||||
// Don't inject component styles (use our own)
|
||||
Tabs.setUseDefaultStyles(false);
|
||||
|
||||
class App extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
@@ -36,194 +24,44 @@ class App extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
_renderRequestPanel (actions, activeRequest, tabs) {
|
||||
if (!activeRequest) {
|
||||
return (
|
||||
<section className="grid__cell section section--bordered grid--v grid--start">
|
||||
<header className="header bg-super-light section__header"></header>
|
||||
<div className="section__body grid__cell"></div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="grid__cell section section--bordered">
|
||||
<div className="grid--v wide">
|
||||
<div className="header section__header">
|
||||
<RequestUrlBar
|
||||
sendRequest={actions.requests.send}
|
||||
onUrlChange={url => {db.update(activeRequest, {url})}}
|
||||
onMethodChange={method => {db.update(activeRequest, {method})}}
|
||||
request={activeRequest}
|
||||
/>
|
||||
</div>
|
||||
<Tabs className="grid__cell grid--v section__body"
|
||||
onSelect={i => actions.tabs.select('request', i)}
|
||||
selectedIndex={tabs.request || 0}>
|
||||
<TabList className="grid grid--start">
|
||||
<Tab className="no-wrap grid grid--center">
|
||||
<button>JSON</button>
|
||||
<Dropdown>
|
||||
<button> <i className="fa fa-caret-down"></i></button>
|
||||
<ul>
|
||||
<li><button><i className="fa fa-file-text"></i> Plain Text</button></li>
|
||||
<li><button><i className="fa fa-picture-o"></i> File Upload</button></li>
|
||||
<li><button><i className="fa fa-bars"></i> Form Data</button></li>
|
||||
<li><button><i className="fa fa-code"></i> HTML/XML</button></li>
|
||||
</ul>
|
||||
</Dropdown>
|
||||
</Tab>
|
||||
<Tab>
|
||||
<button className="no-wrap">
|
||||
Params {activeRequest.params.length ? `(${activeRequest.params.length})` : ''}
|
||||
</button>
|
||||
</Tab>
|
||||
<Tab>
|
||||
<button className="no-wrap">
|
||||
Headers {activeRequest.headers.length ? `(${activeRequest.headers.length})` : ''}
|
||||
</button>
|
||||
</Tab>
|
||||
</TabList>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<RequestBodyEditor
|
||||
onChange={body => {db.update(activeRequest, {body})}}
|
||||
request={activeRequest}/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div>
|
||||
<KeyValueEditor
|
||||
className="pad"
|
||||
namePlaceholder="name"
|
||||
valuePlaceholder="value"
|
||||
uniquenessKey={activeRequest._id}
|
||||
pairs={activeRequest.params}
|
||||
onChange={params => {db.update(activeRequest, {params})}}
|
||||
/>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div>
|
||||
<div className="pad">
|
||||
<label>Basic Authentication</label>
|
||||
<RequestAuthEditor
|
||||
request={activeRequest}
|
||||
onChange={authentication => {db.update(activeRequest, {authentication})}}
|
||||
/>
|
||||
<br/>
|
||||
<label>Other Headers</label>
|
||||
<KeyValueEditor
|
||||
namePlaceholder="My-Header"
|
||||
valuePlaceholder="Value"
|
||||
uniquenessKey={activeRequest._id}
|
||||
pairs={activeRequest.headers}
|
||||
onChange={headers => {db.update(activeRequest, {headers})}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
_renderResponsePanel (actions, activeResponse, tabs) {
|
||||
if (!activeResponse) {
|
||||
return (
|
||||
<section className="grid__cell section grid--v grid--start">
|
||||
<header className="header bg-light section__header"></header>
|
||||
<div className="section__body grid__cell"></div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="grid__cell section">
|
||||
<div className="grid--v wide">
|
||||
<header
|
||||
className="grid grid--center header text-center bg-super-light txt-sm section__header">
|
||||
{!activeResponse ? null : (
|
||||
<div>
|
||||
<StatusTag
|
||||
statusCode={activeResponse.statusCode}
|
||||
statusMessage={activeResponse.statusMessage}
|
||||
/>
|
||||
<TimeTag milliseconds={activeResponse.millis}/>
|
||||
<SizeTag bytes={activeResponse.bytes}/>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
<Tabs className="grid__cell grid--v section__body"
|
||||
onSelect={i => actions.tabs.select('response', i)}
|
||||
selectedIndex={tabs.response || 0}>
|
||||
<TabList className="grid grid--start">
|
||||
<Tab><button>Preview</button></Tab>
|
||||
<Tab><button>Raw</button></Tab>
|
||||
<Tab><button>Headers</button></Tab>
|
||||
</TabList>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<Editor
|
||||
value={activeResponse && activeResponse.body || ''}
|
||||
prettify={true}
|
||||
options={{
|
||||
mode: activeResponse && activeResponse.contentType || 'text/plain',
|
||||
readOnly: true,
|
||||
placeholder: 'nothing yet...'
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell editor-wrapper">
|
||||
<Editor
|
||||
value={activeResponse && activeResponse.body || ''}
|
||||
options={{
|
||||
lineWrapping: true,
|
||||
mode: 'text/plain',
|
||||
readOnly: true,
|
||||
placeholder: 'nothing yet...'
|
||||
}}
|
||||
/>
|
||||
</TabPanel>
|
||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||
<div className="wide">
|
||||
<div className="grid--v grid--start pad">
|
||||
{!activeResponse ? null : activeResponse.headers.map((h, i) => (
|
||||
<div className="grid grid__cell grid__cell--no-flex selectable" key={i}>
|
||||
<div className="grid__cell">{h.name}</div>
|
||||
<div className="grid__cell">{h.value}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
</Tabs>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const {actions, tabs, modals, workspaces} = this.props;
|
||||
const {actions, modals, workspaces} = this.props;
|
||||
const {requests, requestGroups, responses} = workspaces;
|
||||
|
||||
const activeRequest = requests.active;
|
||||
const activeResponse = activeRequest ? responses[activeRequest._id] : undefined;
|
||||
|
||||
return (
|
||||
<div className="grid bg-super-dark tall">
|
||||
<Sidebar
|
||||
workspace={workspaces.active}
|
||||
workspaceId={workspaces.active._id}
|
||||
activateRequest={db.requestActivate}
|
||||
changeFilter={actions.requests.changeFilter}
|
||||
addRequestToRequestGroup={requestGroup => db.requestCreate({parentId: requestGroup._id})}
|
||||
toggleRequestGroup={requestGroup => db.update(requestGroup, {collapsed: !requestGroup.collapsed})}
|
||||
activeRequest={activeRequest}
|
||||
activeFilter={requests.filter}
|
||||
activeRequestId={activeRequest._id}
|
||||
filter={requests.filter}
|
||||
requestGroups={requestGroups.all.sort((a, b) => a._id > b._id ? -1 : 1)}
|
||||
requests={requests.all.sort((a, b) => a._id > b._id ? -1 : 1)}/>
|
||||
requests={requests.all.sort((a, b) => a._id > b._id ? -1 : 1)}
|
||||
/>
|
||||
<div className="grid wide grid--collapse">
|
||||
{this._renderRequestPanel(actions, activeRequest, tabs)}
|
||||
{this._renderResponsePanel(actions, activeResponse, tabs)}
|
||||
<RequestPane
|
||||
request={activeRequest}
|
||||
sendRequest={actions.requests.send}
|
||||
updateRequestBody={body => db.update(activeRequest, {body})}
|
||||
updateRequestUrl={url => db.update(activeRequest, {url})}
|
||||
updateRequestMethod={method => db.update(activeRequest, {method})}
|
||||
updateRequestParams={params => db.update(activeRequest, {params})}
|
||||
updateRequestAuthentication={authentication => db.update(activeRequest, {authentication})}
|
||||
updateRequestHeaders={headers => db.update(activeRequest, {headers})}
|
||||
/>
|
||||
<ResponsePane
|
||||
response={activeResponse}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Prompts />
|
||||
|
||||
{modals.map(m => {
|
||||
if (m.id === EnvironmentEditModal.defaultProps.id) {
|
||||
return (
|
||||
@@ -246,21 +84,14 @@ class App extends Component {
|
||||
App.propTypes = {
|
||||
actions: PropTypes.shape({
|
||||
requests: PropTypes.shape({
|
||||
update: PropTypes.func.isRequired,
|
||||
remove: PropTypes.func.isRequired,
|
||||
send: PropTypes.func.isRequired,
|
||||
changeFilter: PropTypes.func.isRequired
|
||||
}),
|
||||
requestGroups: PropTypes.shape({
|
||||
remove: PropTypes.func.isRequired,
|
||||
update: PropTypes.func.isRequired,
|
||||
toggle: PropTypes.func.isRequired
|
||||
}),
|
||||
modals: PropTypes.shape({
|
||||
hide: PropTypes.func.isRequired
|
||||
}),
|
||||
tabs: PropTypes.shape({
|
||||
select: PropTypes.func.isRequired
|
||||
})
|
||||
}).isRequired,
|
||||
workspaces: PropTypes.shape({
|
||||
@@ -274,7 +105,6 @@ App.propTypes = {
|
||||
active: PropTypes.object
|
||||
}).isRequired
|
||||
}).isRequired,
|
||||
tabs: PropTypes.object.isRequired,
|
||||
modals: PropTypes.array.isRequired
|
||||
};
|
||||
|
||||
@@ -282,7 +112,6 @@ function mapStateToProps (state) {
|
||||
return {
|
||||
actions: state.actions,
|
||||
workspaces: state.workspaces,
|
||||
tabs: state.tabs,
|
||||
modals: state.modals
|
||||
};
|
||||
}
|
||||
@@ -291,7 +120,6 @@ function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
actions: {
|
||||
global: bindActionCreators(GlobalActions, dispatch),
|
||||
tabs: bindActionCreators(TabActions, dispatch),
|
||||
modals: bindActionCreators(ModalActions, dispatch),
|
||||
requestGroups: bindActionCreators(RequestGroupActions, dispatch),
|
||||
requests: bindActionCreators(RequestActions, dispatch)
|
||||
|
||||
@@ -13,7 +13,7 @@ export const TYPE_RESPONSE = 'Response';
|
||||
let db = new PouchDB('insomnia.db', {adapter: 'websql'});
|
||||
|
||||
// For browser console debugging
|
||||
global.db = db;
|
||||
// global.db = db;
|
||||
|
||||
let changeListeners = {};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import {render} from 'react-dom'
|
||||
import {Provider} from 'react-redux'
|
||||
import {Tabs} from 'react-tabs'
|
||||
|
||||
import createStore from './redux/create'
|
||||
import App from './containers/App'
|
||||
@@ -12,6 +13,9 @@ import './css/lib/fontawesome/css/font-awesome.css'
|
||||
import {initStore} from './redux/initstore'
|
||||
import {initDB} from './database'
|
||||
|
||||
// Don't inject component styles (use our own)
|
||||
Tabs.setUseDefaultStyles(false);
|
||||
|
||||
export const store = createStore();
|
||||
|
||||
console.log('-- Loading App --');
|
||||
|
||||
@@ -37,7 +37,7 @@ const workspaces = generateEntityReducer(
|
||||
);
|
||||
|
||||
const requestGroups = generateEntityReducer(
|
||||
'requestGroup',
|
||||
'requestGroup',
|
||||
requestGroupFns.REQUEST_GROUP_UPDATE,
|
||||
requestGroupFns.REQUEST_GROUP_DELETE
|
||||
);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {combineReducers} from 'redux'
|
||||
|
||||
import workspaces from './modules/workspaces'
|
||||
import tabs from './modules/tabs'
|
||||
import global from './modules/global'
|
||||
import modals from './modules/modals'
|
||||
import entities from './modules/entities'
|
||||
@@ -10,6 +9,5 @@ export default combineReducers({
|
||||
workspaces,
|
||||
modals,
|
||||
global,
|
||||
tabs,
|
||||
entities
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user