Refactor hooks to be easier to use

This commit is contained in:
Gregory Schier
2023-03-13 23:25:41 -07:00
parent d7ff52038d
commit 02574cf5e0
19 changed files with 314 additions and 258 deletions

View File

@@ -0,0 +1,20 @@
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import type { HttpRequest } from '../lib/models';
import { useRequests } from './useRequests';
export function useActiveRequest(): HttpRequest | null {
const params = useParams<{ requestId?: string }>();
const requests = useRequests();
const [activeRequest, setActiveRequest] = useState<HttpRequest | null>(null);
useEffect(() => {
if (requests.length === 0) {
setActiveRequest(null);
} else {
setActiveRequest(requests.find((r) => r.id === params.requestId) ?? null);
}
}, [requests, params.requestId]);
return activeRequest;
}

View File

@@ -0,0 +1,20 @@
import { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import type { Workspace } from '../lib/models';
import { useWorkspaces } from './useWorkspaces';
export function useActiveWorkspace(): Workspace | null {
const params = useParams<{ workspaceId?: string }>();
const workspaces = useWorkspaces();
const [activeWorkspace, setActiveWorkspace] = useState<Workspace | null>(null);
useEffect(() => {
if (workspaces.length === 0) {
setActiveWorkspace(null);
} else {
setActiveWorkspace(workspaces.find((w) => w.id === params.workspaceId) ?? null);
}
}, [workspaces, params.workspaceId]);
return activeWorkspace;
}

View File

@@ -0,0 +1,23 @@
import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import { useNavigate } from 'react-router-dom';
import type { HttpRequest } from '../lib/models';
import { useActiveWorkspace } from './useActiveWorkspace';
export function useCreateRequest({ navigateAfter }: { navigateAfter: boolean }) {
const workspace = useActiveWorkspace();
const navigate = useNavigate();
return useMutation<string, unknown, Pick<HttpRequest, 'name'>>({
mutationFn: async (patch) => {
if (workspace === null) {
throw new Error("Cannot create request when there's no active workspace");
}
return invoke('create_request', { ...patch, workspaceId: workspace?.id });
},
onSuccess: async (requestId) => {
if (navigateAfter) {
navigate(`/workspaces/${workspace?.id}/requests/${requestId}`);
}
},
});
}

View File

@@ -0,0 +1,18 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { HttpRequest } from '../lib/models';
import { requestsQueryKey } from './useRequests';
export function useDeleteRequest(request: HttpRequest | null) {
const queryClient = useQueryClient();
return useMutation<void, string>({
mutationFn: async () => {
if (request == null) return;
await invoke('delete_request', { requestId: request.id });
},
onSuccess: async () => {
if (request == null) return;
await queryClient.invalidateQueries(requestsQueryKey(request.workspaceId));
},
});
}

View File

@@ -0,0 +1,16 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
export function useDeleteResponses(requestId?: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => {
if (requestId == null) return;
await invoke('delete_all_responses', { requestId });
},
onSuccess: () => {
if (requestId == null) return;
queryClient.setQueryData(['responses', { requestId: requestId }], []);
},
});
}

View File

@@ -1,87 +0,0 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import { useNavigate, useNavigation } from 'react-router-dom';
import type { HttpRequest } from '../lib/models';
import { convertDates } from '../lib/models';
import { responsesQueryKey } from './useResponses';
export function requestsQueryKey(workspaceId: string) {
return ['requests', { workspaceId }];
}
export function useRequests(workspaceId: string) {
return useQuery({
queryKey: requestsQueryKey(workspaceId),
queryFn: async () => {
const requests = (await invoke('requests', { workspaceId })) as HttpRequest[];
return requests.map(convertDates);
},
});
}
export function useRequestUpdate(request: HttpRequest | null) {
return useMutation<void, unknown, Partial<HttpRequest>>({
mutationFn: async (patch) => {
if (request == null) {
throw new Error("Can't update a null request");
}
const updatedRequest = { ...request, ...patch };
console.log('UPDATE REQUEST', updatedRequest.url);
await invoke('update_request', {
request: {
...updatedRequest,
createdAt: updatedRequest.createdAt.toISOString().replace('Z', ''),
updatedAt: updatedRequest.updatedAt.toISOString().replace('Z', ''),
},
});
},
});
}
export function useRequestCreate({
workspaceId,
navigateAfter,
}: {
workspaceId: string;
navigateAfter: boolean;
}) {
const navigate = useNavigate();
return useMutation<string, unknown, Pick<HttpRequest, 'name'>>({
mutationFn: async (patch) => invoke('create_request', { ...patch, workspaceId }),
onSuccess: async (requestId) => {
if (navigateAfter) {
navigate(`/workspaces/${workspaceId}/requests/${requestId}`);
}
},
});
}
export function useSendRequest(request: HttpRequest | null) {
const queryClient = useQueryClient();
return useMutation<void, string>({
mutationFn: async () => {
if (request == null) return;
await invoke('send_request', { requestId: request.id });
},
onSuccess: async () => {
if (request == null) return;
await queryClient.invalidateQueries(responsesQueryKey(request.id));
},
});
}
export function useDeleteRequest(request: HttpRequest | null) {
const queryClient = useQueryClient();
return useMutation<void, string>({
mutationFn: async () => {
if (request == null) return;
await invoke('delete_request', { requestId: request.id });
},
onSuccess: async () => {
if (request == null) return;
await queryClient.invalidateQueries(requestsQueryKey(request.workspaceId));
},
});
}

View File

@@ -0,0 +1,24 @@
import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { HttpRequest } from '../lib/models';
import { convertDates } from '../lib/models';
import { useActiveWorkspace } from './useActiveWorkspace';
export function requestsQueryKey(workspaceId: string) {
return ['requests', { workspaceId }];
}
export function useRequests() {
const workspace = useActiveWorkspace();
return (
useQuery({
enabled: workspace != null,
queryKey: requestsQueryKey(workspace?.id ?? 'n/a'),
queryFn: async () => {
if (workspace == null) return [];
const requests = (await invoke('requests', { workspaceId: workspace.id })) as HttpRequest[];
return requests.map(convertDates);
},
}).data ?? []
);
}

View File

@@ -0,0 +1,20 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { HttpResponse } from '../lib/models';
export function useDeleteResponse(response?: HttpResponse) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => {
if (response == null) return;
await invoke('delete_response', { id: response.id });
},
onSuccess: () => {
if (response == null) return;
queryClient.setQueryData(
['responses', { requestId: response.requestId }],
(responses: HttpResponse[] = []) => responses.filter((r) => r.id !== response.id),
);
},
});
}

View File

@@ -1,50 +1,26 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useQuery } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { HttpResponse } from '../lib/models';
import { convertDates } from '../lib/models';
import { useActiveRequest } from './useActiveRequest';
export function responsesQueryKey(requestId: string) {
return ['responses', { requestId }];
}
export function useResponses(requestId: string) {
return useQuery<HttpResponse[]>({
initialData: [],
queryKey: responsesQueryKey(requestId),
queryFn: async () => {
const responses = (await invoke('responses', { requestId })) as HttpResponse[];
return responses.map(convertDates);
},
});
}
export function useDeleteResponse(response?: HttpResponse) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => {
if (response == null) return;
await invoke('delete_response', { id: response.id });
},
onSuccess: () => {
if (response == null) return;
queryClient.setQueryData(
['responses', { requestId: response.requestId }],
(responses: HttpResponse[] = []) => responses.filter((r) => r.id !== response.id),
);
},
});
}
export function useDeleteAllResponses(requestId?: string) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async () => {
if (requestId == null) return;
await invoke('delete_all_responses', { requestId });
},
onSuccess: () => {
if (requestId == null) return;
queryClient.setQueryData(['responses', { requestId: requestId }], []);
},
});
export function useResponses() {
const activeRequest = useActiveRequest();
return (
useQuery<HttpResponse[]>({
enabled: activeRequest != null,
initialData: [],
queryKey: responsesQueryKey(activeRequest?.id ?? 'n/a'),
queryFn: async () => {
const responses = (await invoke('responses', {
requestId: activeRequest?.id,
})) as HttpResponse[];
return responses.map(convertDates);
},
}).data ?? []
);
}

View File

@@ -0,0 +1,18 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { HttpRequest } from '../lib/models';
import { responsesQueryKey } from './useResponses';
export function useSendRequest(request: HttpRequest | null) {
const queryClient = useQueryClient();
return useMutation<void, string>({
mutationFn: async () => {
if (request == null) return;
await invoke('send_request', { requestId: request.id });
},
onSuccess: async () => {
if (request == null) return;
await queryClient.invalidateQueries(responsesQueryKey(request.id));
},
});
}

View File

@@ -0,0 +1,23 @@
import { useMutation } from '@tanstack/react-query';
import { invoke } from '@tauri-apps/api';
import type { HttpRequest } from '../lib/models';
export function useUpdateRequest(request: HttpRequest | null) {
return useMutation<void, unknown, Partial<HttpRequest>>({
mutationFn: async (patch) => {
if (request == null) {
throw new Error("Can't update a null request");
}
const updatedRequest = { ...request, ...patch };
await invoke('update_request', {
request: {
...updatedRequest,
createdAt: updatedRequest.createdAt.toISOString().replace('Z', ''),
updatedAt: updatedRequest.updatedAt.toISOString().replace('Z', ''),
},
});
},
});
}

View File

@@ -4,8 +4,10 @@ import { convertDates } from '../lib/models';
import { useQuery } from '@tanstack/react-query';
export function useWorkspaces() {
return useQuery(['workspaces'], async () => {
const workspaces = (await invoke('workspaces')) as Workspace[];
return workspaces.map(convertDates);
});
return (
useQuery(['workspaces'], async () => {
const workspaces = (await invoke('workspaces')) as Workspace[];
return workspaces.map(convertDates);
}).data ?? []
);
}