1- import { DataFrame , stringify } from 'hightable'
2- import { ReactNode , useEffect , useState } from 'react'
1+ import type { DataFrame , ResolvedValue } from 'hightable'
2+ import { stringify } from 'hightable'
3+ import { ReactNode , useCallback , useEffect , useState } from 'react'
34import { useConfig } from '../../hooks/useConfig.js'
45import { cn } from '../../lib/utils.js'
56import ContentWrapper from '../ContentWrapper/ContentWrapper.js'
67import Json from '../Json/Json.js'
8+ import jsonStyles from '../Json/Json.module.css'
79import SlideCloseButton from '../SlideCloseButton/SlideCloseButton.js'
810import styles from '../TextView/TextView.module.css'
9- import jsonStyles from '../Json/Json.module.css'
1011
1112interface ViewerProps {
1213 df : DataFrame
1314 row : number
1415 col : number
1516 setProgress : ( progress : number ) => void
16- setError : ( error : Error ) => void
17+ setError : ( error : unknown ) => void
1718 onClose : ( ) => void
1819}
1920
21+ const UNLOADED_CELL_PLACEHOLDER = '<the content has not been fetched yet>'
22+
2023/**
2124 * Cell viewer displays a single cell from a table.
2225 */
2326export default function CellPanel ( { df, row, col, setProgress, setError, onClose } : ViewerProps ) {
2427 const [ content , setContent ] = useState < ReactNode > ( )
2528 const { customClass } = useConfig ( )
2629
30+ const fillContent = useCallback ( ( cell : ResolvedValue < unknown > | undefined ) => {
31+ let content : ReactNode
32+ if ( cell === undefined ) {
33+ content =
34+ < code className = { cn ( jsonStyles . textView , customClass ?. textView ) } >
35+ { UNLOADED_CELL_PLACEHOLDER }
36+ </ code >
37+ } else {
38+ const { value } = cell
39+ if ( value instanceof Object && ! ( value instanceof Date ) ) {
40+ content =
41+ < code className = { cn ( jsonStyles . jsonView , customClass ?. jsonView ) } >
42+ < Json json = { value } />
43+ </ code >
44+ } else {
45+ content =
46+ < code className = { cn ( styles . textView , customClass ?. textView ) } >
47+ { stringify ( value ) }
48+ </ code >
49+ }
50+ }
51+ setContent ( content )
52+ setError ( undefined )
53+ } , [ customClass ?. textView , customClass ?. jsonView , setError ] )
54+
2755 // Load cell data
2856 useEffect ( ( ) => {
2957 async function loadCellData ( ) {
3058 try {
3159 setProgress ( 0.5 )
32- const asyncRows = df . rows ( { start : row , end : row + 1 } )
33- if ( asyncRows . length > 1 || ! ( 0 in asyncRows ) ) {
34- throw new Error ( `Expected 1 row, got ${ asyncRows . length } ` )
35- }
36- const asyncRow = asyncRows [ 0 ]
37- // Await cell data
60+
3861 const columnName = df . header [ col ]
3962 if ( columnName === undefined ) {
4063 throw new Error ( `Column name missing at index col=${ col } ` )
4164 }
42- const asyncCell = asyncRow . cells [ columnName ]
43- if ( asyncCell === undefined ) {
44- throw new Error ( `Cell missing at column ${ columnName } ` )
65+ let cell = df . getCell ( { row, column : columnName } )
66+ if ( cell === undefined ) {
67+ fillContent ( undefined )
68+ return
4569 }
46- const value : unknown = await asyncCell
47- if ( value instanceof Object && ! ( value instanceof Date ) ) {
48- setContent (
49- < code className = { cn ( jsonStyles . jsonView , customClass ?. jsonView ) } >
50- < Json json = { value } />
51- </ code >
52- )
53- } else {
54- setContent (
55- < code className = { cn ( styles . textView , customClass ?. textView ) } >
56- { stringify ( value ) }
57- </ code >
58- )
70+ await df . fetch ( { rowStart : row , rowEnd : row + 1 , columns : [ columnName ] } )
71+ cell = df . getCell ( { row, column : columnName } )
72+ if ( cell === undefined ) {
73+ throw new Error ( `Cell at row=${ row } , column=${ columnName } is undefined` )
5974 }
75+ fillContent ( cell )
6076 } catch ( error ) {
6177 setError ( error as Error )
6278 } finally {
@@ -65,7 +81,7 @@ export default function CellPanel({ df, row, col, setProgress, setError, onClose
6581 }
6682
6783 void loadCellData ( )
68- } , [ df , col , row , setProgress , setError , customClass ] )
84+ } , [ df , col , row , setProgress , setError , fillContent ] )
6985
7086 const headers = < >
7187 < SlideCloseButton onClick = { onClose } />
0 commit comments