diff --git a/apps/yaak-client/components/CurlViewer.tsx b/apps/yaak-client/components/CurlViewer.tsx
new file mode 100644
index 000000000..9c6e9d615
--- /dev/null
+++ b/apps/yaak-client/components/CurlViewer.tsx
@@ -0,0 +1,54 @@
+import { useQuery } from "@tanstack/react-query";
+import type { HttpRequest } from "@yaakapp-internal/models";
+import type { CSSProperties } from "react";
+import { requestToCurl } from "../lib/curl";
+import { CopyIconButton } from "./CopyIconButton";
+import { Editor } from "./core/Editor/LazyEditor";
+
+interface Props {
+ request: HttpRequest;
+ style?: CSSProperties;
+}
+
+export function CurlViewer({ request, style }: Props) {
+ const curl = useQuery({
+ queryKey: ["request_curl", request.id, request.updatedAt],
+ queryFn: () => requestToCurl(request, "send"),
+ });
+
+ const value = curl.data ?? "";
+
+ return (
+
+ {curl.isError ? (
+
Failed to render curl command.
+ ) : (
+ <>
+
+
+
+
+
+
+ >
+ )}
+
+ );
+}
diff --git a/apps/yaak-client/components/HttpRequestLayout.tsx b/apps/yaak-client/components/HttpRequestLayout.tsx
index 2ee1233d7..1a41b3bdc 100644
--- a/apps/yaak-client/components/HttpRequestLayout.tsx
+++ b/apps/yaak-client/components/HttpRequestLayout.tsx
@@ -3,10 +3,12 @@ import type { SlotProps } from "@yaakapp-internal/ui";
import { SplitLayout } from "@yaakapp-internal/ui";
import classNames from "classnames";
import { useAtomValue } from "jotai";
-import type { CSSProperties } from "react";
+import type { CSSProperties, ReactNode } from "react";
import { useCurrentGraphQLSchema } from "../hooks/useIntrospectGraphQL";
import { activeWorkspaceAtom } from "../hooks/useActiveWorkspace";
import { workspaceLayoutAtom } from "../lib/atoms";
+import { curlPanelRequestIdAtom } from "../lib/curlPanel";
+import { CurlViewer } from "./CurlViewer";
import { GraphQLDocsExplorer } from "./graphql/GraphQLDocsExplorer";
import { showGraphQLDocExplorerAtom } from "./graphql/graphqlAtoms";
import { HttpRequestPane } from "./HttpRequestPane";
@@ -22,7 +24,9 @@ export function HttpRequestLayout({ activeRequest, style }: Props) {
const graphQLSchema = useCurrentGraphQLSchema(activeRequest);
const workspaceLayout = useAtomValue(workspaceLayoutAtom);
const activeWorkspace = useAtomValue(activeWorkspaceAtom);
+ const curlPanelRequestId = useAtomValue(curlPanelRequestIdAtom);
const wsId = activeWorkspace?.id ?? "n/a";
+ const showCurlPanelForRequest = curlPanelRequestId === activeRequest.id;
const requestResponseSplit = ({ style }: Pick) => (
(
- (
+ (
+
+ )}
/>
)}
/>
);
}
- return requestResponseSplit({ style });
+ return (
+
+ );
+}
+
+function CurlSplit({
+ activeRequest,
+ mainSlot,
+ showCurlPanel,
+ style,
+ workspaceId,
+}: {
+ activeRequest: HttpRequest;
+ mainSlot: (props: Pick) => ReactNode;
+ showCurlPanel: boolean;
+ style: CSSProperties;
+ workspaceId: string;
+}) {
+ if (!showCurlPanel) {
+ return mainSlot({ style });
+ }
+
+ return (
+ (
+
+
+
+ )}
+ />
+ );
}
diff --git a/apps/yaak-client/components/RecentRequestsDropdown.tsx b/apps/yaak-client/components/RecentRequestsDropdown.tsx
index 12b150ef8..8efd114ac 100644
--- a/apps/yaak-client/components/RecentRequestsDropdown.tsx
+++ b/apps/yaak-client/components/RecentRequestsDropdown.tsx
@@ -1,5 +1,6 @@
import classNames from "classnames";
-import { useMemo, useRef } from "react";
+import type { MouseEvent } from "react";
+import { useCallback, useMemo, useRef } from "react";
import { useActiveRequest } from "../hooks/useActiveRequest";
import { activeWorkspaceIdAtom } from "../hooks/useActiveWorkspace";
import { allRequestsAtom } from "../hooks/useAllRequests";
@@ -7,6 +8,7 @@ import { useHotKey } from "../hooks/useHotKey";
import { useKeyboardEvent } from "../hooks/useKeyboardEvent";
import { useRecentRequests } from "../hooks/useRecentRequests";
import { jotaiStore } from "../lib/jotai";
+import { renameModelWithPrompt } from "../lib/renameModelWithPrompt";
import { resolvedModelName } from "../lib/resolvedModelName";
import { router } from "../lib/router";
import { Button } from "./core/Button";
@@ -46,6 +48,18 @@ export function RecentRequestsDropdown({ className }: Props) {
dropdownRef.current?.prev?.();
});
+ const handleDoubleClick = useCallback(
+ (e: MouseEvent) => {
+ e.preventDefault();
+ e.stopPropagation();
+ if (activeRequest == null) return;
+
+ dropdownRef.current?.close?.();
+ void renameModelWithPrompt(activeRequest);
+ },
+ [activeRequest],
+ );
+
const items = useMemo(() => {
const activeWorkspaceId = jotaiStore.get(activeWorkspaceIdAtom);
if (activeWorkspaceId === null) return [];
@@ -88,6 +102,7 @@ export function RecentRequestsDropdown({ className }: Props) {