feat: add publish specific locale (#7669)
## Description 1. Adds ability to publish a specific individual locale (collections and globals) 2. Shows published locale in versions list and version comparison 3. Adds new int tests to `versions` test suite - [X] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository. ## Type of change - [X] New feature (non-breaking change which adds functionality) - [ ] This change requires a documentation update ## Checklist: - [X] I have added tests that prove my fix is effective or that my feature works - [X] Existing test suite passes locally with my changes - [ ] I have made corresponding changes to the documentation --------- Co-authored-by: Dan Ribbens <dan.ribbens@gmail.com>
This commit is contained in:
committed by
GitHub
parent
aee76cb793
commit
b7a0b15786
24
test/versions/collections/Localized.ts
Normal file
24
test/versions/collections/Localized.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { localizedCollectionSlug } from '../slugs.js'
|
||||
|
||||
const LocalizedPosts: CollectionConfig = {
|
||||
slug: localizedCollectionSlug,
|
||||
versions: {
|
||||
drafts: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default LocalizedPosts
|
||||
@@ -8,12 +8,14 @@ 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 LocalizedPosts from './collections/Localized.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 LocalizedGlobal from './globals/LocalizedGlobal.js'
|
||||
import { seed } from './seed.js'
|
||||
|
||||
export default buildConfigWithDefaults({
|
||||
@@ -28,14 +30,36 @@ export default buildConfigWithDefaults({
|
||||
AutosavePosts,
|
||||
DraftPosts,
|
||||
DraftWithMax,
|
||||
LocalizedPosts,
|
||||
VersionPosts,
|
||||
CustomIDs,
|
||||
],
|
||||
globals: [AutosaveGlobal, DraftGlobal, DraftWithMaxGlobal, DisablePublishGlobal],
|
||||
globals: [AutosaveGlobal, DraftGlobal, DraftWithMaxGlobal, DisablePublishGlobal, LocalizedGlobal],
|
||||
indexSortableFields: true,
|
||||
localization: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'es'],
|
||||
locales: [
|
||||
{
|
||||
code: 'en',
|
||||
label: 'English',
|
||||
},
|
||||
{
|
||||
code: 'es',
|
||||
label: {
|
||||
en: 'Spanish',
|
||||
es: 'Español',
|
||||
de: 'Spanisch',
|
||||
},
|
||||
},
|
||||
{
|
||||
code: 'de',
|
||||
label: {
|
||||
en: 'German',
|
||||
es: 'Alemán',
|
||||
de: 'Deutsch',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
onInit: async (payload) => {
|
||||
if (process.env.SEED_IN_CONFIG_ONINIT !== 'false') {
|
||||
|
||||
@@ -48,8 +48,8 @@ import { reInitializeDB } from '../helpers/reInitializeDB.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import { titleToDelete } from './shared.js'
|
||||
import {
|
||||
autoSaveGlobalSlug,
|
||||
autosaveCollectionSlug,
|
||||
autoSaveGlobalSlug,
|
||||
customIDSlug,
|
||||
disablePublishGlobalSlug,
|
||||
disablePublishSlug,
|
||||
@@ -57,6 +57,8 @@ import {
|
||||
draftGlobalSlug,
|
||||
draftWithMaxCollectionSlug,
|
||||
draftWithMaxGlobalSlug,
|
||||
localizedCollectionSlug,
|
||||
localizedGlobalSlug,
|
||||
postCollectionSlug,
|
||||
} from './slugs.js'
|
||||
|
||||
@@ -66,6 +68,8 @@ const dirname = path.dirname(filename)
|
||||
const { beforeAll, beforeEach, describe } = test
|
||||
|
||||
let payload: PayloadTestSDK<Config>
|
||||
let global: AdminUrlUtil
|
||||
let id: string
|
||||
|
||||
const waitForAutoSaveToComplete = async (page: Page) => {
|
||||
await expect(async () => {
|
||||
@@ -97,6 +101,8 @@ describe('versions', () => {
|
||||
let disablePublishURL: AdminUrlUtil
|
||||
let customIDURL: AdminUrlUtil
|
||||
let postURL: AdminUrlUtil
|
||||
let global: AdminUrlUtil
|
||||
let id: string
|
||||
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
@@ -282,7 +288,7 @@ describe('versions', () => {
|
||||
hasText: 'Versions',
|
||||
})
|
||||
await versionsTab.waitFor({ state: 'visible' })
|
||||
const versionsPill = versionsTab.locator('.doc-tab__count--has-count')
|
||||
const versionsPill = versionsTab.locator('.doc-tab__count')
|
||||
await versionsPill.waitFor({ state: 'visible' })
|
||||
const versionCount = versionsTab.locator('.doc-tab__count').first()
|
||||
await expect(versionCount).toHaveText('11')
|
||||
@@ -320,7 +326,6 @@ describe('versions', () => {
|
||||
await saveDocAndAssert(page, '#action-save-draft')
|
||||
const savedDocURL = page.url()
|
||||
await page.goto(`${savedDocURL}/versions`)
|
||||
await page.waitForURL(`${savedDocURL}/versions`)
|
||||
const row2 = page.locator('tbody .row-2')
|
||||
const versionID = await row2.locator('.cell-id').textContent()
|
||||
await page.goto(`${savedDocURL}/versions/${versionID}`)
|
||||
@@ -612,4 +617,90 @@ describe('versions', () => {
|
||||
expect(versionsTabUpdated).toBeTruthy()
|
||||
})
|
||||
})
|
||||
describe('Collections - publish specific locale', () => {
|
||||
beforeAll(() => {
|
||||
url = new AdminUrlUtil(serverURL, localizedCollectionSlug)
|
||||
global = new AdminUrlUtil(serverURL, localizedGlobalSlug)
|
||||
})
|
||||
test('should show publish individual locale dropdown', async () => {
|
||||
await page.goto(url.create)
|
||||
const publishOptions = page.locator('.doc-controls__controls .popup')
|
||||
|
||||
await expect(publishOptions).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show option to publish current locale', async () => {
|
||||
await page.goto(url.create)
|
||||
const publishOptions = page.locator('.doc-controls__controls .popup')
|
||||
await publishOptions.click()
|
||||
|
||||
const publishSpecificLocale = page.locator('.doc-controls__controls .popup__content')
|
||||
|
||||
await expect(publishSpecificLocale).toContainText('English')
|
||||
})
|
||||
|
||||
test('should publish specific locale', async () => {
|
||||
await page.goto(url.create)
|
||||
await changeLocale(page, 'es')
|
||||
const textField = page.locator('#field-text')
|
||||
const status = page.locator('.status__value')
|
||||
|
||||
await textField.fill('spanish published')
|
||||
await saveDocAndAssert(page)
|
||||
await expect(status).toContainText('Changed')
|
||||
|
||||
await textField.fill('spanish draft')
|
||||
await saveDocAndAssert(page, '#action-save-draft')
|
||||
await expect(status).toContainText('Changed')
|
||||
|
||||
await changeLocale(page, 'en')
|
||||
await textField.fill('english published')
|
||||
const publishOptions = page.locator('.doc-controls__controls .popup')
|
||||
await publishOptions.click()
|
||||
|
||||
const publishSpecificLocale = page.locator('.popup-button-list button').first()
|
||||
await expect(publishSpecificLocale).toContainText('English')
|
||||
await publishSpecificLocale.click()
|
||||
|
||||
id = await page.locator('.id-label').getAttribute('title')
|
||||
|
||||
const data = await payload.find({
|
||||
collection: localizedCollectionSlug,
|
||||
locale: '*',
|
||||
where: {
|
||||
id: { equals: id },
|
||||
},
|
||||
})
|
||||
|
||||
const publishedDoc = data.docs[0]
|
||||
|
||||
expect(publishedDoc.text).toStrictEqual({
|
||||
en: 'english published',
|
||||
es: 'spanish published',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Globals - publish individual locale', () => {
|
||||
beforeAll(() => {
|
||||
url = new AdminUrlUtil(serverURL, localizedGlobalSlug)
|
||||
})
|
||||
|
||||
test('should show publish individual locale dropdown', async () => {
|
||||
await page.goto(url.global(localizedGlobalSlug))
|
||||
const publishOptions = page.locator('.doc-controls__controls .popup')
|
||||
|
||||
await expect(publishOptions).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show option to publish current locale', async () => {
|
||||
await page.goto(url.global(localizedGlobalSlug))
|
||||
const publishOptions = page.locator('.doc-controls__controls .popup')
|
||||
await publishOptions.click()
|
||||
|
||||
const publishSpecificLocale = page.locator('.doc-controls__controls .popup__content')
|
||||
|
||||
await expect(publishSpecificLocale).toContainText('English')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
24
test/versions/globals/LocalizedGlobal.ts
Normal file
24
test/versions/globals/LocalizedGlobal.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { GlobalConfig } from 'payload'
|
||||
|
||||
import { localizedGlobalSlug } from '../slugs.js'
|
||||
|
||||
const LocalizedGlobal: GlobalConfig = {
|
||||
slug: localizedGlobalSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
versions: {
|
||||
drafts: true,
|
||||
},
|
||||
}
|
||||
|
||||
export default LocalizedGlobal
|
||||
@@ -12,7 +12,12 @@ import { initPayloadInt } from '../helpers/initPayloadInt.js'
|
||||
import { clearAndSeedEverything } from './clearAndSeedEverything.js'
|
||||
import AutosavePosts from './collections/Autosave.js'
|
||||
import AutosaveGlobal from './globals/Autosave.js'
|
||||
import { autosaveCollectionSlug, draftCollectionSlug } from './slugs.js'
|
||||
import {
|
||||
autosaveCollectionSlug,
|
||||
draftCollectionSlug,
|
||||
localizedCollectionSlug,
|
||||
localizedGlobalSlug,
|
||||
} from './slugs.js'
|
||||
|
||||
let payload: Payload
|
||||
let restClient: NextRESTClient
|
||||
@@ -1563,4 +1568,565 @@ describe('Versions', () => {
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Publish Individual Locale', () => {
|
||||
const collection = localizedCollectionSlug
|
||||
const global = localizedGlobalSlug
|
||||
|
||||
describe('Collections', () => {
|
||||
let postID: string
|
||||
|
||||
beforeEach(async () => {
|
||||
await payload.delete({
|
||||
collection,
|
||||
where: {},
|
||||
})
|
||||
})
|
||||
|
||||
it('should save correct doc data when publishing individual locale', async () => {
|
||||
// save spanish draft
|
||||
const draft1 = await payload.create({
|
||||
collection,
|
||||
data: {
|
||||
text: 'Spanish draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
postID = draft1.id as any
|
||||
|
||||
// save english draft
|
||||
const draft2 = await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English draft',
|
||||
description: 'My English description',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'en',
|
||||
})
|
||||
|
||||
// save german draft
|
||||
const draft3 = await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
text: 'German draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'de',
|
||||
})
|
||||
|
||||
// publish only english
|
||||
const publishedEN1 = await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English published 1',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
locale: 'en',
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const docWithoutSpanishDraft = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
// We're getting the published version,
|
||||
// which should not leak any unpublished Spanish content
|
||||
// and should retain the English fields that were not explicitly
|
||||
// passed in from publishedEN1
|
||||
expect(docWithoutSpanishDraft.text.es).toBeUndefined()
|
||||
expect(docWithoutSpanishDraft.description.en).toStrictEqual('My English description')
|
||||
|
||||
const docWithSpanishDraft1 = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
draft: true,
|
||||
})
|
||||
|
||||
// After updating English via specific locale,
|
||||
// We should expect to see that Spanish translations were maintained
|
||||
expect(docWithSpanishDraft1.text.es).toStrictEqual('Spanish draft')
|
||||
expect(docWithSpanishDraft1.text.en).toStrictEqual('English published 1')
|
||||
expect(docWithSpanishDraft1.description.en).toStrictEqual('My English description')
|
||||
|
||||
const publishedEN2 = await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English published 2',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
locale: 'en',
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const docWithoutSpanishDraft2 = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
// On the second consecutive publish of a specific locale,
|
||||
// Make sure we maintain draft data that has never been published
|
||||
// even after two + consecutive publish events
|
||||
expect(docWithoutSpanishDraft2.text.es).toBeUndefined()
|
||||
expect(docWithoutSpanishDraft2.text.en).toStrictEqual('English published 2')
|
||||
expect(docWithoutSpanishDraft2.description.en).toStrictEqual('My English description')
|
||||
|
||||
await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
text: 'German draft 1',
|
||||
_status: 'draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'de',
|
||||
})
|
||||
|
||||
const docWithGermanDraft = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
draft: true,
|
||||
})
|
||||
|
||||
// Make sure we retain the Spanish draft,
|
||||
// which may be lost when we create a new draft with German.
|
||||
// Update operation should fetch both draft locales as well as published
|
||||
// and merge them.
|
||||
expect(docWithGermanDraft.text.de).toStrictEqual('German draft 1')
|
||||
expect(docWithGermanDraft.text.es).toStrictEqual('Spanish draft')
|
||||
expect(docWithGermanDraft.text.en).toStrictEqual('English published 2')
|
||||
|
||||
const publishedDE = await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
_status: 'published',
|
||||
text: 'German published 1',
|
||||
},
|
||||
draft: false,
|
||||
locale: 'de',
|
||||
publishSpecificLocale: 'de',
|
||||
})
|
||||
|
||||
const publishedENFinal = await payload.update({
|
||||
id: postID,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English published 3',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
locale: 'en',
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const finalPublishedNoES = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(finalPublishedNoES.text.de).toStrictEqual('German published 1')
|
||||
expect(finalPublishedNoES.text.en).toStrictEqual('English published 3')
|
||||
expect(finalPublishedNoES.text.es).toBeUndefined()
|
||||
|
||||
const finalDraft = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
draft: true,
|
||||
})
|
||||
|
||||
expect(finalDraft.text.de).toStrictEqual('German published 1')
|
||||
expect(finalDraft.text.en).toStrictEqual('English published 3')
|
||||
expect(finalDraft.text.es).toStrictEqual('Spanish draft')
|
||||
|
||||
const published = await payload.update({
|
||||
collection,
|
||||
id: postID,
|
||||
data: {
|
||||
_status: 'published',
|
||||
},
|
||||
})
|
||||
|
||||
const finalPublished = await payload.findByID({
|
||||
collection,
|
||||
id: postID,
|
||||
locale: 'all',
|
||||
draft: true,
|
||||
})
|
||||
|
||||
expect(finalPublished.text.de).toStrictEqual('German published 1')
|
||||
expect(finalPublished.text.en).toStrictEqual('English published 3')
|
||||
expect(finalPublished.text.es).toStrictEqual('Spanish draft')
|
||||
})
|
||||
|
||||
it('should not leak draft data', async () => {
|
||||
const draft = await payload.create({
|
||||
collection,
|
||||
data: {
|
||||
text: 'Spanish draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
const published = await payload.update({
|
||||
id: draft.id,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English publish',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const publishedOnlyEN = await payload.findByID({
|
||||
collection,
|
||||
id: draft.id,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedOnlyEN.text.es).toBeUndefined()
|
||||
expect(publishedOnlyEN.text.en).toStrictEqual('English publish')
|
||||
})
|
||||
|
||||
it('should merge draft data from other locales when publishing all', async () => {
|
||||
const draft = await payload.create({
|
||||
collection,
|
||||
data: {
|
||||
text: 'Spanish draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
const published = await payload.update({
|
||||
id: draft.id,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English publish',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const publishedOnlyEN = await payload.findByID({
|
||||
collection,
|
||||
id: draft.id,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedOnlyEN.text.es).toBeUndefined()
|
||||
expect(publishedOnlyEN.text.en).toStrictEqual('English publish')
|
||||
|
||||
const published2 = await payload.update({
|
||||
id: draft.id,
|
||||
collection,
|
||||
data: {
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
})
|
||||
|
||||
const publishedAll = await payload.findByID({
|
||||
collection,
|
||||
id: published2.id,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedAll.text.es).toStrictEqual('Spanish draft')
|
||||
expect(publishedAll.text.en).toStrictEqual('English publish')
|
||||
})
|
||||
|
||||
it('should publish non-default individual locale', async () => {
|
||||
const draft = await payload.create({
|
||||
collection,
|
||||
data: {
|
||||
text: 'Spanish draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
const published = await payload.update({
|
||||
id: draft.id,
|
||||
collection,
|
||||
data: {
|
||||
text: 'German publish',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
publishSpecificLocale: 'de',
|
||||
})
|
||||
|
||||
const publishedOnlyDE = await payload.findByID({
|
||||
collection,
|
||||
id: published.id,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedOnlyDE.text.es).toBeUndefined()
|
||||
expect(publishedOnlyDE.text.en).toBeUndefined()
|
||||
expect(publishedOnlyDE.text.de).toStrictEqual('German publish')
|
||||
})
|
||||
|
||||
it('should show correct data in latest version', async () => {
|
||||
const draft = await payload.create({
|
||||
collection,
|
||||
data: {
|
||||
text: 'Spanish draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
const published = await payload.update({
|
||||
id: draft.id,
|
||||
collection,
|
||||
data: {
|
||||
text: 'English publish',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const publishedOnlyEN = await payload.findByID({
|
||||
collection,
|
||||
id: published.id,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedOnlyEN.text.es).toBeUndefined()
|
||||
expect(publishedOnlyEN.text.en).toStrictEqual('English publish')
|
||||
|
||||
const allVersions = await payload.findVersions({
|
||||
collection,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
const versions = allVersions.docs.filter(
|
||||
(version) => version.parent === published.id && version.snapshot !== true,
|
||||
)
|
||||
const latestVersion = versions[0].version
|
||||
|
||||
expect(latestVersion.text.es).toBeUndefined()
|
||||
expect(latestVersion.text.en).toStrictEqual('English publish')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Globals', () => {
|
||||
it('should save correct global data when publishing individual locale', async () => {
|
||||
// publish german
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'German published',
|
||||
_status: 'published',
|
||||
},
|
||||
locale: 'de',
|
||||
})
|
||||
|
||||
// save spanish draft
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Spanish draft',
|
||||
content: 'Spanish draft content',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
// publish only english
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Eng published',
|
||||
_status: 'published',
|
||||
},
|
||||
locale: 'en',
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const globalData = await payload.findGlobal({
|
||||
slug: global,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
// Expect only previously published data to be present
|
||||
expect(globalData.title.es).toBeUndefined()
|
||||
expect(globalData.title.en).toStrictEqual('Eng published')
|
||||
expect(globalData.title.de).toStrictEqual('German published')
|
||||
})
|
||||
|
||||
it('should not leak draft data', async () => {
|
||||
// save spanish draft
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Another spanish draft',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
// publish only english
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Eng published',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
locale: 'en',
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const globalData = await payload.findGlobal({
|
||||
slug: global,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
// Expect no draft data to be present
|
||||
expect(globalData.title.es).toBeUndefined()
|
||||
expect(globalData.title.en).toStrictEqual('Eng published')
|
||||
})
|
||||
|
||||
it('should merge draft data from other locales when publishing all', async () => {
|
||||
// save spanish draft
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Spanish draft',
|
||||
content: 'Spanish draft content',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
// publish only english
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Eng published',
|
||||
_status: 'published',
|
||||
},
|
||||
locale: 'en',
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const publishedOnlyEN = await payload.findGlobal({
|
||||
slug: global,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedOnlyEN.title.es).toBeUndefined()
|
||||
expect(publishedOnlyEN.title.en).toStrictEqual('Eng published')
|
||||
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
_status: 'published',
|
||||
},
|
||||
})
|
||||
|
||||
const publishedAll = await payload.findGlobal({
|
||||
slug: global,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
expect(publishedAll.title.es).toStrictEqual('Spanish draft')
|
||||
expect(publishedAll.title.en).toStrictEqual('Eng published')
|
||||
})
|
||||
|
||||
it('should publish non-default individual locale', async () => {
|
||||
// save spanish draft
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'Test span draft',
|
||||
content: 'Test span draft content',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
// publish only german
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'German published',
|
||||
_status: 'published',
|
||||
},
|
||||
locale: 'de',
|
||||
publishSpecificLocale: 'de',
|
||||
})
|
||||
|
||||
const globalData = await payload.findGlobal({
|
||||
slug: global,
|
||||
locale: 'all',
|
||||
})
|
||||
|
||||
// Expect only published data to be present
|
||||
expect(globalData.title.es).toBeFalsy()
|
||||
expect(globalData.title.de).toStrictEqual('German published')
|
||||
})
|
||||
|
||||
it('should show correct data in latest version', async () => {
|
||||
// save spanish draft
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'New spanish draft',
|
||||
content: 'New spanish draft content',
|
||||
},
|
||||
draft: true,
|
||||
locale: 'es',
|
||||
})
|
||||
|
||||
// publish only english
|
||||
await payload.updateGlobal({
|
||||
slug: global,
|
||||
data: {
|
||||
title: 'New eng',
|
||||
_status: 'published',
|
||||
},
|
||||
draft: false,
|
||||
publishSpecificLocale: 'en',
|
||||
})
|
||||
|
||||
const allVersions = await payload.findGlobalVersions({
|
||||
slug: global,
|
||||
locale: 'all',
|
||||
where: {
|
||||
'version._status': {
|
||||
equals: 'published',
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const versions = allVersions.docs
|
||||
const latestVersion = versions[0].version
|
||||
expect(latestVersion.title.es).toBeFalsy()
|
||||
expect(latestVersion.title.en).toStrictEqual('New eng')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface Config {
|
||||
'autosave-posts': AutosavePost;
|
||||
'draft-posts': DraftPost;
|
||||
'draft-with-max-posts': DraftWithMaxPost;
|
||||
'localized-posts': LocalizedPost;
|
||||
'version-posts': VersionPost;
|
||||
'custom-ids': CustomId;
|
||||
users: User;
|
||||
@@ -30,8 +31,9 @@ export interface Config {
|
||||
'draft-global': DraftGlobal;
|
||||
'draft-with-max-global': DraftWithMaxGlobal;
|
||||
'disable-publish-global': DisablePublishGlobal;
|
||||
'localized-global': LocalizedGlobal;
|
||||
};
|
||||
locale: 'en' | 'es';
|
||||
locale: 'en' | 'es' | 'de';
|
||||
user: User & {
|
||||
collection: 'users';
|
||||
};
|
||||
@@ -148,6 +150,22 @@ export interface DraftWithMaxPost {
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localized-posts".
|
||||
*/
|
||||
type LocalizedString = {
|
||||
[k: string]: string;
|
||||
};
|
||||
|
||||
export interface LocalizedPost {
|
||||
id: string;
|
||||
text?: string | LocalizedString | null;
|
||||
description?: string | LocalizedString | null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "custom-ids".
|
||||
@@ -253,6 +271,18 @@ export interface DisablePublishGlobal {
|
||||
updatedAt?: string | null;
|
||||
createdAt?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "localized-global".
|
||||
*/
|
||||
export interface LocalizedGlobal {
|
||||
id: string;
|
||||
title?: string | null;
|
||||
content?: string | null;
|
||||
_status?: ('draft' | 'published') | null;
|
||||
updatedAt?: string | null;
|
||||
createdAt?: string | null;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "auth".
|
||||
@@ -263,6 +293,6 @@ export interface Auth {
|
||||
|
||||
|
||||
declare module 'payload' {
|
||||
// @ts-ignore
|
||||
// @ts-ignore
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,3 +25,7 @@ export const draftGlobalSlug = 'draft-global'
|
||||
export const draftWithMaxGlobalSlug = 'draft-with-max-global'
|
||||
|
||||
export const globalSlugs = [autoSaveGlobalSlug, draftGlobalSlug]
|
||||
|
||||
export const localizedCollectionSlug = 'localized-posts'
|
||||
|
||||
export const localizedGlobalSlug = 'localized-global'
|
||||
|
||||
Reference in New Issue
Block a user