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) {