Grpc layout use new models

This commit is contained in:
Gregory Schier
2024-02-03 13:28:31 -08:00
parent dc077209cc
commit 4892863dd7
10 changed files with 152 additions and 125 deletions

View File

@@ -3,11 +3,11 @@ import classNames from 'classnames';
import { format } from 'date-fns'; import { format } from 'date-fns';
import type { CSSProperties, FormEvent } from 'react'; import type { CSSProperties, FormEvent } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useActiveRequestId } from '../hooks/useActiveRequestId'; import { useActiveRequest } from '../hooks/useActiveRequest';
import { useAlert } from '../hooks/useAlert'; import { useAlert } from '../hooks/useAlert';
import type { GrpcMessage } from '../hooks/useGrpc'; import type { GrpcMessage } from '../hooks/useGrpc';
import { useGrpc } from '../hooks/useGrpc'; import { useGrpc } from '../hooks/useGrpc';
import { useKeyValue } from '../hooks/useKeyValue'; import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import { Banner } from './core/Banner'; import { Banner } from './core/Banner';
import { Button } from './core/Button'; import { Button } from './core/Button';
import { Editor } from './core/Editor'; import { Editor } from './core/Editor';
@@ -27,38 +27,20 @@ interface Props {
} }
export function GrpcConnectionLayout({ style }: Props) { export function GrpcConnectionLayout({ style }: Props) {
const activeRequestId = useActiveRequestId(); const activeRequest = useActiveRequest('grpc_request');
const url = useKeyValue<string>({ const updateRequest = useUpdateGrpcRequest(activeRequest?.id ?? null);
namespace: 'debug',
key: ['grpc_url', activeRequestId ?? ''],
defaultValue: '',
});
const alert = useAlert(); const alert = useAlert();
const service = useKeyValue<string | null>({
namespace: 'debug',
key: ['grpc_service', activeRequestId ?? ''],
defaultValue: null,
});
const method = useKeyValue<string | null>({
namespace: 'debug',
key: ['grpc_method', activeRequestId ?? ''],
defaultValue: null,
});
const message = useKeyValue<string>({
namespace: 'debug',
key: ['grpc_message', activeRequestId ?? ''],
defaultValue: '',
});
const [activeMessage, setActiveMessage] = useState<GrpcMessage | null>(null); const [activeMessage, setActiveMessage] = useState<GrpcMessage | null>(null);
const [resp, setResp] = useState<string>(''); const [resp, setResp] = useState<string>('');
const grpc = useGrpc(url.value ?? null, activeRequestId); const grpc = useGrpc(activeRequest?.url ?? null, activeRequest?.id ?? null);
const activeMethod = useMemo(() => { const activeMethod = useMemo(() => {
if (grpc.services == null) return null; if (grpc.services == null || activeRequest == null) return null;
const s = grpc.services.find((s) => s.name === service.value);
const s = grpc.services.find((s) => s.name === activeRequest.service);
if (s == null) return null; if (s == null) return null;
return s.methods.find((m) => m.name === method.value); return s.methods.find((m) => m.name === activeRequest.method);
}, [grpc.services, method.value, service.value]); }, [activeRequest, grpc.services]);
const handleCancel = useCallback(() => { const handleCancel = useCallback(() => {
grpc.cancel.mutateAsync().catch(console.error); grpc.cancel.mutateAsync().catch(console.error);
@@ -67,9 +49,9 @@ export function GrpcConnectionLayout({ style }: Props) {
const handleConnect = useCallback( const handleConnect = useCallback(
async (e: FormEvent) => { async (e: FormEvent) => {
e.preventDefault(); e.preventDefault();
if (activeMethod == null) return; if (activeMethod == null || activeRequest == null) return;
if (service.value == null || method.value == null) { if (activeRequest.service == null || activeRequest.method == null) {
alert({ alert({
id: 'grpc-invalid-service-method', id: 'grpc-invalid-service-method',
title: 'Error', title: 'Error',
@@ -77,63 +59,54 @@ export function GrpcConnectionLayout({ style }: Props) {
}); });
} }
if (activeMethod.clientStreaming && activeMethod.serverStreaming) { if (activeMethod.clientStreaming && activeMethod.serverStreaming) {
await grpc.bidiStreaming.mutateAsync({ await grpc.bidiStreaming.mutateAsync(activeRequest);
service: service.value ?? 'n/a',
method: method.value ?? 'n/a',
message: message.value ?? '',
});
} else if (activeMethod.serverStreaming && !activeMethod.clientStreaming) { } else if (activeMethod.serverStreaming && !activeMethod.clientStreaming) {
await grpc.serverStreaming.mutateAsync({ await grpc.serverStreaming.mutateAsync(activeRequest);
service: service.value ?? 'n/a',
method: method.value ?? 'n/a',
message: message.value ?? '',
});
} else { } else {
setResp( setResp(await grpc.unary.mutateAsync(activeRequest));
await grpc.unary.mutateAsync({
service: service.value ?? 'n/a',
method: method.value ?? 'n/a',
message: message.value ?? '',
}),
);
} }
}, },
[ [activeMethod, activeRequest, alert, grpc.bidiStreaming, grpc.serverStreaming, grpc.unary],
activeMethod,
alert,
grpc.bidiStreaming,
grpc.serverStreaming,
grpc.unary,
message.value,
method.value,
service.value,
],
); );
useEffect(() => { useEffect(() => {
if (grpc.services == null) return; if (grpc.services == null || activeRequest == null) return;
const s = grpc.services.find((s) => s.name === service.value); const s = grpc.services.find((s) => s.name === activeRequest.service);
if (s == null) { if (s == null) {
service.set(grpc.services[0]?.name ?? null); updateRequest.mutate({
method.set(grpc.services[0]?.methods[0]?.name ?? null); service: grpc.services[0]?.name ?? null,
method: grpc.services[0]?.methods[0]?.name ?? null,
});
return; return;
} }
const m = s.methods.find((m) => m.name === method.value); const m = s.methods.find((m) => m.name === activeRequest.method);
if (m == null) { if (m == null) {
method.set(s.methods[0]?.name ?? null); updateRequest.mutate({ method: s.methods[0]?.name ?? null });
return; return;
} }
}, [grpc.services, method, service]); }, [activeRequest, grpc.services, updateRequest]);
const handleChangeService = useCallback( const handleChangeService = useCallback(
(v: string) => { async (v: string) => {
const [serviceName, methodName] = v.split('/', 2); const [serviceName, methodName] = v.split('/', 2);
if (serviceName == null || methodName == null) throw new Error('Should never happen'); if (serviceName == null || methodName == null) throw new Error('Should never happen');
method.set(methodName); await updateRequest.mutateAsync({
service.set(serviceName); service: serviceName,
method: methodName,
});
}, },
[method, service], [updateRequest],
);
const handleChangeUrl = useCallback(
(url: string) => updateRequest.mutateAsync({ url }),
[updateRequest],
);
const handleChangeMessage = useCallback(
(message: string) => updateRequest.mutateAsync({ message }),
[updateRequest],
); );
const select = useMemo(() => { const select = useMemo(() => {
@@ -144,9 +117,9 @@ export function GrpcConnectionLayout({ style }: Props) {
value: `${s.name}/${m.name}`, value: `${s.name}/${m.name}`,
})), })),
) ?? []; ) ?? [];
const value = `${service.value ?? ''}/${method.value ?? ''}`; const value = `${activeRequest?.service ?? ''}/${activeRequest?.method ?? ''}`;
return { value, options }; return { value, options };
}, [grpc.services, method.value, service.value]); }, [activeRequest?.method, activeRequest?.service, grpc.services]);
const [paneSize, setPaneSize] = useState(99999); const [paneSize, setPaneSize] = useState(99999);
const urlContainerEl = useRef<HTMLDivElement>(null); const urlContainerEl = useRef<HTMLDivElement>(null);
@@ -154,8 +127,8 @@ export function GrpcConnectionLayout({ style }: Props) {
setPaneSize(entry.contentRect.width); setPaneSize(entry.contentRect.width);
}); });
if (url.isLoading || url.value == null) { if (activeRequest == null) {
return null; return;
} }
return ( return (
@@ -173,14 +146,14 @@ export function GrpcConnectionLayout({ style }: Props) {
)} )}
> >
<UrlBar <UrlBar
url={url.value ?? ''} url={activeRequest.url ?? ''}
method={null} method={null}
submitIcon={null} submitIcon={null}
forceUpdateKey={activeRequestId ?? ''} forceUpdateKey={activeRequest?.id ?? ''}
placeholder="localhost:50051" placeholder="localhost:50051"
onSubmit={handleConnect} onSubmit={handleConnect}
isLoading={grpc.unary.isLoading} isLoading={grpc.unary.isLoading}
onUrlChange={url.set} onUrlChange={handleChangeUrl}
/> />
<HStack space={1.5}> <HStack space={1.5}>
<RadioDropdown <RadioDropdown
@@ -228,23 +201,21 @@ export function GrpcConnectionLayout({ style }: Props) {
size="sm" size="sm"
title="to-do" title="to-do"
hotkeyAction="grpc_request.send" hotkeyAction="grpc_request.send"
onClick={() => grpc.send.mutateAsync({ message: message.value ?? '' })} onClick={() => grpc.send.mutateAsync({ message: activeRequest.message ?? '' })}
icon="sendHorizontal" icon="sendHorizontal"
/> />
)} )}
</HStack> </HStack>
</div> </div>
{!service.isLoading && !method.isLoading && ( <GrpcEditor
<GrpcEditor forceUpdateKey={activeRequest?.id ?? ''}
forceUpdateKey={activeRequestId ?? ''} url={activeRequest.url ?? ''}
url={url.value ?? ''} defaultValue={activeRequest.message}
defaultValue={message.value} onChange={handleChangeMessage}
onChange={message.set} service={activeRequest.service}
service={service.value ?? null} method={activeRequest.method}
method={method.value ?? null} className="bg-gray-50"
className="bg-gray-50" />
/>
)}
</VStack> </VStack>
)} )}
rightSlot={() => rightSlot={() =>

View File

@@ -19,14 +19,15 @@ import { useDuplicateRequest } from '../hooks/useDuplicateRequest';
import { useFolders } from '../hooks/useFolders'; import { useFolders } from '../hooks/useFolders';
import { useGrpcRequests } from '../hooks/useGrpcRequests'; import { useGrpcRequests } from '../hooks/useGrpcRequests';
import { useHotKey } from '../hooks/useHotKey'; import { useHotKey } from '../hooks/useHotKey';
import { useHttpRequests } from '../hooks/useHttpRequests';
import { useKeyValue } from '../hooks/useKeyValue'; import { useKeyValue } from '../hooks/useKeyValue';
import { useLatestResponse } from '../hooks/useLatestResponse'; import { useLatestResponse } from '../hooks/useLatestResponse';
import { usePrompt } from '../hooks/usePrompt'; import { usePrompt } from '../hooks/usePrompt';
import { useHttpRequests } from '../hooks/useHttpRequests';
import { useSendManyRequests } from '../hooks/useSendFolder'; import { useSendManyRequests } from '../hooks/useSendFolder';
import { useSendRequest } from '../hooks/useSendRequest'; import { useSendRequest } from '../hooks/useSendRequest';
import { useSidebarHidden } from '../hooks/useSidebarHidden'; import { useSidebarHidden } from '../hooks/useSidebarHidden';
import { useUpdateAnyFolder } from '../hooks/useUpdateAnyFolder'; import { useUpdateAnyFolder } from '../hooks/useUpdateAnyFolder';
import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest';
import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest'; import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest';
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest'; import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
import { fallbackRequestName } from '../lib/fallbackRequestName'; import { fallbackRequestName } from '../lib/fallbackRequestName';
@@ -69,7 +70,8 @@ export function Sidebar({ className }: Props) {
const [hasFocus, setHasFocus] = useState<boolean>(false); const [hasFocus, setHasFocus] = useState<boolean>(false);
const [selectedId, setSelectedId] = useState<string | null>(null); const [selectedId, setSelectedId] = useState<string | null>(null);
const [selectedTree, setSelectedTree] = useState<TreeNode | null>(null); const [selectedTree, setSelectedTree] = useState<TreeNode | null>(null);
const updateAnyRequest = useUpdateAnyHttpRequest(); const updateAnyHttpRequest = useUpdateAnyHttpRequest();
const updateAnyGrpcRequest = useUpdateAnyGrpcRequest();
const updateAnyFolder = useUpdateAnyFolder(); const updateAnyFolder = useUpdateAnyFolder();
const [draggingId, setDraggingId] = useState<string | null>(null); const [draggingId, setDraggingId] = useState<string | null>(null);
const [hoveredTree, setHoveredTree] = useState<TreeNode | null>(null); const [hoveredTree, setHoveredTree] = useState<TreeNode | null>(null);
@@ -119,6 +121,7 @@ export function Sidebar({ className }: Props) {
childItems.sort((a, b) => a.sortPriority - b.sortPriority); childItems.sort((a, b) => a.sortPriority - b.sortPriority);
const depth = node.depth + 1; const depth = node.depth + 1;
for (const item of childItems) { for (const item of childItems) {
console.log('ADD ITEM', item.id, item);
treeParentMap[item.id] = node; treeParentMap[item.id] = node;
node.children.push(next({ item, children: [], depth })); node.children.push(next({ item, children: [], depth }));
if (item.model !== 'folder') { if (item.model !== 'folder') {
@@ -342,12 +345,11 @@ export function Sidebar({ className }: Props) {
const updateFolder = (f: Folder) => ({ ...f, sortPriority, folderId }); const updateFolder = (f: Folder) => ({ ...f, sortPriority, folderId });
return updateAnyFolder.mutateAsync({ id: child.item.id, update: updateFolder }); return updateAnyFolder.mutateAsync({ id: child.item.id, update: updateFolder });
} else if (child.item.model === 'grpc_request') { } else if (child.item.model === 'grpc_request') {
// TODO const updateRequest = (r: GrpcRequest) => ({ ...r, sortPriority, folderId });
// const updateRequest = (r: HttpRequest) => ({ ...r, sortPriority, folderId }); return updateAnyGrpcRequest.mutateAsync({ id: child.item.id, update: updateRequest });
// return updateAnyRequest.mutateAsync({ id: child.item.id, update: updateRequest });
} else if (child.item.model === 'http_request') { } else if (child.item.model === 'http_request') {
const updateRequest = (r: HttpRequest) => ({ ...r, sortPriority, folderId }); const updateRequest = (r: HttpRequest) => ({ ...r, sortPriority, folderId });
return updateAnyRequest.mutateAsync({ id: child.item.id, update: updateRequest }); return updateAnyHttpRequest.mutateAsync({ id: child.item.id, update: updateRequest });
} }
}), }),
); );
@@ -357,23 +359,23 @@ export function Sidebar({ className }: Props) {
const updateFolder = (f: Folder) => ({ ...f, sortPriority, folderId }); const updateFolder = (f: Folder) => ({ ...f, sortPriority, folderId });
await updateAnyFolder.mutateAsync({ id: child.item.id, update: updateFolder }); await updateAnyFolder.mutateAsync({ id: child.item.id, update: updateFolder });
} else if (child.item.model === 'grpc_request') { } else if (child.item.model === 'grpc_request') {
// TODO const updateRequest = (r: GrpcRequest) => ({ ...r, sortPriority, folderId });
// const updateRequest = (r: HttpRequest) => ({ ...r, sortPriority, folderId }); await updateAnyGrpcRequest.mutateAsync({ id: child.item.id, update: updateRequest });
// await updateAnyRequest.mutateAsync({ id: child.item.id, update: updateRequest });
} else if (child.item.model === 'http_request') { } else if (child.item.model === 'http_request') {
const updateRequest = (r: HttpRequest) => ({ ...r, sortPriority, folderId }); const updateRequest = (r: HttpRequest) => ({ ...r, sortPriority, folderId });
await updateAnyRequest.mutateAsync({ id: child.item.id, update: updateRequest }); await updateAnyHttpRequest.mutateAsync({ id: child.item.id, update: updateRequest });
} }
} }
setDraggingId(null); setDraggingId(null);
}, },
[ [
hoveredIndex,
hoveredTree,
handleClearSelected, handleClearSelected,
hoveredTree,
hoveredIndex,
treeParentMap, treeParentMap,
updateAnyFolder, updateAnyFolder,
updateAnyRequest, updateAnyGrpcRequest,
updateAnyHttpRequest,
], ],
); );

View File

@@ -34,7 +34,6 @@ export default function Workspace() {
const { setWidth, width, resetWidth } = useSidebarWidth(); const { setWidth, width, resetWidth } = useSidebarWidth();
const { hide, show, hidden } = useSidebarHidden(); const { hide, show, hidden } = useSidebarHidden();
const activeRequest = useActiveRequest(); const activeRequest = useActiveRequest();
console.log('ACTIVE REQUEST', activeRequest);
const windowSize = useWindowSize(); const windowSize = useWindowSize();
const [floating, setFloating] = useState<boolean>(false); const [floating, setFloating] = useState<boolean>(false);

View File

@@ -4,7 +4,7 @@ import { InlineCode } from '../components/core/InlineCode';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import { fallbackRequestName } from '../lib/fallbackRequestName'; import { fallbackRequestName } from '../lib/fallbackRequestName';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { getRequest } from '../lib/store'; import { getHttpRequest } from '../lib/store';
import { useConfirm } from './useConfirm'; import { useConfirm } from './useConfirm';
import { httpRequestsQueryKey } from './useHttpRequests'; import { httpRequestsQueryKey } from './useHttpRequests';
import { responsesQueryKey } from './useResponses'; import { responsesQueryKey } from './useResponses';
@@ -15,7 +15,7 @@ export function useDeleteAnyRequest() {
return useMutation<HttpRequest | null, string, string>({ return useMutation<HttpRequest | null, string, string>({
mutationFn: async (id) => { mutationFn: async (id) => {
const request = await getRequest(id); const request = await getHttpRequest(id);
const confirmed = await confirm({ const confirmed = await confirm({
id: 'delete-request', id: 'delete-request',
title: 'Delete Request', title: 'Delete Request',

View File

@@ -4,6 +4,7 @@ import type { UnlistenFn } from '@tauri-apps/api/event';
import { emit, listen } from '@tauri-apps/api/event'; import { emit, listen } from '@tauri-apps/api/event';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import { tryFormatJson } from '../lib/formatters'; import { tryFormatJson } from '../lib/formatters';
import type { GrpcRequest } from '../lib/models';
import { useKeyValue } from './useKeyValue'; import { useKeyValue } from './useKeyValue';
interface ReflectResponseService { interface ReflectResponseService {
@@ -31,9 +32,9 @@ export function useGrpc(url: string | null, requestId: string | null) {
unlisten.current?.(); unlisten.current?.();
}, [requestId]); }, [requestId]);
const unary = useMutation<string, string, { service: string; method: string; message: string }>({ const unary = useMutation<string, string, GrpcRequest>({
mutationKey: ['grpc_unary', url], mutationKey: ['grpc_unary', url],
mutationFn: async ({ service, method, message }) => { mutationFn: async ({ service, method, message, url }) => {
if (url === null) throw new Error('No URL provided'); if (url === null) throw new Error('No URL provided');
return (await invoke('cmd_grpc_call_unary', { return (await invoke('cmd_grpc_call_unary', {
endpoint: url, endpoint: url,
@@ -44,13 +45,9 @@ export function useGrpc(url: string | null, requestId: string | null) {
}, },
}); });
const serverStreaming = useMutation< const serverStreaming = useMutation<void, string, GrpcRequest>({
void,
string,
{ service: string; method: string; message: string }
>({
mutationKey: ['grpc_server_streaming', url], mutationKey: ['grpc_server_streaming', url],
mutationFn: async ({ service, method, message }) => { mutationFn: async ({ service, method, message, url }) => {
if (url === null) throw new Error('No URL provided'); if (url === null) throw new Error('No URL provided');
await messages.set([ await messages.set([
{ {
@@ -79,13 +76,9 @@ export function useGrpc(url: string | null, requestId: string | null) {
}, },
}); });
const bidiStreaming = useMutation< const bidiStreaming = useMutation<void, string, GrpcRequest>({
void,
string,
{ service: string; method: string; message: string }
>({
mutationKey: ['grpc_bidi_streaming', url], mutationKey: ['grpc_bidi_streaming', url],
mutationFn: async ({ service, method, message }) => { mutationFn: async ({ service, method, message, url }) => {
if (url === null) throw new Error('No URL provided'); if (url === null) throw new Error('No URL provided');
const id: string = await invoke('cmd_grpc_bidi_streaming', { const id: string = await invoke('cmd_grpc_bidi_streaming', {
endpoint: url, endpoint: url,
@@ -93,7 +86,7 @@ export function useGrpc(url: string | null, requestId: string | null) {
method, method,
message, message,
}); });
messages.set([ await messages.set([
{ type: 'info', message: `Started connection ${id}`, timestamp: new Date().toISOString() }, { type: 'info', message: `Started connection ${id}`, timestamp: new Date().toISOString() },
]); ]);
setActiveConnectionId(id); setActiveConnectionId(id);

View File

@@ -4,7 +4,7 @@ import { save } from '@tauri-apps/api/dialog';
import slugify from 'slugify'; import slugify from 'slugify';
import { trackEvent } from '../lib/analytics'; import { trackEvent } from '../lib/analytics';
import type { HttpResponse } from '../lib/models'; import type { HttpResponse } from '../lib/models';
import { getRequest } from '../lib/store'; import { getHttpRequest } from '../lib/store';
import { useActiveCookieJar } from './useActiveCookieJar'; import { useActiveCookieJar } from './useActiveCookieJar';
import { useActiveEnvironmentId } from './useActiveEnvironmentId'; import { useActiveEnvironmentId } from './useActiveEnvironmentId';
import { useAlert } from './useAlert'; import { useAlert } from './useAlert';
@@ -15,7 +15,7 @@ export function useSendAnyRequest(options: { download?: boolean } = {}) {
const { activeCookieJar } = useActiveCookieJar(); const { activeCookieJar } = useActiveCookieJar();
return useMutation<HttpResponse | null, string, string | null>({ return useMutation<HttpResponse | null, string, string | null>({
mutationFn: async (id) => { mutationFn: async (id) => {
const request = await getRequest(id); const request = await getHttpRequest(id);
if (request == null) { if (request == null) {
return null; return null;
} }

View File

@@ -0,0 +1,35 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { GrpcRequest } from '../lib/models';
import { getGrpcRequest } from '../lib/store';
import { grpcRequestsQueryKey } from './useGrpcRequests';
export function useUpdateAnyGrpcRequest() {
const queryClient = useQueryClient();
return useMutation<
void,
unknown,
{ id: string; update: Partial<GrpcRequest> | ((r: GrpcRequest) => GrpcRequest) }
>({
mutationFn: async ({ id, update }) => {
const request = await getGrpcRequest(id);
if (request === null) {
throw new Error("Can't update a null request");
}
const patchedRequest =
typeof update === 'function' ? update(request) : { ...request, ...update };
await invoke('cmd_update_grpc_request', { request: patchedRequest });
},
onMutate: async ({ id, update }) => {
const request = await getGrpcRequest(id);
if (request === null) return;
const patchedRequest =
typeof update === 'function' ? update(request) : { ...request, ...update };
queryClient.setQueryData<GrpcRequest[]>(grpcRequestsQueryKey(request), (requests) =>
(requests ?? []).map((r) => (r.id === patchedRequest.id ? patchedRequest : r)),
);
},
});
}

View File

@@ -1,7 +1,7 @@
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api';
import type { HttpRequest } from '../lib/models'; import type { HttpRequest } from '../lib/models';
import { getRequest } from '../lib/store'; import { getHttpRequest } from '../lib/store';
import { httpRequestsQueryKey } from './useHttpRequests'; import { httpRequestsQueryKey } from './useHttpRequests';
export function useUpdateAnyHttpRequest() { export function useUpdateAnyHttpRequest() {
@@ -13,7 +13,7 @@ export function useUpdateAnyHttpRequest() {
{ id: string; update: Partial<HttpRequest> | ((r: HttpRequest) => HttpRequest) } { id: string; update: Partial<HttpRequest> | ((r: HttpRequest) => HttpRequest) }
>({ >({
mutationFn: async ({ id, update }) => { mutationFn: async ({ id, update }) => {
const request = await getRequest(id); const request = await getHttpRequest(id);
if (request === null) { if (request === null) {
throw new Error("Can't update a null request"); throw new Error("Can't update a null request");
} }
@@ -23,7 +23,7 @@ export function useUpdateAnyHttpRequest() {
await invoke('cmd_update_http_request', { request: patchedRequest }); await invoke('cmd_update_http_request', { request: patchedRequest });
}, },
onMutate: async ({ id, update }) => { onMutate: async ({ id, update }) => {
const request = await getRequest(id); const request = await getHttpRequest(id);
if (request === null) return; if (request === null) return;
const patchedRequest = const patchedRequest =
typeof update === 'function' ? update(request) : { ...request, ...update }; typeof update === 'function' ? update(request) : { ...request, ...update };

View File

@@ -0,0 +1,10 @@
import { useMutation } from '@tanstack/react-query';
import type { GrpcRequest } from '../lib/models';
import { useUpdateAnyGrpcRequest } from './useUpdateAnyGrpcRequest';
export function useUpdateGrpcRequest(id: string | null) {
const updateAnyRequest = useUpdateAnyGrpcRequest();
return useMutation<void, unknown, Partial<GrpcRequest> | ((r: GrpcRequest) => GrpcRequest)>({
mutationFn: async (update) => updateAnyRequest.mutateAsync({ id: id ?? 'n/a', update }),
});
}

View File

@@ -1,11 +1,28 @@
import { invoke } from '@tauri-apps/api'; import { invoke } from '@tauri-apps/api';
import type { CookieJar, Environment, Folder, HttpRequest, Settings, Workspace } from './models'; import type {
CookieJar,
Environment,
Folder,
GrpcRequest,
HttpRequest,
Settings,
Workspace,
} from './models';
export async function getSettings(): Promise<Settings> { export async function getSettings(): Promise<Settings> {
return invoke('cmd_get_settings', {}); return invoke('cmd_get_settings', {});
} }
export async function getRequest(id: string | null): Promise<HttpRequest | null> { export async function getGrpcRequest(id: string | null): Promise<GrpcRequest | null> {
if (id === null) return null;
const request: GrpcRequest = (await invoke('cmd_get_grpc_request', { id })) ?? null;
if (request == null) {
return null;
}
return request;
}
export async function getHttpRequest(id: string | null): Promise<HttpRequest | null> {
if (id === null) return null; if (id === null) return null;
const request: HttpRequest = (await invoke('cmd_get_http_request', { id })) ?? null; const request: HttpRequest = (await invoke('cmd_get_http_request', { id })) ?? null;
if (request == null) { if (request == null) {