1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { Grid, Paper, Toolbar } from '@material-ui/core';
7 import ContextMenu, { ContextMenuActionGroup } from "../../components/context-menu/context-menu";
8 import ColumnSelector from "../../components/column-selector/column-selector";
9 import DataTable from "../../components/data-table/data-table";
10 import { mockAnchorFromMouseEvent } from "../../components/popover/helpers";
11 import { DataColumn, toggleSortDirection } from "../../components/data-table/data-column";
12 import { DataTableFilterItem } from '../../components/data-table-filters/data-table-filters';
13 import { DataExplorerColumn } from './data-explorer-column';
15 interface DataExplorerProps<T> {
17 columns: Array<DataExplorerColumn<T>>;
18 contextActions: Array<ContextMenuActionGroup<T>>;
19 onRowClick: (item: T) => void;
20 onColumnToggle: (column: DataExplorerColumn<T>) => void;
21 onSortingToggle: (column: DataExplorerColumn<T>) => void;
22 onFiltersChange: (columns: DataExplorerColumn<T>) => void;
25 interface DataExplorerState<T> {
27 anchorEl?: HTMLElement;
32 class DataExplorer<T> extends React.Component<DataExplorerProps<T>, DataExplorerState<T>> {
33 state: DataExplorerState<T> = {
40 {...this.state.contextMenu}
41 actions={this.contextActions}
42 onClose={this.closeContextMenu} />
44 <Grid container justify="flex-end">
46 columns={this.columns}
47 onColumnToggle={this.toggleColumn} />
51 columns={this.columns}
52 items={this.props.items}
53 onRowClick={(_, row: T) => this.props.onRowClick(row)}
54 onRowContextMenu={this.openItemMenuOnRowClick} />
59 get columns(): Array<DataColumn<T>> {
60 return this.props.columns.map((column): DataColumn<T> => ({
61 configurable: column.configurable,
62 filters: column.filters,
64 onFiltersChange: column.filterable ? this.changeFilters(column) : undefined,
65 onSortToggle: column.sortable ? this.toggleSort(column) : undefined,
66 render: column.render,
67 renderHeader: column.renderHeader,
68 selected: column.selected,
69 sortDirection: column.sortDirection
73 get contextActions() {
74 return this.props.contextActions.map(actionGroup =>
75 actionGroup.map(action => ({
77 onClick: (item: T) => {
78 this.closeContextMenu();
84 toggleColumn = (column: DataExplorerColumn<T>) => {
85 this.props.onColumnToggle(column);
88 toggleSort = (column: DataExplorerColumn<T>) => () => {
89 this.props.onSortingToggle(toggleSortDirection(column));
92 changeFilters = (column: DataExplorerColumn<T>) => (filters: DataTableFilterItem[]) => {
93 this.props.onFiltersChange({ ...column, filters });
96 openItemMenuOnRowClick = (event: React.MouseEvent<HTMLElement>, item: T) => {
97 event.preventDefault();
100 anchorEl: mockAnchorFromMouseEvent(event),
106 openItemMenuOnActionsClick = (event: React.MouseEvent<HTMLElement>, item: T) => {
109 anchorEl: event.currentTarget,
115 closeContextMenu = () => {
116 this.setState({ contextMenu: {} });
121 export default DataExplorer;