fix(db-mongodb): localized blocks with fallback and versions (#13974)

Fixes https://github.com/payloadcms/payload/issues/13663
The issue appears to be reproducible only with 3 or more locales
This commit is contained in:
Sasha
2025-10-02 04:43:28 +03:00
committed by GitHub
parent 4b193dae53
commit 1e654c0a95
4 changed files with 53 additions and 2 deletions

View File

@@ -4,7 +4,7 @@ export const blocksCollectionSlug = 'blocks-fields'
export const BlocksCollection: CollectionConfig = {
slug: blocksCollectionSlug,
versions: { drafts: true },
versions: { drafts: { autosave: true } },
fields: [
{
type: 'tabs',
@@ -37,6 +37,10 @@ export const BlocksCollection: CollectionConfig = {
{
slug: 'blockInsideBlock',
fields: [
{
name: 'text',
type: 'text',
},
{
name: 'content',
type: 'blocks',

View File

@@ -3,10 +3,12 @@ import type { GeneratedTypes } from 'helpers/sdk/types.js'
import { expect, test } from '@playwright/test'
import { addArrayRow } from 'helpers/e2e/fields/array/index.js'
import { addBlock } from 'helpers/e2e/fields/blocks/addBlock.js'
import { navigateToDoc } from 'helpers/e2e/navigateToDoc.js'
import { openDocControls } from 'helpers/e2e/openDocControls.js'
import { upsertPreferences } from 'helpers/e2e/preferences.js'
import { openDocDrawer } from 'helpers/e2e/toggleDocDrawer.js'
import { waitForAutoSaveToRunAndComplete } from 'helpers/e2e/waitForAutoSaveToRunAndComplete.js'
import { RESTClient } from 'helpers/rest.js'
import path from 'path'
import { fileURLToPath } from 'url'
@@ -28,6 +30,7 @@ import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
import { arrayCollectionSlug } from './collections/Array/index.js'
import { blocksCollectionSlug } from './collections/Blocks/index.js'
import { nestedToArrayAndBlockCollectionSlug } from './collections/NestedToArrayAndBlock/index.js'
import { noLocalizedFieldsCollectionSlug } from './collections/NoLocalizedFields/index.js'
import { richTextSlug } from './collections/RichText/index.js'
@@ -63,6 +66,7 @@ let urlPostsWithDrafts: AdminUrlUtil
let urlArray: AdminUrlUtil
let arrayWithFallbackURL: AdminUrlUtil
let noLocalizedFieldsURL: AdminUrlUtil
let urlBlocks: AdminUrlUtil
const title = 'english title'
const spanishTitle = 'spanish title'
@@ -90,6 +94,7 @@ describe('Localization', () => {
urlArray = new AdminUrlUtil(serverURL, arrayCollectionSlug)
arrayWithFallbackURL = new AdminUrlUtil(serverURL, arrayWithFallbackCollectionSlug)
noLocalizedFieldsURL = new AdminUrlUtil(serverURL, noLocalizedFieldsCollectionSlug)
urlBlocks = new AdminUrlUtil(serverURL, blocksCollectionSlug)
context = await browser.newContext()
page = await context.newPage()
@@ -651,6 +656,41 @@ describe('Localization', () => {
})
.toBeTruthy()
})
test('blocks - should show fallback checkbox for non-default locale', async () => {
await page.goto(urlBlocks.create)
await addBlock({ page, blockToSelect: 'Block Inside Block', fieldName: 'content' })
const rowTextInput = page.locator(`#field-content__0__text`)
await rowTextInput.fill('text')
await saveDocAndAssert(page)
await changeLocale(page, 'pt')
const fallbackCheckbox = page.locator('#field-content', {
hasText: 'Fallback to default locale',
})
await expect(fallbackCheckbox).toBeVisible()
})
test('blocks - should successfully save with the fallback', async () => {
await page.goto(urlBlocks.create)
await addBlock({ page, blockToSelect: 'Block Inside Block', fieldName: 'content' })
const rowTextInput = page.locator(`#field-content__0__text`)
await rowTextInput.fill('text')
await saveDocAndAssert(page)
await changeLocale(page, 'pt')
await rowTextInput.fill('changed')
await waitForAutoSaveToRunAndComplete(page)
await saveDocAndAssert(page)
const docID = page.url().split('/').pop()?.split('?').shift()
const doc = await payload.find({
collection: 'blocks-fields',
where: { id: { equals: docID } },
locale: 'all',
})
// eslint-disable-next-line payload/no-flaky-assertions
expect(doc.docs).toHaveLength(1)
})
})
test('should use label in search filter when string or object', async () => {

View File

@@ -172,7 +172,7 @@ export interface RichText {
root: {
type: string;
children: {
type: string;
type: any;
version: number;
[k: string]: unknown;
}[];
@@ -202,6 +202,7 @@ export interface BlocksField {
| null;
content?:
| {
text?: string | null;
content?:
| {
text?: string | null;
@@ -390,6 +391,7 @@ export interface NoLocalizedField {
text?: string | null;
updatedAt: string;
createdAt: string;
_status?: ('draft' | 'published') | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
@@ -903,6 +905,7 @@ export interface BlocksFieldsSelect<T extends boolean = true> {
blockInsideBlock?:
| T
| {
text?: T;
content?:
| T
| {
@@ -1086,6 +1089,7 @@ export interface NoLocalizedFieldsSelect<T extends boolean = true> {
text?: T;
updatedAt?: T;
createdAt?: T;
_status?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema