Skip to content

Commit

Permalink
Add Pager service and EuiTablePagination component (#178)
Browse files Browse the repository at this point in the history
* Add Pager service and tests.
* Add EuiTablePagination component and document it.
  • Loading branch information
cjcenizal authored Dec 4, 2017
1 parent b0c1768 commit 55fc0ea
Show file tree
Hide file tree
Showing 15 changed files with 521 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Add `wrap` prop to `<EuiFlexGroup>` ([#170](https://github.com/elastic/eui/pull/170))
- Add `scope` prop to `<EuiTableHeaderCell>` and `<EuiTableHeaderCellCheckbox>` ([#171](https://github.com/elastic/eui/pull/171))
- Add `disabled` prop to `<EuiContextMenuItem>` ([#172](https://github.com/elastic/eui/pull/172))
- Add `<EuiTablePagination>` component and `Pager` service ([#178](https://github.com/elastic/eui/pull/178))

**Bug fixes**

Expand Down
3 changes: 0 additions & 3 deletions src-docs/src/views/kibana/watches.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
KibanaChrome,
ManagementSideNav,
Table,
TablePagination,
} from '../partials';

export default class extends Component {
Expand Down Expand Up @@ -162,8 +161,6 @@ export default class extends Component {
<Table />

<EuiSpacer size="m" />

<TablePagination />
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
Expand Down
1 change: 0 additions & 1 deletion src-docs/src/views/partials.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export { default as KibanaChrome } from './kibana/kibana_chrome';
export { default as KibanaHeader } from './header/header';
export { default as TablePagination } from './pagination/customizable_pagination';
export { default as ManagementSideNav } from './side_nav/side_nav_complex';
export { default as Table } from './table/table';
export {
Expand Down
48 changes: 46 additions & 2 deletions src-docs/src/views/table/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
EuiTableHeader,
EuiTableHeaderCell,
EuiTableHeaderCellCheckbox,
EuiTablePagination,
EuiTableRow,
EuiTableRowCell,
EuiTableRowCellCheckbox,
Expand All @@ -30,6 +31,7 @@ import {
import {
LEFT_ALIGNMENT,
RIGHT_ALIGNMENT,
Pager,
SortableProperties,
} from '../../../../src/services';

Expand All @@ -41,6 +43,7 @@ export default class extends Component {
itemIdToSelectedMap: {},
itemIdToOpenActionsPopoverMap: {},
sortedColumn: 'title',
itemsPerPage: 20,
};

this.items = [{
Expand Down Expand Up @@ -233,8 +236,29 @@ export default class extends Component {
isActionsPopover: true,
width: '32px',
}];

this.pager = new Pager(this.items.length, this.state.itemsPerPage);
this.state.firstItemIndex = this.pager.getFirstItemIndex();
this.state.lastItemIndex = this.pager.getLastItemIndex();
}

onChangeItemsPerPage = itemsPerPage => {
this.pager.setItemsPerPage(itemsPerPage);
this.setState({
itemsPerPage,
firstItemIndex: this.pager.getFirstItemIndex(),
lastItemIndex: this.pager.getLastItemIndex(),
});
}

onChangePage = pageIndex => {
this.pager.goToPageIndex(pageIndex);
this.setState({
firstItemIndex: this.pager.getFirstItemIndex(),
lastItemIndex: this.pager.getLastItemIndex(),
});
};

onSort = prop => {
this.sortableProperties.sortOn(prop);

Expand Down Expand Up @@ -345,7 +369,7 @@ export default class extends Component {
}

renderRows() {
return this.items.map(item => {
const renderRow = item => {
const cells = this.columns.map(column => {
const cell = item[column.id];

Expand Down Expand Up @@ -451,7 +475,16 @@ export default class extends Component {
{cells}
</EuiTableRow>
);
});
};

const rows = [];

for (let itemIndex = this.state.firstItemIndex; itemIndex <= this.state.lastItemIndex; itemIndex++) {
const item = this.items[itemIndex];
rows.push(renderRow(item));
}

return rows;
}

render() {
Expand Down Expand Up @@ -486,6 +519,17 @@ export default class extends Component {
{this.renderRows()}
</EuiTableBody>
</EuiTable>

<EuiSpacer size="m" />

<EuiTablePagination
activePage={this.pager.getCurrentPageIndex()}
itemsPerPage={this.state.itemsPerPage}
itemsPerPageOptions={[5, 10, 20]}
pageCount={this.pager.getTotalPages()}
onChangeItemsPerPage={this.onChangeItemsPerPage}
onChangePage={this.onChangePage}
/>
</div>
);
}
Expand Down
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export {
EuiTableHeaderButton,
EuiTableHeaderCell,
EuiTableHeaderCellCheckbox,
EuiTablePagination,
EuiTableRow,
EuiTableRowCell,
EuiTableRowCellCheckbox,
Expand Down
3 changes: 1 addition & 2 deletions src/components/pagination/pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ export const EuiPagination = ({

EuiPagination.propTypes = {
className: PropTypes.string,
pagesCount: PropTypes.number,
pageCount: PropTypes.number,
activePage: PropTypes.number,
onPageClick: PropTypes.func,
pageLinkProvider: PropTypes.func,
};
1 change: 1 addition & 0 deletions src/components/table/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { EuiTableHeader } from './table_header';
export { EuiTableHeaderButton } from './table_header_button';
export { EuiTableHeaderCell } from './table_header_cell';
export { EuiTableHeaderCellCheckbox } from './table_header_cell_checkbox';
export { EuiTablePagination } from './table_pagination';
export { EuiTableRow } from './table_row';
export { EuiTableRowCell } from './table_row_cell';
export { EuiTableRowCellCheckbox } from './table_row_cell_checkbox';
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`EuiTablePagination is rendered 1`] = `
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--justifyContentSpaceBetween euiFlexGroup--responsive"
>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<div
class="euiPopover euiPopover--anchorUpRight euiPopover--withTitle"
>
<button
aria-controls="customizablePagination"
aria-expanded="false"
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiButtonEmpty--iconRight"
type="button"
>
<span
class="euiButtonEmpty__content"
>
<svg
aria-hidden="true"
class="euiIcon euiButtonEmpty__icon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_down-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_down-a"
/>
</svg>
<span>
Rows per page: 50
</span>
</span>
</button>
</div>
</div>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<div
class="euiPagination"
>
<button
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
type="button"
>
<span
class="euiButtonEmpty__content"
>
<svg
aria-hidden="true"
class="euiIcon euiButtonEmpty__icon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_left-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_left-a"
transform="rotate(90 8 8)"
/>
</svg>
<span>
Previous
</span>
</span>
</button>
<button
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiButtonEmpty--iconRight euiPaginationButton"
type="button"
>
<span
class="euiButtonEmpty__content"
>
<svg
aria-hidden="true"
class="euiIcon euiButtonEmpty__icon euiIcon--medium"
height="16"
viewBox="0 0 16 16"
width="16"
xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<path
d="M13.069 5.157L8.384 9.768a.546.546 0 0 1-.768 0L2.93 5.158a.552.552 0 0 0-.771 0 .53.53 0 0 0 0 .759l4.684 4.61c.641.631 1.672.63 2.312 0l4.684-4.61a.53.53 0 0 0 0-.76.552.552 0 0 0-.771 0z"
id="arrow_right-a"
/>
</defs>
<use
fill-rule="nonzero"
href="#arrow_right-a"
transform="matrix(0 1 1 0 0 0)"
/>
</svg>
<span>
Next
</span>
</span>
</button>
</div>
</div>
</div>
`;
1 change: 1 addition & 0 deletions src/components/table/table_pagination/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EuiTablePagination } from './table_pagination';
111 changes: 111 additions & 0 deletions src/components/table/table_pagination/table_pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React, {
Component,
} from 'react';
import PropTypes from 'prop-types';

import {
EuiButtonEmpty,
EuiContextMenuItem,
EuiContextMenuPanel,
EuiFlexGroup,
EuiFlexItem,
EuiPagination,
EuiPopover,
} from '../../../../src/components';

export class EuiTablePagination extends Component {
constructor(props) {
super(props);

this.state = {
isPopoverOpen: false,
};
}

onButtonClick = () => {
this.setState({
isPopoverOpen: !this.state.isPopoverOpen,
});
};

closePopover = () => {
this.setState({
isPopoverOpen: false,
});
};

render() {
const {
activePage,
itemsPerPage,
itemsPerPageOptions,
onChangeItemsPerPage,
onChangePage,
pageCount,
} = this.props;

const button = (
<EuiButtonEmpty
size="s"
color="text"
iconType="arrowDown"
iconSide="right"
onClick={this.onButtonClick}
>
{`Rows per page: ${itemsPerPage}`}
</EuiButtonEmpty>
);

const items = itemsPerPageOptions.map(itemsPerPageOption => (
<EuiContextMenuItem
key={itemsPerPageOption}
icon={itemsPerPageOption === itemsPerPage ? 'check' : 'empty'}
onClick={() => { this.closePopover(); onChangeItemsPerPage(itemsPerPageOption); }}
>
{`${itemsPerPageOption} rows`}
</EuiContextMenuItem>
));

return (
<EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
<EuiFlexItem grow={false}>
<EuiPopover
id="customizablePagination"
button={button}
isOpen={this.state.isPopoverOpen}
closePopover={this.closePopover}
panelPaddingSize="none"
withTitle
anchorPosition="upRight"
>
<EuiContextMenuPanel
items={items}
/>
</EuiPopover>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiPagination
pageCount={pageCount}
activePage={activePage}
onPageClick={onChangePage}
/>
</EuiFlexItem>
</EuiFlexGroup>
);
}
}

EuiTablePagination.propTypes = {
activePage: PropTypes.number,
itemsPerPage: PropTypes.number,
itemsPerPageOptions: PropTypes.arrayOf(PropTypes.number),
onChangeItemsPerPage: PropTypes.func,
onChangePage: PropTypes.func,
pageCount: PropTypes.number,
};

EuiTablePagination.defaultProps = {
itemsPerPage: 50,
itemsPerPageOptions: [10, 20, 50, 100],
};
Loading

0 comments on commit 55fc0ea

Please sign in to comment.