Merge pull request #456 from akinshaywai/design/history-ui-improvements

design(ui): improve HistoryList loading/empty states and add button tooltips
This commit is contained in:
Simon
2026-04-16 16:02:16 +08:00
committed by GitHub
2 changed files with 45 additions and 8 deletions

View File

@@ -1,4 +1,12 @@
import { ArrowDownToLine, ArrowLeft, CheckCircle, RotateCcw, Trash2, XCircle } from 'lucide-react' import {
ArrowDownToLine,
ArrowLeft,
CheckCircle,
History,
RotateCcw,
Trash2,
XCircle,
} from 'lucide-react'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState } from 'react'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
@@ -29,8 +37,13 @@ export function HistoryList({
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const load = useCallback(async () => { const load = useCallback(async () => {
try {
setSessions(await listSessions()) setSessions(await listSessions())
} catch (err) {
console.error('[HistoryList] Failed to load sessions:', err)
} finally {
setLoading(false) setLoading(false)
}
}, []) }, [])
useEffect(() => { useEffect(() => {
@@ -57,7 +70,14 @@ export function HistoryList({
<div className="flex flex-col h-screen bg-background"> <div className="flex flex-col h-screen bg-background">
{/* Header */} {/* Header */}
<header className="flex items-center gap-2 border-b px-3 py-2"> <header className="flex items-center gap-2 border-b px-3 py-2">
<Button variant="ghost" size="icon-sm" onClick={onBack} className="cursor-pointer"> <Button
variant="ghost"
size="icon-sm"
onClick={onBack}
className="cursor-pointer"
aria-label="Back"
title="Back"
>
<ArrowLeft className="size-3.5" /> <ArrowLeft className="size-3.5" />
</Button> </Button>
<span className="text-sm font-medium flex-1">History</span> <span className="text-sm font-medium flex-1">History</span>
@@ -80,14 +100,23 @@ export function HistoryList({
{/* List */} {/* List */}
<div className="flex-1 overflow-y-auto"> <div className="flex-1 overflow-y-auto">
{loading && ( {loading && (
<div className="flex items-center justify-center h-32 text-xs text-muted-foreground"> <div className="flex flex-col" aria-label="Loading history" aria-busy="true">
Loading... {[...Array(4)].map((_, i) => (
<div key={i} className="flex items-start gap-2 px-3 py-2.5 border-b">
<div className="size-3.5 mt-0.5 rounded-full bg-muted animate-pulse shrink-0" />
<div className="flex-1 space-y-1.5">
<div className="h-2.5 bg-muted animate-pulse rounded w-3/4" />
<div className="h-2 bg-muted animate-pulse rounded w-1/3" />
</div>
</div>
))}
</div> </div>
)} )}
{!loading && sessions.length === 0 && ( {!loading && sessions.length === 0 && (
<div className="flex items-center justify-center h-32 text-xs text-muted-foreground"> <div className="flex flex-col items-center justify-center h-40 gap-2 text-muted-foreground">
No history yet <History className="size-8 opacity-30" />
<p className="text-xs">No history yet</p>
</div> </div>
)} )}

View File

@@ -147,6 +147,8 @@ export default function App() {
size="icon-sm" size="icon-sm"
onClick={() => setView({ name: 'history' })} onClick={() => setView({ name: 'history' })}
className="cursor-pointer" className="cursor-pointer"
aria-label="History"
title="History"
> >
<History className="size-3.5" /> <History className="size-3.5" />
</Button> </Button>
@@ -155,6 +157,8 @@ export default function App() {
size="icon-sm" size="icon-sm"
onClick={() => setView({ name: 'config' })} onClick={() => setView({ name: 'config' })}
className="cursor-pointer" className="cursor-pointer"
aria-label="Settings"
title="Settings"
> >
<Settings className="size-3.5" /> <Settings className="size-3.5" />
</Button> </Button>
@@ -205,6 +209,8 @@ export default function App() {
variant="destructive" variant="destructive"
onClick={handleStop} onClick={handleStop}
className="size-7" className="size-7"
aria-label="Stop task"
title="Stop task"
> >
<Square className="size-3" /> <Square className="size-3" />
</InputGroupButton> </InputGroupButton>
@@ -215,6 +221,8 @@ export default function App() {
onClick={() => handleSubmit()} onClick={() => handleSubmit()}
disabled={!inputValue.trim()} disabled={!inputValue.trim()}
className="size-7 cursor-pointer" className="size-7 cursor-pointer"
aria-label="Send"
title="Send"
> >
<Send className="size-3" /> <Send className="size-3" />
</InputGroupButton> </InputGroupButton>