Fix deletion in sidebar

This commit is contained in:
Gregory Schier
2024-02-25 12:56:57 -08:00
parent 520ff0f68c
commit 31b5032817
2 changed files with 36 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
import classNames from 'classnames'; import classNames from 'classnames';
import type { ForwardedRef, ReactNode } from 'react'; import type { ForwardedRef, ReactNode } from 'react';
import React, { Fragment, forwardRef, useCallback, useMemo, useRef, useState } from 'react'; import React, { forwardRef, Fragment, useCallback, useMemo, useRef, useState } from 'react';
import type { XYCoord } from 'react-dnd'; import type { XYCoord } from 'react-dnd';
import { useDrag, useDrop } from 'react-dnd'; import { useDrag, useDrop } from 'react-dnd';
import { useKey, useKeyPressEvent } from 'react-use'; import { useKey, useKeyPressEvent } from 'react-use';
@@ -11,8 +11,6 @@ import { useActiveWorkspace } from '../hooks/useActiveWorkspace';
import { useAppRoutes } from '../hooks/useAppRoutes'; import { useAppRoutes } from '../hooks/useAppRoutes';
import { useCreateFolder } from '../hooks/useCreateFolder'; import { useCreateFolder } from '../hooks/useCreateFolder';
import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest'; import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest';
import { useDeleteAnyGrpcRequest } from '../hooks/useDeleteAnyGrpcRequest';
import { useDeleteAnyHttpRequest } from '../hooks/useDeleteAnyHttpRequest';
import { useDeleteFolder } from '../hooks/useDeleteFolder'; import { useDeleteFolder } from '../hooks/useDeleteFolder';
import { useDeleteRequest } from '../hooks/useDeleteRequest'; import { useDeleteRequest } from '../hooks/useDeleteRequest';
import { useDuplicateGrpcRequest } from '../hooks/useDuplicateGrpcRequest'; import { useDuplicateGrpcRequest } from '../hooks/useDuplicateGrpcRequest';
@@ -68,8 +66,6 @@ export function Sidebar({ className }: Props) {
const httpRequests = useHttpRequests(); const httpRequests = useHttpRequests();
const grpcRequests = useGrpcRequests(); const grpcRequests = useGrpcRequests();
const folders = useFolders(); const folders = useFolders();
const deleteAnyHttpRequest = useDeleteAnyHttpRequest();
const deleteAnyGrpcRequest = useDeleteAnyGrpcRequest();
const activeWorkspace = useActiveWorkspace(); const activeWorkspace = useActiveWorkspace();
const duplicateHttpRequest = useDuplicateHttpRequest({ const duplicateHttpRequest = useDuplicateHttpRequest({
id: activeRequest?.id ?? null, id: activeRequest?.id ?? null,
@@ -108,9 +104,10 @@ export function Sidebar({ className }: Props) {
[collapsed.value], [collapsed.value],
); );
const { tree, treeParentMap, selectableRequests } = useMemo<{ const { tree, treeParentMap, selectableRequests, selectedRequest } = useMemo<{
tree: TreeNode | null; tree: TreeNode | null;
treeParentMap: Record<string, TreeNode>; treeParentMap: Record<string, TreeNode>;
selectedRequest: HttpRequest | GrpcRequest | null;
selectableRequests: { selectableRequests: {
id: string; id: string;
index: number; index: number;
@@ -123,14 +120,23 @@ export function Sidebar({ className }: Props) {
index: number; index: number;
tree: TreeNode; tree: TreeNode;
}[] = []; }[] = [];
if (activeWorkspace == null) { if (activeWorkspace == null) {
return { tree: null, treeParentMap, selectableRequests }; return { tree: null, treeParentMap, selectableRequests, selectedRequest: null };
} }
let selectedRequest: HttpRequest | GrpcRequest | null = null;
let selectableRequestIndex = 0; let selectableRequestIndex = 0;
// Put requests and folders into a tree structure // Put requests and folders into a tree structure
const next = (node: TreeNode): TreeNode => { const next = (node: TreeNode): TreeNode => {
if (
node.item.id === selectedId &&
(node.item.model === 'http_request' || node.item.model === 'grpc_request')
) {
selectedRequest = node.item;
}
const childItems = [...httpRequests, ...grpcRequests, ...folders].filter((f) => const childItems = [...httpRequests, ...grpcRequests, ...folders].filter((f) =>
node.item.model === 'workspace' ? f.folderId == null : f.folderId === node.item.id, node.item.model === 'workspace' ? f.folderId == null : f.folderId === node.item.id,
); );
@@ -149,8 +155,10 @@ export function Sidebar({ className }: Props) {
const tree = next({ item: activeWorkspace, children: [], depth: 0 }); const tree = next({ item: activeWorkspace, children: [], depth: 0 });
return { tree, treeParentMap, selectableRequests }; return { tree, treeParentMap, selectableRequests, selectedRequest };
}, [activeWorkspace, httpRequests, grpcRequests, folders]); }, [activeWorkspace, selectedId, httpRequests, grpcRequests, folders]);
const deleteSelectedRequest = useDeleteRequest(selectedRequest);
const focusActiveRequest = useCallback( const focusActiveRequest = useCallback(
( (
@@ -221,16 +229,15 @@ export function Sidebar({ className }: Props) {
const handleBlur = useCallback(() => setHasFocus(false), []); const handleBlur = useCallback(() => setHasFocus(false), []);
const handleDeleteKey = useCallback( const handleDeleteKey = useCallback(
(e: KeyboardEvent) => { async (e: KeyboardEvent) => {
if (!hasFocus) return; if (!hasFocus) return;
e.preventDefault(); e.preventDefault();
const selected = selectableRequests.find((r) => r.id === selectedId); const selected = selectableRequests.find((r) => r.id === selectedId);
if (selected == null) return; if (selected == null) return;
deleteAnyHttpRequest.mutate(selected.id); await deleteSelectedRequest.mutateAsync();
deleteAnyGrpcRequest.mutate(selected.id);
}, },
[deleteAnyHttpRequest, deleteAnyGrpcRequest, hasFocus, selectableRequests, selectedId], [hasFocus, selectableRequests, deleteSelectedRequest, selectedId],
); );
useKeyPressEvent('Backspace', handleDeleteKey); useKeyPressEvent('Backspace', handleDeleteKey);
@@ -577,7 +584,7 @@ const SidebarItem = forwardRef(function SidebarItem(
const createRequest = useCreateHttpRequest(); const createRequest = useCreateHttpRequest();
const createFolder = useCreateFolder(); const createFolder = useCreateFolder();
const deleteFolder = useDeleteFolder(itemId); const deleteFolder = useDeleteFolder(itemId);
const deleteRequest = useDeleteRequest(itemId); const deleteRequest = useDeleteRequest(activeRequest ?? null);
const duplicateHttpRequest = useDuplicateHttpRequest({ id: itemId, navigateAfter: true }); const duplicateHttpRequest = useDuplicateHttpRequest({ id: itemId, navigateAfter: true });
const duplicateGrpcRequest = useDuplicateGrpcRequest({ id: itemId, navigateAfter: true }); const duplicateGrpcRequest = useDuplicateGrpcRequest({ id: itemId, navigateAfter: true });
const sendRequest = useSendRequest(itemId); const sendRequest = useSendRequest(itemId);

View File

@@ -1,11 +1,21 @@
import { useMutation } from '@tanstack/react-query'; import { useMutation } from '@tanstack/react-query';
import type { HttpRequest } from '../lib/models'; import type { GrpcRequest, HttpRequest } from '../lib/models';
import { useDeleteAnyGrpcRequest } from './useDeleteAnyGrpcRequest';
import { useDeleteAnyHttpRequest } from './useDeleteAnyHttpRequest'; import { useDeleteAnyHttpRequest } from './useDeleteAnyHttpRequest';
export function useDeleteRequest(id: string | null) { export function useDeleteRequest(request: HttpRequest | GrpcRequest | null) {
const deleteAnyRequest = useDeleteAnyHttpRequest(); const deleteAnyHttpRequest = useDeleteAnyHttpRequest();
const deleteAnyGrpcRequest = useDeleteAnyGrpcRequest();
return useMutation<HttpRequest | null, string>({ return useMutation<void, string>({
mutationFn: () => deleteAnyRequest.mutateAsync(id ?? 'n/a'), mutationFn: async () => {
if (request?.model === 'http_request') {
await deleteAnyHttpRequest.mutateAsync(request.id);
} else if (request?.model === 'grpc_request') {
await deleteAnyGrpcRequest.mutateAsync(request.id);
} else {
// Request is null
}
},
}); });
} }