mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-21 17:09:09 +01:00
Working sidebar actions for grpc
This commit is contained in:
@@ -24,7 +24,6 @@ use tonic_reflection::pb::server_reflection_response::MessageResponse;
|
||||
use tonic_reflection::pb::ServerReflectionRequest;
|
||||
|
||||
pub async fn fill_pool_from_files(paths: Vec<PathBuf>) -> Result<DescriptorPool, String> {
|
||||
println!("FILL POOL FROM FILES");
|
||||
let mut pool = DescriptorPool::new();
|
||||
let random_file_name = format!("{}.desc", uuid::Uuid::new_v4());
|
||||
let desc_path = temp_dir().join(random_file_name);
|
||||
@@ -51,8 +50,6 @@ pub async fn fill_pool_from_files(paths: Vec<PathBuf>) -> Result<DescriptorPool,
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Running: {:?}", cmd);
|
||||
|
||||
let output = cmd.output().map_err(|e| e.to_string())?;
|
||||
if !output.status.success() {
|
||||
return Err(format!(
|
||||
@@ -75,21 +72,7 @@ pub async fn fill_pool_from_files(paths: Vec<PathBuf>) -> Result<DescriptorPool,
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
pub fn get_transport() -> Client<HttpsConnector<HttpConnector>, BoxBody> {
|
||||
let connector = HttpsConnectorBuilder::new().with_native_roots();
|
||||
let connector = connector.https_or_http().enable_http2().wrap_connector({
|
||||
let mut http_connector = HttpConnector::new();
|
||||
http_connector.enforce_http(false);
|
||||
http_connector
|
||||
});
|
||||
Client::builder()
|
||||
.pool_max_idle_per_host(0)
|
||||
.http2_only(true)
|
||||
.build(connector)
|
||||
}
|
||||
|
||||
pub async fn fill_pool(uri: &Uri) -> Result<DescriptorPool, String> {
|
||||
println!("FILL POOL FROM URI");
|
||||
let mut pool = DescriptorPool::new();
|
||||
let mut client = ServerReflectionClient::with_origin(get_transport(), uri.clone());
|
||||
|
||||
@@ -103,6 +86,19 @@ pub async fn fill_pool(uri: &Uri) -> Result<DescriptorPool, String> {
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
pub fn get_transport() -> Client<HttpsConnector<HttpConnector>, BoxBody> {
|
||||
let connector = HttpsConnectorBuilder::new().with_native_roots();
|
||||
let connector = connector.https_or_http().enable_http2().wrap_connector({
|
||||
let mut http_connector = HttpConnector::new();
|
||||
http_connector.enforce_http(false);
|
||||
http_connector
|
||||
});
|
||||
Client::builder()
|
||||
.pool_max_idle_per_host(0)
|
||||
.http2_only(true)
|
||||
.build(connector)
|
||||
}
|
||||
|
||||
async fn list_services(
|
||||
reflect_client: &mut ServerReflectionClient<Client<HttpsConnector<HttpConnector>, BoxBody>>,
|
||||
) -> Result<Vec<String>, String> {
|
||||
|
||||
@@ -44,16 +44,17 @@ use crate::http::send_http_request;
|
||||
use crate::models::{
|
||||
cancel_pending_grpc_connections, cancel_pending_responses, create_response,
|
||||
delete_all_grpc_connections, delete_all_http_responses, delete_cookie_jar, delete_environment,
|
||||
delete_folder, delete_grpc_connection, delete_http_request, delete_http_response,
|
||||
delete_workspace, duplicate_grpc_request, duplicate_http_request, get_cookie_jar,
|
||||
get_environment, get_folder, get_grpc_request, get_http_request, get_http_response,
|
||||
get_key_value_raw, get_or_create_settings, get_workspace, get_workspace_export_resources,
|
||||
list_cookie_jars, list_environments, list_folders, list_grpc_connections, list_grpc_messages,
|
||||
list_grpc_requests, list_requests, list_responses, list_workspaces, set_key_value_raw,
|
||||
update_response_if_id, update_settings, upsert_cookie_jar, upsert_environment, upsert_folder,
|
||||
upsert_grpc_connection, upsert_grpc_message, upsert_grpc_request, upsert_http_request,
|
||||
upsert_workspace, CookieJar, Environment, EnvironmentVariable, Folder, GrpcConnection,
|
||||
GrpcMessage, GrpcRequest, HttpRequest, HttpResponse, KeyValue, Settings, Workspace,
|
||||
delete_folder, delete_grpc_connection, delete_grpc_request, delete_http_request,
|
||||
delete_http_response, delete_workspace, duplicate_grpc_request, duplicate_http_request,
|
||||
get_cookie_jar, get_environment, get_folder, get_grpc_request, get_http_request,
|
||||
get_http_response, get_key_value_raw, get_or_create_settings, get_workspace,
|
||||
get_workspace_export_resources, list_cookie_jars, list_environments, list_folders,
|
||||
list_grpc_connections, list_grpc_messages, list_grpc_requests, list_requests, list_responses,
|
||||
list_workspaces, set_key_value_raw, update_response_if_id, update_settings, upsert_cookie_jar,
|
||||
upsert_environment, upsert_folder, upsert_grpc_connection, upsert_grpc_message,
|
||||
upsert_grpc_request, upsert_http_request, upsert_workspace, CookieJar, Environment,
|
||||
EnvironmentVariable, Folder, GrpcConnection, GrpcMessage, GrpcRequest, HttpRequest,
|
||||
HttpResponse, KeyValue, Settings, Workspace,
|
||||
};
|
||||
use crate::plugin::{ImportResources, ImportResult};
|
||||
use crate::updates::{update_mode_from_str, UpdateMode, YaakUpdater};
|
||||
@@ -103,7 +104,6 @@ async fn cmd_grpc_reflect(
|
||||
.map_err(|e| e.to_string())?;
|
||||
let uri = safe_uri(&req.url).map_err(|e| e.to_string())?;
|
||||
if req.proto_files.0.len() > 0 {
|
||||
println!("REFLECT FROM FILES");
|
||||
grpc_handle
|
||||
.lock()
|
||||
.await
|
||||
@@ -1331,8 +1331,8 @@ async fn cmd_update_http_request(
|
||||
async fn cmd_delete_grpc_request(
|
||||
app_handle: AppHandle,
|
||||
request_id: &str,
|
||||
) -> Result<HttpRequest, String> {
|
||||
delete_http_request(&app_handle, request_id)
|
||||
) -> Result<GrpcRequest, String> {
|
||||
delete_grpc_request(&app_handle, request_id)
|
||||
.await
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
@@ -1379,6 +1379,26 @@ pub async fn list_responses_by_workspace_id(
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_grpc_request(
|
||||
app_handle: &AppHandle,
|
||||
id: &str,
|
||||
) -> Result<GrpcRequest, sqlx::Error> {
|
||||
let req = get_grpc_request(app_handle, id).await?;
|
||||
|
||||
let db = get_db(app_handle).await;
|
||||
let _ = sqlx::query!(
|
||||
r#"
|
||||
DELETE FROM grpc_requests
|
||||
WHERE id = ?
|
||||
"#,
|
||||
id,
|
||||
)
|
||||
.execute(&db)
|
||||
.await;
|
||||
|
||||
emit_deleted_model(app_handle, req)
|
||||
}
|
||||
|
||||
pub async fn delete_grpc_connection(
|
||||
app_handle: &AppHandle,
|
||||
id: &str,
|
||||
|
||||
@@ -65,6 +65,7 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
||||
<div className="overflow-y-auto h-full">
|
||||
{...messages.map((m) => (
|
||||
<HStack
|
||||
role="button"
|
||||
key={m.id}
|
||||
space={2}
|
||||
onClick={() => {
|
||||
@@ -72,7 +73,10 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
||||
else setActiveMessageId(m.id);
|
||||
}}
|
||||
alignItems="center"
|
||||
className={classNames('px-2 py-1 font-mono', m === activeMessage && 'bg-highlight')}
|
||||
className={classNames(
|
||||
'px-2 py-1 font-mono cursor-default group',
|
||||
m === activeMessage && '!bg-highlight',
|
||||
)}
|
||||
>
|
||||
<Icon
|
||||
className={
|
||||
@@ -80,8 +84,22 @@ export function GrpcConnectionMessagesPane({ style, methodType, activeRequest }:
|
||||
}
|
||||
icon={m.isInfo ? 'info' : m.isServer ? 'arrowBigDownDash' : 'arrowBigUpDash'}
|
||||
/>
|
||||
<div className="w-full truncate text-gray-800 text-2xs">{m.message}</div>
|
||||
<div className="text-gray-600 text-2xs">{format(m.createdAt, 'HH:mm:ss')}</div>
|
||||
<div
|
||||
className={classNames(
|
||||
'w-full truncate text-gray-800 text-2xs group-hover:text-gray-900',
|
||||
m.id === activeMessageId && 'text-gray-900',
|
||||
)}
|
||||
>
|
||||
{m.message}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
'text-gray-600 text-2xs group-hover:text-gray-700',
|
||||
m.id === activeMessageId && 'text-gray-700',
|
||||
)}
|
||||
>
|
||||
{format(m.createdAt, 'HH:mm:ss')}
|
||||
</div>
|
||||
</HStack>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,8 @@ import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
|
||||
import { useAppRoutes } from '../hooks/useAppRoutes';
|
||||
import { useCreateFolder } from '../hooks/useCreateFolder';
|
||||
import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest';
|
||||
import { useDeleteAnyRequest } from '../hooks/useDeleteAnyRequest';
|
||||
import { useDeleteAnyGrpcRequest } from '../hooks/useDeleteAnyGrpcRequest';
|
||||
import { useDeleteAnyHttpRequest } from '../hooks/useDeleteAnyHttpRequest';
|
||||
import { useDeleteFolder } from '../hooks/useDeleteFolder';
|
||||
import { useDeleteRequest } from '../hooks/useDeleteRequest';
|
||||
import { useDuplicateGrpcRequest } from '../hooks/useDuplicateGrpcRequest';
|
||||
@@ -36,6 +37,7 @@ import { fallbackRequestName } from '../lib/fallbackRequestName';
|
||||
import { NAMESPACE_NO_SYNC } from '../lib/keyValueStore';
|
||||
import type { Folder, GrpcRequest, HttpRequest, Workspace } from '../lib/models';
|
||||
import { isResponseLoading } from '../lib/models';
|
||||
import type { DropdownItem } from './core/Dropdown';
|
||||
import { ContextMenu } from './core/Dropdown';
|
||||
import { Icon } from './core/Icon';
|
||||
import { InlineCode } from './core/InlineCode';
|
||||
@@ -65,7 +67,8 @@ export function Sidebar({ className }: Props) {
|
||||
const httpRequests = useHttpRequests();
|
||||
const grpcRequests = useGrpcRequests();
|
||||
const folders = useFolders();
|
||||
const deleteAnyRequest = useDeleteAnyRequest();
|
||||
const deleteAnyHttpRequest = useDeleteAnyHttpRequest();
|
||||
const deleteAnyGrpcRequest = useDeleteAnyGrpcRequest();
|
||||
const activeWorkspace = useActiveWorkspace();
|
||||
const duplicateHttpRequest = useDuplicateHttpRequest({
|
||||
id: activeRequest?.id ?? null,
|
||||
@@ -223,9 +226,10 @@ export function Sidebar({ className }: Props) {
|
||||
|
||||
const selected = selectableRequests.find((r) => r.id === selectedId);
|
||||
if (selected == null) return;
|
||||
deleteAnyRequest.mutate(selected.id);
|
||||
deleteAnyHttpRequest.mutate(selected.id);
|
||||
deleteAnyGrpcRequest.mutate(selected.id);
|
||||
},
|
||||
[deleteAnyRequest, hasFocus, selectableRequests, selectedId],
|
||||
[deleteAnyHttpRequest, deleteAnyGrpcRequest, hasFocus, selectableRequests, selectedId],
|
||||
);
|
||||
|
||||
useKeyPressEvent('Backspace', handleDeleteKey);
|
||||
@@ -683,15 +687,19 @@ const SidebarItem = forwardRef(function SidebarItem(
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
key: 'sendRequest',
|
||||
label: 'Send',
|
||||
hotKeyAction: 'http_request.send',
|
||||
hotKeyLabelOnly: true, // Already bound in URL bar
|
||||
leftSlot: <Icon icon="sendHorizontal" />,
|
||||
onSelect: () => sendRequest.mutate(),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
...((itemModel === 'http_request'
|
||||
? [
|
||||
{
|
||||
key: 'sendRequest',
|
||||
label: 'Send',
|
||||
hotKeyAction: 'http_request.send',
|
||||
hotKeyLabelOnly: true, // Already bound in URL bar
|
||||
leftSlot: <Icon icon="sendHorizontal" />,
|
||||
onSelect: () => sendRequest.mutate(),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
]
|
||||
: []) as DropdownItem[]),
|
||||
{
|
||||
key: 'duplicateRequest',
|
||||
label: 'Duplicate',
|
||||
|
||||
@@ -30,7 +30,7 @@ export function Confirm({ onHide, onResult, variant = 'confirm' }: ConfirmProps)
|
||||
};
|
||||
|
||||
return (
|
||||
<HStack space={2} justifyContent="end" className="mt-2 mb-4 flex-row-reverse">
|
||||
<HStack space={2} justifyContent="start" className="mt-2 mb-4 flex-row-reverse">
|
||||
<Button className="focus" color={colors[variant]} onClick={handleSuccess}>
|
||||
{confirmButtonTexts[variant]}
|
||||
</Button>
|
||||
|
||||
43
src-web/hooks/useDeleteAnyGrpcRequest.tsx
Normal file
43
src-web/hooks/useDeleteAnyGrpcRequest.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { invoke } from '@tauri-apps/api';
|
||||
import { InlineCode } from '../components/core/InlineCode';
|
||||
import { trackEvent } from '../lib/analytics';
|
||||
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
||||
import type { GrpcRequest } from '../lib/models';
|
||||
import { getGrpcRequest } from '../lib/store';
|
||||
import { useConfirm } from './useConfirm';
|
||||
import { grpcRequestsQueryKey } from './useGrpcRequests';
|
||||
|
||||
export function useDeleteAnyGrpcRequest() {
|
||||
const queryClient = useQueryClient();
|
||||
const confirm = useConfirm();
|
||||
|
||||
return useMutation<GrpcRequest | null, string, string>({
|
||||
mutationFn: async (id) => {
|
||||
const request = await getGrpcRequest(id);
|
||||
if (request == null) return null;
|
||||
|
||||
const confirmed = await confirm({
|
||||
id: 'delete-grpc-request',
|
||||
title: 'Delete Request',
|
||||
variant: 'delete',
|
||||
description: (
|
||||
<>
|
||||
Permanently delete <InlineCode>{fallbackRequestName(request)}</InlineCode>?
|
||||
</>
|
||||
),
|
||||
});
|
||||
if (!confirmed) return null;
|
||||
return invoke('cmd_delete_grpc_request', { requestId: id });
|
||||
},
|
||||
onSettled: () => trackEvent('GrpcRequest', 'Delete'),
|
||||
onSuccess: async (request) => {
|
||||
if (request === null) return;
|
||||
|
||||
const { workspaceId, id: requestId } = request;
|
||||
queryClient.setQueryData<GrpcRequest[]>(grpcRequestsQueryKey({ workspaceId }), (requests) =>
|
||||
(requests ?? []).filter((r) => r.id !== requestId),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -9,13 +9,15 @@ import { useConfirm } from './useConfirm';
|
||||
import { httpRequestsQueryKey } from './useHttpRequests';
|
||||
import { httpResponsesQueryKey } from './useHttpResponses';
|
||||
|
||||
export function useDeleteAnyRequest() {
|
||||
export function useDeleteAnyHttpRequest() {
|
||||
const queryClient = useQueryClient();
|
||||
const confirm = useConfirm();
|
||||
|
||||
return useMutation<HttpRequest | null, string, string>({
|
||||
mutationFn: async (id) => {
|
||||
const request = await getHttpRequest(id);
|
||||
if (request == null) return null;
|
||||
|
||||
const confirmed = await confirm({
|
||||
id: 'delete-request',
|
||||
title: 'Delete Request',
|
||||
@@ -1,9 +1,9 @@
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import type { HttpRequest } from '../lib/models';
|
||||
import { useDeleteAnyRequest } from './useDeleteAnyRequest';
|
||||
import { useDeleteAnyHttpRequest } from './useDeleteAnyHttpRequest';
|
||||
|
||||
export function useDeleteRequest(id: string | null) {
|
||||
const deleteAnyRequest = useDeleteAnyRequest();
|
||||
const deleteAnyRequest = useDeleteAnyHttpRequest();
|
||||
|
||||
return useMutation<HttpRequest | null, string>({
|
||||
mutationFn: () => deleteAnyRequest.mutateAsync(id ?? 'n/a'),
|
||||
|
||||
Reference in New Issue
Block a user