From 64f9565ec9f7099883e1f19f5bba5cfe82f9b0ec Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Mon, 28 Jun 2021 22:10:40 -0400 Subject: [PATCH 1/2] refactor(table): explicitly mark accepted field table for grid view --- src/charts/grid.tsx | 33 ++++++++++++++++++--------------- src/utilities/types.ts | 4 +++- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/charts/grid.tsx b/src/charts/grid.tsx index 2c115fd..76c850c 100644 --- a/src/charts/grid.tsx +++ b/src/charts/grid.tsx @@ -18,7 +18,11 @@ const switchMode = (currentMode: string) => { type OnChangeProps = (input: number | string) => void; -type FilterIndexSignature = "integer" | "number" | "string"; +// Only some field types are filterable +// Iterate over a union type +// https://stackoverflow.com/a/59420158/5129731 +const filterableFields= ['integer' , 'number' , 'string'] as const; +type FilterIndexSignature = typeof filterableFields[number]; interface NumberFilterProps { onChange: OnChangeProps; @@ -147,6 +151,11 @@ interface Props { theme?: string; } +const filterableFieldSet = new Set(filterableFields); +function isFilterableFieldType (fieldType: any): fieldType is FilterIndexSignature { + return filterableFieldSet.has(fieldType); +} + class DataResourceTransformGrid extends React.PureComponent { static defaultProps = { metadata: {}, @@ -173,21 +182,13 @@ class DataResourceTransformGrid extends React.PureComponent { const { primaryKey = [] } = schema; const tableColumns = schema.fields.map((field: Dx.Field) => { - if ( - field.type === "string" || - field.type === "number" || - field.type === "integer" - ) { + if (isFilterableFieldType(field.type)) { return { Header: field.name, accessor: field.name, fixed: primaryKey.indexOf(field.name) !== -1 && "left", filterMethod: (filter: Dx.JSONObject, row: Dx.JSONObject) => { - if ( - field.type === "string" || - field.type === "number" || - field.type === "integer" - ) { + if (isFilterableFieldType(field.type)) { return filterMethod[field.type](filters[field.name])(filter, row); } }, @@ -197,17 +198,19 @@ class DataResourceTransformGrid extends React.PureComponent { field.name, (newFilter: { [key: string]: Function }) => { this.setState({ filters: { ...filters, ...newFilter } }); - } - ) + }, + ), }; } else { return { Header: field.name, id: field.name, accessor: (rowValue: { [key: string]: any }) => { - return field.type === "boolean" ? rowValue[field.name].toString() : rowValue[field.name] + return field.type === "boolean" + ? rowValue[field.name].toString() + : rowValue[field.name]; }, - fixed: primaryKey.indexOf(field.name) !== -1 && "left" + fixed: primaryKey.indexOf(field.name) !== -1 && "left", }; } }); diff --git a/src/utilities/types.ts b/src/utilities/types.ts index eb379f6..ff23855 100644 --- a/src/utilities/types.ts +++ b/src/utilities/types.ts @@ -78,7 +78,9 @@ export interface Schema { export const defaultPrimaryKey = "dx-default-pk"; export interface Field { name: string; - type: string; + // Types are based on the json-schema standard, with some variations + // https://specs.frictionlessdata.io/table-schema/#types-and-formats + type: 'string' | 'integer' | 'number' | 'boolean' | 'datetime' | string; // Other types are permitted, but not explicitly handled } From 4b3f41158921a38c4618d0ae53df16fdf97894d0 Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Mon, 28 Jun 2021 22:19:51 -0400 Subject: [PATCH 2/2] fix(table): Stringify non-primitive datatypes before display in react-table --- src/charts/grid.tsx | 12 ++++++++++-- src/utilities/types.ts | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/charts/grid.tsx b/src/charts/grid.tsx index 76c850c..8af7f97 100644 --- a/src/charts/grid.tsx +++ b/src/charts/grid.tsx @@ -21,6 +21,7 @@ type OnChangeProps = (input: number | string) => void; // Only some field types are filterable // Iterate over a union type // https://stackoverflow.com/a/59420158/5129731 +// Members come from values of Field.type const filterableFields= ['integer' , 'number' , 'string'] as const; type FilterIndexSignature = typeof filterableFields[number]; @@ -156,6 +157,13 @@ function isFilterableFieldType (fieldType: any): fieldType is FilterIndexSignatu return filterableFieldSet.has(fieldType); } +// Non-primitive field types cannot be outputted directly as React children +// Members come from possible values of Field.type +const shouldStringifyFieldSet = new Set([ + 'boolean', + 'object' +]) + class DataResourceTransformGrid extends React.PureComponent { static defaultProps = { metadata: {}, @@ -206,8 +214,8 @@ class DataResourceTransformGrid extends React.PureComponent { Header: field.name, id: field.name, accessor: (rowValue: { [key: string]: any }) => { - return field.type === "boolean" - ? rowValue[field.name].toString() + return shouldStringifyFieldSet.has(field.type) + ? JSON.stringify(rowValue[field.name]) : rowValue[field.name]; }, fixed: primaryKey.indexOf(field.name) !== -1 && "left", diff --git a/src/utilities/types.ts b/src/utilities/types.ts index ff23855..7445d62 100644 --- a/src/utilities/types.ts +++ b/src/utilities/types.ts @@ -80,7 +80,7 @@ export interface Field { name: string; // Types are based on the json-schema standard, with some variations // https://specs.frictionlessdata.io/table-schema/#types-and-formats - type: 'string' | 'integer' | 'number' | 'boolean' | 'datetime' | string; // Other types are permitted, but not explicitly handled + type: 'string' | 'integer' | 'number' | 'boolean' | 'datetime' | 'object' | string; // Other types are permitted, but not explicitly handled }