feat(ui): allow array fields to be filtered in list view (#11925)
### What? Allows array fields to be filtered in the list view. ### Why? Array fields were not filterable in the list view although all other field types were filterable already. ### How? Adds handling for array fields as filter option. 
This commit is contained in:
19
test/admin/collections/Array.ts
Normal file
19
test/admin/collections/Array.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { CollectionConfig } from 'payload'
|
||||
|
||||
import { arrayCollectionSlug } from '../slugs.js'
|
||||
|
||||
export const Array: CollectionConfig = {
|
||||
slug: arrayCollectionSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'array',
|
||||
type: 'array',
|
||||
fields: [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import path from 'path'
|
||||
const filename = fileURLToPath(import.meta.url)
|
||||
const dirname = path.dirname(filename)
|
||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||
import { Array } from './collections/Array.js'
|
||||
import { BaseListFilter } from './collections/BaseListFilter.js'
|
||||
import { CustomFields } from './collections/CustomFields/index.js'
|
||||
import { CustomViews1 } from './collections/CustomViews1.js'
|
||||
@@ -158,6 +159,7 @@ export default buildConfigWithDefaults({
|
||||
CollectionGroup2A,
|
||||
CollectionGroup2B,
|
||||
Geo,
|
||||
Array,
|
||||
DisableDuplicate,
|
||||
DisableCopyToLocale,
|
||||
BaseListFilter,
|
||||
|
||||
@@ -17,6 +17,7 @@ import { AdminUrlUtil } from '../../../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../../../helpers/initPayloadE2ENoConfig.js'
|
||||
import { customAdminRoutes } from '../../shared.js'
|
||||
import {
|
||||
arrayCollectionSlug,
|
||||
customViews1CollectionSlug,
|
||||
geoCollectionSlug,
|
||||
listDrawerSlug,
|
||||
@@ -57,6 +58,7 @@ const dirname = path.resolve(currentFolder, '../../')
|
||||
describe('List View', () => {
|
||||
let page: Page
|
||||
let geoUrl: AdminUrlUtil
|
||||
let arrayUrl: AdminUrlUtil
|
||||
let postsUrl: AdminUrlUtil
|
||||
let baseListFiltersUrl: AdminUrlUtil
|
||||
let customViewsUrl: AdminUrlUtil
|
||||
@@ -79,6 +81,7 @@ describe('List View', () => {
|
||||
}))
|
||||
|
||||
geoUrl = new AdminUrlUtil(serverURL, geoCollectionSlug)
|
||||
arrayUrl = new AdminUrlUtil(serverURL, arrayCollectionSlug)
|
||||
postsUrl = new AdminUrlUtil(serverURL, postsCollectionSlug)
|
||||
with300DocumentsUrl = new AdminUrlUtil(serverURL, with300DocumentsSlug)
|
||||
baseListFiltersUrl = new AdminUrlUtil(serverURL, 'base-list-filters')
|
||||
@@ -389,6 +392,32 @@ describe('List View', () => {
|
||||
await expect(page.locator(tableRowLocator)).toHaveCount(2)
|
||||
})
|
||||
|
||||
test('should allow to filter in array field', async () => {
|
||||
await createArray()
|
||||
|
||||
await page.goto(arrayUrl.list)
|
||||
await expect(page.locator(tableRowLocator)).toHaveCount(1)
|
||||
|
||||
await addListFilter({
|
||||
page,
|
||||
fieldLabel: 'Array > Text',
|
||||
operatorLabel: 'equals',
|
||||
value: 'test',
|
||||
})
|
||||
|
||||
await expect(page.locator(tableRowLocator)).toHaveCount(1)
|
||||
|
||||
await page.locator('.condition__actions .btn.condition__actions-remove').click()
|
||||
await addListFilter({
|
||||
page,
|
||||
fieldLabel: 'Array > Text',
|
||||
operatorLabel: 'equals',
|
||||
value: 'not-matching',
|
||||
})
|
||||
|
||||
await expect(page.locator(tableRowLocator)).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('should reset filter value when a different field is selected', async () => {
|
||||
const id = (await page.locator('.cell-id').first().innerText()).replace('ID: ', '')
|
||||
|
||||
@@ -1405,3 +1434,12 @@ async function createGeo(overrides?: Partial<Geo>): Promise<Geo> {
|
||||
},
|
||||
}) as unknown as Promise<Geo>
|
||||
}
|
||||
|
||||
async function createArray() {
|
||||
return payload.create({
|
||||
collection: arrayCollectionSlug,
|
||||
data: {
|
||||
array: [{ text: 'test' }],
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ export interface Config {
|
||||
'group-two-collection-ones': GroupTwoCollectionOne;
|
||||
'group-two-collection-twos': GroupTwoCollectionTwo;
|
||||
geo: Geo;
|
||||
array: Array;
|
||||
'disable-duplicate': DisableDuplicate;
|
||||
'disable-copy-to-locale': DisableCopyToLocale;
|
||||
'base-list-filters': BaseListFilter;
|
||||
@@ -108,6 +109,7 @@ export interface Config {
|
||||
'group-two-collection-ones': GroupTwoCollectionOnesSelect<false> | GroupTwoCollectionOnesSelect<true>;
|
||||
'group-two-collection-twos': GroupTwoCollectionTwosSelect<false> | GroupTwoCollectionTwosSelect<true>;
|
||||
geo: GeoSelect<false> | GeoSelect<true>;
|
||||
array: ArraySelect<false> | ArraySelect<true>;
|
||||
'disable-duplicate': DisableDuplicateSelect<false> | DisableDuplicateSelect<true>;
|
||||
'disable-copy-to-locale': DisableCopyToLocaleSelect<false> | DisableCopyToLocaleSelect<true>;
|
||||
'base-list-filters': BaseListFiltersSelect<false> | BaseListFiltersSelect<true>;
|
||||
@@ -414,6 +416,21 @@ export interface Geo {
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "array".
|
||||
*/
|
||||
export interface Array {
|
||||
id: string;
|
||||
array?:
|
||||
| {
|
||||
text?: string | null;
|
||||
id?: string | null;
|
||||
}[]
|
||||
| null;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "disable-duplicate".
|
||||
@@ -534,6 +551,10 @@ export interface PayloadLockedDocument {
|
||||
relationTo: 'geo';
|
||||
value: string | Geo;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'array';
|
||||
value: string | Array;
|
||||
} | null)
|
||||
| ({
|
||||
relationTo: 'disable-duplicate';
|
||||
value: string | DisableDuplicate;
|
||||
@@ -818,6 +839,20 @@ export interface GeoSelect<T extends boolean = true> {
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "array_select".
|
||||
*/
|
||||
export interface ArraySelect<T extends boolean = true> {
|
||||
array?:
|
||||
| T
|
||||
| {
|
||||
text?: T;
|
||||
id?: T;
|
||||
};
|
||||
updatedAt?: T;
|
||||
createdAt?: T;
|
||||
}
|
||||
/**
|
||||
* This interface was referenced by `Config`'s JSON-Schema
|
||||
* via the `definition` "disable-duplicate_select".
|
||||
|
||||
@@ -2,6 +2,7 @@ export const usersCollectionSlug = 'users'
|
||||
export const customViews1CollectionSlug = 'custom-views-one'
|
||||
export const customViews2CollectionSlug = 'custom-views-two'
|
||||
export const geoCollectionSlug = 'geo'
|
||||
export const arrayCollectionSlug = 'array'
|
||||
export const postsCollectionSlug = 'posts'
|
||||
export const group1Collection1Slug = 'group-one-collection-ones'
|
||||
export const group1Collection2Slug = 'group-one-collection-twos'
|
||||
@@ -23,6 +24,7 @@ export const collectionSlugs = [
|
||||
customViews1CollectionSlug,
|
||||
customViews2CollectionSlug,
|
||||
geoCollectionSlug,
|
||||
arrayCollectionSlug,
|
||||
postsCollectionSlug,
|
||||
group1Collection1Slug,
|
||||
group1Collection2Slug,
|
||||
|
||||
Reference in New Issue
Block a user