Skip to content

Commit 19073ab

Browse files
committed
Docs: reworded the Elasticsearch/OpenSearch result-window note and clarified that reports, previews, and classification store listings are exceptions to the global pagination config.
Harden pagination config validation Drop non-integer entries from pimcore_studio_ui.pagination.page_size_options instead of silently casting them, and reject non-integer input (e.g. 20.5,20,5) in the page-size CreatableSelect. Replace the remaining hardcoded default page sizes with appConfig.defaultPageSize for consistency.
1 parent e019358 commit 19073ab

6 files changed

Lines changed: 44 additions & 15 deletions

File tree

assets/js/src/core/components/pagination/pagination.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { useTranslation } from 'react-i18next'
1616
import { useStyles } from '@Pimcore/components/pagination/pagination.styles'
1717
import cn from 'classnames'
1818
import { appConfig } from '@Pimcore/app/config/app-config'
19-
import {DEFAULT_PAGE_SIZE} from "@Pimcore/modules/user/management/detail/tabs/references/constants";
2019

2120
export interface PaginationProps extends Omit<BasePaginationProps, 'pageSize' | 'defaultCurrent' | 'onShowSizeChange' | 'responsive' | 'totalBoundaryShowSizeChanger'> {
2221
}
@@ -29,7 +28,7 @@ export const Pagination = (props: PaginationProps): React.JSX.Element => {
2928

3029
const defaultProps: Partial<PaginationProps> = {
3130
current: 1,
32-
defaultPageSize: DEFAULT_PAGE_SIZE,
31+
defaultPageSize: appConfig.defaultPageSize,
3332
pageSizeOptions: appConfig.pageSizeOptions,
3433
showSizeChanger: false,
3534
simple: true,
@@ -61,8 +60,14 @@ export const Pagination = (props: PaginationProps): React.JSX.Element => {
6160
})) ?? []
6261

6362
const onSelectChange: SelectProps['onChange'] = (value) => {
63+
const parsedValue = Number(value)
64+
65+
if (!Number.isInteger(parsedValue)) {
66+
return
67+
}
68+
6469
setCurrent(1)
65-
setPageSize(Number(value))
70+
setPageSize(parsedValue)
6671
}
6772

6873
const itemRenderer: PaginationProps['itemRender'] = (page, type, originalElement) => {
@@ -112,15 +117,15 @@ export const Pagination = (props: PaginationProps): React.JSX.Element => {
112117
<CreatableSelect
113118
disabled={ paginationProps.disabled }
114119
inputType="number"
115-
numberInputProps={ { min: 1 } }
120+
numberInputProps={ { min: 1, precision: 0 } }
116121
onChange={ onSelectChange }
117122
onCreateOption={ (value) => ({
118123
value,
119124
label: `${value} / ${t('pagination.page')}`
120125
}) }
121126
options={ selectOptions }
122127
popupMatchSelectWidth={ false }
123-
validate={ (value) => !isNaN(parseInt(value)) && parseInt(value) > 0 }
128+
validate={ (value) => /^\d+$/.test(value.trim()) && Number(value) > 0 }
124129
value={ String(pageSize) }
125130
width={ 112 }
126131
/>

assets/js/src/core/modules/data-object/listing/data-layer/hooks/use-data-query-helper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { useClassDefinitionSelection } from '../../decorator/class-definition-se
1616
import { useData } from '@Pimcore/modules/element/listing/abstract/data-layer/provider/data/use-data'
1717
import { useAvailableColumns } from '@Pimcore/modules/element/listing/decorators/utils/column-configuration/context-layer/provider/available-columns/use-available-columns'
1818
import { useLanguageSelection } from '@Pimcore/components/language-selection'
19-
import {DEFAULT_PAGE_SIZE} from "@Pimcore/modules/user/management/detail/tabs/references/constants";
19+
import {appConfig} from "@Pimcore/app/config/app-config";
2020

2121
export const useDataQueryHelper: SettingsProviderProps['useDataQueryHelper'] = () => {
2222
const { useElementId } = useSettings()
@@ -80,7 +80,7 @@ export const useDataQueryHelper: SettingsProviderProps['useDataQueryHelper'] = (
8080
filters: {
8181
includeDescendants: true,
8282
page: 1,
83-
pageSize: DEFAULT_PAGE_SIZE
83+
pageSize: appConfig.defaultPageSize
8484
}
8585
}
8686
}

assets/js/src/core/modules/element/editor/shared-tab-manager/tabs/dependencies/components/pagination/pagination.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export const Pagination = (props: PaginationProps): React.JSX.Element => {
3737
return (
3838
<PimPagination
3939
current={ props.page }
40-
defaultPageSize={ 20 }
40+
defaultPageSize={ appConfig.defaultPageSize }
4141
onChange={ props.onChange }
4242
pageSizeOptions={ appConfig.pageSizeOptions }
4343
showSizeChanger

assets/js/src/core/modules/element/listing/decorators/paging/context-layer/paging/provider/paging-provider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010

1111
import React, { createContext, useMemo, useState } from 'react'
12-
import {DEFAULT_PAGE_SIZE} from "@Pimcore/modules/user/management/detail/tabs/references/constants";
12+
import {appConfig} from "@Pimcore/app/config/app-config";
1313

1414
export interface PagingData {
1515
page: number
@@ -24,7 +24,7 @@ export const PagingContext = createContext<PagingContextProps>(undefined)
2424

2525
export const PagingProvider = ({ children }: { children: React.ReactNode }): React.JSX.Element => {
2626
const [page, setPage] = useState(1)
27-
const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE)
27+
const [pageSize, setPageSize] = useState(appConfig.defaultPageSize)
2828

2929
return useMemo(() => (
3030
<PagingContext.Provider value={ { page, setPage, pageSize, setPageSize } }>

doc/03_Configuration_and_Administration/01_Configuration/07_Pagination.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ pimcore_studio_ui:
1919
- `page_size_options` is a comma separated list of page sizes offered in the page-size changer.
2020
- `default_page_size` is the page size a listing starts with before the user picks another option. The default value should be included in the `page_size_options`.
2121

22-
> **Note:** Elasticsearch and OpenSearch limit how many results can be fetched in a single request
23-
> (by default 10,000, controlled by the `index.max_result_window` index setting). Make sure the
24-
> largest value in `page_size_options` does not exceed that limit, or listings using it will fail.
22+
> **Note:** Elasticsearch and OpenSearch limit each request's result window (`from + size`) to
23+
> `index.max_result_window` (10,000 by default). Keep every requested page offset plus page size
24+
> within that limit; limiting only the largest page-size option does not prevent deep-page failures.
2525

26-
Both settings apply globally to all paginated listings in the UI.
26+
Both settings apply globally to the most paginated listings in the UI.
27+
There are exceptions for reports, previews, and classification store listings which have an individual configuration.

src/DependencyInjection/PimcoreStudioUiExtension.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public function load(array $configs, ContainerBuilder $container): void
7474

7575
$container->setParameter(
7676
'pimcore_studio_ui.pagination.page_size_options',
77-
array_map(static fn (string $option): int => (int) trim($option), explode(',', $config['pagination']['page_size_options']))
77+
$this->parsePageSizeOptions($config['pagination']['page_size_options'])
7878
);
7979

8080
$container->setParameter(
@@ -83,6 +83,29 @@ public function load(array $configs, ContainerBuilder $container): void
8383
);
8484
}
8585

86+
/**
87+
* Parses a comma-separated string of page size options into a list of integers.
88+
* Non-numeric or malformed entries are silently discarded.
89+
*
90+
* @param string $pageSizeOptions comma-separated list of page sizes, e.g. "10, 25, 50"
91+
*
92+
* @return int[] the parsed page size options
93+
*/
94+
private function parsePageSizeOptions(string $pageSizeOptions): array
95+
{
96+
$options = [];
97+
98+
foreach (explode(',', $pageSizeOptions) as $option) {
99+
$option = trim($option);
100+
101+
if (ctype_digit($option)) {
102+
$options[] = (int) $option;
103+
}
104+
}
105+
106+
return $options;
107+
}
108+
86109
/**
87110
* Registers the configured studio url_path under the "studio" Pimcore context
88111
* so site resolution and document routing are bypassed for studio requests.

0 commit comments

Comments
 (0)