fix(ui): copyToLocale should not pass any id's to avoid duplicates (#11887)
### What?
Using the `Copy To Locale` function causes validation errors on content
with `id` fields in postgres, since these should be unique.
```
key not found: error:valueMustBeUnique
key not found: error:followingFieldsInvalid
[13:11:29] ERROR: There was an error copying data from "en" to "de"
err: {
"type": "ValidationError",
"message": "error:followingFieldsInvalid id",
"stack":
ValidationError: error:followingFieldsInvalid id
```
### Why?
In `packages/ui/src/utilities/copyDataFromLocale.ts` we are passing all
data from `fromLocaleData` including the `id` fields, which causes
duplicates on fields with unique id's like `Blocks` and `Arrays`.
### How?
To resolve this i implemented a function that recursively remove any
`id` field on the passed data.
### Fixes
- https://github.com/payloadcms/payload/issues/10684
- https://discord.com/channels/967097582721572934/1351497930984521800
---------
Co-authored-by: Jessica Chowdhury <jessica@trbl.design>
This commit is contained in:
@@ -183,6 +183,17 @@ function mergeData(
|
||||
return toLocaleData
|
||||
}
|
||||
|
||||
function removeIds(data: Data): Data {
|
||||
if (Array.isArray(data)) {
|
||||
return data.map(removeIds)
|
||||
}
|
||||
if (typeof data === 'object' && data !== null) {
|
||||
const { id: _id, ...rest } = data
|
||||
return Object.fromEntries(Object.entries(rest).map(([key, value]) => [key, removeIds(value)]))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
export const copyDataFromLocaleHandler = async (args: CopyDataFromLocaleArgs) => {
|
||||
const { req } = args
|
||||
|
||||
@@ -288,7 +299,8 @@ export const copyDataFromLocale = async (args: CopyDataFromLocaleArgs) => {
|
||||
throw new Error(`Error fetching data from locale "${toLocale}"`)
|
||||
}
|
||||
|
||||
const { id, ...fromLocaleDataWithoutID } = fromLocaleData.value
|
||||
const fromLocaleDataWithoutID = removeIds(fromLocaleData.value)
|
||||
const toLocaleDataWithoutID = removeIds(toLocaleData.value)
|
||||
|
||||
return globalSlug
|
||||
? await payload.updateGlobal({
|
||||
@@ -296,8 +308,8 @@ export const copyDataFromLocale = async (args: CopyDataFromLocaleArgs) => {
|
||||
data: overrideData
|
||||
? fromLocaleDataWithoutID
|
||||
: mergeData(
|
||||
fromLocaleData.value,
|
||||
toLocaleData.value,
|
||||
fromLocaleDataWithoutID,
|
||||
toLocaleDataWithoutID,
|
||||
globals[globalSlug].config.fields,
|
||||
req,
|
||||
false,
|
||||
@@ -313,8 +325,8 @@ export const copyDataFromLocale = async (args: CopyDataFromLocaleArgs) => {
|
||||
data: overrideData
|
||||
? fromLocaleDataWithoutID
|
||||
: mergeData(
|
||||
fromLocaleData.value,
|
||||
toLocaleData.value,
|
||||
fromLocaleDataWithoutID,
|
||||
toLocaleDataWithoutID,
|
||||
collections[collectionSlug].config.fields,
|
||||
req,
|
||||
false,
|
||||
|
||||
Reference in New Issue
Block a user