Skip to content

Commit 592f404

Browse files
authored
fix(next): ensure query preset from url is applied (#15323)
Previously, if you visited the list view from a URL that contains the `preset` param (e.g. `http://localhost:3000/admin/collections/pages?preset=69728460f29c932fb002feb9`), the preset would not be applied. This PR is ensured the preset is applied and adds an e2e test to verify this functionality
1 parent 2511c02 commit 592f404

File tree

3 files changed

+70
-38
lines changed

3 files changed

+70
-38
lines changed

packages/next/src/views/List/index.tsx

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ export const renderListView = async (
110110
},
111111
visibleEntities,
112112
} = initPageResult
113+
const {
114+
routes: { admin: adminRoute },
115+
} = config
113116

114117
if (
115118
!collectionConfig ||
@@ -140,7 +143,44 @@ export const renderListView = async (
140143
},
141144
})
142145

143-
query.preset = collectionPreferences?.preset
146+
let queryPreset: QueryPreset | undefined
147+
let queryPresetPermissions: SanitizedCollectionPermission | undefined
148+
149+
if (collectionPreferences?.preset) {
150+
try {
151+
queryPreset = (await payload.findByID({
152+
id: collectionPreferences?.preset,
153+
collection: 'payload-query-presets',
154+
depth: 0,
155+
overrideAccess: false,
156+
user,
157+
})) as QueryPreset
158+
159+
if (queryPreset) {
160+
queryPresetPermissions = (
161+
await getDocumentPermissions({
162+
id: queryPreset.id,
163+
collectionConfig: req.payload.collections['payload-query-presets'].config,
164+
data: queryPreset,
165+
req,
166+
})
167+
)?.docPermissions
168+
}
169+
} catch (err) {
170+
req.payload.logger.error(`Error fetching query preset or preset permissions: ${err}`)
171+
}
172+
}
173+
174+
query.preset = queryPreset?.id
175+
if (queryPreset?.where && !query.where) {
176+
query.where = queryPreset.where
177+
}
178+
query.groupBy = query.groupBy ?? queryPreset?.groupBy ?? collectionPreferences?.groupBy
179+
180+
const columnPreference = query.columns
181+
? transformColumnsToPreferences(query.columns)
182+
: (queryPreset?.columns ?? collectionPreferences?.columns)
183+
query.columns = transformColumnsToSearchParams(columnPreference)
144184

145185
query.page = isNumber(query?.page) ? Number(query.page) : 0
146186

@@ -150,14 +190,6 @@ export const renderListView = async (
150190
collectionPreferences?.sort ||
151191
(typeof collectionConfig.defaultSort === 'string' ? collectionConfig.defaultSort : undefined)
152192

153-
query.groupBy = collectionPreferences?.groupBy
154-
155-
query.columns = transformColumnsToSearchParams(collectionPreferences?.columns || [])
156-
157-
const {
158-
routes: { admin: adminRoute },
159-
} = config
160-
161193
const baseFilterConstraint = await (
162194
collectionConfig.admin?.baseFilter ?? collectionConfig.admin?.baseListFilter
163195
)?.({
@@ -167,9 +199,6 @@ export const renderListView = async (
167199
sort: query.sort,
168200
})
169201

170-
let queryPreset: QueryPreset | undefined
171-
let queryPresetPermissions: SanitizedCollectionPermission | undefined
172-
173202
let whereWithMergedSearch = mergeListSearchAndWhere({
174203
collectionConfig,
175204
search: typeof query?.search === 'string' ? query.search : undefined,
@@ -189,29 +218,6 @@ export const renderListView = async (
189218
}
190219
}
191220

192-
if (collectionPreferences?.preset) {
193-
try {
194-
queryPreset = (await payload.findByID({
195-
id: collectionPreferences?.preset,
196-
collection: 'payload-query-presets',
197-
depth: 0,
198-
overrideAccess: false,
199-
user,
200-
})) as QueryPreset
201-
202-
if (queryPreset) {
203-
queryPresetPermissions = await getDocumentPermissions({
204-
id: queryPreset.id,
205-
collectionConfig: config.collections.find((c) => c.slug === 'payload-query-presets'),
206-
data: queryPreset,
207-
req,
208-
})?.then(({ docPermissions }) => docPermissions)
209-
}
210-
} catch (err) {
211-
req.payload.logger.error(`Error fetching query preset or preset permissions: ${err}`)
212-
}
213-
}
214-
215221
let Table: React.ReactNode | React.ReactNode[] = null
216222
let columnState: Column[] = []
217223
let data: PaginatedDocs = {
@@ -234,7 +240,7 @@ export const renderListView = async (
234240
clientConfig,
235241
collectionConfig: clientCollectionConfig,
236242
collectionSlug,
237-
columns: collectionPreferences?.columns,
243+
columns: columnPreference,
238244
i18n,
239245
permissions,
240246
})

test/helpers/e2e/groupBy/addGroupBy.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ export const addGroupBy = async (
1616
await field.locator('.rs__option', { hasText: exactText(fieldLabel) })?.click()
1717
await expect(field.locator('.react-select--single-value')).toHaveText(fieldLabel)
1818

19-
await expect(page).toHaveURL(new RegExp(`&groupBy=${fieldPath}`))
19+
await expect(page).toHaveURL(new RegExp(`[&?]groupBy=${fieldPath}`))
2020
await expect(page.locator('body')).not.toContainText('Loading')
2121

22-
return { groupByContainer, field }
22+
return { field, groupByContainer }
2323
}

test/query-presets/e2e.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,4 +709,30 @@ describe('Query Presets', () => {
709709
// Verify reset button is hidden again after reset
710710
await expect(page.locator('#reset-preset')).toBeHidden()
711711
})
712+
713+
test('should apply preset from URL query param', async ({ page }) => {
714+
// Navigate directly to the list view with a preset query param
715+
await page.goto(`${pagesUrl.list}?preset=${seededData.everyone.id}`)
716+
717+
// Verify the where query is in the URL
718+
await assertURLParams({
719+
page,
720+
columns: seededData.everyone.columns,
721+
where: seededData.everyone.where,
722+
preset: seededData.everyone.id,
723+
})
724+
725+
// Verify the preset is selected in the preset selector
726+
await expect(
727+
page.locator('button#select-preset', {
728+
hasText: exactText(seededData.everyone.title),
729+
}),
730+
).toBeVisible()
731+
732+
// Verify the actual results are filtered correctly
733+
// The seeded preset filters for text: { equals: 'example page' }
734+
const tableRows = page.locator('.collection-list .table tbody tr')
735+
await expect(tableRows).toHaveCount(1)
736+
await expect(tableRows.first()).toContainText('example page')
737+
})
712738
})

0 commit comments

Comments
 (0)