From ae525e0e0b457f93eb1f4ba592295ef3ef326b98 Mon Sep 17 00:00:00 2001 From: ChengLei Shao Date: Wed, 9 Oct 2024 15:38:43 +0800 Subject: [PATCH] chore: simple paginate hasNext option (#5358) * chore: simple paginate hasNext option * fix: usePaginationProps * fix: usePaginationProps --------- Co-authored-by: katherinehhh --- .../actions/src/__tests__/list-action.test.ts | 48 +++++++++++++++++++ packages/core/actions/src/actions/list.ts | 7 ++- .../antd/grid-card/GridCard.tsx | 5 +- .../schema-component/antd/table-v2/Table.tsx | 6 ++- .../src/default-actions/list.ts | 5 +- 5 files changed, 64 insertions(+), 7 deletions(-) diff --git a/packages/core/actions/src/__tests__/list-action.test.ts b/packages/core/actions/src/__tests__/list-action.test.ts index 5bd8a4909..8533cd650 100644 --- a/packages/core/actions/src/__tests__/list-action.test.ts +++ b/packages/core/actions/src/__tests__/list-action.test.ts @@ -146,4 +146,52 @@ describe('list action', () => { expect(response.status).toEqual(200); expect(response.body.count).toEqual(0); }); + + it('should list with simple paginate', async () => { + const Item = app.collection({ + name: 'items', + simplePaginate: true, + fields: [{ type: 'string', name: 'name' }], + }); + + await app.db.sync(); + + await Item.repository.create({ + values: [ + { + name: 'item1', + }, + { + name: 'item2', + }, + { + name: 'item3', + }, + ], + }); + + const response = await app + .agent() + .resource('items') + .list({ + fields: ['id'], + pageSize: 1, + page: 2, + }); + + const body = response.body; + expect(body.hasNext).toBeTruthy(); + + const lastPageResponse = await app + .agent() + .resource('items') + .list({ + fields: ['id'], + pageSize: 1, + page: 3, + }); + + const lastPageBody = lastPageResponse.body; + expect(lastPageBody.hasNext).toBeFalsy(); + }); }); diff --git a/packages/core/actions/src/actions/list.ts b/packages/core/actions/src/actions/list.ts index 0ad05ccce..0fcf556b1 100644 --- a/packages/core/actions/src/actions/list.ts +++ b/packages/core/actions/src/actions/list.ts @@ -7,7 +7,6 @@ * For more information, please refer to: https://www.nocobase.com/agreement. */ -import { assign, isValidFilter } from '@nocobase/utils'; import { Context } from '..'; import { getRepositoryFromParams, pageArgsToLimitArgs } from '../utils'; import { DEFAULT_PAGE, DEFAULT_PER_PAGE } from '../constants'; @@ -49,9 +48,13 @@ async function listWithPagination(ctx: Context) { }); if (simplePaginate) { + options.limit = options.limit + 1; + const rows = await repository.find(options); + ctx.body = { - rows, + rows: rows.slice(0, pageSize), + hasNext: rows.length > pageSize, page: Number(page), pageSize: Number(pageSize), }; diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx index 05777e75e..deb748099 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.tsx @@ -81,8 +81,7 @@ const usePaginationProps = () => { const field = useField(); const { service, columnCount: _columnCount = defaultColumnCount } = useGridCardBlockContext(); const meta = service?.data?.meta; - const { count, pageSize, page } = meta || {}; - + const { count, pageSize, page, hasNext } = meta || {}; if (count) { return { total: count || 0, @@ -100,7 +99,7 @@ const usePaginationProps = () => { showTitle: false, showSizeChanger: true, hideOnSinglePage: false, - total: field.value?.length < pageSize ? pageSize * page : pageSize * page + 1, + total: field.value?.length < pageSize || !hasNext ? pageSize * page : pageSize * page + 1, className: css` .ant-pagination-simple-pager { display: none !important; diff --git a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx index f33c7acb4..6230c2d73 100644 --- a/packages/core/client/src/schema-component/antd/table-v2/Table.tsx +++ b/packages/core/client/src/schema-component/antd/table-v2/Table.tsx @@ -42,6 +42,7 @@ import { useToken } from '../__builtins__'; import { SubFormProvider } from '../association-field/hooks'; import { ColumnFieldProvider } from './components/ColumnFieldProvider'; import { extractIndex, isCollectionFieldComponent, isColumnComponent } from './utils'; +import { useDataBlockRequest } from '../../../'; const MemoizedAntdTable = React.memo(AntdTable); const useArrayField = (props) => { @@ -267,6 +268,9 @@ const usePaginationProps = (pagination1, pagination2) => { const { t } = useTranslation(); const field: any = useField(); const { token } = useToken(); + const { data } = useDataBlockRequest() || ({} as any); + const { meta } = data || {}; + const { hasNext } = meta || {}; const pagination = useMemo( () => ({ ...pagination1, ...pagination2 }), [JSON.stringify({ ...pagination1, ...pagination2 })], @@ -295,7 +299,7 @@ const usePaginationProps = (pagination1, pagination2) => { showSizeChanger: true, hideOnSinglePage: false, ...pagination, - total: field.value?.length < pageSize ? pageSize * current : pageSize * current + 1, + total: field.value?.length < pageSize || !hasNext ? pageSize * current : pageSize * current + 1, className: css` .ant-pagination-simple-pager { display: none !important; diff --git a/packages/core/data-source-manager/src/default-actions/list.ts b/packages/core/data-source-manager/src/default-actions/list.ts index a1de82d7e..50874f9f1 100644 --- a/packages/core/data-source-manager/src/default-actions/list.ts +++ b/packages/core/data-source-manager/src/default-actions/list.ts @@ -57,9 +57,12 @@ async function listWithPagination(ctx: Context) { }); if (simplePaginate) { + options.limit = options.limit + 1; + const rows = await repository.find(options); ctx.body = { - rows, + rows: rows.slice(0, pageSize), + hasNext: rows.length > pageSize, page: Number(page), pageSize: Number(pageSize), };