feat(ui): useTableColumns add abillity to reset columns state (#8296)

Fixes https://github.com/payloadcms/payload/issues/8205

Adds `resetColumnsState` method to `useTableColumns` return
Example of a `BeforeList` component for column state reset:
```ts
'use client'

import { Pill, useTableColumns } from '@payloadcms/ui'

function ResetDefaultColumnsButton() {
  const { resetColumnsState } = useTableColumns()

  return <Pill onClick={resetColumnsState}>Reset to default columns</Pill>
}

export { ResetDefaultColumnsButton }

```

Additionally, fixes that `setActiveColumns` didn't respect the passed
order of columns and didn't update the UI immediately
This commit is contained in:
Sasha
2024-09-19 05:35:03 +03:00
committed by GitHub
parent a095a6f891
commit 72995fccf5
4 changed files with 120 additions and 7 deletions

View File

@@ -15,6 +15,7 @@ import { getInitialColumns } from './getInitialColumns.js'
export interface ITableColumns { export interface ITableColumns {
columns: Column[] columns: Column[]
moveColumn: (args: { fromIndex: number; toIndex: number }) => void moveColumn: (args: { fromIndex: number; toIndex: number }) => void
resetColumnsState: () => void
setActiveColumns: (columns: string[]) => void setActiveColumns: (columns: string[]) => void
toggleColumn: (column: string) => void toggleColumn: (column: string) => void
} }
@@ -122,19 +123,35 @@ export const TableColumnsProvider: React.FC<Props> = ({
) )
const setActiveColumns = React.useCallback( const setActiveColumns = React.useCallback(
(activeColumnAccessors) => { (activeColumnAccessors: string[]) => {
const activeColumns = tableColumns.map((col) => { const activeColumns = tableColumns
return { .map((col) => {
...col, return {
active: activeColumnAccessors.includes(col.accessor), ...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) updateColumnPreferences(activeColumns)
}, },
[tableColumns, updateColumnPreferences], [tableColumns, updateColumnPreferences],
) )
const resetColumnsState = React.useCallback(() => {
setActiveColumns(defaultColumns)
}, [defaultColumns, setActiveColumns])
// ////////////////////////////////////////////// // //////////////////////////////////////////////
// Get preferences on collection change (drawers) // Get preferences on collection change (drawers)
// ////////////////////////////////////////////// // //////////////////////////////////////////////
@@ -182,6 +199,7 @@ export const TableColumnsProvider: React.FC<Props> = ({
value={{ value={{
columns: tableColumns, columns: tableColumns,
moveColumn, moveColumn,
resetColumnsState,
setActiveColumns, setActiveColumns,
toggleColumn, toggleColumn,
}} }}

View File

@@ -12,6 +12,9 @@ export const Posts: CollectionConfig = {
description: 'This is a custom collection description.', description: 'This is a custom collection description.',
group: 'One', group: 'One',
listSearchableFields: ['id', 'title', 'description', 'number'], listSearchableFields: ['id', 'title', 'description', 'number'],
components: {
beforeListTable: ['/components/ResetColumns/index.js#ResetDefaultColumnsButton'],
},
meta: { meta: {
description: 'This is a custom meta description for posts', description: 'This is a custom meta description for posts',
openGraph: { openGraph: {

View File

@@ -0,0 +1,11 @@
'use client'
import { Pill, useTableColumns } from '@payloadcms/ui'
function ResetDefaultColumnsButton() {
const { resetColumnsState } = useTableColumns()
return <Pill onClick={resetColumnsState}>Reset to default columns</Pill>
}
export { ResetDefaultColumnsButton }

View File

@@ -27,6 +27,7 @@ export interface Config {
customIdTab: CustomIdTab; customIdTab: CustomIdTab;
customIdRow: CustomIdRow; customIdRow: CustomIdRow;
'disable-duplicate': DisableDuplicate; 'disable-duplicate': DisableDuplicate;
'payload-locked-documents': PayloadLockedDocument;
'payload-preferences': PayloadPreference; 'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration; 'payload-migrations': PayloadMigration;
}; };
@@ -269,6 +270,86 @@ export interface DisableDuplicate {
updatedAt: string; updatedAt: string;
createdAt: 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 * This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-preferences". * via the `definition` "payload-preferences".