fix(ui): reordering with a join field inside a group (#12803)

Fixes https://github.com/payloadcms/payload/issues/12802
This commit is contained in:
Sasha
2025-06-13 19:31:07 +03:00
committed by GitHub
parent 06ad17108b
commit e60db0750a
5 changed files with 59 additions and 28 deletions

View File

@@ -41,6 +41,7 @@ type RelationshipTableComponentProps = {
readonly BeforeInput?: React.ReactNode readonly BeforeInput?: React.ReactNode
readonly disableTable?: boolean readonly disableTable?: boolean
readonly field: JoinFieldClient readonly field: JoinFieldClient
readonly fieldPath?: string
readonly filterOptions?: Where readonly filterOptions?: Where
readonly initialData?: PaginatedDocs readonly initialData?: PaginatedDocs
readonly initialDrawerData?: DocumentDrawerProps['initialData'] readonly initialDrawerData?: DocumentDrawerProps['initialData']
@@ -60,6 +61,7 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
BeforeInput, BeforeInput,
disableTable = false, disableTable = false,
field, field,
fieldPath,
filterOptions, filterOptions,
initialData: initialDataFromProps, initialData: initialDataFromProps,
initialDrawerData, initialDrawerData,
@@ -343,7 +345,7 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
orderableFieldName={ orderableFieldName={
!field.orderable || Array.isArray(field.collection) !field.orderable || Array.isArray(field.collection)
? undefined ? undefined
: `_${field.collection}_${field.name}_order` : `_${field.collection}_${fieldPath.replaceAll('.', '_')}_order`
} }
> >
<TableColumnsProvider <TableColumnsProvider

View File

@@ -213,6 +213,7 @@ const JoinFieldComponent: JoinFieldClientComponent = (props) => {
BeforeInput={BeforeInput} BeforeInput={BeforeInput}
disableTable={filterOptions === null} disableTable={filterOptions === null}
field={field as JoinFieldClient} field={field as JoinFieldClient}
fieldPath={path}
filterOptions={filterOptions} filterOptions={filterOptions}
initialData={docID && value ? value : ({ docs: [] } as PaginatedDocs)} initialData={docID && value ? value : ({ docs: [] } as PaginatedDocs)}
initialDrawerData={initialDrawerData} initialDrawerData={initialDrawerData}

View File

@@ -35,5 +35,18 @@ export const OrderableJoinCollection: CollectionConfig = {
on: 'orderableField', on: 'orderableField',
collection: 'orderable', collection: 'orderable',
}, },
{
name: 'group',
type: 'group',
fields: [
{
name: 'orderableJoinField',
type: 'join',
on: 'orderableField',
orderable: true,
collection: 'orderable',
},
],
},
], ],
} }

View File

@@ -80,7 +80,7 @@ describe('Sort functionality', () => {
await page.goto(url.list) await page.goto(url.list)
await page.getByText('Join A').click() await page.getByText('Join A').click()
await expect(page.locator('.sort-header button')).toHaveCount(2) await expect(page.locator('.sort-header button')).toHaveCount(3)
await assertRows(0, 'A', 'B', 'C', 'D') await assertRows(0, 'A', 'B', 'C', 'D')
await moveRow(2, 3, 'success', 0) // move to middle await moveRow(2, 3, 'success', 0) // move to middle

View File

@@ -82,6 +82,7 @@ export interface Config {
collectionsJoins: { collectionsJoins: {
'orderable-join': { 'orderable-join': {
orderableJoinField1: 'orderable'; orderableJoinField1: 'orderable';
'group.orderableJoinField': 'orderable';
orderableJoinField2: 'orderable'; orderableJoinField2: 'orderable';
nonOrderableJoinField: 'orderable'; nonOrderableJoinField: 'orderable';
}; };
@@ -100,7 +101,7 @@ export interface Config {
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>; 'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
}; };
db: { db: {
defaultIDType: number; defaultIDType: string;
}; };
globals: {}; globals: {};
globalsSelect: {}; globalsSelect: {};
@@ -136,7 +137,7 @@ export interface UserAuthOperations {
* via the `definition` "posts". * via the `definition` "posts".
*/ */
export interface Post { export interface Post {
id: number; id: string;
text?: string | null; text?: string | null;
number?: number | null; number?: number | null;
number2?: number | null; number2?: number | null;
@@ -166,7 +167,7 @@ export interface Draft {
* via the `definition` "default-sort". * via the `definition` "default-sort".
*/ */
export interface DefaultSort { export interface DefaultSort {
id: number; id: string;
text?: string | null; text?: string | null;
number?: number | null; number?: number | null;
updatedAt: string; updatedAt: string;
@@ -177,7 +178,7 @@ export interface DefaultSort {
* via the `definition` "non-unique-sort". * via the `definition` "non-unique-sort".
*/ */
export interface NonUniqueSort { export interface NonUniqueSort {
id: number; id: string;
title?: string | null; title?: string | null;
order?: number | null; order?: number | null;
updatedAt: string; updatedAt: string;
@@ -188,7 +189,7 @@ export interface NonUniqueSort {
* via the `definition` "localized". * via the `definition` "localized".
*/ */
export interface Localized { export interface Localized {
id: number; id: string;
text?: string | null; text?: string | null;
number?: number | null; number?: number | null;
number2?: number | null; number2?: number | null;
@@ -206,10 +207,11 @@ export interface Localized {
export interface Orderable { export interface Orderable {
id: string; id: string;
_orderable_orderableJoinField2_order?: string | null; _orderable_orderableJoinField2_order?: string | null;
_orderable_group_orderableJoinField_order?: string | null;
_orderable_orderableJoinField1_order?: string | null; _orderable_orderableJoinField1_order?: string | null;
_order?: string | null; _order?: string | null;
title?: string | null; title?: string | null;
orderableField?: (number | null) | OrderableJoin; orderableField?: (string | null) | OrderableJoin;
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
} }
@@ -218,20 +220,27 @@ export interface Orderable {
* via the `definition` "orderable-join". * via the `definition` "orderable-join".
*/ */
export interface OrderableJoin { export interface OrderableJoin {
id: number; id: string;
title?: string | null; title?: string | null;
orderableJoinField1?: { orderableJoinField1?: {
docs?: (number | Orderable)[]; docs?: (string | Orderable)[];
hasNextPage?: boolean; hasNextPage?: boolean;
totalDocs?: number; totalDocs?: number;
}; };
group?: {
orderableJoinField?: {
docs?: (string | Orderable)[];
hasNextPage?: boolean;
totalDocs?: number;
};
};
orderableJoinField2?: { orderableJoinField2?: {
docs?: (number | Orderable)[]; docs?: (string | Orderable)[];
hasNextPage?: boolean; hasNextPage?: boolean;
totalDocs?: number; totalDocs?: number;
}; };
nonOrderableJoinField?: { nonOrderableJoinField?: {
docs?: (number | Orderable)[]; docs?: (string | Orderable)[];
hasNextPage?: boolean; hasNextPage?: boolean;
totalDocs?: number; totalDocs?: number;
}; };
@@ -243,7 +252,7 @@ export interface OrderableJoin {
* via the `definition` "users". * via the `definition` "users".
*/ */
export interface User { export interface User {
id: number; id: string;
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
email: string; email: string;
@@ -260,44 +269,44 @@ export interface User {
* via the `definition` "payload-locked-documents". * via the `definition` "payload-locked-documents".
*/ */
export interface PayloadLockedDocument { export interface PayloadLockedDocument {
id: number; id: string;
document?: document?:
| ({ | ({
relationTo: 'posts'; relationTo: 'posts';
value: number | Post; value: string | Post;
} | null) } | null)
| ({ | ({
relationTo: 'drafts'; relationTo: 'drafts';
value: number | Draft; value: string | Draft;
} | null) } | null)
| ({ | ({
relationTo: 'default-sort'; relationTo: 'default-sort';
value: number | DefaultSort; value: string | DefaultSort;
} | null) } | null)
| ({ | ({
relationTo: 'non-unique-sort'; relationTo: 'non-unique-sort';
value: number | NonUniqueSort; value: string | NonUniqueSort;
} | null) } | null)
| ({ | ({
relationTo: 'localized'; relationTo: 'localized';
value: number | Localized; value: string | Localized;
} | null) } | null)
| ({ | ({
relationTo: 'orderable'; relationTo: 'orderable';
value: number | Orderable; value: string | Orderable;
} | null) } | null)
| ({ | ({
relationTo: 'orderable-join'; relationTo: 'orderable-join';
value: number | OrderableJoin; value: string | OrderableJoin;
} | null) } | null)
| ({ | ({
relationTo: 'users'; relationTo: 'users';
value: number | User; value: string | User;
} | null); } | null);
globalSlug?: string | null; globalSlug?: string | null;
user: { user: {
relationTo: 'users'; relationTo: 'users';
value: number | User; value: string | User;
}; };
updatedAt: string; updatedAt: string;
createdAt: string; createdAt: string;
@@ -307,10 +316,10 @@ export interface PayloadLockedDocument {
* via the `definition` "payload-preferences". * via the `definition` "payload-preferences".
*/ */
export interface PayloadPreference { export interface PayloadPreference {
id: number; id: string;
user: { user: {
relationTo: 'users'; relationTo: 'users';
value: number | User; value: string | User;
}; };
key?: string | null; key?: string | null;
value?: value?:
@@ -330,7 +339,7 @@ export interface PayloadPreference {
* via the `definition` "payload-migrations". * via the `definition` "payload-migrations".
*/ */
export interface PayloadMigration { export interface PayloadMigration {
id: number; id: string;
name?: string | null; name?: string | null;
batch?: number | null; batch?: number | null;
updatedAt: string; updatedAt: string;
@@ -409,6 +418,7 @@ export interface LocalizedSelect<T extends boolean = true> {
*/ */
export interface OrderableSelect<T extends boolean = true> { export interface OrderableSelect<T extends boolean = true> {
_orderable_orderableJoinField2_order?: T; _orderable_orderableJoinField2_order?: T;
_orderable_group_orderableJoinField_order?: T;
_orderable_orderableJoinField1_order?: T; _orderable_orderableJoinField1_order?: T;
_order?: T; _order?: T;
title?: T; title?: T;
@@ -423,6 +433,11 @@ export interface OrderableSelect<T extends boolean = true> {
export interface OrderableJoinSelect<T extends boolean = true> { export interface OrderableJoinSelect<T extends boolean = true> {
title?: T; title?: T;
orderableJoinField1?: T; orderableJoinField1?: T;
group?:
| T
| {
orderableJoinField?: T;
};
orderableJoinField2?: T; orderableJoinField2?: T;
nonOrderableJoinField?: T; nonOrderableJoinField?: T;
updatedAt?: T; updatedAt?: T;
@@ -485,6 +500,6 @@ export interface Auth {
declare module 'payload' { declare module 'payload' {
// @ts-ignore // @ts-ignore
export interface GeneratedTypes extends Config {} export interface GeneratedTypes extends Config {}
} }