mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-14 06:16:08 +01: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 { showToast } from '../lib/toast';
|
||||
import { BinaryFileEditor } from './BinaryFileEditor';
|
||||
import { ConfirmLargeRequestBody } from './ConfirmLargeRequestBody';
|
||||
import { CountBadge } from './core/CountBadge';
|
||||
import { Editor } from './core/Editor/Editor';
|
||||
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
|
||||
@@ -373,72 +374,74 @@ export function HttpRequestPane({ style, fullHeight, className, activeRequest }:
|
||||
/>
|
||||
</TabContent>
|
||||
<TabContent value={TAB_BODY}>
|
||||
{activeRequest.bodyType === BODY_TYPE_JSON ? (
|
||||
<Editor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
autocompleteFunctions
|
||||
autocompleteVariables
|
||||
placeholder="..."
|
||||
heightMode={fullHeight ? 'full' : 'auto'}
|
||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||
language="json"
|
||||
onChange={handleBodyTextChange}
|
||||
stateKey={`json.${activeRequest.id}`}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_XML ? (
|
||||
<Editor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
autocompleteFunctions
|
||||
autocompleteVariables
|
||||
placeholder="..."
|
||||
heightMode={fullHeight ? 'full' : 'auto'}
|
||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||
language="xml"
|
||||
onChange={handleBodyTextChange}
|
||||
stateKey={`xml.${activeRequest.id}`}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_GRAPHQL ? (
|
||||
<GraphQLEditor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
baseRequest={activeRequest}
|
||||
request={activeRequest}
|
||||
onChange={handleBodyChange}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_FORM_URLENCODED ? (
|
||||
<FormUrlencodedEditor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
request={activeRequest}
|
||||
onChange={handleBodyChange}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_FORM_MULTIPART ? (
|
||||
<FormMultipartEditor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
request={activeRequest}
|
||||
onChange={handleBodyChange}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_BINARY ? (
|
||||
<BinaryFileEditor
|
||||
requestId={activeRequest.id}
|
||||
contentType={contentType}
|
||||
body={activeRequest.body}
|
||||
onChange={(body) => patchModel(activeRequest, { body })}
|
||||
onChangeContentType={handleContentTypeChange}
|
||||
/>
|
||||
) : typeof activeRequest.bodyType === 'string' ? (
|
||||
<Editor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
autocompleteFunctions
|
||||
autocompleteVariables
|
||||
language={languageFromContentType(contentType)}
|
||||
placeholder="..."
|
||||
heightMode={fullHeight ? 'full' : 'auto'}
|
||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||
onChange={handleBodyTextChange}
|
||||
stateKey={`other.${activeRequest.id}`}
|
||||
/>
|
||||
) : (
|
||||
<EmptyStateText>No Body</EmptyStateText>
|
||||
)}
|
||||
<ConfirmLargeRequestBody request={activeRequest}>
|
||||
{activeRequest.bodyType === BODY_TYPE_JSON ? (
|
||||
<Editor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
autocompleteFunctions
|
||||
autocompleteVariables
|
||||
placeholder="..."
|
||||
heightMode={fullHeight ? 'full' : 'auto'}
|
||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||
language="json"
|
||||
onChange={handleBodyTextChange}
|
||||
stateKey={`json.${activeRequest.id}`}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_XML ? (
|
||||
<Editor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
autocompleteFunctions
|
||||
autocompleteVariables
|
||||
placeholder="..."
|
||||
heightMode={fullHeight ? 'full' : 'auto'}
|
||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||
language="xml"
|
||||
onChange={handleBodyTextChange}
|
||||
stateKey={`xml.${activeRequest.id}`}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_GRAPHQL ? (
|
||||
<GraphQLEditor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
baseRequest={activeRequest}
|
||||
request={activeRequest}
|
||||
onChange={handleBodyChange}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_FORM_URLENCODED ? (
|
||||
<FormUrlencodedEditor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
request={activeRequest}
|
||||
onChange={handleBodyChange}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_FORM_MULTIPART ? (
|
||||
<FormMultipartEditor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
request={activeRequest}
|
||||
onChange={handleBodyChange}
|
||||
/>
|
||||
) : activeRequest.bodyType === BODY_TYPE_BINARY ? (
|
||||
<BinaryFileEditor
|
||||
requestId={activeRequest.id}
|
||||
contentType={contentType}
|
||||
body={activeRequest.body}
|
||||
onChange={(body) => patchModel(activeRequest, { body })}
|
||||
onChangeContentType={handleContentTypeChange}
|
||||
/>
|
||||
) : typeof activeRequest.bodyType === 'string' ? (
|
||||
<Editor
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
autocompleteFunctions
|
||||
autocompleteVariables
|
||||
language={languageFromContentType(contentType)}
|
||||
placeholder="..."
|
||||
heightMode={fullHeight ? 'full' : 'auto'}
|
||||
defaultValue={`${activeRequest.body?.text ?? ''}`}
|
||||
onChange={handleBodyTextChange}
|
||||
stateKey={`other.${activeRequest.id}`}
|
||||
/>
|
||||
) : (
|
||||
<EmptyStateText>No Body</EmptyStateText>
|
||||
)}
|
||||
</ConfirmLargeRequestBody>
|
||||
</TabContent>
|
||||
<TabContent value={TAB_DESCRIPTION}>
|
||||
<div className="grid grid-rows-[auto_minmax(0,1fr)] h-full">
|
||||
|
||||
Reference in New Issue
Block a user