diff --git a/package-lock.json b/package-lock.json index b1a3adeb..07ccbb06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,9 +10,10 @@ "license": "Apache-2.0", "dependencies": { "@metrostar/comet-data-viz": "1.1.1", - "@metrostar/comet-extras": "1.1.0", + "@metrostar/comet-extras": "1.2.0", "@metrostar/comet-uswds": "1.4.0", "@tanstack/react-query": "4.32.0", + "@tanstack/react-table": "8.9.3", "@types/keycloak-js": "^3.4.1", "@uswds/uswds": "3.6.0", "axios": "1.4.0", @@ -30,9 +31,10 @@ "@babel/preset-env": "7.22.9", "@babel/preset-react": "7.22.5", "@babel/preset-typescript": "7.22.5", - "@testing-library/jest-dom": "5.17.0", + "@testing-library/jest-dom": "6.1.3", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", + "@types/jest": "^29.5.4", "@types/react": "18.2.17", "@types/react-dom": "18.2.7", "@typescript-eslint/eslint-plugin": "6.2.0", @@ -74,9 +76,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.2.0.tgz", - "integrity": "sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz", + "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -3042,9 +3044,9 @@ } }, "node_modules/@jest/schemas": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", - "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -3354,10 +3356,11 @@ } }, "node_modules/@metrostar/comet-extras": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@metrostar/comet-extras/-/comet-extras-1.1.0.tgz", - "integrity": "sha512-ht/qb84IeKkIiBK+rorzDFnUwJZxDy9B4QbU6uz+6tKex7oN5Qdok/tqUWFplt3nILU8nNul54j0Uq5qH9fo/Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@metrostar/comet-extras/-/comet-extras-1.2.0.tgz", + "integrity": "sha512-z7UkaSf8Blv4pMZcjFlJSrsagIRYyUk2RP47R1nIGZE4So7DiuPLcyNI+XFv4HijsffXTlnmw3Zb8lLPB/m0kA==", "dependencies": { + "@tanstack/react-table": "8.9.3", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -3516,6 +3519,37 @@ } } }, + "node_modules/@tanstack/react-table": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.9.3.tgz", + "integrity": "sha512-Ng9rdm3JPoSCi6cVZvANsYnF+UoGVRxflMb270tVj0+LjeT/ZtZ9ckxF6oLPLcKesza6VKBqtdF9mQ+vaz24Aw==", + "dependencies": { + "@tanstack/table-core": "8.9.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.9.3.tgz", + "integrity": "sha512-NpHZBoHTfqyJk0m/s/+CSuAiwtebhYK90mDuf5eylTvgViNOujiaOaxNDxJkQQAsVvHWZftUGAx1EfO1rkKtLg==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", @@ -3606,14 +3640,13 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz", - "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.3.tgz", + "integrity": "sha512-YzpjRHoCBWPzpPNtg6gnhasqtE/5O4qz8WCwDEaxtfnPO6gkaLrnuXusrGSPyhIGPezr1HM7ZH0CFaUTY9PJEQ==", "dev": true, "dependencies": { - "@adobe/css-tools": "^4.0.1", + "@adobe/css-tools": "^4.3.0", "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", "aria-query": "^5.0.0", "chalk": "^3.0.0", "css.escape": "^1.5.1", @@ -3622,9 +3655,29 @@ "redent": "^3.0.0" }, "engines": { - "node": ">=8", + "node": ">=14", "npm": ">=6", "yarn": ">=1" + }, + "peerDependencies": { + "@jest/globals": ">= 28", + "@types/jest": ">= 28", + "jest": ">= 28", + "vitest": ">= 0.32" + }, + "peerDependenciesMeta": { + "@jest/globals": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "jest": { + "optional": true + }, + "vitest": { + "optional": true + } } }, "node_modules/@testing-library/jest-dom/node_modules/ansi-styles": { @@ -3909,9 +3962,9 @@ } }, "node_modules/@types/jest": { - "version": "29.5.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.3.tgz", - "integrity": "sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==", + "version": "29.5.4", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.4.tgz", + "integrity": "sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==", "dev": true, "dependencies": { "expect": "^29.0.0", @@ -3931,12 +3984,12 @@ } }, "node_modules/@types/jest/node_modules/pretty-format": { - "version": "29.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.2.tgz", - "integrity": "sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", + "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.6.0", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4038,15 +4091,6 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.9", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz", - "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==", - "dev": true, - "dependencies": { - "@types/jest": "*" - } - }, "node_modules/@types/tough-cookie": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", diff --git a/package.json b/package.json index 2d632cfe..cb458e98 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,10 @@ }, "dependencies": { "@metrostar/comet-data-viz": "1.1.1", - "@metrostar/comet-extras": "1.1.0", + "@metrostar/comet-extras": "1.2.0", "@metrostar/comet-uswds": "1.4.0", "@tanstack/react-query": "4.32.0", + "@tanstack/react-table": "8.9.3", "@types/keycloak-js": "^3.4.1", "@uswds/uswds": "3.6.0", "axios": "1.4.0", @@ -47,9 +48,10 @@ "@babel/preset-env": "7.22.9", "@babel/preset-react": "7.22.5", "@babel/preset-typescript": "7.22.5", - "@testing-library/jest-dom": "5.17.0", + "@testing-library/jest-dom": "6.1.3", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", + "@types/jest": "^29.5.4", "@types/react": "18.2.17", "@types/react-dom": "18.2.7", "@typescript-eslint/eslint-plugin": "6.2.0", diff --git a/src/pages/dashboard/dashboard-table/dashboard-table.test.tsx b/src/pages/dashboard/dashboard-table/dashboard-table.test.tsx index ca96f3d1..e8ee74f4 100644 --- a/src/pages/dashboard/dashboard-table/dashboard-table.test.tsx +++ b/src/pages/dashboard/dashboard-table/dashboard-table.test.tsx @@ -27,9 +27,9 @@ describe('DashboardTable', () => { await act(async () => { expect(baseElement).toBeTruthy(); }); - expect(baseElement.querySelector('.usa-table')).toBeDefined(); + expect(baseElement.querySelector('.data-table')).toBeDefined(); expect( - baseElement.querySelectorAll('.usa-table > tbody > tr'), + baseElement.querySelectorAll('.data-table > tbody > tr'), ).toHaveLength(5); }); }); diff --git a/src/pages/dashboard/dashboard-table/dashboard-table.tsx b/src/pages/dashboard/dashboard-table/dashboard-table.tsx index 4ecd3a67..1cf532fd 100644 --- a/src/pages/dashboard/dashboard-table/dashboard-table.tsx +++ b/src/pages/dashboard/dashboard-table/dashboard-table.tsx @@ -1,4 +1,5 @@ -import { Table, TableColumn } from '@metrostar/comet-uswds'; +import { DataTable } from '@metrostar/comet-extras'; +import { ColumnDef } from '@tanstack/react-table'; import React, { useEffect, useState } from 'react'; import { NavLink } from 'react-router-dom'; import { Launch } from '../../../types/launch'; @@ -12,52 +13,61 @@ export const DashboardTable = ({ items, }: DashboardTableProps): React.ReactElement => { const [data, setData] = useState(); + const cols = React.useMemo[]>( + () => [ + { + accessorKey: 'name', + header: 'Name', + cell: (info) => info.getValue(), + }, + { + accessorKey: 'provider', + header: 'Service Provider', + cell: (info) => info.getValue(), + }, + { + accessorKey: 'status', + header: 'Status', + cell: (info) => info.getValue(), + }, + { + accessorKey: 'last_updated', + header: 'Last Updated', + cell: (info) => info.getValue(), + }, + ], + [], + ); + useEffect(() => { if (items) { const newData: LaunchData[] = []; items.forEach((item: Launch) => { newData.push({ - name: { - value: ( - - {item.name} - - ), - sortValue: item.status.name, - }, - provider: { - value: item.launch_service_provider.name, - sortValue: item.launch_service_provider.name, - }, - status: { value: item.status.name, sortValue: item.status.name }, - last_updated: { - value: item.last_updated, - sortValue: item.last_updated, - }, + name: ( + + {item.name} + + ), + provider: item.launch_service_provider.name, + status: item.status.name, + last_updated: item.last_updated, }); }); setData(newData); } }, [items]); - const columns: TableColumn[] = [ - { id: 'name', name: 'Name' }, - { id: 'provider', name: 'Service Provider' }, - { id: 'status', name: 'Status' }, - { id: 'last_updated', name: 'Last Updated' }, - ]; - return data ? ( - + sortCol="last_updated" + sortDir="desc" + > ) : ( <> ); diff --git a/src/pages/dashboard/types.ts b/src/pages/dashboard/types.ts index 8eb3ceae..b44dadd9 100644 --- a/src/pages/dashboard/types.ts +++ b/src/pages/dashboard/types.ts @@ -1,15 +1,10 @@ import { ReactNode } from 'react'; export interface LaunchData { - provider: SortableDataCell; - name: SortableDataCell; - status: SortableDataCell; - last_updated: SortableDataCell; -} - -export interface SortableDataCell { - value: string | ReactNode; - sortValue: string; + name: string | ReactNode; + provider: string; + status: string; + last_updated: string; } export interface ChartData {