From 55a996af19e1b6bd28262fd6974033de75813474 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 26 Aug 2023 23:34:04 -0400 Subject: [PATCH] chore: localized groups --- .../db-postgres/src/transform/write/blocks.ts | 64 ++++++++++ .../src/transform/write/traverseFields.ts | 71 +++++------ .../src/upsertRow/deleteExistingRowsByPath.ts | 3 +- test/postgres/int.spec.ts | 112 ++++++++++++++++++ test/postgres/seed/localizedBlocks.ts | 47 -------- test/postgres/seed/localizedGroups.ts | 31 ----- 6 files changed, 208 insertions(+), 120 deletions(-) create mode 100644 packages/db-postgres/src/transform/write/blocks.ts delete mode 100644 test/postgres/seed/localizedBlocks.ts delete mode 100644 test/postgres/seed/localizedGroups.ts diff --git a/packages/db-postgres/src/transform/write/blocks.ts b/packages/db-postgres/src/transform/write/blocks.ts new file mode 100644 index 0000000000..00fa36bd77 --- /dev/null +++ b/packages/db-postgres/src/transform/write/blocks.ts @@ -0,0 +1,64 @@ +/* eslint-disable no-param-reassign */ +import { BlockField } from 'payload/types'; +import toSnakeCase from 'to-snake-case'; +import { BlockRowToInsert } from './types'; +import { traverseFields } from './traverseFields'; + +type Args = { + blocks: { + [blockType: string]: BlockRowToInsert[] + } + data: Record[] + field: BlockField + locale: string + path: string + relationships: Record[] + tableName +} +export const transformBlocks = ({ + blocks, + data, + field, + locale, + path, + relationships, + tableName, +}: Args) => { + data.forEach((blockRow, i) => { + if (typeof blockRow.blockType !== 'string') return; + const matchedBlock = field.blocks.find(({ slug }) => slug === blockRow.blockType); + if (!matchedBlock) return; + + if (!blocks[blockRow.blockType]) blocks[blockRow.blockType] = []; + + const newRow: BlockRowToInsert = { + arrays: {}, + row: { + _order: i + 1, + _path: `${path}${field.name}`, + }, + locales: {}, + }; + + if (field.localized) newRow.row._locale = locale; + + const blockTableName = `${tableName}_${toSnakeCase(blockRow.blockType)}`; + + traverseFields({ + arrays: newRow.arrays, + blocks, + columnPrefix: '', + data: blockRow, + fields: matchedBlock.fields, + locale, + locales: newRow.locales, + newTableName: blockTableName, + parentTableName: blockTableName, + path: `${path || ''}${field.name}.${i}.`, + relationships, + row: newRow.row, + }); + + blocks[blockRow.blockType].push(newRow); + }); +}; diff --git a/packages/db-postgres/src/transform/write/traverseFields.ts b/packages/db-postgres/src/transform/write/traverseFields.ts index 421c39a83f..1bd465edec 100644 --- a/packages/db-postgres/src/transform/write/traverseFields.ts +++ b/packages/db-postgres/src/transform/write/traverseFields.ts @@ -5,6 +5,7 @@ import { fieldAffectsData, valueIsValueWithRelation } from 'payload/dist/fields/ import { ArrayRowToInsert, BlockRowToInsert } from './types'; import { isArrayOfRows } from '../../utilities/isArrayOfRows'; import { transformArray } from './array'; +import { transformBlocks } from './blocks'; type Args = { arrays: { @@ -98,46 +99,29 @@ export const traverseFields = ({ if (field.type === 'blocks') { if (field.localized) { if (typeof data[field.name] === 'object' && data[field.name] !== null) { - // loop over each locale - console.log(data[field.name]); + Object.entries(data[field.name]).forEach(([localeKey, localeData]) => { + if (Array.isArray(localeData)) { + transformBlocks({ + blocks, + data: localeData, + field, + locale: localeKey, + path, + relationships, + tableName: newTableName, + }); + } + }); } } else if (isArrayOfRows(fieldData)) { - fieldData.forEach((blockRow, i) => { - if (typeof blockRow.blockType !== 'string') return; - const matchedBlock = field.blocks.find(({ slug }) => slug === blockRow.blockType); - if (!matchedBlock) return; - - if (!blocks[blockRow.blockType]) blocks[blockRow.blockType] = []; - - const newRow: BlockRowToInsert = { - arrays: {}, - row: { - _order: i + 1, - _path: `${path}${field.name}`, - }, - locales: {}, - }; - - if (field.localized) newRow.row._locale = locale; - - const blockTableName = `${newTableName}_${toSnakeCase(blockRow.blockType)}`; - - traverseFields({ - arrays: newRow.arrays, - blocks, - columnPrefix: '', - data: blockRow, - fields: matchedBlock.fields, - locale, - locales: newRow.locales, - newTableName: blockTableName, - parentTableName: blockTableName, - path: `${path || ''}${field.name}.${i}.`, - relationships, - row: newRow.row, - }); - - blocks[blockRow.blockType].push(newRow); + transformBlocks({ + blocks, + data: fieldData, + field, + locale, + path, + relationships, + tableName: newTableName, }); } @@ -209,7 +193,7 @@ export const traverseFields = ({ if (fieldAffectsData(field)) { const valuesToTransform: { localeKey?: string, ref: unknown, value: unknown }[] = []; - if ((field.localized || forceLocalized)) { + if ((field.localized)) { if (typeof fieldData === 'object' && fieldData !== null) { Object.entries(fieldData).forEach(([localeKey, localeData]) => { if (!locales[localeKey]) locales[localeKey] = {}; @@ -222,7 +206,14 @@ export const traverseFields = ({ }); } } else { - valuesToTransform.push({ value: fieldData, ref: row }); + let ref = row; + + if (forceLocalized) { + if (!locales[locale]) locales[locale] = {}; + ref = locales[locale]; + } + + valuesToTransform.push({ value: fieldData, ref }); } valuesToTransform.forEach(({ localeKey, ref, value }) => { diff --git a/packages/db-postgres/src/upsertRow/deleteExistingRowsByPath.ts b/packages/db-postgres/src/upsertRow/deleteExistingRowsByPath.ts index 32c60f6e95..a9943dc0bb 100644 --- a/packages/db-postgres/src/upsertRow/deleteExistingRowsByPath.ts +++ b/packages/db-postgres/src/upsertRow/deleteExistingRowsByPath.ts @@ -41,7 +41,6 @@ export const deleteExistingRowsByPath = async ({ if (localizedPathsToDelete.size > 0 && locale) { const whereConstraints = [ eq(table[parentColumnName], parentID), - eq(table[localeColumnName], locale), ]; if (pathColumnName) whereConstraints.push(inArray(table[pathColumnName], Array.from(localizedPathsToDelete))); @@ -62,6 +61,6 @@ export const deleteExistingRowsByPath = async ({ await adapter.db.delete(table) .where( and(...whereConstraints), - ).returning(); + ); } }; diff --git a/test/postgres/int.spec.ts b/test/postgres/int.spec.ts index ea1f44ccf1..e97ce536d6 100644 --- a/test/postgres/int.spec.ts +++ b/test/postgres/int.spec.ts @@ -339,4 +339,116 @@ describe('Postgres', () => { expect(retrievedArray.array.es[1].text).toStrictEqual('hello 2 in spanish'); }); }); + + describe('localized blocks', () => { + let localizedBlocks; + + it('creates localized blocks', async () => { + localizedBlocks = await payload.create({ + collection: 'localized-blocks', + data: { + title: 'hello', + layout: [ + { + blockType: 'text', + text: 'hello in english', + }, + { + blockType: 'number', + number: 1337, + }, + ], + }, + }); + + expect(localizedBlocks.layout[0].text).toStrictEqual('hello in english'); + expect(localizedBlocks.layout[1].number).toStrictEqual(1337); + }); + + it('adds localized blocks', async () => { + const updated = await payload.update({ + collection: 'localized-blocks', + id: localizedBlocks.id, + locale: 'es', + data: { + title: 'hello in spanish', + layout: [ + { + blockType: 'text', + text: 'hello in spanish', + }, + { + blockType: 'number', + number: 1338, + }, + ], + }, + }); + + expect(updated.layout[0].text).toStrictEqual('hello in spanish'); + expect(updated.layout[1].number).toStrictEqual(1338); + }); + + it('retrieves blocks field in all locales', async () => { + const retrievedBlocks = await payload.findByID({ + collection: 'localized-blocks', + id: localizedBlocks.id, + locale: 'all', + }); + + expect(retrievedBlocks.layout.en[0].text).toStrictEqual('hello in english'); + expect(retrievedBlocks.layout.en[1].number).toStrictEqual(1337); + expect(retrievedBlocks.layout.es[0].text).toStrictEqual('hello in spanish'); + expect(retrievedBlocks.layout.es[1].number).toStrictEqual(1338); + }); + }); + + describe('localized group', () => { + let localizedGroup; + + it('creates localized group', async () => { + localizedGroup = await payload.create({ + collection: 'localized-groups', + data: { + group: { + text: 'en', + number: 123, + }, + }, + }); + + expect(localizedGroup.group.text).toStrictEqual('en'); + expect(localizedGroup.group.number).toStrictEqual(123); + }); + + it('adds localized group', async () => { + const updated = await payload.update({ + collection: 'localized-groups', + id: localizedGroup.id, + locale: 'es', + data: { + group: { + text: 'es', + number: 456, + }, + }, + }); + + expect(updated.group.text).toStrictEqual('es'); + expect(updated.group.number).toStrictEqual(456); + }); + + it('retrieves group field in all locales', async () => { + const retrievedGroup = await payload.findByID({ + collection: 'localized-groups', + id: localizedGroup.id, + locale: 'all', + }); + + expect(retrievedGroup.group.en.text).toStrictEqual('en'); + expect(retrievedGroup.group.en.number).toStrictEqual(123); + expect(retrievedGroup.group.es.text).toStrictEqual('es'); + expect(retrievedGroup.group.es.number).toStrictEqual(456); + }); + }); }); diff --git a/test/postgres/seed/localizedBlocks.ts b/test/postgres/seed/localizedBlocks.ts deleted file mode 100644 index 7cf8a6d0e3..0000000000 --- a/test/postgres/seed/localizedBlocks.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Payload } from '../../../src'; - -export const seedLocalizedBlocks = async (payload: Payload) => { - const localizedBlock = await payload.create({ - collection: 'localized-blocks', - data: { - title: 'hello', - layout: [ - { - blockType: 'text', - text: 'hello in english', - }, - { - blockType: 'number', - number: 1337, - }, - ], - }, - }); - - await payload.update({ - collection: 'localized-blocks', - id: localizedBlock.id, - locale: 'es', - data: { - title: 'hello in spanish', - layout: [ - { - blockType: 'text', - text: 'hello in spanny', - }, - { - blockType: 'number', - number: 69420, - }, - ], - }, - }); - - const retrievedBlock = await payload.findByID({ - collection: 'localized-blocks', - id: localizedBlock.id, - locale: 'all', - }); - - console.log(retrievedBlock); -}; diff --git a/test/postgres/seed/localizedGroups.ts b/test/postgres/seed/localizedGroups.ts deleted file mode 100644 index 91b833cb49..0000000000 --- a/test/postgres/seed/localizedGroups.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { Payload } from '../../../src'; - -export const seedLocalizedGroups = async (payload: Payload) => { - const localizedGroup = await payload.create({ - collection: 'localized-groups', - data: { - group: { - text: 'en', - number: 123, - }, - }, - }); - - const test = await payload.update({ - collection: 'localized-groups', - id: localizedGroup.id, - locale: 'es', - data: { - group: { - text: 'es', - number: 456, - }, - }, - }); - - const retrievedGroup = await payload.findByID({ - collection: 'localized-groups', - id: localizedGroup.id, - locale: 'all', - }); -};