|
1 | | -'use client' |
2 | | - |
3 | | -import { useEffect, useRef } from 'react' |
4 | | -import { PillsRing } from '@sim/emcn' |
5 | | -import { getToolStatusDisplayTitle } from '@/lib/mothership/tools/tool-display' |
6 | | -import type { GenericResourceData } from '@/app/workspace/[workspaceId]/home/types' |
7 | | - |
8 | | -interface GenericResourceContentProps { |
9 | | - data: GenericResourceData |
10 | | -} |
11 | | - |
12 | | -// TODO: Emir — replace with rich UI (status icons, collapsible result cards, copy-to-clipboard, etc.) |
13 | | -export function GenericResourceContent({ data }: GenericResourceContentProps) { |
14 | | - const bottomRef = useRef<HTMLDivElement>(null) |
15 | | - |
16 | | - useEffect(() => { |
17 | | - const el = bottomRef.current |
18 | | - const container = el?.parentElement |
19 | | - if (container) { |
20 | | - container.scrollTop = container.scrollHeight |
21 | | - } |
22 | | - }, [data.entries.length]) |
23 | | - |
24 | | - if (data.entries.length === 0) { |
25 | | - return ( |
26 | | - <div className='flex h-full items-center justify-center'> |
27 | | - <p className='text-[var(--text-muted)] text-small'>No results yet</p> |
28 | | - </div> |
29 | | - ) |
30 | | - } |
31 | | - |
| 1 | +/** The panel for a `generic` resource, which carries no content of its own. */ |
| 2 | +export function GenericResourceContent() { |
32 | 3 | return ( |
33 | | - <div className='flex h-full flex-col divide-y divide-[var(--border)] overflow-y-auto [scrollbar-gutter:stable]'> |
34 | | - {data.entries.map((entry) => ( |
35 | | - <div key={entry.toolCallId} className='flex flex-col gap-2 px-4 py-3'> |
36 | | - <div className='flex items-center gap-2'> |
37 | | - {entry.status === 'executing' && ( |
38 | | - <PillsRing className='size-[14px] shrink-0 text-[var(--text-tertiary)]' animate /> |
39 | | - )} |
40 | | - <span className='text-[var(--text-primary)] text-small'> |
41 | | - {getToolStatusDisplayTitle(entry.displayTitle, entry.status, entry.toolName)} |
42 | | - </span> |
43 | | - {entry.status === 'error' && ( |
44 | | - <span className='ml-auto text-[var(--text-error)] text-caption'>Error</span> |
45 | | - )} |
46 | | - {entry.status === 'skipped' && ( |
47 | | - <span className='ml-auto text-[var(--text-muted)] text-caption'>Skipped</span> |
48 | | - )} |
49 | | - {entry.status === 'rejected' && ( |
50 | | - <span className='ml-auto text-[var(--text-muted)] text-caption'>Rejected</span> |
51 | | - )} |
52 | | - </div> |
53 | | - {entry.streamingArgs && ( |
54 | | - <pre className='overflow-x-auto whitespace-pre-wrap break-words font-mono text-[var(--text-body)] text-caption'> |
55 | | - {entry.streamingArgs} |
56 | | - </pre> |
57 | | - )} |
58 | | - {!entry.streamingArgs && entry.result?.output != null && ( |
59 | | - <pre className='overflow-x-auto whitespace-pre-wrap break-words font-mono text-[var(--text-body)] text-caption'> |
60 | | - {typeof entry.result.output === 'string' |
61 | | - ? entry.result.output |
62 | | - : JSON.stringify(entry.result.output, null, 2)} |
63 | | - </pre> |
64 | | - )} |
65 | | - {entry.result?.error && ( |
66 | | - <p className='text-[var(--text-error)] text-caption'>{entry.result.error}</p> |
67 | | - )} |
68 | | - </div> |
69 | | - ))} |
70 | | - <div ref={bottomRef} /> |
| 4 | + <div className='flex h-full items-center justify-center'> |
| 5 | + <p className='text-[var(--text-muted)] text-small'>No results yet</p> |
71 | 6 | </div> |
72 | 7 | ) |
73 | 8 | } |
0 commit comments