Skip to content
This repository has been archived by the owner on Jun 21, 2019. It is now read-only.

Commit

Permalink
Support async data manager #3
Browse files Browse the repository at this point in the history
* Basic support for async data manager
* Still need to support loading indicators and update doc and examples
  • Loading branch information
Rémi Koenig committed Oct 29, 2016
1 parent 70abcdd commit ce25052
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 32 deletions.
18 changes: 11 additions & 7 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ <h3>Custom data manager</h3>
<pre><code class="language-jsx">import {Table, Column} from ReactTisch;

const dataManager = {
getItemCount: () => 2,
getFilterOptions: () => [[]],
// Note: getVisibleRows should take into account the state (searchText, selectedFilters, etc). Refer to the
// Note: visibleRows should take into account the state (searchText, selectedFilters, etc). Refer to the
// documentation for more details.
getVisibleRows: (state) => [{index: 0, data: {name: 'Joe'}}, {index: 1, data: {name: 'Mike'}}]
getData: (state) => ({
itemCount: 2,
filterOptions: [[]],
visibleRows: [{index: 0, data: {name: 'Joe'}}, {index: 1, data: {name: 'Mike'}}]
})
};

&lt;Table dataManager={dataManager}&gt;
Expand Down Expand Up @@ -134,9 +136,11 @@ <h3>Custom data manager</h3>
);

const dataManager = {
getItemCount: () => 2,
getFilterOptions: () => [[]],
getVisibleRows: (state) => [{index: 0, data: {name: 'Joe'}}, {index: 1, data: {name: 'Mike'}}]
getData: (state) => ({
itemCount: 2,
filterOptions: [[]],
visibleRows: [{index: 0, data: {name: 'Joe'}}, {index: 1, data: {name: 'Mike'}}]
})
};

ReactDOM.render(
Expand Down
21 changes: 13 additions & 8 deletions src/DataManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,26 @@ class DataManager {
}));
}

getItemCount() {
return this.itemCount;
}

getFilterOptions() {
return this.uniqueValues;
}

getVisibleRows({selectedFilters, sortColumn, sortOrder, itemsPerPage, activePage, searchText}) {
let sortedAndFilteredRowIndexes = this.sortedRowIndexes(sortColumn, sortOrder)
.filter(rowIndex => this.doesRowMatchFilters(rowIndex, selectedFilters))
.filter(rowIndex => this.doesRowMatchSearch(rowIndex, searchText));

return this.paginatedRows(sortedAndFilteredRowIndexes, activePage, itemsPerPage);
}

getData(state, onLoad) {
/*
* Only required public member of DataManager.
* It doesn't have to return data: for an async data manager, it can call the onLoad callback provided in the
* second argument when data is ready.
*/
return {
visibleRows: this.getVisibleRows(state),
itemCount: this.itemCount,
filterOptions: this.uniqueValues
};
}
}

export default DataManager;
46 changes: 32 additions & 14 deletions src/TableController.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ class TableController extends React.Component {
activePage: 1,
searchText: '',
selectedRows: {},
canSelectRows: false
canSelectRows: false,
forcedRedrawData: null
};

static propTypes = {
Expand Down Expand Up @@ -41,50 +42,67 @@ class TableController extends React.Component {
this.updateStateFromProps(this.props);
}

_setState(newState) {
this.setState({
forcedRedrawData: null,
...newState
});
}

onSort(sortColumn, sortOrder) {
this.setState({sortColumn, sortOrder});
this._setState({sortColumn, sortOrder});
}

onFilter(selectedFilters) {
this.setState({selectedFilters});
this._setState({selectedFilters});
}

onPageSelect(activePage) {
this.setState({activePage});
this._setState({activePage});
}

onSearch(searchText) {
this.setState({searchText});
this._setState({searchText});
}

onItemsPerPageSelect(itemsPerPage) {
this.setState({itemsPerPage});
this._setState({itemsPerPage});
}

onRowSelection(selectedRows) {
if (this.state.canSelectRows) {
this.setState({selectedRows});
this._setState({selectedRows});
}
}

pageCount() {
let {itemsPerPage, dataManager} = this.state;
return Math.ceil(dataManager.getItemCount() / itemsPerPage);
pageCount(itemCount) {
let {itemsPerPage} = this.state;
return Math.ceil(itemCount / itemsPerPage);
}

onDataUpdate(newData) {
this.setState({
forcedRedrawData: newData
});
}

render() {
let data = this.state.forcedRedrawData ||
this.state.dataManager.getData(this.state, this.onDataUpdate.bind(this));


return (
<TablePresentation
filterOptions={this.state.dataManager.getFilterOptions()}
filterOptions={data.filterOptions}
sortColumn={this.state.sortColumn}
sortOrder={this.state.sortOrder}
selectedFilters={this.state.selectedFilters}
activePage={this.state.activePage}
searchText={this.state.searchText}
pageCount={this.pageCount()}
pageCount={this.pageCount(data.itemCount)}
itemsPerPage={this.state.itemsPerPage}
selectedRows={this.state.selectedRows}
itemCount={this.state.dataManager.getItemCount()}
itemCount={data.itemCount}

onSearch={this.onSearch.bind(this)}
onSort={this.onSort.bind(this)}
Expand All @@ -93,7 +111,7 @@ class TableController extends React.Component {
onItemsPerPageSelect={this.onItemsPerPageSelect.bind(this)}
onRowSelection={this.onRowSelection.bind(this)}

visibleRows={this.state.dataManager.getVisibleRows(this.state)}
visibleRows={data.visibleRows}
>
{this.props.children}
</TablePresentation>
Expand Down
8 changes: 5 additions & 3 deletions test/Table.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ describe('Simple <Table/>', () => {

describe("custom data manager", () => {
const dataManager = {
getItemCount: () => 2,
getFilterOptions: () => [[]],
getVisibleRows: () => [{index: 0, data: {name: 'Joe'}}, {index: 1, data: {name: 'Mike'}}]
getData: () => ({
itemCount: 2,
filterOptions: [[]],
visibleRows: [{index: 0, data: {name: 'Joe'}}, {index: 1, data: {name: 'Mike'}}]
})
};
let testTableWithCustomDataManager = (
<Table dataManager={dataManager}>
Expand Down

0 comments on commit ce25052

Please sign in to comment.