mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-18 23:09:47 +02:00
Hide large GRPC messages by default
This commit is contained in:
@@ -10,9 +10,11 @@ import { JsonAttributeTree } from './core/JsonAttributeTree';
|
|||||||
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
|
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
|
||||||
import { Separator } from './core/Separator';
|
import { Separator } from './core/Separator';
|
||||||
import { SplitLayout } from './core/SplitLayout';
|
import { SplitLayout } from './core/SplitLayout';
|
||||||
import { HStack } from './core/Stacks';
|
import { HStack, VStack } from './core/Stacks';
|
||||||
import { EmptyStateText } from './EmptyStateText';
|
import { EmptyStateText } from './EmptyStateText';
|
||||||
import { RecentConnectionsDropdown } from './RecentConnectionsDropdown';
|
import { RecentConnectionsDropdown } from './RecentConnectionsDropdown';
|
||||||
|
import { Button } from './core/Button';
|
||||||
|
import { useStateWithDeps } from '../hooks/useStateWithDeps';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
@@ -32,6 +34,8 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
|||||||
const connections = useGrpcConnections(activeRequest.id ?? null);
|
const connections = useGrpcConnections(activeRequest.id ?? null);
|
||||||
const activeConnection = connections[0] ?? null;
|
const activeConnection = connections[0] ?? null;
|
||||||
const events = useGrpcEvents(activeConnection?.id ?? null);
|
const events = useGrpcEvents(activeConnection?.id ?? null);
|
||||||
|
const [showLarge, setShowLarge] = useStateWithDeps<boolean>(false, [activeRequest.id]);
|
||||||
|
const [showingLarge, setShowingLarge] = useState<boolean>(false);
|
||||||
|
|
||||||
const activeEvent = useMemo(
|
const activeEvent = useMemo(
|
||||||
() => events.find((m) => m.id === activeEventId) ?? null,
|
() => events.find((m) => m.id === activeEventId) ?? null,
|
||||||
@@ -102,7 +106,30 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
|||||||
<div className="mb-2 select-text cursor-text font-semibold">
|
<div className="mb-2 select-text cursor-text font-semibold">
|
||||||
Message {activeEvent.eventType === 'client_message' ? 'Sent' : 'Received'}
|
Message {activeEvent.eventType === 'client_message' ? 'Sent' : 'Received'}
|
||||||
</div>
|
</div>
|
||||||
<JsonAttributeTree attrValue={JSON.parse(activeEvent?.content ?? '{}')} />
|
{!showLarge && activeEvent.content.length > 1000 * 1000 ? (
|
||||||
|
<VStack space={2} className="text-sm italic text-gray-500">
|
||||||
|
Message previews larger than 1MB are hidden
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
setShowingLarge(true);
|
||||||
|
setTimeout(() => {
|
||||||
|
setShowLarge(true);
|
||||||
|
setShowingLarge(false);
|
||||||
|
}, 500);
|
||||||
|
}}
|
||||||
|
isLoading={showingLarge}
|
||||||
|
color="gray"
|
||||||
|
variant="border"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
Try Showing
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</VStack>
|
||||||
|
) : (
|
||||||
|
<JsonAttributeTree attrValue={JSON.parse(activeEvent?.content ?? '{}')} />
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="h-full grid grid-rows-[auto_minmax(0,1fr)]">
|
<div className="h-full grid grid-rows-[auto_minmax(0,1fr)]">
|
||||||
@@ -111,7 +138,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
|||||||
{activeEvent.content}
|
{activeEvent.content}
|
||||||
</div>
|
</div>
|
||||||
{activeEvent.error && (
|
{activeEvent.error && (
|
||||||
<div className="text-xs font-mono py-1 text-orange-700">
|
<div className="select-text cursor-text text-xs font-mono py-1 text-orange-700">
|
||||||
{activeEvent.error}
|
{activeEvent.error}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -196,12 +223,8 @@ function EventRow({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<div className={classNames('w-full truncate text-2xs')}>
|
<div className={classNames('w-full truncate text-2xs')}>
|
||||||
{content}
|
{content.slice(0, 1000)}
|
||||||
{error && (
|
{error && <span className="text-orange-600"> ({error})</span>}
|
||||||
<>
|
|
||||||
<span className="text-orange-600"> ({error})</span>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={classNames('opacity-50 text-2xs')}>
|
<div className={classNames('opacity-50 text-2xs')}>
|
||||||
{format(createdAt + 'Z', 'HH:mm:ss.SSS')}
|
{format(createdAt + 'Z', 'HH:mm:ss.SSS')}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|||||||
import type { EditorView } from 'codemirror';
|
import type { EditorView } from 'codemirror';
|
||||||
import type { HTMLAttributes, ReactNode } from 'react';
|
import type { HTMLAttributes, ReactNode } from 'react';
|
||||||
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
|
import { forwardRef, useCallback, useMemo, useRef, useState } from 'react';
|
||||||
import { useStateSyncDefault } from '../../hooks/useStateSyncDefault';
|
import { useStateWithDeps } from '../../hooks/useStateWithDeps';
|
||||||
import type { EditorProps } from './Editor';
|
import type { EditorProps } from './Editor';
|
||||||
import { Editor } from './Editor';
|
import { Editor } from './Editor';
|
||||||
import { IconButton } from './IconButton';
|
import { IconButton } from './IconButton';
|
||||||
@@ -72,7 +72,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
|||||||
}: InputProps,
|
}: InputProps,
|
||||||
ref,
|
ref,
|
||||||
) {
|
) {
|
||||||
const [obscured, setObscured] = useStateSyncDefault(type === 'password');
|
const [obscured, setObscured] = useStateWithDeps(type === 'password', [type]);
|
||||||
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
|
const [currentValue, setCurrentValue] = useState(defaultValue ?? '');
|
||||||
const [focused, setFocused] = useState(false);
|
const [focused, setFocused] = useState(false);
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
|
import type { DependencyList } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like useState, except it will update the value when the default value changes
|
* Like useState, except it will update the value when the default value changes
|
||||||
*/
|
*/
|
||||||
export function useStateSyncDefault<T>(defaultValue: T) {
|
export function useStateWithDeps<T>(defaultValue: T, deps: DependencyList) {
|
||||||
const [value, setValue] = useState(defaultValue);
|
const [value, setValue] = useState(defaultValue);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue(defaultValue);
|
setValue(defaultValue);
|
||||||
}, [defaultValue]);
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, deps);
|
||||||
return [value, setValue] as const;
|
return [value, setValue] as const;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user