Skip to content

fix(ui): relationship using list drawer correctly updates when hasMany is true #12176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions packages/ui/src/fields/Relationship/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,38 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
let newFilterOptions = filterOptions

if (value) {
;(Array.isArray(value) ? value : [value]).forEach((val) => {
;(Array.isArray(relationTo) ? relationTo : [relationTo]).forEach((relationTo) => {
newFilterOptions = {
...(filterOptions || {}),
[relationTo]: {
...(typeof filterOptions?.[relationTo] === 'object' ? filterOptions[relationTo] : {}),
id: {
not_in: [typeof val === 'object' ? val.value : val],
},
},
const valuesByRelation = (Array.isArray(value) ? value : [value]).reduce((acc, val) => {
if (typeof val === 'object' && val.relationTo) {
if (!acc[val.relationTo]) {
acc[val.relationTo] = []
}
})
acc[val.relationTo].push(val.value)
} else if (val) {
const relation = Array.isArray(relationTo) ? undefined : relationTo
if (relation) {
if (!acc[relation]) {
acc[relation] = []
}
acc[relation].push(val)
}
}
return acc
}, {})

;(Array.isArray(relationTo) ? relationTo : [relationTo]).forEach((relation) => {
newFilterOptions = {
...(newFilterOptions || {}),
[relation]: {
...(typeof filterOptions?.[relation] === 'object' ? filterOptions[relation] : {}),
...(valuesByRelation[relation]
? {
id: {
not_in: valuesByRelation[relation],
},
}
: {}),
},
}
})
}

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

if (hasMany) {
const withSelection = Array.isArray(value) ? value : []
withSelection.push(formattedSelection)
setValue(withSelection)
setValue([...withSelection, formattedSelection])
} else {
setValue(formattedSelection)
}
Expand Down
46 changes: 45 additions & 1 deletion test/fields/collections/Relationship/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,15 @@ describe('relationship', () => {
await expect(listDrawerContent).toBeHidden()

const selectedValue = relationshipField.locator('.relationship--multi-value-label__text')
await expect(selectedValue).toBeVisible()
await expect(selectedValue).toHaveCount(1)

await relationshipField.click()
await expect(listDrawerContent).toBeVisible()
await button.click()
await expect(listDrawerContent).toBeHidden()

const selectedValues = relationshipField.locator('.relationship--multi-value-label__text')
await expect(selectedValues).toHaveCount(2)
})

test('should handle `hasMany` polymorphic relationship when `appearance: "drawer"`', async () => {
Expand Down Expand Up @@ -807,6 +815,42 @@ describe('relationship', () => {
await expect(newRows).toHaveCount(1)
await expect(listDrawerContent.getByText('Seeded text document')).toHaveCount(0)
})

test('should filter out existing values from polymorphic relationship list drawer', async () => {
await page.goto(url.create)
const relationshipField = page.locator('#field-polymorphicRelationshipDrawer')
await relationshipField.click()
const listDrawerContent = page.locator('.list-drawer').locator('.drawer__content')
await expect(listDrawerContent).toBeVisible()

const relationToSelector = page.locator('.list-header__select-collection')
await expect(relationToSelector).toBeVisible()

await relationToSelector.locator('.rs__control').click()
const option = relationToSelector.locator('.rs__option').nth(1)
await option.click()
const rows = listDrawerContent.locator('table tbody tr')
await expect(rows).toHaveCount(2)
const firstRow = rows.first()
const button = firstRow.locator('button')
await button.click()
await expect(listDrawerContent).toBeHidden()

const selectedValue = relationshipField.locator('.relationship--single-value__text')
await expect(selectedValue).toBeVisible()

await relationshipField.click()
await expect(listDrawerContent).toBeVisible()
await expect(relationToSelector).toBeVisible()
await relationToSelector.locator('.rs__control').click()
await option.click()
const newRows = listDrawerContent.locator('table tbody tr')
await expect(newRows).toHaveCount(1)
const newFirstRow = newRows.first()
const newButton = newFirstRow.locator('button')
await newButton.click()
await expect(listDrawerContent).toBeHidden()
})
})

async function createTextFieldDoc(overrides?: Partial<TextField>): Promise<TextField> {
Expand Down
2 changes: 1 addition & 1 deletion test/fields/collections/Relationship/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ const RelationshipFields: CollectionConfig = {
},
{
name: 'relationshipDrawerHasManyPolymorphic',
relationTo: ['text-fields'],
relationTo: ['text-fields', 'array-fields'],
admin: {
appearance: 'drawer',
},
Expand Down
Loading