feat(ui): new pagination with page number and page size (#10921)

* feat(ui): new pagination with page number and page size

* fix unit tests

* fix unit tests

* fix pagination issue

---------

Co-authored-by: Shailesh Parmar <shailesh.parmar.webdev@gmail.com>
This commit is contained in:
Chirag Madlani 2023-04-14 16:24:14 +05:30 committed by GitHub
parent 6b8b9a179b
commit fa93a37fcd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 66 deletions

View File

@ -27,7 +27,6 @@ import unique from 'fork-ts-checker-webpack-plugin/lib/utils/array/unique';
import {
isEmpty,
isNil,
isNumber,
isString,
isUndefined,
lowerCase,
@ -81,7 +80,6 @@ const Explore: React.FC<ExploreProps> = ({
onChangeSortValue,
onChangeShowDeleted,
showDeleted,
page = 1,
onChangePage = noop,
loading,
quickFilters,
@ -400,19 +398,12 @@ const Explore: React.FC<ExploreProps> = ({
<SearchedData
isFilterSelected
showResultCount
currentPage={page}
data={searchResults?.hits.hits ?? []}
handleSummaryPanelDisplay={handleSummaryPanelDisplay}
isSummaryPanelVisible={showSummaryPanel}
paginate={(value) => {
if (isNumber(value)) {
onChangePage(value);
} else if (!isNaN(Number.parseInt(value))) {
onChangePage(Number.parseInt(value));
}
}}
selectedEntityId={entityDetails?.id || ''}
totalValue={searchResults?.hits.total.value ?? 0}
onPaginationChange={onChangePage}
/>
) : (
<Loader />

View File

@ -82,8 +82,7 @@ export interface ExploreProps {
showDeleted: boolean;
onChangeShowDeleted: (showDeleted: boolean) => void;
page?: number;
onChangePage?: (page: number) => void;
onChangePage?: (page: number, size?: number) => void;
loading?: boolean;

View File

@ -73,9 +73,8 @@ export interface SearchedDataProps {
children?: ReactNode;
selectedEntityId: string;
data: SearchHitBody<ExploreSearchIndex, SourceType>[];
currentPage: number;
isLoading?: boolean;
paginate: (value: string | number) => void;
onPaginationChange: (value: number, pageSize?: number) => void;
totalValue: number;
fetchLeftPanel?: () => ReactNode;
isSummaryPanelVisible: boolean;

View File

@ -106,7 +106,7 @@ const MOCK_PROPS = {
currentPage: 0,
data: mockData,
handleSummaryPanelDisplay: mockHandleSummaryPanelDisplay,
paginate: mockPaginate,
onPaginationChange: mockPaginate,
selectedEntityId: 'name1',
totalValue: 10,
};
@ -145,19 +145,6 @@ describe('Test SearchedData Component', () => {
expect(getByText(container, /hello world/i)).toBeInTheDocument();
});
it('Pagination Should be there if data is more than 10 count', () => {
const { container } = render(
<SearchedData {...MOCK_PROPS} totalValue={11}>
<p>hello world</p>
</SearchedData>,
{
wrapper: MemoryRouter,
}
);
expect(getByText(container, /Pagination/i)).toBeInTheDocument();
});
it('Onboarding component should display if there is showOnboardingTemplate is true', () => {
const { container } = render(
<SearchedData

View File

@ -11,18 +11,17 @@
* limitations under the License.
*/
import { Pagination } from 'antd';
import classNames from 'classnames';
import { ELASTICSEARCH_ERROR_PLACEHOLDER_TYPE } from 'enums/common.enum';
import { isUndefined } from 'lodash';
import PropTypes from 'prop-types';
import React from 'react';
import { isNumber, isUndefined } from 'lodash';
import Qs from 'qs';
import React, { useMemo } from 'react';
import { getEntityName } from 'utils/EntityUtils';
import { PAGE_SIZE } from '../../constants/constants';
import { MAX_RESULT_HITS } from '../../constants/explore.constants';
import { Paging } from '../../generated/type/paging';
import { pluralize } from '../../utils/CommonUtils';
import ErrorPlaceHolderES from '../common/error-with-placeholder/ErrorPlaceHolderES';
import NextPrevious from '../common/next-previous/NextPrevious';
import TableDataCardV2 from '../common/table-data-card-v2/TableDataCardV2';
import Loader from '../Loader/Loader';
import Onboarding from '../onboarding/Onboarding';
@ -38,9 +37,8 @@ const ASSETS_NAME = [
const SearchedData: React.FC<SearchedDataProps> = ({
children,
data,
currentPage,
isLoading = false,
paginate,
onPaginationChange,
showResultCount = false,
showOnboardingTemplate = false,
showOnlyChildren = false,
@ -51,7 +49,7 @@ const SearchedData: React.FC<SearchedDataProps> = ({
selectedEntityId,
handleSummaryPanelDisplay,
}) => {
const highlightSearchResult = () => {
const searchResultCards = useMemo(() => {
return data.map(({ _source: table, highlight }, index) => {
let tDesc = table.description ?? '';
const highLightedTexts = highlight?.description || [];
@ -108,7 +106,12 @@ const SearchedData: React.FC<SearchedDataProps> = ({
</div>
);
});
};
}, [
data,
isSummaryPanelVisible,
handleSummaryPanelDisplay,
selectedEntityId,
]);
const ResultCount = () => {
if (showResultCount && (isFilterSelected || searchText)) {
@ -122,6 +125,16 @@ const SearchedData: React.FC<SearchedDataProps> = ({
}
};
const { page, size } = useMemo(
() =>
Qs.parse(
location.search.startsWith('?')
? location.search.substr(1)
: location.search
),
[location.search]
);
return (
<>
{isLoading ? (
@ -138,17 +151,20 @@ const SearchedData: React.FC<SearchedDataProps> = ({
<div
className="tw-grid tw-grid-rows-1 tw-grid-cols-1"
data-testid="search-results">
{highlightSearchResult()}
{totalValue > PAGE_SIZE && data.length > 0 && (
<NextPrevious
isNumberBased
currentPage={currentPage}
pageSize={PAGE_SIZE}
paging={{} as Paging}
pagingHandler={paginate}
totalCount={totalValue}
/>
)}
{searchResultCards}
<Pagination
hideOnSinglePage
className="text-center"
current={isNumber(Number(page)) ? Number(page) : 1}
pageSize={
size && isNumber(Number(size))
? Number(size)
: PAGE_SIZE
}
pageSizeOptions={[10, 25, 50]}
total={totalValue}
onChange={onPaginationChange}
/>
</div>
) : (
<Onboarding />
@ -171,16 +187,4 @@ const SearchedData: React.FC<SearchedDataProps> = ({
);
};
SearchedData.propTypes = {
children: PropTypes.element,
data: PropTypes.array.isRequired,
currentPage: PropTypes.number.isRequired,
isLoading: PropTypes.bool,
paginate: PropTypes.func.isRequired,
showResultCount: PropTypes.bool,
showOnboardingTemplate: PropTypes.bool,
totalValue: PropTypes.number.isRequired,
fetchLeftPanel: PropTypes.func,
};
export default SearchedData;

View File

@ -119,8 +119,10 @@ const ExplorePage: FunctionComponent = () => {
[facetFilters]
);
const handlePageChange: ExploreProps['onChangePage'] = (page) => {
history.push({ search: Qs.stringify({ ...parsedSearch, page }) });
const handlePageChange: ExploreProps['onChangePage'] = (page, size) => {
history.push({
search: Qs.stringify({ ...parsedSearch, page, size: size ?? PAGE_SIZE }),
});
};
// Filters that can be common for all the Entities Ex. Tables, Topics, etc.
@ -234,9 +236,18 @@ const ExplorePage: FunctionComponent = () => {
return Number.parseInt(pageParam);
}, [parsedSearch.page]);
const size = useMemo(() => {
const sizeParam = parsedSearch.size;
if (!isString(sizeParam) || isNaN(Number.parseInt(sizeParam))) {
return PAGE_SIZE;
}
return Number.parseInt(sizeParam);
}, [parsedSearch.size]);
useEffect(() => {
handlePageChange(page);
}, [page]);
handlePageChange(page, size);
}, [page, size]);
const showDeleted = useMemo(() => {
const showDeletedParam = parsedSearch.showDeleted;
@ -305,7 +316,7 @@ const ExplorePage: FunctionComponent = () => {
sortField: sortValue,
sortOrder,
pageNumber: page,
pageSize: PAGE_SIZE,
pageSize: size,
includeDeleted: showDeleted,
})
.then((res) => res)
@ -373,6 +384,7 @@ const ExplorePage: FunctionComponent = () => {
elasticsearchQueryFilter,
searchIndex,
page,
size,
]);
const handleAdvanceSearchQuickFiltersChange = useCallback(
@ -422,7 +434,6 @@ const ExplorePage: FunctionComponent = () => {
aggregations={updatedAggregations}
facetFilters={facetFilters}
loading={isLoading}
page={page}
quickFilters={advancesSearchQuickFilters}
searchIndex={searchIndex}
searchResults={searchResults}