diff --git a/packages/insomnia-app/app/ui/components/panes/blank-pane.js b/packages/insomnia-app/app/ui/components/panes/blank-pane.js
new file mode 100644
index 0000000000..2558c9cbd8
--- /dev/null
+++ b/packages/insomnia-app/app/ui/components/panes/blank-pane.js
@@ -0,0 +1,16 @@
+// @flow
+import React from 'react';
+import { Pane, PaneBody, PaneHeader } from './pane';
+
+type Props = {
+ type: 'request' | 'response',
+};
+
+const BlankPane = ({ type }: Props) => (
+
+
+
+
+);
+
+export default BlankPane;
diff --git a/packages/insomnia-app/app/ui/components/panes/grpc-request-pane.js b/packages/insomnia-app/app/ui/components/panes/grpc-request-pane.js
new file mode 100644
index 0000000000..d38a196747
--- /dev/null
+++ b/packages/insomnia-app/app/ui/components/panes/grpc-request-pane.js
@@ -0,0 +1,7 @@
+// @flow
+import React from 'react';
+import BlankPane from './blank-pane';
+
+const GrpcRequestPane = () => ;
+
+export default GrpcRequestPane;
diff --git a/packages/insomnia-app/app/ui/components/panes/grpc-response-pane.js b/packages/insomnia-app/app/ui/components/panes/grpc-response-pane.js
new file mode 100644
index 0000000000..ddbaf2a8ef
--- /dev/null
+++ b/packages/insomnia-app/app/ui/components/panes/grpc-response-pane.js
@@ -0,0 +1,7 @@
+// @flow
+import React from 'react';
+import BlankPane from './blank-pane';
+
+const GrpcResponsePane = () => ;
+
+export default GrpcResponsePane;
diff --git a/packages/insomnia-app/app/ui/components/panes/pane.js b/packages/insomnia-app/app/ui/components/panes/pane.js
new file mode 100644
index 0000000000..398bbdeda6
--- /dev/null
+++ b/packages/insomnia-app/app/ui/components/panes/pane.js
@@ -0,0 +1,45 @@
+// @flow
+import classnames from 'classnames';
+import React from 'react';
+
+type PaneProps = {
+ className?: string,
+ type: 'request' | 'response',
+};
+
+type PaneHeaderProps = {
+ className?: string,
+};
+
+type PaneBodyProps = {
+ className?: string,
+ placeholder?: boolean,
+};
+
+export const Pane = ({ className, type, children }: PaneProps) => (
+
+);
+
+export const PaneHeader = ({ className, children }: PaneHeaderProps) => (
+
+);
+
+export const paneBodyClasses = 'pane__body theme--pane__body';
+
+export const PaneBody = ({ placeholder, children }: PaneBodyProps) => (
+
+ {children}
+
+);
+
+// This class component is needed in order to apply a ref to it for resizing
+// The component can be removed, once PR #2712 is merged
+export class ResizablePaneWrapper extends React.PureComponent {
+ render() {
+ return <>{this.props.children}>;
+ }
+}
diff --git a/packages/insomnia-app/app/ui/components/panes/placeholder-request-pane.js b/packages/insomnia-app/app/ui/components/panes/placeholder-request-pane.js
new file mode 100644
index 0000000000..c1f1881327
--- /dev/null
+++ b/packages/insomnia-app/app/ui/components/panes/placeholder-request-pane.js
@@ -0,0 +1,76 @@
+// @flow
+import React from 'react';
+import Hotkey from '../hotkey';
+import { hotKeyRefs } from '../../../common/hotkeys';
+import * as hotkeys from '../../../common/hotkeys';
+import type { Request } from '../../../models/request';
+import type { ForceToWorkspace } from '../../redux/modules/helpers';
+import { Pane, PaneBody, PaneHeader } from './pane';
+
+type Props = {
+ hotKeyRegistry: hotkeys.HotKeyRegistry,
+ handleImportFile: (forceToWorkspace?: ForceToWorkspace) => void,
+ handleCreateRequest: () => Promise,
+};
+
+const PlaceholderRequestPane = ({
+ hotKeyRegistry,
+ handleImportFile,
+ handleCreateRequest,
+}: Props) => (
+
+
+
+
+
+
+
+ | New Request |
+
+
+
+
+ |
+
+
+ | Switch Requests |
+
+
+
+
+ |
+
+
+ | Edit Environments |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+);
+
+export default PlaceholderRequestPane;
diff --git a/packages/insomnia-app/app/ui/components/panes/placeholder-response-pane.js b/packages/insomnia-app/app/ui/components/panes/placeholder-response-pane.js
new file mode 100644
index 0000000000..79ff37daba
--- /dev/null
+++ b/packages/insomnia-app/app/ui/components/panes/placeholder-response-pane.js
@@ -0,0 +1,71 @@
+// @flow
+import React from 'react';
+import Hotkey from '../hotkey';
+import { hotKeyRefs } from '../../../common/hotkeys';
+import * as hotkeys from '../../../common/hotkeys';
+import { Pane, PaneBody, PaneHeader } from './pane';
+
+type Props = {
+ hotKeyRegistry: hotkeys.HotKeyRegistry,
+};
+
+const PlaceholderResponsePane = ({ hotKeyRegistry, children }: Props) => (
+
+
+
+
+
+
+
+ | Send Request |
+
+
+
+
+ |
+
+
+ | Focus Url Bar |
+
+
+
+
+ |
+
+
+ | Manage Cookies |
+
+
+
+
+ |
+
+
+ | Edit Environments |
+
+
+
+
+ |
+
+
+
+
+
+ {children}
+
+);
+
+export default PlaceholderResponsePane;
diff --git a/packages/insomnia-app/app/ui/components/request-pane.js b/packages/insomnia-app/app/ui/components/panes/request-pane.js
similarity index 79%
rename from packages/insomnia-app/app/ui/components/request-pane.js
rename to packages/insomnia-app/app/ui/components/panes/request-pane.js
index c678c136af..01633da350 100644
--- a/packages/insomnia-app/app/ui/components/request-pane.js
+++ b/packages/insomnia-app/app/ui/components/panes/request-pane.js
@@ -5,31 +5,33 @@ import type {
RequestBody,
RequestHeader,
RequestParameter,
-} from '../../models/request';
-import type { Workspace } from '../../models/workspace';
-import type { OAuth2Token } from '../../models/o-auth-2-token';
+} from '../../../models/request';
+import type { Workspace } from '../../../models/workspace';
+import type { OAuth2Token } from '../../../models/o-auth-2-token';
import autobind from 'autobind-decorator';
import { deconstructQueryStringToParams, extractQueryStringFromUrl } from 'insomnia-url';
import * as React from 'react';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
-import { getAuthTypeName, getContentTypeName } from '../../common/constants';
-import * as db from '../../common/database';
-import { hotKeyRefs } from '../../common/hotkeys';
-import * as models from '../../models';
-import AuthDropdown from './dropdowns/auth-dropdown';
-import ContentTypeDropdown from './dropdowns/content-type-dropdown';
-import AuthWrapper from './editors/auth/auth-wrapper';
-import BodyEditor from './editors/body/body-editor';
-import RequestHeadersEditor from './editors/request-headers-editor';
-import ErrorBoundary from './error-boundary';
-import Hotkey from './hotkey';
-import MarkdownPreview from './markdown-preview';
-import { showModal } from './modals/index';
-import RequestSettingsModal from './modals/request-settings-modal';
-import RenderedQueryString from './rendered-query-string';
-import RequestUrlBar from './request-url-bar.js';
-import type { Settings } from '../../models/settings';
-import RequestParametersEditor from './editors/request-parameters-editor';
+import { getAuthTypeName, getContentTypeName } from '../../../common/constants';
+import * as db from '../../../common/database';
+import * as models from '../../../models';
+import AuthDropdown from '../dropdowns/auth-dropdown';
+import ContentTypeDropdown from '../dropdowns/content-type-dropdown';
+import AuthWrapper from '../editors/auth/auth-wrapper';
+import BodyEditor from '../editors/body/body-editor';
+import RequestHeadersEditor from '../editors/request-headers-editor';
+import ErrorBoundary from '../error-boundary';
+import MarkdownPreview from '../markdown-preview';
+import { showModal } from '../modals';
+import RequestSettingsModal from '../modals/request-settings-modal';
+import RenderedQueryString from '../rendered-query-string';
+import RequestUrlBar from '../request-url-bar.js';
+import type { Settings } from '../../../models/settings';
+import RequestParametersEditor from '../editors/request-parameters-editor';
+import type { ForceToWorkspace } from '../../redux/modules/helpers';
+import PlaceholderRequestPane from './placeholder-request-pane';
+import { Pane, paneBodyClasses, PaneHeader } from './pane';
+import classnames from 'classnames';
type Props = {
// Functions
@@ -53,7 +55,7 @@ type Props = {
updateSettingsUseBulkHeaderEditor: Function,
updateSettingsUseBulkParametersEditor: Function,
handleImport: Function,
- handleImportFile: Function,
+ handleImportFile: (forceToWorkspace?: ForceToWorkspace) => void,
// Other
workspace: Workspace,
@@ -109,14 +111,6 @@ class RequestPane extends React.PureComponent {
updateSettingsUseBulkParametersEditor(!settings.useBulkParametersEditor);
}
- _handleImportFile() {
- this.props.handleImportFile();
- }
-
- _handleCreateRequest() {
- this.props.handleCreateRequest();
- }
-
_handleImportQueryFromUrl() {
const { request, forceUpdateRequest } = this.props;
@@ -150,6 +144,8 @@ class RequestPane extends React.PureComponent {
handleGenerateCode,
handleGetRenderContext,
handleImport,
+ handleImportFile,
+ handleCreateRequest,
handleRender,
handleSend,
handleSendAndDownload,
@@ -172,69 +168,15 @@ class RequestPane extends React.PureComponent {
downloadPath,
} = this.props;
- const paneClasses = 'request-pane theme--pane pane';
- const paneHeaderClasses = 'pane__header theme--pane__header';
- const paneBodyClasses = 'pane__body theme--pane__body';
-
const hotKeyRegistry = settings.hotKeyRegistry;
if (!request) {
return (
-
-
-
-
-
-
-
- | New Request |
-
-
-
-
- |
-
-
- | Switch Requests |
-
-
-
-
- |
-
-
- | Edit Environments |
-
-
-
-
- |
-
-
-
-
-
-
-
-
-
-
-
+
);
}
@@ -250,8 +192,8 @@ class RequestPane extends React.PureComponent {
const uniqueKey = `${forceRefreshCounter}::${request._id}`;
return (
-
-
+
+
{
downloadPath={downloadPath}
/>
-
-
+
+
{
)}
-
+
);
}
}
diff --git a/packages/insomnia-app/app/ui/components/response-pane.js b/packages/insomnia-app/app/ui/components/panes/response-pane.js
similarity index 71%
rename from packages/insomnia-app/app/ui/components/response-pane.js
rename to packages/insomnia-app/app/ui/components/panes/response-pane.js
index 561452d50c..465aac3dca 100644
--- a/packages/insomnia-app/app/ui/components/response-pane.js
+++ b/packages/insomnia-app/app/ui/components/panes/response-pane.js
@@ -1,6 +1,6 @@
// @flow
-import type { Request } from '../../models/request';
-import type { Response } from '../../models/response';
+import type { Request } from '../../../models/request';
+import type { Response } from '../../../models/response';
import * as React from 'react';
import autobind from 'autobind-decorator';
@@ -8,30 +8,32 @@ import fs from 'fs';
import mime from 'mime-types';
import { remote } from 'electron';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
-import SizeTag from './tags/size-tag';
-import StatusTag from './tags/status-tag';
-import TimeTag from './tags/time-tag';
-import Button from './base/button';
-import PreviewModeDropdown from './dropdowns/preview-mode-dropdown';
-import ResponseViewer from './viewers/response-viewer';
-import ResponseHistoryDropdown from './dropdowns/response-history-dropdown';
-import ResponseTimer from './response-timer';
-import ResponseTimelineViewer from './viewers/response-timeline-viewer';
-import ResponseHeadersViewer from './viewers/response-headers-viewer';
-import ResponseCookiesViewer from './viewers/response-cookies-viewer';
-import * as models from '../../models';
-import { PREVIEW_MODE_SOURCE } from '../../common/constants';
-import { getSetCookieHeaders } from '../../common/misc';
-import { cancelRequestById } from '../../network/network';
-import Hotkey from './hotkey';
-import ErrorBoundary from './error-boundary';
-import type { HotKeyRegistry } from '../../common/hotkeys';
-import { hotKeyRefs } from '../../common/hotkeys';
-import type { RequestVersion } from '../../models/request-version';
-import { showError } from '../components/modals/index';
+import SizeTag from '../tags/size-tag';
+import StatusTag from '../tags/status-tag';
+import TimeTag from '../tags/time-tag';
+import Button from '../base/button';
+import PreviewModeDropdown from '../dropdowns/preview-mode-dropdown';
+import ResponseViewer from '../viewers/response-viewer';
+import ResponseHistoryDropdown from '../dropdowns/response-history-dropdown';
+import ResponseTimer from '../response-timer';
+import ResponseTimelineViewer from '../viewers/response-timeline-viewer';
+import ResponseHeadersViewer from '../viewers/response-headers-viewer';
+import ResponseCookiesViewer from '../viewers/response-cookies-viewer';
+import * as models from '../../../models';
+import { PREVIEW_MODE_SOURCE } from '../../../common/constants';
+import { getSetCookieHeaders } from '../../../common/misc';
+import { cancelRequestById } from '../../../network/network';
+import ErrorBoundary from '../error-boundary';
+import type { HotKeyRegistry } from '../../../common/hotkeys';
+import type { RequestVersion } from '../../../models/request-version';
+import { showError } from '../modals';
import { json as jsonPrettify } from 'insomnia-prettify';
-import type { Environment } from '../../models/environment';
-import type { UnitTestResult } from '../../models/unit-test-result';
+import type { Environment } from '../../../models/environment';
+import type { UnitTestResult } from '../../../models/unit-test-result';
+import BlankPane from './blank-pane';
+import PlaceholderResponsePane from './placeholder-response-pane';
+import { Pane, paneBodyClasses, PaneHeader } from './pane';
+import classnames from 'classnames';
type Props = {
// Functions
@@ -204,90 +206,28 @@ class ResponsePane extends React.PureComponent {
responses,
showCookiesModal,
} = this.props;
- const paneClasses = 'response-pane theme--pane pane';
- const paneHeaderClasses = 'pane__header theme--pane__header';
- const paneBodyClasses = 'pane__body theme--pane__body';
if (!request) {
- return (
-
- );
+ return ;
}
if (!response) {
return (
-
-
-
-
-
-
-
- | Send Request |
-
-
-
-
- |
-
-
- | Focus Url Bar |
-
-
-
-
- |
-
-
- | Manage Cookies |
-
-
-
-
- |
-
-
- | Edit Environments |
-
-
-
-
- |
-
-
-
-
-
-
+
cancelRequestById(request._id)}
loadStartTime={loadStartTime}
/>
-
+
);
}
const cookieHeaders = getSetCookieHeaders(response.headers);
return (
-
+
{!response ? null : (
-
+
@@ -305,10 +245,10 @@ class ResponsePane extends React.PureComponent
{
className="tall pane__header__right"
right
/>
-
+
)}
@@ -400,7 +340,7 @@ class ResponsePane extends React.PureComponent {
loadStartTime={loadStartTime}
/>
-
+
);
}
}
diff --git a/packages/insomnia-app/app/ui/components/wrapper-debug.js b/packages/insomnia-app/app/ui/components/wrapper-debug.js
index a6638ab19f..0510182f15 100644
--- a/packages/insomnia-app/app/ui/components/wrapper-debug.js
+++ b/packages/insomnia-app/app/ui/components/wrapper-debug.js
@@ -4,9 +4,9 @@ import autobind from 'autobind-decorator';
import { Breadcrumb, Header } from 'insomnia-components';
import PageLayout from './page-layout';
import type { WrapperProps } from './wrapper';
-import RequestPane from './request-pane';
+import RequestPane from './panes/request-pane';
import ErrorBoundary from './error-boundary';
-import ResponsePane from './response-pane';
+import ResponsePane from './panes/response-pane';
import SidebarChildren from './sidebar/sidebar-children';
import SidebarFilter from './sidebar/sidebar-filter';
import EnvironmentsDropdown from './dropdowns/environments-dropdown';
@@ -15,6 +15,10 @@ import WorkspaceDropdown from './dropdowns/workspace-dropdown';
import { ACTIVITY_HOME, isInsomnia } from '../../common/constants';
import ActivityToggle from './activity-toggle';
import { isGrpcRequest } from '../../models/helpers/is-model';
+import type { ForceToWorkspace } from '../redux/modules/helpers';
+import GrpcRequestPane from './panes/grpc-request-pane';
+import GrpcResponsePane from './panes/grpc-response-pane';
+import { ResizablePaneWrapper } from './panes/pane';
type Props = {
forceRefreshKey: string,
@@ -26,7 +30,7 @@ type Props = {
handleForceUpdateRequest: Function,
handleForceUpdateRequestHeaders: Function,
handleImport: Function,
- handleImportFile: Function,
+ handleImportFile: (forceToWorkspace?: ForceToWorkspace) => void,
handleRequestCreate: Function,
handleRequestGroupCreate: Function,
handleSendAndDownloadRequestWithActiveEnvironment: Function,
@@ -252,10 +256,42 @@ class WrapperDebug extends React.PureComponent {
settings,
} = this.props.wrapperProps;
+ const dragPanes = (
+ <>
+
+
+
+ >
+ );
+
// activeRequest being truthy only needs to be checked for isGrpcRequest (for now)
// The RequestPane and ResponsePane components already handle the case where activeRequest is null
if (activeRequest && isGrpcRequest(activeRequest)) {
- return null;
+ return (
+
+
+
+
+
+
+ {dragPanes}
+
+
+
+
+
+
+ );
}
return (
@@ -298,19 +334,7 @@ class WrapperDebug extends React.PureComponent {
/>
-
-
-
+ {dragPanes}