Skip to content

Commit ec5b673

Browse files
authored
fix: copy to locale with localized fields inside tabs (#13456)
Fixes #13374
1 parent 3dd142c commit ec5b673

File tree

4 files changed

+98
-13
lines changed

4 files changed

+98
-13
lines changed

packages/payload/src/utilities/traverseFields.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -416,27 +416,38 @@ export const traverseFields = ({
416416
})
417417
) {
418418
if (Array.isArray(currentRef)) {
419-
return
420-
}
421-
422-
for (const key in currentRef as Record<string, unknown>) {
423-
const localeData = currentRef[key as keyof typeof currentRef]
424-
if (!Array.isArray(localeData)) {
425-
continue
426-
}
427-
428419
traverseArrayOrBlocksField({
429420
callback,
430421
callbackStack,
431422
config,
432-
data: localeData,
423+
data: currentRef,
433424
field,
434425
fillEmpty,
435426
leavesFirst,
436427
parentIsLocalized: true,
437428
parentPath,
438429
parentRef: currentParentRef,
439430
})
431+
} else {
432+
for (const key in currentRef as Record<string, unknown>) {
433+
const localeData = currentRef[key as keyof typeof currentRef]
434+
if (!Array.isArray(localeData)) {
435+
continue
436+
}
437+
438+
traverseArrayOrBlocksField({
439+
callback,
440+
callbackStack,
441+
config,
442+
data: localeData,
443+
field,
444+
fillEmpty,
445+
leavesFirst,
446+
parentIsLocalized: true,
447+
parentPath,
448+
parentRef: currentParentRef,
449+
})
450+
}
440451
}
441452
} else if (Array.isArray(currentRef)) {
442453
traverseArrayOrBlocksField({

test/localization/collections/Blocks/index.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,30 @@ export const blocksCollectionSlug = 'blocks-fields'
44

55
export const BlocksCollection: CollectionConfig = {
66
slug: blocksCollectionSlug,
7+
versions: { drafts: true },
78
fields: [
9+
{
10+
type: 'tabs',
11+
tabs: [
12+
{
13+
label: 'Tab',
14+
fields: [
15+
{
16+
name: 'tabContent',
17+
label: 'Content',
18+
type: 'blocks',
19+
localized: true,
20+
blocks: [
21+
{
22+
slug: 'blockInsideTab',
23+
fields: [{ type: 'text', name: 'text' }],
24+
},
25+
],
26+
},
27+
],
28+
},
29+
],
30+
},
831
{
932
name: 'content',
1033
label: 'Content',

test/localization/int.spec.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2903,7 +2903,7 @@ describe('Localization', () => {
29032903
})
29042904

29052905
const req = await createLocalReq({ user }, payload)
2906-
2906+
global.d = true
29072907
const res = (await copyDataFromLocaleHandler({
29082908
fromLocale: 'en',
29092909
req,
@@ -2915,6 +2915,36 @@ describe('Localization', () => {
29152915
expect(res.content?.[0]?.content?.[0]?.text).toBe('some-text')
29162916
})
29172917

2918+
it('should copy block inside tab to locale', async () => {
2919+
// This was previously an e2e test but it was migrated to int
2920+
// because at the moment only int tests run in Postgres in CI,
2921+
// and that's where the bug occurs.
2922+
const doc = await payload.create({
2923+
collection: 'blocks-fields',
2924+
locale: 'en',
2925+
data: {
2926+
tabContent: [
2927+
{
2928+
blockType: 'blockInsideTab',
2929+
text: 'some-text',
2930+
},
2931+
],
2932+
},
2933+
})
2934+
2935+
const req = await createLocalReq({ user }, payload)
2936+
global.d = true
2937+
const res = (await copyDataFromLocaleHandler({
2938+
fromLocale: 'en',
2939+
req,
2940+
toLocale: 'pt',
2941+
docID: doc.id,
2942+
collectionSlug: 'blocks-fields',
2943+
})) as BlocksField
2944+
2945+
expect(res.tabContent?.[0]?.text).toBe('some-text')
2946+
})
2947+
29182948
it('should copy localized nested to arrays', async () => {
29192949
const doc = await payload.create({
29202950
collection: 'nested',

test/localization/payload-types.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ export interface RichText {
192192
*/
193193
export interface BlocksField {
194194
id: string;
195+
tabContent?:
196+
| {
197+
text?: string | null;
198+
id?: string | null;
199+
blockName?: string | null;
200+
blockType: 'blockInsideTab';
201+
}[]
202+
| null;
195203
content?:
196204
| {
197205
content?:
@@ -217,6 +225,7 @@ export interface BlocksField {
217225
| null;
218226
updatedAt: string;
219227
createdAt: string;
228+
_status?: ('draft' | 'published') | null;
220229
}
221230
/**
222231
* This interface was referenced by `Config`'s JSON-Schema
@@ -877,6 +886,17 @@ export interface RichTextSelect<T extends boolean = true> {
877886
* via the `definition` "blocks-fields_select".
878887
*/
879888
export interface BlocksFieldsSelect<T extends boolean = true> {
889+
tabContent?:
890+
| T
891+
| {
892+
blockInsideTab?:
893+
| T
894+
| {
895+
text?: T;
896+
id?: T;
897+
blockName?: T;
898+
};
899+
};
880900
content?:
881901
| T
882902
| {
@@ -910,6 +930,7 @@ export interface BlocksFieldsSelect<T extends boolean = true> {
910930
};
911931
updatedAt?: T;
912932
createdAt?: T;
933+
_status?: T;
913934
}
914935
/**
915936
* This interface was referenced by `Config`'s JSON-Schema
@@ -1499,6 +1520,6 @@ export interface Auth {
14991520

15001521

15011522
declare module 'payload' {
1502-
// @ts-ignore
1523+
// @ts-ignore
15031524
export interface GeneratedTypes extends Config {}
1504-
}
1525+
}

0 commit comments

Comments
 (0)