From e63c4004bc14445c1387d9d20ad3316f47aee717 Mon Sep 17 00:00:00 2001 From: Dave Bauman Date: Fri, 20 May 2022 13:36:02 -0400 Subject: [PATCH] feat: Render CSV and JSON files as tables This change adds a table renderer to nicely display CSV and JSON files. Like the HTML Renderer, the user can drop down into the raw view of the data. --- package-lock.json | 85 ++++++++ packages/frontend/package.json | 4 + .../components/file-viewer/file-viewer.tsx | 24 +++ .../renderers/csv-renderer/csv-renderer.tsx | 45 +++++ .../renderers/json-renderer/json-renderer.tsx | 45 +++++ .../table-renderer/table-renderer.tsx | 183 ++++++++++++++++++ packages/frontend/src/shared/icon-factory.tsx | 8 +- packages/frontend/src/shared/mime-utils.ts | 5 +- .../src/types/react-table-config.d.ts | 130 +++++++++++++ 9 files changed, 527 insertions(+), 2 deletions(-) create mode 100644 packages/frontend/src/components/renderers/csv-renderer/csv-renderer.tsx create mode 100644 packages/frontend/src/components/renderers/json-renderer/json-renderer.tsx create mode 100644 packages/frontend/src/components/renderers/table-renderer/table-renderer.tsx create mode 100644 packages/frontend/src/types/react-table-config.d.ts diff --git a/package-lock.json b/package-lock.json index eba2604a4..833ff5c2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4054,6 +4054,15 @@ "resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz", "integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ==" }, + "node_modules/@types/papaparse": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.2.tgz", + "integrity": "sha512-BNbCHJkTE4RwmAFkCxEalET4mDvGr/1ld7ZtQ4i/laWI/iiVt+GL07stdvufle4KfywyvloqqpIiJscXNCrKxA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -4170,6 +4179,15 @@ "@types/react-router": "*" } }, + "node_modules/@types/react-table": { + "version": "7.7.12", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.12.tgz", + "integrity": "sha512-bRUent+NR/WwtDGwI/BqhZ8XnHghwHw0HUKeohzB5xN3K2qKWYE5w19e7GCuOkL1CXD9Gi1HFy7TIm2AvgWUHg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", @@ -17057,6 +17075,11 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "node_modules/papaparse": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz", + "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==" + }, "node_modules/param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -18462,6 +18485,18 @@ "react": ">= 0.14.0" } }, + "node_modules/react-table": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17.0.0-0 || ^18.0.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", @@ -22506,6 +22541,12 @@ "vega-lite": "*" } }, + "node_modules/vega-embed/node_modules/yallist": { + "version": "4.0.0", + "extraneous": true, + "inBundle": true, + "license": "ISC" + }, "node_modules/vega-encode": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-4.9.0.tgz", @@ -23791,6 +23832,7 @@ "mdast-util-find-and-replace": "2.1.0", "nanoid": "3.3.4", "node-emoji": "1.11.0", + "papaparse": "5.3.2", "parsimmon": "1.18.1", "react": "18.1.0", "react-ace": "10.1.0", @@ -23814,6 +23856,7 @@ "react-router-dom": "6.3.0", "react-select": "4.3.1", "react-syntax-highlighter": "15.5.0", + "react-table": "7.8.0", "react-vega": "7.5.1", "redux-persist": "6.0.0", "rehype-autolink-headings": "6.1.1", @@ -23840,12 +23883,14 @@ "@types/jest": "27.4.1", "@types/luxon": "2.3.2", "@types/node-emoji": "1.8.1", + "@types/papaparse": "5.3.2", "@types/parsimmon": "1.10.6", "@types/react": "18.0.9", "@types/react-datepicker": "4.4.1", "@types/react-dom": "18.0.4", "@types/react-linkify": "1.0.1", "@types/react-router-dom": "5.3.3", + "@types/react-table": "7.7.12", "@typescript-eslint/eslint-plugin": "5.25.0", "@typescript-eslint/parser": "5.24.0", "@vitejs/plugin-react": "1.3.2", @@ -26879,12 +26924,14 @@ "@types/jest": "27.4.1", "@types/luxon": "2.3.2", "@types/node-emoji": "1.8.1", + "@types/papaparse": "5.3.2", "@types/parsimmon": "1.10.6", "@types/react": "18.0.9", "@types/react-datepicker": "4.4.1", "@types/react-dom": "18.0.4", "@types/react-linkify": "1.0.1", "@types/react-router-dom": "5.3.3", + "@types/react-table": "7.7.12", "@typescript-eslint/eslint-plugin": "5.25.0", "@typescript-eslint/parser": "5.24.0", "@urql/core": "2.4.4", @@ -26913,6 +26960,7 @@ "mdast-util-find-and-replace": "2.1.0", "nanoid": "3.3.4", "node-emoji": "1.11.0", + "papaparse": "5.3.2", "parsimmon": "1.18.1", "prettier": "2.6.2", "react": "18.1.0", @@ -26937,6 +26985,7 @@ "react-router-dom": "6.3.0", "react-select": "4.3.1", "react-syntax-highlighter": "15.5.0", + "react-table": "7.8.0", "react-vega": "7.5.1", "redux-persist": "6.0.0", "rehype-autolink-headings": "6.1.1", @@ -29137,6 +29186,15 @@ "resolved": "https://registry.npmjs.org/@types/p-queue/-/p-queue-2.3.2.tgz", "integrity": "sha512-eKAv5Ql6k78dh3ULCsSBxX6bFNuGjTmof5Q/T6PiECDq0Yf8IIn46jCyp3RJvCi8owaEmm3DZH1PEImjBMd/vQ==" }, + "@types/papaparse": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.2.tgz", + "integrity": "sha512-BNbCHJkTE4RwmAFkCxEalET4mDvGr/1ld7ZtQ4i/laWI/iiVt+GL07stdvufle4KfywyvloqqpIiJscXNCrKxA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -29248,6 +29306,15 @@ "@types/react-router": "*" } }, + "@types/react-table": { + "version": "7.7.12", + "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-7.7.12.tgz", + "integrity": "sha512-bRUent+NR/WwtDGwI/BqhZ8XnHghwHw0HUKeohzB5xN3K2qKWYE5w19e7GCuOkL1CXD9Gi1HFy7TIm2AvgWUHg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/retry": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", @@ -38818,6 +38885,11 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "papaparse": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz", + "integrity": "sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw==" + }, "param-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", @@ -39824,6 +39896,12 @@ "refractor": "^3.6.0" } }, + "react-table": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", + "requires": {} + }, "react-transition-group": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", @@ -42889,6 +42967,13 @@ "vega-schema-url-parser": "^2.2.0", "vega-themes": "^2.10.0", "vega-tooltip": "^0.27.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "bundled": true, + "extraneous": true + } } }, "vega-encode": { diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 56abce443..f7fe42f35 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -29,6 +29,7 @@ "mdast-util-find-and-replace": "2.1.0", "nanoid": "3.3.4", "node-emoji": "1.11.0", + "papaparse": "5.3.2", "parsimmon": "1.18.1", "react": "18.1.0", "react-ace": "10.1.0", @@ -52,6 +53,7 @@ "react-router-dom": "6.3.0", "react-select": "4.3.1", "react-syntax-highlighter": "15.5.0", + "react-table": "7.8.0", "react-vega": "7.5.1", "redux-persist": "6.0.0", "rehype-autolink-headings": "6.1.1", @@ -78,12 +80,14 @@ "@types/jest": "27.4.1", "@types/luxon": "2.3.2", "@types/node-emoji": "1.8.1", + "@types/papaparse": "5.3.2", "@types/parsimmon": "1.10.6", "@types/react": "18.0.9", "@types/react-datepicker": "4.4.1", "@types/react-dom": "18.0.4", "@types/react-linkify": "1.0.1", "@types/react-router-dom": "5.3.3", + "@types/react-table": "7.7.12", "@typescript-eslint/eslint-plugin": "5.25.0", "@typescript-eslint/parser": "5.24.0", "@vitejs/plugin-react": "1.3.2", diff --git a/packages/frontend/src/components/file-viewer/file-viewer.tsx b/packages/frontend/src/components/file-viewer/file-viewer.tsx index 7c66a8ec1..b1aa7299b 100644 --- a/packages/frontend/src/components/file-viewer/file-viewer.tsx +++ b/packages/frontend/src/components/file-viewer/file-viewer.tsx @@ -30,8 +30,10 @@ import { useScrollToLocation } from '../../shared/use-scroll-to-location'; import { useFetch } from '../../shared/useFetch'; import { MarkdownContainer } from '../markdown-container/markdown-container'; import { CodeRenderer } from '../renderers/code-renderer/code-renderer'; +import { CsvRenderer } from '../renderers/csv-renderer/csv-renderer'; import { HtmlRenderer } from '../renderers/html-renderer/html-renderer'; import { ImageRenderer } from '../renderers/image-renderer/image-renderer'; +import { JsonRenderer } from '../renderers/json-renderer/json-renderer'; import { PdfRenderer } from '../renderers/pdf-renderer/pdf-renderer'; import { VideoRenderer } from '../renderers/video-renderer/video-renderer'; @@ -230,6 +232,28 @@ export const FileViewer = ({ canDisplayRendered = !canDisplayRaw; break; + case MIME_VIEWER.Csv: + unpause(); + if (mode === 'rendered') { + renderer = ; + } else if (mode === 'raw') { + renderer = ; + } + canDisplayRaw = mode === 'rendered'; + canDisplayRendered = !canDisplayRaw; + break; + + case MIME_VIEWER.Json: + unpause(); + if (mode === 'rendered') { + renderer = ; + } else if (mode === 'raw') { + renderer = ; + } + canDisplayRaw = mode === 'rendered'; + canDisplayRendered = !canDisplayRaw; + break; + case MIME_VIEWER.None: pause(); renderer = ; diff --git a/packages/frontend/src/components/renderers/csv-renderer/csv-renderer.tsx b/packages/frontend/src/components/renderers/csv-renderer/csv-renderer.tsx new file mode 100644 index 000000000..3c1f9699c --- /dev/null +++ b/packages/frontend/src/components/renderers/csv-renderer/csv-renderer.tsx @@ -0,0 +1,45 @@ +/** + * Copyright 2022 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Papa from 'papaparse'; +import { useMemo } from 'react'; + +import { TableRenderer } from '../table-renderer/table-renderer'; + +export const CsvRenderer = ({ contents }) => { + const results = useMemo(() => { + if (contents) { + // Parse CSV file to extract columns and data + const { data, meta } = Papa.parse(contents, { header: true }); + + const columns = meta.fields?.map((column) => ({ + Header: column, + accessor: column + })); + + return { + columns, + data + }; + } + }, [contents]); + + if (results === undefined) { + return null; + } + + return ; +}; diff --git a/packages/frontend/src/components/renderers/json-renderer/json-renderer.tsx b/packages/frontend/src/components/renderers/json-renderer/json-renderer.tsx new file mode 100644 index 000000000..39c45a1cb --- /dev/null +++ b/packages/frontend/src/components/renderers/json-renderer/json-renderer.tsx @@ -0,0 +1,45 @@ +/** + * Copyright 2022 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useMemo } from 'react'; + +import { TableRenderer } from '../table-renderer/table-renderer'; + +export const JsonRenderer = ({ contents }) => { + const results = useMemo(() => { + if (contents) { + const data = JSON.parse(contents); + + // Assume all the columns are in the first row + // We could extend this to take a larger sample of data to determine the columns + const columns = Object.keys(data[0]).map((column) => ({ + Header: column, + accessor: column + })); + + return { + columns, + data + }; + } + }, [contents]); + + if (results === undefined) { + return null; + } + + return ; +}; diff --git a/packages/frontend/src/components/renderers/table-renderer/table-renderer.tsx b/packages/frontend/src/components/renderers/table-renderer/table-renderer.tsx new file mode 100644 index 000000000..1e60e4b43 --- /dev/null +++ b/packages/frontend/src/components/renderers/table-renderer/table-renderer.tsx @@ -0,0 +1,183 @@ +/** + * Copyright 2022 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Flex, + HStack, + IconButton, + NumberInput, + NumberInputField, + NumberInputStepper, + NumberIncrementStepper, + NumberDecrementStepper, + Select, + Table, + TableContainer, + Tbody, + Td, + Text, + Th, + Thead, + Tooltip, + Tr, + Icon +} from '@chakra-ui/react'; +import { usePagination, useSortBy, useTable } from 'react-table'; + +import { iconFactory, iconFactoryAs } from '../../../shared/icon-factory'; + +export const TableRenderer = ({ columns, data }) => { + const { + canNextPage, + canPreviousPage, + getTableProps, + getTableBodyProps, + gotoPage, + headers, + nextPage, + page, + pageCount, + pageOptions, + prepareRow, + previousPage, + setPageSize, + state: { pageIndex, pageSize } + } = useTable( + { + columns, + data, + initialState: { + pageSize: 25 + } + }, + useSortBy, + usePagination + ); + + return ( + <> + + + + + {headers.map((header) => ( + + ))} + + + + {page.map((row) => { + prepareRow(row); + return ( + + {row.cells.map((cell) => { + console.log('cell', cell); + return ; + })} + + ); + })} + +
+ {header.render('Header')} + {header.isSorted && ( + + )} +
{cell.render('Cell')}
+
+ + + + + gotoPage(0)} + isDisabled={!canPreviousPage} + icon={iconFactoryAs('paginateFirst')} + aria-label="First Page" + /> + + + + + + + + + Page {pageIndex + 1} of {pageOptions.length} + + { + const page = value ? value - 1 : 0; + gotoPage(page); + }} + > + + + + + + + + + + + + + + + + gotoPage(pageCount - 1)} + isDisabled={!canNextPage} + icon={iconFactoryAs('paginateLast')} + aria-label="Last Page" + /> + + + + + ); +}; diff --git a/packages/frontend/src/shared/icon-factory.tsx b/packages/frontend/src/shared/icon-factory.tsx index 73058805d..666fe545a 100644 --- a/packages/frontend/src/shared/icon-factory.tsx +++ b/packages/frontend/src/shared/icon-factory.tsx @@ -46,10 +46,11 @@ import { FaUsers, FaUserTimes } from 'react-icons/fa'; -import { FiActivity } from 'react-icons/fi'; +import { FiActivity, FiChevronLeft, FiChevronRight, FiChevronsLeft, FiChevronsRight } from 'react-icons/fi'; import { GoCheck, GoChevronDown, + GoChevronLeft, GoChevronRight, GoChevronUp, GoCircleSlash, @@ -117,6 +118,7 @@ const icons = { calendar: VscCalendar, check: GoCheck, chevronDown: GoChevronDown, + chevronLeft: GoChevronLeft, chevronRight: GoChevronRight, chevronUp: GoChevronUp, clone: GrClone, @@ -160,6 +162,10 @@ const icons = { optionsMenu: BsThreeDotsVertical, news: AiFillGift, page: GrDocumentText, + paginateLeft: FiChevronLeft, + paginateRight: FiChevronRight, + paginateFirst: FiChevronsLeft, + paginateLast: FiChevronsRight, permissions: FaUserEdit, preview: VscPreview, previousPage: VscChevronLeft, diff --git a/packages/frontend/src/shared/mime-utils.ts b/packages/frontend/src/shared/mime-utils.ts index 17a0b1200..c3a7014eb 100644 --- a/packages/frontend/src/shared/mime-utils.ts +++ b/packages/frontend/src/shared/mime-utils.ts @@ -29,8 +29,10 @@ export enum MIME_EDITOR { export enum MIME_VIEWER { Code, + Csv, Html, Image, + Json, Markdown, PDF, Video, @@ -56,7 +58,7 @@ const mimeTypes: MimeTypeDefinition[] = [ editor: MIME_EDITOR.Code, viewer: MIME_VIEWER.Code }, - { mimeType: 'application/json', editorLanguage: 'json', editor: MIME_EDITOR.Code, viewer: MIME_VIEWER.Code }, + { mimeType: 'application/json', editorLanguage: 'json', editor: MIME_EDITOR.Code, viewer: MIME_VIEWER.Json }, { mimeType: 'application/pdf', editor: MIME_EDITOR.None, viewer: MIME_VIEWER.PDF }, { mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation', @@ -85,6 +87,7 @@ const mimeTypes: MimeTypeDefinition[] = [ { mimeType: 'image/*', editor: MIME_EDITOR.None, viewer: MIME_VIEWER.Image }, + { mimeType: 'text/csv', editor: MIME_EDITOR.Code, viewer: MIME_VIEWER.Csv }, { mimeType: 'text/html', editorLanguage: 'xml', editor: MIME_EDITOR.Html, viewer: MIME_VIEWER.Html }, { mimeType: 'text/markdown', editorLanguage: 'markdown', editor: MIME_EDITOR.Markdown, viewer: MIME_VIEWER.Markdown }, { mimeType: 'text/plain', editorLanguage: 'text', editor: MIME_EDITOR.Code, viewer: MIME_VIEWER.Code }, diff --git a/packages/frontend/src/types/react-table-config.d.ts b/packages/frontend/src/types/react-table-config.d.ts new file mode 100644 index 000000000..96fe4002a --- /dev/null +++ b/packages/frontend/src/types/react-table-config.d.ts @@ -0,0 +1,130 @@ +/** + * Copyright 2022 Expedia, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Adapted from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-table + +import type { + UseColumnOrderInstanceProps, + UseColumnOrderState, + UseExpandedHooks, + UseExpandedInstanceProps, + UseExpandedOptions, + UseExpandedRowProps, + UseExpandedState, + UseFiltersColumnOptions, + UseFiltersColumnProps, + UseFiltersInstanceProps, + UseFiltersOptions, + UseFiltersState, + UseGlobalFiltersColumnOptions, + UseGlobalFiltersInstanceProps, + UseGlobalFiltersOptions, + UseGlobalFiltersState, + UseGroupByCellProps, + UseGroupByColumnOptions, + UseGroupByColumnProps, + UseGroupByHooks, + UseGroupByInstanceProps, + UseGroupByOptions, + UseGroupByRowProps, + UseGroupByState, + UsePaginationInstanceProps, + UsePaginationOptions, + UsePaginationState, + UseRowSelectHooks, + UseRowSelectInstanceProps, + UseRowSelectOptions, + UseRowSelectRowProps, + UseRowSelectState, + UseRowStateCellProps, + UseRowStateInstanceProps, + UseRowStateOptions, + UseRowStateRowProps, + UseRowStateState, + UseSortByColumnOptions, + UseSortByColumnProps, + UseSortByHooks, + UseSortByInstanceProps, + UseSortByOptions, + UseSortByState +} from 'react-table'; + +declare module 'react-table' { + // take this file as-is, or comment out the sections that don't apply to your plugin configuration + + export interface TableOptions> + extends UseExpandedOptions, + UseFiltersOptions, + UseGlobalFiltersOptions, + UseGroupByOptions, + UsePaginationOptions, + UseRowSelectOptions, + UseRowStateOptions, + UseSortByOptions, + // note that having Record here allows you to add anything to the options, this matches the spirit of the + // underlying js library, but might be cleaner if it's replaced by a more specific type that matches your + // feature set, this is a safe default. + Record {} + + export interface Hooks = Record> + extends UseExpandedHooks, + UseGroupByHooks, + UseRowSelectHooks, + UseSortByHooks {} + + export interface TableInstance = Record> + extends UseColumnOrderInstanceProps, + UseExpandedInstanceProps, + UseFiltersInstanceProps, + UseGlobalFiltersInstanceProps, + UseGroupByInstanceProps, + UsePaginationInstanceProps, + UseRowSelectInstanceProps, + UseRowStateInstanceProps, + UseSortByInstanceProps {} + + export interface TableState = Record> + extends UseColumnOrderState, + UseExpandedState, + UseFiltersState, + UseGlobalFiltersState, + UseGroupByState, + UsePaginationState, + UseRowSelectState, + UseRowStateState, + UseSortByState {} + + export interface ColumnInterface = Record> + extends UseFiltersColumnOptions, + UseGlobalFiltersColumnOptions, + UseGroupByColumnOptions, + UseSortByColumnOptions {} + + export interface ColumnInstance = Record> + extends UseFiltersColumnProps, + UseGroupByColumnProps, + UseSortByColumnProps {} + + export interface Cell = Record, V = any> + extends UseGroupByCellProps, + UseRowStateCellProps {} + + export interface Row = Record> + extends UseExpandedRowProps, + UseGroupByRowProps, + UseRowSelectRowProps, + UseRowStateRowProps {} +}