+type DataExplorerProps<T> = DataExplorerDataProps<T> & WithStyles<CssRules>;
+
+export const DataExplorer = withStyles(styles)(
+ class DataExplorerGeneric<T> extends React.Component<DataExplorerProps<T>> {
+ render() {
+ return <Paper>
+ <Toolbar className={this.props.classes.toolbar}>
+ <Grid container justify="space-between" wrap="nowrap" alignItems="center">
+ <div className={this.props.classes.searchBox}>
+ <SearchInput
+ value={this.props.searchValue}
+ onSearch={this.props.onSearch}/>
+ </div>
+ <ColumnSelector
+ columns={this.props.columns}
+ onColumnToggle={this.props.onColumnToggle}/>
+ </Grid>
+ </Toolbar>
+ <DataTable
+ columns={[...this.props.columns, this.contextMenuColumn]}
+ items={this.props.items}
+ onRowClick={(_, item: T) => this.props.onRowClick(item)}
+ onContextMenu={this.props.onContextMenu}
+ onRowDoubleClick={(_, item: T) => this.props.onRowDoubleClick(item)}
+ onFiltersChange={this.props.onFiltersChange}
+ onSortToggle={this.props.onSortToggle}
+ extractKey={this.props.extractKey}/>
+ <Toolbar>
+ {this.props.items.length > 0 &&
+ <Grid container justify="flex-end">
+ <TablePagination
+ count={this.props.itemsAvailable}
+ rowsPerPage={this.props.rowsPerPage}
+ rowsPerPageOptions={this.props.rowsPerPageOptions}
+ page={this.props.page}
+ onChangePage={this.changePage}
+ onChangeRowsPerPage={this.changeRowsPerPage}
+ component="div"
+ />
+ </Grid>}
+ </Toolbar>
+ </Paper>;
+ }
+
+ changePage = (event: React.MouseEvent<HTMLButtonElement>, page: number) => {
+ this.props.onChangePage(page);
+ }
+
+ changeRowsPerPage: React.ChangeEventHandler<HTMLTextAreaElement | HTMLInputElement> = (event) => {
+ this.props.onChangeRowsPerPage(parseInt(event.target.value, 10));
+ }
+
+ renderContextMenuTrigger = (item: T) =>
+ <Grid container justify="flex-end">
+ <IconButton onClick={event => this.props.onContextMenu(event, item)}>
+ <MoreVertIcon/>
+ </IconButton>