mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-25 02:41:21 +01:00
Add .oxfmtignore to skip generated bindings and wasm-pack output. Add npm format script, update DEVELOPMENT.md for Vite+ toolchain, and format all non-generated files with oxfmt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
3.2 KiB
TypeScript
90 lines
3.2 KiB
TypeScript
import type { HttpResponse } from "@yaakapp-internal/models";
|
|
import { deleteModel } from "@yaakapp-internal/models";
|
|
import { useCopyHttpResponse } from "../hooks/useCopyHttpResponse";
|
|
import { useDeleteHttpResponses } from "../hooks/useDeleteHttpResponses";
|
|
import { useSaveResponse } from "../hooks/useSaveResponse";
|
|
import { pluralize } from "../lib/pluralize";
|
|
import { Dropdown } from "./core/Dropdown";
|
|
import { HttpStatusTag } from "./core/HttpStatusTag";
|
|
import { Icon } from "./core/Icon";
|
|
import { IconButton } from "./core/IconButton";
|
|
import { HStack } from "./core/Stacks";
|
|
|
|
interface Props {
|
|
responses: HttpResponse[];
|
|
activeResponse: HttpResponse;
|
|
onPinnedResponseId: (id: string) => void;
|
|
className?: string;
|
|
}
|
|
|
|
export const RecentHttpResponsesDropdown = function ResponsePane({
|
|
activeResponse,
|
|
responses,
|
|
onPinnedResponseId,
|
|
}: Props) {
|
|
const deleteAllResponses = useDeleteHttpResponses(activeResponse?.requestId);
|
|
const latestResponseId = responses[0]?.id ?? "n/a";
|
|
const saveResponse = useSaveResponse(activeResponse);
|
|
const copyResponse = useCopyHttpResponse(activeResponse);
|
|
|
|
return (
|
|
<Dropdown
|
|
items={[
|
|
{
|
|
label: "Save to File",
|
|
onSelect: saveResponse.mutate,
|
|
leftSlot: <Icon icon="save" />,
|
|
hidden: responses.length === 0 || !!activeResponse.error,
|
|
disabled: activeResponse.state !== "closed" && activeResponse.status >= 100,
|
|
},
|
|
{
|
|
label: "Copy Body",
|
|
onSelect: copyResponse.mutate,
|
|
leftSlot: <Icon icon="copy" />,
|
|
hidden: responses.length === 0 || !!activeResponse.error,
|
|
disabled: activeResponse.state !== "closed" && activeResponse.status >= 100,
|
|
},
|
|
{
|
|
label: "Delete",
|
|
leftSlot: <Icon icon="trash" />,
|
|
onSelect: () => deleteModel(activeResponse),
|
|
},
|
|
{
|
|
label: "Unpin Response",
|
|
onSelect: () => onPinnedResponseId(activeResponse.id),
|
|
leftSlot: <Icon icon="unpin" />,
|
|
hidden: latestResponseId === activeResponse.id,
|
|
disabled: responses.length === 0,
|
|
},
|
|
{ type: "separator", label: "History" },
|
|
{
|
|
label: `Delete ${responses.length} ${pluralize("Response", responses.length)}`,
|
|
onSelect: deleteAllResponses.mutate,
|
|
hidden: responses.length === 0,
|
|
disabled: responses.length === 0,
|
|
},
|
|
{ type: "separator" },
|
|
...responses.map((r: HttpResponse) => ({
|
|
label: (
|
|
<HStack space={2}>
|
|
<HttpStatusTag short className="text-xs" response={r} />
|
|
<span className="text-text-subtle">→</span>{" "}
|
|
<span className="font-mono text-sm">{r.elapsed >= 0 ? `${r.elapsed}ms` : "n/a"}</span>
|
|
</HStack>
|
|
),
|
|
leftSlot: activeResponse?.id === r.id ? <Icon icon="check" /> : <Icon icon="empty" />,
|
|
onSelect: () => onPinnedResponseId(r.id),
|
|
})),
|
|
]}
|
|
>
|
|
<IconButton
|
|
title="Show response history"
|
|
icon={activeResponse?.id === latestResponseId ? "history" : "pin"}
|
|
className="m-0.5 text-text-subtle"
|
|
size="sm"
|
|
iconSize="md"
|
|
/>
|
|
</Dropdown>
|
|
);
|
|
};
|