fix(drizzle): array/relationship/select hasMany in localized field (#8355)

This PR addresses these issues with localized groups / tabs with
Postgres / SQLite:

- Array fields inside of localized groups. Fixes
https://github.com/payloadcms/payload/issues/8322
- Select fields with `hasMany: true` inside of localized groups. Related
to 1, but still needed its own additional logic.
- Relationship (non-polymorphic / non has-many) inside of localized
groups. Previously, even just trying to define them in the config led to
a crash. Fixes https://github.com/payloadcms/payload/issues/8308

Ensures test coverage for localized groups.
This commit is contained in:
Sasha
2024-09-23 18:34:02 +03:00
committed by GitHub
parent 36ba6d47b4
commit 338c93a229
6 changed files with 192 additions and 3 deletions

View File

@@ -879,7 +879,7 @@ export const traverseFields = ({
// add relationship to table
relationsToBuild.set(fieldName, {
type: 'one',
localized: adapter.payload.config.localization && field.localized,
localized: adapter.payload.config.localization && (field.localized || forceLocalized),
target: tableName,
})

View File

@@ -886,7 +886,7 @@ export const traverseFields = ({
// add relationship to table
relationsToBuild.set(fieldName, {
type: 'one',
localized: adapter.payload.config.localization && field.localized,
localized: adapter.payload.config.localization && (field.localized || forceLocalized),
target: tableName,
})

View File

@@ -527,13 +527,23 @@ export const traverseFields = <T extends Record<string, unknown>>({
return selectResult
}, {})
} else {
result[field.name] = fieldData.map(({ value }) => value)
let selectData = fieldData
if (withinArrayOrBlockLocale) {
selectData = selectData.filter(({ locale }) => locale === withinArrayOrBlockLocale)
}
result[field.name] = selectData.map(({ value }) => value)
}
}
return result
}
if (field.localized && Array.isArray(table._locales)) {
if (!table._locales.length && adapter.payload.config.localization) {
adapter.payload.config.localization.localeCodes.forEach((_locale) =>
(table._locales as unknown[]).push({ _locale }),
)
}
table._locales.forEach((localeRow) => {
valuesToTransform.push({
ref: localizedFieldData,

View File

@@ -221,6 +221,48 @@ const GroupFields: CollectionConfig = {
},
],
},
{
name: 'localizedGroupArr',
type: 'group',
localized: true,
fields: [
{
name: 'array',
type: 'array',
fields: [
{
type: 'text',
name: 'text',
},
],
},
],
},
{
name: 'localizedGroupSelect',
type: 'group',
localized: true,
fields: [
{
type: 'select',
hasMany: true,
options: ['one', 'two'],
name: 'select',
},
],
},
{
name: 'localizedGroupRel',
type: 'group',
localized: true,
fields: [
{
type: 'relationship',
relationTo: 'email-fields',
name: 'email',
},
],
},
],
}

View File

@@ -1336,6 +1336,129 @@ describe('Fields', () => {
expect(res.camelCaseGroup.array[0].text).toBe('text')
expect(res.camelCaseGroup.array[0].array[0].text).toBe('nested')
})
it('should insert/update/read localized group with array inside', async () => {
const doc = await payload.create({
collection: 'group-fields',
locale: 'en',
data: {
group: { text: 'req' },
localizedGroupArr: {
array: [{ text: 'text-en' }],
},
},
})
expect(doc.localizedGroupArr.array[0].text).toBe('text-en')
const esDoc = await payload.update({
collection: 'group-fields',
locale: 'es',
id: doc.id,
data: {
localizedGroupArr: {
array: [{ text: 'text-es' }],
},
},
})
expect(esDoc.localizedGroupArr.array[0].text).toBe('text-es')
const allDoc = await payload.findByID({
collection: 'group-fields',
id: doc.id,
locale: 'all',
})
expect(allDoc.localizedGroupArr.en.array[0].text).toBe('text-en')
expect(allDoc.localizedGroupArr.es.array[0].text).toBe('text-es')
})
it('should insert/update/read localized group with select hasMany inside', async () => {
const doc = await payload.create({
collection: 'group-fields',
locale: 'en',
data: {
group: { text: 'req' },
localizedGroupSelect: {
select: ['one', 'two'],
},
},
})
expect(doc.localizedGroupSelect.select).toStrictEqual(['one', 'two'])
const esDoc = await payload.update({
collection: 'group-fields',
locale: 'es',
id: doc.id,
data: {
localizedGroupSelect: {
select: ['one'],
},
},
})
expect(esDoc.localizedGroupSelect.select).toStrictEqual(['one'])
const allDoc = await payload.findByID({
collection: 'group-fields',
id: doc.id,
locale: 'all',
})
expect(allDoc.localizedGroupSelect.en.select).toStrictEqual(['one', 'two'])
expect(allDoc.localizedGroupSelect.es.select).toStrictEqual(['one'])
})
it('should insert/update/read localized group with relationship inside', async () => {
const rel_1 = await payload.create({
collection: 'email-fields',
data: { email: 'pro123@gmail.com' },
})
const rel_2 = await payload.create({
collection: 'email-fields',
data: { email: 'frank@gmail.com' },
})
const doc = await payload.create({
collection: 'group-fields',
depth: 0,
data: {
group: { text: 'requireddd' },
localizedGroupRel: {
email: rel_1.id,
},
},
})
expect(doc.localizedGroupRel.email).toBe(rel_1.id)
const upd = await payload.update({
collection: 'group-fields',
depth: 0,
id: doc.id,
locale: 'es',
data: {
localizedGroupRel: {
email: rel_2.id,
},
},
})
expect(upd.localizedGroupRel.email).toBe(rel_2.id)
const docAll = await payload.findByID({
collection: 'group-fields',
id: doc.id,
locale: 'all',
depth: 0,
})
expect(docAll.localizedGroupRel.en.email).toBe(rel_1.id)
expect(docAll.localizedGroupRel.es.email).toBe(rel_2.id)
})
})
describe('tabs', () => {

View File

@@ -957,6 +957,20 @@ export interface GroupField {
}[]
| null;
};
localizedGroupArr?: {
array?:
| {
text?: string | null;
id?: string | null;
}[]
| null;
};
localizedGroupSelect?: {
select?: ('one' | 'two')[] | null;
};
localizedGroupRel?: {
email?: (string | null) | EmailField;
};
updatedAt: string;
createdAt: string;
}