Skip to content

Commit 0efc610

Browse files
authored
fix(db-postgres): select hasMany nested to array + tab/group (#8739)
1 parent cc99c3a commit 0efc610

File tree

4 files changed

+197
-2
lines changed

4 files changed

+197
-2
lines changed

packages/db-postgres/src/transform/write/traverseFields.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ export const traverseFields = ({
207207
if (typeof data[field.name] === 'object' && data[field.name] !== null) {
208208
if (field.localized) {
209209
Object.entries(data[field.name]).forEach(([localeKey, localeData]) => {
210+
// preserve array ID if there is
211+
localeData._uuid = data.id || data._uuid
212+
210213
traverseFields({
211214
adapter,
212215
arrays,
@@ -232,14 +235,18 @@ export const traverseFields = ({
232235
})
233236
})
234237
} else {
238+
// preserve array ID if there is
239+
const groupData = data[field.name] as Record<string, unknown>
240+
groupData._uuid = data.id || data._uuid
241+
235242
traverseFields({
236243
adapter,
237244
arrays,
238245
baseTableName,
239246
blocks,
240247
blocksToDelete,
241248
columnPrefix: `${columnName}_`,
242-
data: data[field.name] as Record<string, unknown>,
249+
data: groupData,
243250
existingLocales,
244251
fieldPrefix: `${fieldName}_`,
245252
fields: field.fields,
@@ -266,6 +273,9 @@ export const traverseFields = ({
266273
if (typeof data[tab.name] === 'object' && data[tab.name] !== null) {
267274
if (tab.localized) {
268275
Object.entries(data[tab.name]).forEach(([localeKey, localeData]) => {
276+
// preserve array ID if there is
277+
localeData._uuid = data.id || data._uuid
278+
269279
traverseFields({
270280
adapter,
271281
arrays,
@@ -291,14 +301,18 @@ export const traverseFields = ({
291301
})
292302
})
293303
} else {
304+
const tabData = data[tab.name] as Record<string, unknown>
305+
// preserve array ID if there is
306+
tabData._uuid = data.id || data._uuid
307+
294308
traverseFields({
295309
adapter,
296310
arrays,
297311
baseTableName,
298312
blocks,
299313
blocksToDelete,
300314
columnPrefix: `${columnPrefix || ''}${toSnakeCase(tab.name)}_`,
301-
data: data[tab.name] as Record<string, unknown>,
315+
data: tabData,
302316
existingLocales,
303317
fieldPrefix: `${fieldPrefix || ''}${tab.name}_`,
304318
fields: tab.fields,

test/fields/collections/Select/index.ts

+82
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

+48
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,54 @@ describe('Fields', () => {
573573

574574
expect(resInSecond.totalDocs).toBe(1)
575575
})
576+
577+
it('should CRUD within array hasMany', async () => {
578+
const doc = await payload.create({
579+
collection: 'select-fields',
580+
data: { array: [{ selectHasMany: ['one', 'two'] }] },
581+
})
582+
583+
expect(doc.array[0].selectHasMany).toStrictEqual(['one', 'two'])
584+
585+
const upd = await payload.update({
586+
collection: 'select-fields',
587+
id: doc.id,
588+
data: {
589+
array: [
590+
{
591+
id: doc.array[0].id,
592+
selectHasMany: ['six'],
593+
},
594+
],
595+
},
596+
})
597+
598+
expect(upd.array[0].selectHasMany).toStrictEqual(['six'])
599+
})
600+
601+
it('should CRUD within array + group hasMany', async () => {
602+
const doc = await payload.create({
603+
collection: 'select-fields',
604+
data: { array: [{ group: { selectHasMany: ['one', 'two'] } }] },
605+
})
606+
607+
expect(doc.array[0].group.selectHasMany).toStrictEqual(['one', 'two'])
608+
609+
const upd = await payload.update({
610+
collection: 'select-fields',
611+
id: doc.id,
612+
data: {
613+
array: [
614+
{
615+
id: doc.array[0].id,
616+
group: { selectHasMany: ['six'] },
617+
},
618+
],
619+
},
620+
})
621+
622+
expect(upd.array[0].group.selectHasMany).toStrictEqual(['six'])
623+
})
576624
})
577625

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

test/fields/payload-types.ts

+51
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,17 @@ export interface ArrayField {
271271
id?: string | null
272272
}[]
273273
| null
274+
nestedArrayLocalized?:
275+
| {
276+
array?:
277+
| {
278+
text?: string | null
279+
id?: string | null
280+
}[]
281+
| null
282+
id?: string | null
283+
}[]
284+
| null
274285
updatedAt: string
275286
createdAt: string
276287
}
@@ -841,6 +852,37 @@ export interface GroupField {
841852
| null
842853
}
843854
}
855+
localizedGroupArr?: {
856+
array?:
857+
| {
858+
text?: string | null
859+
id?: string | null
860+
}[]
861+
| null
862+
}
863+
localizedGroupSelect?: {
864+
select?: ('one' | 'two')[] | null
865+
}
866+
localizedGroupRel?: {
867+
rel?: (string | null) | TextField
868+
}
869+
localizedGroupManyRel?: {
870+
email?: (string | TextField)[] | null
871+
}
872+
localizedGroupPolyRel?: {
873+
email?: {
874+
relationTo: 'text-fields'
875+
value: string | TextField
876+
} | null
877+
}
878+
localizedGroupPolyHasManyRel?: {
879+
email?:
880+
| {
881+
relationTo: 'text-fields'
882+
value: string | TextField
883+
}[]
884+
| null
885+
}
844886
updatedAt: string
845887
createdAt: string
846888
}
@@ -1116,6 +1158,15 @@ export interface SelectField {
11161158
select?: ('one' | 'two' | 'three') | null
11171159
selectReadOnly?: ('one' | 'two' | 'three') | null
11181160
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null
1161+
array?:
1162+
| {
1163+
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null
1164+
group?: {
1165+
selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null
1166+
}
1167+
id?: string | null
1168+
}[]
1169+
| null
11191170
selectHasManyLocalized?: ('one' | 'two')[] | null
11201171
selectI18n?: ('one' | 'two' | 'three') | null
11211172
simple?: ('One' | 'Two' | 'Three') | null

0 commit comments

Comments
 (0)