diff --git a/client/src/components/PageSize/PageSize.jsx b/client/src/components/PageSize/PageSize.jsx new file mode 100644 index 000000000..b7a2aec91 --- /dev/null +++ b/client/src/components/PageSize/PageSize.jsx @@ -0,0 +1,34 @@ +import React from 'react'; +import './styles.scss'; + +const PageSize = ({ + pageNumber, + totalPageNumber, + currentPageSize, + totalRecords, + ranges = [10, 25, 50, 100, 150, 200], + onChange, + editPageNumber, + showTotalPageNumber = true +}) => { + var pageSizeOptions = []; + var pageSizeOptionsList = []; + ranges.forEach(element => pageSizeOptions[element] = element ); + //if server's pageSize does not belong to ranges, it should be added - when the page is loaded for the first + if(!ranges.includes(currentPageSize)){ + pageSizeOptions[currentPageSize] = currentPageSize; + } + pageSizeOptions.forEach((k) => { + pageSizeOptionsList.push(); + }) + return ( +
+ Results + +
+ ); +}; + +export default PageSize; \ No newline at end of file diff --git a/client/src/components/PageSize/index.js b/client/src/components/PageSize/index.js new file mode 100644 index 000000000..5c7846ff1 --- /dev/null +++ b/client/src/components/PageSize/index.js @@ -0,0 +1,3 @@ +import PageSize from './PageSize'; + +export default PageSize; diff --git a/client/src/components/PageSize/styles.scss b/client/src/components/PageSize/styles.scss new file mode 100644 index 000000000..d4470abf0 --- /dev/null +++ b/client/src/components/PageSize/styles.scss @@ -0,0 +1,11 @@ +@import "../../css/init"; + +// result per page +#result-per-page{ + float: left; + display: flex; +} +#result-per-page span{ + margin: 5px; +} + diff --git a/client/src/containers/Topic/TopicList/TopicList.jsx b/client/src/containers/Topic/TopicList/TopicList.jsx index 87b735b3e..105e347b0 100644 --- a/client/src/containers/Topic/TopicList/TopicList.jsx +++ b/client/src/containers/Topic/TopicList/TopicList.jsx @@ -16,6 +16,7 @@ import Root from '../../../components/Root'; import DateTime from '../../../components/DateTime'; import {getClusterUIOptions} from '../../../utils/functions'; import {handlePageChange, getPageNumber} from './../../../utils/pagination'; +import PageSize from '../../../components/PageSize'; class TopicList extends Root { state = { @@ -27,6 +28,7 @@ class TopicList extends Root { deleteData: {}, pageNumber: 1, totalPageNumber: 1, + currentPageSize: 1, searchData: { search: '', topicListView: constants.SETTINGS_VALUES.TOPIC.TOPIC_DEFAULT_VIEW.HIDE_INTERNAL @@ -72,6 +74,7 @@ class TopicList extends Root { const query = new URLSearchParams(this.props.location.search); const {searchData, keepSearch} = this.state; let { pageNumber } = this.state; + let { currentPageSize } = this.state; const uiOptions = await getClusterUIOptions(clusterId) let searchDataTmp; @@ -87,6 +90,7 @@ class TopicList extends Root { (uiOptions && uiOptions.topic && uiOptions.topic.defaultView)? uiOptions.topic.defaultView : searchData.topicListView, } pageNumber = (query.get('page'))? parseInt(query.get('page')) : parseInt(pageNumber) + currentPageSize = (query.get('uiPageSize'))? parseInt(query.get('uiPageSize')) : parseInt(currentPageSize) } this.setState({ @@ -94,7 +98,8 @@ class TopicList extends Root { searchData: searchDataTmp, keepSearch: keepSearchTmp, uiOptions: uiOptions ?? {}, - pageNumber: pageNumber + pageNumber: pageNumber, + currentPageSize: currentPageSize }, callBackFunction); } @@ -153,12 +158,23 @@ class TopicList extends Root { }); }; + handlePageSizeChangeSubmission = value => { + let pageNumber = 1; + this.setState({ currentPageSize: value, pageNumber: pageNumber},() => { + this.getTopics(); + this.props.history.push({ + pathname: `/ui/${this.state.selectedCluster}/topic`, + search: `search=${this.state.searchData.search}&topicListView=${this.state.searchData.topicListView}&uiPageSize=${value}` + }); + }); + }; + async getTopics() { - const { selectedCluster, pageNumber } = this.state; + const { selectedCluster, pageNumber, currentPageSize } = this.state; const { search, topicListView } = this.state.searchData; this.setState({ loading: true } ); - let response = await this.getApi(uriTopics(selectedCluster, search, topicListView, pageNumber)); + let response = await this.getApi(uriTopics(selectedCluster, search, topicListView, pageNumber, currentPageSize)); let data = response.data; if (data) { @@ -167,7 +183,7 @@ class TopicList extends Root { } else { this.setState({ topics: [] }); } - this.setState({ selectedCluster, totalPageNumber: data.page, loading: false } ) + this.setState({ selectedCluster, totalPageNumber: data.page, currentPageSize: data.pageSize, loading: false } ) } else { this.setState({ topics: [], loading: false, totalPageNumber: 0}); } @@ -279,7 +295,7 @@ class TopicList extends Root { } render() { - const { topics, selectedCluster, searchData, pageNumber, totalPageNumber, loading, collapseConsumerGroups, keepSearch, uiOptions } = this.state; + const { topics, selectedCluster, searchData, pageNumber, totalPageNumber, currentPageSize, loading, collapseConsumerGroups, keepSearch, uiOptions } = this.state; const uiOptionsTopic = uiOptions.topic ?? {}; const dateTimeFormat = uiOptions.topicData && uiOptions.topicData.dateTimeFormat ? uiOptions.topicData.dateTimeFormat : @@ -441,9 +457,18 @@ class TopicList extends Root { }} doSubmit={this.handleSearch} /> + + + diff --git a/client/src/utils/endpoints.js b/client/src/utils/endpoints.js index 116437454..199beb90b 100644 --- a/client/src/utils/endpoints.js +++ b/client/src/utils/endpoints.js @@ -35,8 +35,12 @@ export const uriUIOptions = (clusterId) => { return `${apiUrl}/${clusterId}/ui-options`; }; -export const uriTopics = (clusterId, search, show, page) => { - return `${apiUrl}/${clusterId}/topic?search=${search}&show=${show}&page=${page}`; +export const uriTopics = (clusterId, search, show, page, pageSize) => { + if(pageSize === 1){ + return `${apiUrl}/${clusterId}/topic?search=${search}&show=${show}&page=${page}`; + }else{ + return `${apiUrl}/${clusterId}/topic?search=${search}&show=${show}&page=${page}&uiPageSize=${pageSize}`; + } }; export const uriTopicDefaultConf = () => `${apiUrl}/topic/defaults-configs`; diff --git a/src/main/java/org/akhq/controllers/TopicController.java b/src/main/java/org/akhq/controllers/TopicController.java index ffb3ca36d..02e42be22 100644 --- a/src/main/java/org/akhq/controllers/TopicController.java +++ b/src/main/java/org/akhq/controllers/TopicController.java @@ -84,10 +84,11 @@ public ResultPagedList list( String cluster, Optional search, Optional show, - Optional page + Optional page, + Optional uiPageSize ) throws ExecutionException, InterruptedException { URIBuilder uri = URIBuilder.fromURI(request.getUri()); - Pagination pagination = new Pagination(pageSize, uri, page.orElse(1)); + Pagination pagination = new Pagination(uiPageSize.orElse(pageSize), uri, page.orElse(1)); return ResultPagedList.of(this.topicRepository.list( cluster, diff --git a/src/main/java/org/akhq/utils/PagedList.java b/src/main/java/org/akhq/utils/PagedList.java index 76a877d82..57a0c785f 100644 --- a/src/main/java/org/akhq/utils/PagedList.java +++ b/src/main/java/org/akhq/utils/PagedList.java @@ -25,6 +25,10 @@ public int total() { return this.total; } + public int pageSize() { + return this.pageSize; + } + public URIBuilder before() { if (currentPage - 1 > 0) { return uri.addParameter("page", String.valueOf(currentPage - 1)); diff --git a/src/main/java/org/akhq/utils/ResultPagedList.java b/src/main/java/org/akhq/utils/ResultPagedList.java index 1ccd253ad..1ce991738 100644 --- a/src/main/java/org/akhq/utils/ResultPagedList.java +++ b/src/main/java/org/akhq/utils/ResultPagedList.java @@ -1,11 +1,11 @@ package org.akhq.utils; +import java.util.List; + import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.List; - @NoArgsConstructor @AllArgsConstructor @Getter @@ -15,6 +15,7 @@ public class ResultPagedList { private String after; private int page; private int total; + private int pageSize; public static ResultPagedList of(PagedList pagedList) { return new ResultPagedList<>( @@ -22,7 +23,8 @@ public static ResultPagedList of(PagedList pagedList) { pagedList.before().toNormalizedURI(false).toString(), pagedList.after().toNormalizedURI(false).toString(), pagedList.pageCount(), - pagedList.total() + pagedList.total(), + pagedList.pageSize() ); } }