feat(plugin-import-export): adds sort order control and sync with sort-by field (#13478)
### What? This PR adds a dedicated `sortOrder` select field (Ascending / Descending) to the import-export plugin, alongside updates to the existing `SortBy` component. The new field and component logic keep the sort field (`sort`) in sync with the selected sort direction. ### Why? Previously, descending sorting did not work. While the `SortBy` field could read the list view’s `query.sort` param, if the value contained a leading dash (e.g. `-title`), it would not be handled correctly. Only ascending sorts such as `sort=title` worked, and the preview table would not reflect a descending order. ### How? - Added a new `sortOrder` select field to the export options schema. - Implemented a `SortOrder` custom component using ReactSelect: - On new exports, reads `query.sort` from the list view and sets both `sortOrder` and `sort` (combined value with or without a leading dash). - Handles external changes to `sort` that include a leading dash. - Updated `SortBy`: - No longer writes to `sort` during initial hydration—`SortOrder` owns initial value setting. - On user field changes, writes the combined value using the current `sortOrder`.
This commit is contained in:
@@ -227,6 +227,60 @@ describe('@payloadcms/plugin-import-export', () => {
|
||||
).rejects.toThrow(/Limit/)
|
||||
})
|
||||
|
||||
it('should export results sorted ASC by title when sort="title"', async () => {
|
||||
let doc = await payload.create({
|
||||
collection: 'exports',
|
||||
user,
|
||||
data: {
|
||||
collectionSlug: 'pages',
|
||||
format: 'csv',
|
||||
sort: 'title',
|
||||
where: {
|
||||
or: [{ title: { contains: 'Title' } }, { title: { contains: 'Array' } }],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
doc = await payload.findByID({
|
||||
collection: 'exports',
|
||||
id: doc.id,
|
||||
})
|
||||
|
||||
expect(doc.filename).toBeDefined()
|
||||
const expectedPath = path.join(dirname, './uploads', doc.filename as string)
|
||||
const data = await readCSV(expectedPath)
|
||||
|
||||
expect(data[0].id).toBeDefined()
|
||||
expect(data[0].title).toStrictEqual('Array 0')
|
||||
})
|
||||
|
||||
it('should export results sorted DESC by title when sort="-title"', async () => {
|
||||
let doc = await payload.create({
|
||||
collection: 'exports',
|
||||
user,
|
||||
data: {
|
||||
collectionSlug: 'pages',
|
||||
format: 'csv',
|
||||
sort: '-title',
|
||||
where: {
|
||||
or: [{ title: { contains: 'Title' } }, { title: { contains: 'Array' } }],
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
doc = await payload.findByID({
|
||||
collection: 'exports',
|
||||
id: doc.id,
|
||||
})
|
||||
|
||||
expect(doc.filename).toBeDefined()
|
||||
const expectedPath = path.join(dirname, './uploads', doc.filename as string)
|
||||
const data = await readCSV(expectedPath)
|
||||
|
||||
expect(data[0].id).toBeDefined()
|
||||
expect(data[0].title).toStrictEqual('Title 4')
|
||||
})
|
||||
|
||||
it('should create a file for collection csv with draft data', async () => {
|
||||
const draftPage = await payload.create({
|
||||
collection: 'pages',
|
||||
|
||||
@@ -270,6 +270,7 @@ export interface Export {
|
||||
limit?: number | null;
|
||||
page?: number | null;
|
||||
sort?: string | null;
|
||||
sortOrder?: ('asc' | 'desc') | null;
|
||||
locale?: ('all' | 'en' | 'es' | 'de') | null;
|
||||
drafts?: ('yes' | 'no') | null;
|
||||
selectionToUse?: ('currentSelection' | 'currentFilters' | 'all') | null;
|
||||
@@ -307,6 +308,7 @@ export interface ExportsTask {
|
||||
limit?: number | null;
|
||||
page?: number | null;
|
||||
sort?: string | null;
|
||||
sortOrder?: ('asc' | 'desc') | null;
|
||||
locale?: ('all' | 'en' | 'es' | 'de') | null;
|
||||
drafts?: ('yes' | 'no') | null;
|
||||
selectionToUse?: ('currentSelection' | 'currentFilters' | 'all') | null;
|
||||
@@ -609,6 +611,7 @@ export interface ExportsSelect<T extends boolean = true> {
|
||||
limit?: T;
|
||||
page?: T;
|
||||
sort?: T;
|
||||
sortOrder?: T;
|
||||
locale?: T;
|
||||
drafts?: T;
|
||||
selectionToUse?: T;
|
||||
@@ -637,6 +640,7 @@ export interface ExportsTasksSelect<T extends boolean = true> {
|
||||
limit?: T;
|
||||
page?: T;
|
||||
sort?: T;
|
||||
sortOrder?: T;
|
||||
locale?: T;
|
||||
drafts?: T;
|
||||
selectionToUse?: T;
|
||||
@@ -729,6 +733,7 @@ export interface TaskCreateCollectionExport {
|
||||
limit?: number | null;
|
||||
page?: number | null;
|
||||
sort?: string | null;
|
||||
sortOrder?: ('asc' | 'desc') | null;
|
||||
locale?: ('all' | 'en' | 'es' | 'de') | null;
|
||||
drafts?: ('yes' | 'no') | null;
|
||||
selectionToUse?: ('currentSelection' | 'currentFilters' | 'all') | null;
|
||||
|
||||
Reference in New Issue
Block a user