fix(ui): populate nested fields for enableListViewSelectAPI (#13827)
Fixes an issue with the new experimental `enableListViewSelectAPI`
config option.
Group fields were not populating properly in the list view
### Before (incorrect)
```ts
{
group.field: true
}
```
### After (correct)
```ts
{
group: {
field: true
}
}
```
This commit is contained in:
@@ -21,5 +21,15 @@ export const ListViewSelectAPI: CollectionConfig = {
|
||||
name: 'description',
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
name: 'groupNameField',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ let payload: PayloadTestSDK<Config>
|
||||
|
||||
import { listViewSelectAPISlug } from 'admin/collections/ListViewSelectAPI/index.js'
|
||||
import { devUser } from 'credentials.js'
|
||||
import { getRowByCellValueAndAssert } from 'helpers/e2e/getRowByCellValueAndAssert.js'
|
||||
import {
|
||||
openListColumns,
|
||||
reorderColumns,
|
||||
@@ -993,58 +994,101 @@ describe('List View', () => {
|
||||
await toggleColumn(page, { columnLabel: 'ID', columnName: 'id', targetState: 'off' })
|
||||
})
|
||||
|
||||
test('should use select API in the list view when `enableListViewSelectAPI` is true', async () => {
|
||||
const doc = await payload.create({
|
||||
collection: listViewSelectAPISlug,
|
||||
data: {
|
||||
title: 'This is a test title',
|
||||
description: 'This is a test description',
|
||||
},
|
||||
describe('enableListViewSelectAPI', () => {
|
||||
test('`id` should always be selected even when toggled off', async () => {
|
||||
const doc = await payload.create({
|
||||
collection: listViewSelectAPISlug,
|
||||
data: {
|
||||
title: 'This is a test title',
|
||||
description: 'This is a test description',
|
||||
},
|
||||
})
|
||||
|
||||
const selectAPIUrl = new AdminUrlUtil(serverURL, listViewSelectAPISlug)
|
||||
|
||||
await page.goto(selectAPIUrl.list)
|
||||
|
||||
const printedResults = page.locator('#table-state')
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const resultText = await printedResults.innerText()
|
||||
const parsedResult = JSON.parse(resultText)
|
||||
return Boolean(parsedResult[0].id && parsedResult[0].description)
|
||||
},
|
||||
{
|
||||
timeout: 3000,
|
||||
intervals: [100, 250, 500, 1000],
|
||||
},
|
||||
)
|
||||
.toBeTruthy()
|
||||
|
||||
await toggleColumn(page, { columnLabel: 'ID', columnName: 'id', targetState: 'off' })
|
||||
|
||||
await toggleColumn(page, {
|
||||
columnLabel: 'Description',
|
||||
columnName: 'description',
|
||||
targetState: 'off',
|
||||
})
|
||||
|
||||
// Poll until the "description" field is removed from the response BUT `id` is still present
|
||||
// The `id` field will remain selected despite it being inactive
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const resultText = await printedResults.innerText()
|
||||
const parsedResult = JSON.parse(resultText)
|
||||
return Boolean(parsedResult[0].description === undefined && parsedResult[0].id)
|
||||
},
|
||||
{
|
||||
timeout: 3000,
|
||||
intervals: [100, 250, 500, 1000],
|
||||
},
|
||||
)
|
||||
.toBeTruthy()
|
||||
})
|
||||
|
||||
const selectAPIUrl = new AdminUrlUtil(serverURL, listViewSelectAPISlug)
|
||||
|
||||
await page.goto(selectAPIUrl.list)
|
||||
|
||||
const printedResults = page.locator('#table-state')
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const resultText = await printedResults.innerText()
|
||||
const parsedResult = JSON.parse(resultText)
|
||||
return Boolean(parsedResult[0].id && parsedResult[0].description)
|
||||
test('group fields should populate with the select API', async () => {
|
||||
const doc = await payload.create({
|
||||
collection: listViewSelectAPISlug,
|
||||
data: {
|
||||
title: 'This is a test title',
|
||||
description: 'This is a test description',
|
||||
group: {
|
||||
groupNameField: 'Select Nested Field',
|
||||
},
|
||||
},
|
||||
{
|
||||
timeout: 3000,
|
||||
intervals: [100, 250, 500, 1000],
|
||||
},
|
||||
)
|
||||
.toBeTruthy()
|
||||
})
|
||||
|
||||
await toggleColumn(page, { columnLabel: 'ID', columnName: 'id', targetState: 'off' })
|
||||
const selectAPIUrl = new AdminUrlUtil(serverURL, listViewSelectAPISlug)
|
||||
|
||||
await toggleColumn(page, {
|
||||
columnLabel: 'Description',
|
||||
columnName: 'description',
|
||||
targetState: 'off',
|
||||
await page.goto(selectAPIUrl.list)
|
||||
|
||||
await toggleColumn(page, {
|
||||
columnLabel: 'Group > Group Name Field',
|
||||
columnName: 'group.groupNameField',
|
||||
targetState: 'off',
|
||||
})
|
||||
|
||||
await toggleColumn(page, {
|
||||
columnLabel: 'Group > Group Name Field',
|
||||
columnName: 'group.groupNameField',
|
||||
targetState: 'on',
|
||||
})
|
||||
|
||||
await getRowByCellValueAndAssert({
|
||||
cellClass: `.cell-group__groupNameField`,
|
||||
page,
|
||||
textToMatch: 'Select Nested Field',
|
||||
})
|
||||
|
||||
// cleanup after run
|
||||
await payload.delete({
|
||||
id: doc.id,
|
||||
collection: listViewSelectAPISlug,
|
||||
})
|
||||
})
|
||||
|
||||
// Poll until the "description" field is removed from the response BUT `id` is still present
|
||||
// The `id` field will remain selected despite it being inactive
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const resultText = await printedResults.innerText()
|
||||
const parsedResult = JSON.parse(resultText)
|
||||
return Boolean(parsedResult[0].description === undefined && parsedResult[0].id)
|
||||
},
|
||||
{
|
||||
timeout: 3000,
|
||||
intervals: [100, 250, 500, 1000],
|
||||
},
|
||||
)
|
||||
.toBeTruthy()
|
||||
})
|
||||
|
||||
test('should toggle columns and save to preferences', async () => {
|
||||
|
||||
@@ -594,6 +594,9 @@ export interface ListViewSelectApi {
|
||||
id: string;
|
||||
title?: string | null;
|
||||
description?: string | null;
|
||||
group?: {
|
||||
groupNameField?: string | null;
|
||||
};
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -1153,6 +1156,11 @@ export interface CustomListDrawerSelect<T extends boolean = true> {
|
||||
export interface ListViewSelectApiSelect<T extends boolean = true> {
|
||||
title?: T;
|
||||
description?: T;
|
||||
group?:
|
||||
| T
|
||||
| {
|
||||
groupNameField?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ export const testEslintConfig = [
|
||||
'createFolderFromDoc',
|
||||
'assertURLParams',
|
||||
'uploadImage',
|
||||
'getRowByCellValueAndAssert',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
23
test/helpers/e2e/getRowByCellValueAndAssert.ts
Normal file
23
test/helpers/e2e/getRowByCellValueAndAssert.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
export async function getRowByCellValueAndAssert({
|
||||
page,
|
||||
textToMatch,
|
||||
cellClass,
|
||||
}: {
|
||||
cellClass: `.cell-${string}`
|
||||
page: Page
|
||||
textToMatch: string
|
||||
}): Promise<Locator> {
|
||||
const row = page
|
||||
.locator(`.collection-list .table tr`)
|
||||
.filter({
|
||||
has: page.locator(`${cellClass}`, { hasText: textToMatch }),
|
||||
})
|
||||
.first()
|
||||
|
||||
await expect(row).toBeVisible()
|
||||
return row
|
||||
}
|
||||
@@ -2,6 +2,8 @@ import type { Page } from '@playwright/test'
|
||||
|
||||
import type { AdminUrlUtil } from '../../helpers/adminUrlUtil.js'
|
||||
|
||||
import { getRowByCellValueAndAssert } from './getRowByCellValueAndAssert.js'
|
||||
|
||||
export async function goToListDoc({
|
||||
page,
|
||||
cellClass,
|
||||
@@ -14,12 +16,7 @@ export async function goToListDoc({
|
||||
urlUtil: AdminUrlUtil
|
||||
}) {
|
||||
await page.goto(urlUtil.list)
|
||||
const row = page
|
||||
.locator(`.collection-list .table tr`)
|
||||
.filter({
|
||||
has: page.locator(`${cellClass}`, { hasText: textToMatch }),
|
||||
})
|
||||
.first()
|
||||
const row = await getRowByCellValueAndAssert({ page, textToMatch, cellClass })
|
||||
const cellLink = row.locator(`td a`).first()
|
||||
const linkURL = await cellLink.getAttribute('href')
|
||||
await page.goto(`${urlUtil.serverURL}${linkURL}`)
|
||||
|
||||
Reference in New Issue
Block a user