diff --git a/src/app/components/ThreadList.tsx b/src/app/components/ThreadList.tsx index 21962f5..d5d88d2 100644 --- a/src/app/components/ThreadList.tsx +++ b/src/app/components/ThreadList.tsx @@ -173,7 +173,6 @@ export function ThreadList({ const [renameValue, setRenameValue] = useState(""); const [deleteTarget, setDeleteTarget] = useState(null); const [actionBusy, setActionBusy] = useState(false); - const isResearchView = view !== "skills" && view !== "memory"; const threads = useThreads({ status: statusFilter === "all" ? undefined : statusFilter, @@ -345,6 +344,11 @@ export function ThreadList({ - {isResearchView && ( -
-
-
-
- )} - {isResearchView ? ( -
-

Research

-
- - {onClose && ( - - )} -
-
- ) : onClose ? ( - - ) : null} - - {isResearchView ? ( - - {threads.error && } - - {!threads.error && !threads.data && threads.isLoading && ( - + setSearch(e.target.value)} + placeholder="Search research…" + aria-label="Search research" + autoComplete="off" + spellCheck={false} + className="w-full rounded-md border border-border bg-background py-1.5 pl-8 pr-8 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring" + /> + {search && ( + )} + + +
+

Research

+
+ + {onClose && ( + + )} +
+
- {!threads.error && !threads.isLoading && isEmpty && } + + {threads.error && } - {!threads.error && - !isEmpty && - search.trim() && - filtered.length === 0 && ( -
-

- No research matches your search. -

-
- )} + {!threads.error && !threads.data && threads.isLoading && ( + + )} - {!threads.error && !isEmpty && filtered.length > 0 && ( -
- {( - Object.keys(GROUP_LABELS) as Array - ).map((group) => { - const groupThreads = grouped[group]; - if (groupThreads.length === 0) return null; + {!threads.error && !threads.isLoading && isEmpty && } - return ( -
-

- {GROUP_LABELS[group]} -

-
- {groupThreads.map((thread) => ( -
- {/* Selectable row — a native button so Enter/Space and - role come for free. Action buttons are SIBLINGS (below), - never nested inside this button. */} - - {/* Per-thread actions — siblings of the select button (not - nested); shown on touch, reveal on hover/focus on desktop. */} -
- - -
-
- ))} -
-
- ); - })} - - {!isReachingEnd && ( -
- -
- )} + {!threads.error && + !isEmpty && + search.trim() && + filtered.length === 0 && ( +
+

+ No research matches your search. +

)} - - ) : ( -
- Use the navigation above to switch views, or start a new chat to - return to research history. -
- )} + + {!threads.error && !isEmpty && filtered.length > 0 && ( +
+ {( + Object.keys(GROUP_LABELS) as Array + ).map((group) => { + const groupThreads = grouped[group]; + if (groupThreads.length === 0) return null; + + return ( +
+

+ {GROUP_LABELS[group]} +

+
+ {groupThreads.map((thread) => ( +
+ {/* Selectable row — a native button so Enter/Space and + role come for free. Action buttons are SIBLINGS (below), + never nested inside this button. */} + + {/* Per-thread actions — siblings of the select button (not + nested); shown on touch, reveal on hover/focus on desktop. */} +
+ + +
+
+ ))} +
+
+ ); + })} + + {!isReachingEnd && ( +
+ +
+ )} +
+ )} + {/* Rename dialog */}