Skip to content

Commit 872b205

Browse files
authored
fix(drizzle): select hasMany nested to array + tab/group (#8737)
Fixes #8732
1 parent 99b4359 commit 872b205

File tree

4 files changed

+173
-2
lines changed

4 files changed

+173
-2
lines changed

packages/drizzle/src/transform/write/traverseFields.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ export const traverseFields = ({
212212
if (typeof data[field.name] === 'object' && data[field.name] !== null) {
213213
if (field.localized) {
214214
Object.entries(data[field.name]).forEach(([localeKey, localeData]) => {
215+
// preserve array ID if there is
216+
localeData._uuid = data.id || data._uuid
217+
215218
traverseFields({
216219
adapter,
217220
arrays,
@@ -237,14 +240,18 @@ export const traverseFields = ({
237240
})
238241
})
239242
} else {
243+
// preserve array ID if there is
244+
const groupData = data[field.name] as Record<string, unknown>
245+
groupData._uuid = data.id || data._uuid
246+
240247
traverseFields({
241248
adapter,
242249
arrays,
243250
baseTableName,
244251
blocks,
245252
blocksToDelete,
246253
columnPrefix: `${columnName}_`,
247-
data: data[field.name] as Record<string, unknown>,
254+
data: groupData,
248255
existingLocales,
249256
fieldPrefix: `${fieldName}_`,
250257
fields: field.fields,
@@ -275,6 +282,9 @@ export const traverseFields = ({
275282
if (typeof data[tab.name] === 'object' && data[tab.name] !== null) {
276283
if (tab.localized) {
277284
Object.entries(data[tab.name]).forEach(([localeKey, localeData]) => {
285+
// preserve array ID if there is
286+
localeData._uuid = data.id || data._uuid
287+
278288
traverseFields({
279289
adapter,
280290
arrays,
@@ -300,14 +310,18 @@ export const traverseFields = ({
300310
})
301311
})
302312
} else {
313+
const tabData = data[tab.name] as Record<string, unknown>
314+
// preserve array ID if there is
315+
tabData._uuid = data.id || data._uuid
316+
303317
traverseFields({
304318
adapter,
305319
arrays,
306320
baseTableName,
307321
blocks,
308322
blocksToDelete,
309323
columnPrefix: `${columnPrefix || ''}${toSnakeCase(tab.name)}_`,
310-
data: data[tab.name] as Record<string, unknown>,
324+
data: tabData,
311325
existingLocales,
312326
fieldPrefix: `${fieldPrefix || ''}${tab.name}_`,
313327
fields: tab.fields,

test/fields/collections/Select/index.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,88 @@ const SelectFields: CollectionConfig = {
8282
},
8383
],
8484
},
85+
{
86+
name: 'array',
87+
type: 'array',
88+
fields: [
89+
{
90+
name: 'selectHasMany',
91+
hasMany: true,
92+
type: 'select',
93+
admin: {
94+
isClearable: true,
95+
isSortable: true,
96+
},
97+
options: [
98+
{
99+
label: 'Value One',
100+
value: 'one',
101+
},
102+
{
103+
label: 'Value Two',
104+
value: 'two',
105+
},
106+
{
107+
label: 'Value Three',
108+
value: 'three',
109+
},
110+
{
111+
label: 'Value Four',
112+
value: 'four',
113+
},
114+
{
115+
label: 'Value Five',
116+
value: 'five',
117+
},
118+
{
119+
label: 'Value Six',
120+
value: 'six',
121+
},
122+
],
123+
},
124+
{
125+
name: 'group',
126+
type: 'group',
127+
fields: [
128+
{
129+
name: 'selectHasMany',
130+
hasMany: true,
131+
type: 'select',
132+
admin: {
133+
isClearable: true,
134+
isSortable: true,
135+
},
136+
options: [
137+
{
138+
label: 'Value One',
139+
value: 'one',
140+
},
141+
{
142+
label: 'Value Two',
143+
value: 'two',
144+
},
145+
{
146+
label: 'Value Three',
147+
value: 'three',
148+
},
149+
{
150+
label: 'Value Four',
151+
value: 'four',
152+
},
153+
{
154+
label: 'Value Five',
155+
value: 'five',
156+
},
157+
{
158+
label: 'Value Six',
159+
value: 'six',
160+
},
161+
],
162+
},
163+
],
164+
},
165+
],
166+
},
85167
{
86168
name: 'selectHasManyLocalized',
87169
type: 'select',

test/fields/int.spec.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,54 @@ describe('Fields', () => {
552552
expect(hitResult).toBeDefined()
553553
expect(missResult).toBeFalsy()
554554
})
555+
556+
it('should CRUD within array hasMany', async () => {
557+
const doc = await payload.create({
558+
collection: 'select-fields',
559+
data: { array: [{ selectHasMany: ['one', 'two'] }] },
560+
})
561+
562+
expect(doc.array[0].selectHasMany).toStrictEqual(['one', 'two'])
563+
564+
const upd = await payload.update({
565+
collection: 'select-fields',
566+
id: doc.id,
567+
data: {
568+
array: [
569+
{
570+
id: doc.array[0].id,
571+
selectHasMany: ['six'],
572+
},
573+
],
574+
},
575+
})
576+
577+
expect(upd.array[0].selectHasMany).toStrictEqual(['six'])
578+
})
579+
580+
it('should CRUD within array + group hasMany', async () => {
581+
const doc = await payload.create({
582+
collection: 'select-fields',
583+
data: { array: [{ group: { selectHasMany: ['one', 'two'] } }] },
584+
})
585+
586+
expect(doc.array[0].group.selectHasMany).toStrictEqual(['one', 'two'])
587+
588+
const upd = await payload.update({
589+
collection: 'select-fields',
590+
id: doc.id,
591+
data: {
592+
array: [
593+
{
594+
id: doc.array[0].id,
595+
group: { selectHasMany: ['six'] },
596+
},
597+
],
598+
},
599+
})
600+
601+
expect(upd.array[0].group.selectHasMany).toStrictEqual(['six'])
602+
})
555603
})
556604

557605
describe('number', () => {

test/fields/payload-types.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export interface Config {
6060
'uploads-multi': UploadsMulti;
6161
'uploads-poly': UploadsPoly;
6262
'uploads-multi-poly': UploadsMultiPoly;
63+
'uploads-restricted': UploadsRestricted;
6364
'ui-fields': UiField;
6465
'payload-locked-documents': PayloadLockedDocument;
6566
'payload-preferences': PayloadPreference;
@@ -1328,6 +1329,15 @@ export interface SelectField {
13281329
select?: ('one' | 'two' | 'three') | null;
13291330
selectReadOnly?: ('one' | 'two' | 'three') | null;
13301331
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null;
1332+
array?:
1333+
| {
1334+
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null;
1335+
group?: {
1336+
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null;
1337+
};
1338+
id?: string | null;
1339+
}[]
1340+
| null;
13311341
selectHasManyLocalized?: ('one' | 'two')[] | null;
13321342
selectI18n?: ('one' | 'two' | 'three') | null;
13331343
simple?: ('One' | 'Two' | 'Three') | null;
@@ -1619,6 +1629,19 @@ export interface UploadsMultiPoly {
16191629
updatedAt: string;
16201630
createdAt: string;
16211631
}
1632+
/**
1633+
* This interface was referenced by `Config`'s JSON-Schema
1634+
* via the `definition` "uploads-restricted".
1635+
*/
1636+
export interface UploadsRestricted {
1637+
id: string;
1638+
text?: string | null;
1639+
uploadWithoutRestriction?: (string | null) | Upload;
1640+
uploadWithAllowCreateFalse?: (string | null) | Upload;
1641+
uploadMultipleWithAllowCreateFalse?: (string | Upload)[] | null;
1642+
updatedAt: string;
1643+
createdAt: string;
1644+
}
16221645
/**
16231646
* This interface was referenced by `Config`'s JSON-Schema
16241647
* via the `definition` "ui-fields".
@@ -1764,6 +1787,10 @@ export interface PayloadLockedDocument {
17641787
relationTo: 'uploads-multi-poly';
17651788
value: string | UploadsMultiPoly;
17661789
} | null)
1790+
| ({
1791+
relationTo: 'uploads-restricted';
1792+
value: string | UploadsRestricted;
1793+
} | null)
17671794
| ({
17681795
relationTo: 'ui-fields';
17691796
value: string | UiField;

0 commit comments

Comments
 (0)