The form component's `initializing` and `processing` states do not disable fields that are rendered outside of `DocumentFields`. Fields currently rely on the `readOnly` prop provided by `DocumentFields` and do not subscribe to these states for themselves. This means that fields that are rendered outright, such as within the bulk edit drawer, they do not receive a `readOnly` prop and are therefore never disabled. The fix is add a `disabled` property to the `useField` hook. This subscribes to the `initializing` and `processing` states in the same way as `DocumentFields`, however, now each field can determine its own disabled state instead of relying solely on the `readOnly` prop. Adding this new prop has no overhead as `processing` and `initializing` is already being subscribed to within `useField`.
107 lines
3.0 KiB
TypeScript
107 lines
3.0 KiB
TypeScript
'use client'
|
|
import type { ClientField, SanitizedDocumentPermissions } from 'payload'
|
|
|
|
import { fieldIsSidebar } from 'payload/shared'
|
|
import React, { useMemo } from 'react'
|
|
|
|
import { useFormInitializing, useFormProcessing } from '../../forms/Form/context.js'
|
|
import { RenderFields } from '../../forms/RenderFields/index.js'
|
|
import { Gutter } from '../Gutter/index.js'
|
|
import './index.scss'
|
|
|
|
const baseClass = 'document-fields'
|
|
|
|
type Args = {
|
|
readonly AfterFields?: React.ReactNode
|
|
readonly BeforeFields?: React.ReactNode
|
|
readonly Description?: React.ReactNode
|
|
readonly docPermissions: SanitizedDocumentPermissions
|
|
readonly fields: ClientField[]
|
|
readonly forceSidebarWrap?: boolean
|
|
readonly readOnly?: boolean
|
|
readonly schemaPathSegments: string[]
|
|
}
|
|
|
|
export const DocumentFields: React.FC<Args> = ({
|
|
AfterFields,
|
|
BeforeFields,
|
|
Description,
|
|
docPermissions,
|
|
fields,
|
|
forceSidebarWrap,
|
|
readOnly,
|
|
schemaPathSegments,
|
|
}) => {
|
|
const { hasSidebarFields, mainFields, sidebarFields } = useMemo(() => {
|
|
return fields.reduce(
|
|
(acc, field) => {
|
|
if (fieldIsSidebar(field)) {
|
|
acc.sidebarFields.push(field)
|
|
acc.mainFields.push(null)
|
|
acc.hasSidebarFields = true
|
|
} else {
|
|
acc.mainFields.push(field)
|
|
acc.sidebarFields.push(null)
|
|
}
|
|
return acc
|
|
},
|
|
{
|
|
hasSidebarFields: false,
|
|
mainFields: [] as ClientField[],
|
|
sidebarFields: [] as ClientField[],
|
|
},
|
|
)
|
|
}, [fields])
|
|
|
|
return (
|
|
<div
|
|
className={[
|
|
baseClass,
|
|
hasSidebarFields ? `${baseClass}--has-sidebar` : `${baseClass}--no-sidebar`,
|
|
forceSidebarWrap && `${baseClass}--force-sidebar-wrap`,
|
|
]
|
|
.filter(Boolean)
|
|
.join(' ')}
|
|
>
|
|
<div className={`${baseClass}__main`}>
|
|
<Gutter className={`${baseClass}__edit`}>
|
|
{Description ? (
|
|
<header className={`${baseClass}__header`}>
|
|
<div className={`${baseClass}__sub-header`}>{Description}</div>
|
|
</header>
|
|
) : null}
|
|
{BeforeFields}
|
|
<RenderFields
|
|
className={`${baseClass}__fields`}
|
|
fields={mainFields}
|
|
forceRender
|
|
parentIndexPath=""
|
|
parentPath=""
|
|
parentSchemaPath={schemaPathSegments.join('.')}
|
|
permissions={docPermissions?.fields}
|
|
readOnly={readOnly}
|
|
/>
|
|
{AfterFields}
|
|
</Gutter>
|
|
</div>
|
|
{hasSidebarFields ? (
|
|
<div className={`${baseClass}__sidebar-wrap`}>
|
|
<div className={`${baseClass}__sidebar`}>
|
|
<div className={`${baseClass}__sidebar-fields`}>
|
|
<RenderFields
|
|
fields={sidebarFields}
|
|
forceRender
|
|
parentIndexPath=""
|
|
parentPath=""
|
|
parentSchemaPath={schemaPathSegments.join('.')}
|
|
permissions={docPermissions?.fields}
|
|
readOnly={readOnly}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
)
|
|
}
|