fix(live-preview): clear hasMany relationships

This commit is contained in:
Jacob Fletcher
2023-11-24 09:56:50 -05:00
parent 24dacd6712
commit aab2407112
4 changed files with 143 additions and 116 deletions

View File

@@ -125,7 +125,7 @@ export const traverseFields = <T>(args: {
case 'relationship': case 'relationship':
// Handle `hasMany` relationships // Handle `hasMany` relationships
if (fieldSchema.hasMany && Array.isArray(incomingData[fieldName])) { if (fieldSchema.hasMany && Array.isArray(incomingData[fieldName])) {
if (!result[fieldName]) { if (!result[fieldName] || !incomingData[fieldName].length) {
result[fieldName] = [] result[fieldName] = []
} }

View File

@@ -50,6 +50,79 @@ export const Pages: CollectionConfig = {
}, },
], ],
}, },
{
label: 'Test',
fields: [
{
name: 'relationshipInRichText',
type: 'richText',
},
{
name: 'relationshipAsUpload',
type: 'upload',
relationTo: 'media',
},
{
name: 'relationshipMonoHasOne',
type: 'relationship',
relationTo: 'posts',
},
{
name: 'relationshipMonoHasMany',
type: 'relationship',
relationTo: 'posts',
hasMany: true,
},
{
name: 'relationshipPolyHasOne',
type: 'relationship',
relationTo: ['posts'],
},
{
name: 'relationshipPolyHasMany',
type: 'relationship',
relationTo: ['posts'],
hasMany: true,
},
{
name: 'arrayOfRelationships',
type: 'array',
fields: [
{
name: 'uploadInArray',
type: 'upload',
relationTo: 'media',
},
{
name: 'richTextInArray',
type: 'richText',
},
{
name: 'relationshipInArrayMonoHasOne',
type: 'relationship',
relationTo: 'posts',
},
{
name: 'relationshipInArrayMonoHasMany',
type: 'relationship',
relationTo: 'posts',
hasMany: true,
},
{
name: 'relationshipInArrayPolyHasOne',
type: 'relationship',
relationTo: ['posts'],
},
{
name: 'relationshipInArrayPolyHasMany',
type: 'relationship',
relationTo: ['posts'],
hasMany: true,
},
],
},
],
},
], ],
}, },
{ {
@@ -71,73 +144,5 @@ export const Pages: CollectionConfig = {
}, },
], ],
}, },
{
name: 'relationshipInRichText',
type: 'richText',
},
{
name: 'relationshipAsUpload',
type: 'upload',
relationTo: 'media',
},
{
name: 'relationshipMonoHasOne',
type: 'relationship',
relationTo: 'posts',
},
{
name: 'relationshipMonoHasMany',
type: 'relationship',
relationTo: 'posts',
hasMany: true,
},
{
name: 'relationshipPolyHasOne',
type: 'relationship',
relationTo: ['posts'],
},
{
name: 'relationshipPolyHasMany',
type: 'relationship',
relationTo: ['posts'],
hasMany: true,
},
{
name: 'arrayOfRelationships',
type: 'array',
fields: [
{
name: 'uploadInArray',
type: 'upload',
relationTo: 'media',
},
{
name: 'richTextInArray',
type: 'richText',
},
{
name: 'relationshipInArrayMonoHasOne',
type: 'relationship',
relationTo: 'posts',
},
{
name: 'relationshipInArrayMonoHasMany',
type: 'relationship',
relationTo: 'posts',
hasMany: true,
},
{
name: 'relationshipInArrayPolyHasOne',
type: 'relationship',
relationTo: ['posts'],
},
{
name: 'relationshipInArrayPolyHasMany',
type: 'relationship',
relationTo: ['posts'],
hasMany: true,
},
],
},
], ],
} }

View File

@@ -220,13 +220,20 @@ describe('Collections - Live Preview', () => {
expect(merge1.relationshipPolyHasMany).toMatchObject([ expect(merge1.relationshipPolyHasMany).toMatchObject([
{ value: testPost, relationTo: postsSlug }, { value: testPost, relationTo: postsSlug },
]) ])
})
it('— relationships - can clear relationships', async () => {
const initialData: Partial<Page> = {
title: 'Test Page',
relationshipMonoHasOne: testPost.id,
relationshipMonoHasMany: [testPost.id],
relationshipPolyHasOne: { value: testPost.id, relationTo: postsSlug },
relationshipPolyHasMany: [{ value: testPost.id, relationTo: postsSlug }],
}
// Clear relationships
const merge2 = await mergeData({ const merge2 = await mergeData({
depth: 1, depth: 1,
fieldSchema: schemaJSON, fieldSchema: schemaJSON,
incomingData: { incomingData: {
...merge1,
relationshipMonoHasOne: null, relationshipMonoHasOne: null,
relationshipMonoHasMany: [], relationshipMonoHasMany: [],
relationshipPolyHasOne: null, relationshipPolyHasOne: null,
@@ -242,33 +249,6 @@ describe('Collections - Live Preview', () => {
expect(merge2.relationshipMonoHasMany).toEqual([]) expect(merge2.relationshipMonoHasMany).toEqual([])
expect(merge2.relationshipPolyHasOne).toBeFalsy() expect(merge2.relationshipPolyHasOne).toBeFalsy()
expect(merge2.relationshipPolyHasMany).toEqual([]) expect(merge2.relationshipPolyHasMany).toEqual([])
// Now populate the relationships again
// This will ensure that the first merge wasn't just initial state
const merge3 = await mergeData({
depth: 1,
fieldSchema: schemaJSON,
incomingData: {
...merge2,
relationshipMonoHasOne: testPost.id,
relationshipMonoHasMany: [testPost.id],
relationshipPolyHasOne: { value: testPost.id, relationTo: postsSlug },
relationshipPolyHasMany: [{ value: testPost.id, relationTo: postsSlug }],
},
initialData,
serverURL,
returnNumberOfRequests: true,
})
expect(merge3._numberOfRequests).toEqual(4)
expect(merge3.relationshipMonoHasOne).toMatchObject(testPost)
expect(merge3.relationshipMonoHasMany).toMatchObject([testPost])
expect(merge3.relationshipPolyHasOne).toMatchObject({ value: testPost, relationTo: postsSlug })
expect(merge3.relationshipPolyHasMany).toMatchObject([
{ value: testPost, relationTo: postsSlug },
])
}) })
it('— relationships - populates within arrays', async () => { it('— relationships - populates within arrays', async () => {

View File

@@ -52,8 +52,20 @@ export const RelationshipsBlock: React.FC<RelationshipsBlockProps> = (props) =>
<p> <p>
<b>Monomorphic Has Many:</b> <b>Monomorphic Has Many:</b>
</p> </p>
{data?.relationshipMonoHasMany?.map((item, index) => {data?.relationshipMonoHasMany ? (
item ? <div key={index}>{typeof item === 'string' ? item : item.title}</div> : 'null', <Fragment>
{data?.relationshipMonoHasMany.length
? data?.relationshipMonoHasMany?.map((item, index) =>
item ? (
<div key={index}>{typeof item === 'string' ? item : item.title}</div>
) : (
'null'
),
)
: 'None'}
</Fragment>
) : (
<div>None</div>
)} )}
<p> <p>
<b>Polymorphic Has One:</b> <b>Polymorphic Has One:</b>
@@ -70,12 +82,22 @@ export const RelationshipsBlock: React.FC<RelationshipsBlockProps> = (props) =>
<p> <p>
<b>Polymorphic Has Many:</b> <b>Polymorphic Has Many:</b>
</p> </p>
{data?.relationshipPolyHasMany?.map((item, index) => {data?.relationshipPolyHasMany ? (
item.value ? ( <Fragment>
<div key={index}>{typeof item.value === 'string' ? item.value : item.value.title}</div> {data?.relationshipPolyHasMany.length
) : ( ? data?.relationshipPolyHasMany?.map((item, index) =>
'null' item.value ? (
), <div key={index}>
{typeof item.value === 'string' ? item.value : item.value.title}
</div>
) : (
'null'
),
)
: 'None'}
</Fragment>
) : (
<div>None</div>
)} )}
<p> <p>
<b>Array of Relationships:</b> <b>Array of Relationships:</b>
@@ -113,8 +135,20 @@ export const RelationshipsBlock: React.FC<RelationshipsBlockProps> = (props) =>
<p> <p>
<b>Monomorphic Has Many:</b> <b>Monomorphic Has Many:</b>
</p> </p>
{item?.relationshipInArrayMonoHasMany?.map((rel, relIndex) => {item?.relationshipInArrayMonoHasMany ? (
rel ? <div key={relIndex}>{typeof rel === 'string' ? rel : rel.title}</div> : 'null', <Fragment>
{item?.relationshipInArrayMonoHasMany.length
? item?.relationshipInArrayMonoHasMany?.map((rel, relIndex) =>
rel ? (
<div key={relIndex}>{typeof rel === 'string' ? rel : rel.title}</div>
) : (
'null'
),
)
: 'None'}
</Fragment>
) : (
<div>None</div>
)} )}
<p> <p>
<b>Polymorphic Has One:</b> <b>Polymorphic Has One:</b>
@@ -131,14 +165,22 @@ export const RelationshipsBlock: React.FC<RelationshipsBlockProps> = (props) =>
<p> <p>
<b>Polymorphic Has Many:</b> <b>Polymorphic Has Many:</b>
</p> </p>
{item?.relationshipInArrayPolyHasMany?.map((rel, relIndex) => {item?.relationshipInArrayPolyHasMany ? (
rel.value ? ( <Fragment>
<div key={relIndex}> {item?.relationshipInArrayPolyHasMany.length
{typeof rel.value === 'string' ? rel.value : rel.value.title} ? item?.relationshipInArrayPolyHasMany?.map((rel, relIndex) =>
</div> rel.value ? (
) : ( <div key={relIndex}>
'null' {typeof rel.value === 'string' ? rel.value : rel.value.title}
), </div>
) : (
'null'
),
)
: 'None'}
</Fragment>
) : (
<div>None</div>
)} )}
</div> </div>
))} ))}