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