Skip to content

Commit

Permalink
fix(network): previews of datasets with JSON bodies now load
Browse files Browse the repository at this point in the history
issue here was making adjustments to body data structure (adding row numbers) was happening regardless of weather the body is JSON or CSV, which would crash some JSON data structures. The better solution is to decide weather a body is JSON or CSV as early as possible, delegating all details to format-specific components.
  • Loading branch information
b5 committed Feb 21, 2020
1 parent a5ec274 commit 57e7862
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 90 deletions.
81 changes: 81 additions & 0 deletions app/components/BodyTablePreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import React from 'react'

import Dataset, { Body } from '../models/dataset'
import { TypeLabel } from './TwoDSchemaLayout'

interface BodyPreviewProps {
data: Dataset
}

// BodyTablePreview is a lightweight version of BodyTable that we're hoping to
// merge into BodyTable in the near future
// TODO (b5) - merge BodyTablePreview functionality into BodyTable
const BodyTablePreview: React.FunctionComponent<BodyPreviewProps> = ({ data }) => {
const { body, structure } = data

if (!body) return null

const bdy = addRowNumbers(body)

const tableRows = bdy.map((row: any[], i: number) => {
return (
<tr key={i}>
{row.map((d: any, j: number) => {
const isFirstColumn = j === 0
if (isFirstColumn) d = parseInt(d) + 1
return (
<td key={j} className={isFirstColumn ? 'first-column' : ''}>
<div className='cell'>{typeof d === 'boolean' ? JSON.stringify(d) : d}</div>
</td>
)
})}
</tr>
)
})

let headers: Array<{ type: string, title: string}> = []
if (structure && structure.schema) {
structure.schema.items.items.forEach((column: { type: string, title: string}) => {
headers.push(column)
})
}

return (<div className='table-container'>
<table style={{ display: 'table' }}>
<thead>
<tr>
<th>
<div className='cell'>#</div>
</th>
{headers.length > 0 && headers.map((d: any, j: number) => {
return (
<th key={j} >
<div className='cell' >
<TypeLabel type={d.type} showLabel={false}/>&nbsp;{d.title}
</div>
</th>
)
})}
</tr>
</thead>
<tbody>
{tableRows}
</tbody>
</table>
</div>)
}

// adds row numbers to an array of arrays or object
const addRowNumbers = (body: Body): any[][] | any[] => {
if (!body) return body
if (Array.isArray(body)) {
return body.map((row: any[], i): any[] => { return [i, ...row] })
}

return Object.keys(body).map((key: string): Record<any, any> => ({
' ': key,
...body[key]
}))
}

export default BodyTablePreview
108 changes: 18 additions & 90 deletions app/components/dataset/BodySegment.tsx
Original file line number Diff line number Diff line change
@@ -1,93 +1,9 @@
import React from 'react'
// import numeral from 'numeral'

import Dataset, { Body } from '../../models/dataset'
import Dataset from '../../models/dataset'
import Segment from '../chrome/Segment'
import { TypeLabel } from '../TwoDSchemaLayout'
import BodyJson from '../BodyJson'

interface BodyPreviewProps {
data: Dataset
}

const BodyPreviewTable: React.FunctionComponent<BodyPreviewProps> = ({ data }) => {
const { body, structure } = data

if (!body) return null

const bdy = addRowNumbers(body)

let bodyPreview

if (!structure || (structure && structure.format !== 'csv')) {
bodyPreview =
<div id='json-preview-container'>
<BodyJson data={bdy} previewWarning={false}/>
</div>
} else {
const tableRows = bdy.map((row: any[], i: number) => {
return (
<tr key={i}>
{row.map((d: any, j: number) => {
const isFirstColumn = j === 0
if (isFirstColumn) d = parseInt(d) + 1
return (
<td key={j} className={isFirstColumn ? 'first-column' : ''}>
<div className='cell'>{typeof d === 'boolean' ? JSON.stringify(d) : d}</div>
</td>
)
})}
</tr>
)
})
let headers: Array<{ type: string, title: string}> = []
if (structure && structure.schema) {
structure.schema.items.items.forEach((column: { type: string, title: string}) => {
headers.push(column)
})
}

bodyPreview =
<div className='table-container'>
<table style={{ display: 'table' }}>
<thead>
<tr>
<th>
<div className='cell'>#</div>
</th>
{headers.length > 0 && headers.map((d: any, j: number) => {
return (
<th key={j} >
<div className='cell' >
<TypeLabel type={d.type} showLabel={false}/>&nbsp;{d.title}
</div>
</th>
)
})}
</tr>
</thead>
<tbody>
{tableRows}
</tbody>
</table>
</div>
}

return bodyPreview
}

// adds row numbers to an array of arrays or object
const addRowNumbers = (body: Body): any[][] | any[] => {
if (!body) return body
if (Array.isArray(body)) {
return body.map((row: any[], i): any[] => { return [i, ...row] })
}

return Object.keys(body).map((key: string): Record<any, any> => ({
' ': key,
...body[key]
}))
}
import BodyTablePreview from '../BodyTablePreview'

interface BodySegmentProps {
name?: string
Expand All @@ -96,22 +12,34 @@ interface BodySegmentProps {
}

const BodySegment: React.FunctionComponent<BodySegmentProps> = ({ data, collapsable }) => {
if (!data.body) {
const { body, structure } = data

if (!body) {
return null
}

let subhead = ''
let bodyComponent

if (structure) {
subhead = `previewing ${body.length} of ${structure.entries} rows`
}

if (data.structure) {
subhead = `previewing ${data.body.length} of ${data.structure.entries} rows`
if (!structure || (structure && structure.format !== 'csv')) {
bodyComponent =
<div id='json-preview-container'>
<BodyJson data={body} previewWarning={false}/>
</div>
} else {
bodyComponent = <BodyTablePreview data={data} />
}

return <Segment
icon='body'
name='body'
subhead={subhead}
collapsable={collapsable}
content={<BodyPreviewTable data={data} />}
content={bodyComponent}
/>
}

Expand Down

0 comments on commit 57e7862

Please sign in to comment.