CellDetailPanel.tsx72 lines · main
1import { useEffect, useState } from 'react'
2import remarkGfm from 'remark-gfm'
3import { Sheet, SheetContent, SheetHeader, SheetTitle } from 'ui'
4
5import { Markdown } from '@/components/interfaces/Markdown'
6import CodeEditor from '@/components/ui/CodeEditor/CodeEditor'
7import { TwoOptionToggle } from '@/components/ui/TwoOptionToggle'
8
9interface CellDetailPanelProps {
10 column: string
11 value: any
12 visible: boolean
13 onClose: () => void
14}
15
16export const CellDetailPanel = ({ column, value, visible, onClose }: CellDetailPanelProps) => {
17 const [view, setView] = useState<'view' | 'md'>('view')
18
19 const formattedValue =
20 value === null
21 ? ''
22 : typeof value === 'object'
23 ? JSON.stringify(value, null, '\t')
24 : String(value)
25 const showMarkdownToggle = typeof value === 'string'
26
27 useEffect(() => {
28 if (visible) setView('view')
29 }, [visible])
30
31 return (
32 <Sheet open={visible} onOpenChange={() => onClose()}>
33 <SheetContent size="lg" className="flex flex-col gap-0">
34 <SheetHeader className="py-2.5">
35 <SheetTitle className="flex items-center justify-between pr-7">
36 <p className="truncate">
37 Viewing cell details on column: <code className="text-sm">{column}</code>
38 </p>
39 {showMarkdownToggle && (
40 <TwoOptionToggle
41 options={['MD', 'view']}
42 activeOption={view}
43 borderOverride="border-muted"
44 onClickOption={(value) => setView(value as 'view' | 'md')}
45 />
46 )}
47 </SheetTitle>
48 </SheetHeader>
49 {view === 'view' ? (
50 <div className="relative h-full">
51 <CodeEditor
52 isReadOnly
53 id="sql-editor-expand-cell"
54 language="json"
55 value={formattedValue}
56 placeholder={value === null ? 'NULL' : undefined}
57 options={{ wordWrap: 'off', contextmenu: false }}
58 />
59 </div>
60 ) : (
61 <div className="grow py-4 px-4 bg-default overflow-y-auto">
62 <Markdown
63 remarkPlugins={[remarkGfm]}
64 className="max-w-full! markdown-body"
65 content={formattedValue}
66 />
67 </div>
68 )}
69 </SheetContent>
70 </Sheet>
71 )
72}