({
sessions,
activeSessionId,
session,
replayTargetId,
replaySettings,
streaming,
onRefreshSessions,
onSelectSession,
onNewChat,
onReplayTarget,
onReplaySettingsChange,
onReplay,
onStopReplay,
}: SessionSidebarProps)
| 36 | } |
| 37 | |
| 38 | export function SessionSidebar({ |
| 39 | sessions, |
| 40 | activeSessionId, |
| 41 | session, |
| 42 | replayTargetId, |
| 43 | replaySettings, |
| 44 | streaming, |
| 45 | onRefreshSessions, |
| 46 | onSelectSession, |
| 47 | onNewChat, |
| 48 | onReplayTarget, |
| 49 | onReplaySettingsChange, |
| 50 | onReplay, |
| 51 | onStopReplay, |
| 52 | }: SessionSidebarProps) { |
| 53 | const turns = assistantTurns(session.messages); |
| 54 | const canReplay = Boolean(replayTargetId) && !streaming; |
| 55 | |
| 56 | return ( |
| 57 | <aside className="chat-sidebar"> |
| 58 | <div className="chat-sidebar-hdr"> |
| 59 | <span className="chat-sidebar-title">Sessions</span> |
| 60 | <div className="chat-sidebar-hdr-actions"> |
| 61 | <button type="button" onClick={onRefreshSessions} disabled={streaming}> |
| 62 | ↻ |
| 63 | </button> |
| 64 | <button type="button" onClick={onNewChat} disabled={streaming}> |
| 65 | + |
| 66 | </button> |
| 67 | </div> |
| 68 | </div> |
| 69 | |
| 70 | <div className="chat-session-list"> |
| 71 | {sessions.length === 0 && ( |
| 72 | <div className="chat-session-empty">No saved sessions yet.</div> |
| 73 | )} |
| 74 | {sessions.map((s) => ( |
| 75 | <button |
| 76 | key={s.id} |
| 77 | type="button" |
| 78 | className={`chat-session-item${s.id === activeSessionId ? " chat-session-item-active" : ""}`} |
| 79 | onClick={() => onSelectSession(s.id)} |
| 80 | disabled={streaming} |
| 81 | title={s.preview} |
| 82 | > |
| 83 | <span className="chat-session-item-id">{s.id.slice(5, 14)}</span> |
| 84 | <span className="chat-session-item-preview">{s.preview}</span> |
| 85 | <span className="chat-session-item-meta"> |
| 86 | {formatSessionWhen(s.updatedAt)} · {s.messageCount} msgs |
| 87 | </span> |
| 88 | </button> |
| 89 | ))} |
| 90 | </div> |
| 91 | |
| 92 | <div className="chat-replay-panel"> |
| 93 | <div className="chat-replay-title">Stream replay</div> |
| 94 | <p className="chat-replay-hint"> |
| 95 | Re-stream a saved assistant reply through HtmlStream. |
nothing calls this directly
no test coverage detected