fix: preserve source locale data when copying locale from localized subfields with a non-localized parent field(array, block)
What?
When copying locale data, only the toLocaleData(target locale) got the value from the copyFrom locale data, while all other locales besides target locale were lost. It happens for array/block fields that were not localized themselves but contained localized subfields. Details in issue #12536
Why?
I found copyDataFromLocale function correctly merges the data. After digging into this, the issue appears at the saving stage. When saving, the beforeChange hook invokes mergeLocaleActions part within packages/payload/src/fields/hooks/beforeChange/promise.ts, which That the siblingDocWithLocales parameter didn't include the complete locale data. When mergeLocaleActions tries to preserve existing locale values from siblingDocWithLocales, it can't find the source locale data and sets it to undefined, effectively deleting it. (The root issue causes this still need to investigate)
How?
My solution is to fetch complete locale data (locale: 'all') in the copyDataFromLocale and passing it through request context to the beforeChange hooks, and reconstructed an enhancedSiblingDocWithLocales to ensure all locale values are preserved during the merge process.
The fix ensures that when copying locale data, the system has access to the complete picture of all locale values, not just the target locale, preventing accidental data loss.
The changes are targeted only to Copy Locale Operation and the beforeChange hook, and it only affect when the new added context exists, so it won't make affect to other operations.
Current int tests check if the toLocaleData value received from fromLocaleData, however it overlooked the case that source locale data is lost. So I added int test to check if the non-target locale stay the same.
I believe there’s a better way to fix this, but for now this is the best solution I can think of.
Update: On the surface, the issue still comes down to siblingDocWithLocales not including the complete locale data. I thought the missing data was during the process of updateByIDOperation, however after I revisited my entire thought process, I'm not convinced I’ve pinpointed the true root cause yet. The PR I submitted is essentially a workaround that I force-passed an extra context and reconstructed an enhancedSiblingDocWithLocales. It feels a bit hacky, and I’m not confident it fully addresses the underlying problem.
Let's see if Payload team can take another look and help us get to the core of why the locale data isn’t being carried through correctly.
Fixes #12536
hope this pull request will be reviewed and merged soon :)
On the surface, the issue still comes down to siblingDocWithLocales not including the complete locale data. I thought the missing data was during the process of updateByIDOperation, however after I revisited my entire thought process, I'm not convinced I’ve pinpointed the true root cause yet. The PR I submitted is essentially a workaround that I force-passed an extra context and reconstructed an enhancedSiblingDocWithLocales. It feels a bit hacky, and I’m not confident it fully addresses the underlying problem.
Let's see if Payload team can take another look and help us get to the core of why the locale data isn’t being carried through correctly.
Any update or workaround for that? We need a reliable copy to locale button, otherwise i would like to deactivate it..
We very need this fix, because we a planning to go to production soon, and it's blocking us to manage/prepare the multilanguage data.
Same!
Since this issue is closed now. Is this no longer a problem?