fix(next): cannot filter trash (#13320)
### What? - Updated `TrashView` to pass `trash: true` as a dedicated prop instead of embedding it in the `query` object. - Modified `renderListView` to correctly merge `trash` and `where` queries by using both `queryFromArgs` and `queryFromReq`. - Ensured filtering (via `where`) works correctly in the trash view. ### Why? Previously, the `trash: true` flag was injected into the `query` object, and `renderListView` only used `queryFromArgs`. This caused the `where` clause from filters (added by the `WhereBuilder`) to be overridden, breaking filtering in the trash view. ### How? - Introduced an explicit `trash` prop in `renderListView` arguments. - Updated `TrashView` to pass `trash: true` separately. - Updated `renderListView` to apply the `trash` filter in addition to any `where` conditions.
This commit is contained in:
@@ -34,13 +34,13 @@ npm i @payloadcms/plugin-csm
|
||||
Then in the `plugins` array of your Payload Config, call the plugin and enable any collections that require Content Source Maps.
|
||||
|
||||
```ts
|
||||
import { buildConfig } from "payload/config"
|
||||
import contentSourceMaps from "@payloadcms/plugin-csm"
|
||||
import { buildConfig } from 'payload/config'
|
||||
import contentSourceMaps from '@payloadcms/plugin-csm'
|
||||
|
||||
const config = buildConfig({
|
||||
collections: [
|
||||
{
|
||||
slug: "pages",
|
||||
slug: 'pages',
|
||||
fields: [
|
||||
{
|
||||
name: 'slug',
|
||||
@@ -55,7 +55,7 @@ const config = buildConfig({
|
||||
],
|
||||
plugins: [
|
||||
contentSourceMaps({
|
||||
collections: ["pages"],
|
||||
collections: ['pages'],
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
@@ -45,7 +45,7 @@ The following options are available:
|
||||
|
||||
| Path | Description |
|
||||
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`url`** | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
||||
| **`url`** | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
||||
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
|
||||
| **`collections`** | Array of collection slugs to enable Live Preview on. |
|
||||
| **`globals`** | Array of global slugs to enable Live Preview on. |
|
||||
|
||||
@@ -19,17 +19,14 @@ type RenderTrashViewArgs = {
|
||||
redirectAfterRestore?: boolean
|
||||
} & AdminViewServerProps
|
||||
|
||||
export const TrashView: React.FC<
|
||||
{ query?: any } & Omit<RenderTrashViewArgs, 'enableRowSelections'>
|
||||
> = async (args) => {
|
||||
export const TrashView: React.FC<Omit<RenderTrashViewArgs, 'enableRowSelections'>> = async (
|
||||
args,
|
||||
) => {
|
||||
try {
|
||||
const { List: TrashList } = await renderListView({
|
||||
...args,
|
||||
enableRowSelections: true,
|
||||
query: {
|
||||
...(args.query || {}),
|
||||
trash: true, // force trash view
|
||||
},
|
||||
trash: true,
|
||||
viewType: 'trash',
|
||||
})
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ type RenderListViewArgs = {
|
||||
query: ListQuery
|
||||
redirectAfterDelete?: boolean
|
||||
redirectAfterDuplicate?: boolean
|
||||
/**
|
||||
* @experimental This prop is subject to change in future releases.
|
||||
*/
|
||||
trash?: boolean
|
||||
} & AdminViewServerProps
|
||||
|
||||
/**
|
||||
@@ -66,6 +70,7 @@ export const renderListView = async (
|
||||
params,
|
||||
query: queryFromArgs,
|
||||
searchParams,
|
||||
trash,
|
||||
viewType,
|
||||
} = args
|
||||
|
||||
@@ -153,7 +158,7 @@ export const renderListView = async (
|
||||
where: combineWhereConstraints([query?.where, baseListFilter]),
|
||||
})
|
||||
|
||||
if (query?.trash === true) {
|
||||
if (trash === true) {
|
||||
whereWithMergedSearch = {
|
||||
and: [
|
||||
whereWithMergedSearch,
|
||||
@@ -217,7 +222,7 @@ export const renderListView = async (
|
||||
enableRowSelections,
|
||||
query,
|
||||
req,
|
||||
trash: query?.trash === true,
|
||||
trash,
|
||||
user,
|
||||
where: whereWithMergedSearch,
|
||||
}))
|
||||
@@ -234,7 +239,7 @@ export const renderListView = async (
|
||||
page: query?.page ? Number(query.page) : undefined,
|
||||
req,
|
||||
sort: query?.sort,
|
||||
trash: query?.trash === true,
|
||||
trash,
|
||||
user,
|
||||
where: whereWithMergedSearch,
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { addListFilter } from 'helpers/e2e/addListFilter.js'
|
||||
import * as path from 'path'
|
||||
import { mapAsync } from 'payload'
|
||||
import { fileURLToPath } from 'url'
|
||||
@@ -537,6 +538,47 @@ describe('Trash', () => {
|
||||
})
|
||||
.toBe(0)
|
||||
})
|
||||
|
||||
test('Should properly filter trashed docs through where query builder', async () => {
|
||||
const createdDocs: Post[] = []
|
||||
|
||||
// Create 2 "Test Post" docs
|
||||
await mapAsync([...Array(2)], async (item, index) => {
|
||||
const doc = await createTrashedPostDoc({
|
||||
title: `Test Post ${index + 1}`,
|
||||
})
|
||||
createdDocs.push(doc)
|
||||
})
|
||||
|
||||
// Create 2 "Some Post" docs
|
||||
await mapAsync([...Array(2)], async (item, index) => {
|
||||
const doc = await createTrashedPostDoc({
|
||||
title: `Some Post ${index + 1}`,
|
||||
})
|
||||
createdDocs.push(doc)
|
||||
})
|
||||
|
||||
await page.goto(postsUrl.trash)
|
||||
|
||||
await addListFilter({
|
||||
page,
|
||||
fieldLabel: 'Title',
|
||||
operatorLabel: 'is like',
|
||||
value: 'Test',
|
||||
})
|
||||
|
||||
await expect(page.locator('.cell-title', { hasText: 'Test Post' })).toHaveCount(2)
|
||||
await expect(page.locator('.cell-title', { hasText: 'Some Post' })).toHaveCount(0)
|
||||
|
||||
// Cleanup: permanently delete the created docs
|
||||
await mapAsync(createdDocs, async (doc) => {
|
||||
await payload.delete({
|
||||
collection: postsSlug,
|
||||
id: doc.id,
|
||||
trash: true, // Force permanent delete
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Edit view', () => {
|
||||
|
||||
@@ -21,15 +21,8 @@
|
||||
"skipLibCheck": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"sourceMap": true,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"DOM.Iterable",
|
||||
"ES2022"
|
||||
],
|
||||
"types": [
|
||||
"node",
|
||||
"jest"
|
||||
],
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
||||
"types": ["node", "jest"],
|
||||
"incremental": true,
|
||||
"isolatedModules": true,
|
||||
"plugins": [
|
||||
@@ -38,72 +31,36 @@
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"@payload-config": [
|
||||
"./test/joins/config.ts"
|
||||
],
|
||||
"@payloadcms/admin-bar": [
|
||||
"./packages/admin-bar/src"
|
||||
],
|
||||
"@payloadcms/live-preview": [
|
||||
"./packages/live-preview/src"
|
||||
],
|
||||
"@payloadcms/live-preview-react": [
|
||||
"./packages/live-preview-react/src/index.ts"
|
||||
],
|
||||
"@payloadcms/live-preview-vue": [
|
||||
"./packages/live-preview-vue/src/index.ts"
|
||||
],
|
||||
"@payloadcms/ui": [
|
||||
"./packages/ui/src/exports/client/index.ts"
|
||||
],
|
||||
"@payloadcms/ui/shared": [
|
||||
"./packages/ui/src/exports/shared/index.ts"
|
||||
],
|
||||
"@payloadcms/ui/rsc": [
|
||||
"./packages/ui/src/exports/rsc/index.ts"
|
||||
],
|
||||
"@payloadcms/ui/scss": [
|
||||
"./packages/ui/src/scss.scss"
|
||||
],
|
||||
"@payloadcms/ui/scss/app.scss": [
|
||||
"./packages/ui/src/scss/app.scss"
|
||||
],
|
||||
"@payloadcms/next/*": [
|
||||
"./packages/next/src/exports/*.ts"
|
||||
],
|
||||
"@payload-config": ["./test/_community/config.ts"],
|
||||
"@payloadcms/admin-bar": ["./packages/admin-bar/src"],
|
||||
"@payloadcms/live-preview": ["./packages/live-preview/src"],
|
||||
"@payloadcms/live-preview-react": ["./packages/live-preview-react/src/index.ts"],
|
||||
"@payloadcms/live-preview-vue": ["./packages/live-preview-vue/src/index.ts"],
|
||||
"@payloadcms/ui": ["./packages/ui/src/exports/client/index.ts"],
|
||||
"@payloadcms/ui/shared": ["./packages/ui/src/exports/shared/index.ts"],
|
||||
"@payloadcms/ui/rsc": ["./packages/ui/src/exports/rsc/index.ts"],
|
||||
"@payloadcms/ui/scss": ["./packages/ui/src/scss.scss"],
|
||||
"@payloadcms/ui/scss/app.scss": ["./packages/ui/src/scss/app.scss"],
|
||||
"@payloadcms/next/*": ["./packages/next/src/exports/*.ts"],
|
||||
"@payloadcms/richtext-lexical/client": [
|
||||
"./packages/richtext-lexical/src/exports/client/index.ts"
|
||||
],
|
||||
"@payloadcms/richtext-lexical/rsc": [
|
||||
"./packages/richtext-lexical/src/exports/server/rsc.ts"
|
||||
],
|
||||
"@payloadcms/richtext-slate/rsc": [
|
||||
"./packages/richtext-slate/src/exports/server/rsc.ts"
|
||||
],
|
||||
"@payloadcms/richtext-lexical/rsc": ["./packages/richtext-lexical/src/exports/server/rsc.ts"],
|
||||
"@payloadcms/richtext-slate/rsc": ["./packages/richtext-slate/src/exports/server/rsc.ts"],
|
||||
"@payloadcms/richtext-slate/client": [
|
||||
"./packages/richtext-slate/src/exports/client/index.ts"
|
||||
],
|
||||
"@payloadcms/plugin-seo/client": [
|
||||
"./packages/plugin-seo/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-sentry/client": [
|
||||
"./packages/plugin-sentry/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-stripe/client": [
|
||||
"./packages/plugin-stripe/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-search/client": [
|
||||
"./packages/plugin-search/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-seo/client": ["./packages/plugin-seo/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-sentry/client": ["./packages/plugin-sentry/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-stripe/client": ["./packages/plugin-stripe/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-search/client": ["./packages/plugin-search/src/exports/client.ts"],
|
||||
"@payloadcms/plugin-form-builder/client": [
|
||||
"./packages/plugin-form-builder/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-import-export/rsc": [
|
||||
"./packages/plugin-import-export/src/exports/rsc.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant/rsc": [
|
||||
"./packages/plugin-multi-tenant/src/exports/rsc.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant/rsc": ["./packages/plugin-multi-tenant/src/exports/rsc.ts"],
|
||||
"@payloadcms/plugin-multi-tenant/utilities": [
|
||||
"./packages/plugin-multi-tenant/src/exports/utilities.ts"
|
||||
],
|
||||
@@ -113,42 +70,25 @@
|
||||
"@payloadcms/plugin-multi-tenant/client": [
|
||||
"./packages/plugin-multi-tenant/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant": [
|
||||
"./packages/plugin-multi-tenant/src/index.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant": ["./packages/plugin-multi-tenant/src/index.ts"],
|
||||
"@payloadcms/plugin-multi-tenant/translations/languages/all": [
|
||||
"./packages/plugin-multi-tenant/src/translations/index.ts"
|
||||
],
|
||||
"@payloadcms/plugin-multi-tenant/translations/languages/*": [
|
||||
"./packages/plugin-multi-tenant/src/translations/languages/*.ts"
|
||||
],
|
||||
"@payloadcms/next": [
|
||||
"./packages/next/src/exports/*"
|
||||
],
|
||||
"@payloadcms/storage-azure/client": [
|
||||
"./packages/storage-azure/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/storage-s3/client": [
|
||||
"./packages/storage-s3/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/next": ["./packages/next/src/exports/*"],
|
||||
"@payloadcms/storage-azure/client": ["./packages/storage-azure/src/exports/client.ts"],
|
||||
"@payloadcms/storage-s3/client": ["./packages/storage-s3/src/exports/client.ts"],
|
||||
"@payloadcms/storage-vercel-blob/client": [
|
||||
"./packages/storage-vercel-blob/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/storage-gcs/client": [
|
||||
"./packages/storage-gcs/src/exports/client.ts"
|
||||
],
|
||||
"@payloadcms/storage-gcs/client": ["./packages/storage-gcs/src/exports/client.ts"],
|
||||
"@payloadcms/storage-uploadthing/client": [
|
||||
"./packages/storage-uploadthing/src/exports/client.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"${configDir}/src"
|
||||
],
|
||||
"exclude": [
|
||||
"${configDir}/dist",
|
||||
"${configDir}/build",
|
||||
"${configDir}/temp",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
"include": ["${configDir}/src"],
|
||||
"exclude": ["${configDir}/dist", "${configDir}/build", "${configDir}/temp", "**/*.spec.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user