Skip to content

Commit aee7d36

Browse files
authored
Merge pull request #1832 from payloadcms/fix/#1808
fix: #1808, arrays and blocks now save localized nested field data upon reordering rows
2 parents 78af86f + febbea5 commit aee7d36

File tree

7 files changed

+104
-7
lines changed

7 files changed

+104
-7
lines changed

src/fields/hooks/beforeChange/getExistingRowDoc.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@
55
* Otherwise, return an empty object.
66
*/
77

8-
export const getExistingRowDoc = (incomingRow: Record<string, unknown>, existingRow?: Record<string, unknown>): Record<string, unknown> => {
9-
if (incomingRow.id && incomingRow.id === existingRow?.id) {
10-
return existingRow;
8+
export const getExistingRowDoc = (incomingRow: Record<string, unknown>, existingRows?: unknown): Record<string, unknown> => {
9+
if (incomingRow.id && Array.isArray(existingRows)) {
10+
const matchedExistingRow = existingRows.find((existingRow) => {
11+
if (typeof existingRow === 'object' && 'id' in existingRow) {
12+
if (existingRow.id === incomingRow.id) return existingRow;
13+
}
14+
15+
return false;
16+
});
17+
18+
if (matchedExistingRow) return matchedExistingRow;
1119
}
1220

1321
return {};

src/fields/hooks/beforeChange/promise.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ export const promise = async ({
223223
path: `${path}${field.name}.${i}.`,
224224
req,
225225
siblingData: row,
226-
siblingDoc: getExistingRowDoc(row, siblingDoc[field.name]?.[i]),
227-
siblingDocWithLocales: getExistingRowDoc(row, siblingDocWithLocales[field.name]?.[i]),
226+
siblingDoc: getExistingRowDoc(row, siblingDoc[field.name]),
227+
siblingDocWithLocales: getExistingRowDoc(row, siblingDocWithLocales[field.name]),
228228
skipValidation: skipValidationFromHere,
229229
}));
230230
});
@@ -257,8 +257,8 @@ export const promise = async ({
257257
path: `${path}${field.name}.${i}.`,
258258
req,
259259
siblingData: row,
260-
siblingDoc: getExistingRowDoc(row, siblingDoc[field.name]?.[i]),
261-
siblingDocWithLocales: getExistingRowDoc(row, siblingDocWithLocales[field.name]?.[i]),
260+
siblingDoc: getExistingRowDoc(row, siblingDoc[field.name]),
261+
siblingDocWithLocales: getExistingRowDoc(row, siblingDocWithLocales[field.name]),
262262
skipValidation: skipValidationFromHere,
263263
}));
264264
}

test/fields/payload-types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,17 @@ export interface GroupField {
282282
potentiallyEmptyGroup: {
283283
text?: string;
284284
};
285+
groupInRow: {
286+
field?: string;
287+
secondField?: string;
288+
thirdField?: string;
289+
};
290+
secondGroupInRow: {
291+
field?: string;
292+
nestedGroup: {
293+
nestedField?: string;
294+
};
295+
};
285296
createdAt: string;
286297
updatedAt: string;
287298
}

test/localization/config.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { buildConfig } from '../buildConfig';
22
import { devUser } from '../credentials';
3+
import { GlobalArray } from './Array';
34
import { LocalizedPost, RelationshipLocalized } from './payload-types';
45
import {
56
defaultLocale,
@@ -175,6 +176,24 @@ export default buildConfig({
175176
],
176177
},
177178
],
179+
globals: [
180+
{
181+
slug: 'global-array',
182+
fields: [
183+
{
184+
name: 'array',
185+
type: 'array',
186+
fields: [
187+
{
188+
name: 'text',
189+
type: 'text',
190+
localized: true,
191+
},
192+
],
193+
},
194+
],
195+
},
196+
],
178197
onInit: async (payload) => {
179198
const collection = slug;
180199

@@ -266,5 +285,30 @@ export default buildConfig({
266285
],
267286
},
268287
});
288+
289+
const globalArray = await payload.updateGlobal({
290+
slug: 'global-array',
291+
data: {
292+
array: [
293+
{
294+
text: 'test en 1',
295+
},
296+
{
297+
text: 'test en 2',
298+
},
299+
],
300+
},
301+
});
302+
303+
await payload.updateGlobal({
304+
slug: 'global-array',
305+
locale: 'es',
306+
data: {
307+
array: globalArray.array.map((row, i) => ({
308+
...row,
309+
text: `test es ${i + 1}`,
310+
})),
311+
},
312+
});
269313
},
270314
});

test/localization/int.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
WithLocalizedRelationship,
88
LocalizedRequired,
99
RelationshipLocalized,
10+
GlobalArray,
1011
} from './payload-types';
1112
import type { LocalizedPostAllLocale } from './config';
1213
import config, { relationshipLocalizedSlug, slug, withLocalizedRelSlug, withRequiredLocalizedFields } from './config';
@@ -477,6 +478,27 @@ describe('Localization', () => {
477478
});
478479
});
479480

481+
describe('Localized - arrays with nested localized fields', () => {
482+
it('should allow moving rows and retain existing row locale data', async () => {
483+
const globalArray = await payload.findGlobal<GlobalArray>({
484+
slug: 'global-array',
485+
});
486+
487+
const reversedArrayRows = [...globalArray.array].reverse();
488+
489+
const updatedGlobal = await payload.updateGlobal({
490+
slug: 'global-array',
491+
locale: 'all',
492+
data: {
493+
array: reversedArrayRows,
494+
},
495+
});
496+
497+
expect(updatedGlobal.array[0].text.en).toStrictEqual('test en 2');
498+
expect(updatedGlobal.array[0].text.es).toStrictEqual('test es 2');
499+
});
500+
});
501+
480502
describe('Localized - required', () => {
481503
it('should update without passing all required fields', async () => {
482504
const newDoc = await payload.create({

test/localization/payload-types.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@
66
*/
77

88
export interface Config {}
9+
/**
10+
* This interface was referenced by `Config`'s JSON-Schema
11+
* via the `definition` "global-array".
12+
*/
13+
export interface GlobalArray {
14+
id: string;
15+
array: {
16+
text?: string;
17+
id?: string;
18+
}[];
19+
}
920
/**
1021
* This interface was referenced by `Config`'s JSON-Schema
1122
* via the `definition` "users".

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"compilerOptions": {
33
"target": "es2019",
4+
"sourceMap": true,
45
"module": "commonjs",
56
"allowJs": true, /* Allow javascript files to be compiled. */
67
"checkJs": false, /* Report errors in .js files. */

0 commit comments

Comments
 (0)