Response info in new tab

This commit is contained in:
Gregory Schier
2024-07-23 12:13:09 -07:00
parent fd2c6930f0
commit 25033dc831
5 changed files with 79 additions and 35 deletions

View File

@@ -1,8 +1,5 @@
import { open } from '@tauri-apps/plugin-shell';
import type { HttpResponse } from '../lib/models';
import { IconButton } from './core/IconButton';
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
import { Separator } from './core/Separator';
interface Props {
response: HttpResponse;
@@ -13,33 +10,9 @@ export function ResponseHeaders({ response }: Props) {
<div className="overflow-auto h-full pb-4">
<KeyValueRows>
{response.headers.map((h, i) => (
<KeyValueRow key={i} label={h.name} value={h.value} labelClassName="!text-violet-600" />
<KeyValueRow labelColor="primary" key={i} label={h.name} value={h.value} />
))}
</KeyValueRows>
<Separator className="my-4">Other Info</Separator>
<KeyValueRows>
<KeyValueRow label="Version" value={response.version} />
<KeyValueRow label="Remote Address" value={response.remoteAddr} />
<KeyValueRow
label={
<div className="flex items-center">
URL
<IconButton
iconSize="sm"
className="inline-block w-auto ml-1 !h-auto opacity-50 hover:opacity-100"
icon="externalLink"
onClick={() => open(response.url)}
title="Open in browser"
/>
</div>
}
value={
<div className="flex">
<span className="select-text cursor-text">{response.url}</span>
</div>
}
/>
</KeyValueRows>
</div>
);
}

View File

@@ -0,0 +1,39 @@
import { open } from '@tauri-apps/plugin-shell';
import type { HttpResponse } from '../lib/models';
import { IconButton } from './core/IconButton';
import { KeyValueRow, KeyValueRows } from './core/KeyValueRow';
interface Props {
response: HttpResponse;
}
export function ResponseInfo({ response }: Props) {
return (
<div className="overflow-auto h-full pb-4">
<KeyValueRows>
<KeyValueRow labelColor="info" label="Version" value={response.version} />
<KeyValueRow labelColor="info" label="Remote Address" value={response.remoteAddr} />
<KeyValueRow
labelColor="info"
label={
<div className="flex items-center">
URL
<IconButton
iconSize="sm"
className="inline-block w-auto ml-1 !h-auto opacity-50 hover:opacity-100"
icon="externalLink"
onClick={() => open(response.url)}
title="Open in browser"
/>
</div>
}
value={
<div className="flex">
<span className="select-text cursor-text">{response.url}</span>
</div>
}
/>
</KeyValueRows>
</div>
);
}

View File

@@ -20,6 +20,7 @@ import { TabContent, Tabs } from './core/Tabs/Tabs';
import { EmptyStateText } from './EmptyStateText';
import { RecentResponsesDropdown } from './RecentResponsesDropdown';
import { ResponseHeaders } from './ResponseHeaders';
import { ResponseInfo } from './ResponseInfo';
import { AudioViewer } from './responseViewers/AudioViewer';
import { CsvViewer } from './responseViewers/CsvViewer';
import { ImageViewer } from './responseViewers/ImageViewer';
@@ -46,7 +47,7 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
() => [
{
value: 'body',
label: 'Preview',
label: 'Preview Mode',
options: {
value: viewMode,
onChange: setViewMode,
@@ -67,6 +68,10 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
),
value: 'headers',
},
{
label: 'Info',
value: 'info',
},
],
[activeResponse?.headers, contentType, setViewMode, viewMode],
);
@@ -148,6 +153,9 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
<TabContent value="headers">
<ResponseHeaders response={activeResponse} />
</TabContent>
<TabContent value="info">
<ResponseInfo response={activeResponse} />
</TabContent>
<TabContent value="body">
{!activeResponse.contentLength ? (
<div className="pb-2 h-full">
@@ -166,6 +174,8 @@ export const ResponsePane = memo(function ResponsePane({ style, className, activ
) : viewMode === 'pretty' && contentType?.includes('html') ? (
<WebPageViewer response={activeResponse} />
) : (
// ) : viewMode === 'pretty' && contentType?.includes('json') ? (
// <JsonAttributeTree attrValue={activeResponse} />
<TextViewer
className="-mr-2" // Pull to the right
response={activeResponse}

View File

@@ -9,9 +9,16 @@ interface Props {
attrValue: any;
attrKey?: string | number;
attrKeyJsonPath?: string;
className?: string;
}
export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPath }: Props) => {
export const JsonAttributeTree = ({
depth = 0,
attrKey,
attrValue,
attrKeyJsonPath,
className,
}: Props) => {
attrKeyJsonPath = attrKeyJsonPath ?? `${attrKey}`;
const [isExpanded, setIsExpanded] = useState(true);
@@ -59,7 +66,7 @@ export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPa
: null,
isExpandable: attrValue.length > 0,
label: isExpanded ? `[${attrValue.length || ' '}]` : `[⋯]`,
labelClassName: 'text-subtler',
labelClassName: 'text-fg-subtler',
};
} else {
return {
@@ -77,10 +84,18 @@ export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPa
}, [attrValue, attrKeyJsonPath, isExpanded, depth]);
const labelEl = (
<span className={classNames(labelClassName, 'select-text group-hover:text-fg')}>{label}</span>
<span className={classNames(labelClassName, 'select-text group-hover:text-fg-subtle')}>
{label}
</span>
);
return (
<div className={classNames(/*depth === 0 && '-ml-4',*/ 'font-mono text-xs')}>
<div
className={classNames(
className,
/*depth === 0 && '-ml-4',*/ 'font-mono text-xs',
depth === 0 && 'h-full overflow-y-auto pb-2',
)}
>
<div className="flex items-center">
{isExpandable ? (
<button className="group relative flex items-center pl-4 w-full" onClick={toggleExpanded}>

View File

@@ -24,13 +24,20 @@ interface Props {
label: ReactNode;
value: ReactNode;
labelClassName?: string;
labelColor?: 'secondary' | 'primary' | 'info';
}
export function KeyValueRow({ label, value, labelClassName }: Props) {
export function KeyValueRow({ label, value, labelColor = 'secondary', labelClassName }: Props) {
return (
<>
<td
className={classNames('py-0.5 pr-2 text-fg-subtle select-text cursor-text', labelClassName)}
className={classNames(
'py-0.5 pr-2 select-text cursor-text',
labelClassName,
labelColor === 'primary' && 'text-fg-primary',
labelColor === 'secondary' && 'text-fg-subtle',
labelColor === 'info' && 'text-fg-info',
)}
>
{label}
</td>