Add table row mouse event handling props
[arvados.git] / src / components / data-table / data-table.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as React from 'react';
6 import { Table, TableBody, TableRow, TableCell, TableHead, StyleRulesCallback, Theme, WithStyles, withStyles, Typography } from '@material-ui/core';
7 import { DataColumn } from './data-column';
8
9 export interface DataTableProps<T> {
10     items: T[];
11     columns: Array<DataColumn<T>>;
12     onRowClick?: (event: React.MouseEvent<HTMLTableRowElement>, item: T) => void;
13     onRowContextMenu?: (event: React.MouseEvent<HTMLTableRowElement>, item: T) => void;
14 }
15
16 class DataTable<T> extends React.Component<DataTableProps<T> & WithStyles<CssRules>> {
17     render() {
18         const { items, columns, classes, onRowClick, onRowContextMenu } = this.props;
19         return <div className={classes.tableContainer}>
20             {items.length > 0 ?
21                 <Table>
22                     <TableHead>
23                         <TableRow>
24                             {columns
25                                 .filter(column => column.selected)
26                                 .map(({ name, renderHeader, key }, index) =>
27                                     <TableCell key={key || index}>
28                                         {renderHeader ? renderHeader() : name}
29                                     </TableCell>
30                                 )}
31                         </TableRow>
32                     </TableHead>
33                     <TableBody className={classes.tableBody}>
34                         {items
35                             .map((item, index) =>
36                                 <TableRow
37                                     hover
38                                     key={index}
39                                     onClick={event => onRowClick && onRowClick(event, item)}
40                                     onContextMenu={event => onRowContextMenu && onRowContextMenu(event, item)}>
41                                     {columns
42                                         .filter(column => column.selected)
43                                         .map((column, index) => (
44                                             <TableCell key={column.key || index}>
45                                                 {column.render(item)}
46                                             </TableCell>
47                                         ))}
48                                 </TableRow>
49                             )}
50                     </TableBody>
51                 </Table> : <Typography 
52                     className={classes.noItemsInfo}
53                     variant="body2"
54                     gutterBottom>
55                     No items
56                 </Typography>}
57         </div>;
58     }
59 }
60
61 type CssRules = "tableBody" | "tableContainer" | "noItemsInfo";
62
63 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
64     tableContainer: {
65         overflowX: 'auto'
66     },
67     tableBody: {
68         background: theme.palette.background.paper
69     },
70     noItemsInfo: {
71         textAlign: "center",
72         padding: theme.spacing.unit
73     }
74 });
75
76 export default withStyles(styles)(DataTable);