feat: FlatUiTable component API and docs improvements

This commit is contained in:
Demenech
2024-04-09 15:54:03 -03:00
parent 22038fbd4f
commit e6f0ab4ec8
2 changed files with 47 additions and 44 deletions

View File

@@ -2,6 +2,7 @@ import { QueryClient, QueryClientProvider, useQuery } from 'react-query';
import Papa from 'papaparse'; import Papa from 'papaparse';
import { Grid } from '@githubocto/flat-ui'; import { Grid } from '@githubocto/flat-ui';
import LoadingSpinner from './LoadingSpinner'; import LoadingSpinner from './LoadingSpinner';
import { Data } from '../types/properties';
const queryClient = new QueryClient(); const queryClient = new QueryClient();
@@ -36,30 +37,25 @@ export async function parseCsv(file: string, parsingConfig): Promise<any> {
} }
export interface FlatUiTableProps { export interface FlatUiTableProps {
url?: string; data: Data;
data?: { [key: string]: number | string }[]; uniqueId?: number;
rawCsv?: string;
randomId?: number;
bytes: number; bytes: number;
parsingConfig: any; parsingConfig: any;
} }
export const FlatUiTable: React.FC<FlatUiTableProps> = ({ export const FlatUiTable: React.FC<FlatUiTableProps> = ({
url,
data, data,
rawCsv, uniqueId,
bytes = 5132288, bytes = 5132288,
parsingConfig = {}, parsingConfig = {},
}) => { }) => {
const randomId = Math.random(); uniqueId = uniqueId ?? Math.random();
return ( return (
// Provide the client to your App // Provide the client to your App
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<TableInner <TableInner
bytes={bytes} bytes={bytes}
url={url}
data={data} data={data}
rawCsv={rawCsv} uniqueId={uniqueId}
randomId={randomId}
parsingConfig={parsingConfig} parsingConfig={parsingConfig}
/> />
</QueryClientProvider> </QueryClientProvider>
@@ -67,33 +63,32 @@ export const FlatUiTable: React.FC<FlatUiTableProps> = ({
}; };
const TableInner: React.FC<FlatUiTableProps> = ({ const TableInner: React.FC<FlatUiTableProps> = ({
url,
data, data,
rawCsv, uniqueId,
randomId,
bytes, bytes,
parsingConfig, parsingConfig,
}) => { }) => {
if (data) { const url = data.url;
const csv = data.csv;
const values = data.values;
if (values) {
return ( return (
<div className="w-full" style={{ height: '500px' }}> <div className="w-full" style={{ height: '500px' }}>
<Grid data={data} /> <Grid data={values} />
</div> </div>
); );
} }
const { data: csvString, isLoading: isDownloadingCSV } = useQuery( const { data: csvString, isLoading: isDownloadingCSV } = useQuery(
['dataCsv', url, randomId], ['dataCsv', url, uniqueId],
() => getCsv(url as string, bytes), () => getCsv(url as string, bytes),
{ enabled: !!url } { enabled: !!url }
); );
const { data: parsedData, isLoading: isParsing } = useQuery( const { data: parsedData, isLoading: isParsing } = useQuery(
['dataPreview', csvString, randomId], ['dataPreview', csvString, uniqueId],
() => () =>
parseCsv( parseCsv(csv ? (csv as string) : (csvString as string), parsingConfig),
rawCsv ? (rawCsv as string) : (csvString as string), { enabled: csv ? true : !!csvString }
parsingConfig
),
{ enabled: rawCsv ? true : !!csvString }
); );
if (isParsing || isDownloadingCSV) if (isParsing || isDownloadingCSV)
<div className="w-full flex justify-center items-center h-[500px]"> <div className="w-full flex justify-center items-center h-[500px]">

View File

@@ -10,23 +10,25 @@ const meta: Meta = {
argTypes: { argTypes: {
data: { data: {
description: description:
'Data to be displayed in the table, must be setup as an array of key value pairs', 'Data to be displayed. \n\n \
}, Must be an object with one of the following properties: `url`, `values` or `csv` \n\n \
csv: { `url`: URL pointing to a CSV file. \n\n \
description: 'CSV data as string.', `values`: array of objects. \n\n \
}, `csv`: string with valid CSV. \n\n \
url: { ',
description:
'Fetch the data from a CSV file remotely. only the first 5MB of data will be displayed',
}, },
bytes: { bytes: {
description: description:
'Fetch the data from a CSV file remotely. only the first <bytes> of data will be displayed', 'Fetch the data from a CSV file remotely. Only the first <bytes> of data will be displayed. Defaults to 5MB.',
}, },
parsingConfig: { parsingConfig: {
description: description:
'Configuration for parsing the CSV data. See https://www.papaparse.com/docs#config for more details', 'Configuration for parsing the CSV data. See https://www.papaparse.com/docs#config for more details',
}, },
uniqueId: {
description:
'Provide a unique ID to help with cache revalidation of the fetched data.',
},
}, },
}; };
@@ -36,34 +38,40 @@ type Story = StoryObj<FlatUiTableProps>;
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args // More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
export const FromColumnsAndData: Story = { export const FromColumnsAndData: Story = {
name: 'Table data', name: 'Table from array or objects',
args: { args: {
data: [ data: {
{ id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, values: [
{ id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 },
{ id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 },
{ id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 },
{ id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 },
{ id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 },
{ id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 },
], { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 },
],
},
}, },
}; };
export const FromRawCSV: Story = { export const FromRawCSV: Story = {
name: 'Table from raw CSV', name: 'Table from inline CSV',
args: { args: {
rawCsv: ` data: {
csv: `
Year,Temp Anomaly Year,Temp Anomaly
1850,-0.418 1850,-0.418
2020,0.923 2020,0.923
`, `,
},
}, },
}; };
export const FromURL: Story = { export const FromURL: Story = {
name: 'Table from URL', name: 'Table from URL',
args: { args: {
url: 'https://storage.openspending.org/alberta-budget/__os_imported__alberta_total.csv', data: {
url: 'https://storage.openspending.org/alberta-budget/__os_imported__alberta_total.csv',
},
}, },
}; };