mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-23 00:58:32 +02:00
Short method tags and hide active in cmd+k
This commit is contained in:
@@ -2,6 +2,8 @@ import classNames from 'classnames';
|
|||||||
import type { KeyboardEvent, ReactNode } from 'react';
|
import type { KeyboardEvent, ReactNode } from 'react';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useActiveEnvironmentId } from '../hooks/useActiveEnvironmentId';
|
import { useActiveEnvironmentId } from '../hooks/useActiveEnvironmentId';
|
||||||
|
import { useActiveRequestId } from '../hooks/useActiveRequestId';
|
||||||
|
import { useActiveWorkspaceId } from '../hooks/useActiveWorkspaceId';
|
||||||
import { useAppRoutes } from '../hooks/useAppRoutes';
|
import { useAppRoutes } from '../hooks/useAppRoutes';
|
||||||
import { useOpenWorkspace } from '../hooks/useOpenWorkspace';
|
import { useOpenWorkspace } from '../hooks/useOpenWorkspace';
|
||||||
import { useRecentRequests } from '../hooks/useRecentRequests';
|
import { useRecentRequests } from '../hooks/useRecentRequests';
|
||||||
@@ -10,25 +12,28 @@ import { useRequests } from '../hooks/useRequests';
|
|||||||
import { useWorkspaces } from '../hooks/useWorkspaces';
|
import { useWorkspaces } from '../hooks/useWorkspaces';
|
||||||
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
import { fallbackRequestName } from '../lib/fallbackRequestName';
|
||||||
import { Heading } from './core/Heading';
|
import { Heading } from './core/Heading';
|
||||||
|
import { HttpMethodTag } from './core/HttpMethodTag';
|
||||||
import { Icon } from './core/Icon';
|
import { Icon } from './core/Icon';
|
||||||
import { PlainInput } from './core/PlainInput';
|
import { PlainInput } from './core/PlainInput';
|
||||||
|
import { HStack } from './core/Stacks';
|
||||||
|
|
||||||
interface CommandPaletteGroup {
|
interface CommandPaletteGroup {
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
label: ReactNode;
|
||||||
items: CommandPaletteItem[];
|
items: CommandPaletteItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CommandPaletteItem {
|
type CommandPaletteItem = {
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
|
||||||
onSelect: () => void;
|
onSelect: () => void;
|
||||||
}
|
} & ({ searchText: string; label: ReactNode } | { label: string });
|
||||||
|
|
||||||
export function CommandPalette({ onClose }: { onClose: () => void }) {
|
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 activeWorkspaceId = useActiveWorkspaceId();
|
||||||
const workspaces = useWorkspaces();
|
const workspaces = useWorkspaces();
|
||||||
const recentWorkspaces = useRecentWorkspaces();
|
const recentWorkspaces = useRecentWorkspaces();
|
||||||
const requests = useRequests();
|
const requests = useRequests();
|
||||||
@@ -78,9 +83,19 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const r of sortedRequests.slice(0, 4)) {
|
for (const r of sortedRequests.slice(0, 4)) {
|
||||||
|
if (r.id === activeRequestId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
requestGroup.items.push({
|
requestGroup.items.push({
|
||||||
key: `switch-request-${r.id}`,
|
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: () => {
|
onSelect: () => {
|
||||||
return routes.navigate('request', {
|
return routes.navigate('request', {
|
||||||
workspaceId: r.workspaceId,
|
workspaceId: r.workspaceId,
|
||||||
@@ -98,6 +113,9 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const w of sortedWorkspaces.slice(0, 4)) {
|
for (const w of sortedWorkspaces.slice(0, 4)) {
|
||||||
|
if (w.id === activeWorkspaceId) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
workspaceGroup.items.push({
|
workspaceGroup.items.push({
|
||||||
key: `switch-workspace-${w.id}`,
|
key: `switch-workspace-${w.id}`,
|
||||||
label: w.name,
|
label: w.name,
|
||||||
@@ -106,13 +124,24 @@ export function CommandPalette({ onClose }: { onClose: () => void }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return [requestGroup, workspaceGroup];
|
return [requestGroup, workspaceGroup];
|
||||||
}, [activeEnvironmentId, openWorkspace, routes, sortedRequests, sortedWorkspaces]);
|
}, [
|
||||||
|
activeEnvironmentId,
|
||||||
|
activeRequestId,
|
||||||
|
activeWorkspaceId,
|
||||||
|
openWorkspace,
|
||||||
|
routes,
|
||||||
|
sortedRequests,
|
||||||
|
sortedWorkspaces,
|
||||||
|
]);
|
||||||
|
|
||||||
const filteredGroups = useMemo(
|
const filteredGroups = useMemo(
|
||||||
() =>
|
() =>
|
||||||
groups
|
groups
|
||||||
.map((g) => {
|
.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;
|
return g;
|
||||||
})
|
})
|
||||||
.filter((g) => g.items.length > 0),
|
.filter((g) => g.items.length > 0),
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export function RecentRequestsDropdown({ className }: Pick<ButtonProps, 'classNa
|
|||||||
key: request.id,
|
key: request.id,
|
||||||
label: fallbackRequestName(request),
|
label: fallbackRequestName(request),
|
||||||
// leftSlot: <CountBadge className="!ml-0 px-0 w-5" count={recentRequestItems.length} />,
|
// 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: () => {
|
onSelect: () => {
|
||||||
routes.navigate('request', {
|
routes.navigate('request', {
|
||||||
requestId: request.id,
|
requestId: request.id,
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import type { GrpcRequest, HttpRequest } from '../../lib/models';
|
|||||||
interface Props {
|
interface Props {
|
||||||
request: HttpRequest | GrpcRequest;
|
request: HttpRequest | GrpcRequest;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
shortNames?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const methodMap: Record<string, string> = {
|
const longMethodMap = {
|
||||||
get: 'GET',
|
get: 'GET',
|
||||||
put: 'PUT',
|
put: 'PUT',
|
||||||
post: 'POST',
|
post: 'POST',
|
||||||
@@ -15,9 +16,20 @@ const methodMap: Record<string, string> = {
|
|||||||
options: 'OPTIONS',
|
options: 'OPTIONS',
|
||||||
head: 'HEAD',
|
head: 'HEAD',
|
||||||
grpc: 'GRPC',
|
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 =
|
const method =
|
||||||
request.model === 'http_request' && request.bodyType === 'graphql'
|
request.model === 'http_request' && request.bodyType === 'graphql'
|
||||||
? 'GQL'
|
? 'GQL'
|
||||||
@@ -26,9 +38,17 @@ export function HttpMethodTag({ request, className }: Props) {
|
|||||||
: request.method;
|
: request.method;
|
||||||
|
|
||||||
const m = method.toLowerCase();
|
const m = method.toLowerCase();
|
||||||
|
const methodMap: Record<string, string> = shortNames ? shortMethodMap : longMethodMap;
|
||||||
return (
|
return (
|
||||||
<span className={classNames(className, 'text-xs font-mono text-fg-subtle')}>
|
<span
|
||||||
{methodMap[m] ?? m.slice(0, 3).toUpperCase()}
|
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>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user