Skip to content

Commit

Permalink
feat(dg): show numbers of rows pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
gjulivan committed Jan 10, 2025
1 parent cc88b77 commit edd40dc
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 75 deletions.
4 changes: 4 additions & 0 deletions packages/pluggableWidgets/datagrid-web/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added

- We have introduced show number of rows for virtual scrolling and load more pagination mode.

## [2.28.2] - 2024-12-12

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,16 @@ export function getProperties(
]);
}
});
if (values.pagination !== "buttons") {
if (values.pagination === "buttons") {
hidePropertyIn(defaultProperties, values, "showNumberOfRows");
} else {
hidePropertyIn(defaultProperties, values, "showPagingButtons");
}

if (values.showNumberOfRows === false) {
hidePropertyIn(defaultProperties, values, "pagingPosition");
}

if (values.pagination !== "loadMore") {
hidePropertyIn(defaultProperties, values, "loadMoreButtonCaption");
}
Expand Down
7 changes: 5 additions & 2 deletions packages/pluggableWidgets/datagrid-web/src/Datagrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const Container = observer((props: Props): ReactElement => {
return props.datasource.status === ValueStatus.Loading;
}, [exportProgress, isRefreshing, props.datasource.status, props.datasource.hasMoreItems]);

const showPagingButtonsOrRows = props.pagination === "buttons" ? props.showPagingButtons : props.showNumberOfRows;

return (
<Widget
className={props.class}
Expand Down Expand Up @@ -134,9 +136,10 @@ const Container = observer((props: Props): ReactElement => {
loadMoreButtonCaption={props.loadMoreButtonCaption?.value}
paging={useShowPagination({
pagination: props.pagination,
showPagingButtons: props.showPagingButtons,
showPagingButtonsOrRows,
totalCount: props.datasource.totalCount,
limit: props.datasource.limit
limit: props.datasource.limit,
requestTotalCount: props.datasource.requestTotalCount
})}
pagingPosition={props.pagingPosition}
showPagingButtons={props.showPagingButtons}
Expand Down
22 changes: 13 additions & 9 deletions packages/pluggableWidgets/datagrid-web/src/Datagrid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,6 @@
<enumerationValue key="loadMore">Load more</enumerationValue>
</enumerationValues>
</property>
<property key="pagingPosition" type="enumeration" defaultValue="bottom">
<caption>Position of paging buttons</caption>
<description />
<enumerationValues>
<enumerationValue key="bottom">Below grid</enumerationValue>
<enumerationValue key="top">Above grid</enumerationValue>
<enumerationValue key="both">Both</enumerationValue>
</enumerationValues>
</property>
<property key="showPagingButtons" type="enumeration" defaultValue="always">
<caption>Show paging buttons</caption>
<description />
Expand All @@ -253,6 +244,19 @@
<enumerationValue key="auto">Auto</enumerationValue>
</enumerationValues>
</property>
<property key="showNumberOfRows" type="boolean" defaultValue="false">
<caption>Show number of rows</caption>
<description />
</property>
<property key="pagingPosition" type="enumeration" defaultValue="bottom">
<caption>Position of pagination</caption>
<description />
<enumerationValues>
<enumerationValue key="bottom">Below grid</enumerationValue>
<enumerationValue key="top">Above grid</enumerationValue>
<enumerationValue key="both">Both</enumerationValue>
</enumerationValues>
</property>
<property key="loadMoreButtonCaption" type="textTemplate" required="false">
<caption>Load more caption</caption>
<description />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ const Main = observer(<C extends GridColumn>(props: WidgetProps<C>): ReactElemen
visibleColumns
} = props;

const isInfinite = !paging;
const isInfinite = paginationType === "virtualScrolling";
const showHeader = !!headerContent;
const showTopBar = paging && (pagingPosition === "top" || pagingPosition === "both");

Expand All @@ -149,6 +149,7 @@ const Main = observer(<C extends GridColumn>(props: WidgetProps<C>): ReactElemen
pageSize={pageSize}
showPagingButtons={props.showPagingButtons}
previousPage={() => setPage && setPage(prev => prev - 1)}
pagination={paginationType}
/>
) : null;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
import { useMemo } from "react";
import { useMemo, useEffect } from "react";
import { PaginationEnum, ShowPagingButtonsEnum } from "../../typings/DatagridProps";

interface ShowPaginationProps {
pagination: PaginationEnum;
showPagingButtons: ShowPagingButtonsEnum;
showPagingButtonsOrRows: ShowPagingButtonsEnum | boolean;
totalCount?: number;
limit: number;
requestTotalCount: (needTotalCount: boolean) => void;
}

export const useShowPagination = (props: ShowPaginationProps): boolean => {
const { pagination, showPagingButtons, totalCount, limit } = props;
const { pagination, showPagingButtonsOrRows, totalCount, limit, requestTotalCount } = props;

useEffect(() => {
if (pagination !== "buttons" && showPagingButtonsOrRows) {
requestTotalCount(true);
}
}, [pagination]);

Check warning on line 19 in packages/pluggableWidgets/datagrid-web/src/utils/useShowPagination.ts

View workflow job for this annotation

GitHub Actions / Run code quality check

React Hook useEffect has missing dependencies: 'requestTotalCount' and 'showPagingButtonsOrRows'. Either include them or remove the dependency array

return useMemo(() => {
return (
pagination === "buttons" &&
(showPagingButtons === "always" ||
(showPagingButtons === "auto" && (totalCount ? totalCount > limit : false)))
showPagingButtonsOrRows === true ||
showPagingButtonsOrRows === "always" ||
(showPagingButtonsOrRows === "auto" && (totalCount ? totalCount > limit : false))
);
}, [pagination, showPagingButtons, totalCount, limit]);
}, [pagination, showPagingButtonsOrRows, totalCount, limit]);

Check warning on line 27 in packages/pluggableWidgets/datagrid-web/src/utils/useShowPagination.ts

View workflow job for this annotation

GitHub Actions / Run code quality check

React Hook useMemo has an unnecessary dependency: 'pagination'. Either exclude it or remove the dependency array
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ export interface ColumnsType {

export type PaginationEnum = "buttons" | "virtualScrolling" | "loadMore";

export type PagingPositionEnum = "bottom" | "top" | "both";

export type ShowPagingButtonsEnum = "always" | "auto";

export type PagingPositionEnum = "bottom" | "top" | "both";

export type ShowEmptyPlaceholderEnum = "none" | "custom";

export type OnClickTriggerEnum = "single" | "double";
Expand Down Expand Up @@ -116,8 +116,9 @@ export interface DatagridContainerProps {
columnsFilterable: boolean;
pageSize: number;
pagination: PaginationEnum;
pagingPosition: PagingPositionEnum;
showPagingButtons: ShowPagingButtonsEnum;
showNumberOfRows: boolean;
pagingPosition: PagingPositionEnum;
loadMoreButtonCaption?: DynamicValue<string>;
showEmptyPlaceholder: ShowEmptyPlaceholderEnum;
emptyPlaceholder?: ReactNode;
Expand Down Expand Up @@ -161,8 +162,9 @@ export interface DatagridPreviewProps {
columnsFilterable: boolean;
pageSize: number | null;
pagination: PaginationEnum;
pagingPosition: PagingPositionEnum;
showPagingButtons: ShowPagingButtonsEnum;
showNumberOfRows: boolean;
pagingPosition: PagingPositionEnum;
loadMoreButtonCaption: string;
showEmptyPlaceholder: ShowEmptyPlaceholderEnum;
emptyPlaceholder: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> };
Expand Down
119 changes: 68 additions & 51 deletions packages/shared/widget-plugin-grid/src/components/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { createElement, Dispatch, HTMLAttributes, ReactElement, SetStateAction } from "react";
import { createElement, Dispatch, HTMLAttributes, ReactElement, SetStateAction, Fragment } from "react";
import ControlIcon from "../internal/ControlIcon.js";

// copied from DatagridProps.d.ts
type PaginationEnum = "buttons" | "virtualScrolling" | "loadMore";
type ShowPagingButtonsEnum = "always" | "auto" | "hide";

export interface PaginationProps {
canNextPage: boolean;
canPreviousPage: boolean;
Expand All @@ -11,23 +15,28 @@ export interface PaginationProps {
pageSize: number;
previousPage: () => void;
setPaginationIndex?: Dispatch<SetStateAction<number>>;
showPagingButtons?: "always" | "auto";
showPagingButtons?: ShowPagingButtonsEnum;
labelNextPage?: string;
labelPreviousPage?: string;
labelFirstPage?: string;
labelLastPage?: string;
labelPagination?: string;
labelPagingStatus?: string;
pagination: PaginationEnum;
}

export function Pagination(props: PaginationProps): ReactElement | null {
const numberOfPages =
props.numberOfItems !== undefined ? Math.ceil(props.numberOfItems / props.pageSize) : undefined;
const lastPage = numberOfPages !== undefined ? numberOfPages - 1 : 0;
const hasLastPage = numberOfPages !== undefined;
const initialItem = props.numberOfItems === 0 ? 0 : props.page * props.pageSize + 1;
const lastItem = getLastItem(props.canNextPage, props.numberOfItems, props.page, props.pageSize);

const showControls = props.pagination === "buttons";
const initialItem = props.numberOfItems === 0 ? 0 : showControls ? props.page * props.pageSize + 1 : 1;
const lastItem = showControls
? getLastItem(props.canNextPage, props.numberOfItems ?? 0, props.page, props.pageSize)
: props.page * props.pageSize > (props.numberOfItems ?? 0)
? props.numberOfItems ?? 0
: props.page * props.pageSize;
const setPageIndex = (page: number): void => {
if (props.setPaginationIndex) {
props.setPaginationIndex(page);
Expand All @@ -38,63 +47,71 @@ export function Pagination(props: PaginationProps): ReactElement | null {
return null;
}

const pagingStatus = `${initialItem} to ${lastItem} ${
const pagingStatus = `${showControls ? `${initialItem} to ${lastItem}` : lastItem} ${
hasLastPage ? `of ${props.numberOfItems ?? (numberOfPages ?? 1) * props.pageSize}` : ""
}`;

return (
<div aria-label={props.labelPagination ?? "Pagination"} className="pagination-bar">
<button
className="btn pagination-button"
disabled={props.page === 0}
{...getEvents(() => {
props.gotoPage(0);
setPageIndex(0);
})}
aria-label={props.labelFirstPage ?? "Go to first page"}
>
<ControlIcon direction="step-backward" />
</button>
<button
className="btn pagination-button"
disabled={!props.canPreviousPage}
{...getEvents(() => {
props.previousPage();
setPageIndex(props.page - 1);
})}
aria-label={props.labelPreviousPage ?? "Go to previous page"}
>
<ControlIcon direction="backward" />
</button>
{showControls && (
<Fragment>
<button
className="btn pagination-button"
disabled={props.page === 0}
{...getEvents(() => {
props.gotoPage(0);
setPageIndex(0);
})}
aria-label={props.labelFirstPage ?? "Go to first page"}
>
<ControlIcon direction="step-backward" />
</button>
<button
className="btn pagination-button"
disabled={!props.canPreviousPage}
{...getEvents(() => {
props.previousPage();
setPageIndex(props.page - 1);
})}
aria-label={props.labelPreviousPage ?? "Go to previous page"}
>
<ControlIcon direction="backward" />
</button>
</Fragment>
)}
<span className="sr-only sr-only-focusable">
{props.labelPagingStatus ?? "Currently showing"} {pagingStatus}
</span>
<div aria-hidden className="paging-status">
{pagingStatus}
</div>
<button
aria-label={props.labelNextPage ?? "Go to next page"}
className="btn pagination-button"
disabled={!props.canNextPage}
{...getEvents(() => {
props.nextPage();
setPageIndex(props.page + 1);
})}
>
<ControlIcon direction="forward" />
</button>
{hasLastPage && (
<button
aria-label={props.labelLastPage ?? "Go to last page"}
className="btn pagination-button"
disabled={props.page === lastPage || props.numberOfItems === 0}
{...getEvents(() => {
props.gotoPage(lastPage);
setPageIndex(lastPage);
})}
>
<ControlIcon direction="step-forward" />
</button>
{showControls && (
<Fragment>
<button
aria-label={props.labelNextPage ?? "Go to next page"}
className="btn pagination-button"
disabled={!props.canNextPage}
{...getEvents(() => {
props.nextPage();
setPageIndex(props.page + 1);
})}
>
<ControlIcon direction="forward" />
</button>
{hasLastPage && (
<button
aria-label={props.labelLastPage ?? "Go to last page"}
className="btn pagination-button"
disabled={props.page === lastPage || props.numberOfItems === 0}
{...getEvents(() => {
props.gotoPage(lastPage);
setPageIndex(lastPage);
})}
>
<ControlIcon direction="step-forward" />
</button>
)}
</Fragment>
)}
</div>
);
Expand Down

0 comments on commit edd40dc

Please sign in to comment.