mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
Some stuff (#83)
This commit is contained in:
parent
f6f148185d
commit
ab6d4e03d6
@ -122,20 +122,29 @@ export function recursiveRender (obj, context) {
|
|||||||
return newObj;
|
return newObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getRenderedRequest (request, environmentId) {
|
export async function getRenderContext (request, environmentId, ancestors = null) {
|
||||||
const ancestors = await db.withAncestors(request);
|
if (!ancestors) {
|
||||||
const workspace = ancestors.find(doc => doc.type === models.workspace.type);
|
ancestors = await db.withAncestors(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspace = ancestors.find(doc => doc.type === models.workspace.type);
|
||||||
const rootEnvironment = await models.environment.getOrCreateForWorkspace(workspace);
|
const rootEnvironment = await models.environment.getOrCreateForWorkspace(workspace);
|
||||||
const subEnvironment = await models.environment.getById(environmentId);
|
const subEnvironment = await models.environment.getById(environmentId);
|
||||||
const cookieJar = await models.cookieJar.getOrCreateForWorkspace(workspace);
|
|
||||||
|
|
||||||
// Generate the context we need to render
|
// Generate the context we need to render
|
||||||
const renderContext = buildRenderContext(
|
return buildRenderContext(
|
||||||
ancestors,
|
ancestors,
|
||||||
rootEnvironment,
|
rootEnvironment,
|
||||||
subEnvironment
|
subEnvironment
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getRenderedRequest (request, environmentId) {
|
||||||
|
const ancestors = await db.withAncestors(request);
|
||||||
|
const workspace = ancestors.find(doc => doc.type === models.workspace.type);
|
||||||
|
const cookieJar = await models.cookieJar.getOrCreateForWorkspace(workspace);
|
||||||
|
|
||||||
|
const renderContext = await getRenderContext(request, environmentId, ancestors);
|
||||||
|
|
||||||
// Render all request properties
|
// Render all request properties
|
||||||
const renderedRequest = recursiveRender(request, renderContext);
|
const renderedRequest = recursiveRender(request, renderContext);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "insomnia",
|
"name": "insomnia",
|
||||||
"version": "4.2.12",
|
"version": "4.2.13",
|
||||||
"productName": "Insomnia",
|
"productName": "Insomnia",
|
||||||
"longName": "Insomnia REST Client",
|
"longName": "Insomnia REST Client",
|
||||||
"description": "A simple and beautiful REST API client",
|
"description": "A simple and beautiful REST API client",
|
||||||
|
@ -72,6 +72,7 @@ class RequestPane extends PureComponent {
|
|||||||
editorLineWrapping,
|
editorLineWrapping,
|
||||||
handleSend,
|
handleSend,
|
||||||
handleSendAndDownload,
|
handleSendAndDownload,
|
||||||
|
handleRender,
|
||||||
forceRefreshCounter,
|
forceRefreshCounter,
|
||||||
useBulkHeaderEditor,
|
useBulkHeaderEditor,
|
||||||
handleGenerateCode,
|
handleGenerateCode,
|
||||||
@ -190,6 +191,7 @@ class RequestPane extends PureComponent {
|
|||||||
<TabPanel className="editor-wrapper">
|
<TabPanel className="editor-wrapper">
|
||||||
<BodyEditor
|
<BodyEditor
|
||||||
handleUpdateRequestMimeType={updateRequestMimeType}
|
handleUpdateRequestMimeType={updateRequestMimeType}
|
||||||
|
handleRender={handleRender}
|
||||||
key={uniqueKey}
|
key={uniqueKey}
|
||||||
request={request}
|
request={request}
|
||||||
onChange={updateRequestBody}
|
onChange={updateRequestBody}
|
||||||
@ -285,6 +287,7 @@ RequestPane.propTypes = {
|
|||||||
handleSendAndDownload: PropTypes.func.isRequired,
|
handleSendAndDownload: PropTypes.func.isRequired,
|
||||||
handleCreateRequest: PropTypes.func.isRequired,
|
handleCreateRequest: PropTypes.func.isRequired,
|
||||||
handleGenerateCode: PropTypes.func.isRequired,
|
handleGenerateCode: PropTypes.func.isRequired,
|
||||||
|
handleRender: PropTypes.func.isRequired,
|
||||||
updateRequestUrl: PropTypes.func.isRequired,
|
updateRequestUrl: PropTypes.func.isRequired,
|
||||||
updateRequestMethod: PropTypes.func.isRequired,
|
updateRequestMethod: PropTypes.func.isRequired,
|
||||||
updateRequestBody: PropTypes.func.isRequired,
|
updateRequestBody: PropTypes.func.isRequired,
|
||||||
|
@ -168,6 +168,7 @@ class Wrapper extends Component {
|
|||||||
handleStartDragPane,
|
handleStartDragPane,
|
||||||
handleStartDragSidebar,
|
handleStartDragSidebar,
|
||||||
handleSetSidebarFilter,
|
handleSetSidebarFilter,
|
||||||
|
handleRender,
|
||||||
handleGenerateCodeForActiveRequest,
|
handleGenerateCodeForActiveRequest,
|
||||||
handleGenerateCode,
|
handleGenerateCode,
|
||||||
isLoading,
|
isLoading,
|
||||||
@ -244,6 +245,7 @@ class Wrapper extends Component {
|
|||||||
handleCreateRequest={handleCreateRequestForWorkspace}
|
handleCreateRequest={handleCreateRequestForWorkspace}
|
||||||
handleGenerateCode={handleGenerateCodeForActiveRequest}
|
handleGenerateCode={handleGenerateCodeForActiveRequest}
|
||||||
handleImport={this._handleImport}
|
handleImport={this._handleImport}
|
||||||
|
handleRender={handleRender}
|
||||||
updateRequestBody={this._handleUpdateRequestBody}
|
updateRequestBody={this._handleUpdateRequestBody}
|
||||||
updateRequestUrl={this._handleUpdateRequestUrl}
|
updateRequestUrl={this._handleUpdateRequestUrl}
|
||||||
updateRequestMethod={this._handleUpdateRequestMethod}
|
updateRequestMethod={this._handleUpdateRequestMethod}
|
||||||
@ -353,6 +355,7 @@ Wrapper.propTypes = {
|
|||||||
handleSetRequestPaneRef: PropTypes.func.isRequired,
|
handleSetRequestPaneRef: PropTypes.func.isRequired,
|
||||||
handleSetResponsePaneRef: PropTypes.func.isRequired,
|
handleSetResponsePaneRef: PropTypes.func.isRequired,
|
||||||
handleSetResponsePreviewMode: PropTypes.func.isRequired,
|
handleSetResponsePreviewMode: PropTypes.func.isRequired,
|
||||||
|
handleRender: PropTypes.func.isRequired,
|
||||||
handleSetResponseFilter: PropTypes.func.isRequired,
|
handleSetResponseFilter: PropTypes.func.isRequired,
|
||||||
handleSetActiveResponse: PropTypes.func.isRequired,
|
handleSetActiveResponse: PropTypes.func.isRequired,
|
||||||
handleSetSidebarRef: PropTypes.func.isRequired,
|
handleSetSidebarRef: PropTypes.func.isRequired,
|
||||||
|
@ -132,23 +132,41 @@ class Editor extends Component {
|
|||||||
const {value} = this.props;
|
const {value} = this.props;
|
||||||
|
|
||||||
// Add overlay to editor to make all links clickable
|
// Add overlay to editor to make all links clickable
|
||||||
CodeMirror.defineMode('clickable', (config, parserConfig) => {
|
CodeMirror.defineMode('master', (config, parserConfig) => {
|
||||||
const baseMode = CodeMirror.getMode(config, parserConfig.baseMode || 'text/plain');
|
const baseMode = CodeMirror.getMode(config, parserConfig.baseMode || 'text/plain');
|
||||||
|
|
||||||
// Only add the click mode if we have links to click
|
// Only add the click mode if we have links to click
|
||||||
if (!this.props.onClickLink) {
|
const highlightLinks = !!this.props.onClickLink;
|
||||||
return baseMode;
|
const highlightNunjucks = !this.props.readOnly;
|
||||||
}
|
|
||||||
|
const regexUrl = /^(https?:\/\/)?([\da-z.\-]+)\.([a-z.]{2,6})([\/\w .\-]*)*\/?/;
|
||||||
|
const regexVariable = /^{{[ |a-zA-Z0-9_\-+,'"\\()\[\]]+}}/;
|
||||||
|
const regexTag = /^{%[ |a-zA-Z0-9_\-+,'"\\()\[\]]+%}/;
|
||||||
|
const regexComment = /^{#[^#]+#}/;
|
||||||
|
|
||||||
const overlay = {
|
const overlay = {
|
||||||
token: function (stream, state) {
|
token: function (stream, state) {
|
||||||
// console.log('state', state);
|
if (highlightLinks && stream.match(regexUrl, true)) {
|
||||||
if (stream.match(/^(https?:\/\/)?([\da-z.\-]+)\.([a-z.]{2,6})([\/\w .\-]*)*\/?/, true)) {
|
|
||||||
return 'clickable';
|
return 'clickable';
|
||||||
}
|
}
|
||||||
|
|
||||||
while (stream.next() != null && !stream.match("http", false)) {
|
if (highlightNunjucks && stream.match(regexVariable, true)) {
|
||||||
// Do nothing
|
return 'variable-3';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highlightNunjucks && stream.match(regexTag, true)) {
|
||||||
|
return 'variable-3';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (highlightNunjucks && stream.match(regexComment, true)) {
|
||||||
|
return 'comment';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (stream.next() != null) {
|
||||||
|
if (stream.match(regexUrl, false)) break;
|
||||||
|
if (stream.match(regexVariable, false)) break;
|
||||||
|
if (stream.match(regexTag, false)) break;
|
||||||
|
if (stream.match(regexComment, false)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -271,7 +289,7 @@ class Editor extends Component {
|
|||||||
readOnly,
|
readOnly,
|
||||||
placeholder: this.props.placeholder || '',
|
placeholder: this.props.placeholder || '',
|
||||||
mode: {
|
mode: {
|
||||||
name: 'clickable',
|
name: 'master',
|
||||||
baseMode: normalizedMode,
|
baseMode: normalizedMode,
|
||||||
},
|
},
|
||||||
lineWrapping: this.props.lineWrapping,
|
lineWrapping: this.props.lineWrapping,
|
||||||
@ -424,16 +442,12 @@ class Editor extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {readOnly, fontSize, lightTheme, mode, filter} = this.props;
|
const {readOnly, fontSize, mode, filter} = this.props;
|
||||||
|
|
||||||
const classes = classnames(
|
const classes = classnames(
|
||||||
'editor',
|
'editor',
|
||||||
this.props.className,
|
this.props.className,
|
||||||
{
|
{'editor--readonly': readOnly}
|
||||||
'editor--readonly': readOnly,
|
|
||||||
'editor--light-theme': !!lightTheme,
|
|
||||||
'editor--dark-theme': !lightTheme
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const toolbarChildren = [];
|
const toolbarChildren = [];
|
||||||
@ -500,6 +514,7 @@ Editor.propTypes = {
|
|||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
onFocusChange: PropTypes.func,
|
onFocusChange: PropTypes.func,
|
||||||
onClickLink: PropTypes.func,
|
onClickLink: PropTypes.func,
|
||||||
|
render: PropTypes.func,
|
||||||
keyMap: PropTypes.string,
|
keyMap: PropTypes.string,
|
||||||
mode: PropTypes.string,
|
mode: PropTypes.string,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
@ -509,8 +524,8 @@ Editor.propTypes = {
|
|||||||
autoPrettify: PropTypes.bool,
|
autoPrettify: PropTypes.bool,
|
||||||
manualPrettify: PropTypes.bool,
|
manualPrettify: PropTypes.bool,
|
||||||
className: PropTypes.any,
|
className: PropTypes.any,
|
||||||
lightTheme: PropTypes.bool,
|
|
||||||
updateFilter: PropTypes.func,
|
updateFilter: PropTypes.func,
|
||||||
|
readOnly: PropTypes.bool,
|
||||||
filter: PropTypes.string
|
filter: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import {getContentTypeFromHeaders, CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_FO
|
|||||||
import {newBodyRaw, newBodyFormUrlEncoded, newBodyForm, newBodyFile} from '../../../../models/request';
|
import {newBodyRaw, newBodyFormUrlEncoded, newBodyForm, newBodyFile} from '../../../../models/request';
|
||||||
|
|
||||||
class BodyEditor extends PureComponent {
|
class BodyEditor extends PureComponent {
|
||||||
_handleRawChange = (rawValue) => {
|
_handleRawChange = rawValue => {
|
||||||
const {onChange, request} = this.props;
|
const {onChange, request} = this.props;
|
||||||
|
|
||||||
const contentType = getContentTypeFromHeaders(request.headers);
|
const contentType = getContentTypeFromHeaders(request.headers);
|
||||||
@ -16,26 +16,26 @@ class BodyEditor extends PureComponent {
|
|||||||
onChange(newBody);
|
onChange(newBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleFormUrlEncodedChange = (parameters) => {
|
_handleFormUrlEncodedChange = parameters => {
|
||||||
const {onChange} = this.props;
|
const {onChange} = this.props;
|
||||||
const newBody = newBodyFormUrlEncoded(parameters);
|
const newBody = newBodyFormUrlEncoded(parameters);
|
||||||
onChange(newBody);
|
onChange(newBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleFormChange = (parameters) => {
|
_handleFormChange = parameters => {
|
||||||
const {onChange} = this.props;
|
const {onChange} = this.props;
|
||||||
const newBody = newBodyForm(parameters);
|
const newBody = newBodyForm(parameters);
|
||||||
onChange(newBody);
|
onChange(newBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleFileChange = (path) => {
|
_handleFileChange = path => {
|
||||||
const {onChange} = this.props;
|
const {onChange} = this.props;
|
||||||
const newBody = newBodyFile(path);
|
const newBody = newBodyFile(path);
|
||||||
onChange(newBody);
|
onChange(newBody);
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {keyMap, fontSize, lineWrapping, request} = this.props;
|
const {keyMap, fontSize, lineWrapping, request, handleRender} = this.props;
|
||||||
const fileName = request.body.fileName;
|
const fileName = request.body.fileName;
|
||||||
const mimeType = request.body.mimeType;
|
const mimeType = request.body.mimeType;
|
||||||
const isBodyEmpty = typeof mimeType !== 'string' && !request.body.text;
|
const isBodyEmpty = typeof mimeType !== 'string' && !request.body.text;
|
||||||
@ -74,6 +74,7 @@ class BodyEditor extends PureComponent {
|
|||||||
lineWrapping={lineWrapping}
|
lineWrapping={lineWrapping}
|
||||||
contentType={contentType || 'text/plain'}
|
contentType={contentType || 'text/plain'}
|
||||||
content={request.body.text || ''}
|
content={request.body.text || ''}
|
||||||
|
render={handleRender}
|
||||||
onChange={this._handleRawChange}
|
onChange={this._handleRawChange}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@ -81,7 +82,7 @@ class BodyEditor extends PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div className="editor pad valign-center text-center">
|
<div className="editor pad valign-center text-center">
|
||||||
<p className="pad super-faint text-sm text-center">
|
<p className="pad super-faint text-sm text-center">
|
||||||
<i className="fa fa-hand-peace-o" style={{fontSize: '8rem', opacity: 0.3}}></i>
|
<i className="fa fa-hand-peace-o" style={{fontSize: '8rem', opacity: 0.3}}/>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
Select a body type from above
|
Select a body type from above
|
||||||
</p>
|
</p>
|
||||||
@ -95,6 +96,7 @@ BodyEditor.propTypes = {
|
|||||||
// Required
|
// Required
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
handleUpdateRequestMimeType: PropTypes.func.isRequired,
|
handleUpdateRequestMimeType: PropTypes.func.isRequired,
|
||||||
|
handleRender: PropTypes.func.isRequired,
|
||||||
request: PropTypes.object.isRequired,
|
request: PropTypes.object.isRequired,
|
||||||
|
|
||||||
// Optional
|
// Optional
|
||||||
|
@ -8,6 +8,7 @@ class RawEditor extends Component {
|
|||||||
content,
|
content,
|
||||||
fontSize,
|
fontSize,
|
||||||
keyMap,
|
keyMap,
|
||||||
|
render,
|
||||||
lineWrapping,
|
lineWrapping,
|
||||||
onChange,
|
onChange,
|
||||||
className
|
className
|
||||||
@ -20,6 +21,7 @@ class RawEditor extends Component {
|
|||||||
keyMap={keyMap}
|
keyMap={keyMap}
|
||||||
value={content}
|
value={content}
|
||||||
className={className}
|
className={className}
|
||||||
|
render={render}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
mode={contentType}
|
mode={contentType}
|
||||||
lineWrapping={lineWrapping}
|
lineWrapping={lineWrapping}
|
||||||
@ -34,11 +36,12 @@ RawEditor.propTypes = {
|
|||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
content: PropTypes.string.isRequired,
|
content: PropTypes.string.isRequired,
|
||||||
contentType: PropTypes.string.isRequired,
|
contentType: PropTypes.string.isRequired,
|
||||||
|
fontSize: PropTypes.number.isRequired,
|
||||||
|
keyMap: PropTypes.string.isRequired,
|
||||||
|
lineWrapping: PropTypes.bool.isRequired,
|
||||||
|
|
||||||
// Optional
|
// Optional
|
||||||
fontSize: PropTypes.number,
|
render: PropTypes.func,
|
||||||
keyMap: PropTypes.string,
|
|
||||||
lineWrapping: PropTypes.bool
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RawEditor;
|
export default RawEditor;
|
||||||
|
@ -2,6 +2,7 @@ import React, {Component, PropTypes} from 'react';
|
|||||||
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
|
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
|
||||||
import {shell} from 'electron';
|
import {shell} from 'electron';
|
||||||
import Modal from '../base/Modal';
|
import Modal from '../base/Modal';
|
||||||
|
import Button from '../base/Button';
|
||||||
import ModalBody from '../base/ModalBody';
|
import ModalBody from '../base/ModalBody';
|
||||||
import ModalHeader from '../base/ModalHeader';
|
import ModalHeader from '../base/ModalHeader';
|
||||||
import SettingsShortcuts from '../settings/SettingsShortcuts';
|
import SettingsShortcuts from '../settings/SettingsShortcuts';
|
||||||
@ -23,6 +24,29 @@ class SettingsModal extends Component {
|
|||||||
this.state = {}
|
this.state = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setModalRef = m => this.modal = m;
|
||||||
|
_trackTab = name => trackEvent('Setting', `Tab ${name}`);
|
||||||
|
_handleTabSelect = currentTabIndex => this.setState({currentTabIndex});
|
||||||
|
_handleUpdateSetting = (key, value) => {
|
||||||
|
models.settings.update(this.props.settings, {[key]: value});
|
||||||
|
trackEvent('Setting', 'Change', key)
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleExportAllToFile = () => {
|
||||||
|
this.props.handleExportAllToFile();
|
||||||
|
this.modal.hide()
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleExportWorkspace = () => {
|
||||||
|
this.props.handleExportWorkspaceToFile();
|
||||||
|
this.modal.hide()
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleImport = () => {
|
||||||
|
this.props.handleImportFile();
|
||||||
|
this.modal.hide()
|
||||||
|
};
|
||||||
|
|
||||||
_handleChangeTheme = (theme, track = true) => {
|
_handleChangeTheme = (theme, track = true) => {
|
||||||
document.body.setAttribute('theme', theme);
|
document.body.setAttribute('theme', theme);
|
||||||
models.settings.update(this.props.settings, {theme});
|
models.settings.update(this.props.settings, {theme});
|
||||||
@ -52,23 +76,13 @@ class SettingsModal extends Component {
|
|||||||
this.modal.toggle();
|
this.modal.toggle();
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleTabSelect (currentTabIndex) {
|
|
||||||
this.setState({currentTabIndex});
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {settings} = this.props;
|
||||||
settings,
|
|
||||||
handleExportAllToFile,
|
|
||||||
handleExportWorkspaceToFile,
|
|
||||||
handleImportFile,
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
const {currentTabIndex} = this.state;
|
const {currentTabIndex} = this.state;
|
||||||
const email = session.isLoggedIn() ? session.getEmail() : null;
|
const email = session.isLoggedIn() ? session.getEmail() : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal ref={m => this.modal = m} tall={true} {...this.props}>
|
<Modal ref={this._setModalRef} tall={true} {...this.props}>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
{getAppName()} Preferences
|
{getAppName()} Preferences
|
||||||
<span className="faint txt-sm">
|
<span className="faint txt-sm">
|
||||||
@ -78,57 +92,45 @@ class SettingsModal extends Component {
|
|||||||
</span>
|
</span>
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<ModalBody noScroll={true}>
|
<ModalBody noScroll={true}>
|
||||||
<Tabs onSelect={i => this._handleTabSelect(i)} selectedIndex={currentTabIndex}>
|
<Tabs onSelect={this._handleTabSelect} selectedIndex={currentTabIndex}>
|
||||||
<TabList>
|
<TabList>
|
||||||
<Tab selected={this._currentTabIndex === 0}>
|
<Tab selected={this._currentTabIndex === 0}>
|
||||||
<button onClick={e => trackEvent('Setting', 'Tab General')}>
|
<Button value="General" onClick={this._trackTab}>
|
||||||
General
|
General
|
||||||
</button>
|
</Button>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab selected={this._currentTabIndex === 1}>
|
<Tab selected={this._currentTabIndex === 1}>
|
||||||
<button onClick={e => trackEvent('Setting', 'Tab Import/Export')}>
|
<Button value="Import/Export" onClick={this._trackTab}>
|
||||||
Import/Export
|
Import/Export
|
||||||
</button>
|
</Button>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab selected={this._currentTabIndex === 2}>
|
<Tab selected={this._currentTabIndex === 2}>
|
||||||
<button onClick={e => trackEvent('Setting', 'Tab Themes')}>
|
<Button value="Themes" onClick={this._trackTab}>
|
||||||
Themes
|
Themes
|
||||||
</button>
|
</Button>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab selected={this._currentTabIndex === 3}>
|
<Tab selected={this._currentTabIndex === 3}>
|
||||||
<button onClick={e => trackEvent('Setting', 'Tab Shortcuts')}>
|
<Button value="shortcuts" onClick={this._trackTab}>
|
||||||
Shortcuts
|
Shortcuts
|
||||||
</button>
|
</Button>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab selected={this._currentTabIndex === 5}>
|
<Tab selected={this._currentTabIndex === 4}>
|
||||||
<button onClick={e => trackEvent('Setting', 'Tab About')}>
|
<Button value="About" onClick={this._trackTab}>
|
||||||
About
|
About
|
||||||
</button>
|
</Button>
|
||||||
</Tab>
|
</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanel className="pad scrollable">
|
<TabPanel className="pad scrollable">
|
||||||
<SettingsGeneral
|
<SettingsGeneral
|
||||||
settings={settings}
|
settings={settings}
|
||||||
updateSetting={(key, value) => {
|
updateSetting={this._handleUpdateSetting}
|
||||||
models.settings.update(settings, {[key]: value});
|
|
||||||
trackEvent('Setting', 'Change', key)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel className="pad scrollable">
|
<TabPanel className="pad scrollable">
|
||||||
<SettingsImportExport
|
<SettingsImportExport
|
||||||
handleExportAll={() => {
|
handleExportAll={this._handleExportAllToFile}
|
||||||
handleExportAllToFile();
|
handleExportWorkspace={this._handleExportWorkspace}
|
||||||
this.modal.hide()
|
handleImport={this._handleImport}
|
||||||
}}
|
|
||||||
handleExportWorkspace={() => {
|
|
||||||
handleExportWorkspaceToFile();
|
|
||||||
this.modal.hide()
|
|
||||||
}}
|
|
||||||
handleImport={() => {
|
|
||||||
handleImportFile();
|
|
||||||
this.modal.hide()
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel className="pad scrollable">
|
<TabPanel className="pad scrollable">
|
||||||
|
@ -1,52 +1,71 @@
|
|||||||
import React, {PropTypes} from 'react';
|
import React, {Component, PropTypes} from 'react';
|
||||||
|
|
||||||
const SettingsGeneral = ({settings, updateSetting}) => (
|
class SettingsGeneral extends Component {
|
||||||
|
_handleUpdateSetting = e => {
|
||||||
|
let value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
|
||||||
|
|
||||||
|
if (e.target.type === 'number') {
|
||||||
|
value = parseInt(value, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.updateSetting(e.target.name, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {settings} = this.props;
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="form-control form-control--thin">
|
<div className="form-control form-control--thin">
|
||||||
<label className="inline-block">Follow redirects automatically
|
<label className="inline-block">Follow redirects automatically
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
name="followRedirects"
|
||||||
checked={settings.followRedirects}
|
checked={settings.followRedirects}
|
||||||
onChange={e => updateSetting('followRedirects', e.target.checked)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-control form-control--thin">
|
<div className="form-control form-control--thin">
|
||||||
<label className="inline-block">Validate SSL Certificates
|
<label className="inline-block">Validate SSL Certificates
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
name="validateSSL"
|
||||||
checked={settings.validateSSL}
|
checked={settings.validateSSL}
|
||||||
onChange={e => updateSetting('validateSSL', e.target.checked)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-control form-control--thin">
|
<div className="form-control form-control--thin">
|
||||||
<label className="inline-block">Show passwords in plain-text
|
<label className="inline-block">Show passwords in plain-text
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
name="showPasswords"
|
||||||
checked={settings.showPasswords}
|
checked={settings.showPasswords}
|
||||||
onChange={e => updateSetting('showPasswords', e.target.checked)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-control form-control--thin">
|
<div className="form-control form-control--thin">
|
||||||
<label className="inline-block">Use bulk header editor by default
|
<label className="inline-block">Use bulk header editor by default
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
name="useBulkHeaderEditor"
|
||||||
checked={settings.useBulkHeaderEditor}
|
checked={settings.useBulkHeaderEditor}
|
||||||
onChange={e => updateSetting('useBulkHeaderEditor', e.target.checked)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-control form-control--thin">
|
<div className="form-control form-control--thin">
|
||||||
<label className="inline-block">Always use vertical layout
|
<label className="inline-block">Always use vertical layout
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
name="forceVerticalLayout"
|
||||||
checked={settings.forceVerticalLayout}
|
checked={settings.forceVerticalLayout}
|
||||||
onChange={e => updateSetting('forceVerticalLayout', e.target.checked)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-control form-control--thin">
|
<div className="form-control form-control--thin">
|
||||||
<label className="inline-block">Wrap Long Lines
|
<label className="inline-block">Wrap Long Lines
|
||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
|
name="editorLineWrapping"
|
||||||
checked={settings.editorLineWrapping}
|
checked={settings.editorLineWrapping}
|
||||||
onChange={e => updateSetting('editorLineWrapping', e.target.checked)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -54,10 +73,11 @@ const SettingsGeneral = ({settings, updateSetting}) => (
|
|||||||
<div className="form-control form-control--outlined pad-top-sm">
|
<div className="form-control form-control--outlined pad-top-sm">
|
||||||
<label>Text Editor Font Size (px)
|
<label>Text Editor Font Size (px)
|
||||||
<input type="number"
|
<input type="number"
|
||||||
|
name="editorFontSize"
|
||||||
min={8}
|
min={8}
|
||||||
max={20}
|
max={20}
|
||||||
defaultValue={settings.editorFontSize}
|
defaultValue={settings.editorFontSize}
|
||||||
onChange={e => updateSetting('editorFontSize', parseInt(e.target.value, 10))}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -65,7 +85,8 @@ const SettingsGeneral = ({settings, updateSetting}) => (
|
|||||||
<label>
|
<label>
|
||||||
Text Editor Key Map
|
Text Editor Key Map
|
||||||
<select defaultValue={settings.editorKeyMap}
|
<select defaultValue={settings.editorKeyMap}
|
||||||
onChange={e => updateSetting('editorKeyMap', e.target.value)}>
|
name="editorKeyMap"
|
||||||
|
onChange={this._handleUpdateSetting}>
|
||||||
<option value="default">Default</option>
|
<option value="default">Default</option>
|
||||||
<option value="vim">Vim</option>
|
<option value="vim">Vim</option>
|
||||||
<option value="emacs">Emacs</option>
|
<option value="emacs">Emacs</option>
|
||||||
@ -78,32 +99,37 @@ const SettingsGeneral = ({settings, updateSetting}) => (
|
|||||||
<div className="form-control form-control--outlined">
|
<div className="form-control form-control--outlined">
|
||||||
<label>Request Timeout (ms) (0 for no timeout)
|
<label>Request Timeout (ms) (0 for no timeout)
|
||||||
<input type="number"
|
<input type="number"
|
||||||
|
name="timeout"
|
||||||
min={0}
|
min={0}
|
||||||
defaultValue={settings.timeout}
|
defaultValue={settings.timeout}
|
||||||
onChange={e => updateSetting('timeout', parseInt(e.target.value, 10))}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-row">
|
<div className="form-row">
|
||||||
<div className="form-control form-control--outlined">
|
<div className="form-control form-control--outlined">
|
||||||
<label>HTTP Proxy
|
<label>HTTP Proxy
|
||||||
<input type="text"
|
<input type="text"
|
||||||
|
name="httpProxy"
|
||||||
placeholder="localhost:8005"
|
placeholder="localhost:8005"
|
||||||
defaultValue={settings.httpProxy}
|
defaultValue={settings.httpProxy}
|
||||||
onChange={e => updateSetting('httpProxy', e.target.value)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-control form-control--outlined">
|
<div className="form-control form-control--outlined">
|
||||||
<label>HTTPS Proxy
|
<label>HTTPS Proxy
|
||||||
<input placeholder="localhost:8005"
|
<input placeholder="localhost:8005"
|
||||||
|
name="httpsProxy"
|
||||||
type="text"
|
type="text"
|
||||||
defaultValue={settings.httpsProxy}
|
defaultValue={settings.httpsProxy}
|
||||||
onChange={e => updateSetting('httpsProxy', e.target.value)}/>
|
onChange={this._handleUpdateSetting}/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SettingsGeneral.propTypes = {
|
SettingsGeneral.propTypes = {
|
||||||
settings: PropTypes.object.isRequired,
|
settings: PropTypes.object.isRequired,
|
||||||
|
@ -28,6 +28,7 @@ import * as network from '../../common/network';
|
|||||||
import {debounce} from '../../common/misc';
|
import {debounce} from '../../common/misc';
|
||||||
import * as mime from 'mime-types';
|
import * as mime from 'mime-types';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import * as render from '../../common/render';
|
||||||
|
|
||||||
const KEY_ENTER = 13;
|
const KEY_ENTER = 13;
|
||||||
const KEY_COMMA = 188;
|
const KEY_COMMA = 188;
|
||||||
@ -143,7 +144,7 @@ class App extends Component {
|
|||||||
models.requestGroup.create({parentId, name})
|
models.requestGroup.create({parentId, name})
|
||||||
};
|
};
|
||||||
|
|
||||||
_requestCreate = async (parentId) => {
|
_requestCreate = async parentId => {
|
||||||
const request = await showModal(RequestCreateModal, {parentId});
|
const request = await showModal(RequestCreateModal, {parentId});
|
||||||
this._handleSetActiveRequest(request._id)
|
this._handleSetActiveRequest(request._id)
|
||||||
};
|
};
|
||||||
@ -158,7 +159,14 @@ class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newRequest = await models.request.duplicate(request);
|
const newRequest = await models.request.duplicate(request);
|
||||||
this._handleSetActiveRequest(newRequest._id)
|
await this._handleSetActiveRequest(newRequest._id)
|
||||||
|
};
|
||||||
|
|
||||||
|
_handleRenderText = async text => {
|
||||||
|
const {activeEnvironment, activeRequest} = this.props;
|
||||||
|
const environmentId = activeEnvironment ? activeEnvironment._id : null;
|
||||||
|
const context = await render.getRenderContext(activeRequest, environmentId);
|
||||||
|
return render.render(text, context);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleGenerateCodeForActiveRequest = () => {
|
_handleGenerateCodeForActiveRequest = () => {
|
||||||
@ -206,12 +214,13 @@ class App extends Component {
|
|||||||
this._savePaneWidth(paneWidth);
|
this._savePaneWidth(paneWidth);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleSetActiveRequest = activeRequestId => {
|
_handleSetActiveRequest = async activeRequestId => {
|
||||||
this._updateActiveWorkspaceMeta({activeRequestId});
|
await this._updateActiveWorkspaceMeta({activeRequestId});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleSetActiveEnvironment = activeEnvironmentId => {
|
_handleSetActiveEnvironment = async activeEnvironmentId => {
|
||||||
this._updateActiveWorkspaceMeta({activeEnvironmentId});
|
await this._updateActiveWorkspaceMeta({activeEnvironmentId});
|
||||||
|
this._wrapper.forceRequestPaneRefresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
_saveSidebarWidth = debounce(sidebarWidth => this._updateActiveWorkspaceMeta({sidebarWidth}));
|
_saveSidebarWidth = debounce(sidebarWidth => this._updateActiveWorkspaceMeta({sidebarWidth}));
|
||||||
@ -220,12 +229,12 @@ class App extends Component {
|
|||||||
this._saveSidebarWidth(sidebarWidth);
|
this._saveSidebarWidth(sidebarWidth);
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleSetSidebarHidden = sidebarHidden => {
|
_handleSetSidebarHidden = async sidebarHidden => {
|
||||||
this._updateActiveWorkspaceMeta({sidebarHidden});
|
await this._updateActiveWorkspaceMeta({sidebarHidden});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleSetSidebarFilter = sidebarFilter => {
|
_handleSetSidebarFilter = async sidebarFilter => {
|
||||||
this._updateActiveWorkspaceMeta({sidebarFilter});
|
await this._updateActiveWorkspaceMeta({sidebarFilter});
|
||||||
};
|
};
|
||||||
|
|
||||||
_handleSetRequestGroupCollapsed = (requestGroupId, collapsed) => {
|
_handleSetRequestGroupCollapsed = (requestGroupId, collapsed) => {
|
||||||
@ -431,7 +440,7 @@ class App extends Component {
|
|||||||
trackEvent('General', 'Launched', getAppVersion(), {nonInteraction: true});
|
trackEvent('General', 'Launched', getAppVersion(), {nonInteraction: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
db.onChange(changes => {
|
db.onChange(async changes => {
|
||||||
for (const change of changes) {
|
for (const change of changes) {
|
||||||
const [event, doc, fromSync] = change;
|
const [event, doc, fromSync] = change;
|
||||||
const {activeRequest} = this.props;
|
const {activeRequest} = this.props;
|
||||||
@ -499,6 +508,7 @@ class App extends Component {
|
|||||||
handleStartDragPane={this._startDragPane}
|
handleStartDragPane={this._startDragPane}
|
||||||
handleResetDragPane={this._resetDragPane}
|
handleResetDragPane={this._resetDragPane}
|
||||||
handleCreateRequest={this._requestCreate}
|
handleCreateRequest={this._requestCreate}
|
||||||
|
handleRender={this._handleRenderText}
|
||||||
handleDuplicateRequest={this._requestDuplicate}
|
handleDuplicateRequest={this._requestDuplicate}
|
||||||
handleDuplicateRequestGroup={this._requestGroupDuplicate}
|
handleDuplicateRequestGroup={this._requestGroupDuplicate}
|
||||||
handleCreateRequestGroup={this._requestGroupCreate}
|
handleCreateRequestGroup={this._requestGroupCreate}
|
||||||
|
@ -176,7 +176,6 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.cm-comment,
|
|
||||||
span.cm-meta,
|
span.cm-meta,
|
||||||
span.cm-qualifier {
|
span.cm-qualifier {
|
||||||
color: var(--color-font);
|
color: var(--color-font);
|
||||||
@ -215,7 +214,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
span.cm-variable-3 {
|
span.cm-variable-3 {
|
||||||
color: var(--color-info);
|
color: var(--color-surprise);
|
||||||
}
|
}
|
||||||
|
|
||||||
span.cm-def {
|
span.cm-def {
|
||||||
@ -238,6 +237,10 @@
|
|||||||
color: var(--color-surprise);
|
color: var(--color-surprise);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.cm-comment {
|
||||||
|
color: var(--hl);
|
||||||
|
}
|
||||||
|
|
||||||
span.cm-error {
|
span.cm-error {
|
||||||
background: var(--color-danger);
|
background: var(--color-danger);
|
||||||
color: var(--color-font-danger);
|
color: var(--color-font-danger);
|
||||||
|
@ -45,7 +45,7 @@ body {
|
|||||||
--color-notice: #ead950;
|
--color-notice: #ead950;
|
||||||
--color-warning: #ff9a1f;
|
--color-warning: #ff9a1f;
|
||||||
--color-danger: #ff5d4b;
|
--color-danger: #ff5d4b;
|
||||||
--color-surprise: #a590ff;
|
--color-surprise: #a896ff;
|
||||||
--color-info: #22c2f0;
|
--color-info: #22c2f0;
|
||||||
|
|
||||||
.tag {
|
.tag {
|
||||||
|
Loading…
Reference in New Issue
Block a user