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>
55 lines
1.5 KiB
TypeScript
55 lines
1.5 KiB
TypeScript
import type { Page } from '@playwright/test'
|
|
|
|
import { expect } from '@playwright/test'
|
|
import { exactText } from 'helpers.js'
|
|
import { TEST_TIMEOUT_LONG } from 'playwright.config.js'
|
|
|
|
import { openQueryPresetDrawer } from './openQueryPresetDrawer.js'
|
|
|
|
export async function selectPreset({ page, presetTitle }: { page: Page; presetTitle: string }) {
|
|
await openQueryPresetDrawer({ page })
|
|
const modal = page.locator('[id^=list-drawer_0_]')
|
|
await expect(modal).toBeVisible()
|
|
|
|
const currentURL = page.url()
|
|
|
|
await modal
|
|
.locator('tbody tr td button', {
|
|
hasText: exactText(presetTitle),
|
|
})
|
|
.first()
|
|
.click()
|
|
|
|
await page.waitForURL(() => page.url() !== currentURL)
|
|
|
|
await expect(
|
|
page.locator('button#select-preset', {
|
|
hasText: exactText(presetTitle),
|
|
}),
|
|
).toBeVisible()
|
|
}
|
|
|
|
export async function clearSelectedPreset({ page }: { page: Page }) {
|
|
const queryPresetsControl = page.locator('button#select-preset')
|
|
const clearButton = queryPresetsControl.locator('#clear-preset')
|
|
|
|
if (await clearButton.isVisible()) {
|
|
await clearButton.click()
|
|
}
|
|
|
|
// columns can either be omitted or an empty string after being cleared
|
|
const regex = /columns=(?:\[\]|$)/
|
|
|
|
await page.waitForURL((url) => !regex.test(url.search), {
|
|
timeout: TEST_TIMEOUT_LONG,
|
|
})
|
|
|
|
await expect(queryPresetsControl.locator('#clear-preset')).toBeHidden()
|
|
|
|
await expect(
|
|
page.locator('button#select-preset', {
|
|
hasText: exactText('Select Preset'),
|
|
}),
|
|
).toBeVisible()
|
|
}
|