From f09b9c085f83abb360bc30d13cfd507e7bd31a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Wed, 6 Mar 2024 17:30:59 +0000 Subject: [PATCH] WIP: TreeTable component --- web/src/components/core/TreeTable.jsx | 99 +++++++++++++++++++++++++++ web/src/components/core/index.js | 1 + 2 files changed, 100 insertions(+) create mode 100644 web/src/components/core/TreeTable.jsx diff --git a/web/src/components/core/TreeTable.jsx b/web/src/components/core/TreeTable.jsx new file mode 100644 index 0000000000..dca2e866b9 --- /dev/null +++ b/web/src/components/core/TreeTable.jsx @@ -0,0 +1,99 @@ +/* + * Copyright (c) [2024] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React from "react"; +import { Table, Thead, Tr, Th, Tbody, Td, TreeRowWrapper } from '@patternfly/react-table'; + +/** + * Table built on top of PF/Table + * @component + * + * @param {object} props + */ +export default function TreeTable({ + columns = [], + items = [], + itemChildren = () => [], + rowClassNames = () => "" +}) { + const renderColumns = (item, treeRow) => { + return columns.map((c, cIdx) => { + const props = { dataLabel: c.title }; + + if (cIdx === 0) props.treeRow = treeRow; + + return ( + // FIXME: using an array below becasue for some reason React is + // complaining about + // Objects are not valid as a React child (found: object with keys {title}). If you meant to render a collection of children, use an array instead. + // when rendering the first column using the treeRow prop + // Checking the PF/Table code might help to understand what is going on + // there + {[c.content(item)]} + ); + }); + }; + + const renderRows = (items, level) => { + if (!items?.length > 0) return; + + return ( + items.map((item, itemIdx) => { + const children = itemChildren(item); + + const treeRow = { + props: { + isExpanded: true, + isDetailsExpanded: true, + "aria-level": level, + "aria-posinset": itemIdx + 1, + "aria-setsize": children?.length || 0 + } + }; + + const rowProps = { + row: { props: treeRow.props }, + className: rowClassNames(item) + }; + + return ( + + {renderColumns(item, treeRow)} + { renderRows(children, level + 1)} + + ); + }) + ); + }; + + return ( + + + + { columns.map((c, i) => ) } + + + + { renderRows(items, 1) } + +
{c.title}
+ ); +} diff --git a/web/src/components/core/index.js b/web/src/components/core/index.js index 0213c66215..9365c9e8d2 100644 --- a/web/src/components/core/index.js +++ b/web/src/components/core/index.js @@ -57,3 +57,4 @@ export { default as PasswordInput } from "./PasswordInput"; export { default as DevelopmentInfo } from "./DevelopmentInfo"; export { default as Selector } from "./Selector"; export { default as OptionsPicker } from "./OptionsPicker"; +export { default as TreeTable } from "./TreeTable";