fix: max versions config not being respected on globals (#6654)

Closes https://github.com/payloadcms/payload/issues/6646

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
This commit is contained in:
Paul
2024-06-06 13:21:32 -04:00
committed by GitHub
parent 9bd9e7a986
commit 8dd5e4dc24
7 changed files with 327 additions and 12 deletions

View File

@@ -68,7 +68,7 @@ export const enforceMaxVersions = async ({
}
await payload.db.deleteVersions({
collection: collection?.slug,
collection: slug,
req,
where: deleteQuery,
})

View File

@@ -0,0 +1,125 @@
import type { CollectionConfig } from 'payload/types'
import CollectionVersionButton from '../elements/CollectionVersionButton/index.js'
import CollectionVersionsButton from '../elements/CollectionVersionsButton/index.js'
import { CustomPublishButton } from '../elements/CustomSaveButton/index.js'
import { draftWithMaxCollectionSlug } from '../slugs.js'
const DraftWithMaxPosts: CollectionConfig = {
slug: draftWithMaxCollectionSlug,
access: {
read: ({ req: { user } }) => {
if (user) {
return true
}
return {
or: [
{
_status: {
equals: 'published',
},
},
{
_status: {
exists: false,
},
},
],
}
},
readVersions: ({ req: { user } }) => Boolean(user),
},
admin: {
components: {
edit: {
PublishButton: CustomPublishButton,
},
views: {
Edit: {
Version: {
actions: [CollectionVersionButton],
},
Versions: {
actions: [CollectionVersionsButton],
},
},
},
},
defaultColumns: ['title', 'description', 'createdAt', '_status'],
preview: () => 'https://payloadcms.com',
useAsTitle: 'title',
},
fields: [
{
name: 'title',
type: 'text',
label: 'Title',
localized: true,
required: true,
unique: true,
},
{
name: 'description',
type: 'textarea',
label: 'Description',
required: true,
},
{
name: 'radio',
type: 'radio',
options: [
{
label: { en: 'Test en', es: 'Test es' },
value: 'test',
},
],
},
{
name: 'select',
type: 'select',
hasMany: true,
options: [
{
label: { en: 'Test1 en', es: 'Test1 es' },
value: 'test1',
},
{
label: { en: 'Test2 en', es: 'Test2 es' },
value: 'test2',
},
],
},
{
name: 'blocksField',
type: 'blocks',
blocks: [
{
slug: 'block',
fields: [
{
name: 'text',
type: 'text',
},
{
name: 'localized',
type: 'text',
localized: true,
},
],
},
],
},
{
name: 'relation',
type: 'relationship',
relationTo: draftWithMaxCollectionSlug,
},
],
versions: {
drafts: true,
maxPerDoc: 1,
},
}
export default DraftWithMaxPosts

View File

@@ -3,16 +3,26 @@ import AutosavePosts from './collections/Autosave.js'
import CustomIDs from './collections/CustomIDs.js'
import DisablePublish from './collections/DisablePublish.js'
import DraftPosts from './collections/Drafts.js'
import DraftWithMax from './collections/DraftsWithMax.js'
import Posts from './collections/Posts.js'
import VersionPosts from './collections/Versions.js'
import AutosaveGlobal from './globals/Autosave.js'
import DisablePublishGlobal from './globals/DisablePublish.js'
import DraftGlobal from './globals/Draft.js'
import DraftWithMaxGlobal from './globals/DraftWithMax.js'
import { seed } from './seed.js'
export default buildConfigWithDefaults({
collections: [DisablePublish, Posts, AutosavePosts, DraftPosts, VersionPosts, CustomIDs],
globals: [AutosaveGlobal, DraftGlobal, DisablePublishGlobal],
collections: [
DisablePublish,
Posts,
AutosavePosts,
DraftPosts,
DraftWithMax,
VersionPosts,
CustomIDs,
],
globals: [AutosaveGlobal, DraftGlobal, DraftWithMaxGlobal, DisablePublishGlobal],
indexSortableFields: true,
localization: {
defaultLocale: 'en',

View File

@@ -55,6 +55,8 @@ import {
disablePublishSlug,
draftCollectionSlug,
draftGlobalSlug,
draftWithMaxCollectionSlug,
draftWithMaxGlobalSlug,
postCollectionSlug,
} from './slugs.js'
@@ -352,6 +354,44 @@ describe('versions', () => {
expect(href).toBe(`${pathname}/versions`)
})
test('global — respects max number of versions', async () => {
await payload.updateGlobal({
slug: draftWithMaxGlobalSlug,
data: {
title: 'initial title',
},
})
const global = new AdminUrlUtil(serverURL, draftWithMaxGlobalSlug)
await page.goto(global.global(draftWithMaxGlobalSlug))
const titleFieldInitial = page.locator('#field-title')
await titleFieldInitial.fill('updated title')
await saveDocAndAssert(page, '#action-save-draft')
await expect(titleFieldInitial).toHaveValue('updated title')
const versionsTab = page.locator('.doc-tab', {
hasText: '1',
})
await versionsTab.waitFor({ state: 'visible' })
expect(versionsTab).toBeTruthy()
const titleFieldUpdated = page.locator('#field-title')
await titleFieldUpdated.fill('latest title')
await saveDocAndAssert(page, '#action-save-draft')
await expect(titleFieldUpdated).toHaveValue('latest title')
const versionsTabUpdated = page.locator('.doc-tab', {
hasText: '1',
})
await versionsTabUpdated.waitFor({ state: 'visible' })
expect(versionsTabUpdated).toBeTruthy()
})
test('global — has versions route', async () => {
const global = new AdminUrlUtil(serverURL, globalSlug)
const versionsURL = `${global.global(globalSlug)}/versions`
@@ -535,5 +575,45 @@ describe('versions', () => {
await expect(page.locator('.rs__option')).toHaveText('some title')
})
test('collection — respects max number of versions', async () => {
const maxOneCollection = await payload.create({
collection: draftWithMaxCollectionSlug,
data: {
title: 'initial title',
description: 'some description',
},
draft: true,
})
const collection = new AdminUrlUtil(serverURL, draftWithMaxCollectionSlug)
await page.goto(collection.edit(maxOneCollection.id))
const titleFieldInitial = page.locator('#field-title')
await titleFieldInitial.fill('updated title')
await saveDocAndAssert(page, '#action-save-draft')
await expect(titleFieldInitial).toHaveValue('updated title')
const versionsTab = page.locator('.doc-tab', {
hasText: '1',
})
await versionsTab.waitFor({ state: 'visible' })
expect(versionsTab).toBeTruthy()
const titleFieldUpdated = page.locator('#field-title')
await titleFieldUpdated.fill('latest title')
await saveDocAndAssert(page, '#action-save-draft')
await expect(titleFieldUpdated).toHaveValue('latest title')
const versionsTabUpdated = page.locator('.doc-tab', {
hasText: '1',
})
await versionsTabUpdated.waitFor({ state: 'visible' })
expect(versionsTabUpdated).toBeTruthy()
})
})
})

View File

@@ -0,0 +1,61 @@
import type { GlobalConfig } from 'payload/types'
import GlobalVersionButton from '../elements/GlobalVersionButton/index.js'
import GlobalVersionsButton from '../elements/GlobalVersionsButton/index.js'
import { draftWithMaxGlobalSlug } from '../slugs.js'
const DraftWithMaxGlobal: GlobalConfig = {
slug: draftWithMaxGlobalSlug,
label: 'Draft Global',
admin: {
preview: () => 'https://payloadcms.com',
components: {
views: {
Edit: {
Version: {
actions: [GlobalVersionButton],
},
Versions: {
actions: [GlobalVersionsButton],
},
},
},
},
},
versions: {
max: 1,
drafts: 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 DraftWithMaxGlobal

View File

@@ -12,6 +12,7 @@ export interface Config {
posts: Post;
'autosave-posts': AutosavePost;
'draft-posts': DraftPost;
'draft-with-max-posts': DraftWithMaxPost;
'version-posts': VersionPost;
'custom-ids': CustomId;
users: User;
@@ -21,6 +22,7 @@ export interface Config {
globals: {
'autosave-global': AutosaveGlobal;
'draft-global': DraftGlobal;
'draft-with-max-global': DraftWithMaxGlobal;
'disable-publish-global': DisablePublishGlobal;
};
locale: 'en' | 'es';
@@ -98,6 +100,30 @@ export interface DraftPost {
createdAt: string;
_status?: ('draft' | 'published') | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "draft-with-max-posts".
*/
export interface DraftWithMaxPost {
id: string;
title: string;
description: string;
radio?: 'test' | null;
select?: ('test1' | 'test2')[] | null;
blocksField?:
| {
text?: string | null;
localized?: string | null;
id?: string | null;
blockName?: string | null;
blockType: 'block';
}[]
| null;
relation?: (string | null) | DraftWithMaxPost;
updatedAt: string;
createdAt: string;
_status?: ('draft' | 'published') | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "custom-ids".
@@ -181,6 +207,17 @@ export interface DraftGlobal {
updatedAt?: string | null;
createdAt?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "draft-with-max-global".
*/
export interface DraftWithMaxGlobal {
id: string;
title: string;
_status?: ('draft' | 'published') | null;
updatedAt?: string | null;
createdAt?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "disable-publish-global".

View File

@@ -1,16 +1,17 @@
export const autosaveCollectionSlug = 'autosave-posts' as const
export const autosaveCollectionSlug = 'autosave-posts'
export const customIDSlug = 'custom-ids' as const
export const customIDSlug = 'custom-ids'
export const draftCollectionSlug = 'draft-posts' as const
export const draftCollectionSlug = 'draft-posts'
export const draftWithMaxCollectionSlug = 'draft-with-max-posts'
export const postCollectionSlug = 'posts' as const
export const postCollectionSlug = 'posts'
export const versionCollectionSlug = 'version-posts' as const
export const versionCollectionSlug = 'version-posts'
export const disablePublishSlug = 'disable-publish' as const
export const disablePublishSlug = 'disable-publish'
export const disablePublishGlobalSlug = 'disable-publish-global' as const
export const disablePublishGlobalSlug = 'disable-publish-global'
export const collectionSlugs = [
autosaveCollectionSlug,
@@ -19,7 +20,8 @@ export const collectionSlugs = [
versionCollectionSlug,
]
export const autoSaveGlobalSlug = 'autosave-global' as const
export const draftGlobalSlug = 'draft-global' as const
export const autoSaveGlobalSlug = 'autosave-global'
export const draftGlobalSlug = 'draft-global'
export const draftWithMaxGlobalSlug = 'draft-with-max-global'
export const globalSlugs = [autoSaveGlobalSlug, draftGlobalSlug]