Skip to content

Commit cd546b3

Browse files
authored
feat(ui): add support for disabling join field row types (#12738)
### What? This PR adds a new `admin.disableRowTypes` config to `'join'` fields which hides the `"Type"` column from the relationship table. ### Why? While the collection type column _can be_ helpful for providing information, it's not always necessary and can sometimes be redundant when the field only has a singular relationTo. Hiding it can be helpful by removing visual noise and providing editors the data directly. ### How? By threading `admin.disableRowTypes` directly to the `getTableState` function of the `RelationshipTable` component. **With row types** (via `admin.disableRowTypes: false | undefined` OR default for polymorphic): ![image](https://github.com/user-attachments/assets/22b55477-cf56-4b0e-a845-e6f2b39efe3b) **Without row types** (default for monomorphic): ![image](https://github.com/user-attachments/assets/3a2bb0ba-2d5e-4299-8689-249b2d3fefe2)
1 parent 4b6b0c5 commit cd546b3

File tree

7 files changed

+94
-11
lines changed

7 files changed

+94
-11
lines changed

docs/fields/join.mdx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,12 @@ _\* An asterisk denotes that a property is required._
157157

158158
You can control the user experience of the join field using the `admin` config properties. The following options are supported:
159159

160-
| Option | Description |
161-
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------- |
162-
| **`defaultColumns`** | Array of field names that correspond to which columns to show in the relationship table. Default is the collection config. |
163-
| **`allowCreate`** | Set to `false` to remove the controls for making new related documents from this field. |
164-
| **`components.Label`** | Override the default Label of the Field Component. [More details](./overview#label) |
160+
| Option | Description |
161+
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
162+
| **`defaultColumns`** | Array of field names that correspond to which columns to show in the relationship table. Default is the collection config. |
163+
| **`allowCreate`** | Set to `false` to remove the controls for making new related documents from this field. |
164+
| **`components.Label`** | Override the default Label of the Field Component. [More details](./overview#label) |
165+
| **`disableRowTypes`** | Set to `false` to render row types, and `true` to hide them. Defaults to `false` for join fields with a singular `relationTo`, and `true` for join fields where `relationTo` is an array. |
165166

166167
## Join Field Data
167168

packages/payload/src/fields/config/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,6 +1628,7 @@ export type JoinField = {
16281628
} & Admin['components']
16291629
defaultColumns?: string[]
16301630
disableBulkEdit?: never
1631+
disableRowTypes?: boolean
16311632
readOnly?: never
16321633
} & Admin
16331634
/**
@@ -1679,8 +1680,11 @@ export type JoinField = {
16791680

16801681
export type JoinFieldClient = {
16811682
admin?: AdminClient &
1682-
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
1683-
Pick<JoinField['admin'], 'allowCreate' | 'defaultColumns' | 'disableBulkEdit' | 'readOnly'>
1683+
Pick<
1684+
JoinField['admin'],
1685+
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
1686+
'allowCreate' | 'defaultColumns' | 'disableBulkEdit' | 'disableRowTypes' | 'readOnly'
1687+
>
16841688
} & { targetField: Pick<RelationshipFieldClient, 'relationTo'> } & FieldBaseClient &
16851689
Pick<
16861690
JoinField,

packages/ui/src/elements/RelationshipTable/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
144144
}))
145145
: undefined
146146

147+
const renderRowTypes =
148+
typeof field.admin.disableRowTypes === 'boolean'
149+
? !field.admin.disableRowTypes
150+
: Array.isArray(relationTo)
151+
147152
const {
148153
data: newData,
149154
state: newColumnState,
@@ -159,7 +164,7 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
159164
: `_${field.collection}_${field.name}_order`,
160165
parent,
161166
query: newQuery,
162-
renderRowTypes: true,
167+
renderRowTypes,
163168
tableAppearance: 'condensed',
164169
})
165170

@@ -172,6 +177,7 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
172177
field.defaultLimit,
173178
field.defaultSort,
174179
field.admin.defaultColumns,
180+
field.admin.disableRowTypes,
175181
field.collection,
176182
field.name,
177183
field.orderable,

test/joins/collections/Categories.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ValidationError } from 'payload'
44

55
import { categoriesSlug, hiddenPostsSlug, postsSlug } from '../shared.js'
66
import { singularSlug } from './Singular.js'
7+
import { versionsSlug } from './Versions.js'
78

89
export const Categories: CollectionConfig = {
910
slug: categoriesSlug,
@@ -55,13 +56,22 @@ export const Categories: CollectionConfig = {
5556
beforeInput: ['/components/BeforeInput.js#BeforeInput'],
5657
Description: '/components/CustomDescription/index.js#FieldDescriptionComponent',
5758
},
59+
disableRowTypes: false,
5860
},
5961
collection: postsSlug,
6062
defaultSort: '-title',
6163
defaultLimit: 5,
6264
on: 'category',
6365
maxDepth: 1,
6466
},
67+
{
68+
name: 'noRowTypes',
69+
type: 'join',
70+
collection: postsSlug,
71+
defaultLimit: 5,
72+
on: 'category',
73+
maxDepth: 1,
74+
},
6575
{
6676
name: 'hasManyPosts',
6777
type: 'join',
@@ -95,6 +105,7 @@ export const Categories: CollectionConfig = {
95105
on: 'group.category',
96106
admin: {
97107
defaultColumns: ['id', 'createdAt', 'title'],
108+
disableRowTypes: false,
98109
},
99110
},
100111
{
@@ -129,6 +140,21 @@ export const Categories: CollectionConfig = {
129140
collection: 'posts',
130141
on: 'blocks.category',
131142
},
143+
{
144+
name: 'polymorphicJoin',
145+
type: 'join',
146+
collection: [postsSlug, versionsSlug],
147+
on: 'category',
148+
},
149+
{
150+
name: 'polymorphicJoinNoRowTypes',
151+
type: 'join',
152+
collection: [postsSlug, versionsSlug],
153+
on: 'category',
154+
admin: {
155+
disableRowTypes: true,
156+
},
157+
},
132158
{
133159
name: 'polymorphic',
134160
type: 'join',

test/joins/collections/Uploads.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export const Uploads: CollectionConfig = {
1515
type: 'join',
1616
collection: 'posts',
1717
on: 'upload',
18+
admin: {
19+
disableRowTypes: false,
20+
},
1821
},
1922
],
2023
upload: {

test/joins/config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ export default buildConfigWithDefaults({
277277
},
278278
],
279279
},
280-
281280
{
282281
slug: 'folders',
283282
fields: [

test/joins/e2e.spec.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ describe('Join Field', () => {
219219
await saveDocAndAssert(page)
220220
})
221221

222-
test('should render collection type in first column of relationship table', async () => {
222+
test('should render collection type in first column of relationship table when disableRowTypes false', async () => {
223223
await page.goto(categoriesURL.edit(categoryID))
224224
const joinField = page.locator('#field-relatedPosts.field-type.join')
225225
await expect(joinField).toBeVisible()
@@ -237,7 +237,51 @@ describe('Join Field', () => {
237237
}
238238
})
239239

240-
test('should render drawer toggler without document link in second column of relationship table', async () => {
240+
test('should hide collection type column of monomorphic relationship table by default', async () => {
241+
await page.goto(categoriesURL.edit(categoryID))
242+
const joinField = page.locator('#field-noRowTypes.field-type.join')
243+
const tableHeaderRow = joinField.locator('.table thead > tr')
244+
const firstColumnHeader = tableHeaderRow.locator('th').first()
245+
await expect(firstColumnHeader).toHaveId('heading-title')
246+
})
247+
248+
test('should render collection type in first column of polymorphic relationship table by default', async () => {
249+
await page.goto(categoriesURL.edit(categoryID))
250+
const joinField = page.locator('#field-polymorphicJoin.field-type.join')
251+
await expect(joinField).toBeVisible()
252+
const text = joinField.locator('thead tr th#heading-collection:first-child')
253+
await expect(text).toHaveText('Type')
254+
const cells = joinField.locator('.relationship-table tbody tr td:first-child .pill__label')
255+
256+
const count = await cells.count()
257+
258+
for (let i = 0; i < count; i++) {
259+
const element = cells.nth(i)
260+
// Perform actions on each element
261+
await expect(element).toBeVisible()
262+
await expect(element).toHaveText('Post')
263+
}
264+
})
265+
266+
test('should not render collection type in polymorphic relationship table with disableRowTypes true', async () => {
267+
await page.goto(categoriesURL.edit(categoryID))
268+
const joinField = page.locator('#field-polymorphicJoinNoRowTypes.field-type.join')
269+
await expect(joinField).toBeVisible()
270+
const text = joinField.locator('thead tr th#heading-title:first-child')
271+
await expect(text).toHaveText('Title')
272+
const cells = joinField.locator('.relationship-table tbody tr td:first-child .pill__label')
273+
274+
const count = await cells.count()
275+
276+
for (let i = 0; i < count; i++) {
277+
const element = cells.nth(i)
278+
// Perform actions on each element
279+
await expect(element).toBeVisible()
280+
await expect(element).toHaveText(/Test Post \d+/)
281+
}
282+
})
283+
284+
test('should render drawer toggler without document link in second column of relationship table with row types', async () => {
241285
await page.goto(categoriesURL.edit(categoryID))
242286
const joinField = page.locator('#field-relatedPosts.field-type.join')
243287
await expect(joinField).toBeVisible()

0 commit comments

Comments
 (0)