From: Michal Klobukowski Date: Fri, 22 Jun 2018 10:13:00 +0000 (+0200) Subject: Add pagination to data explorer X-Git-Tag: 1.2.0~69^2~3 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/06a247fec429a11fb27c0ebf50ba9c31ffc8d0c2?ds=sidebyside Add pagination to data explorer Feature #13633 Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski --- diff --git a/src/components/data-explorer/data-explorer.test.tsx b/src/components/data-explorer/data-explorer.test.tsx index 8ced6cb3..152d0369 100644 --- a/src/components/data-explorer/data-explorer.test.tsx +++ b/src/components/data-explorer/data-explorer.test.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from "react"; -import { mount, configure } from "enzyme"; +import { configure, mount } from "enzyme"; import * as Adapter from 'enzyme-adapter-react-16'; import DataExplorer from "./data-explorer"; @@ -11,10 +11,12 @@ import ContextMenu from "../context-menu/context-menu"; import ColumnSelector from "../column-selector/column-selector"; import DataTable from "../data-table/data-table"; import SearchInput from "../search-input/search-input"; +import { TablePagination } from "@material-ui/core"; configure({ adapter: new Adapter() }); describe("", () => { + it("communicates with ", () => { const onContextAction = jest.fn(); const dataExplorer = mount(", () => { dataExplorer.find(ContextMenu).prop("onActionClick")({ name: "Action 1", icon: "" }); expect(onContextAction).toHaveBeenCalledWith({ name: "Action 1", icon: "" }, "Item 1"); }); - + it("communicates with ", () => { const onSearch = jest.fn(); const dataExplorer = mount(); + onSearch={onSearch} />); expect(dataExplorer.find(SearchInput).prop("value")).toEqual("search value"); dataExplorer.find(SearchInput).prop("onSearch")("new value"); expect(onSearch).toHaveBeenCalledWith("new value"); @@ -78,6 +80,35 @@ describe("", () => { expect(onSortToggle).toHaveBeenCalledWith("sortToggle"); expect(onRowClick).toHaveBeenCalledWith("rowClick"); }); + + it("renders if items list is not empty", () => { + const onChangePage = jest.fn(); + const onChangeRowsPerPage = jest.fn(); + const dataExplorer = mount(); + expect(dataExplorer.find(TablePagination)).toHaveLength(1); + }); + + it("communicates with ", () => { + const onChangePage = jest.fn(); + const onChangeRowsPerPage = jest.fn(); + const dataExplorer = mount(); + expect(dataExplorer.find(TablePagination).prop("page")).toEqual(10); + expect(dataExplorer.find(TablePagination).prop("rowsPerPage")).toEqual(50); + dataExplorer.find(TablePagination).prop("onChangePage")(undefined, 6); + dataExplorer.find(TablePagination).prop("onChangeRowsPerPage")({ target: { value: 10 } }); + expect(onChangePage).toHaveBeenCalledWith(6); + expect(onChangeRowsPerPage).toHaveBeenCalledWith(10); + }); }); const mockDataExplorerProps = () => ({ @@ -85,10 +116,14 @@ const mockDataExplorerProps = () => ({ items: [], contextActions: [], searchValue: "", + page: 0, + rowsPerPage: 0, onSearch: jest.fn(), onFiltersChange: jest.fn(), onSortToggle: jest.fn(), onRowClick: jest.fn(), onColumnToggle: jest.fn(), - onContextAction: jest.fn() + onContextAction: jest.fn(), + onChangePage: jest.fn(), + onChangeRowsPerPage: jest.fn() }); \ No newline at end of file diff --git a/src/components/data-explorer/data-explorer.tsx b/src/components/data-explorer/data-explorer.tsx index cf9886c3..d797b897 100644 --- a/src/components/data-explorer/data-explorer.tsx +++ b/src/components/data-explorer/data-explorer.tsx @@ -3,7 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; -import { Grid, Paper, Toolbar, StyleRulesCallback, withStyles, Theme, WithStyles } from '@material-ui/core'; +import { Grid, Paper, Toolbar, StyleRulesCallback, withStyles, Theme, WithStyles, TablePagination, Table } from '@material-ui/core'; import ContextMenu, { ContextMenuActionGroup, ContextMenuAction } from "../../components/context-menu/context-menu"; import ColumnSelector from "../../components/column-selector/column-selector"; import DataTable from "../../components/data-table/data-table"; @@ -17,12 +17,16 @@ interface DataExplorerProps { columns: Array>; contextActions: ContextMenuActionGroup[]; searchValue: string; + rowsPerPage: number; + page: number; onSearch: (value: string) => void; onRowClick: (item: T) => void; onColumnToggle: (column: DataColumn) => void; onContextAction: (action: ContextMenuAction, item: T) => void; onSortToggle: (column: DataColumn) => void; onFiltersChange: (filters: DataTableFilterItem[], column: DataColumn) => void; + onChangePage: (page: number) => void; + onChangeRowsPerPage: (rowsPerPage: number) => void; } interface DataExplorerState { @@ -63,7 +67,19 @@ class DataExplorer extends React.Component & WithStyles< onRowContextMenu={this.openContextMenu} onFiltersChange={this.props.onFiltersChange} onSortToggle={this.props.onSortToggle} /> - + + {this.props.items.length > 0 && + + + } + ; } @@ -89,6 +105,14 @@ class DataExplorer extends React.Component & WithStyles< } } + changePage = (event: React.MouseEvent | null, page: number) => { + this.props.onChangePage(page); + } + + changeRowsPerPage: React.ChangeEventHandler = (event) => { + this.props.onChangeRowsPerPage(parseInt(event.target.value, 10)); + } + } type CssRules = "searchBox" | "toolbar"; diff --git a/src/views-components/project-explorer/project-explorer.tsx b/src/views-components/project-explorer/project-explorer.tsx index 4757440c..4931c09a 100644 --- a/src/views-components/project-explorer/project-explorer.tsx +++ b/src/views-components/project-explorer/project-explorer.tsx @@ -28,11 +28,15 @@ interface ProjectExplorerProps { interface ProjectExplorerState { columns: Array>; searchValue: string; + page: number; + rowsPerPage: number; } class ProjectExplorer extends React.Component { state: ProjectExplorerState = { searchValue: "", + page: 0, + rowsPerPage: 10, columns: [{ name: "Name", selected: true, @@ -106,12 +110,16 @@ class ProjectExplorer extends React.Component; + onContextAction={this.executeAction} + onChangePage={this.changePage} + onChangeRowsPerPage={this.changeRowsPerPage} />; } toggleColumn = (toggledColumn: DataColumn) => { @@ -151,6 +159,14 @@ class ProjectExplorer extends React.Component { this.setState({ searchValue }); } + + changePage = (page: number) => { + this.setState({ page }); + } + + changeRowsPerPage = (rowsPerPage: number) => { + this.setState({ rowsPerPage }); + } } const renderName = (item: ProjectExplorerItem) =>