From 4d20f2075fe288f1f0dbeeb40b038c440b328208 Mon Sep 17 00:00:00 2001 From: Julian Freeman Date: Mon, 1 Dec 2025 11:03:12 -0400 Subject: [PATCH] improve response panel --- spec/fix-response-panel.md | 59 ++++++++++++++++++++++++++++++++ src/App.vue | 49 +++++++++++++++++++++++--- src/components/ResponsePanel.vue | 48 ++++++++++++++++++++------ 3 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 spec/fix-response-panel.md diff --git a/spec/fix-response-panel.md b/spec/fix-response-panel.md new file mode 100644 index 0000000..49324d7 --- /dev/null +++ b/spec/fix-response-panel.md @@ -0,0 +1,59 @@ +# UI Improvement: Resizable Panels & Copy Action + +**Context:** +We are polishing the "Main Workspace" area of the LiteRequest application. +**Goal:** +1. Add a **"Copy Body" button** to the Response Panel for quick access to the result. +2. Make the vertical split between the **Request Panel** (top) and **Response Panel** (bottom) resizable by the user. + +## 1. Feature: Response Copy Button + +### 1.1 UI Changes +* **Location:** Inside the `ResponsePanel.vue`, in the **Meta Bar / Header** (the row displaying Status Code and Time), aligned to the right. +* **Icon:** Use the `Clipboard` icon from `lucide-vue-next`. +* **Interaction:** + * **Default:** Shows the `Clipboard` icon. + * **On Click:** Copies the content of the Response Body to the system clipboard. + * **Feedback:** After clicking, change the icon to `Check` (Checkmark) for 2 seconds to indicate success, then revert to `Clipboard`. +* **Style:** Small, ghost-style button (transparent background, changing color on hover). + +### 1.2 Logic Implementation +* Use the browser API: `navigator.clipboard.writeText(props.body)`. +* Use a local ref `isCopied` (boolean) to handle the icon toggle state. +* Use `setTimeout` to reset `isCopied` back to `false` after 2000ms. + +## 2. Feature: Resizable Split Pane + +### 2.1 UI Changes +* **Location:** The parent component that contains `` and `` (likely `App.vue` or `MainWorkspace.vue`). +* **Visuals:** Insert a **Resizer Handle** (a thin horizontal bar) between the two panels. + * *Height:* 4px - 6px. + * *Color:* `bg-slate-800` (hover: `bg-indigo-500`). + * *Cursor:* `cursor-row-resize`. + +### 2.2 Logic Implementation +* **State:** Use a `ref` for `topPanelHeight` (initially `50%` or `50vh`). +* **Drag Logic:** + 1. **`onMouseDown`** (on the Resizer): Set a `isDragging` flag to true. Add `mousemove` and `mouseup` event listeners to the `window` (global). + 2. **`onMouseMove`** (on Window): Calculate the new percentage or pixel height based on `e.clientY` relative to the window height. Update `topPanelHeight`. + 3. **`onMouseUp`** (on Window): Set `isDragging` to false. Remove the window event listeners. +* **Layout Application:** + * Apply `:style="{ height: topPanelHeight }"` to the **Request Panel** container. + * Apply `flex-1` (or calculated remaining height) to the **Response Panel** container. + * Ensure `min-height` is set (e.g., 200px) on both panels to prevent them from collapsing completely. + +## 3. Implementation Steps for AI + +Please generate the code updates in the following order: + +1. **ResponsePanel.vue:** + * Update the template to include the Copy Button in the header. + * Add the script logic for `copyToClipboard`. +2. **Main Layout (App.vue or similar):** + * Refactor the template to wrap RequestPanel and ResponsePanel in the resizable structure. + * Implement the `useDraggable` logic (or manual event handlers) in `