From f0835acb3398ee3a3d4e595310ca90fc0bef2ec3 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Mon, 27 Feb 2023 15:42:06 -0800 Subject: [PATCH] Implement request deletion --- src-tauri/sqlx-data.json | 10 ++++++++++ src-tauri/src/main.rs | 16 ++++++++++++++++ src-tauri/src/models.rs | 17 +++++++++++++++++ src-web/App.tsx | 10 +++++++++- src-web/components/Icon.tsx | 3 +++ src-web/hooks/useRequest.ts | 23 +++++++++++++++++++++-- src-web/main.tsx | 19 ++++++++++++++----- 7 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src-tauri/sqlx-data.json b/src-tauri/sqlx-data.json index c02fc2aa..b30772c2 100644 --- a/src-tauri/sqlx-data.json +++ b/src-tauri/sqlx-data.json @@ -186,6 +186,16 @@ }, "query": "\n INSERT INTO http_requests (id, workspace_id, name, url, method, body, headers, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)\n ON CONFLICT (id) DO UPDATE SET\n updated_at = CURRENT_TIMESTAMP,\n name = excluded.name,\n method = excluded.method,\n body = excluded.body,\n url = excluded.url\n " }, + "448a1d1f1866ab42c0f81fcf8eb2930bf21dfdd43ca4831bc1a198cf45ac3732": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Right": 1 + } + }, + "query": "\n DELETE FROM http_requests\n WHERE id = ?\n " + }, "55eae4b20a2c313134579b0ea43bad4dc2dd313db6cd1654f783bac12602db8a": { "describe": { "columns": [ diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 98ad5d22..07a42991 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -193,6 +193,21 @@ async fn update_request( Ok(()) } +#[tauri::command] +async fn delete_request( + app_handle: AppHandle, + db_instance: State<'_, Mutex>>, + request_id: &str, +) -> Result { + let pool = &*db_instance.lock().await; + let req = models::delete_request(request_id, pool) + .await + .expect("Failed to delete request"); + app_handle.emit_all("deleted_request", request_id).unwrap(); + + Ok(req) +} + #[tauri::command] async fn requests( workspace_id: &str, @@ -324,6 +339,7 @@ fn main() { send_request, create_request, update_request, + delete_request, responses, delete_response, delete_all_responses, diff --git a/src-tauri/src/models.rs b/src-tauri/src/models.rs index 81337426..7c2832a9 100644 --- a/src-tauri/src/models.rs +++ b/src-tauri/src/models.rs @@ -187,6 +187,23 @@ pub async fn get_request(id: &str, pool: &Pool) -> Result) -> Result { + let req = get_request(id, pool) + .await + .expect("Failed to get request to delete"); + let _ = sqlx::query!( + r#" + DELETE FROM http_requests + WHERE id = ? + "#, + id, + ) + .execute(pool) + .await; + + Ok(req) +} + pub async fn create_response( request_id: &str, elapsed: i64, diff --git a/src-web/App.tsx b/src-web/App.tsx index d59a6f70..c2e45209 100644 --- a/src-web/App.tsx +++ b/src-web/App.tsx @@ -6,8 +6,14 @@ import { Sidebar } from './components/Sidebar'; import { UrlBar } from './components/UrlBar'; import { Grid } from './components/Grid'; import { useParams } from 'react-router-dom'; -import { useRequests, useRequestUpdate, useSendRequest } from './hooks/useRequest'; +import { + useDeleteRequest, + useRequests, + useRequestUpdate, + useSendRequest, +} from './hooks/useRequest'; import { ResponsePane } from './components/ResponsePane'; +import { IconButton } from './components/IconButton'; type Params = { workspaceId: string; @@ -22,6 +28,7 @@ function App() { const updateRequest = useRequestUpdate(request ?? null); const sendRequest = useSendRequest(request ?? null); + const deleteRequest = useDeleteRequest(request ?? null); useEffect(() => { const listener = async (e: KeyboardEvent) => { @@ -41,6 +48,7 @@ function App() { Test Request + deleteRequest.mutate()} /> > = { @@ -51,6 +53,7 @@ const icons: Record> = { question: QuestionMarkIcon, eye: EyeOpenIcon, code: CodeIcon, + trash: TrashIcon, }; export interface IconProps { diff --git a/src-web/hooks/useRequest.ts b/src-web/hooks/useRequest.ts index 347296be..145e9f0e 100644 --- a/src-web/hooks/useRequest.ts +++ b/src-web/hooks/useRequest.ts @@ -2,10 +2,14 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { invoke } from '@tauri-apps/api'; import { convertDates, HttpRequest } from '../lib/models'; import { responsesQueryKey } from './useResponses'; -import { useNavigate, useNavigation } from 'react-router-dom'; +import { useNavigate } from 'react-router-dom'; + +export function requestsQueryKey(workspaceId: string) { + return ['requests', { workspaceId }]; +} export function useRequests(workspaceId: string) { - return useQuery(['requests'], async () => { + return useQuery(requestsQueryKey(workspaceId), async () => { const requests = (await invoke('requests', { workspaceId })) as HttpRequest[]; return requests.map(convertDates); }); @@ -40,6 +44,7 @@ export function useRequestCreate({ return useMutation>({ mutationFn: async (patch) => invoke('create_request', { ...patch, workspaceId }), onSuccess: async (requestId) => { + console.log('DONE', { requestId, navigateAfter }); if (navigateAfter) { navigate(`/workspaces/${workspaceId}/requests/${requestId}`); } @@ -60,3 +65,17 @@ export function useSendRequest(request: HttpRequest | null) { }, }); } + +export function useDeleteRequest(request: HttpRequest | null) { + const queryClient = useQueryClient(); + return useMutation({ + 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)); + }, + }); +} diff --git a/src-web/main.tsx b/src-web/main.tsx index 874c32c0..70f1e685 100644 --- a/src-web/main.tsx +++ b/src-web/main.tsx @@ -12,6 +12,7 @@ import { Layout } from './components/Layout'; import { Workspaces } from './pages/Workspaces'; import './main.css'; import { convertDates, HttpRequest } from './lib/models'; +import { requestsQueryKey } from './hooks/useRequest'; setTheme(); @@ -20,16 +21,24 @@ await init(); greet(); const queryClient = new QueryClient(); + await listen('updated_request', ({ payload: request }: { payload: HttpRequest }) => { - queryClient.setQueryData(['requests'], (requests: HttpRequest[] = []) => + queryClient.setQueryData(requestsQueryKey(request.workspaceId), (requests: HttpRequest[] = []) => requests.map((r) => (r.id === request.id ? convertDates(request) : r)), ); }); + await listen('created_request', ({ payload: request }: { payload: HttpRequest }) => { - queryClient.setQueryData(['requests'], (requests: HttpRequest[] = []) => [ - ...requests, - convertDates(request), - ]); + queryClient.setQueryData( + requestsQueryKey(request.workspaceId), + (requests: HttpRequest[] = []) => [...requests, convertDates(request)], + ); +}); + +await listen('deleted_request', ({ payload: request }: { payload: HttpRequest }) => { + queryClient.setQueryData(requestsQueryKey(request.workspaceId), (requests: HttpRequest[] = []) => + requests.filter((r) => r.id !== request.id), + ); }); const router = createBrowserRouter([