Even better styles

This commit is contained in:
Gregory Schier
2024-02-01 00:36:49 -08:00
parent 1628d0c843
commit a3c979a987
5 changed files with 67 additions and 53 deletions

View File

@@ -1,17 +1,16 @@
import classNames from 'classnames';
import { format } from 'date-fns';
import { m } from 'framer-motion';
import type { CSSProperties, FormEvent } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useAlert } from '../hooks/useAlert';
import type { GrpcMessage } from '../hooks/useGrpc';
import { useGrpc } from '../hooks/useGrpc';
import { useKeyValue } from '../hooks/useKeyValue';
import { tryFormatJson } from '../lib/formatters';
import { Banner } from './core/Banner';
import { Editor } from './core/Editor';
import { HotKeyList } from './core/HotKeyList';
import { Icon } from './core/Icon';
import { IconButton } from './core/IconButton';
import { JsonAttributeTree } from './core/JsonAttributeTree';
import { Select } from './core/Select';
import { Separator } from './core/Separator';
@@ -144,12 +143,30 @@ export function GrpcConnectionLayout({ style }: Props) {
id="foo"
url={url.value ?? ''}
method={null}
submitIcon={null}
forceUpdateKey="to-do"
placeholder="localhost:50051"
onSubmit={handleConnect}
isLoading={grpc.unary.isLoading}
onUrlChange={url.set}
submitIcon={
/>
<Select
hideLabel
name="service"
label="Service"
className="text-gray-800"
size="sm"
value={select.value}
onChange={handleChangeService}
options={select.options}
/>
<IconButton
className="border border-highlight"
size="sm"
title="ofo"
hotkeyAction="request.send"
onClick={handleConnect}
icon={
!activeMethod?.clientStreaming && activeMethod?.serverStreaming
? 'arrowDownToDot'
: activeMethod?.clientStreaming && !activeMethod?.serverStreaming
@@ -159,15 +176,6 @@ export function GrpcConnectionLayout({ style }: Props) {
: 'sendHorizontal'
}
/>
<Select
hideLabel
name="service"
label="Service"
size="sm"
value={select.value}
onChange={handleChangeService}
options={select.options}
/>
</div>
<GrpcEditor
forceUpdateKey={[service, method].join('::')}
@@ -225,10 +233,10 @@ export function GrpcConnectionLayout({ style }: Props) {
activeMessage ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-[100%]',
)}
>
<div className="pb-2 px-2">
<div className="pb-1 px-2">
<Separator />
</div>
<div className="pl-2">
<div className="pl-2 pb-1">
<JsonAttributeTree
depth={0}
attrValue={JSON.parse(activeMessage?.message ?? '{}')}

View File

@@ -180,9 +180,9 @@ export const ResponsePane = memo(function ResponsePane({ style, className }: Pro
<WebPageViewer response={activeResponse} />
) : contentType?.match(/csv|tab-separated/) ? (
<CsvViewer className="pb-2" response={activeResponse} />
) : contentType?.startsWith('application/json') ? (
<JsonViewer response={activeResponse} />
) : (
// ) : contentType?.startsWith('application/json') ? (
// <JsonViewer response={activeResponse} />
<TextViewer response={activeResponse} pretty={viewMode === 'pretty'} />
)}
</TabContent>

View File

@@ -14,7 +14,7 @@ type Props = Pick<HttpRequest, 'id' | 'url'> & {
placeholder: string;
onSubmit: (e: FormEvent) => void;
onUrlChange: (url: string) => void;
submitIcon?: IconProps['icon'];
submitIcon?: IconProps['icon'] | null;
onMethodChange?: (method: string) => void;
isLoading: boolean;
forceUpdateKey: string;
@@ -74,16 +74,18 @@ export const UrlBar = memo(function UrlBar({
)
}
rightSlot={
<IconButton
size="xs"
iconSize="md"
title="Send Request"
type="submit"
className="w-8 mr-0.5 my-0.5"
icon={isLoading ? 'update' : submitIcon}
spin={isLoading}
hotkeyAction="request.send"
/>
submitIcon !== null && (
<IconButton
size="xs"
iconSize="md"
title="Send Request"
type="submit"
className="w-8 mr-0.5 my-0.5"
icon={isLoading ? 'update' : submitIcon}
spin={isLoading}
hotkeyAction="request.send"
/>
)
}
/>
</form>

View File

@@ -38,8 +38,8 @@ export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPa
))
: null,
isExpandable: true,
label: isExpanded ? undefined : `{⋯}`,
labelClassName: 'text-gray-500',
label: isExpanded ? '{ }' : `{⋯}`,
labelClassName: 'text-gray-600',
};
} else if (jsonType === '[object Array]') {
return {
@@ -54,8 +54,8 @@ export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPa
))
: null,
isExpandable: true,
label: isExpanded ? undefined : `[⋯]`,
labelClassName: 'text-gray-500',
label: isExpanded ? '[ ]' : `[⋯]`,
labelClassName: 'text-gray-600',
};
} else {
return {
@@ -72,25 +72,38 @@ export const JsonAttributeTree = ({ depth = 0, attrKey, attrValue, attrKeyJsonPa
}
}, [attrValue, attrKeyJsonPath, isExpanded, depth]);
const labelEl = (
<span className={classNames(labelClassName, 'select-text group-hover:text-gray-800')}>
{label}
</span>
);
return (
<div className={classNames(depth === 0 && '-ml-4', 'font-mono text-xs')}>
<div className={classNames(/*depth === 0 && '-ml-4',*/ 'font-mono text-xs')}>
<div className="flex items-center">
{depth === 0 ? null : isExpandable ? (
<button className="relative flex items-center pl-4" onClick={toggleExpanded}>
{isExpandable ? (
<button className="group relative flex items-center pl-4" onClick={toggleExpanded}>
<Icon
className={classNames(
'left-0 absolute transition-transform text-gray-500 flex gap-1 items-center',
isExpanded ? 'rotate-90' : '',
)}
size="xs"
icon="chevronRight"
className={classNames(
'left-0 absolute transition-transform text-gray-600 flex items-center',
'group-hover:text-gray-900',
isExpanded ? 'rotate-90' : '',
)}
/>
<span className="text-violet-600 mr-1.5 whitespace-nowrap">{attrKey}:</span>
<span className="text-violet-600 mr-1.5 whitespace-nowrap">
{attrKey === undefined ? '$' : attrKey}:
</span>
{labelEl}
</button>
) : (
<span className="text-violet-600 mr-1.5 pl-4 whitespace-nowrap">{attrKey}:</span>
<>
<span className="text-violet-600 mr-1.5 pl-4 whitespace-nowrap select-text">
{attrKey}:
</span>
{labelEl}
</>
)}
<span className={classNames(labelClassName, 'select-text')}>{label}</span>
</div>
{children && <div className="ml-4 whitespace-nowrap">{children}</div>}
</div>

View File

@@ -19,20 +19,8 @@ export function useGrpc(url: string | null) {
useListenToTauriEvent<string>(
'grpc_message',
(event) => {
console.log('GOT MESSAGE', event);
setMessages((prev) => [
...prev,
{
message: JSON.stringify({
dummy: 'Yo, this is a dummy message',
another: 'property',
list: [1, 2, 3, 4, 5],
null: null,
bool: true,
}),
time: new Date(),
isServer: false,
},
{ message: event.payload, time: new Date(), isServer: true },
]);
},
@@ -59,6 +47,9 @@ export function useGrpc(url: string | null) {
mutationKey: ['grpc_server_streaming', url],
mutationFn: async ({ service, method, message }) => {
if (url === null) throw new Error('No URL provided');
setMessages([
{ isServer: false, message: JSON.stringify(JSON.parse(message)), time: new Date() },
]);
return (await invoke('grpc_server_streaming', {
endpoint: url,
service,