diff --git a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md index 3edbbd4f9d..c58037c199 100644 --- a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] + +### Added + +- Added option for users to dynamically change the page size. + ## [2.18.0] - 2024-04-30 ### Changed diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index 97da1fdc07..86fefe52a7 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -88,7 +88,12 @@ export function getProperties( if (values.showEmptyPlaceholder === "none") { hidePropertyIn(defaultProperties, values, "emptyPlaceholder"); } - + if (values.pageSizeType === "dynamic") { + hidePropertyIn(defaultProperties, values, "pageSize"); + } + if (values.pageSizeType === "static") { + hidePropertyIn(defaultProperties, values, "dynamicPageSize"); + } hideSelectionProperties(defaultProperties, values); changePropertyIn( diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.tsx b/packages/pluggableWidgets/datagrid-web/src/Datagrid.tsx index 71f7ff949f..d23afe858e 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.tsx @@ -5,6 +5,7 @@ import { ReactElement, ReactNode, createElement, useCallback, useEffect, useMemo import { DatagridContainerProps } from "../typings/DatagridProps"; import { Cell } from "./components/Cell"; import { Widget } from "./components/Widget"; +import { isAvailable } from "@mendix/widget-plugin-platform/framework/is-available"; import { WidgetHeaderContext } from "./components/WidgetHeaderContext"; import { UpdateDataSourceFn, useDG2ExportApi } from "./features/export"; import "./ui/Datagrid.scss"; @@ -27,9 +28,11 @@ interface Props extends DatagridContainerProps { const Container = observer((props: Props): ReactElement => { const isInfiniteLoad = props.pagination === "virtualScrolling" || props.pagination === "loadMore"; - const currentPage = isInfiniteLoad - ? props.datasource.limit / props.pageSize - : props.datasource.offset / props.pageSize; + const pageSizeNew = + props.pageSizeType === "dynamic" + ? Number(isAvailable(props.dynamicPageSize) ? props.dynamicPageSize.value : 0) + : props.pageSize; + const currentPage = isInfiniteLoad ? props.datasource.limit / pageSizeNew : props.datasource.offset / pageSizeNew; const { FilterContext } = useFilterContext(); const { columnsStore, rootStore } = props; @@ -54,7 +57,6 @@ const Container = observer((props: Props): ReactElement => { if (limit != null) { props.datasource?.setLimit(limit); } - if (reload) { props.datasource.reload(); } @@ -70,17 +72,22 @@ const Container = observer((props: Props): ReactElement => { }, props.refreshInterval * 1000); } }, [props.datasource, props.refreshInterval]); - + useEffect(() => { + if (props.pageSizeType === "dynamic") { + props.datasource.setLimit(pageSizeNew); + props.datasource.setOffset(0); + } + }, [pageSizeNew]); const setPage = useCallback( (computePage: (prevPage: number) => number) => { const newPage = computePage(currentPage); if (isInfiniteLoad) { - props.datasource.setLimit(newPage * props.pageSize); + props.datasource.setLimit(newPage * pageSizeNew); } else { - props.datasource.setOffset(newPage * props.pageSize); + props.datasource.setOffset(newPage * pageSizeNew); } }, - [props.datasource, props.pageSize, isInfiniteLoad, currentPage] + [props.datasource, pageSizeNew, isInfiniteLoad, currentPage] ); const selectionHelper = useSelectionHelper(props.itemSelection, props.datasource, props.onSelectionChange); @@ -101,7 +108,7 @@ const Container = observer((props: Props): ReactElement => { const focusController = useFocusTargetController({ rows: items.length, columns: visibleColumnsCount, - pageSize: props.pageSize + pageSize: pageSizeNew }); const cellEventsController = useCellEventsController(selectActionHelper, clickActionHelper, focusController); @@ -163,13 +170,16 @@ const Container = observer((props: Props): ReactElement => { ) } - hasMoreItems={props.datasource.hasMoreItems ?? false} + hasMoreItems={ + pageSizeNew !== 0 && + (props.datasource.hasMoreItems || (currentPage + 1) * pageSizeNew < (props.datasource.totalCount || 0)) + } headerWrapperRenderer={useCallback((_columnIndex: number, header: ReactElement) => header, [])} id={useMemo(() => `DataGrid${generateUUID()}`, [])} numberOfItems={props.datasource.totalCount} onExportCancel={abort} page={currentPage} - pageSize={props.pageSize} + pageSize={pageSizeNew} paginationType={props.pagination} loadMoreButtonCaption={props.loadMoreButtonCaption?.value} paging={useShowPagination({ diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 74494e6305..c2a679bb10 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -203,6 +203,21 @@ + + Pagination + + + Static + Dynamic + + + + PageSize + Select an attribute for dynamic page size. + + + + Page size diff --git a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts index bb8f09424d..fbf8b10005 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -47,6 +47,8 @@ export interface ColumnsType { wrapText: boolean; } +export type PageSizeTypeEnum = "static" | "dynamic"; + export type PaginationEnum = "buttons" | "virtualScrolling" | "loadMore"; export type PagingPositionEnum = "bottom" | "top" | "both"; @@ -107,6 +109,8 @@ export interface DatagridContainerProps { showSelectAllToggle: boolean; columns: ColumnsType[]; columnsFilterable: boolean; + pageSizeType: PageSizeTypeEnum; + dynamicPageSize: EditableValue; pageSize: number; pagination: PaginationEnum; pagingPosition: PagingPositionEnum; @@ -150,6 +154,8 @@ export interface DatagridPreviewProps { showSelectAllToggle: boolean; columns: ColumnsPreviewType[]; columnsFilterable: boolean; + pageSizeType: PageSizeTypeEnum; + dynamicPageSize: string; pageSize: number | null; pagination: PaginationEnum; pagingPosition: PagingPositionEnum;