Working sidebar actions for grpc

This commit is contained in:
Gregory Schier
2024-02-07 00:02:02 -08:00
parent 94a9a5d5d5
commit 7bc26fd448
9 changed files with 137 additions and 50 deletions

View File

@@ -65,6 +65,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
<div className="overflow-y-auto h-full">
{...messages.map((m) => (
<HStack
role="button"
key={m.id}
space={2}
onClick={() => {
@@ -72,7 +73,10 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
else setActiveMessageId(m.id);
}}
alignItems="center"
className={classNames('px-2 py-1 font-mono', m === activeMessage && 'bg-highlight')}
className={classNames(
'px-2 py-1 font-mono cursor-default group',
m === activeMessage && '!bg-highlight',
)}
>
<Icon
className={
@@ -80,8 +84,22 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
}
icon={m.isInfo ? 'info' : m.isServer ? 'arrowBigDownDash' : 'arrowBigUpDash'}
/>
<div className="w-full truncate text-gray-800 text-2xs">{m.message}</div>
<div className="text-gray-600 text-2xs">{format(m.createdAt, 'HH:mm:ss')}</div>
<div
className={classNames(
'w-full truncate text-gray-800 text-2xs group-hover:text-gray-900',
m.id === activeMessageId && 'text-gray-900',
)}
>
{m.message}
</div>
<div
className={classNames(
'text-gray-600 text-2xs group-hover:text-gray-700',
m.id === activeMessageId && 'text-gray-700',
)}
>
{format(m.createdAt, 'HH:mm:ss')}
</div>
</HStack>
))}
</div>

View File

@@ -11,7 +11,8 @@ import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
import { useAppRoutes } from '../hooks/useAppRoutes';
import { useCreateFolder } from '../hooks/useCreateFolder';
import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest';
import { useDeleteAnyRequest } from '../hooks/useDeleteAnyRequest';
import { useDeleteAnyGrpcRequest } from '../hooks/useDeleteAnyGrpcRequest';
import { useDeleteAnyHttpRequest } from '../hooks/useDeleteAnyHttpRequest';
import { useDeleteFolder } from '../hooks/useDeleteFolder';
import { useDeleteRequest } from '../hooks/useDeleteRequest';
import { useDuplicateGrpcRequest } from '../hooks/useDuplicateGrpcRequest';
@@ -36,6 +37,7 @@ import { fallbackRequestName } from '../lib/fallbackRequestName';
import { NAMESPACE_NO_SYNC } from '../lib/keyValueStore';
import type { Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models';
import { isResponseLoading } from '../lib/models';
import type { DropdownItem } from './core/Dropdown';
import { ContextMenu } from './core/Dropdown';
import { Icon } from './core/Icon';
import { InlineCode } from './core/InlineCode';
@@ -65,7 +67,8 @@ export function Sidebar({ className }: Props) {
const httpRequests = useHttpRequests();
const grpcRequests = useGrpcRequests();
const folders = useFolders();
const deleteAnyRequest = useDeleteAnyRequest();
const deleteAnyHttpRequest = useDeleteAnyHttpRequest();
const deleteAnyGrpcRequest = useDeleteAnyGrpcRequest();
const activeWorkspace = useActiveWorkspace();
const duplicateHttpRequest = useDuplicateHttpRequest({
id: activeRequest?.id ?? null,
@@ -223,9 +226,10 @@ export function Sidebar({ className }: Props) {
const selected = selectableRequests.find((r) => r.id === selectedId);
if (selected == null) return;
deleteAnyRequest.mutate(selected.id);
deleteAnyHttpRequest.mutate(selected.id);
deleteAnyGrpcRequest.mutate(selected.id);
},
[deleteAnyRequest, hasFocus, selectableRequests, selectedId],
[deleteAnyHttpRequest, deleteAnyGrpcRequest, hasFocus, selectableRequests, selectedId],
);
useKeyPressEvent('Backspace', handleDeleteKey);
@@ -683,15 +687,19 @@ const SidebarItem = forwardRef(function SidebarItem(
},
]
: [
{
key: 'sendRequest',
label: 'Send',
hotKeyAction: 'http_request.send',
hotKeyLabelOnly: true, // Already bound in URL bar
leftSlot: <Icon icon="sendHorizontal" />,
onSelect: () => sendRequest.mutate(),
},
{ type: 'separator' },
...((itemModel === 'http_request'
? [
{
key: 'sendRequest',
label: 'Send',
hotKeyAction: 'http_request.send',
hotKeyLabelOnly: true, // Already bound in URL bar
leftSlot: <Icon icon="sendHorizontal" />,
onSelect: () => sendRequest.mutate(),
},
{ type: 'separator' },
]
: []) as DropdownItem[]),
{
key: 'duplicateRequest',
label: 'Duplicate',

View File

@@ -30,7 +30,7 @@ export function Confirm({ onHide, onResult, variant = 'confirm' }: ConfirmProps)
};
return (
<HStack space={2} justifyContent="end" className="mt-2 mb-4 flex-row-reverse">
<HStack space={2} justifyContent="start" className="mt-2 mb-4 flex-row-reverse">
<Button className="focus" color={colors[variant]} onClick={handleSuccess}>
{confirmButtonTexts[variant]}
</Button>

View File

@@ -0,0 +1,43 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics';
import { fallbackRequestName } from '../lib/fallbackRequestName';
import type { GrpcRequest } from '../lib/models';
import { getGrpcRequest } from '../lib/store';
import { useConfirm } from './useConfirm';
import { grpcRequestsQueryKey } from './useGrpcRequests';
export function useDeleteAnyGrpcRequest() {
const queryClient = useQueryClient();
const confirm = useConfirm();
return useMutation<GrpcRequest | null, string, string>({
mutationFn: async (id) => {
const request = await getGrpcRequest(id);
if (request == null) return null;
const confirmed = await confirm({
id: 'delete-grpc-request',
title: 'Delete Request',
variant: 'delete',
description: (
<>
Permanently delete <InlineCode>{fallbackRequestName(request)}</InlineCode>?
</>
),
});
if (!confirmed) return null;
return invoke('cmd_delete_grpc_request', { requestId: id });
},
onSettled: () => trackEvent('GrpcRequest', 'Delete'),
onSuccess: async (request) => {
if (request === null) return;
const { workspaceId, id: requestId } = request;
queryClient.setQueryData<GrpcRequest[]>(grpcRequestsQueryKey({ workspaceId }), (requests) =>
(requests ?? []).filter((r) => r.id !== requestId),
);
},
});
}

View File

@@ -9,13 +9,15 @@ import { useConfirm } from './useConfirm';
import { httpRequestsQueryKey } from './useHttpRequests';
import { httpResponsesQueryKey } from './useHttpResponses';
export function useDeleteAnyRequest() {
export function useDeleteAnyHttpRequest() {
const queryClient = useQueryClient();
const confirm = useConfirm();
return useMutation<HttpRequest | null, string, string>({
mutationFn: async (id) => {
const request = await getHttpRequest(id);
if (request == null) return null;
const confirmed = await confirm({
id: 'delete-request',
title: 'Delete Request',

View File

@@ -1,9 +1,9 @@
import { useMutation } from '@tanstack/react-query';
import type { HttpRequest } from '../lib/models';
import { useDeleteAnyRequest } from './useDeleteAnyRequest';
import { useDeleteAnyHttpRequest } from './useDeleteAnyHttpRequest';
export function useDeleteRequest(id: string | null) {
const deleteAnyRequest = useDeleteAnyRequest();
const deleteAnyRequest = useDeleteAnyHttpRequest();
return useMutation<HttpRequest | null, string>({
mutationFn: () => deleteAnyRequest.mutateAsync(id ?? 'n/a'),