-
Notifications
You must be signed in to change notification settings - Fork 8
feat: Add composable table variant #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,23 +1,17 @@ | ||||||
| import React from 'react'; | ||||||
| import React, { useContext } from 'react'; | ||||||
|
Check failure on line 1 in src/components/TableToolsTable/TableToolsTable.js
|
||||||
| import propTypes from 'prop-types'; | ||||||
| import { Pagination, PaginationVariant } from '@patternfly/react-core'; | ||||||
| import { | ||||||
| Table, | ||||||
| TableBody, | ||||||
| TableHeader, | ||||||
| } from '@patternfly/react-table/deprecated'; | ||||||
| import { | ||||||
| SkeletonTable, | ||||||
| ColumnManagementModal, | ||||||
| } from '@patternfly/react-component-groups'; | ||||||
|
|
||||||
| import PrimaryToolbar from '@redhat-cloud-services/frontend-components/PrimaryToolbar'; | ||||||
| import { ColumnManagementModal } from '@patternfly/react-component-groups'; | ||||||
| import TableToolbar from '@redhat-cloud-services/frontend-components/TableToolbar'; | ||||||
|
|
||||||
| import useTableTools from '~/hooks/useTableTools'; | ||||||
| import { TableStateProvider, FilterModal, TableViewToggle } from '~/components'; | ||||||
| import { TableContext } from '~/hooks/useTableContext/constants'; | ||||||
| import { TableStateProvider, FilterModal } from '~/components'; | ||||||
|
|
||||||
| import { variants, queryClient } from './constants'; | ||||||
|
Check failure on line 11 in src/components/TableToolsTable/TableToolsTable.js
|
||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Found 2 issues:
Suggested change
|
||||||
|
|
||||||
| const TableToolsTable = ({ | ||||||
| tableToolsTableVariant = 'table', | ||||||
| loading: externalLoading, | ||||||
| items: externalItems, | ||||||
| error: externalError, | ||||||
|
|
@@ -28,20 +22,16 @@ | |||||
| // TODO I'm not sure if we need this level of customisation. | ||||||
| // It might actually hurt in the long run. Consider removing until we really have the case where we need this | ||||||
| toolbarProps: toolbarPropsProp, | ||||||
| tableHeaderProps, | ||||||
| tableBodyProps, | ||||||
| tableToolbarProps, | ||||||
| paginationProps, | ||||||
| ...tablePropsRest | ||||||
| }) => { | ||||||
| const { TableComponent, ToolbarComponent } = variants[tableToolsTableVariant]; | ||||||
| const { | ||||||
| view, | ||||||
| loading, | ||||||
| toolbarProps, | ||||||
| tableProps, | ||||||
| filterModalProps, | ||||||
| columnManagerModalProps, | ||||||
| tableViewToggleProps, | ||||||
| ...tableToolsProps | ||||||
| } = useTableTools( | ||||||
| externalLoading, | ||||||
| externalItems, | ||||||
|
|
@@ -59,26 +49,9 @@ | |||||
|
|
||||||
| return ( | ||||||
| <> | ||||||
| <PrimaryToolbar aria-label="Table toolbar" {...toolbarProps}> | ||||||
| {toolbarProps?.children} | ||||||
| {tableViewToggleProps && <TableViewToggle {...tableViewToggleProps} />} | ||||||
| </PrimaryToolbar> | ||||||
| <ToolbarComponent {...{ ...tableToolsProps, ...{ toolbarProps } }} /> | ||||||
|
|
||||||
| { | ||||||
| // TODO This is a bit hackish. We should rather have an indicator if data necessary for the current view is loading. | ||||||
| (view === 'rows' || (view === 'tree' && !treeTable)) && loading ? ( | ||||||
| <SkeletonTable | ||||||
| rowsCount={toolbarProps?.pagination?.perPage || 10} | ||||||
| // TODO use Th when migrating to PF composable tables | ||||||
| columns={columns.map(({ title }) => title)} | ||||||
| /> | ||||||
| ) : ( | ||||||
| <Table aria-label="Table" {...tableProps}> | ||||||
| <TableHeader {...tableHeaderProps} /> | ||||||
| <TableBody {...tableBodyProps} /> | ||||||
| </Table> | ||||||
| ) | ||||||
| } | ||||||
| <TableComponent {...{ ...tableToolsProps, ...{ toolbarProps } }} /> | ||||||
|
|
||||||
| <TableToolbar isFooter {...tableToolbarProps}> | ||||||
| {toolbarProps.pagination && ( | ||||||
|
|
@@ -101,6 +74,7 @@ | |||||
| }; | ||||||
|
|
||||||
| TableToolsTable.propTypes = { | ||||||
| tableToolsTableVariant: propTypes.string, | ||||||
| items: propTypes.oneOfType([propTypes.array, propTypes.func]).isRequired, | ||||||
| columns: propTypes.arrayOf( | ||||||
| propTypes.shape({ | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| import React, { useEffect } from 'react'; | ||
| import { Table, Th } from '@patternfly/react-table'; | ||
| import { SkeletonTable } from '@patternfly/react-component-groups'; | ||
|
|
||
| import TableHead from './components/TableHead'; | ||
| import TableBody from './components/TableBody'; | ||
| import useTableToolsForComposable from './hooks/useTableToolsForComposable'; | ||
|
|
||
| const ComposableTable = (props) => { | ||
| const composableTableProps = useTableToolsForComposable(props); | ||
| const { | ||
| columns, | ||
| rows, | ||
| view, | ||
| loading, | ||
| tableTree, | ||
| pagination, | ||
| bulkSelect, | ||
| expandable, | ||
| total, | ||
| } = composableTableProps; | ||
|
|
||
| useEffect(() => { | ||
| console.group('ComposableTable props'); | ||
| console.warn( | ||
| 'Note: The "composable" variant is considered experimental and not fully featured yet.', | ||
| ); | ||
|
|
||
| console.log('props', props); | ||
| console.log('composableTableProps', composableTableProps); | ||
|
|
||
| console.groupEnd(); | ||
| }, [composableTableProps, props]); | ||
|
|
||
| return (view === 'rows' || (view === 'tree' && !tableTree)) && loading ? ( | ||
| <SkeletonTable | ||
| rowsCount={pagination?.perPage || 10} | ||
| columns={columns.map(({ title, sortable }) => ( | ||
| <Th | ||
| key={title} | ||
| {...(sortable | ||
| ? { sort: { columnIndex: 0, sortBy: { property: sortable } } } | ||
| : {})} | ||
| > | ||
| {title} | ||
| </Th> | ||
| ))} | ||
| /> | ||
| ) : ( | ||
| <Table> | ||
| <TableHead | ||
| columns={columns} | ||
| hasBulkSelect={!!bulkSelect} | ||
| isExpandable={!!expandable} | ||
| /> | ||
| <TableBody | ||
| columns={columns} | ||
| rows={rows} | ||
| total={total} | ||
| bulkSelect={bulkSelect} | ||
| expandable={expandable} | ||
| /> | ||
| </Table> | ||
| ); | ||
| }; | ||
|
|
||
| export default ComposableTable; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import React from 'react'; | ||
| import propTypes from 'prop-types'; | ||
| import { Td } from '@patternfly/react-table'; | ||
|
|
||
| const Cell = ({ row, column: { title, key, Component } }) => ( | ||
| <Td> | ||
| {Component ? ( | ||
| <Component {...row.item} /> | ||
| ) : ( | ||
| row.item[key || title?.toLowerCase()] | ||
| )} | ||
| </Td> | ||
| ); | ||
|
|
||
| Cell.propTypes = { | ||
| row: propTypes.object, | ||
| column: propTypes.object, | ||
| }; | ||
|
|
||
| export default Cell; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import React from 'react'; | ||
| import propTypes from 'prop-types'; | ||
| import { Tbody, Td, Tr } from '@patternfly/react-table'; | ||
|
|
||
| import NoResultsTable from '~/components/NoResultsTable'; | ||
|
|
||
| import Cell from './Cell'; | ||
|
|
||
| const TableBody = ({ total, columns, rows, bulkSelect, expandable }) => ( | ||
|
Check failure on line 9 in src/components/TableToolsTable/components/ComposableTable/components/TableBody.js
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| <Tbody> | ||
| {total === 0 ? ( | ||
| <Tr> | ||
| <Td colSpan={columns?.length + (bulkSelect ? 1 : 0)}> | ||
| <NoResultsTable /> | ||
| </Td> | ||
| </Tr> | ||
| ) : ( | ||
| rows?.map((row, idx) => ( | ||
| <Tr key={row?.item?.id || idx}> | ||
| {!!expandable && ( | ||
| <Td | ||
| {...(expandable | ||
| ? { | ||
| expand: { | ||
| rowIndex: idx, | ||
| isExpanded: expandable.isExpanded(row?.item?.itemId), | ||
|
Check failure on line 26 in src/components/TableToolsTable/components/ComposableTable/components/TableBody.js
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| onToggle: () => expandable.onToggle(row?.item?.itemId), | ||
|
Check failure on line 27 in src/components/TableToolsTable/components/ComposableTable/components/TableBody.js
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }, | ||
| } | ||
| : {})} | ||
| /> | ||
| )} | ||
| {!!bulkSelect && ( | ||
| <Td | ||
| {...(bulkSelect | ||
| ? { | ||
| select: { | ||
| rowIndex: idx, | ||
| onSelect: () => bulkSelect.selectOne(row?.item), | ||
|
Check failure on line 39 in src/components/TableToolsTable/components/ComposableTable/components/TableBody.js
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| isSelected: bulkSelect.isItemSelected(row?.item?.itemId), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }, | ||
| } | ||
| : {})} | ||
| /> | ||
| )} | ||
|
|
||
| {columns.map((column) => ( | ||
| <Cell key={column.title + `-${idx}`} row={row} column={column} /> | ||
| ))} | ||
| </Tr> | ||
| )) | ||
| )} | ||
| </Tbody> | ||
| ); | ||
|
|
||
| TableBody.propTypes = { | ||
| rows: propTypes.array, | ||
| columns: propTypes.array, | ||
| }; | ||
|
|
||
| export default TableBody; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import React from 'react'; | ||
| import propTypes from 'prop-types'; | ||
| import { Thead, Tr, Th } from '@patternfly/react-table'; | ||
|
|
||
| const TableHead = ({ columns, hasBulkSelect, isExpandable }) => ( | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| <Thead> | ||
| <Tr> | ||
| {hasBulkSelect && <Th />} | ||
| {isExpandable && <Th />} | ||
| {columns.map(({ title, sortable }, idx) => ( | ||
| <Th | ||
| key={title} | ||
| {...(sortable | ||
| ? { | ||
| sort: { | ||
| columnIndex: idx, | ||
| sortBy: { property: sortable }, | ||
| onSort: (_event, index, direction, ...args) => { | ||
| console.log(_event, index, direction, ...args); | ||
| }, | ||
| }, | ||
| } | ||
| : {})} | ||
| > | ||
| {title} | ||
| </Th> | ||
| ))} | ||
| </Tr> | ||
| </Thead> | ||
| ); | ||
|
|
||
| TableHead.propTypes = { | ||
| columns: propTypes.object, | ||
| hasBulkSelect: propTypes.bool, | ||
| }; | ||
|
|
||
| export default TableHead; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| import { useMemo } from 'react'; | ||
|
|
||
| /** | ||
|
Check warning on line 3 in src/components/TableToolsTable/components/ComposableTable/hooks/useTableToolsForComposable.js
|
||
| * This hook is an adapter to put required props into the right place and | ||
| * form to be consumable by the ComposableTable components | ||
| * | ||
| * @param {object} [options] AsyncTableTools options | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Found 11 issues: |
||
| * | ||
| * @returns {object} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing JSDoc @returns description. [eslint:jsdoc/require-returns-description] |
||
| * | ||
| * @group Hooks | ||
| * | ||
|
qltysh[bot] marked this conversation as resolved.
qltysh[bot] marked this conversation as resolved.
Comment on lines
+3
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Found 11 issues: |
||
| */ | ||
| const useTableToolsForComposable = ({ | ||
| loading, | ||
| view, | ||
| total, | ||
| bulkSelect, | ||
| expandable, | ||
| tableProps: { cells: columns, rows, tableTree }, | ||
| toolbarProps: { pagination }, | ||
| }) => { | ||
| const composableReturn = useMemo( | ||
| () => ({ | ||
| columns, | ||
| rows, | ||
| tableTree, | ||
| loading, | ||
| view, | ||
| pagination, | ||
| bulkSelect, | ||
| expandable, | ||
| total, | ||
| }), | ||
| [ | ||
| columns, | ||
| rows, | ||
| tableTree, | ||
| loading, | ||
| view, | ||
| pagination, | ||
| bulkSelect, | ||
| total, | ||
| expandable, | ||
| ], | ||
| ); | ||
|
|
||
| return composableReturn; | ||
| }; | ||
|
|
||
| export default useTableToolsForComposable; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 2 issues:
1. 'useContext' is defined but never used. [eslint:@typescript-eslint/no-unused-vars]
2. 'useContext' is defined but never used. [eslint:no-unused-vars]