Skip to content

Commit

Permalink
Merge branch 'enhancement-itemtable-visual-improvements' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
campb303 committed Mar 13, 2021
2 parents 8faa519 + 0799a8f commit 21858cd
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 107 deletions.
227 changes: 120 additions & 107 deletions src/components/ItemTable/ItemTable.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useState } from "react";
import PropTypes from "prop-types";
import { useTable, useFilters, useFlexLayout, useSortBy } from "react-table";
import { Table, TableBody, TableCell, TableHead, TableRow, TableContainer, Box, Grid, ButtonGroup, IconButton, makeStyles, useTheme } from "@material-ui/core";
import { Table, TableBody, TableCell, TableHead, TableRow, TableContainer, Box, Grid, makeStyles, useTheme } from "@material-ui/core";
import { useHistory } from "react-router-dom";
import RelativeTime from "react-relative-time";
import ItemTableFilter from "../ItemTableFilter/"
import ItemTableFilter from "../ItemTableFilter/";
import ItemtTableSortButtons from "../ItemTableSortButtons/";
import { ArrowDownward, ArrowUpward } from "@material-ui/icons";
import ItemTableCell from "../ItemTableCell";
import LastUpdatedCell from "../LastUpdatedCell/";
Expand Down Expand Up @@ -40,6 +41,12 @@ export default function ItemTable({ data, rowCanBeSelected, loading }) {
borderLeftStyle: "solid",
borderColor: theme.palette.type === "light" ? theme.palette.grey[300] : theme.palette.grey[500]
},
tableMargin: {
marginTop: theme.spacing(2)
},
tableHeaderPadding: {
paddingBottom: theme.spacing(2)
},
});
const classes = useStyles();

Expand Down Expand Up @@ -90,116 +97,122 @@ export default function ItemTable({ data, rowCanBeSelected, loading }) {
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow, } = tableInstance;

return (
loading
? (
<Box className={classes.loadingAnnimation}>
<img src={jester} alt="Items are loading." />
</Box>
)
: (
<TableContainer>
<Table
{...getTableProps}
aria-label="Table of Queue Items"
size="small"
>
<TableHead>
{headerGroups.map(headerGroup => (
<TableRow {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<TableCell {...column.getHeaderProps()}>
loading ? (
<Box className={classes.loadingAnnimation}>
<img src={jester} alt="Items are loading." />
</Box>
) : (
<TableContainer>
<Table
{...getTableProps}
aria-label="Table of Queue Items"
size="small"
classes={{ root: classes.tableMargin }}
>
<TableHead>
{headerGroups.map(headerGroup => (
<TableRow {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => {
// Determine sort directions
const isSortedAsc = column.isSorted && !column.isSortedDesc;
const isSortedDesc = column.isSorted && column.isSortedDesc;

return (
<Grid container spacing={0}>
<Grid item sm={10} >
{column.render("Filter")}
</Grid>
<Grid item sm={2} alignItems='center' justify='center'>
<ButtonGroup orientation="vertical" size="small">
<IconButton
size="small"
onClick={(_ => {
const isSortedAsc = column.isSorted && !column.isSortedDesc;
isSortedAsc ? column.clearSortBy() : column.toggleSortBy(false)
})}
>
<ArrowUpward {...column.getSortByToggleProps()}
fontSize="inherit"
color={column.isSorted && column.isSortedDesc === false ? "default" : "disabled"}
/>
</IconButton>
<IconButton
size="small"
onClick={(_ => {
const isSortedDesc = column.isSorted && column.isSortedDesc;
isSortedDesc ? column.clearSortBy() : column.toggleSortBy(true)
})}
>
<ArrowDownward {...column.getSortByToggleProps(column.isSortedDesc)}
fontSize="inherit"
color={column.isSorted && column.isSortedDesc ? "default" : "disabled"}
<TableCell
{...column.getHeaderProps()}
classes={{ root: classes.tableHeaderPadding }}
>
<Grid container spacing={0}>
<Grid item sm={10} >
{column.render("Filter")}
</Grid>
<Grid item sm={2} alignItems='center' justify='center'>
<ItemtTableSortButtons
sortAscArrowProps={{
...column.getSortByToggleProps(),
onClick: _ => (isSortedAsc ? column.clearSortBy() : column.toggleSortBy(false))
}}
sortDescArrowProps={{
...column.getSortByToggleProps(),
onClick: _ => (isSortedDesc ? column.clearSortBy() : column.toggleSortBy(true))
}}
sortDirection={(_ => {
if (isSortedAsc) {
return 'asc';
}
else if (isSortedDesc) {
return 'desc';
}
else {
return undefined;
}
})()}
/>
</IconButton>
</ButtonGroup>
</Grid>
</Grid>
</Grid>
</TableCell>
</Grid>
</TableCell>
))}
</TableRow>
))}
</TableHead>
<TableBody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
let isSelected = selectedRow.queue === row.original.queue && selectedRow.number === row.original.number
return (
<TableRow
hover
onClick={() => {
history.push(`/${row.original.queue}/${row.original.number}`);
setSelectedRow({ queue: row.original.queue, number: row.original.number });
}}
// This functionality should be achieved by using the selected prop and
// overriding the selected class but this applied the secondary color at 0.08% opacity.
// Overridding the root class is a workaround.
classes={{
root: (isSelected && rowCanBeSelected) ? classes.rowSelected : classes.bandedRows,
hover: classes.hoverBackgroundColor
}}
{...row.getRowProps()}
>
{row.cells.map(cell => (
cell.render(_ => {
switch (cell.column.id) {
case "dateReceived":
return (
<ItemTableCell TableCellProps={cell.getCellProps()}>
<RelativeTime value={cell.value} />
</ItemTableCell>
);
case "lastUpdated":
return (
<LastUpdatedCell
time={cell.value}
ItemTableCellProps={cell.getCellProps()}
/>
);
default:
return (
<ItemTableCell TableCellProps={cell.getCellProps()}>
{cell.value}
</ItemTableCell>
);
}
})
))}
);
})}
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
)
))}
</TableHead>

<TableBody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
let isSelected = selectedRow.queue === row.original.queue && selectedRow.number === row.original.number
return (
<TableRow
hover
onClick={() => {
history.push(`/${row.original.queue}/${row.original.number}`);
setSelectedRow({ queue: row.original.queue, number: row.original.number });
}}
// This functionality should be achieved by using the selected prop and
// overriding the selected class but this applied the secondary color at 0.08% opacity.
// Overridding the root class is a workaround.
classes={{
root: (isSelected && rowCanBeSelected) ? classes.rowSelected : classes.bandedRows,
hover: classes.hoverBackgroundColor
}}
{...row.getRowProps()}
>
{row.cells.map(cell => (
cell.render(_ => {
switch (cell.column.id) {
case "dateReceived":
return (
<ItemTableCell TableCellProps={cell.getCellProps()}>
<RelativeTime value={cell.value} />
</ItemTableCell>
);
case "lastUpdated":
return (
<LastUpdatedCell
time={cell.value}
ItemTableCellProps={cell.getCellProps()}
/>
);
default:
return (
<ItemTableCell TableCellProps={cell.getCellProps()}>
{cell.value}
</ItemTableCell>
);
}
})
))}
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
)
);
};
}

ItemTable.propTypes = {
/** Array of items from all active queues to display in table. */
Expand Down
43 changes: 43 additions & 0 deletions src/components/ItemTableSortButtons/ItemTableSortButtons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import PropTypes from "prop-types";
import { ButtonGroup, IconButton } from "@material-ui/core";
import { ArrowDownward, ArrowUpward } from "@material-ui/icons";

export default function ItemTableSortButtons({ sortDirection, sortAscArrowProps, sortDescArrowProps }) {
return (
<ButtonGroup orientation="vertical" size="small">
<IconButton edge="start">
<ArrowUpward
{...sortAscArrowProps}
// Inherit fontsize from containing element to avoid overflow.
fontSize="inherit"
color={sortDirection === 'asc' ? "secondary" : "default"}
/>
</IconButton>
<IconButton edge="start">
<ArrowDownward
{...sortDescArrowProps}
// Inherit fontsize from containing element to avoid overflow.
fontSize="inherit"
color={sortDirection === 'desc' ? "secondary" : "default"}
/>
</IconButton>
</ButtonGroup>
)
}

ItemTableSortButtons.propTypes = {
/** String representing sort direction. */
"sortDirection": PropTypes.oneOf(['asc', 'desc', undefined ]),
/** Props passed to ArrowUpward component. */
"sortAscArrowProps": PropTypes.object,
/** Props passed to ArrowDownward component. */
"sortDescArrowProps": PropTypes.object
};

ItemTableSortButtons.defaultProps = {
"sortDirection": undefined,
"sortAscArrowProps": { onClick: _ => alert("No onClick function set. This does nothing.") },
"sortDescArrowProps": { onClick: _ => alert("No onClick function set. This does nothing.") }
};

68 changes: 68 additions & 0 deletions src/components/ItemTableSortButtons/ItemTableSortButtons.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
The ItemTableSortButtons are used to sort in ascending or descending order based on which button is selected. It is to be used with the [ItemTable](/#/Components/ItemTable).

## Default Usage
```jsx
import React, { useState, useEffect } from "react";
import { Paper, TableCell, } from "@material-ui/core";
import ItemTableFilter from "../ItemTableFilter/";




<TableCell component={Paper}>
<ItemTableFilter label="Queue"/>
<ItemTableSortButtons/>
</TableCell>


```
```jsx static
<ItemTableSortButtons sortDirection="sortDirection" sortAscArrowProps={someObject} sortDescArrowProps={someObject} />

```
Used without any props, the ItemTableSort will display arrows with default styling.


## Sorting by Ascending
If the `sortDirection` prop is passed `asc`, the ItemTableSortButtons will display the active styling for the ascending arrow. If a onClick function is present the table will run that function on button click
```jsx
import React, { useState, useEffect } from "react";
import { Paper, TableCell, } from "@material-ui/core";
import ItemTableFilter from "../ItemTableFilter/";




<TableCell component={Paper}>
<ItemTableFilter label="Queue"/>
<ItemTableSortButtons sortDirection="asc" />
</TableCell>


```
```jsx static
<ItemTableSortButtons sortDirection="asc"/>
```
## Sorting by Descending
If the `sortDirection` prop is passed `desc`, the ItemTableSortButtons will display the active styling for the descending arrow. If a onClick function is present the table will run that function on button click
```jsx
import React, { useState, useEffect } from "react";
import { Paper, TableCell, } from "@material-ui/core";
import ItemTableFilter from "../ItemTableFilter/";




<TableCell component={Paper}>
<ItemTableFilter label="Queue"/>
<ItemTableSortButtons sortDirection="desc" />
</TableCell>


```
```jsx static
<ItemTableSortButtons sortDirection="desc"/>
```



3 changes: 3 additions & 0 deletions src/components/ItemTableSortButtons/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import ItemtTableSortButtons from './ItemTableSortButtons'

export default ItemtTableSortButtons;

0 comments on commit 21858cd

Please sign in to comment.