Skip to content

Commit 5bd852c

Browse files
authored
fix(ui): relationship using list drawer correctly updates when hasMany is true (#12176)
### What? This fixes an issue raised by @maximseshuk in this PR #11553. Here is the text of the original comment: If the field has the property hasMany: true and you select one item, it shows up in the select field, but any additional selected items won't be visible in the select field, even though the data is actually there and can be saved. After refreshing the page, they appear. In addition I added a fix to an issue where the filterOptions weren't being passed in to the useListDrawer hook properly in polymorphic relationships ### How? Instead of using the push method to update the value state, a new array is created and directly set using useState. I think the issue was because using push mutates the original array.
1 parent c85fb80 commit 5bd852c

File tree

3 files changed

+78
-15
lines changed

3 files changed

+78
-15
lines changed

packages/ui/src/fields/Relationship/index.tsx

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,38 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
136136
let newFilterOptions = filterOptions
137137

138138
if (value) {
139-
;(Array.isArray(value) ? value : [value]).forEach((val) => {
140-
;(Array.isArray(relationTo) ? relationTo : [relationTo]).forEach((relationTo) => {
141-
newFilterOptions = {
142-
...(filterOptions || {}),
143-
[relationTo]: {
144-
...(typeof filterOptions?.[relationTo] === 'object' ? filterOptions[relationTo] : {}),
145-
id: {
146-
not_in: [typeof val === 'object' ? val.value : val],
147-
},
148-
},
139+
const valuesByRelation = (Array.isArray(value) ? value : [value]).reduce((acc, val) => {
140+
if (typeof val === 'object' && val.relationTo) {
141+
if (!acc[val.relationTo]) {
142+
acc[val.relationTo] = []
149143
}
150-
})
144+
acc[val.relationTo].push(val.value)
145+
} else if (val) {
146+
const relation = Array.isArray(relationTo) ? undefined : relationTo
147+
if (relation) {
148+
if (!acc[relation]) {
149+
acc[relation] = []
150+
}
151+
acc[relation].push(val)
152+
}
153+
}
154+
return acc
155+
}, {})
156+
157+
;(Array.isArray(relationTo) ? relationTo : [relationTo]).forEach((relation) => {
158+
newFilterOptions = {
159+
...(newFilterOptions || {}),
160+
[relation]: {
161+
...(typeof filterOptions?.[relation] === 'object' ? filterOptions[relation] : {}),
162+
...(valuesByRelation[relation]
163+
? {
164+
id: {
165+
not_in: valuesByRelation[relation],
166+
},
167+
}
168+
: {}),
169+
},
170+
}
151171
})
152172
}
153173

@@ -174,8 +194,7 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
174194

175195
if (hasMany) {
176196
const withSelection = Array.isArray(value) ? value : []
177-
withSelection.push(formattedSelection)
178-
setValue(withSelection)
197+
setValue([...withSelection, formattedSelection])
179198
} else {
180199
setValue(formattedSelection)
181200
}

test/fields/collections/Relationship/e2e.spec.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,15 @@ describe('relationship', () => {
742742
await expect(listDrawerContent).toBeHidden()
743743

744744
const selectedValue = relationshipField.locator('.relationship--multi-value-label__text')
745-
await expect(selectedValue).toBeVisible()
745+
await expect(selectedValue).toHaveCount(1)
746+
747+
await relationshipField.click()
748+
await expect(listDrawerContent).toBeVisible()
749+
await button.click()
750+
await expect(listDrawerContent).toBeHidden()
751+
752+
const selectedValues = relationshipField.locator('.relationship--multi-value-label__text')
753+
await expect(selectedValues).toHaveCount(2)
746754
})
747755

748756
test('should handle `hasMany` polymorphic relationship when `appearance: "drawer"`', async () => {
@@ -807,6 +815,42 @@ describe('relationship', () => {
807815
await expect(newRows).toHaveCount(1)
808816
await expect(listDrawerContent.getByText('Seeded text document')).toHaveCount(0)
809817
})
818+
819+
test('should filter out existing values from polymorphic relationship list drawer', async () => {
820+
await page.goto(url.create)
821+
const relationshipField = page.locator('#field-polymorphicRelationshipDrawer')
822+
await relationshipField.click()
823+
const listDrawerContent = page.locator('.list-drawer').locator('.drawer__content')
824+
await expect(listDrawerContent).toBeVisible()
825+
826+
const relationToSelector = page.locator('.list-header__select-collection')
827+
await expect(relationToSelector).toBeVisible()
828+
829+
await relationToSelector.locator('.rs__control').click()
830+
const option = relationToSelector.locator('.rs__option').nth(1)
831+
await option.click()
832+
const rows = listDrawerContent.locator('table tbody tr')
833+
await expect(rows).toHaveCount(2)
834+
const firstRow = rows.first()
835+
const button = firstRow.locator('button')
836+
await button.click()
837+
await expect(listDrawerContent).toBeHidden()
838+
839+
const selectedValue = relationshipField.locator('.relationship--single-value__text')
840+
await expect(selectedValue).toBeVisible()
841+
842+
await relationshipField.click()
843+
await expect(listDrawerContent).toBeVisible()
844+
await expect(relationToSelector).toBeVisible()
845+
await relationToSelector.locator('.rs__control').click()
846+
await option.click()
847+
const newRows = listDrawerContent.locator('table tbody tr')
848+
await expect(newRows).toHaveCount(1)
849+
const newFirstRow = newRows.first()
850+
const newButton = newFirstRow.locator('button')
851+
await newButton.click()
852+
await expect(listDrawerContent).toBeHidden()
853+
})
810854
})
811855

812856
async function createTextFieldDoc(overrides?: Partial<TextField>): Promise<TextField> {

test/fields/collections/Relationship/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ const RelationshipFields: CollectionConfig = {
158158
},
159159
{
160160
name: 'relationshipDrawerHasManyPolymorphic',
161-
relationTo: ['text-fields'],
161+
relationTo: ['text-fields', 'array-fields'],
162162
admin: {
163163
appearance: 'drawer',
164164
},

0 commit comments

Comments
 (0)