mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-21 00:11:21 +02:00
Hide large request bodies by default
This commit is contained in:
76
src-web/components/ConfirmLargeRequestBody.tsx
Normal file
76
src-web/components/ConfirmLargeRequestBody.tsx
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import type { HttpRequest } from '@yaakapp-internal/models';
|
||||||
|
import { patchModel } from '@yaakapp-internal/models';
|
||||||
|
import { type ReactNode } from 'react';
|
||||||
|
import { useToggle } from '../hooks/useToggle';
|
||||||
|
import { showConfirm } from '../lib/confirm';
|
||||||
|
import { Banner } from './core/Banner';
|
||||||
|
import { Button } from './core/Button';
|
||||||
|
import { InlineCode } from './core/InlineCode';
|
||||||
|
import { Link } from './core/Link';
|
||||||
|
import { SizeTag } from './core/SizeTag';
|
||||||
|
import { HStack } from './core/Stacks';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ReactNode;
|
||||||
|
request: HttpRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LARGE_TEXT_BYTES = 2 * 1000 * 1000;
|
||||||
|
|
||||||
|
export function ConfirmLargeRequestBody({ children, request }: Props) {
|
||||||
|
const [showLargeResponse, toggleShowLargeResponse] = useToggle();
|
||||||
|
|
||||||
|
if (request.body?.text == null) {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
const contentLength = request.body.text.length ?? 0;
|
||||||
|
const tooLargeBytes = LARGE_TEXT_BYTES;
|
||||||
|
const isLarge = contentLength > tooLargeBytes;
|
||||||
|
if (!showLargeResponse && isLarge) {
|
||||||
|
return (
|
||||||
|
<Banner color="primary" className="flex flex-col gap-3">
|
||||||
|
<p>
|
||||||
|
Rendering content over{' '}
|
||||||
|
<InlineCode>
|
||||||
|
<SizeTag contentLength={tooLargeBytes} />
|
||||||
|
</InlineCode>{' '}
|
||||||
|
may impact performance.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
See{' '}
|
||||||
|
<Link href="https://feedback.yaak.app/en/help/articles/1198684-working-with-large-values">
|
||||||
|
Working With Large Values
|
||||||
|
</Link>{' '}
|
||||||
|
for tips.
|
||||||
|
</p>
|
||||||
|
<HStack wrap space={2}>
|
||||||
|
<Button color="primary" size="xs" onClick={toggleShowLargeResponse}>
|
||||||
|
Reveal Body
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
color="danger"
|
||||||
|
size="xs"
|
||||||
|
variant="border"
|
||||||
|
onClick={async () => {
|
||||||
|
const confirm = await showConfirm({
|
||||||
|
id: 'delete-body-' + request.id,
|
||||||
|
confirmText: 'Delete Body',
|
||||||
|
title: 'Delete Body Text',
|
||||||
|
description: 'Are you sure you want to delete the request body text?',
|
||||||
|
color: 'danger',
|
||||||
|
});
|
||||||
|
if (confirm) {
|
||||||
|
await patchModel(request, { body: { ...request.body, text: '' } });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Delete Body
|
||||||
|
</Button>
|
||||||
|
</HStack>
|
||||||
|
</Banner>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ import { prepareImportQuerystring } from '../lib/prepareImportQuerystring';
|
|||||||
import { resolvedModelName } from '../lib/resolvedModelName';
|
import { resolvedModelName } from '../lib/resolvedModelName';
|
||||||
import { showToast } from '../lib/toast';
|
import { showToast } from '../lib/toast';
|
||||||
import { BinaryFileEditor } from './BinaryFileEditor';
|
import { BinaryFileEditor } from './BinaryFileEditor';
|
||||||
|
import { ConfirmLargeRequestBody } from './ConfirmLargeRequestBody';
|
||||||
import { CountBadge } from './core/CountBadge';
|
import { CountBadge } from './core/CountBadge';
|
||||||
import { Editor } from './core/Editor/Editor';
|
import { Editor } from './core/Editor/Editor';
|
||||||
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
|
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
|
||||||
@@ -373,72 +374,74 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }:
|
|||||||
/>
|
/>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value={TAB_BODY}>
|
<TabContent value={TAB_BODY}>
|
||||||
{activeRequest.bodyType === BODY_TYPE_JSON ? (
|
<ConfirmLargeRequestBody request={activeRequest}>
|
||||||
<Editor
|
{activeRequest.bodyType === BODY_TYPE_JSON ? (
|
||||||
forceUpdateKey={forceUpdateKey}
|
<Editor
|
||||||
autocompleteFunctions
|
forceUpdateKey={forceUpdateKey}
|
||||||
autocompleteVariables
|
autocompleteFunctions
|
||||||
placeholder="..."
|
autocompleteVariables
|
||||||
heightMode={fullHeight ? 'full' : 'auto'}
|
placeholder="..."
|
||||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
heightMode={fullHeight ? 'full' : 'auto'}
|
||||||
language="json"
|
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||||
onChange={handleBodyTextChange}
|
language="json"
|
||||||
stateKey={`json.${activeRequest.id}`}
|
onChange={handleBodyTextChange}
|
||||||
/>
|
stateKey={`json.${activeRequest.id}`}
|
||||||
) : activeRequest.bodyType === BODY_TYPE_XML ? (
|
/>
|
||||||
<Editor
|
) : activeRequest.bodyType === BODY_TYPE_XML ? (
|
||||||
forceUpdateKey={forceUpdateKey}
|
<Editor
|
||||||
autocompleteFunctions
|
forceUpdateKey={forceUpdateKey}
|
||||||
autocompleteVariables
|
autocompleteFunctions
|
||||||
placeholder="..."
|
autocompleteVariables
|
||||||
heightMode={fullHeight ? 'full' : 'auto'}
|
placeholder="..."
|
||||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
heightMode={fullHeight ? 'full' : 'auto'}
|
||||||
language="xml"
|
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||||
onChange={handleBodyTextChange}
|
language="xml"
|
||||||
stateKey={`xml.${activeRequest.id}`}
|
onChange={handleBodyTextChange}
|
||||||
/>
|
stateKey={`xml.${activeRequest.id}`}
|
||||||
) : activeRequest.bodyType === BODY_TYPE_GRAPHQL ? (
|
/>
|
||||||
<GraphQLEditor
|
) : activeRequest.bodyType === BODY_TYPE_GRAPHQL ? (
|
||||||
forceUpdateKey={forceUpdateKey}
|
<GraphQLEditor
|
||||||
baseRequest={activeRequest}
|
forceUpdateKey={forceUpdateKey}
|
||||||
request={activeRequest}
|
baseRequest={activeRequest}
|
||||||
onChange={handleBodyChange}
|
request={activeRequest}
|
||||||
/>
|
onChange={handleBodyChange}
|
||||||
) : activeRequest.bodyType === BODY_TYPE_FORM_URLENCODED ? (
|
/>
|
||||||
<FormUrlencodedEditor
|
) : activeRequest.bodyType === BODY_TYPE_FORM_URLENCODED ? (
|
||||||
forceUpdateKey={forceUpdateKey}
|
<FormUrlencodedEditor
|
||||||
request={activeRequest}
|
forceUpdateKey={forceUpdateKey}
|
||||||
onChange={handleBodyChange}
|
request={activeRequest}
|
||||||
/>
|
onChange={handleBodyChange}
|
||||||
) : activeRequest.bodyType === BODY_TYPE_FORM_MULTIPART ? (
|
/>
|
||||||
<FormMultipartEditor
|
) : activeRequest.bodyType === BODY_TYPE_FORM_MULTIPART ? (
|
||||||
forceUpdateKey={forceUpdateKey}
|
<FormMultipartEditor
|
||||||
request={activeRequest}
|
forceUpdateKey={forceUpdateKey}
|
||||||
onChange={handleBodyChange}
|
request={activeRequest}
|
||||||
/>
|
onChange={handleBodyChange}
|
||||||
) : activeRequest.bodyType === BODY_TYPE_BINARY ? (
|
/>
|
||||||
<BinaryFileEditor
|
) : activeRequest.bodyType === BODY_TYPE_BINARY ? (
|
||||||
requestId={activeRequest.id}
|
<BinaryFileEditor
|
||||||
contentType={contentType}
|
requestId={activeRequest.id}
|
||||||
body={activeRequest.body}
|
contentType={contentType}
|
||||||
onChange={(body) => patchModel(activeRequest, { body })}
|
body={activeRequest.body}
|
||||||
onChangeContentType={handleContentTypeChange}
|
onChange={(body) => patchModel(activeRequest, { body })}
|
||||||
/>
|
onChangeContentType={handleContentTypeChange}
|
||||||
) : typeof activeRequest.bodyType === 'string' ? (
|
/>
|
||||||
<Editor
|
) : typeof activeRequest.bodyType === 'string' ? (
|
||||||
forceUpdateKey={forceUpdateKey}
|
<Editor
|
||||||
autocompleteFunctions
|
forceUpdateKey={forceUpdateKey}
|
||||||
autocompleteVariables
|
autocompleteFunctions
|
||||||
language={languageFromContentType(contentType)}
|
autocompleteVariables
|
||||||
placeholder="..."
|
language={languageFromContentType(contentType)}
|
||||||
heightMode={fullHeight ? 'full' : 'auto'}
|
placeholder="..."
|
||||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
heightMode={fullHeight ? 'full' : 'auto'}
|
||||||
onChange={handleBodyTextChange}
|
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||||
stateKey={`other.${activeRequest.id}`}
|
onChange={handleBodyTextChange}
|
||||||
/>
|
stateKey={`other.${activeRequest.id}`}
|
||||||
) : (
|
/>
|
||||||
<EmptyStateText>No Body</EmptyStateText>
|
) : (
|
||||||
)}
|
<EmptyStateText>No Body</EmptyStateText>
|
||||||
|
)}
|
||||||
|
</ConfirmLargeRequestBody>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
<TabContent value={TAB_DESCRIPTION}>
|
<TabContent value={TAB_DESCRIPTION}>
|
||||||
<div className="grid grid-rows-[auto_minmax(0,1fr)] h-full">
|
<div className="grid grid-rows-[auto_minmax(0,1fr)] h-full">
|
||||||
|
|||||||
Reference in New Issue
Block a user