feat: adds disableGroupBy to fields admin props (#14017)

### What?

Adds a new `disableGroupBy` admin config property for fields to control
their visibility in the list view GroupBy dropdown.

### Why

Previously, the GroupByBuilder was incorrectly using `disableListFilter`
to determine which fields to show in the group-by dropdown.

### How

- Added new `disableGroupBy` property to the field admin config types.
- Updated `GroupByBuilder` to filter fields based on `disableGroupBy`
instead of `disableListFilter`

---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
  - https://app.asana.com/0/0/1211511898438807
This commit is contained in:
Patrik
2025-10-02 09:22:32 -04:00
committed by GitHub
parent ef57d24200
commit 537f58b4bc
11 changed files with 62 additions and 9 deletions

View File

@@ -616,8 +616,9 @@ The following options are available:
| **`readOnly`** | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. | | **`readOnly`** | Setting a field to `readOnly` has no effect on the API whatsoever but disables the admin component's editability to prevent editors from modifying the field's value. |
| **`disabled`** | If a field is `disabled`, it is completely omitted from the [Admin Panel](../admin/overview) entirely. | | **`disabled`** | If a field is `disabled`, it is completely omitted from the [Admin Panel](../admin/overview) entirely. |
| **`disableBulkEdit`** | Set `disableBulkEdit` to `true` to prevent fields from appearing in the select options when making edits for multiple documents. Defaults to `true` for UI fields. | | **`disableBulkEdit`** | Set `disableBulkEdit` to `true` to prevent fields from appearing in the select options when making edits for multiple documents. Defaults to `true` for UI fields. |
| **`disableListColumn`** | Set `disableListColumn` to `true` to prevent fields from appearing in the list view column selector. | | **`disableGroupBy`** | Set `disableGroupBy` to `true` to prevent fields from appearing in the list view groupBy options. Defaults to `false`. |
| **`disableListFilter`** | Set `disableListFilter` to `true` to prevent fields from appearing in the list view filter options. | | **`disableListColumn`** | Set `disableListColumn` to `true` to prevent fields from appearing in the list view column selector. Defaults to `false`. |
| **`disableListFilter`** | Set `disableListFilter` to `true` to prevent fields from appearing in the list view filter options. Defaults to `false`. |
| **`hidden`** | Will transform the field into a `hidden` input type. Its value will still submit with requests in the Admin Panel, but the field itself will not be visible to editors. | | **`hidden`** | Will transform the field into a `hidden` input type. Its value will still submit with requests in the Admin Panel, but the field itself will not be visible to editors. |
### Field Descriptions ### Field Descriptions

View File

@@ -202,16 +202,18 @@ Each image size also supports `admin` options to control whether it appears in t
width: 400, width: 400,
height: 300, height: 300,
admin: { admin: {
disableGroupBy: true, // hide from list view groupBy options
disableListColumn: true, // hide from list view columns disableListColumn: true, // hide from list view columns
disableListFilter: true, // hide from list view filters disableListFilter: true, // hide from list view filters
}, },
} }
``` ```
| Option | Description | | Option | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **`disableListColumn`** | If set to `true`, this image size will not be available as a selectable column in the collection list view. Defaults to `false`. | | **`disableGroupBy`** | If set to `true`, this image size will not be available as a selectable groupBy option in the collection list view. Defaults to `false`. |
| **`disableListFilter`** | If set to `true`, this image size will not be available as a filter option in the collection list view. Defaults to `false`. | | **`disableListColumn`** | If set to `true`, this image size will not be available as a selectable column in the collection list view. Defaults to `false`. |
| **`disableListFilter`** | If set to `true`, this image size will not be available as a filter option in the collection list view. Defaults to `false`. |
This is useful for hiding large or rarely used image sizes from the list view UI while still keeping them available in the API. This is useful for hiding large or rarely used image sizes from the list view UI while still keeping them available in the API.

View File

@@ -89,6 +89,7 @@ export const addOrderableFieldsAndHook = (
admin: { admin: {
disableBulkEdit: true, disableBulkEdit: true,
disabled: true, disabled: true,
disableGroupBy: true,
disableListColumn: true, disableListColumn: true,
disableListFilter: true, disableListFilter: true,
hidden: true, hidden: true,

View File

@@ -366,6 +366,11 @@ type Admin = {
description?: Description description?: Description
disableBulkEdit?: boolean disableBulkEdit?: boolean
disabled?: boolean disabled?: boolean
/**
* Shows / hides fields from appearing in the list view groupBy options.
* @type boolean
*/
disableGroupBy?: boolean
/** /**
* Shows / hides fields from appearing in the list view column selector. * Shows / hides fields from appearing in the list view column selector.
* @type boolean * @type boolean
@@ -390,6 +395,11 @@ export type AdminClient = {
description?: StaticDescription description?: StaticDescription
disableBulkEdit?: boolean disableBulkEdit?: boolean
disabled?: boolean disabled?: boolean
/**
* Shows / hides fields from appearing in the list view groupBy options.
* @type boolean
*/
disableGroupBy?: boolean
/** /**
* Shows / hides fields from appearing in the list view column selector. * Shows / hides fields from appearing in the list view column selector.
* @type boolean * @type boolean

View File

@@ -170,6 +170,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
name, name,
type: 'number', type: 'number',
admin: { admin: {
disableGroupBy: true,
disableListColumn: true, disableListColumn: true,
disableListFilter: true, disableListFilter: true,
hidden: true, hidden: true,
@@ -184,7 +185,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
} }
// In Payload v4, image size subfields (`url`, `width`, `height`, etc.) should // In Payload v4, image size subfields (`url`, `width`, `height`, etc.) should
// default to `disableListColumn: true` and `disableListFilter: true` // default to `disableGroupBy: true`, `disableListColumn: true` and `disableListFilter: true`
// to avoid cluttering the collection list view and filters by default. // to avoid cluttering the collection list view and filters by default.
if (uploadOptions.imageSizes) { if (uploadOptions.imageSizes) {
uploadFields = uploadFields.concat([ uploadFields = uploadFields.concat([
@@ -199,6 +200,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
type: 'group', type: 'group',
admin: { admin: {
hidden: true, hidden: true,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },
@@ -207,6 +209,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
...url, ...url,
admin: { admin: {
...url.admin, ...url.admin,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },
@@ -232,6 +235,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
...width, ...width,
admin: { admin: {
...width.admin, ...width.admin,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },
@@ -240,6 +244,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
...height, ...height,
admin: { admin: {
...height.admin, ...height.admin,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },
@@ -248,6 +253,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
...mimeType, ...mimeType,
admin: { admin: {
...mimeType.admin, ...mimeType.admin,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },
@@ -256,6 +262,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
...filesize, ...filesize,
admin: { admin: {
...filesize.admin, ...filesize.admin,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },
@@ -264,6 +271,7 @@ export const getBaseUploadFields = ({ collection, config }: Options): Field[] =>
...filename, ...filename,
admin: { admin: {
...filename.admin, ...filename.admin,
...(size.admin?.disableGroupBy && { disableGroupBy: true }),
...(size.admin?.disableListColumn && { disableListColumn: true }), ...(size.admin?.disableListColumn && { disableListColumn: true }),
...(size.admin?.disableListFilter && { disableListFilter: true }), ...(size.admin?.disableListFilter && { disableListFilter: true }),
}, },

View File

@@ -72,11 +72,17 @@ export type ImageSize = {
/** /**
* Admin UI options that control how this image size appears in list views. * Admin UI options that control how this image size appears in list views.
* *
* NOTE: In Payload v4, these options (`disableListColumn`, `disableListFilter`) * NOTE: In Payload v4, these options (`disableGroupBy`, `disableListColumn` and `disableListFilter`)
* should default to `true` so image size subfields are hidden from list columns * should default to `true` so image size subfields are hidden from list columns
* and filters by default, reducing noise in the admin UI. * and filters by default, reducing noise in the admin UI.
*/ */
admin?: { admin?: {
/**
* If set to true, this image size will not be available
* as a selectable groupBy option in the collection list view.
* @default false
*/
disableGroupBy?: boolean
/** /**
* If set to true, this image size will not be available * If set to true, this image size will not be available
* as a selectable column in the collection list view. * as a selectable column in the collection list view.

View File

@@ -51,6 +51,7 @@ export const tenantField = ({
admin: { admin: {
allowCreate: false, allowCreate: false,
allowEdit: false, allowEdit: false,
disableGroupBy: true,
disableListColumn: true, disableListColumn: true,
disableListFilter: true, disableListFilter: true,
position: 'sidebar', position: 'sidebar',

View File

@@ -101,7 +101,7 @@ export const GroupByBuilder: React.FC<Props> = ({ collectionSlug, fields }) => {
}} }}
options={reducedFields.filter( options={reducedFields.filter(
(field) => (field) =>
!field.field.admin.disableListFilter && !field.field.admin.disableGroupBy &&
field.value !== 'id' && field.value !== 'id' &&
supportedFieldTypes.includes(field.field.type), supportedFieldTypes.includes(field.field.type),
)} )}

View File

@@ -22,6 +22,14 @@ export const PostsCollection: CollectionConfig = {
type: 'relationship', type: 'relationship',
relationTo: categoriesSlug, relationTo: categoriesSlug,
}, },
{
name: 'virtualTitleFromCategory',
type: 'text',
virtual: 'category.title',
admin: {
disableGroupBy: true,
},
},
{ {
name: 'checkbox', name: 'checkbox',
type: 'checkbox', type: 'checkbox',

View File

@@ -804,6 +804,20 @@ test.describe('Group By', () => {
).toBeVisible() ).toBeVisible()
}) })
test('should hide field from groupBy options when admin.disableGroupBy is true', async () => {
await page.goto(url.list)
const { groupByContainer } = await openGroupBy(page)
const field = groupByContainer.locator('#group-by--field-select')
await field.click()
await expect(
field.locator('.rs__option', {
hasText: exactText('Virtual Title From Category'),
}),
).toBeHidden()
})
test.describe('Trash', () => { test.describe('Trash', () => {
test('should show trashed docs in trash view when group-by is active', async () => { test('should show trashed docs in trash view when group-by is active', async () => {
await page.goto(url.list) await page.goto(url.list)

View File

@@ -127,6 +127,7 @@ export interface Post {
id: string; id: string;
title?: string | null; title?: string | null;
category?: (string | null) | Category; category?: (string | null) | Category;
virtualTitleFromCategory?: string | null;
checkbox?: boolean | null; checkbox?: boolean | null;
date?: string | null; date?: string | null;
tab1Field?: string | null; tab1Field?: string | null;
@@ -321,6 +322,7 @@ export interface PayloadMigration {
export interface PostsSelect<T extends boolean = true> { export interface PostsSelect<T extends boolean = true> {
title?: T; title?: T;
category?: T; category?: T;
virtualTitleFromCategory?: T;
checkbox?: T; checkbox?: T;
date?: T; date?: T;
tab1Field?: T; tab1Field?: T;