From 37179096b06968e49a19d169747cd7cfd2dd6b7d Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Sun, 29 Mar 2026 17:47:58 -0400 Subject: [PATCH] =?UTF-8?q?refactor:=20assistant=20page=20=E2=80=94=20Task?= =?UTF-8?q?Lane=20UX=20+=20ChatSidebar=20improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TaskLane: - Simplify action buttons: merge "Paste Result"/"Type Answer" into single primary button, make "Skip" icon-only (reduces decision points from 3→1) - Strengthen done state: solid left-border success green + checkmark icon instead of faint tint that nearly disappears - Boost progress bar: 3px→5px, better contrast colors, inline count label - Differentiate from ChatSidebar: use bg-page instead of bg-sidebar, add accent top-border to signal "active workspace" - Make skipped tasks clickable to un-skip (matching done→reopen pattern) - Fix slide-in animation: add slide-in-from-right keyframe - Fix duplicate style props, stray quote from replace_all - Consolidate 6 grip dot divs to Array.from loop ChatSidebar: - Add inline delete confirmation ("Delete? Yes / No") instead of immediate destructive action - Fix text-xs text-[0.625rem] double class conflict on Pinned header Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/components/assistant/ChatSidebar.tsx | 75 ++++++++++----- .../src/components/assistant/TaskLane.tsx | 93 ++++++++++--------- frontend/src/index.css | 4 + 3 files changed, 102 insertions(+), 70 deletions(-) diff --git a/frontend/src/components/assistant/ChatSidebar.tsx b/frontend/src/components/assistant/ChatSidebar.tsx index 133f0a60..bea51f18 100644 --- a/frontend/src/components/assistant/ChatSidebar.tsx +++ b/frontend/src/components/assistant/ChatSidebar.tsx @@ -1,3 +1,4 @@ +import { useState } from 'react' import { Plus, Pin, Trash2, MessageSquare, History, X } from 'lucide-react' import { cn } from '@/lib/utils' import type { ChatListItem } from '@/types/assistant-chat' @@ -84,7 +85,7 @@ export function ChatSidebar({
{pinnedChats.length > 0 && (
- + Pinned
@@ -184,39 +185,65 @@ function ChatItem({ onDelete: () => void onTogglePin: () => void }) { + const [confirming, setConfirming] = useState(false) + return (
-
{chat.title}
-
- {chat.message_count} messages + {confirming ? ( +
+ Delete? + + +
+ ) : ( + <> +
{chat.title}
+
+ {chat.message_count} messages +
+ + )} +
+ {!confirming && ( +
+ +
-
-
- - -
+ )}
) } diff --git a/frontend/src/components/assistant/TaskLane.tsx b/frontend/src/components/assistant/TaskLane.tsx index 7a6a5850..590f34b3 100644 --- a/frontend/src/components/assistant/TaskLane.tsx +++ b/frontend/src/components/assistant/TaskLane.tsx @@ -225,8 +225,8 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa return (
{/* Resize grip handle */}
-
-
-
-
-
-
+ {Array.from({ length: 6 }).map((_, i) => ( +
+ ))}
{/* Header */} -
+

Tasks 0 && (
-
+
Questions @@ -282,16 +279,19 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa if (q.state === 'done') { return ( -
updateTask(idx, { state: 'active' })}> -
{q.text}
-
"{q.value}"
+
updateTask(idx, { state: 'active' })}> +
+ + {q.text} +
+
"{q.value}"
) } if (q.state === 'skipped') { return ( -
+
updateTask(idx, { state: 'pending' })} title="Click to restore">
{q.text}
Skipped @@ -342,9 +342,10 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
)} @@ -357,7 +358,7 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa {/* ── Checks Section ── */} {actionTasks.length > 0 && (
-
+
Diagnostic Checks @@ -401,10 +402,10 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa if (a.state === 'done') { return ( -
updateTask(idx, { state: 'active' })}> -
-
{a.label}
- ✓ Done +
updateTask(idx, { state: 'active' })}> +
+ + {a.label}
) @@ -412,7 +413,7 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa if (a.state === 'skipped') { return ( -
+
updateTask(idx, { state: 'pending' })} title="Click to restore">
{a.label}
Skipped @@ -464,24 +465,19 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
) : ( -
+
-
)} @@ -495,19 +491,24 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa {/* Footer */}
{/* Progress bar */} -
- {tasks.map((t, i) => ( -
- ))} +
+
+ {tasks.map((t, i) => ( +
+ ))} +
+ + {handledCount}/{totalCount} +
{/* Collapsible preview */} {anyHandled && ( diff --git a/frontend/src/index.css b/frontend/src/index.css index 2fb1f923..8405b22f 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -82,6 +82,7 @@ --animate-fade-in: fade-in 200ms ease-out both; --animate-fade-in-up: fade-in-up 200ms ease-out both; --animate-slide-in-left: slide-in-from-left 200ms ease-out; + --animate-slide-in-right: slide-in-from-right 200ms ease-out both; --animate-slide-in-bottom: slide-in-from-bottom 200ms ease-out both; --animate-scale-in: scale-in 150ms ease-out both; --animate-fade: fadeIn 300ms ease both; @@ -95,6 +96,9 @@ @keyframes slide-in-from-left { from { transform: translateX(-100%); } to { transform: translateX(0); } } + @keyframes slide-in-from-right { + from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: translateX(0); } + } @keyframes slide-in-from-bottom { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } }