From 0437076c6bb701235ad100da27224dba5083bd5d Mon Sep 17 00:00:00 2001 From: NicolasSuzuki Date: Sat, 7 Sep 2024 01:16:44 -0300 Subject: [PATCH] feat(ISSUE-2571): Add page size and current page index to data browser --- src/dashboard/Data/Browser/Browser.scss | 75 ++++++++++++++- .../Data/Browser/BrowserTable.react.js | 96 +++++++++++++++++-- 2 files changed, 162 insertions(+), 9 deletions(-) diff --git a/src/dashboard/Data/Browser/Browser.scss b/src/dashboard/Data/Browser/Browser.scss index ba6b92c463..f703c6d7a3 100644 --- a/src/dashboard/Data/Browser/Browser.scss +++ b/src/dashboard/Data/Browser/Browser.scss @@ -264,4 +264,77 @@ body:global(.expanded) { position: relative; } } -} \ No newline at end of file +} + +.paginationContainer { + display: flex; + justify-content: space-between; + align-items: center; + border: none; + padding: 10px; + border-radius: 5px; + font-family: Arial, sans-serif; + + .paginationItemsContainer { + display: flex; + align-items: center; + justify-content: space-between; + width: 30%; + + .paginationTotal { + font-weight: bold; + } + + .paginationSelect { + padding: 5px; + font-size: 14px; + } + } + .paginationControls { + display: flex; + align-items: center; + gap: 10px; + + + .paginationPage { + margin: 0 10px; + } + + .paginationBtnNext { + background-color: #f4f4f4; + border: 1px solid #ddd; + padding: 5px 10px; + border-radius: 3px; + cursor: pointer; + transition: background-color 0.3s ease; + margin-left: 5px; + + &:disabled { + background-color: #e0e0e0; + cursor: not-allowed; + } + + &:hover:not(:disabled) { + background-color: #e9e9e9; + } + } + .paginationBtnPrev { + background-color: #f4f4f4; + border: 1px solid #ddd; + padding: 5px 10px; + border-radius: 3px; + cursor: pointer; + transition: background-color 0.3s ease; + margin-right: 5px; + + &:disabled { + background-color: #e0e0e0; + cursor: not-allowed; + } + + &:hover:not(:disabled) { + background-color: #e9e9e9; + } + } + } +} \ No newline at end of file diff --git a/src/dashboard/Data/Browser/BrowserTable.react.js b/src/dashboard/Data/Browser/BrowserTable.react.js index 6bf22627fc..d020c0f881 100644 --- a/src/dashboard/Data/Browser/BrowserTable.react.js +++ b/src/dashboard/Data/Browser/BrowserTable.react.js @@ -18,6 +18,7 @@ import Button from 'components/Button/Button.react'; import { CurrentApp } from 'context/currentApp'; const MAX_ROWS = 200; // Number of rows to render at any time +const LIMIT_DEFAULT = 10; // Number of rows to render at any time const ROWS_OFFSET = 160; const ROW_HEIGHT = 30; @@ -30,25 +31,56 @@ export default class BrowserTable extends React.Component { this.state = { offset: 0, + limit: LIMIT_DEFAULT, + currentPage: 1, }; this.handleScroll = this.handleScroll.bind(this); this.tableRef = React.createRef(); } + handleItemsPerPageChange = (event) => { + const itemsPerPage = Number(event.target.value); + this.setState({ + limit: itemsPerPage, + currentPage: 1, // Reset to first page if items per page changes + offset: 0 // Reset the offset when changing items per page + }); + }; + + handlePreviousPage = () => { + if (this.state.currentPage > 1) { + this.setState((prevState) => ({ + currentPage: prevState.currentPage - 1, + offset: (prevState.currentPage - 2) * prevState.limit + })); + } + }; + + handleNextPage = () => { + const totalPages = Math.ceil(this.props.data?.length / this.state.limit); + if (this.state.currentPage < totalPages) { + this.setState((prevState) => ({ + currentPage: prevState.currentPage + 1, + offset: prevState.currentPage * prevState.limit + })); + } + }; + componentWillReceiveProps(props) { if (props.className !== this.props.className) { this.setState({ offset: 0, + limit: LIMIT_DEFAULT, }); this.tableRef.current.scrollTop = 0; } else if (this.props.newObject !== props.newObject) { - this.setState({ offset: 0 }); + this.setState({ offset: 0, limit: LIMIT_DEFAULT, currentPage: 1 }); this.tableRef.current.scrollTop = 0; } else if (this.props.ordering !== props.ordering) { - this.setState({ offset: 0 }); + this.setState({ offset: 0, limit: LIMIT_DEFAULT, currentPage: 1 }); this.tableRef.current.scrollTop = 0; } else if (this.props.filters.size !== props.filters.size) { - this.setState({ offset: 0 }, () => { + this.setState({ offset: 0, limit: LIMIT_DEFAULT, currentPage: 1 }, () => { this.tableRef.current.scrollTop = 0; }); } @@ -94,7 +126,15 @@ export default class BrowserTable extends React.Component { } render() { + const { data } = this.props; + const { currentPage, limit, ROW_HEIGHT } = this.state; let ordering = {}; + + // Calculate the start and end indices of the data to display + const startIndex = (currentPage - 1) * limit; + const endIndex = Math.min(startIndex + limit, data?.length); + const totalPages = Math.ceil(data?.length / limit); + if (this.props.ordering) { if (this.props.ordering[0] === '-') { ordering = { @@ -281,8 +321,7 @@ export default class BrowserTable extends React.Component { ); } const rows = []; - const end = Math.min(this.state.offset + MAX_ROWS, this.props.data.length); - for (let i = this.state.offset; i < end; i++) { + for (let i = this.state.offset; i < endIndex; i++) { const index = i - this.state.offset; const obj = this.props.data[i]; const currentCol = @@ -338,7 +377,7 @@ export default class BrowserTable extends React.Component { if (this.props.current) { if (this.props.current.row < 0 && this.state.offset === 0) { visible = true; - } else if (this.props.current.row >= this.state.offset && this.props.current.row < end) { + } else if (this.props.current.row >= this.state.offset && this.props.current.row < endIndex) { visible = true; } } @@ -362,7 +401,7 @@ export default class BrowserTable extends React.Component { if (!obj && this.props.current.row < -1) { obj = this.props.editCloneRows[ - this.props.current.row + this.props.editCloneRows.length + 1 + this.props.current.row + this.props.editCloneRows.length + 1 ]; } if (!this.props.isUnique) { @@ -475,6 +514,47 @@ export default class BrowserTable extends React.Component { /> {addRow} {editor} +
+
+ {data.length} items +
+ + +
+
+
+ + Page {currentPage} / {totalPages} + + + +
+
+ ); } else { @@ -514,7 +594,7 @@ export default class BrowserTable extends React.Component { !!this.props.selection && !!this.props.data && Object.values(this.props.selection).filter(checked => checked).length === - this.props.data.length + this.props.data.length } selectAll={checked => this.props.data.forEach(({ id }) => this.props.selectRow(id, checked))