From c8342fb0a982a81a02b8bca49284ac5693fa3145 Mon Sep 17 00:00:00 2001 From: Gregory Schier Date: Thu, 17 Oct 2024 11:17:27 -0700 Subject: [PATCH] Delete send history for workspace --- src-tauri/src/lib.rs | 31 +++++++------ src-tauri/yaak_models/src/queries.rs | 24 ++++++++++- .../components/WorkspaceActionsDropdown.tsx | 13 +++++- src-web/components/core/Icon.tsx | 3 +- src-web/hooks/useAlert.ts | 21 ++++----- src-web/hooks/useDeleteSendHistory.tsx | 43 +++++++++++++++++++ src-web/lib/tauri.ts | 1 + 7 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 src-web/hooks/useDeleteSendHistory.tsx diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index b3c60227..4a0ceb5f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -49,20 +49,7 @@ use yaak_models::models::{ GrpcEvent, GrpcEventType, GrpcRequest, HttpRequest, HttpResponse, HttpResponseState, KeyValue, ModelType, Plugin, Settings, Workspace, }; -use yaak_models::queries::{ - cancel_pending_grpc_connections, cancel_pending_responses, create_default_http_response, - delete_all_grpc_connections, delete_all_http_responses_for_request, delete_cookie_jar, - delete_environment, delete_folder, delete_grpc_connection, delete_grpc_request, - delete_http_request, delete_http_response, delete_plugin, delete_workspace, - duplicate_grpc_request, duplicate_http_request, generate_id, generate_model_id, get_cookie_jar, - get_environment, get_folder, get_grpc_connection, get_grpc_request, get_http_request, - get_http_response, get_key_value_raw, get_or_create_settings, get_plugin, get_workspace, - list_cookie_jars, list_environments, list_folders, list_grpc_connections, list_grpc_events, - list_grpc_requests, list_http_requests, list_http_responses, list_http_responses_for_request, - list_plugins, list_workspaces, set_key_value_raw, update_response_if_id, update_settings, - upsert_cookie_jar, upsert_environment, upsert_folder, upsert_grpc_connection, - upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_plugin, upsert_workspace, -}; +use yaak_models::queries::{cancel_pending_grpc_connections, cancel_pending_responses, create_default_http_response, delete_all_grpc_connections, delete_all_grpc_connections_for_workspace, delete_all_http_responses_for_request, delete_all_http_responses_for_workspace, delete_cookie_jar, delete_environment, delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request, delete_http_response, delete_plugin, delete_workspace, duplicate_grpc_request, duplicate_http_request, generate_id, generate_model_id, get_cookie_jar, get_environment, get_folder, get_grpc_connection, get_grpc_request, get_http_request, get_http_response, get_key_value_raw, get_or_create_settings, get_plugin, get_workspace, list_cookie_jars, list_environments, list_folders, list_grpc_connections_for_workspace, list_grpc_events, list_grpc_requests, list_http_requests, list_http_responses_for_request, list_http_responses_for_workspace, list_plugins, list_workspaces, set_key_value_raw, update_response_if_id, update_settings, upsert_cookie_jar, upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_event, upsert_grpc_request, upsert_http_request, upsert_plugin, upsert_workspace}; use yaak_plugin_runtime::events::{ BootResponse, CallHttpRequestActionRequest, FilterResponse, FindHttpResponsesResponse, GetHttpRequestActionsResponse, GetHttpRequestByIdResponse, GetTemplateFunctionsResponse, Icon, @@ -1505,7 +1492,7 @@ async fn cmd_list_grpc_connections( workspace_id: &str, w: WebviewWindow, ) -> Result, String> { - list_grpc_connections(&w, workspace_id) + list_grpc_connections_for_workspace(&w, workspace_id) .await .map_err(|e| e.to_string()) } @@ -1656,7 +1643,7 @@ async fn cmd_list_http_responses( limit: Option, w: WebviewWindow, ) -> Result, String> { - list_http_responses(&w, workspace_id, limit) + list_http_responses_for_workspace(&w, workspace_id, limit) .await .map_err(|e| e.to_string()) } @@ -1682,6 +1669,17 @@ async fn cmd_delete_all_grpc_connections(request_id: &str, w: WebviewWindow) -> .map_err(|e| e.to_string()) } +#[tauri::command] +async fn cmd_delete_send_history(workspace_id: &str, w: WebviewWindow) -> Result<(), String> { + delete_all_http_responses_for_workspace(&w, workspace_id) + .await + .map_err(|e| e.to_string())?; + delete_all_grpc_connections_for_workspace(&w, workspace_id) + .await + .map_err(|e| e.to_string())?; + Ok(()) +} + #[tauri::command] async fn cmd_delete_all_http_responses(request_id: &str, w: WebviewWindow) -> Result<(), String> { delete_all_http_responses_for_request(&w, request_id) @@ -1909,6 +1907,7 @@ pub fn run() { cmd_curl_to_request, cmd_delete_all_grpc_connections, cmd_delete_all_http_responses, + cmd_delete_send_history, cmd_delete_cookie_jar, cmd_delete_environment, cmd_delete_folder, diff --git a/src-tauri/yaak_models/src/queries.rs b/src-tauri/yaak_models/src/queries.rs index 5fec7cc8..e98e3a58 100644 --- a/src-tauri/yaak_models/src/queries.rs +++ b/src-tauri/yaak_models/src/queries.rs @@ -509,7 +509,7 @@ pub async fn get_grpc_connection( Ok(stmt.query_row(&*params.as_params(), |row| row.try_into())?) } -pub async fn list_grpc_connections( +pub async fn list_grpc_connections_for_workspace( mgr: &impl Manager, workspace_id: &str, ) -> Result> { @@ -573,6 +573,16 @@ pub async fn delete_all_grpc_connections( Ok(()) } +pub async fn delete_all_grpc_connections_for_workspace( + window: &WebviewWindow, + workspace_id: &str, +) -> Result<()> { + for r in list_grpc_connections_for_workspace(window, workspace_id).await? { + delete_grpc_connection(window, &r.id).await?; + } + Ok(()) +} + pub async fn upsert_grpc_event( window: &WebviewWindow, event: &GrpcEvent, @@ -1433,7 +1443,17 @@ pub async fn delete_all_http_responses_for_request( Ok(()) } -pub async fn list_http_responses( +pub async fn delete_all_http_responses_for_workspace( + window: &WebviewWindow, + workspace_id: &str, +) -> Result<()> { + for r in list_http_responses_for_workspace(window, workspace_id, None).await? { + delete_http_response(window, &r.id).await?; + } + Ok(()) +} + +pub async fn list_http_responses_for_workspace( mgr: &impl Manager, workspace_id: &str, limit: Option, diff --git a/src-web/components/WorkspaceActionsDropdown.tsx b/src-web/components/WorkspaceActionsDropdown.tsx index 1ae02ad0..f78730ab 100644 --- a/src-web/components/WorkspaceActionsDropdown.tsx +++ b/src-web/components/WorkspaceActionsDropdown.tsx @@ -2,6 +2,7 @@ import classNames from 'classnames'; import { memo, useCallback, useMemo } from 'react'; import { useActiveWorkspace } from '../hooks/useActiveWorkspace'; import { useCreateWorkspace } from '../hooks/useCreateWorkspace'; +import { useDeleteSendHistory } from '../hooks/useDeleteSendHistory'; import { useDeleteWorkspace } from '../hooks/useDeleteWorkspace'; import { useOpenWorkspace } from '../hooks/useOpenWorkspace'; import { usePrompt } from '../hooks/usePrompt'; @@ -36,6 +37,7 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ const settings = useSettings(); const openWorkspace = useOpenWorkspace(); const openWorkspaceNewWindow = settings?.openWorkspaceNewWindow ?? null; + const deleteSendHistory = useDeleteSendHistory(); const { workspaceItems, extraItems } = useMemo<{ workspaceItems: RadioDropdownItem[]; @@ -70,9 +72,15 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ updateWorkspace.mutate({ name }); }, }, + { + key: 'delete-responses', + label: 'Clear Send History', + leftSlot: , + onSelect: deleteSendHistory.mutate, + }, { key: 'delete', - label: 'Delete', + label: 'Delete Workspace', leftSlot: , onSelect: deleteWorkspace.mutate, variant: 'danger', @@ -90,7 +98,8 @@ export const WorkspaceActionsDropdown = memo(function WorkspaceActionsDropdown({ }, [ activeWorkspace?.name, activeWorkspaceId, - createWorkspace, + createWorkspace.mutate, + deleteSendHistory.mutate, deleteWorkspace.mutate, prompt, updateWorkspace, diff --git a/src-web/components/core/Icon.tsx b/src-web/components/core/Icon.tsx index a37f15f6..2cff7c85 100644 --- a/src-web/components/core/Icon.tsx +++ b/src-web/components/core/Icon.tsx @@ -26,7 +26,7 @@ const icons = { chevron_down: lucide.ChevronDownIcon, chevron_right: lucide.ChevronRightIcon, circle_alert: lucide.CircleAlertIcon, - cloud: lucide.CloudIcon, + clock: lucide.ClockIcon, code: lucide.CodeIcon, cookie: lucide.CookieIcon, copy: lucide.CopyIcon, @@ -48,6 +48,7 @@ const icons = { grip_vertical: lucide.GripVerticalIcon, hand: lucide.HandIcon, help: lucide.CircleHelpIcon, + history: lucide.HistoryIcon, house: lucide.HomeIcon, info: lucide.InfoIcon, keyboard: lucide.KeyboardIcon, diff --git a/src-web/hooks/useAlert.ts b/src-web/hooks/useAlert.ts index d856f8c1..2d63580b 100644 --- a/src-web/hooks/useAlert.ts +++ b/src-web/hooks/useAlert.ts @@ -4,20 +4,17 @@ import { useDialog } from '../components/DialogContext'; import type { AlertProps } from './Alert'; import { Alert } from './Alert'; +interface AlertArg { + id: string; + title: DialogProps['title']; + body: AlertProps['body']; + size?: DialogProps['size']; +} + export function useAlert() { const dialog = useDialog(); - return useCallback( - ({ - id, - title, - body, - size = 'sm', - }: { - id: string; - title: DialogProps['title']; - body: AlertProps['body']; - size?: DialogProps['size']; - }) => + return useCallback<(a: AlertArg) => void>( + ({ id, title, body, size = 'sm' }: AlertArg) => dialog.show({ id, title, diff --git a/src-web/hooks/useDeleteSendHistory.tsx b/src-web/hooks/useDeleteSendHistory.tsx new file mode 100644 index 00000000..fb46f36c --- /dev/null +++ b/src-web/hooks/useDeleteSendHistory.tsx @@ -0,0 +1,43 @@ +import { useMutation } from '@tanstack/react-query'; +import { count } from '../lib/pluralize'; +import { invokeCmd } from '../lib/tauri'; +import { useActiveWorkspace } from './useActiveWorkspace'; +import { useAlert } from './useAlert'; +import { useConfirm } from './useConfirm'; +import { useGrpcConnections } from './useGrpcConnections'; +import { useHttpResponses } from './useHttpResponses'; + +export function useDeleteSendHistory() { + const confirm = useConfirm(); + const alert = useAlert(); + const activeWorkspace = useActiveWorkspace(); + const httpResponses = useHttpResponses(); + const grpcConnections = useGrpcConnections(); + const labels = [ + httpResponses.length > 0 ? count('Http Response', httpResponses.length) : null, + grpcConnections.length > 0 ? count('Grpc Connection', grpcConnections.length) : null, + ].filter((l) => l != null); + + return useMutation({ + mutationKey: ['delete_send_history'], + mutationFn: async () => { + if (labels.length === 0) { + alert({ + id: 'no-responses', + title: 'Nothing to Delete', + body: 'There are no Http Response or Grpc Connections to delete', + }); + return; + } + + const confirmed = await confirm({ + id: 'delete-send-history', + title: 'Clear Send History', + variant: 'delete', + description: <>Delete {labels.join(' and ')}?, + }); + if (!confirmed) return; + await invokeCmd('cmd_delete_send_history', { workspaceId: activeWorkspace?.id ?? 'n/a' }); + }, + }); +} diff --git a/src-web/lib/tauri.ts b/src-web/lib/tauri.ts index 1442e9e4..abaeac33 100644 --- a/src-web/lib/tauri.ts +++ b/src-web/lib/tauri.ts @@ -14,6 +14,7 @@ type TauriCmd = | 'cmd_curl_to_request' | 'cmd_delete_all_grpc_connections' | 'cmd_delete_all_http_responses' + | 'cmd_delete_send_history' | 'cmd_delete_cookie_jar' | 'cmd_delete_environment' | 'cmd_delete_folder'