Consolidate any* hooks

This commit is contained in:
Gregory Schier
2024-06-21 10:01:45 -07:00
parent 146fc133f0
commit b6cd6e415a
13 changed files with 133 additions and 130 deletions

2
package-lock.json generated
View File

@@ -19,7 +19,7 @@
"@lezer/lr": "^1.3.3",
"@react-hook/resize-observer": "^1.2.6",
"@tailwindcss/container-queries": "^0.1.0",
"@tanstack/react-query": "^5.35.5",
"@tanstack/react-query": "^5.45.1",
"@tauri-apps/api": ">=2.0.0-beta.0",
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.1",
"@tauri-apps/plugin-dialog": ">=2.0.0-beta.0",

View File

@@ -40,7 +40,7 @@
"@lezer/lr": "^1.3.3",
"@react-hook/resize-observer": "^1.2.6",
"@tailwindcss/container-queries": "^0.1.0",
"@tanstack/react-query": "^5.35.5",
"@tanstack/react-query": "^5.45.1",
"@tauri-apps/api": ">=2.0.0-beta.0",
"@tauri-apps/plugin-clipboard-manager": "^2.1.0-beta.1",
"@tauri-apps/plugin-dialog": ">=2.0.0-beta.0",

View File

@@ -1,5 +1,5 @@
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest';
import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest';
import type { GrpcRequest, HttpRequest } from '../lib/models';
import { Input } from './core/Input';
import { VStack } from './core/Stacks';
@@ -9,8 +9,8 @@ interface Props<T> {
}
export function BasicAuth<T extends HttpRequest | GrpcRequest>({ request }: Props<T>) {
const updateHttpRequest = useUpdateHttpRequest(request.id);
const updateGrpcRequest = useUpdateGrpcRequest(request.id);
const updateHttpRequest = useUpdateAnyHttpRequest();
const updateGrpcRequest = useUpdateAnyGrpcRequest();
return (
<VStack className="py-2 overflow-y-auto h-full" space={2}>
@@ -25,15 +25,21 @@ export function BasicAuth<T extends HttpRequest | GrpcRequest>({ request }: Prop
defaultValue={`${request.authentication.username}`}
onChange={(username: string) => {
if (request.model === 'http_request') {
updateHttpRequest.mutate((r) => ({
...r,
authentication: { password: r.authentication.password, username },
}));
updateHttpRequest.mutate({
id: request.id,
update: (r) => ({
...r,
authentication: { password: r.authentication.password, username },
}),
});
} else {
updateGrpcRequest.mutate((r) => ({
...r,
authentication: { password: r.authentication.password, username },
}));
updateGrpcRequest.mutate({
id: request.id,
update: (r) => ({
...r,
authentication: { password: r.authentication.password, username },
}),
});
}
}}
/>
@@ -49,15 +55,21 @@ export function BasicAuth<T extends HttpRequest | GrpcRequest>({ request }: Prop
defaultValue={`${request.authentication.password}`}
onChange={(password: string) => {
if (request.model === 'http_request') {
updateHttpRequest.mutate((r) => ({
...r,
authentication: { username: r.authentication.username, password },
}));
updateHttpRequest.mutate({
id: request.id,
update: (r) => ({
...r,
authentication: { username: r.authentication.username, password },
}),
});
} else {
updateGrpcRequest.mutate((r) => ({
...r,
authentication: { username: r.authentication.username, password },
}));
updateGrpcRequest.mutate({
id: request.id,
update: (r) => ({
...r,
authentication: { username: r.authentication.username, password },
}),
});
}
}}
/>

View File

@@ -1,5 +1,5 @@
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest';
import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest';
import type { GrpcRequest, HttpRequest } from '../lib/models';
import { Input } from './core/Input';
import { VStack } from './core/Stacks';
@@ -9,8 +9,8 @@ interface Props<T> {
}
export function BearerAuth<T extends HttpRequest | GrpcRequest>({ request }: Props<T>) {
const updateHttpRequest = useUpdateHttpRequest(request?.id ?? null);
const updateGrpcRequest = useUpdateGrpcRequest(request?.id ?? null);
const updateHttpRequest = useUpdateAnyHttpRequest();
const updateGrpcRequest = useUpdateAnyGrpcRequest();
return (
<VStack className="my-2" space={2}>
@@ -25,15 +25,21 @@ export function BearerAuth<T extends HttpRequest | GrpcRequest>({ request }: Pro
defaultValue={`${request.authentication.token}`}
onChange={(token: string) => {
if (request.model === 'http_request') {
updateHttpRequest.mutate((r) => ({
...r,
authentication: { token },
}));
updateHttpRequest.mutate({
id: request.id ?? null,
update: (r) => ({
...r,
authentication: { token },
}),
});
} else {
updateGrpcRequest.mutate((r) => ({
...r,
authentication: { token },
}));
updateGrpcRequest.mutate({
id: request.id ?? null,
update: (r) => ({
...r,
authentication: { token },
}),
});
}
}}
/>

View File

@@ -6,7 +6,7 @@ import { useGrpc } from '../hooks/useGrpc';
import { useGrpcConnections } from '../hooks/useGrpcConnections';
import { useGrpcEvents } from '../hooks/useGrpcEvents';
import { useGrpcProtoFiles } from '../hooks/useGrpcProtoFiles';
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest';
import { Banner } from './core/Banner';
import { HotKeyList } from './core/HotKeyList';
import { SplitLayout } from './core/SplitLayout';
@@ -21,7 +21,7 @@ const emptyArray: string[] = [];
export function GrpcConnectionLayout({ style }: Props) {
const activeRequest = useActiveRequest('grpc_request');
const { mutateAsync: updateRequest } = useUpdateGrpcRequest(activeRequest?.id ?? null);
const updateRequest = useUpdateAnyGrpcRequest();
const connections = useGrpcConnections(activeRequest?.id ?? null);
const activeConnection = connections[0] ?? null;
const messages = useGrpcEvents(activeConnection?.id ?? null);
@@ -34,16 +34,22 @@ export function GrpcConnectionLayout({ style }: Props) {
if (services == null || activeRequest == null) return;
const s = services.find((s) => s.name === activeRequest.service);
if (s == null) {
updateRequest({
service: services[0]?.name ?? null,
method: services[0]?.methods[0]?.name ?? null,
updateRequest.mutate({
id: activeRequest.id,
update: {
service: services[0]?.name ?? null,
method: services[0]?.methods[0]?.name ?? null,
},
});
return;
}
const m = s.methods.find((m) => m.name === activeRequest.method);
if (m == null) {
updateRequest({ method: s.methods[0]?.name ?? null });
updateRequest.mutate({
id: activeRequest.id,
update: { method: s.methods[0]?.name ?? null },
});
return;
}
}, [activeRequest, services, updateRequest]);

View File

@@ -5,7 +5,7 @@ import React, { useCallback, useMemo, useRef, useState } from 'react';
import { createGlobalState } from 'react-use';
import type { ReflectResponseService } from '../hooks/useGrpc';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest';
import type { GrpcMetadataEntry, GrpcRequest } from '../lib/models';
import { AUTH_TYPE_BASIC, AUTH_TYPE_BEARER, AUTH_TYPE_NONE } from '../lib/models';
import { BasicAuth } from './BasicAuth';
@@ -60,7 +60,7 @@ export function GrpcConnectionSetupPane({
onCancel,
onSend,
}: Props) {
const updateRequest = useUpdateGrpcRequest(activeRequest?.id ?? null);
const updateRequest = useUpdateAnyGrpcRequest();
const [activeTab, setActiveTab] = useActiveTab();
const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null);
@@ -71,15 +71,15 @@ export function GrpcConnectionSetupPane({
});
const handleChangeUrl = useCallback(
(url: string) => updateRequest.mutateAsync({ url }),
[updateRequest],
(url: string) => updateRequest.mutateAsync({ id: activeRequest.id, update: { url } }),
[activeRequest.id, updateRequest],
);
const handleChangeMessage = useCallback(
(message: string) => {
return updateRequest.mutateAsync({ message });
return updateRequest.mutateAsync({ id: activeRequest.id, update: { message } });
},
[updateRequest],
[activeRequest.id, updateRequest],
);
const select = useMemo(() => {
@@ -99,11 +99,14 @@ export function GrpcConnectionSetupPane({
const [serviceName, methodName] = v.split('/', 2);
if (serviceName == null || methodName == null) throw new Error('Should never happen');
await updateRequest.mutateAsync({
service: serviceName,
method: methodName,
id: activeRequest.id,
update: {
service: serviceName,
method: methodName,
},
});
},
[updateRequest],
[activeRequest.id, updateRequest],
);
const handleConnect = useCallback(async () => {
@@ -150,18 +153,27 @@ export function GrpcConnectionSetupPane({
token: authentication.token ?? '',
};
}
await updateRequest.mutateAsync({ authenticationType, authentication });
await updateRequest.mutateAsync({
id: activeRequest.id,
update: { authenticationType, authentication },
});
},
},
},
{ value: 'metadata', label: 'Metadata' },
],
[activeRequest.authentication, activeRequest.authenticationType, updateRequest],
[
activeRequest.authentication,
activeRequest.authenticationType,
activeRequest.id,
updateRequest,
],
);
const handleMetadataChange = useCallback(
(metadata: GrpcMetadataEntry[]) => updateRequest.mutate({ metadata }),
[updateRequest],
(metadata: GrpcMetadataEntry[]) =>
updateRequest.mutate({ id: activeRequest.id, update: { metadata } }),
[activeRequest.id, updateRequest],
);
return (

View File

@@ -9,8 +9,8 @@ import { useIsResponseLoading } from '../hooks/useIsResponseLoading';
import { usePinnedHttpResponse } from '../hooks/usePinnedHttpResponse';
import { useRequests } from '../hooks/useRequests';
import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { useSendRequest } from '../hooks/useSendRequest';
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest';
import { tryFormatJson } from '../lib/formatters';
import type { HttpHeader, HttpRequest, HttpUrlParameter } from '../lib/models';
import {
@@ -59,7 +59,7 @@ export const RequestPane = memo(function RequestPane({
}: Props) {
const requests = useRequests();
const activeRequestId = activeRequest.id;
const updateRequest = useUpdateHttpRequest(activeRequestId);
const updateRequest = useUpdateAnyHttpRequest();
const [activeTab, setActiveTab] = useActiveTab();
const [forceUpdateHeaderEditorKey, setForceUpdateHeaderEditorKey] = useState<number>(0);
const { updateKey: forceUpdateKey } = useRequestUpdateKey(activeRequest.id ?? null);
@@ -76,12 +76,12 @@ export const RequestPane = memo(function RequestPane({
enabled: true,
});
}
await updateRequest.mutateAsync({ headers });
await updateRequest.mutateAsync({ id: activeRequestId, update: { headers } });
// Force update header editor so any changed headers are reflected
setTimeout(() => setForceUpdateHeaderEditorKey((u) => u + 1), 100);
},
[activeRequest.headers, updateRequest],
[activeRequest.headers, activeRequestId, updateRequest],
);
const tabs: TabItem[] = useMemo(
@@ -125,7 +125,7 @@ export const RequestPane = memo(function RequestPane({
newContentType = 'application/json';
}
await updateRequest.mutateAsync(patch);
await updateRequest.mutateAsync({ id: activeRequestId, update: patch });
if (newContentType !== undefined) {
await handleContentTypeChange(newContentType);
@@ -174,7 +174,10 @@ export const RequestPane = memo(function RequestPane({
token: authentication.token ?? '',
};
}
await updateRequest.mutateAsync({ authenticationType, authentication });
await updateRequest.mutateAsync({
id: activeRequestId,
update: { authenticationType, authentication },
});
},
},
},
@@ -186,53 +189,55 @@ export const RequestPane = memo(function RequestPane({
activeRequest.headers,
activeRequest.method,
activeRequest.urlParameters,
activeRequestId,
handleContentTypeChange,
updateRequest,
],
);
const handleBodyChange = useCallback(
(body: HttpRequest['body']) => updateRequest.mutate({ body }),
[updateRequest],
(body: HttpRequest['body']) => updateRequest.mutate({ id: activeRequestId, update: { body } }),
[activeRequestId, updateRequest],
);
const handleBinaryFileChange = useCallback(
(body: HttpRequest['body']) => {
updateRequest.mutate({ body });
updateRequest.mutate({ id: activeRequestId, update: { body } });
},
[updateRequest],
[activeRequestId, updateRequest],
);
const handleBodyTextChange = useCallback(
(text: string) => updateRequest.mutate({ body: { text } }),
[updateRequest],
(text: string) => updateRequest.mutate({ id: activeRequestId, update: { body: { text } } }),
[activeRequestId, updateRequest],
);
const handleHeadersChange = useCallback(
(headers: HttpHeader[]) => updateRequest.mutate({ headers }),
[updateRequest],
(headers: HttpHeader[]) => updateRequest.mutate({ id: activeRequestId, update: { headers } }),
[activeRequestId, updateRequest],
);
const handleUrlParametersChange = useCallback(
(urlParameters: HttpUrlParameter[]) => updateRequest.mutate({ urlParameters }),
[updateRequest],
(urlParameters: HttpUrlParameter[]) =>
updateRequest.mutate({ id: activeRequestId, update: { urlParameters } }),
[activeRequestId, updateRequest],
);
const sendRequest = useSendRequest(activeRequest.id ?? null);
const sendRequest = useSendAnyHttpRequest();
const { activeResponse } = usePinnedHttpResponse(activeRequest);
const cancelResponse = useCancelHttpResponse(activeResponse?.id ?? null);
const handleSend = useCallback(async () => {
await sendRequest.mutateAsync();
}, [sendRequest]);
await sendRequest.mutateAsync(activeRequest.id ?? null);
}, [activeRequest.id, sendRequest]);
const handleCancel = useCallback(async () => {
await cancelResponse.mutateAsync();
}, [cancelResponse]);
const handleMethodChange = useCallback(
(method: string) => updateRequest.mutate({ method }),
[updateRequest],
(method: string) => updateRequest.mutate({ id: activeRequestId, update: { method } }),
[activeRequestId, updateRequest],
);
const handleUrlChange = useCallback(
(url: string) => updateRequest.mutate({ url }),
[updateRequest],
(url: string) => updateRequest.mutate({ id: activeRequestId, update: { url } }),
[activeRequestId, updateRequest],
);
const isLoading = useIsResponseLoading(activeRequestId ?? null);

View File

@@ -23,14 +23,12 @@ import { useLatestHttpResponse } from '../hooks/useLatestHttpResponse';
import { useMoveToWorkspace } from '../hooks/useMoveToWorkspace';
import { usePrompt } from '../hooks/usePrompt';
import { useRequests } from '../hooks/useRequests';
import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
import { useSendManyRequests } from '../hooks/useSendFolder';
import { useSendRequest } from '../hooks/useSendRequest';
import { useSidebarHidden } from '../hooks/useSidebarHidden';
import { useUpdateAnyFolder } from '../hooks/useUpdateAnyFolder';
import { useUpdateAnyGrpcRequest } from '../hooks/useUpdateAnyGrpcRequest';
import { useUpdateAnyHttpRequest } from '../hooks/useUpdateAnyHttpRequest';
import { useUpdateGrpcRequest } from '../hooks/useUpdateGrpcRequest';
import { useUpdateHttpRequest } from '../hooks/useUpdateHttpRequest';
import { useWorkspaces } from '../hooks/useWorkspaces';
import { fallbackRequestName } from '../lib/fallbackRequestName';
import type { Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models';
@@ -609,14 +607,14 @@ const SidebarItem = forwardRef(function SidebarItem(
const duplicateHttpRequest = useDuplicateHttpRequest({ id: itemId, navigateAfter: true });
const duplicateGrpcRequest = useDuplicateGrpcRequest({ id: itemId, navigateAfter: true });
const copyAsCurl = useCopyAsCurl(itemId);
const sendRequest = useSendRequest(itemId);
const sendRequest = useSendAnyHttpRequest();
const moveToWorkspace = useMoveToWorkspace(itemId);
const sendManyRequests = useSendManyRequests();
const latestHttpResponse = useLatestHttpResponse(itemId);
const latestGrpcConnection = useLatestGrpcConnection(itemId);
const updateHttpRequest = useUpdateHttpRequest(itemId);
const updateHttpRequest = useUpdateAnyHttpRequest();
const workspaces = useWorkspaces();
const updateGrpcRequest = useUpdateGrpcRequest(itemId);
const updateGrpcRequest = useUpdateAnyGrpcRequest();
const updateAnyFolder = useUpdateAnyFolder();
const prompt = usePrompt();
const [editing, setEditing] = useState<boolean>(false);
@@ -625,15 +623,14 @@ const SidebarItem = forwardRef(function SidebarItem(
const handleSubmitNameEdit = useCallback(
(el: HTMLInputElement) => {
if (activeRequest == null) return;
if (activeRequest.model === 'http_request') {
updateHttpRequest.mutate((r) => ({ ...r, name: el.value }));
} else if (activeRequest.model === 'grpc_request') {
updateGrpcRequest.mutate((r) => ({ ...r, name: el.value }));
if (itemModel === 'http_request') {
updateHttpRequest.mutate({ id: itemId, update: (r) => ({ ...r, name: el.value }) });
} else if (itemModel === 'grpc_request') {
updateGrpcRequest.mutate({ id: itemId, update: (r) => ({ ...r, name: el.value }) });
}
setEditing(false);
},
[activeRequest, updateGrpcRequest, updateHttpRequest],
[itemId, itemModel, updateGrpcRequest, updateHttpRequest],
);
const handleFocus = useCallback((el: HTMLInputElement | null) => {
@@ -736,7 +733,7 @@ const SidebarItem = forwardRef(function SidebarItem(
hotKeyAction: 'http_request.send',
hotKeyLabelOnly: true, // Already bound in URL bar
leftSlot: <Icon icon="sendHorizontal" />,
onSelect: sendRequest.mutate,
onSelect: () => sendRequest.mutate(itemId),
},
{
key: 'copyCurl',
@@ -769,9 +766,9 @@ const SidebarItem = forwardRef(function SidebarItem(
defaultValue: itemName,
});
if (itemModel === 'http_request') {
updateHttpRequest.mutate((r) => ({ ...r, name }));
updateHttpRequest.mutate({ id: itemId, update: (r) => ({ ...r, name }) });
} else {
updateGrpcRequest.mutate((r) => ({ ...r, name }));
updateGrpcRequest.mutate({ id: itemId, update: (r) => ({ ...r, name }) });
}
},
},

View File

@@ -9,7 +9,7 @@ import { useActiveCookieJar } from './useActiveCookieJar';
import { useActiveEnvironment } from './useActiveEnvironment';
import { useAlert } from './useAlert';
export function useSendAnyRequest(options: { download?: boolean } = {}) {
export function useSendAnyHttpRequest(options: { download?: boolean } = {}) {
const environment = useActiveEnvironment();
const alert = useAlert();
const { activeCookieJar } = useActiveCookieJar();

View File

@@ -1,8 +1,8 @@
import { useMutation } from '@tanstack/react-query';
import { useSendAnyRequest } from './useSendAnyRequest';
import { useSendAnyHttpRequest } from './useSendAnyHttpRequest';
export function useSendManyRequests() {
const sendAnyRequest = useSendAnyRequest();
const sendAnyRequest = useSendAnyHttpRequest();
return useMutation<void, string, string[]>({
mutationKey: ['send_many_requests'],
mutationFn: async (requestIds: string[]) => {

View File

@@ -1,11 +0,0 @@
import { useMutation } from '@tanstack/react-query';
import type { HttpResponse } from '../lib/models';
import { useSendAnyRequest } from './useSendAnyRequest';
export function useSendRequest(id: string | null, options: { download?: boolean } = {}) {
const sendAnyRequest = useSendAnyRequest(options);
return useMutation<HttpResponse | null, string>({
mutationKey: ['send_http_request', id],
mutationFn: () => sendAnyRequest.mutateAsync(id),
});
}

View File

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

View File

@@ -1,11 +0,0 @@
import { useMutation } from '@tanstack/react-query';
import type { HttpRequest } from '../lib/models';
import { useUpdateAnyHttpRequest } from './useUpdateAnyHttpRequest';
export function useUpdateHttpRequest(id: string | null) {
const updateAnyRequest = useUpdateAnyHttpRequest();
return useMutation<void, unknown, Partial<HttpRequest> | ((r: HttpRequest) => HttpRequest)>({
mutationKey: ['update_http_request', id],
mutationFn: async (update) => updateAnyRequest.mutateAsync({ id: id ?? 'n/a', update }),
});
}