Skip to content

Commit d267cad

Browse files
authored
fix: beforeDuplicate localized blocks and arrays (#8144)
fixes #7988
1 parent fa38dfc commit d267cad

File tree

4 files changed

+93
-3
lines changed

4 files changed

+93
-3
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import ObjectIdImport from 'bson-objectid'
2+
3+
import type { FieldHook } from '../config/types.js'
4+
5+
const ObjectId = (ObjectIdImport.default ||
6+
ObjectIdImport) as unknown as typeof ObjectIdImport.default
7+
/**
8+
* Arrays and Blocks need to clear ids beforeDuplicate
9+
*/
10+
export const baseBeforeDuplicateArrays: FieldHook = ({ value }) => {
11+
if (value) {
12+
value = value.map((item) => {
13+
item.id = new ObjectId().toHexString()
14+
return item
15+
})
16+
return value
17+
}
18+
}

packages/payload/src/fields/config/sanitize.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from '../../errors/index.js'
1313
import { MissingEditorProp } from '../../errors/MissingEditorProp.js'
1414
import { formatLabels, toWords } from '../../utilities/formatLabels.js'
15+
import { baseBeforeDuplicateArrays } from '../baseFields/baseBeforeDuplicateArrays.js'
1516
import { baseBlockFields } from '../baseFields/baseBlockFields.js'
1617
import { baseIDField } from '../baseFields/baseIDField.js'
1718
import { setDefaultBeforeDuplicate } from '../setDefaultBeforeDuplicate.js'
@@ -130,6 +131,15 @@ export const sanitizeFields = async ({
130131

131132
if (field.type === 'array' && field.fields) {
132133
field.fields.push(baseIDField)
134+
if (field.localized) {
135+
if (!field.hooks) {
136+
field.hooks = {}
137+
}
138+
if (!field.hooks.beforeDuplicate) {
139+
field.hooks.beforeDuplicate = []
140+
}
141+
field.hooks.beforeDuplicate.push(baseBeforeDuplicateArrays)
142+
}
133143
}
134144

135145
if ((field.type === 'blocks' || field.type === 'array') && field.label) {
@@ -210,6 +220,15 @@ export const sanitizeFields = async ({
210220
}
211221

212222
if (field.type === 'blocks' && field.blocks) {
223+
if (field.localized) {
224+
if (!field.hooks) {
225+
field.hooks = {}
226+
}
227+
if (!field.hooks.beforeDuplicate) {
228+
field.hooks.beforeDuplicate = []
229+
}
230+
field.hooks.beforeDuplicate.push(baseBeforeDuplicateArrays)
231+
}
213232
for (const block of field.blocks) {
214233
if (block._sanitized === true) {
215234
continue

test/localization/config.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ import {
2424
portugueseLocale,
2525
relationEnglishTitle,
2626
relationEnglishTitle2,
27+
relationshipLocalizedSlug,
2728
relationSpanishTitle,
2829
relationSpanishTitle2,
29-
relationshipLocalizedSlug,
3030
spanishLocale,
3131
spanishTitle,
3232
withLocalizedRelSlug,
@@ -348,7 +348,9 @@ export default buildConfigWithDefaults({
348348
if (payload.db.name === 'mongoose') {
349349
await new Promise((resolve, reject) => {
350350
payload.db?.collections[localizedPostsSlug]?.ensureIndexes(function (err) {
351-
if (err) reject(err)
351+
if (err) {
352+
reject(err)
353+
}
352354
resolve(true)
353355
})
354356
})

test/localization/int.spec.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import {
2222
portugueseLocale,
2323
relationEnglishTitle,
2424
relationEnglishTitle2,
25+
relationshipLocalizedSlug,
2526
relationSpanishTitle,
2627
relationSpanishTitle2,
27-
relationshipLocalizedSlug,
2828
spanishLocale,
2929
spanishTitle,
3030
withLocalizedRelSlug,
@@ -1118,6 +1118,57 @@ describe('Localization', () => {
11181118
expect(allLocales.localizedCheckbox.en).toBeTruthy()
11191119
expect(allLocales.localizedCheckbox.es).toBeFalsy()
11201120
})
1121+
1122+
it('should duplicate with localized blocks', async () => {
1123+
const englishText = 'english'
1124+
const spanishText = 'spanish'
1125+
const doc = await payload.create({
1126+
collection: withRequiredLocalizedFields,
1127+
data: {
1128+
layout: [
1129+
{
1130+
blockType: 'text',
1131+
text: englishText,
1132+
},
1133+
],
1134+
title: 'hello',
1135+
},
1136+
locale: defaultLocale,
1137+
})
1138+
1139+
await payload.update({
1140+
id: doc.id,
1141+
collection: withRequiredLocalizedFields,
1142+
data: {
1143+
layout: [
1144+
{
1145+
blockType: 'text',
1146+
text: spanishText,
1147+
},
1148+
],
1149+
title: 'hello',
1150+
},
1151+
locale: spanishLocale,
1152+
})
1153+
1154+
const result = await payload.duplicate({
1155+
id: doc.id,
1156+
collection: withRequiredLocalizedFields,
1157+
locale: defaultLocale,
1158+
})
1159+
1160+
const allLocales = await payload.findByID({
1161+
id: result.id,
1162+
collection: withRequiredLocalizedFields,
1163+
locale: 'all',
1164+
})
1165+
1166+
// check fields
1167+
expect(result.layout[0].text).toStrictEqual(englishText)
1168+
1169+
expect(allLocales.layout.en[0].text).toStrictEqual(englishText)
1170+
expect(allLocales.layout.es[0].text).toStrictEqual(spanishText)
1171+
})
11211172
})
11221173

11231174
describe('Localized group and tabs', () => {

0 commit comments

Comments
 (0)