Skip to content

Commit

Permalink
selectable table
Browse files Browse the repository at this point in the history
  • Loading branch information
priley86 committed Jan 30, 2019
1 parent b23bde8 commit 3a002eb
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,40 @@ import { css } from '@patternfly/react-styles';
import { tableCheck } from '@patternfly/patternfly-next/components/Table/table.css';
import SelectColumn from '../../SelectColumn';

export default (label, { column: { extraParams: { onSelect, rowLabeledBy = 'simple-node' } }, rowIndex, rowData }) => {
export default (
label,
{
column: {
extraParams: { onSelect, rowLabeledBy = 'simple-node' }
},
rowIndex,
rowData
}
) => {
const rowId = rowIndex !== undefined ? rowIndex : -1;
function selectClick(event) {
let selected = rowIndex === undefined ? event.target.checked : rowData && !rowData.selected;
onSelect && onSelect(selected, selected, rowId);
const selected = rowIndex === undefined ? event.target.checked : rowData && !rowData.selected;
onSelect && onSelect(event, selected, rowId, rowData);
}
const customProps = {
...rowId !== -1 ? {
checked: rowData && !!rowData.selected,
'aria-labelledby': rowLabeledBy + rowIndex
} : {
'aria-label': 'Select all rows'
}
}
...(rowId !== -1
? {
checked: rowData && !!rowData.selected,
'aria-labelledby': rowLabeledBy + rowIndex
}
: {
'aria-label': 'Select all rows'
})
};

return ({
return {
className: css(tableCheck),
component: 'td',
scope: '',
children: (
<SelectColumn {...customProps} onSelect={selectClick} name={rowId !== -1 ? `checkrow${rowIndex}` : 'check-all'}>{label}</SelectColumn>
<SelectColumn {...customProps} onSelect={selectClick} name={rowId !== -1 ? `checkrow${rowIndex}` : 'check-all'}>
{label}
</SelectColumn>
)
});
}
};
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { isEqual } from 'lodash-es';
import { resolveRowKey } from 'reactabular-table';
import { TableBody, TableContext } from '@patternfly/react-table';
import calculateAverageHeight from './utils/calculateAverageHeight';
Expand Down Expand Up @@ -63,9 +62,10 @@ class Body extends React.Component {
this.props.container().addEventListener('scroll', this.onScroll);
}, 0);
}
componentDidUpdate() {
this.checkMeasurements();
componentDidUpdate(prevProps) {
this.checkMeasurements(prevProps);
}

componentWillUnmount() {
clearTimeout(this.timeoutId);
}
Expand All @@ -78,22 +78,6 @@ class Body extends React.Component {
return props.height || props.style.maxHeight;
}

// todo: convert `componentWillReceiveProps` to `getDerivedStateFromProps`
componentWillReceiveProps(nextProps) {
if (!isEqual(this.props.rows, nextProps.rows) || this.getHeight(this.props) !== this.getHeight(nextProps)) {
if (process.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && window.LOG_VIRTUALIZED) {
console.log('invalidating measurements'); // eslint-disable-line no-console
}

const rows = this.calculateRows(nextProps);

if (!rows) {
return;
}

this.setState(rows);
}
}
render() {
const { onRow, rows, onScroll, container, ...props } = this.props;
const { startIndex, amountOfRowsToRender, startHeight, endHeight, showExtraRow } = this.state;
Expand Down Expand Up @@ -128,7 +112,7 @@ class Body extends React.Component {
);
}

const tableBody = React.createElement(TableBody, {
const tableBodyProps = {
...props,
style: { height, display: 'block', overflow: 'auto' },
onRow: (row, extra) => {
Expand All @@ -142,7 +126,7 @@ class Body extends React.Component {
},
rowsToRender,
onScroll: this.onScroll
});
};

return (
<VirtualizedBodyContext.Provider
Expand All @@ -158,7 +142,7 @@ class Body extends React.Component {
initialMeasurement: this.initialMeasurement
}}
>
{tableBody}
<TableBody {...tableBodyProps} />
</VirtualizedBodyContext.Provider>
);
}
Expand All @@ -184,29 +168,7 @@ class Body extends React.Component {

this.setState(this.calculateRows(this.props));
}
// getRef() {
// const { ref } = this;

// ref.scrollTo = index => {
// const startIndex = parseInt(index, 10);

// if (startIndex >= 0) {
// const startHeight =
// calculateAverageHeight({
// measuredRows: this.measuredRows,
// rows: this.props.rows,
// rowKey: this.props.rowKey
// }) * startIndex;

// this.scrollTop = startHeight;
// this.ref.scrollTop = startHeight;

// this.setState(this.calculateRows(this.props));
// }
// };

// return ref;
// }
calculateRows(props) {
return calculateRows({
scrollTop: this.scrollTop,
Expand All @@ -216,11 +178,16 @@ class Body extends React.Component {
rows: props.rows
});
}
checkMeasurements() {
// If there are no valid measurements, calculate some after waiting a while.
// Without this styling solutions like Radium won't work as you might expect
// given they can take a while to set container height.
if (this.initialMeasurement) {
checkMeasurements(prevProps) {
// If there are no valid measurements or the rows have changed,
// calculate some after waiting a while. Without this styling solutions
// like Radium won't work as you might expect given they can take a while to set container height.
if (this.initialMeasurement || (prevProps && prevProps.rows !== this.props.rows)) {
// If the rows have changed, but the user has not scrolled, maintain the existing
// scroll position
if (this.ref.current) {
this.ref.current.scrollTop = this.scrollTop;
}
this.timeoutId = setTimeout(() => {
const rows = this.calculateRows(this.props);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
import AutoSizerExample from './examples/AutoSizerExample';
import VirtualizedExample from './examples/VirtualizedExample';
import SortableExample from './examples/SortableExample';
import SelectableExample from './examples/SelectableExample';
import './examples/common/styles';

export default {
title: 'Virtualized',
Expand All @@ -19,6 +21,7 @@ export default {
examples: [
{ component: AutoSizerExample, title: 'Simple AutoSizer Example' },
{ component: VirtualizedExample, title: 'Simple Virtualized Example' },
{ component: SortableExample, title: 'Sortable Virtualized Example' }
{ component: SortableExample, title: 'Sortable Virtualized Example' },
{ component: SelectableExample, title: 'Selectable Virtualized Example' }
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import { Table, TableHeader, headerCol } from '@patternfly/react-table';
import {
VirtualizedBody,
VirtualizedBodyWrapper,
VirtualizedRowWrapper
} from '@patternfly/react-virtualized-extension';

class SelectableExample extends React.Component {
constructor(props) {
super(props);
const rows = [];
for (let i = 0; i < 100; i++) {
rows.push({
id: i,
cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
});
}
this.state = {
columns: [
{ title: 'Repositories', cellTransforms: [headerCol()] },
{ title: 'Branches' },
{ title: 'Pull requests' },
{ title: 'Workspaces' },
{ title: 'Last Commit' }
],
rows
};
this.onSelect = this.onSelect.bind(this);
}

onSelect(event, isSelected, virtualRowIndex, rowData) {
let rows;
if (virtualRowIndex === -1) {
rows = this.state.rows.map(oneRow => {
oneRow.selected = isSelected;
return oneRow;
});
} else {
rows = [...this.state.rows];
const rowIndex = rows.findIndex(r => r.id === rowData.id);
rows[rowIndex].selected = isSelected;
}
this.setState({
rows
});
}

render() {
const { columns, rows } = this.state;

return (
<Table
className="pf-c-virtualized"
caption="Selectable Virtualized Table"
onSelect={this.onSelect}
cells={columns}
rows={rows}
bodyWrapper={VirtualizedBodyWrapper}
rowWrapper={VirtualizedRowWrapper}
>
<TableHeader />
<VirtualizedBody height={400} rowKey="id" />
</Table>
);
}
}

export default SelectableExample;
Original file line number Diff line number Diff line change
Expand Up @@ -5,53 +5,28 @@ import {
VirtualizedBodyWrapper,
VirtualizedRowWrapper
} from '@patternfly/react-virtualized-extension';
// import './sample.css';

class SortableExample extends React.Component {
static title = 'Simple Table';
static title = 'Sortable Table';
constructor(props) {
super(props);

this.tableBody = React.createRef();
this.tableStyles = {
table: {
display: 'flex',
flexFlow: 'column'
},
thead: {
display: 'table',
tableLayout: 'fixed',
width: '100%'
},
tbody: {
display: 'block',
overflowY: 'scroll'
},
tr: {
display: 'table',
tableLayout: 'fixed',
width: '100%'
},
td: {
width: '20%'
}
};

const rows = [];
for (let i = 0; i < 100; i++) {
rows.push({
id: i,
props: { style: this.tableStyles.tr },
cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
});
}
this.state = {
columns: [
{ title: 'Repositories', transforms: [sortable], props: { style: this.tableStyles.td } },
{ title: 'Branches', props: { style: this.tableStyles.td } },
{ title: 'Pull requests', transforms: [sortable], props: { style: this.tableStyles.td } },
{ title: 'Workspaces', props: { style: this.tableStyles.td } },
{ title: 'Last Commit', props: { style: this.tableStyles.td } }
{ title: 'Repositories', transforms: [sortable] },
{ title: 'Branches' },
{ title: 'Pull requests', transforms: [sortable] },
{ title: 'Workspaces' },
{ title: 'Last Commit' }
],
rows,
sortBy: {}
Expand All @@ -78,7 +53,6 @@ class SortableExample extends React.Component {

return (
<Table
style={this.tableStyles.table}
caption="Sortable Virtualized Table"
className="pf-c-virtualized"
cells={columns}
Expand All @@ -88,8 +62,8 @@ class SortableExample extends React.Component {
sortBy={sortBy}
onSort={this.onSort}
>
<TableHeader style={this.tableStyles.thead} />
<VirtualizedBody height={400} rowKey="id" tableBody={this.tableBody} style={this.tableStyles.tbody} />
<TableHeader />
<VirtualizedBody height={400} rowKey="id" tableBody={this.tableBody} />
</Table>
);
}
Expand Down
Loading

0 comments on commit 3a002eb

Please sign in to comment.