fix(ui): filters out upload specific fields for bulk editing (#10726)
### What This PR adds a filtering mechanism to exclude certain reserved fields from being displayed in the `Edit Many` drawer for bulk uploads. This ensures that only relevant fields are available for bulk editing. ### Why Fields like `filename`, `mimeType`, and `filesize` are not intended to be edited in bulk. Filtering these fields streamlines the interface and focuses on fields that are meaningful for bulk operations. ### How - Introduced a `filterOutUploadFields` utility to exclude reserved fields from the field selection in bulk uploads. - Applied this filter to the `Edit Many` drawer, ensuring a more relevant and user-friendly experience. - Reserved fields include properties like `file`, `mimeType`, `url`, `width`, `height`, and others that are not applicable for bulk editing.
This commit is contained in:
@@ -15,6 +15,7 @@ import { RenderFields } from '../../../forms/RenderFields/index.js'
|
|||||||
import { XIcon } from '../../../icons/X/index.js'
|
import { XIcon } from '../../../icons/X/index.js'
|
||||||
import { useAuth } from '../../../providers/Auth/index.js'
|
import { useAuth } from '../../../providers/Auth/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
|
import { filterOutUploadFields } from '../../../utilities/filterOutUploadFields.js'
|
||||||
import { FieldSelect } from '../../FieldSelect/index.js'
|
import { FieldSelect } from '../../FieldSelect/index.js'
|
||||||
import { useFormsManager } from '../FormsManager/index.js'
|
import { useFormsManager } from '../FormsManager/index.js'
|
||||||
import { baseClass, type EditManyBulkUploadsProps } from './index.js'
|
import { baseClass, type EditManyBulkUploadsProps } from './index.js'
|
||||||
@@ -36,6 +37,7 @@ export const EditManyBulkUploadsDrawerContent: React.FC<
|
|||||||
|
|
||||||
const [selectedFields, setSelectedFields] = useState<FieldWithPathClient[]>([])
|
const [selectedFields, setSelectedFields] = useState<FieldWithPathClient[]>([])
|
||||||
const collectionPermissions = permissions?.collections?.[slug]
|
const collectionPermissions = permissions?.collections?.[slug]
|
||||||
|
const filteredFields = filterOutUploadFields(fields)
|
||||||
|
|
||||||
const handleSubmit: FormProps['onSubmit'] = useCallback(
|
const handleSubmit: FormProps['onSubmit'] = useCallback(
|
||||||
(formState) => {
|
(formState) => {
|
||||||
@@ -72,7 +74,7 @@ export const EditManyBulkUploadsDrawerContent: React.FC<
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<Form className={`${baseClass}__form`} initialState={{}} onSubmit={handleSubmit}>
|
<Form className={`${baseClass}__form`} initialState={{}} onSubmit={handleSubmit}>
|
||||||
<FieldSelect fields={fields} setSelected={setSelectedFields} />
|
<FieldSelect fields={filteredFields} setSelected={setSelectedFields} />
|
||||||
{selectedFields.length === 0 ? null : (
|
{selectedFields.length === 0 ? null : (
|
||||||
<RenderFields
|
<RenderFields
|
||||||
fields={selectedFields}
|
fields={selectedFields}
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ import { SelectAllStatus, useSelection } from '../../providers/Selection/index.j
|
|||||||
import { useServerFunctions } from '../../providers/ServerFunctions/index.js'
|
import { useServerFunctions } from '../../providers/ServerFunctions/index.js'
|
||||||
import { useTranslation } from '../../providers/Translation/index.js'
|
import { useTranslation } from '../../providers/Translation/index.js'
|
||||||
import { abortAndIgnore, handleAbortRef } from '../../utilities/abortAndIgnore.js'
|
import { abortAndIgnore, handleAbortRef } from '../../utilities/abortAndIgnore.js'
|
||||||
|
import { filterOutUploadFields } from '../../utilities/filterOutUploadFields.js'
|
||||||
import { mergeListSearchAndWhere } from '../../utilities/mergeListSearchAndWhere.js'
|
import { mergeListSearchAndWhere } from '../../utilities/mergeListSearchAndWhere.js'
|
||||||
import { parseSearchParams } from '../../utilities/parseSearchParams.js'
|
import { parseSearchParams } from '../../utilities/parseSearchParams.js'
|
||||||
import './index.scss'
|
|
||||||
import { FieldSelect } from '../FieldSelect/index.js'
|
import { FieldSelect } from '../FieldSelect/index.js'
|
||||||
import { baseClass, type EditManyProps } from './index.js'
|
import { baseClass, type EditManyProps } from './index.js'
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
const sanitizeUnselectedFields = (formState: FormState, selected: FieldWithPathClient[]) => {
|
const sanitizeUnselectedFields = (formState: FormState, selected: FieldWithPathClient[]) => {
|
||||||
const filteredData = selected.reduce((acc, field) => {
|
const filteredData = selected.reduce((acc, field) => {
|
||||||
@@ -169,6 +170,8 @@ export const EditManyDrawerContent: React.FC<
|
|||||||
const collectionPermissions = permissions?.collections?.[slug]
|
const collectionPermissions = permissions?.collections?.[slug]
|
||||||
const searchParams = useSearchParams()
|
const searchParams = useSearchParams()
|
||||||
|
|
||||||
|
const filteredFields = filterOutUploadFields(fields)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
|
|
||||||
@@ -284,7 +287,7 @@ export const EditManyDrawerContent: React.FC<
|
|||||||
onChange={[onChange]}
|
onChange={[onChange]}
|
||||||
onSuccess={onSuccess}
|
onSuccess={onSuccess}
|
||||||
>
|
>
|
||||||
<FieldSelect fields={fields} setSelected={setSelected} />
|
<FieldSelect fields={filteredFields} setSelected={setSelected} />
|
||||||
{selected.length === 0 ? null : (
|
{selected.length === 0 ? null : (
|
||||||
<RenderFields
|
<RenderFields
|
||||||
fields={selected}
|
fields={selected}
|
||||||
|
|||||||
20
packages/ui/src/utilities/filterOutUploadFields.ts
Normal file
20
packages/ui/src/utilities/filterOutUploadFields.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { FieldWithPathClient } from 'payload'
|
||||||
|
|
||||||
|
export const filterOutUploadFields = (fields: FieldWithPathClient[]): FieldWithPathClient[] => {
|
||||||
|
// List of reserved upload field names
|
||||||
|
const baseUploadFieldNames = [
|
||||||
|
'file',
|
||||||
|
'mimeType',
|
||||||
|
'thumbnailURL',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'filesize',
|
||||||
|
'filename',
|
||||||
|
'url',
|
||||||
|
'focalX',
|
||||||
|
'focalY',
|
||||||
|
'sizes',
|
||||||
|
]
|
||||||
|
|
||||||
|
return fields.filter((field) => !baseUploadFieldNames.includes('name' in field && field.name))
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user