Skip to content

Commit

Permalink
fix(ui): join field ignoring defaultSort and defaultLimit (#9766)
Browse files Browse the repository at this point in the history
The join field was not respecting the defaultSort or defaultLimit of the
field configuration.

### Why?

This was never implemented.

### How?

This fix applies these correct limit and sort properties to the query,
first based on the field config and as a fallback, the collection
configuration.
  • Loading branch information
DanRibbens authored Dec 5, 2024
1 parent 19ddd3c commit a11243e
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 14 deletions.
4 changes: 2 additions & 2 deletions packages/payload/src/admin/functions/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ImportMap } from '../../bin/generateImportMap/index.js'
import type { SanitizedConfig } from '../../config/types.js'
import type { PaginatedDocs } from '../../database/types.js'
import type { PayloadRequest, Where } from '../../types/index.js'
import type { PayloadRequest, Sort, Where } from '../../types/index.js'

export type DefaultServerFunctionArgs = {
importMap: ImportMap
Expand Down Expand Up @@ -43,7 +43,7 @@ export type ListQuery = {
When provided, is automatically injected into the `where` object
*/
search?: string
sort?: string
sort?: Sort
where?: Where
}

Expand Down
5 changes: 4 additions & 1 deletion packages/payload/src/fields/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1410,7 +1410,10 @@ export type JoinField = {
export type JoinFieldClient = {
admin?: AdminClient & Pick<JoinField['admin'], 'allowCreate' | 'disableBulkEdit' | 'readOnly'>
} & FieldBaseClient &
Pick<JoinField, 'collection' | 'index' | 'maxDepth' | 'on' | 'type' | 'where'>
Pick<
JoinField,
'collection' | 'defaultLimit' | 'defaultSort' | 'index' | 'maxDepth' | 'on' | 'type' | 'where'
>

export type FlattenedBlock = {
flattenedFields: FlattenedField[]
Expand Down
18 changes: 16 additions & 2 deletions packages/ui/src/elements/RelationshipTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
allowCreate = true,
BeforeInput,
disableTable = false,
field,
filterOptions,
initialData: initialDataFromProps,
initialDrawerData,
Expand Down Expand Up @@ -104,6 +105,8 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
const renderTable = useCallback(
async (docs?: PaginatedDocs['docs']) => {
const newQuery: ListQuery = {
limit: String(field.defaultLimit || collectionConfig.admin.pagination.defaultLimit),
sort: field.defaultSort || collectionConfig.defaultSort,
...(query || {}),
where: { ...(query?.where || {}) },
}
Expand All @@ -130,7 +133,16 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
setColumnState(newColumnState)
setIsLoadingTable(false)
},
[getTableState, relationTo, filterOptions, query],
[
query,
field.defaultLimit,
field.defaultSort,
collectionConfig.admin.pagination.defaultLimit,
collectionConfig.defaultSort,
filterOptions,
getTableState,
relationTo,
],
)

useIgnoredEffect(
Expand Down Expand Up @@ -227,7 +239,9 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
<ListQueryProvider
collectionSlug={relationTo}
data={data}
defaultLimit={collectionConfig?.admin?.pagination?.defaultLimit}
defaultLimit={
field.defaultLimit ?? collectionConfig?.admin?.pagination?.defaultLimit
}
modifySearchParams={false}
onQueryChange={setQuery}
preferenceKey={preferenceKey}
Expand Down
13 changes: 8 additions & 5 deletions packages/ui/src/providers/ListQuery/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client'
import type { ListQuery, PaginatedDocs, Where } from 'payload'
import type { ListQuery, PaginatedDocs, Sort, Where } from 'payload'

import { useRouter, useSearchParams } from 'next/navigation.js'
import { isNumber } from 'payload/shared'
Expand Down Expand Up @@ -27,7 +27,7 @@ export type ListQueryProps = {
readonly collectionSlug: string
readonly data: PaginatedDocs
readonly defaultLimit?: number
readonly defaultSort?: string
readonly defaultSort?: Sort
readonly modifySearchParams?: boolean
readonly onQueryChange?: (query: ListQuery) => void
readonly preferenceKey?: string
Expand All @@ -36,7 +36,7 @@ export type ListQueryProps = {
export type ListQueryContext = {
data: PaginatedDocs
defaultLimit?: number
defaultSort?: string
defaultSort?: Sort
query: ListQuery
refineListData: (args: ListQuery) => Promise<void>
} & ContextHandlers
Expand Down Expand Up @@ -103,10 +103,13 @@ export const ListQueryProvider: React.FC<ListQueryProps> = ({
}

const newQuery: ListQuery = {
limit: 'limit' in query ? query.limit : (currentQuery?.limit as string),
limit:
'limit' in query
? query.limit
: ((currentQuery?.limit as string) ?? String(defaultLimit)),
page: pageQuery as string,
search: 'search' in query ? query.search : (currentQuery?.search as string),
sort: 'sort' in query ? query.sort : (currentQuery?.sort as string),
sort: 'sort' in query ? query.sort : ((currentQuery?.sort as string) ?? defaultSort),
where: 'where' in query ? query.where : (currentQuery?.where as Where),
}

Expand Down
51 changes: 47 additions & 4 deletions test/joins/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { reorderColumns } from 'helpers/e2e/reorderColumns.js'
import * as path from 'path'
import { fileURLToPath } from 'url'

import type { PayloadTestSDK } from '../helpers/sdk/index.js'
import type { Config } from './payload-types.js'

import {
ensureCompilationIsDone,
exactText,
Expand All @@ -20,6 +23,9 @@ import { categoriesSlug, postsSlug, uploadsSlug } from './shared.js'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)

let payload: PayloadTestSDK<Config>
let serverURL: string

test.describe('Admin Panel', () => {
let page: Page
let categoriesURL: AdminUrlUtil
Expand All @@ -28,8 +34,9 @@ test.describe('Admin Panel', () => {

test.beforeAll(async ({ browser }, testInfo) => {
testInfo.setTimeout(TEST_TIMEOUT_LONG)

const { payload, serverURL } = await initPayloadE2ENoConfig({ dirname })
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({
dirname,
}))
postsURL = new AdminUrlUtil(serverURL, postsSlug)
categoriesURL = new AdminUrlUtil(serverURL, categoriesSlug)
uploadsURL = new AdminUrlUtil(serverURL, uploadsSlug)
Expand Down Expand Up @@ -59,8 +66,44 @@ test.describe('Admin Panel', () => {
const joinField = page.locator('#field-relatedPosts.field-type.join')
await expect(joinField).toBeVisible()
await expect(joinField.locator('.relationship-table table')).toBeVisible()
const columns = await joinField.locator('.relationship-table tbody tr').count()
expect(columns).toBe(3)
const rows = joinField.locator('.relationship-table tbody tr')
await expect(rows).toHaveCount(3)
})

test('should apply defaultLimit and defaultSort on relationship table', async () => {
const result = await payload.find({
collection: categoriesSlug,
limit: 1,
})
const category = result.docs[0]
// seed additional posts to test defaultLimit (5)
await payload.create({
collection: postsSlug,
data: {
title: 'a',
category: category.id,
},
})
await payload.create({
collection: postsSlug,
data: {
title: 'b',
category: category.id,
},
})
await payload.create({
collection: postsSlug,
data: {
title: 'z',
category: category.id,
},
})
await navigateToDoc(page, categoriesURL)
const joinField = page.locator('#field-relatedPosts.field-type.join')
await expect(joinField.locator('.row-1 > .cell-title')).toContainText('z')
await expect(joinField.locator('.paginator > .clickable-arrow--right')).toBeVisible()
const rows = joinField.locator('.relationship-table tbody tr')
await expect(rows).toHaveCount(5)
})

test('should render join field for hidden posts', async () => {
Expand Down

0 comments on commit a11243e

Please sign in to comment.