diff --git a/src-web/components/Dropdown.tsx b/src-web/components/Dropdown.tsx
index 210eeae7..e07f375c 100644
--- a/src-web/components/Dropdown.tsx
+++ b/src-web/components/Dropdown.tsx
@@ -2,7 +2,16 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { DropdownMenuRadioGroup } from '@radix-ui/react-dropdown-menu';
import { motion } from 'framer-motion';
import { CheckIcon } from '@radix-ui/react-icons';
-import { forwardRef, HTMLAttributes, ReactNode } from 'react';
+import {
+ ForwardedRef,
+ forwardRef,
+ HTMLAttributes,
+ ReactNode,
+ useEffect,
+ useImperativeHandle,
+ useMemo,
+ useRef,
+} from 'react';
import classnames from 'classnames';
interface DropdownMenuRadioProps {
@@ -51,11 +60,15 @@ export function DropdownMenuRadio({
export interface DropdownProps {
children: ReactNode;
- items: {
- label: string;
- onSelect?: () => void;
- disabled?: boolean;
- }[];
+ items: (
+ | {
+ label: string;
+ onSelect?: () => void;
+ disabled?: boolean;
+ leftSlot?: ReactNode;
+ }
+ | '-----'
+ )[];
}
export function Dropdown({ children, items }: DropdownProps) {
@@ -64,11 +77,22 @@ export function Dropdown({ children, items }: DropdownProps) {
{children}
- {items.map((item, i) => (
- item.onSelect?.()} disabled={item.disabled}>
- {item.label}
-
- ))}
+ {items.map((item, i) => {
+ if (item === '-----') {
+ return ;
+ } else {
+ return (
+ item.onSelect?.()}
+ disabled={item.disabled}
+ leftSlot={item.leftSlot}
+ >
+ {item.label}
+
+ );
+ }
+ })}
@@ -94,13 +118,25 @@ function DropdownMenuPortal({ children }: DropdownMenuPortalProps) {
const DropdownMenuContent = forwardRef(
function DropdownMenuContent(
{ className, children, ...props }: DropdownMenu.DropdownMenuContentProps,
- ref,
+ ref: ForwardedRef,
) {
+ const divRef = useRef(null);
+ useImperativeHandle(ref, () => divRef.current);
+
+ // Calculate the max height so we can scroll
+ const styles = useMemo(() => {
+ if (divRef.current === null) return;
+ const windowBox = document.documentElement.getBoundingClientRect();
+ const menuBox = divRef.current.getBoundingClientRect();
+ return { maxHeight: windowBox.height - menuBox.top - 5 };
+ }, [divRef.current]);
+
return (
{children}
@@ -216,14 +252,14 @@ function DropdownMenuLabel({ className, children, ...props }: DropdownMenu.Dropd
);
}
-// function DropdownMenuSeparator({ className, ...props }: DropdownMenu.DropdownMenuSeparatorProps) {
-// return (
-//
-// );
-// }
+function DropdownMenuSeparator({ className, ...props }: DropdownMenu.DropdownMenuSeparatorProps) {
+ return (
+
+ );
+}
function DropdownMenuTrigger({
children,
diff --git a/src-web/components/Icon.tsx b/src-web/components/Icon.tsx
index ce2cbc1a..18838cc3 100644
--- a/src-web/components/Icon.tsx
+++ b/src-web/components/Icon.tsx
@@ -1,10 +1,12 @@
import {
ArchiveIcon,
CameraIcon,
+ CheckIcon,
GearIcon,
HomeIcon,
MoonIcon,
PaperPlaneIcon,
+ QuestionMarkIcon,
SunIcon,
TriangleDownIcon,
UpdateIcon,
@@ -20,6 +22,8 @@ type IconName =
| 'triangle-down'
| 'paper-plane'
| 'update'
+ | 'question'
+ | 'check'
| 'sun'
| 'moon';
@@ -28,11 +32,13 @@ const icons: Record> = {
'triangle-down': TriangleDownIcon,
archive: ArchiveIcon,
camera: CameraIcon,
+ check: CheckIcon,
gear: GearIcon,
home: HomeIcon,
update: UpdateIcon,
sun: SunIcon,
moon: MoonIcon,
+ question: QuestionMarkIcon,
};
export interface IconProps {
@@ -43,7 +49,7 @@ export interface IconProps {
}
export function Icon({ icon, spin, size = 'md', className }: IconProps) {
- const Component = icons[icon];
+ const Component = icons[icon] ?? icons.question;
return (
(null);
const responses = useResponses(requestId);
- const response = responses.data[0];
+ const response = activeResponseId
+ ? responses.data.find((r) => r.id === activeResponseId)
+ : responses.data[0];
const deleteResponse = useDeleteResponse(response);
const deleteAllResponses = useDeleteAllResponses(response?.requestId);
+ useEffect(() => {
+ setActiveResponseId(null);
+ }, [responses.data?.length]);
+
const contentType = useMemo(
() =>
response?.headers.find((h) => h.name.toLowerCase() === 'content-type')?.value ?? 'text/plain',
@@ -47,6 +55,12 @@ export function ResponsePane({ requestId, error }: Props) {
onSelect: deleteAllResponses.mutate,
disabled: responses.data.length === 0,
},
+ '-----',
+ ...responses.data.map((r) => ({
+ label: r.status + ' - ' + r.elapsed,
+ leftSlot: response?.id === r.id ? : <>>,
+ onSelect: () => setActiveResponseId(r.id),
+ })),
]}
>