diff --git a/src-web/components/CommandPalette.tsx b/src-web/components/CommandPalette.tsx index e99f5320..e3575f61 100644 --- a/src-web/components/CommandPalette.tsx +++ b/src-web/components/CommandPalette.tsx @@ -2,6 +2,8 @@ import classNames from 'classnames'; import type { KeyboardEvent, ReactNode } from 'react'; import { useCallback, useMemo, useState } from 'react'; import { useActiveEnvironmentId } from '../hooks/useActiveEnvironmentId'; +import { useActiveRequestId } from '../hooks/useActiveRequestId'; +import { useActiveWorkspaceId } from '../hooks/useActiveWorkspaceId'; import { useAppRoutes } from '../hooks/useAppRoutes'; import { useOpenWorkspace } from '../hooks/useOpenWorkspace'; import { useRecentRequests } from '../hooks/useRecentRequests'; @@ -10,25 +12,28 @@ import { useRequests } from '../hooks/useRequests'; import { useWorkspaces } from '../hooks/useWorkspaces'; import { fallbackRequestName } from '../lib/fallbackRequestName'; import { Heading } from './core/Heading'; +import { HttpMethodTag } from './core/HttpMethodTag'; import { Icon } from './core/Icon'; import { PlainInput } from './core/PlainInput'; +import { HStack } from './core/Stacks'; interface CommandPaletteGroup { key: string; - label: string; + label: ReactNode; items: CommandPaletteItem[]; } -interface CommandPaletteItem { +type CommandPaletteItem = { key: string; - label: string; onSelect: () => void; -} +} & ({ searchText: string; label: ReactNode } | { label: string }); export function CommandPalette({ onClose }: { onClose: () => void }) { const [selectedItemKey, setSelectedItemKey] = useState(null); const routes = useAppRoutes(); const activeEnvironmentId = useActiveEnvironmentId(); + const activeRequestId = useActiveRequestId(); + const activeWorkspaceId = useActiveWorkspaceId(); const workspaces = useWorkspaces(); const recentWorkspaces = useRecentWorkspaces(); const requests = useRequests(); @@ -78,9 +83,19 @@ export function CommandPalette({ onClose }: { onClose: () => void }) { }; for (const r of sortedRequests.slice(0, 4)) { + if (r.id === activeRequestId) { + continue; + } + requestGroup.items.push({ key: `switch-request-${r.id}`, - label: fallbackRequestName(r), + searchText: `${r.method} ${r.name}`, + label: ( + + +
{fallbackRequestName(r)}
+
+ ), onSelect: () => { return routes.navigate('request', { workspaceId: r.workspaceId, @@ -98,6 +113,9 @@ export function CommandPalette({ onClose }: { onClose: () => void }) { }; for (const w of sortedWorkspaces.slice(0, 4)) { + if (w.id === activeWorkspaceId) { + continue; + } workspaceGroup.items.push({ key: `switch-workspace-${w.id}`, label: w.name, @@ -106,13 +124,24 @@ export function CommandPalette({ onClose }: { onClose: () => void }) { } return [requestGroup, workspaceGroup]; - }, [activeEnvironmentId, openWorkspace, routes, sortedRequests, sortedWorkspaces]); + }, [ + activeEnvironmentId, + activeRequestId, + activeWorkspaceId, + openWorkspace, + routes, + sortedRequests, + sortedWorkspaces, + ]); const filteredGroups = useMemo( () => groups .map((g) => { - g.items = g.items.filter((v) => v.label.toLowerCase().includes(command.toLowerCase())); + g.items = g.items.filter((v) => { + const s = 'searchText' in v ? v.searchText : v.label; + return s.toLowerCase().includes(command.toLowerCase()); + }); return g; }) .filter((g) => g.items.length > 0), diff --git a/src-web/components/RecentRequestsDropdown.tsx b/src-web/components/RecentRequestsDropdown.tsx index e875ec61..0d01801e 100644 --- a/src-web/components/RecentRequestsDropdown.tsx +++ b/src-web/components/RecentRequestsDropdown.tsx @@ -53,7 +53,7 @@ export function RecentRequestsDropdown({ className }: Pick, - leftSlot: , + leftSlot: , onSelect: () => { routes.navigate('request', { requestId: request.id, diff --git a/src-web/components/core/HttpMethodTag.tsx b/src-web/components/core/HttpMethodTag.tsx index 98aeb030..0a2d787d 100644 --- a/src-web/components/core/HttpMethodTag.tsx +++ b/src-web/components/core/HttpMethodTag.tsx @@ -4,9 +4,10 @@ import type { GrpcRequest, HttpRequest } from '../../lib/models'; interface Props { request: HttpRequest | GrpcRequest; className?: string; + shortNames?: boolean; } -const methodMap: Record = { +const longMethodMap = { get: 'GET', put: 'PUT', post: 'POST', @@ -15,9 +16,20 @@ const methodMap: Record = { options: 'OPTIONS', head: 'HEAD', grpc: 'GRPC', +} as const; + +const shortMethodMap: Record = { + get: 'GET', + put: 'PUT', + post: 'POST', + patch: 'PTCH', + delete: 'DEL', + options: 'OPTS', + head: 'HEAD', + grpc: 'GRPC', }; -export function HttpMethodTag({ request, className }: Props) { +export function HttpMethodTag({ shortNames, request, className }: Props) { const method = request.model === 'http_request' && request.bodyType === 'graphql' ? 'GQL' @@ -26,9 +38,17 @@ export function HttpMethodTag({ request, className }: Props) { : request.method; const m = method.toLowerCase(); + const methodMap: Record = shortNames ? shortMethodMap : longMethodMap; return ( - - {methodMap[m] ?? m.slice(0, 3).toUpperCase()} + + {methodMap[m] ?? m.slice(0, 4).toUpperCase()} ); }