X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/24fc2a5a701dd4bb6edf503efee992942ea5b667..28a7883c373533979f2cc7c5e750221eb8f5f1ec:/src/components/data-table/data-table.tsx diff --git a/src/components/data-table/data-table.tsx b/src/components/data-table/data-table.tsx index 6a02d7e6..22131f00 100644 --- a/src/components/data-table/data-table.tsx +++ b/src/components/data-table/data-table.tsx @@ -3,18 +3,33 @@ // SPDX-License-Identifier: AGPL-3.0 import React from 'react'; -import { Table, TableBody, TableRow, TableCell, TableHead, TableSortLabel, StyleRulesCallback, Theme, WithStyles, withStyles, IconButton } from '@material-ui/core'; +import { + Table, + TableBody, + TableRow, + TableCell, + TableHead, + TableSortLabel, + StyleRulesCallback, + Theme, + WithStyles, + withStyles, + IconButton, + Tooltip, +} from '@material-ui/core'; import classnames from 'classnames'; import { DataColumn, SortDirection } from './data-column'; import { DataTableDefaultView } from '../data-table-default-view/data-table-default-view'; import { DataTableFilters } from '../data-table-filters/data-table-filters-tree'; +import { DataTableMultiselectPopover } from '../data-table-multiselect-popover/data-table-multiselect-popover'; import { DataTableFiltersPopover } from '../data-table-filters/data-table-filters-popover'; import { countNodes, getTreeDirty } from 'models/tree'; import { IconType, PendingIcon } from 'components/icon/icon'; import { SvgIconProps } from '@material-ui/core/SvgIcon'; import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward'; -import { Checkbox } from '@material-ui/core'; import { createTree } from 'models/tree'; +import arraysAreCongruent from 'validators/arrays-are-congruent'; +import { DataTableMultiselectOption } from '../data-table-multiselect-popover/data-table-multiselect-popover'; export type DataColumns = Array>; @@ -39,7 +54,19 @@ export interface DataTableDataProps { currentRoute?: string; } -type CssRules = 'tableBody' | 'root' | 'content' | 'noItemsInfo' | 'checkBoxCell' | 'tableCell' | 'arrow' | 'arrowButton' | 'tableCellWorkflows' | 'loader'; +type CssRules = + | 'tableBody' + | 'root' + | 'content' + | 'noItemsInfo' + | 'checkBoxHead' + | 'checkBoxCell' + | 'checkBox' + | 'tableCell' + | 'arrow' + | 'arrowButton' + | 'tableCellWorkflows' + | 'loader'; const styles: StyleRulesCallback = (theme: Theme) => ({ root: { @@ -61,9 +88,15 @@ const styles: StyleRulesCallback = (theme: Theme) => ({ textAlign: 'center', padding: theme.spacing.unit, }, + checkBoxHead: { + padding: '0', + display: 'flex', + }, checkBoxCell: { - // border: '1px dotted green', padding: '0', + paddingLeft: '10px', + }, + checkBox: { cursor: 'pointer', }, tableCell: { @@ -90,69 +123,106 @@ const styles: StyleRulesCallback = (theme: Theme) => ({ }, }); -const handleSelectAll = () => {}; - -const handleDeselectAll = () => {}; - type DataTableState = { + isSelected: boolean; checkedList: Record; }; -type DataTableProps = DataTableDataProps & WithStyles & DataTableState; +const multiselectOptions: DataTableMultiselectOption[] = [ + { name: 'First Option', fn: (checkedList) => console.log('one', checkedList) }, + { name: 'Second Option', fn: (checkedList) => console.log('two', checkedList) }, + { name: 'Third Option', fn: (checkedList) => console.log('three', checkedList) }, +]; + +type DataTableProps = DataTableDataProps & WithStyles; export const DataTable = withStyles(styles)( class Component extends React.Component> { state: DataTableState = { + isSelected: false, checkedList: {}, }; + + componentDidMount(): void { + this.initializeCheckedList(this.props.items); + } + + componentDidUpdate(prevProps: Readonly>, prevState: DataTableState) { + const { items } = this.props; + const { checkedList } = this.state; + if (!arraysAreCongruent(prevProps.items, items)) { + this.state.isSelected = false; + this.initializeCheckedList(items); + } + if (prevState.checkedList !== checkedList) { + window.localStorage.setItem('selectedRows', JSON.stringify(checkedList)); + } + } + checkBoxColumn: DataColumn = { name: 'checkBoxColumn', selected: true, configurable: false, filters: createTree(), - render: (uuid) => this.handleCheck(uuid)}>, + render: (uuid) => ( + this.handleCheck(uuid)} + onDoubleClick={(ev) => ev.stopPropagation()} + > + ), }; - initializeCheckedList = (items: any[]): void => { - const checkedList = this.state; - for (const uuid in checkedList) { - if (checkedList.hasOwnProperty(uuid)) { - delete checkedList[uuid]; - } - } - items.forEach((uuid) => { - if (!checkedList.hasOwnProperty[uuid]) { + initializeCheckedList = (uuids: any[]): void => { + const { checkedList } = this.state; + uuids.forEach((uuid) => { + if (!checkedList.hasOwnProperty(uuid)) { checkedList[uuid] = false; } }); + for (const key in checkedList) { + if (!uuids.includes(key)) { + delete checkedList[key]; + } + } + window.localStorage.setItem('selectedRows', JSON.stringify(checkedList)); }; - componentDidUpdate(prevProps: Readonly>): void { - if (prevProps.items !== this.props.items) { - this.initializeCheckedList(this.props.items); + handleSelectorSelect = (): void => { + const { isSelected, checkedList } = this.state; + const newCheckedList = { ...checkedList }; + for (const key in newCheckedList) { + newCheckedList[key] = !isSelected; } - } + this.setState({ isSelected: !isSelected, checkedList: newCheckedList }); + }; - handleCheck = async (uuid: string) => { - const checkedList = this.state; + handleCheck = (uuid: string): void => { + const { checkedList } = this.state; const newCheckedList = { ...checkedList }; newCheckedList[uuid] = !checkedList[uuid]; - await this.setState(newCheckedList); + this.setState({ checkedList: newCheckedList }); }; + + handleInvertSelect = (): void => { + const { checkedList } = this.state; + const newCheckedList = { ...checkedList }; + for (const key in newCheckedList) { + newCheckedList[key] = !checkedList[key]; + } + this.setState({ checkedList: newCheckedList }); + }; + render() { const { items, classes, working, columns } = this.props; - if (columns[0].name !== this.checkBoxColumn.name) columns.unshift(this.checkBoxColumn); - const firstBox: HTMLInputElement | null = document.querySelector('input[type="checkbox"]'); + if (columns[0].name === this.checkBoxColumn.name) columns.shift(); + columns.unshift(this.checkBoxColumn); return (
- {this.mapVisibleColumns(this.renderHeadCell)} @@ -178,10 +248,14 @@ export const DataTable = withStyles(styles)( renderHeadCell = (column: DataColumn, index: number) => { const { name, key, renderHeader, filters, sort } = column; const { onSortToggle, onFiltersChange, classes } = this.props; - return index === 0 ? ( + return column.name === 'checkBoxColumn' ? ( -
select all
-
deselect all
+
+ + + + +
) : (