Skip to content

Commit 7c35e88

Browse files
feat: prevent setting column preferences unless edited (#6774)
Fixes #6458 Prevents setting column preferences unless they are manually changed.
1 parent 8f6cedf commit 7c35e88

File tree

2 files changed

+97
-186
lines changed

2 files changed

+97
-186
lines changed

packages/ui/src/elements/TableColumns/columnReducer.ts

Lines changed: 0 additions & 84 deletions
This file was deleted.

packages/ui/src/elements/TableColumns/index.tsx

Lines changed: 97 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,20 @@
11
'use client'
2-
import type { SanitizedCollectionConfig } from 'payload/types'
3-
import type { CellComponentProps } from 'payload/types'
4-
5-
import React, {
6-
createContext,
7-
useCallback,
8-
useContext,
9-
useEffect,
10-
useReducer,
11-
useRef,
12-
useState,
13-
} from 'react'
2+
import type { CellComponentProps, SanitizedCollectionConfig } from 'payload/types'
3+
4+
import React, { createContext, useCallback, useContext, useState } from 'react'
145

156
import type { ColumnPreferences } from '../../providers/ListInfo/index.js'
167
import type { Column } from '../Table/index.js'
17-
import type { Action } from './columnReducer.js'
188

199
import { useComponentMap } from '../../providers/ComponentMap/index.js'
2010
import { useConfig } from '../../providers/Config/index.js'
2111
import { usePreferences } from '../../providers/Preferences/index.js'
2212
import { buildColumnState } from './buildColumnState.js'
23-
import { columnReducer } from './columnReducer.js'
2413
import { filterFields } from './filterFields.js'
2514
import { getInitialColumns } from './getInitialColumns.js'
2615

2716
export interface ITableColumns {
2817
columns: Column[]
29-
dispatchTableColumns: React.Dispatch<Action>
3018
moveColumn: (args: { fromIndex: number; toIndex: number }) => void
3119
setActiveColumns: (columns: string[]) => void
3220
toggleColumn: (column: string) => void
@@ -71,30 +59,105 @@ export const TableColumnsProvider: React.FC<Props> = ({
7159
admin: { defaultColumns, useAsTitle },
7260
} = collectionConfig
7361

74-
const prevCollection = useRef<SanitizedCollectionConfig['slug']>(collectionSlug)
75-
const hasInitialized = useRef(false)
62+
const prevCollection = React.useRef<SanitizedCollectionConfig['slug']>(collectionSlug)
7663
const { getPreference, setPreference } = usePreferences()
7764

7865
const [initialColumns] = useState<ColumnPreferences>(() =>
7966
getInitialColumns(filterFields(fieldMap), useAsTitle, defaultColumns),
8067
)
8168

82-
const [tableColumns, dispatchTableColumns] = useReducer(columnReducer, {}, () => {
83-
return buildColumnState({
69+
const [tableColumns, setTableColumns] = React.useState(() =>
70+
buildColumnState({
8471
cellProps,
8572
columnPreferences: listPreferences?.columns,
8673
columns: initialColumns,
8774
enableRowSelections,
8875
fieldMap,
8976
useAsTitle,
77+
}),
78+
)
79+
80+
const updateColumnPreferences = React.useCallback(
81+
(newColumns: Column[]) => {
82+
const columns = newColumns.map((c) => ({
83+
accessor: c?.accessor,
84+
active: c?.active,
85+
}))
86+
87+
void setPreference(preferenceKey, { columns }, true)
88+
},
89+
[preferenceKey, setPreference],
90+
)
91+
92+
const reassignLinkColumn = (columns: Column[]): Column[] => {
93+
let foundFirstActive = false
94+
const newColumns = columns.map((col) => {
95+
const linkColumn = col.active && !foundFirstActive && col.accessor !== '_select'
96+
if (linkColumn) foundFirstActive = true
97+
98+
return {
99+
...col,
100+
cellProps: {
101+
...col.cellProps,
102+
link: linkColumn,
103+
},
104+
}
90105
})
91-
})
92106

93-
// /////////////////////////////////////
94-
// Get preferences on collection change
95-
// /////////////////////////////////////
107+
return newColumns
108+
}
109+
110+
const moveColumn = useCallback(
111+
(args: { fromIndex: number; toIndex: number }) => {
112+
const { fromIndex, toIndex } = args
113+
114+
const withMovedColumn = [...tableColumns]
115+
const [columnToMove] = withMovedColumn.splice(fromIndex, 1)
116+
withMovedColumn.splice(toIndex, 0, columnToMove)
117+
118+
const newColumns = reassignLinkColumn(withMovedColumn)
119+
setTableColumns(newColumns)
120+
updateColumnPreferences(newColumns)
121+
},
122+
[tableColumns, updateColumnPreferences],
123+
)
124+
125+
const toggleColumn = useCallback(
126+
(column: string) => {
127+
const toggledColumns = tableColumns.map((col) => {
128+
return {
129+
...col,
130+
active: col?.name === column ? !col.active : col.active,
131+
}
132+
})
133+
134+
const newColumns = reassignLinkColumn(toggledColumns)
135+
setTableColumns(newColumns)
136+
updateColumnPreferences(newColumns)
137+
},
138+
[tableColumns, updateColumnPreferences],
139+
)
140+
141+
const setActiveColumns = React.useCallback(
142+
(activeColumnAccessors) => {
143+
const activeColumns = tableColumns.map((col) => {
144+
return {
145+
...col,
146+
active: activeColumnAccessors.includes(col.accessor),
147+
}
148+
})
149+
150+
const newColumns = reassignLinkColumn(activeColumns)
151+
updateColumnPreferences(newColumns)
152+
},
153+
[tableColumns, updateColumnPreferences],
154+
)
96155

97-
useEffect(() => {
156+
// //////////////////////////////////////////////
157+
// Get preferences on collection change (drawers)
158+
// //////////////////////////////////////////////
159+
160+
React.useEffect(() => {
98161
const sync = async () => {
99162
const collectionHasChanged = prevCollection.current !== collectionSlug
100163

@@ -105,19 +168,16 @@ export const TableColumnsProvider: React.FC<Props> = ({
105168
prevCollection.current = collectionSlug
106169

107170
if (currentPreferences?.columns) {
108-
dispatchTableColumns({
109-
type: 'set',
110-
payload: {
111-
columns: buildColumnState({
112-
cellProps,
113-
columnPreferences: currentPreferences?.columns,
114-
columns: initialColumns,
115-
enableRowSelections: true,
116-
fieldMap,
117-
useAsTitle,
118-
}),
119-
},
120-
})
171+
setTableColumns(
172+
buildColumnState({
173+
cellProps,
174+
columnPreferences: currentPreferences?.columns,
175+
columns: initialColumns,
176+
enableRowSelections: true,
177+
fieldMap,
178+
useAsTitle,
179+
}),
180+
)
121181
}
122182
}
123183
}
@@ -135,75 +195,10 @@ export const TableColumnsProvider: React.FC<Props> = ({
135195
initialColumns,
136196
])
137197

138-
// /////////////////////////////////////
139-
// Set preferences on column change
140-
// /////////////////////////////////////
141-
142-
useEffect(() => {
143-
if (!hasInitialized.current) {
144-
hasInitialized.current = true
145-
return
146-
}
147-
148-
const columns = tableColumns.map((c) => ({
149-
accessor: c?.accessor,
150-
active: c?.active,
151-
}))
152-
153-
void setPreference(preferenceKey, { columns }, true)
154-
}, [tableColumns, preferenceKey, setPreference])
155-
156-
const setActiveColumns = useCallback(
157-
(columns: string[]) => {
158-
// dispatchTableColumns({
159-
// type: 'set',
160-
// payload: {
161-
// // onSelect,
162-
// cellProps,
163-
// collection: { ...collectionConfig, fields: formatFields(collectionConfig) },
164-
// columns: columns.map((column) => ({
165-
// accessor: column,
166-
// active: true,
167-
// })),
168-
// i18n,
169-
// },
170-
// })
171-
},
172-
[collectionConfig, cellProps],
173-
)
174-
175-
const moveColumn = useCallback(
176-
(args: { fromIndex: number; toIndex: number }) => {
177-
const { fromIndex, toIndex } = args
178-
179-
dispatchTableColumns({
180-
type: 'move',
181-
payload: {
182-
fromIndex,
183-
toIndex,
184-
},
185-
})
186-
},
187-
[dispatchTableColumns],
188-
)
189-
190-
const toggleColumn = useCallback(
191-
(column: string) => {
192-
dispatchTableColumns({
193-
type: 'toggle',
194-
payload: {
195-
column,
196-
},
197-
})
198-
},
199-
[dispatchTableColumns],
200-
)
201-
202198
return (
203199
<TableColumnContext.Provider
204200
value={{
205201
columns: tableColumns,
206-
dispatchTableColumns,
207202
moveColumn,
208203
setActiveColumns,
209204
toggleColumn,

0 commit comments

Comments
 (0)