mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-22 17:39:46 +01:00
Add rename/delete/send to cmd+k
This commit is contained in:
@@ -5,7 +5,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useActiveCookieJar } from '../hooks/useActiveCookieJar';
|
||||
import { useActiveEnvironment } from '../hooks/useActiveEnvironment';
|
||||
import { useActiveEnvironmentId } from '../hooks/useActiveEnvironmentId';
|
||||
import { useActiveRequestId } from '../hooks/useActiveRequestId';
|
||||
import { useActiveRequest } from '../hooks/useActiveRequest';
|
||||
import { useActiveWorkspaceId } from '../hooks/useActiveWorkspaceId';
|
||||
import { useAppRoutes } from '../hooks/useAppRoutes';
|
||||
import { useCreateEnvironment } from '../hooks/useCreateEnvironment';
|
||||
@@ -13,6 +13,7 @@ import { useCreateGrpcRequest } from '../hooks/useCreateGrpcRequest';
|
||||
import { useCreateHttpRequest } from '../hooks/useCreateHttpRequest';
|
||||
import { useCreateWorkspace } from '../hooks/useCreateWorkspace';
|
||||
import { useDebouncedState } from '../hooks/useDebouncedState';
|
||||
import { useDeleteRequest } from '../hooks/useDeleteRequest';
|
||||
import { useEnvironments } from '../hooks/useEnvironments';
|
||||
import type { HotkeyAction } from '../hooks/useHotKey';
|
||||
import { useHotKey } from '../hooks/useHotKey';
|
||||
@@ -20,7 +21,9 @@ import { useOpenWorkspace } from '../hooks/useOpenWorkspace';
|
||||
import { useRecentEnvironments } from '../hooks/useRecentEnvironments';
|
||||
import { useRecentRequests } from '../hooks/useRecentRequests';
|
||||
import { useRecentWorkspaces } from '../hooks/useRecentWorkspaces';
|
||||
import { useRenameRequest } from '../hooks/useRenameRequest';
|
||||
import { useRequests } from '../hooks/useRequests';
|
||||
import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
|
||||
import { useSidebarHidden } from '../hooks/useSidebarHidden';
|
||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
||||
@@ -55,13 +58,12 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
const [selectedItemKey, setSelectedItemKey] = useState<string | null>(null);
|
||||
const routes = useAppRoutes();
|
||||
const activeEnvironmentId = useActiveEnvironmentId();
|
||||
const activeRequestId = useActiveRequestId();
|
||||
const active = useActiveWorkspaceId();
|
||||
const workspaces = useWorkspaces();
|
||||
const environments = useEnvironments();
|
||||
const recentEnvironments = useRecentEnvironments();
|
||||
const recentWorkspaces = useRecentWorkspaces();
|
||||
const requests = useRequests();
|
||||
const activeRequest = useActiveRequest();
|
||||
const recentRequests = useRecentRequests();
|
||||
const openWorkspace = useOpenWorkspace();
|
||||
const createWorkspace = useCreateWorkspace();
|
||||
@@ -72,6 +74,9 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
const dialog = useDialog();
|
||||
const workspaceId = useActiveWorkspaceId();
|
||||
const activeEnvironment = useActiveEnvironment();
|
||||
const sendRequest = useSendAnyHttpRequest();
|
||||
const renameRequest = useRenameRequest(activeRequest?.id ?? null);
|
||||
const deleteRequest = useDeleteRequest(activeRequest?.id ?? null);
|
||||
const [, setSidebarHidden] = useSidebarHidden();
|
||||
|
||||
const workspaceCommands = useMemo<CommandPaletteItem[]>(() => {
|
||||
@@ -142,20 +147,48 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
onSelect: () => setSidebarHidden((h) => !h),
|
||||
},
|
||||
];
|
||||
|
||||
if (activeRequest?.model === 'http_request') {
|
||||
commands.push({
|
||||
key: 'http_request.send',
|
||||
action: 'http_request.send',
|
||||
label: 'Send Request',
|
||||
onSelect: () => sendRequest.mutateAsync(activeRequest.id),
|
||||
});
|
||||
}
|
||||
|
||||
if (activeRequest != null) {
|
||||
commands.push({
|
||||
key: 'http_request.rename',
|
||||
label: 'Rename Request',
|
||||
onSelect: renameRequest.mutate,
|
||||
});
|
||||
|
||||
commands.push({
|
||||
key: 'http_request.delete',
|
||||
label: 'Delete Request',
|
||||
onSelect: deleteRequest.mutate,
|
||||
});
|
||||
}
|
||||
|
||||
return commands.sort((a, b) =>
|
||||
('searchText' in a ? a.searchText : a.label).localeCompare(
|
||||
'searchText' in b ? b.searchText : b.label,
|
||||
),
|
||||
);
|
||||
}, [
|
||||
activeCookieJar,
|
||||
activeCookieJar?.id,
|
||||
activeEnvironment,
|
||||
activeRequest,
|
||||
createEnvironment.mutate,
|
||||
createGrpcRequest,
|
||||
createHttpRequest,
|
||||
createWorkspace.mutate,
|
||||
deleteRequest.mutate,
|
||||
dialog,
|
||||
renameRequest.mutate,
|
||||
routes.paths,
|
||||
sendRequest,
|
||||
setSidebarHidden,
|
||||
workspaceId,
|
||||
]);
|
||||
@@ -225,10 +258,6 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
};
|
||||
|
||||
for (const r of sortedRequests) {
|
||||
if (r.id === activeRequestId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
requestGroup.items.push({
|
||||
key: `switch-request-${r.id}`,
|
||||
searchText: fallbackRequestName(r),
|
||||
@@ -272,9 +301,6 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
};
|
||||
|
||||
for (const w of sortedWorkspaces) {
|
||||
if (w.id === active) {
|
||||
continue;
|
||||
}
|
||||
workspaceGroup.items.push({
|
||||
key: `switch-workspace-${w.id}`,
|
||||
label: w.name,
|
||||
@@ -286,13 +312,11 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
||||
}, [
|
||||
workspaceCommands,
|
||||
sortedRequests,
|
||||
activeRequestId,
|
||||
routes,
|
||||
activeEnvironmentId,
|
||||
sortedEnvironments,
|
||||
activeEnvironment?.id,
|
||||
sortedWorkspaces,
|
||||
active,
|
||||
openWorkspace,
|
||||
]);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||
import { useEffect } from 'react';
|
||||
import { useAtiveWorkspaceChangedToast } from '../hooks/useAtiveWorkspaceChangedToast';
|
||||
import { useClipboardText } from '../hooks/useClipboardText';
|
||||
import { useCommandPalette } from '../hooks/useCommandPalette';
|
||||
import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette';
|
||||
import { cookieJarsQueryKey } from '../hooks/useCookieJars';
|
||||
import { environmentsQueryKey } from '../hooks/useEnvironments';
|
||||
import { foldersQueryKey } from '../hooks/useFolders';
|
||||
@@ -42,10 +42,12 @@ export function GlobalHooks() {
|
||||
|
||||
// Other useful things
|
||||
useSyncThemeToDocument();
|
||||
useCommandPalette();
|
||||
useNotificationToast();
|
||||
useAtiveWorkspaceChangedToast();
|
||||
|
||||
const toggleCommandPalette = useToggleCommandPalette();
|
||||
useHotKey('command_palette.toggle', toggleCommandPalette);
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const { wasUpdatedExternally } = useRequestUpdateKey(null);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import { useLatestGrpcConnection } from '../hooks/useLatestGrpcConnection';
|
||||
import { useLatestHttpResponse } from '../hooks/useLatestHttpResponse';
|
||||
import { useMoveToWorkspace } from '../hooks/useMoveToWorkspace';
|
||||
import { usePrompt } from '../hooks/usePrompt';
|
||||
import { useRenameRequest } from '../hooks/useRenameRequest';
|
||||
import { useRequests } from '../hooks/useRequests';
|
||||
import { useSendAnyHttpRequest } from '../hooks/useSendAnyHttpRequest';
|
||||
import { useSendManyRequests } from '../hooks/useSendFolder';
|
||||
@@ -649,6 +650,7 @@ function SidebarItem({
|
||||
const activeRequest = useActiveRequest();
|
||||
const deleteFolder = useDeleteFolder(itemId);
|
||||
const deleteRequest = useDeleteRequest(itemId);
|
||||
const renameRequest = useRenameRequest(itemId);
|
||||
const duplicateHttpRequest = useDuplicateHttpRequest({ id: itemId, navigateAfter: true });
|
||||
const duplicateGrpcRequest = useDuplicateGrpcRequest({ id: itemId, navigateAfter: true });
|
||||
const copyAsCurl = useCopyAsCurl(itemId);
|
||||
@@ -795,29 +797,7 @@ function SidebarItem({
|
||||
key: 'renameRequest',
|
||||
label: 'Rename',
|
||||
leftSlot: <Icon icon="pencil" />,
|
||||
onSelect: async () => {
|
||||
const name = await prompt({
|
||||
id: 'rename-request',
|
||||
title: 'Rename Request',
|
||||
description:
|
||||
itemName === '' ? (
|
||||
'Enter a new name'
|
||||
) : (
|
||||
<>
|
||||
Enter a new name for <InlineCode>{itemName}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
placeholder: 'New Name',
|
||||
defaultValue: itemName,
|
||||
});
|
||||
if (itemModel === 'http_request') {
|
||||
updateHttpRequest.mutate({ id: itemId, update: (r) => ({ ...r, name }) });
|
||||
} else {
|
||||
updateGrpcRequest.mutate({ id: itemId, update: (r) => ({ ...r, name }) });
|
||||
}
|
||||
},
|
||||
onSelect: renameRequest.mutate,
|
||||
},
|
||||
{
|
||||
key: 'duplicateRequest',
|
||||
@@ -849,7 +829,7 @@ function SidebarItem({
|
||||
}
|
||||
}, [
|
||||
child.children,
|
||||
copyAsCurl,
|
||||
copyAsCurl.mutate,
|
||||
createDropdownItems,
|
||||
deleteFolder,
|
||||
deleteRequest,
|
||||
@@ -860,11 +840,10 @@ function SidebarItem({
|
||||
itemName,
|
||||
moveToWorkspace.mutate,
|
||||
prompt,
|
||||
renameRequest.mutate,
|
||||
sendManyRequests,
|
||||
sendRequest,
|
||||
updateAnyFolder,
|
||||
updateGrpcRequest,
|
||||
updateHttpRequest,
|
||||
workspaces.length,
|
||||
]);
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import classNames from 'classnames';
|
||||
import React, { memo } from 'react';
|
||||
import { useToggleCommandPalette } from '../hooks/useToggleCommandPalette';
|
||||
import { CookieDropdown } from './CookieDropdown';
|
||||
import { Icon } from './core/Icon';
|
||||
import { IconButton } from './core/IconButton';
|
||||
import { HStack } from './core/Stacks';
|
||||
import { EnvironmentActionsDropdown } from './EnvironmentActionsDropdown';
|
||||
import { ImportCurlButton } from './ImportCurlButton';
|
||||
@@ -16,6 +18,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Props) {
|
||||
const togglePalette = useToggleCommandPalette();
|
||||
return (
|
||||
<HStack space={2} justifyContent="center" className={classNames(className, 'w-full h-full')}>
|
||||
<HStack space={0.5} className="flex-1 pointer-events-none">
|
||||
@@ -32,6 +35,12 @@ export const WorkspaceHeader = memo(function WorkspaceHeader({ className }: Prop
|
||||
</div>
|
||||
<div className="flex-1 flex gap-1 items-center h-full justify-end pointer-events-none pr-0.5">
|
||||
<ImportCurlButton />
|
||||
<IconButton
|
||||
icon="search"
|
||||
title="Search or execute a command"
|
||||
size="sm"
|
||||
onClick={togglePalette}
|
||||
/>
|
||||
<SettingsDropdown />
|
||||
<WindowControls />
|
||||
</div>
|
||||
|
||||
42
src-web/hooks/useRenameRequest.tsx
Normal file
42
src-web/hooks/useRenameRequest.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { InlineCode } from '../components/core/InlineCode';
|
||||
import { usePrompt } from './usePrompt';
|
||||
import { useRequests } from './useRequests';
|
||||
import { useUpdateAnyGrpcRequest } from './useUpdateAnyGrpcRequest';
|
||||
import { useUpdateAnyHttpRequest } from './useUpdateAnyHttpRequest';
|
||||
|
||||
export function useRenameRequest(requestId: string | null) {
|
||||
const prompt = usePrompt();
|
||||
const updateHttpRequest = useUpdateAnyHttpRequest();
|
||||
const updateGrpcRequest = useUpdateAnyGrpcRequest();
|
||||
const requests = useRequests();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async () => {
|
||||
const request = requests.find((r) => r.id === requestId);
|
||||
if (request == null) return;
|
||||
|
||||
const name = await prompt({
|
||||
id: 'rename-request',
|
||||
title: 'Rename Request',
|
||||
description:
|
||||
request.name === '' ? (
|
||||
'Enter a new name'
|
||||
) : (
|
||||
<>
|
||||
Enter a new name for <InlineCode>{request.name}</InlineCode>
|
||||
</>
|
||||
),
|
||||
name: 'name',
|
||||
label: 'Name',
|
||||
placeholder: 'New Name',
|
||||
defaultValue: request.name,
|
||||
});
|
||||
if (request.model === 'http_request') {
|
||||
updateHttpRequest.mutate({ id: request.id, update: (r) => ({ ...r, name }) });
|
||||
} else {
|
||||
updateGrpcRequest.mutate({ id: request.id, update: (r) => ({ ...r, name }) });
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useCallback } from 'react';
|
||||
import { CommandPalette } from '../components/CommandPalette';
|
||||
import { useDialog } from '../components/DialogContext';
|
||||
import { useHotKey } from './useHotKey';
|
||||
|
||||
export function useCommandPalette() {
|
||||
export function useToggleCommandPalette() {
|
||||
const dialog = useDialog();
|
||||
useHotKey('command_palette.toggle', () => {
|
||||
const togglePalette = useCallback(() => {
|
||||
dialog.toggle({
|
||||
id: 'command_palette',
|
||||
size: 'dynamic',
|
||||
@@ -15,5 +15,7 @@ export function useCommandPalette() {
|
||||
noScroll: true,
|
||||
render: ({ hide }) => <CommandPalette onClose={hide} />,
|
||||
});
|
||||
});
|
||||
}, [dialog]);
|
||||
|
||||
return togglePalette;
|
||||
}
|
||||
Reference in New Issue
Block a user