mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-19 07:54:23 +01:00
Refactor hooks to be easier to use
This commit is contained in:
20
src-web/hooks/useActiveRequest.ts
Normal file
20
src-web/hooks/useActiveRequest.ts
Normal 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;
|
||||
}
|
||||
20
src-web/hooks/useActiveWorkspace.ts
Normal file
20
src-web/hooks/useActiveWorkspace.ts
Normal 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;
|
||||
}
|
||||
23
src-web/hooks/useCreateRequest.ts
Normal file
23
src-web/hooks/useCreateRequest.ts
Normal 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}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
18
src-web/hooks/useDeleteRequest.ts
Normal file
18
src-web/hooks/useDeleteRequest.ts
Normal 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));
|
||||
},
|
||||
});
|
||||
}
|
||||
16
src-web/hooks/useDeleteResponses.ts
Normal file
16
src-web/hooks/useDeleteResponses.ts
Normal 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 }], []);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -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));
|
||||
},
|
||||
});
|
||||
}
|
||||
24
src-web/hooks/useRequests.ts
Normal file
24
src-web/hooks/useRequests.ts
Normal 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 ?? []
|
||||
);
|
||||
}
|
||||
20
src-web/hooks/useResponseDelete.ts
Normal file
20
src-web/hooks/useResponseDelete.ts
Normal 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),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -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 ?? []
|
||||
);
|
||||
}
|
||||
|
||||
18
src-web/hooks/useSendRequest.ts
Normal file
18
src-web/hooks/useSendRequest.ts
Normal 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));
|
||||
},
|
||||
});
|
||||
}
|
||||
23
src-web/hooks/useUpdateRequest.ts
Normal file
23
src-web/hooks/useUpdateRequest.ts
Normal 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', ''),
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -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 ?? []
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user