mirror of
https://github.com/Kong/insomnia
synced 2024-11-08 06:39:48 +00:00
Fix select all with large response (#2694)
* Refactor to keep in state info about large & huge response This commit adds 2 properties in the ResponseViewer state: * largeResponse which will be true when a response body weight more that LARGE_RESPONSE_MB * hugeResponse which will be true when a response body weight more that HUGE_RESPONSE_MB * Prevent select-all during response focus hotkey handler on large response * Add a CopyButton in raw & source response viewer * Revert "Add a CopyButton in raw & source response viewer" This reverts commit e094be21 * Add a Copy raw response action in Preview dropdown This action allows the user to copy the raw response directly in the clipboard. It is a useful shortcut to copy huge response where select-all might freeze the application. * fix import * Fix build * remove empty line Co-authored-by: Opender Singh <opender.singh@konghq.com> Co-authored-by: James Gatz <jamesgatzos@gmail.com>
This commit is contained in:
parent
972770731c
commit
4cbd5fa816
@ -7,6 +7,7 @@ import { Dropdown, DropdownButton, DropdownDivider, DropdownItem } from '../base
|
||||
interface Props {
|
||||
download: (pretty: boolean) => any;
|
||||
fullDownload: (pretty: boolean) => any;
|
||||
copyToClipboard: () => any;
|
||||
updatePreviewMode: Function;
|
||||
previewMode: string;
|
||||
showPrettifyOption?: boolean;
|
||||
@ -29,6 +30,11 @@ class PreviewModeDropdown extends PureComponent<Props> {
|
||||
download(false);
|
||||
}
|
||||
|
||||
async _handleCopyRawResponse() {
|
||||
const { copyToClipboard } = this.props;
|
||||
copyToClipboard();
|
||||
}
|
||||
|
||||
renderPreviewMode(mode: string) {
|
||||
const { previewMode } = this.props;
|
||||
return (
|
||||
@ -50,6 +56,10 @@ class PreviewModeDropdown extends PureComponent<Props> {
|
||||
<DropdownDivider>Preview Mode</DropdownDivider>
|
||||
{PREVIEW_MODES.map(this.renderPreviewMode)}
|
||||
<DropdownDivider>Actions</DropdownDivider>
|
||||
<DropdownItem onClick={this._handleCopyRawResponse}>
|
||||
<i className="fa fa-copy" />
|
||||
Copy raw response
|
||||
</DropdownItem>
|
||||
<DropdownItem onClick={this._handleDownloadNormal}>
|
||||
<i className="fa fa-save" />
|
||||
Save Raw Response
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { autoBindMethodsForReact } from 'class-autobind-decorator';
|
||||
import classnames from 'classnames';
|
||||
import { remote } from 'electron';
|
||||
import { clipboard, remote } from 'electron';
|
||||
import fs from 'fs';
|
||||
import { json as jsonPrettify } from 'insomnia-prettify';
|
||||
import mime from 'mime-types';
|
||||
@ -167,6 +167,17 @@ class ResponsePane extends PureComponent<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
async _handleCopyResponseToClipboard() {
|
||||
if (!this.props.response) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bodyBuffer = models.response.getBodyBuffer(this.props.response);
|
||||
if (bodyBuffer) {
|
||||
clipboard.writeText(bodyBuffer.toString('utf8'));
|
||||
}
|
||||
}
|
||||
|
||||
_handleTabSelect(index: number, lastIndex: number) {
|
||||
if (this._responseViewer != null && index === 0 && index !== lastIndex) {
|
||||
// Fix for CodeMirror editor not updating its content.
|
||||
@ -257,6 +268,7 @@ class ResponsePane extends PureComponent<Props> {
|
||||
previewMode={previewMode}
|
||||
updatePreviewMode={handleSetPreviewMode}
|
||||
showPrettifyOption={response.contentType.includes('json')}
|
||||
copyToClipboard={this._handleCopyResponseToClipboard}
|
||||
/>
|
||||
</Tab>
|
||||
<Tab tabIndex="-1">
|
||||
|
@ -47,6 +47,8 @@ interface State {
|
||||
blockingBecauseTooLarge: boolean;
|
||||
bodyBuffer: Buffer | null;
|
||||
error: string;
|
||||
hugeResponse: boolean;
|
||||
largeResponse: boolean;
|
||||
}
|
||||
|
||||
@autoBindMethodsForReact(AUTOBIND_CFG)
|
||||
@ -57,6 +59,8 @@ class ResponseViewer extends Component<Props, State> {
|
||||
blockingBecauseTooLarge: false,
|
||||
bodyBuffer: null,
|
||||
error: '',
|
||||
hugeResponse: false,
|
||||
largeResponse: false,
|
||||
};
|
||||
|
||||
refresh() {
|
||||
@ -91,13 +95,15 @@ class ResponseViewer extends Component<Props, State> {
|
||||
}
|
||||
|
||||
_maybeLoadResponseBody(props: Props, forceShow?: boolean) {
|
||||
// Block the response if it's too large
|
||||
const responseIsTooLarge = props.bytes > LARGE_RESPONSE_MB * 1024 * 1024;
|
||||
const { bytes } = props;
|
||||
const largeResponse = bytes > LARGE_RESPONSE_MB * 1024 * 1024;
|
||||
const hugeResponse = bytes > HUGE_RESPONSE_MB * 1024 * 1024;
|
||||
|
||||
if (!forceShow && !alwaysShowLargeResponses && responseIsTooLarge) {
|
||||
this.setState({
|
||||
blockingBecauseTooLarge: true,
|
||||
});
|
||||
this.setState({ largeResponse, hugeResponse });
|
||||
|
||||
// Block the response if it's too large
|
||||
if (!forceShow && !alwaysShowLargeResponses && largeResponse) {
|
||||
this.setState({ blockingBecauseTooLarge: true });
|
||||
} else {
|
||||
try {
|
||||
const bodyBuffer = props.getBody();
|
||||
@ -193,13 +199,14 @@ class ResponseViewer extends Component<Props, State> {
|
||||
|
||||
this._selectableView?.focus();
|
||||
|
||||
this._selectableView?.selectAll();
|
||||
if (!this.state.largeResponse) {
|
||||
this._selectableView?.selectAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
_renderView() {
|
||||
const {
|
||||
bytes,
|
||||
disableHtmlPreviewJs,
|
||||
disablePreviewLinks,
|
||||
download,
|
||||
@ -227,13 +234,12 @@ class ResponseViewer extends Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
const wayTooLarge = bytes > HUGE_RESPONSE_MB * 1024 * 1024;
|
||||
const { blockingBecauseTooLarge } = this.state;
|
||||
const { blockingBecauseTooLarge, hugeResponse } = this.state;
|
||||
|
||||
if (blockingBecauseTooLarge) {
|
||||
return (
|
||||
<div className="response-pane__notify">
|
||||
{wayTooLarge ? (
|
||||
{hugeResponse ? (
|
||||
<Fragment>
|
||||
<p className="pad faint">Responses over {HUGE_RESPONSE_MB}MB cannot be shown</p>
|
||||
<button onClick={download} className="inline-block btn btn--clicky">
|
||||
@ -251,7 +257,7 @@ class ResponseViewer extends Component<Props, State> {
|
||||
</button>
|
||||
<button
|
||||
onClick={this._handleDismissBlocker}
|
||||
disabled={wayTooLarge}
|
||||
disabled={hugeResponse}
|
||||
className=" inline-block btn btn--clicky margin-xs"
|
||||
>
|
||||
Show Anyway
|
||||
|
Loading…
Reference in New Issue
Block a user