From 9e437ed121dee68ada67b10930cb6a398aa32cf2 Mon Sep 17 00:00:00 2001 From: Abby George Date: Mon, 2 Mar 2020 09:42:10 -0500 Subject: [PATCH] :sparkles: Expanding reference table rows to show reference IDs On clicking a row in the reference table, a list of IDs that reference the given ID are show. --- src/components/tables/ReferenceTable.js | 26 ++++---- src/components/tables/SortableTable.css | 6 ++ src/components/tables/SortableTable.js | 80 +++++++++++++++++++------ 3 files changed, 82 insertions(+), 30 deletions(-) diff --git a/src/components/tables/ReferenceTable.js b/src/components/tables/ReferenceTable.js index d90fd9c..c14e629 100644 --- a/src/components/tables/ReferenceTable.js +++ b/src/components/tables/ReferenceTable.js @@ -32,18 +32,22 @@ class ReferenceTable extends React.Component { ); let uniqueReferences = {}; references.forEach(reference => { - const mapValue = - uniqueReferences[ - [reference.resourceType, reference.name, reference.profile] - ]; + const mapValue = uniqueReferences[reference.profile]; if (!!mapValue) { - uniqueReferences[ - [reference.resourceType, reference.name, reference.profile] - ] = {...mapValue, total: mapValue.total + 1}; + uniqueReferences[reference.profile] = { + ...mapValue, + total: mapValue.total + 1, + children: mapValue.children.concat(reference), + }; } else { - uniqueReferences[ - [reference.resourceType, reference.name, reference.profile] - ] = {...reference, total: 1}; + uniqueReferences[reference.profile] = { + id: `${reference.resourceType}-${reference.name}`, + resourceType: reference.resourceType, + name: reference.name, + profile: reference.profile, + total: 1, + children: [reference], + }; } }); const referenceData = Object.values(uniqueReferences); @@ -68,7 +72,7 @@ class ReferenceTable extends React.Component { ) : null} diff --git a/src/components/tables/SortableTable.css b/src/components/tables/SortableTable.css index a1a6014..abe51cf 100644 --- a/src/components/tables/SortableTable.css +++ b/src/components/tables/SortableTable.css @@ -16,3 +16,9 @@ .sortable-table td:hover { background-color: var(--d3b-hoverblue); } + +.sortable-table__child-row:hover, +.sortable-table__child-row td:hover { + background-color: inherit !important; + cursor: default; +} diff --git a/src/components/tables/SortableTable.js b/src/components/tables/SortableTable.js index ed91861..9490e41 100644 --- a/src/components/tables/SortableTable.js +++ b/src/components/tables/SortableTable.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Table} from 'semantic-ui-react'; +import {Table, Icon} from 'semantic-ui-react'; import _ from 'lodash'; import './SortableTable.css'; @@ -11,6 +11,7 @@ class SortableTable extends React.Component { sortColumn: props.headerCells[0].sortId, sortDirection: 'ascending', sortedData: _.sortBy(props.data, props.headerCells[0].sortId), + activeIndex: -1, }; } @@ -25,13 +26,13 @@ class SortableTable extends React.Component { handleSort = selectedColumn => { const {sortColumn, sortDirection, sortedData} = this.state; - if (sortColumn !== selectedColumn) { + if (selectedColumn && sortColumn !== selectedColumn) { this.setState({ sortColumn: selectedColumn, sortedData: _.sortBy(sortedData, [selectedColumn]), sortDirection: 'ascending', }); - } else { + } else if (selectedColumn) { this.setState({ sortedData: sortedData.reverse(), sortDirection: @@ -40,8 +41,23 @@ class SortableTable extends React.Component { } }; + toggleIndex = index => { + const currentIndex = this.state.activeIndex; + this.setState({ + activeIndex: currentIndex === index ? -1 : index, + }); + }; + + renderIcon = index => + this.state.activeIndex === index ? 'caret up' : 'caret down'; + + onRowClick = (item, index) => { + this.toggleIndex(index); + this.props.onRowClick(item); + }; + render() { - const {headerCells, onRowClick} = this.props; + const {headerCells, rowChildren} = this.props; const {sortDirection, sortColumn, sortedData} = this.state; return ( @@ -62,21 +78,45 @@ class SortableTable extends React.Component { {sortedData.map((item, i) => ( - onRowClick(item)} - > - {headerCells.map(cell => ( - - {cell.func && item[cell.sortId] !== null - ? cell.func(item[cell.sortId]) - : null} - {!cell.func && item[cell.sortId] !== null - ? item[cell.sortId] - : null} - - ))} - + + this.onRowClick(item, i)} + > + {headerCells.map((cell, j) => { + const icon = + rowChildren && j === 0 ? ( + this.toggleIndex(i)} + /> + ) : null; + return ( + + {icon} + {cell.sortId && cell.func && item[cell.sortId] !== null + ? cell.func(item[cell.sortId]) + : null} + {cell.sortId && !cell.func && item[cell.sortId] !== null + ? item[cell.sortId] + : null} + + ); + })} + + {this.props.rowChildren && this.state.activeIndex === i + ? item.children.map((child, j) => ( + + +

{child.id}

+
+
+ )) + : null} +
))}
@@ -98,12 +138,14 @@ SortableTable.propTypes = { id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, }), ), + rowChildren: PropTypes.bool, onRowClick: PropTypes.func, }; SortableTable.defaultProps = { headerCells: [], data: [], + rowChildren: false, onRowClick: () => {}, };