Supports grouping documents by specific fields within the list view. For example, imagine having a "posts" collection with a "categories" field. To report on each specific category, you'd traditionally filter for each category, one at a time. This can be quite inefficient, especially with large datasets. Now, you can interact with all categories simultaneously, grouped by distinct values. Here is a simple demonstration: https://github.com/user-attachments/assets/0dcd19d2-e983-47e6-9ea2-cfdd2424d8b5 Enable on any collection by setting the `admin.groupBy` property: ```ts import type { CollectionConfig } from 'payload' const MyCollection: CollectionConfig = { // ... admin: { groupBy: true } } ``` This is currently marked as beta to gather feedback while we reach full stability, and to leave room for API changes and other modifications. Use at your own risk. Note: when using `groupBy`, bulk editing is done group-by-group. In the future we may support cross-group bulk editing. Dependent on #13102 (merged). --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1210774523852467 --------- Co-authored-by: Paul Popus <paul@payloadcms.com>
50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import type { Locator, Page } from '@playwright/test'
|
|
|
|
import { POLL_TOPASS_TIMEOUT } from 'playwright.config.js'
|
|
|
|
export const goToNextPage = async (
|
|
page: Page,
|
|
options: {
|
|
affectsURL?: boolean // if false, won't wait for URL change (useful for when pagination doesn't affect URL)
|
|
/**
|
|
* Scope the pagination to a specific selector. If not provided, will search the whole page for the controls.
|
|
*/
|
|
scope?: Locator
|
|
// defaults to 2, assuming you're on page 1
|
|
targetPage?: number
|
|
} = { targetPage: 2, affectsURL: true },
|
|
) => {
|
|
const pageControls = (options.scope || page).locator('.paginator')
|
|
await pageControls.locator('button').nth(1).click()
|
|
|
|
if (options.affectsURL) {
|
|
const regex = new RegExp(`page=${options.targetPage}(?:&|$)`)
|
|
await page.waitForURL(regex, { timeout: POLL_TOPASS_TIMEOUT })
|
|
}
|
|
}
|
|
|
|
export const goToPreviousPage = async (
|
|
page: Page,
|
|
options: {
|
|
affectsURL?: boolean // if false, won't wait for URL change (useful for when pagination doesn't affect URL)
|
|
/**
|
|
* Scope the pagination to a specific selector. If not provided, will search the whole page for the controls.
|
|
* This is useful when multiple pagination controls are displayed on the same page (e.g. group-by)
|
|
*/
|
|
scope?: Locator
|
|
// defaults to 1, assuming you're on page 2
|
|
targetPage?: number
|
|
} = {
|
|
targetPage: 1,
|
|
affectsURL: true,
|
|
},
|
|
) => {
|
|
const pageControls = (options.scope || page).locator('.paginator')
|
|
await pageControls.locator('button').nth(0).click()
|
|
|
|
if (options.affectsURL) {
|
|
const regex = new RegExp(`page=${options.targetPage}(?:&|$)`)
|
|
await page.waitForURL(regex, { timeout: POLL_TOPASS_TIMEOUT })
|
|
}
|
|
}
|