Adapting sorting to accept custom fields in Table component

This commit is contained in:
apanizo 2018-10-18 12:19:08 +02:00
parent d00cf82bda
commit 3891f3c1a5
3 changed files with 31 additions and 28 deletions

View File

@ -5,27 +5,26 @@ import TableCell from '@material-ui/core/TableCell'
import TableHead from '@material-ui/core/TableHead' import TableHead from '@material-ui/core/TableHead'
import TableRow from '@material-ui/core/TableRow' import TableRow from '@material-ui/core/TableRow'
import TableSortLabel from '@material-ui/core/TableSortLabel' import TableSortLabel from '@material-ui/core/TableSortLabel'
import Tooltip from '@material-ui/core/Tooltip'
import { type Order } from '~/components/Table/sorting' import { type Order } from '~/components/Table/sorting'
export type Column = { export type Column = {
id: string, id: string,
numeric: boolean, numeric: boolean,
order: boolean,
disablePadding: boolean, disablePadding: boolean,
label: string, label: string,
tooltip?: string,
} }
type Props = { type Props = {
columns: List<Column>, columns: List<Column>,
orderBy: string, // id of one of the described columns orderBy: string, // id of one of the described columns
order: Order, order: Order,
onSort: (property: string) => void, onSort: (property: string, orderAttr: boolean) => void,
} }
class GnoTableHead extends React.PureComponent<Props> { class GnoTableHead extends React.PureComponent<Props> {
changeSort = (property: string) => () => { changeSort = (property: string, orderAttr: boolean) => () => {
this.props.onSort(property) this.props.onSort(property, orderAttr)
} }
render() { render() {
@ -41,19 +40,13 @@ class GnoTableHead extends React.PureComponent<Props> {
padding={column.disablePadding ? 'none' : 'default'} padding={column.disablePadding ? 'none' : 'default'}
sortDirection={orderBy === column.id ? order : false} sortDirection={orderBy === column.id ? order : false}
> >
<Tooltip <TableSortLabel
title={column.tooltip} active={orderBy === column.id}
placement={column.numeric ? 'bottom-end' : 'bottom-start'} direction={order}
enterDelay={300} onClick={this.changeSort(column.id, column.order)}
> >
<TableSortLabel {column.label}
active={orderBy === column.id} </TableSortLabel>
direction={order}
onClick={this.changeSort(column.id)}
>
{column.label}
</TableSortLabel>
</Tooltip>
</TableCell> </TableCell>
))} ))}
</TableRow> </TableRow>

View File

@ -20,6 +20,7 @@ type State = {
page: number, page: number,
order: Order, order: Order,
orderBy: string, orderBy: string,
orderProp: boolean,
} }
class GnoTable<K> extends React.Component<Props<K>, State> { class GnoTable<K> extends React.Component<Props<K>, State> {
@ -27,9 +28,10 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
page: 0, page: 0,
order: 'desc', order: 'desc',
orderBy: this.props.defaultOrderBy, orderBy: this.props.defaultOrderBy,
orderProp: false,
} }
onSort = (property: string) => { onSort = (property: string, orderProp: boolean) => {
const orderBy = property const orderBy = property
let order = 'desc' let order = 'desc'
@ -37,14 +39,16 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
order = 'asc' order = 'asc'
} }
this.setState({ order, orderBy }) this.setState({ order, orderBy, orderProp })
} }
render() { render() {
const { const {
data, label, columns, rowsPerPage = 5, data, label, columns, rowsPerPage = 5,
} = this.props } = this.props
const { order, orderBy, page } = this.state const {
order, orderBy, page, orderProp,
} = this.state
return ( return (
<Table aria-labelledby={label}> <Table aria-labelledby={label}>
@ -55,12 +59,12 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
onSort={this.onSort} onSort={this.onSort}
/> />
<TableBody> <TableBody>
{stableSort(data, getSorting(order, orderBy)) {stableSort(data, getSorting(order, orderBy, orderProp))
.slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage)) .slice(page * rowsPerPage, ((page * rowsPerPage) + rowsPerPage))
.map((row: any) => ( .map((row: any, index: number) => (
<TableRow <TableRow
tabIndex={-1} tabIndex={-1}
key={row.id} key={index}
> >
{ {
columns.map((column: Column) => ( columns.map((column: Column) => (

View File

@ -1,11 +1,17 @@
// @flow // @flow
const desc = (a, b, orderBy) => {
if (b[orderBy] < a[orderBy]) { export const buildOrderFieldFrom = (attr: string) => `${attr}Order`
const desc = (a: Object, b: Object, orderBy: string, orderProp: boolean) => {
const order = orderProp ? buildOrderFieldFrom(orderBy) : orderBy
if (b[order] < a[order]) {
return -1 return -1
} }
if (b[orderBy] > a[orderBy]) { if (b[order] > a[order]) {
return 1 return 1
} }
return 0 return 0
} }
@ -26,5 +32,5 @@ export const stableSort = (array: any, cmp: any) => {
export type Order = 'asc' | 'desc' export type Order = 'asc' | 'desc'
export const getSorting = (order: Order, orderBy: string) => export const getSorting = (order: Order, orderBy: string, orderProp: boolean) =>
(order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy) : (a: any, b: any) => -desc(a, b, orderBy)) (order === 'desc' ? (a: any, b: any) => desc(a, b, orderBy, orderProp) : (a: any, b: any) => -desc(a, b, orderBy, orderProp))