Short method tags and hide active in cmd+k

This commit is contained in:
Gregory Schier
2024-06-07 22:39:11 -07:00
parent f9412e6d8f
commit b456e8ce94
3 changed files with 61 additions and 12 deletions

View File

@@ -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<string | null>(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: (
<HStack space={2}>
<HttpMethodTag className="text-fg-subtler" shortNames request={r} />
<div className="truncate">{fallbackRequestName(r)}</div>
</HStack>
),
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),

View File

@@ -53,7 +53,7 @@ export function RecentRequestsDropdown({ className }: Pick<ButtonProps, 'classNa
key: request.id,
label: fallbackRequestName(request),
// leftSlot: <CountBadge className="!ml-0 px-0 w-5" count={recentRequestItems.length} />,
leftSlot: <HttpMethodTag request={request} />,
leftSlot: <HttpMethodTag className="text-right" shortNames request={request} />,
onSelect: () => {
routes.navigate('request', {
requestId: request.id,

View File

@@ -4,9 +4,10 @@ import type { GrpcRequest, HttpRequest } from '../../lib/models';
interface Props {
request: HttpRequest | GrpcRequest;
className?: string;
shortNames?: boolean;
}
const methodMap: Record<string, string> = {
const longMethodMap = {
get: 'GET',
put: 'PUT',
post: 'POST',
@@ -15,9 +16,20 @@ const methodMap: Record<string, string> = {
options: 'OPTIONS',
head: 'HEAD',
grpc: 'GRPC',
} as const;
const shortMethodMap: Record<keyof typeof longMethodMap, string> = {
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<string, string> = shortNames ? shortMethodMap : longMethodMap;
return (
<span className={classNames(className, 'text-xs font-mono text-fg-subtle')}>
{methodMap[m] ?? m.slice(0, 3).toUpperCase()}
<span
className={classNames(
className,
'text-xs font-mono text-fg-subtle',
'pt-[0.25em]', // Fix for monospace font not vertically centering
shortNames && 'w-[2.5em]',
)}
>
{methodMap[m] ?? m.slice(0, 4).toUpperCase()}
</span>
);
}