fix: add missed pagination property to findVersions and findGlobalVersions and handle it properly (#13763)
* The `pagination` property was missing in `findVersions` and
`findGlobalVersions` Local API operations, although the actual functions
did have it -
1b93c4becc/packages/payload/src/collections/operations/findVersions.ts (L25)
* The handling of the `pagination` property in those functions was
broken, this PR fixes it.
This commit is contained in:
@@ -97,11 +97,15 @@ export const findVersionsOperation = async <TData extends TypeWithVersion<TData>
|
|||||||
// Find
|
// Find
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
const usePagination = pagination && limit !== 0
|
||||||
|
const sanitizedLimit = limit ?? (usePagination ? 10 : 0)
|
||||||
|
const sanitizedPage = page || 1
|
||||||
|
|
||||||
const paginatedDocs = await payload.db.findVersions<TData>({
|
const paginatedDocs = await payload.db.findVersions<TData>({
|
||||||
collection: collectionConfig.slug,
|
collection: collectionConfig.slug,
|
||||||
limit: limit ?? 10,
|
limit: sanitizedLimit,
|
||||||
locale: locale!,
|
locale: locale!,
|
||||||
page: page || 1,
|
page: sanitizedPage,
|
||||||
pagination,
|
pagination,
|
||||||
req,
|
req,
|
||||||
select,
|
select,
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ export type Options<TSlug extends CollectionSlug> = {
|
|||||||
* @default 1
|
* @default 1
|
||||||
*/
|
*/
|
||||||
page?: number
|
page?: number
|
||||||
|
/**
|
||||||
|
* Set to `false` to return all documents and avoid querying for document counts which introduces some overhead.
|
||||||
|
* You can also combine that property with a specified `limit` to limit documents but avoid the count query.
|
||||||
|
*/
|
||||||
|
pagination?: boolean
|
||||||
/**
|
/**
|
||||||
* Specify [populate](https://payloadcms.com/docs/queries/select#populate) to control which fields to include to the result from populated documents.
|
* Specify [populate](https://payloadcms.com/docs/queries/select#populate) to control which fields to include to the result from populated documents.
|
||||||
*/
|
*/
|
||||||
@@ -114,6 +119,7 @@ export async function findVersionsLocal<TSlug extends CollectionSlug>(
|
|||||||
limit,
|
limit,
|
||||||
overrideAccess = true,
|
overrideAccess = true,
|
||||||
page,
|
page,
|
||||||
|
pagination = true,
|
||||||
populate,
|
populate,
|
||||||
select,
|
select,
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
@@ -136,6 +142,7 @@ export async function findVersionsLocal<TSlug extends CollectionSlug>(
|
|||||||
limit,
|
limit,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
page,
|
page,
|
||||||
|
pagination,
|
||||||
populate,
|
populate,
|
||||||
req: await createLocalReq(options as CreateLocalReqOptions, payload),
|
req: await createLocalReq(options as CreateLocalReqOptions, payload),
|
||||||
select,
|
select,
|
||||||
|
|||||||
@@ -79,11 +79,15 @@ export const findVersionsOperation = async <T extends TypeWithVersion<T>>(
|
|||||||
// Find
|
// Find
|
||||||
// /////////////////////////////////////
|
// /////////////////////////////////////
|
||||||
|
|
||||||
|
const usePagination = pagination && limit !== 0
|
||||||
|
const sanitizedLimit = limit ?? (usePagination ? 10 : 0)
|
||||||
|
const sanitizedPage = page || 1
|
||||||
|
|
||||||
const paginatedDocs = await payload.db.findGlobalVersions<T>({
|
const paginatedDocs = await payload.db.findGlobalVersions<T>({
|
||||||
global: globalConfig.slug,
|
global: globalConfig.slug,
|
||||||
limit: limit ?? 10,
|
limit: sanitizedLimit,
|
||||||
locale: locale!,
|
locale: locale!,
|
||||||
page: page || 1,
|
page: sanitizedPage,
|
||||||
pagination,
|
pagination,
|
||||||
req,
|
req,
|
||||||
select,
|
select,
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ export type Options<TSlug extends GlobalSlug> = {
|
|||||||
* @default 1
|
* @default 1
|
||||||
*/
|
*/
|
||||||
page?: number
|
page?: number
|
||||||
|
/**
|
||||||
|
* Set to `false` to return all documents and avoid querying for document counts which introduces some overhead.
|
||||||
|
* You can also combine that property with a specified `limit` to limit documents but avoid the count query.
|
||||||
|
*/
|
||||||
|
pagination?: boolean
|
||||||
/**
|
/**
|
||||||
* Specify [populate](https://payloadcms.com/docs/queries/select#populate) to control which fields to include to the result from populated documents.
|
* Specify [populate](https://payloadcms.com/docs/queries/select#populate) to control which fields to include to the result from populated documents.
|
||||||
*/
|
*/
|
||||||
@@ -101,6 +106,7 @@ export async function findGlobalVersionsLocal<TSlug extends GlobalSlug>(
|
|||||||
limit,
|
limit,
|
||||||
overrideAccess = true,
|
overrideAccess = true,
|
||||||
page,
|
page,
|
||||||
|
pagination = true,
|
||||||
populate,
|
populate,
|
||||||
select,
|
select,
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
@@ -120,6 +126,7 @@ export async function findGlobalVersionsLocal<TSlug extends GlobalSlug>(
|
|||||||
limit,
|
limit,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
page,
|
page,
|
||||||
|
pagination,
|
||||||
populate,
|
populate,
|
||||||
req: await createLocalReq(options as CreateLocalReqOptions, payload),
|
req: await createLocalReq(options as CreateLocalReqOptions, payload),
|
||||||
select,
|
select,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import AutosaveGlobal from './globals/Autosave.js'
|
|||||||
import AutosaveWithDraftButtonGlobal from './globals/AutosaveWithDraftButton.js'
|
import AutosaveWithDraftButtonGlobal from './globals/AutosaveWithDraftButton.js'
|
||||||
import DisablePublishGlobal from './globals/DisablePublish.js'
|
import DisablePublishGlobal from './globals/DisablePublish.js'
|
||||||
import DraftGlobal from './globals/Draft.js'
|
import DraftGlobal from './globals/Draft.js'
|
||||||
|
import DraftUnlimitedGlobal from './globals/DraftUnlimited.js'
|
||||||
import DraftWithMaxGlobal from './globals/DraftWithMax.js'
|
import DraftWithMaxGlobal from './globals/DraftWithMax.js'
|
||||||
import LocalizedGlobal from './globals/LocalizedGlobal.js'
|
import LocalizedGlobal from './globals/LocalizedGlobal.js'
|
||||||
import { MaxVersions } from './globals/MaxVersions.js'
|
import { MaxVersions } from './globals/MaxVersions.js'
|
||||||
@@ -66,6 +67,7 @@ export default buildConfigWithDefaults({
|
|||||||
DisablePublishGlobal,
|
DisablePublishGlobal,
|
||||||
LocalizedGlobal,
|
LocalizedGlobal,
|
||||||
MaxVersions,
|
MaxVersions,
|
||||||
|
DraftUnlimitedGlobal,
|
||||||
],
|
],
|
||||||
indexSortableFields: true,
|
indexSortableFields: true,
|
||||||
localization: {
|
localization: {
|
||||||
|
|||||||
61
test/versions/globals/DraftUnlimited.ts
Normal file
61
test/versions/globals/DraftUnlimited.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import type { GlobalConfig } from 'payload'
|
||||||
|
|
||||||
|
import { draftUnlimitedGlobalSlug } from '../slugs.js'
|
||||||
|
|
||||||
|
const DraftUnlimitedGlobal: GlobalConfig = {
|
||||||
|
slug: draftUnlimitedGlobalSlug,
|
||||||
|
label: 'Draft Unlimited Global',
|
||||||
|
admin: {
|
||||||
|
preview: () => 'https://payloadcms.com',
|
||||||
|
components: {
|
||||||
|
views: {
|
||||||
|
edit: {
|
||||||
|
version: {
|
||||||
|
actions: ['/elements/GlobalVersionButton/index.js'],
|
||||||
|
},
|
||||||
|
versions: {
|
||||||
|
actions: ['/elements/GlobalVersionsButton/index.js'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
versions: {
|
||||||
|
max: 0,
|
||||||
|
drafts: {
|
||||||
|
schedulePublish: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
access: {
|
||||||
|
read: ({ req: { user } }) => {
|
||||||
|
if (user) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
or: [
|
||||||
|
{
|
||||||
|
_status: {
|
||||||
|
equals: 'published',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
_status: {
|
||||||
|
exists: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
localized: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DraftUnlimitedGlobal
|
||||||
@@ -573,6 +573,44 @@ describe('Versions', () => {
|
|||||||
expect(restoredVersion.title).toStrictEqual('v1')
|
expect(restoredVersion.title).toStrictEqual('v1')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('findVersions - pagination should work correctly', async () => {
|
||||||
|
const post = await payload.create({
|
||||||
|
collection: 'draft-posts',
|
||||||
|
data: { description: 'a', title: 'title' },
|
||||||
|
})
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
await payload.update({ collection: 'draft-posts', id: post.id, data: {} })
|
||||||
|
}
|
||||||
|
const res = await payload.findVersions({
|
||||||
|
collection: 'draft-posts',
|
||||||
|
where: { parent: { equals: post.id } },
|
||||||
|
})
|
||||||
|
expect(res.totalDocs).toBe(101)
|
||||||
|
expect(res.docs).toHaveLength(10)
|
||||||
|
const resPaginationFalse = await payload.findVersions({
|
||||||
|
collection: 'draft-posts',
|
||||||
|
where: { parent: { equals: post.id } },
|
||||||
|
pagination: false,
|
||||||
|
})
|
||||||
|
const resPaginationFalse2 = await payload.find({
|
||||||
|
collection: 'draft-posts',
|
||||||
|
// where: { parent: { equals: post.id } },
|
||||||
|
pagination: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(resPaginationFalse.docs).toHaveLength(101)
|
||||||
|
expect(resPaginationFalse.totalDocs).toBe(101)
|
||||||
|
|
||||||
|
const resPaginationFalseLimit0 = await payload.findVersions({
|
||||||
|
collection: 'draft-posts',
|
||||||
|
where: { parent: { equals: post.id } },
|
||||||
|
pagination: false,
|
||||||
|
limit: 0,
|
||||||
|
})
|
||||||
|
expect(resPaginationFalseLimit0.docs).toHaveLength(101)
|
||||||
|
expect(resPaginationFalseLimit0.totalDocs).toBe(101)
|
||||||
|
})
|
||||||
|
|
||||||
describe('Update', () => {
|
describe('Update', () => {
|
||||||
it('should allow a draft to be patched', async () => {
|
it('should allow a draft to be patched', async () => {
|
||||||
const originalTitle = 'Here is a published post'
|
const originalTitle = 'Here is a published post'
|
||||||
@@ -1802,6 +1840,31 @@ describe('Versions', () => {
|
|||||||
expect(version_1_deleted).toBeFalsy()
|
expect(version_1_deleted).toBeFalsy()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('findGlobalVersions - pagination should work correctly', async () => {
|
||||||
|
for (let i = 0; i < 100; i++) {
|
||||||
|
await payload.updateGlobal({ slug: 'draft-unlimited-global', data: { title: 'title' } })
|
||||||
|
}
|
||||||
|
const res = await payload.findGlobalVersions({
|
||||||
|
slug: 'draft-unlimited-global',
|
||||||
|
})
|
||||||
|
expect(res.totalDocs).toBe(100)
|
||||||
|
expect(res.docs).toHaveLength(10)
|
||||||
|
const resPaginationFalse = await payload.findGlobalVersions({
|
||||||
|
slug: 'draft-unlimited-global',
|
||||||
|
pagination: false,
|
||||||
|
})
|
||||||
|
expect(resPaginationFalse.docs).toHaveLength(100)
|
||||||
|
expect(resPaginationFalse.totalDocs).toBe(100)
|
||||||
|
|
||||||
|
const resPaginationFalseLimit0 = await payload.findGlobalVersions({
|
||||||
|
slug: 'draft-unlimited-global',
|
||||||
|
pagination: false,
|
||||||
|
limit: 0,
|
||||||
|
})
|
||||||
|
expect(resPaginationFalseLimit0.docs).toHaveLength(100)
|
||||||
|
expect(resPaginationFalseLimit0.totalDocs).toBe(100)
|
||||||
|
})
|
||||||
|
|
||||||
describe('Read', () => {
|
describe('Read', () => {
|
||||||
it('should allow a version to be retrieved by ID', async () => {
|
it('should allow a version to be retrieved by ID', async () => {
|
||||||
const version = await payload.findGlobalVersionByID({
|
const version = await payload.findGlobalVersionByID({
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ export interface Config {
|
|||||||
'disable-publish-global': DisablePublishGlobal;
|
'disable-publish-global': DisablePublishGlobal;
|
||||||
'localized-global': LocalizedGlobal;
|
'localized-global': LocalizedGlobal;
|
||||||
'max-versions': MaxVersion;
|
'max-versions': MaxVersion;
|
||||||
|
'draft-unlimited-global': DraftUnlimitedGlobal;
|
||||||
};
|
};
|
||||||
globalsSelect: {
|
globalsSelect: {
|
||||||
'autosave-global': AutosaveGlobalSelect<false> | AutosaveGlobalSelect<true>;
|
'autosave-global': AutosaveGlobalSelect<false> | AutosaveGlobalSelect<true>;
|
||||||
@@ -137,6 +138,7 @@ export interface Config {
|
|||||||
'disable-publish-global': DisablePublishGlobalSelect<false> | DisablePublishGlobalSelect<true>;
|
'disable-publish-global': DisablePublishGlobalSelect<false> | DisablePublishGlobalSelect<true>;
|
||||||
'localized-global': LocalizedGlobalSelect<false> | LocalizedGlobalSelect<true>;
|
'localized-global': LocalizedGlobalSelect<false> | LocalizedGlobalSelect<true>;
|
||||||
'max-versions': MaxVersionsSelect<false> | MaxVersionsSelect<true>;
|
'max-versions': MaxVersionsSelect<false> | MaxVersionsSelect<true>;
|
||||||
|
'draft-unlimited-global': DraftUnlimitedGlobalSelect<false> | DraftUnlimitedGlobalSelect<true>;
|
||||||
};
|
};
|
||||||
locale: 'en' | 'es' | 'de';
|
locale: 'en' | 'es' | 'de';
|
||||||
user: User & {
|
user: User & {
|
||||||
@@ -1348,6 +1350,17 @@ export interface MaxVersion {
|
|||||||
updatedAt?: string | null;
|
updatedAt?: string | null;
|
||||||
createdAt?: string | null;
|
createdAt?: string | null;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "draft-unlimited-global".
|
||||||
|
*/
|
||||||
|
export interface DraftUnlimitedGlobal {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
_status?: ('draft' | 'published') | null;
|
||||||
|
updatedAt?: string | null;
|
||||||
|
createdAt?: string | null;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "autosave-global_select".
|
* via the `definition` "autosave-global_select".
|
||||||
@@ -1426,6 +1439,17 @@ export interface MaxVersionsSelect<T extends boolean = true> {
|
|||||||
createdAt?: T;
|
createdAt?: T;
|
||||||
globalType?: T;
|
globalType?: T;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
|
* via the `definition` "draft-unlimited-global_select".
|
||||||
|
*/
|
||||||
|
export interface DraftUnlimitedGlobalSelect<T extends boolean = true> {
|
||||||
|
title?: T;
|
||||||
|
_status?: T;
|
||||||
|
updatedAt?: T;
|
||||||
|
createdAt?: T;
|
||||||
|
globalType?: T;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* This interface was referenced by `Config`'s JSON-Schema
|
* This interface was referenced by `Config`'s JSON-Schema
|
||||||
* via the `definition` "TaskSchedulePublish".
|
* via the `definition` "TaskSchedulePublish".
|
||||||
@@ -1447,7 +1471,7 @@ export interface TaskSchedulePublish {
|
|||||||
relationTo: 'draft-posts-with-change-hook';
|
relationTo: 'draft-posts-with-change-hook';
|
||||||
value: string | DraftPostsWithChangeHook;
|
value: string | DraftPostsWithChangeHook;
|
||||||
} | null);
|
} | null);
|
||||||
global?: 'draft-global' | null;
|
global?: ('draft-global' | 'draft-unlimited-global') | null;
|
||||||
user?: (string | null) | User;
|
user?: (string | null) | User;
|
||||||
};
|
};
|
||||||
output?: unknown;
|
output?: unknown;
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ export const autosaveWithDraftButtonGlobal = 'autosave-with-draft-button-global'
|
|||||||
|
|
||||||
export const draftGlobalSlug = 'draft-global'
|
export const draftGlobalSlug = 'draft-global'
|
||||||
|
|
||||||
|
export const draftUnlimitedGlobalSlug = 'draft-unlimited-global'
|
||||||
|
|
||||||
export const draftWithMaxGlobalSlug = 'draft-with-max-global'
|
export const draftWithMaxGlobalSlug = 'draft-with-max-global'
|
||||||
|
|
||||||
export const globalSlugs = [autoSaveGlobalSlug, draftGlobalSlug]
|
export const globalSlugs = [autoSaveGlobalSlug, draftGlobalSlug]
|
||||||
|
|||||||
Reference in New Issue
Block a user