diff --git a/packages/ui/src/elements/TableColumns/index.tsx b/packages/ui/src/elements/TableColumns/index.tsx index c8a65944b2..684e40a063 100644 --- a/packages/ui/src/elements/TableColumns/index.tsx +++ b/packages/ui/src/elements/TableColumns/index.tsx @@ -15,6 +15,7 @@ import { getInitialColumns } from './getInitialColumns.js' export interface ITableColumns { columns: Column[] moveColumn: (args: { fromIndex: number; toIndex: number }) => void + resetColumnsState: () => void setActiveColumns: (columns: string[]) => void toggleColumn: (column: string) => void } @@ -122,19 +123,35 @@ export const TableColumnsProvider: React.FC = ({ ) const setActiveColumns = React.useCallback( - (activeColumnAccessors) => { - const activeColumns = tableColumns.map((col) => { - return { - ...col, - active: activeColumnAccessors.includes(col.accessor), - } - }) + (activeColumnAccessors: string[]) => { + const activeColumns = tableColumns + .map((col) => { + return { + ...col, + active: activeColumnAccessors.includes(col.accessor), + } + }) + .toSorted((first, second) => { + const indexOfFirst = activeColumnAccessors.indexOf(first.accessor) + const indexOfSecond = activeColumnAccessors.indexOf(second.accessor) + if (indexOfFirst === -1 || indexOfSecond === -1) { + return 0 + } + + return indexOfFirst > indexOfSecond ? 1 : -1 + }) + + setTableColumns(activeColumns) updateColumnPreferences(activeColumns) }, [tableColumns, updateColumnPreferences], ) + const resetColumnsState = React.useCallback(() => { + setActiveColumns(defaultColumns) + }, [defaultColumns, setActiveColumns]) + // ////////////////////////////////////////////// // Get preferences on collection change (drawers) // ////////////////////////////////////////////// @@ -182,6 +199,7 @@ export const TableColumnsProvider: React.FC = ({ value={{ columns: tableColumns, moveColumn, + resetColumnsState, setActiveColumns, toggleColumn, }} diff --git a/test/admin/collections/Posts.ts b/test/admin/collections/Posts.ts index d2b93ddb01..65d060bdc1 100644 --- a/test/admin/collections/Posts.ts +++ b/test/admin/collections/Posts.ts @@ -12,6 +12,9 @@ export const Posts: CollectionConfig = { description: 'This is a custom collection description.', group: 'One', listSearchableFields: ['id', 'title', 'description', 'number'], + components: { + beforeListTable: ['/components/ResetColumns/index.js#ResetDefaultColumnsButton'], + }, meta: { description: 'This is a custom meta description for posts', openGraph: { diff --git a/test/admin/components/ResetColumns/index.tsx b/test/admin/components/ResetColumns/index.tsx new file mode 100644 index 0000000000..2dec0f9cb8 --- /dev/null +++ b/test/admin/components/ResetColumns/index.tsx @@ -0,0 +1,11 @@ +'use client' + +import { Pill, useTableColumns } from '@payloadcms/ui' + +function ResetDefaultColumnsButton() { + const { resetColumnsState } = useTableColumns() + + return Reset to default columns +} + +export { ResetDefaultColumnsButton } diff --git a/test/admin/payload-types.ts b/test/admin/payload-types.ts index b155ab5a63..528c56170e 100644 --- a/test/admin/payload-types.ts +++ b/test/admin/payload-types.ts @@ -27,6 +27,7 @@ export interface Config { customIdTab: CustomIdTab; customIdRow: CustomIdRow; 'disable-duplicate': DisableDuplicate; + 'payload-locked-documents': PayloadLockedDocument; 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; @@ -269,6 +270,86 @@ export interface DisableDuplicate { updatedAt: string; createdAt: string; } +/** + * This interface was referenced by `Config`'s JSON-Schema + * via the `definition` "payload-locked-documents". + */ +export interface PayloadLockedDocument { + id: string; + document?: + | ({ + relationTo: 'uploads'; + value: string | Upload; + } | null) + | ({ + relationTo: 'posts'; + value: string | Post; + } | null) + | ({ + relationTo: 'users'; + value: string | User; + } | null) + | ({ + relationTo: 'hidden-collection'; + value: string | HiddenCollection; + } | null) + | ({ + relationTo: 'collection-no-api-view'; + value: string | CollectionNoApiView; + } | null) + | ({ + relationTo: 'custom-views-one'; + value: string | CustomViewsOne; + } | null) + | ({ + relationTo: 'custom-views-two'; + value: string | CustomViewsTwo; + } | null) + | ({ + relationTo: 'custom-fields'; + value: string | CustomField; + } | null) + | ({ + relationTo: 'group-one-collection-ones'; + value: string | GroupOneCollectionOne; + } | null) + | ({ + relationTo: 'group-one-collection-twos'; + value: string | GroupOneCollectionTwo; + } | null) + | ({ + relationTo: 'group-two-collection-ones'; + value: string | GroupTwoCollectionOne; + } | null) + | ({ + relationTo: 'group-two-collection-twos'; + value: string | GroupTwoCollectionTwo; + } | null) + | ({ + relationTo: 'geo'; + value: string | Geo; + } | null) + | ({ + relationTo: 'customIdTab'; + value: string | CustomIdTab; + } | null) + | ({ + relationTo: 'customIdRow'; + value: string | CustomIdRow; + } | null) + | ({ + relationTo: 'disable-duplicate'; + value: string | DisableDuplicate; + } | null); + editedAt?: string | null; + globalSlug?: string | null; + user: { + relationTo: 'users'; + value: string | User; + }; + updatedAt: string; + createdAt: string; +} /** * This interface was referenced by `Config`'s JSON-Schema * via the `definition` "payload-preferences".