diff --git a/src/admin/components/forms/field-types/Relationship/createRelationMap.ts b/src/admin/components/forms/field-types/Relationship/createRelationMap.ts index 12ebc6c0b..737bd0554 100644 --- a/src/admin/components/forms/field-types/Relationship/createRelationMap.ts +++ b/src/admin/components/forms/field-types/Relationship/createRelationMap.ts @@ -1,4 +1,4 @@ -import { ValueWithRelation } from './types'; +import { Value } from './types'; type RelationMap = { [relation: string]: unknown[] @@ -7,7 +7,7 @@ type RelationMap = { type CreateRelationMap = (args: { hasMany: boolean relationTo: string | string[] - value: unknown + value: Value | Value[] // really needs to be `ValueWithRelation` }) => RelationMap; export const createRelationMap: CreateRelationMap = ({ @@ -33,15 +33,18 @@ export const createRelationMap: CreateRelationMap = ({ if (hasMany && Array.isArray(value)) { value.forEach((val) => { - if (hasMultipleRelations) { + if (hasMultipleRelations && typeof val === 'object' && 'relationTo' in val && 'value' in val) { add(val.relationTo, val.value); - } else { + } + + if (!hasMultipleRelations && typeof relationTo === 'string') { add(relationTo, val); } }); - } else if (hasMultipleRelations) { - const valueWithRelation = value as ValueWithRelation; - add(valueWithRelation?.relationTo, valueWithRelation?.value); + } else if (hasMultipleRelations && Array.isArray(relationTo)) { + if (typeof value === 'object' && 'relationTo' in value && 'value' in value) { + add(value.relationTo, value.value); + } } else { add(relationTo, value); } diff --git a/src/admin/components/forms/field-types/Relationship/index.tsx b/src/admin/components/forms/field-types/Relationship/index.tsx index 25b7e7e47..b4964dfde 100644 --- a/src/admin/components/forms/field-types/Relationship/index.tsx +++ b/src/admin/components/forms/field-types/Relationship/index.tsx @@ -117,7 +117,11 @@ const Relationship: React.FC = (props) => { const relationsToFetch = lastFullyLoadedRelationToUse === -1 ? relations : relations.slice(lastFullyLoadedRelationToUse + 1); let resultsFetched = 0; - const relationMap = createRelationMap({ hasMany, relationTo, value: valueArg }); + const relationMap = createRelationMap({ + hasMany, + relationTo, + value: valueArg, + }); if (!errorLoading) { relationsToFetch.reduce(async (priorRelation, relation) => { @@ -209,12 +213,12 @@ const Relationship: React.FC = (props) => { locale, ]); - const updateSearch = useDebouncedCallback((searchArg: string, valueArg: unknown) => { + const updateSearch = useDebouncedCallback((searchArg: string, valueArg: Value | Value[]) => { getResults({ search: searchArg, value: valueArg, sort: true }); setSearch(searchArg); }, [getResults]); - const handleInputChange = useCallback((searchArg: string, valueArg: unknown) => { + const handleInputChange = useCallback((searchArg: string, valueArg: Value | Value[]) => { if (search !== searchArg) { updateSearch(searchArg, valueArg); } diff --git a/src/admin/components/forms/field-types/Relationship/types.ts b/src/admin/components/forms/field-types/Relationship/types.ts index 30b89daa8..95d487f03 100644 --- a/src/admin/components/forms/field-types/Relationship/types.ts +++ b/src/admin/components/forms/field-types/Relationship/types.ts @@ -19,10 +19,12 @@ export type OptionGroup = { options: Option[] } -export type Value = { +export type ValueWithRelation = { relationTo: string value: string | number -} | string | number +} + +export type Value = ValueWithRelation | string | number type CLEAR = { type: 'CLEAR' @@ -46,16 +48,11 @@ type ADD = { export type Action = CLEAR | ADD | UPDATE -export type ValueWithRelation = { - relationTo: string - value: string -} - export type GetResults = (args: { lastFullyLoadedRelation?: number lastLoadedPage?: number search?: string - value?: unknown + value?: Value | Value[] sort?: boolean onSuccess?: () => void }) => Promise diff --git a/test/fields/collections/Relationship/index.ts b/test/fields/collections/Relationship/index.ts index c077e43bc..e6d76fe4a 100644 --- a/test/fields/collections/Relationship/index.ts +++ b/test/fields/collections/Relationship/index.ts @@ -24,6 +24,21 @@ const RelationshipFields: CollectionConfig = { allowCreate: false, }, }, + { + name: 'relationWithDynamicDefault', + type: 'relationship', + relationTo: 'users', + defaultValue: ({ user }) => user.id, + }, + { + name: 'relationHasManyWithDynamicDefault', + type: 'relationship', + relationTo: ['users'], + defaultValue: ({ user }) => ({ + relationTo: 'users', + value: user.id, + }), + }, ], }; diff --git a/test/fields/e2e.spec.ts b/test/fields/e2e.spec.ts index a5e412463..caa3d0510 100644 --- a/test/fields/e2e.spec.ts +++ b/test/fields/e2e.spec.ts @@ -633,6 +633,12 @@ describe('fields', () => { // expect the button to not exist in the field await expect(await page.locator('#relationToSelfSelectOnly-add-new .relationship-add-new__add-button').count()).toEqual(0); }); + + test('should populate relationship dynamic default value', async () => { + await page.goto(url.create); + await expect(page.locator('#field-relationWithDynamicDefault .relationship--single-value__text')).toContainText('dev@payloadcms.com'); + await expect(page.locator('#field-relationHasManyWithDynamicDefault .relationship--single-value__text')).toContainText('dev@payloadcms.com'); + }); }); describe('upload', () => {