From f8afab2efec53ea869e465f4122608cacf1c8ecc Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 28 Apr 2021 09:15:00 -0400 Subject: [PATCH] some more work on react-table Signed-off-by: Sebastian Malton --- package.json | 2 + .../components/+cluster/cluster-issues.tsx | 125 +++++++++++------- .../reactive-table/reactive-table.tsx | 92 +++++++++++++ yarn.lock | 12 ++ 4 files changed, 182 insertions(+), 49 deletions(-) create mode 100644 src/renderer/components/reactive-table/reactive-table.tsx diff --git a/package.json b/package.json index c3c572d536..eee0ebc3a9 100644 --- a/package.json +++ b/package.json @@ -172,6 +172,7 @@ "@hapi/call": "^8.0.0", "@hapi/subtext": "^7.0.3", "@kubernetes/client-node": "^0.12.0", + "@types/react-table": "^7.0.29", "abort-controller": "^3.0.0", "array-move": "^3.0.0", "await-lock": "^2.1.0", @@ -213,6 +214,7 @@ "react": "^17.0.1", "react-dom": "^17.0.1", "react-router": "^5.2.0", + "react-table": "^7.7.0", "readable-stream": "^3.6.0", "request": "^2.88.2", "request-promise-native": "^1.0.8", diff --git a/src/renderer/components/+cluster/cluster-issues.tsx b/src/renderer/components/+cluster/cluster-issues.tsx index 4e6b961d03..e188d7fa96 100644 --- a/src/renderer/components/+cluster/cluster-issues.tsx +++ b/src/renderer/components/+cluster/cluster-issues.tsx @@ -5,41 +5,41 @@ import { observer } from "mobx-react"; import { computed } from "mobx"; import { Icon } from "../icon"; import { SubHeader } from "../layout/sub-header"; -import { Table, TableCell, TableHead, TableRow } from "../table"; import { nodesStore } from "../+nodes/nodes.store"; import { eventStore } from "../+events/event.store"; -import { autobind, cssNames, prevDefault } from "../../utils"; -import { ItemObject } from "../../item.store"; +import { cssNames } from "../../utils"; import { Spinner } from "../spinner"; -import { ThemeStore } from "../../theme.store"; import { lookupApiLink } from "../../api/kube-api"; -import { kubeSelectedUrlParam, showDetails } from "../kube-object"; +import { ReactiveTable } from "../reactive-table/reactive-table"; +import { Column } from "react-table"; interface Props { className?: string; } -interface IWarning extends ItemObject { +interface IWarning { kind: string; + id: string; + name: string; message: string; selfLink: string; age: string | number; timeDiffFromNow: number; } -enum sortBy { - type = "type", - object = "object", - age = "age", -} +// enum sortBy { +// type = "type", +// object = "object", +// age = "age", +// } @observer export class ClusterIssues extends React.Component { - private sortCallbacks = { - [sortBy.type]: (warning: IWarning) => warning.kind, - [sortBy.object]: (warning: IWarning) => warning.getName(), - [sortBy.age]: (warning: IWarning) => warning.timeDiffFromNow, - }; + // private sortCallbacks = { + // [sortBy.type]: (warning: IWarning) => warning.kind, + // [sortBy.object]: (warning: IWarning) => warning.getName(), + // [sortBy.age]: (warning: IWarning) => warning.timeDiffFromNow, + // }; @computed get warnings() { const warnings: IWarning[] = []; @@ -51,8 +51,8 @@ export class ClusterIssues extends React.Component { node.getWarningConditions().forEach(({ message }) => { warnings.push({ age: getAge(), - getId, - getName, + id: getId(), + name: getName(), timeDiffFromNow: getTimeDiffFromNow(), kind, message, @@ -69,8 +69,8 @@ export class ClusterIssues extends React.Component { const { uid, name, kind } = involvedObject; warnings.push({ - getId: () => uid, - getName: () => name, + id: uid, + name, timeDiffFromNow: getTimeDiffFromNow(), age: getAge(), message, @@ -82,34 +82,57 @@ export class ClusterIssues extends React.Component { return warnings; } - @autobind() - getTableRow(uid: string) { - const { warnings } = this; - const warning = warnings.find(warn => warn.getId() == uid); - const { getId, getName, message, kind, selfLink, age } = warning; + columns: Column[] = [ + { + id: "message", + Header: "Message", + accessor: "message", + }, + { + id: "name", + Header: "Object Name", + accessor: "name", + }, + { + id: "kind", + Header: "Kind", + accessor: "kind", + }, + { + id: "age", + Header: "Age", + accessor: "age", + }, + ]; - return ( - showDetails(selfLink))} - > - - {message} - - - {getName()} - - - {kind} - - - {age} - - - ); - } + // @autobind() + // getTableRow(uid: string) { + // const { warnings } = this; + // const warning = warnings.find(warn => warn.getId() == uid); + // const { getId, getName, message, kind, selfLink, age } = warning; + + // return ( + // showDetails(selfLink))} + // > + // + // {message} + // + // + // {getName()} + // + // + // {kind} + // + // + // {age} + // + // + // ); + // } renderContent() { const { warnings } = this; @@ -136,7 +159,11 @@ export class ClusterIssues extends React.Component { {" "} <>Warnings: {warnings.length} - + {/*
{ TypeAge -
+ */} ); } diff --git a/src/renderer/components/reactive-table/reactive-table.tsx b/src/renderer/components/reactive-table/reactive-table.tsx new file mode 100644 index 0000000000..448df91a8f --- /dev/null +++ b/src/renderer/components/reactive-table/reactive-table.tsx @@ -0,0 +1,92 @@ +import React from "react"; +import { useTable, useBlockLayout, useResizeColumns, Column, HeaderGroup, UseResizeColumnsColumnProps } from "react-table"; + +export interface TableProps { + columns: Column[]; + data: T[]; +} + +export function ReactiveTable({ columns, data }: TableProps) { + const defaultColumn = React.useMemo( + () => ({ + minWidth: 30, + width: 150, + maxWidth: 400, + }), + [] + ); + + const { + getTableProps, + getTableBodyProps, + headerGroups, + rows, + prepareRow, + state, + } = useTable( + { + columns, + data, + defaultColumn, + }, + useBlockLayout, + useResizeColumns + ); + + return ( + <> +
+
+
+ {headerGroups.map(headerGroup => { + const { key, ...headerProps } = headerGroup.getHeaderGroupProps(); + + return ( +
+ {headerGroup.headers.map(c => { + const column = c as HeaderGroup & UseResizeColumnsColumnProps; // needed until react table v8 is done + const { key, ...columnProps } = column.getHeaderProps(); + + return ( +
+ {column.render("Header")} +
+
+ ); + })} +
+ ); + })} +
+ +
+ {rows.map(row => { + prepareRow(row); + const { key, ...rowProps } = row.getRowProps(); + + return ( +
+ {row.cells.map(cell => { + const { key, ...cellProps } = cell.getCellProps(); + + return ( +
+ {cell.render("Cell")} +
+ ); + })} +
+ ); + })} +
+
+
+
+        {JSON.stringify(state, null, 2)}
+      
+ + ); +} diff --git a/yarn.lock b/yarn.lock index f1704da1c9..599693def4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1618,6 +1618,13 @@ "@types/react-dom" "*" "@types/react-transition-group" "*" +"@types/react-table@^7.0.29": + version "7.0.29" + resolved "https://registry.yarnpkg.com/@types/react-table/-/react-table-7.0.29.tgz#af2c82f2d6a39be5bc0f191b30501309a8db0949" + integrity sha512-RCGVKGlTDv3jbj37WJ5HhN3sPb0W/2rqlvyGUtvawnnyrxgI2BGgASvU93rq2jwanVp5J9l1NYAeiGlNhdaBGw== + dependencies: + "@types/react" "*" + "@types/react-transition-group@*", "@types/react-transition-group@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d" @@ -11565,6 +11572,11 @@ react-select@^3.1.0: react-input-autosize "^2.2.2" react-transition-group "^4.3.0" +react-table@^7.7.0: + version "7.7.0" + resolved "https://registry.yarnpkg.com/react-table/-/react-table-7.7.0.tgz#e2ce14d7fe3a559f7444e9ecfe8231ea8373f912" + integrity sha512-jBlj70iBwOTvvImsU9t01LjFjy4sXEtclBovl3mTiqjz23Reu0DKnRza4zlLtOPACx6j2/7MrQIthIK1Wi+LIA== + react-transition-group@^4.3.0, react-transition-group@^4.4.0: version "4.4.1" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"