chore(next): moves document info provider from root to page
This commit is contained in:
@@ -1,19 +1,21 @@
|
||||
import type { Data, DocumentPreferences, ServerSideEditViewProps } from 'payload/types'
|
||||
|
||||
import {
|
||||
DocumentHeader,
|
||||
DocumentInfoProvider,
|
||||
HydrateClientUser,
|
||||
RenderCustomComponent,
|
||||
SetDocumentInfo,
|
||||
buildStateFromSchema,
|
||||
formatFields,
|
||||
} from '@payloadcms/ui'
|
||||
import { notFound } from 'next/navigation.js'
|
||||
import React, { Fragment } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
import type { AdminViewProps } from '../Root/index.d.ts'
|
||||
|
||||
import { EditView } from '../Edit/index.js'
|
||||
import { Settings } from './Settings/index.js'
|
||||
import { formatTitle } from '../Edit/Default/SetDocumentTitle/formatTitle.js'
|
||||
|
||||
export { generateAccountMetadata } from './meta.js'
|
||||
|
||||
@@ -21,6 +23,7 @@ export const Account: React.FC<AdminViewProps> = async ({ initPageResult, search
|
||||
const {
|
||||
permissions,
|
||||
req: {
|
||||
i18n,
|
||||
payload,
|
||||
payload: { config },
|
||||
user,
|
||||
@@ -89,20 +92,31 @@ export const Account: React.FC<AdminViewProps> = async ({ initPageResult, search
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<HydrateClientUser permissions={permissions} user={user} />
|
||||
<SetDocumentInfo
|
||||
AfterFields={<Settings />}
|
||||
action={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
|
||||
apiURL={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
|
||||
collectionSlug={userSlug}
|
||||
docPermissions={collectionPermissions}
|
||||
docPreferences={docPreferences}
|
||||
hasSavePermission={collectionPermissions?.update?.permission}
|
||||
id={user?.id}
|
||||
initialData={data}
|
||||
initialState={initialState}
|
||||
<DocumentInfoProvider
|
||||
AfterFields={<Settings />}
|
||||
action={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
|
||||
apiURL={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
|
||||
collectionSlug={userSlug}
|
||||
docPermissions={collectionPermissions}
|
||||
docPreferences={docPreferences}
|
||||
hasSavePermission={collectionPermissions?.update?.permission}
|
||||
id={user?.id}
|
||||
initialData={data}
|
||||
initialState={initialState}
|
||||
title={formatTitle({
|
||||
collectionConfig,
|
||||
dateFormat: config.admin.dateFormat,
|
||||
i18n,
|
||||
value: data?.[collectionConfig?.admin?.useAsTitle] || data?.id?.toString(),
|
||||
})}
|
||||
>
|
||||
<DocumentHeader
|
||||
collectionConfig={collectionConfig}
|
||||
config={payload.config}
|
||||
i18n={i18n}
|
||||
hideTabs
|
||||
/>
|
||||
<HydrateClientUser permissions={permissions} user={user} />
|
||||
<RenderCustomComponent
|
||||
CustomComponent={
|
||||
typeof CustomAccountComponent === 'function' ? CustomAccountComponent : undefined
|
||||
@@ -110,7 +124,7 @@ export const Account: React.FC<AdminViewProps> = async ({ initPageResult, search
|
||||
DefaultComponent={EditView}
|
||||
componentProps={serverSideProps}
|
||||
/>
|
||||
</Fragment>
|
||||
</DocumentInfoProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ import type { DocumentPermissions } from 'payload/types'
|
||||
|
||||
import {
|
||||
DocumentHeader,
|
||||
DocumentInfoProvider,
|
||||
EditDepthProvider,
|
||||
FormQueryParamsProvider,
|
||||
HydrateClientUser,
|
||||
RenderCustomComponent,
|
||||
SetDocumentInfo,
|
||||
buildStateFromSchema,
|
||||
formatFields,
|
||||
} from '@payloadcms/ui'
|
||||
import React, { Fragment } from 'react'
|
||||
import React from 'react'
|
||||
|
||||
import type { AdminViewProps } from '../Root/index.d.ts'
|
||||
import type { GenerateEditViewMetadata } from './getMetaBySegment.d.ts'
|
||||
@@ -186,7 +186,26 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<DocumentInfoProvider
|
||||
action={action}
|
||||
apiURL={apiURL}
|
||||
collectionSlug={collectionConfig?.slug}
|
||||
disableActions={false}
|
||||
docPermissions={docPermissions}
|
||||
docPreferences={docPreferences}
|
||||
globalSlug={globalConfig?.slug}
|
||||
hasSavePermission={hasSavePermission}
|
||||
id={id}
|
||||
initialData={data}
|
||||
initialState={initialState}
|
||||
title={formatTitle({
|
||||
collectionConfig,
|
||||
dateFormat: config.admin.dateFormat,
|
||||
globalConfig,
|
||||
i18n,
|
||||
value: data?.[collectionConfig?.admin?.useAsTitle] || id?.toString(),
|
||||
})}
|
||||
>
|
||||
<DocumentHeader
|
||||
collectionConfig={collectionConfig}
|
||||
config={payload.config}
|
||||
@@ -194,26 +213,6 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
i18n={i18n}
|
||||
/>
|
||||
<HydrateClientUser permissions={permissions} user={user} />
|
||||
<SetDocumentInfo
|
||||
action={action}
|
||||
apiURL={apiURL}
|
||||
collectionSlug={collectionConfig?.slug}
|
||||
disableActions={false}
|
||||
docPermissions={docPermissions}
|
||||
docPreferences={docPreferences}
|
||||
globalSlug={globalConfig?.slug}
|
||||
hasSavePermission={hasSavePermission}
|
||||
id={id || ''}
|
||||
initialData={data}
|
||||
initialState={initialState}
|
||||
title={formatTitle({
|
||||
collectionConfig,
|
||||
dateFormat: config.admin.dateFormat,
|
||||
globalConfig,
|
||||
i18n,
|
||||
value: data?.[collectionConfig?.admin?.useAsTitle] || id?.toString(),
|
||||
})}
|
||||
/>
|
||||
<EditDepthProvider depth={1} key={`${collectionSlug || globalSlug}-${locale.code}`}>
|
||||
<FormQueryParamsProvider
|
||||
initialParams={{
|
||||
@@ -230,6 +229,6 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
/>
|
||||
</FormQueryParamsProvider>
|
||||
</EditDepthProvider>
|
||||
</Fragment>
|
||||
</DocumentInfoProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -39,5 +39,9 @@ export const formatTitle = ({
|
||||
title = getTranslation(globalConfig?.label, i18n) || globalConfig?.slug
|
||||
}
|
||||
|
||||
if (!title) {
|
||||
title = `[${i18n.t('general:untitled')}]`
|
||||
}
|
||||
|
||||
return title
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import type { ClientConfig } from 'payload/types'
|
||||
|
||||
import { useDocumentInfo, useFormFields, useTranslation } from '@payloadcms/ui'
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
|
||||
import { formatTitle } from './formatTitle.js'
|
||||
|
||||
@@ -17,6 +17,8 @@ export const SetDocumentTitle: React.FC<{
|
||||
|
||||
const field = useFormFields(([fields]) => (useAsTitle && fields && fields?.[useAsTitle]) || null)
|
||||
|
||||
const hasInitialized = useRef(false)
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const { setDocumentTitle } = useDocumentInfo()
|
||||
@@ -37,6 +39,11 @@ export const SetDocumentTitle: React.FC<{
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasInitialized.current) {
|
||||
hasInitialized.current = true
|
||||
return
|
||||
}
|
||||
|
||||
setDocumentTitle(title)
|
||||
}, [setDocumentTitle, title])
|
||||
|
||||
|
||||
@@ -19,13 +19,10 @@ export const DocumentHeader: React.FC<{
|
||||
config: SanitizedConfig
|
||||
customHeader?: React.ReactNode
|
||||
globalConfig?: SanitizedGlobalConfig
|
||||
hideTabs?: boolean
|
||||
i18n: I18n
|
||||
}> = (props) => {
|
||||
const { collectionConfig, config, customHeader, globalConfig, i18n } = props
|
||||
|
||||
const titleFieldConfig = collectionConfig?.fields?.find(
|
||||
(f) => 'name' in f && f?.name === collectionConfig?.admin?.useAsTitle,
|
||||
)
|
||||
const { collectionConfig, config, customHeader, globalConfig, hideTabs, i18n } = props
|
||||
|
||||
return (
|
||||
<Gutter className={baseClass}>
|
||||
@@ -34,20 +31,16 @@ export const DocumentHeader: React.FC<{
|
||||
<Fragment>
|
||||
<RenderTitle
|
||||
className={`${baseClass}__title`}
|
||||
dateFormat={
|
||||
titleFieldConfig && 'date' in titleFieldConfig?.admin
|
||||
? titleFieldConfig?.admin?.date?.displayFormat
|
||||
: undefined
|
||||
}
|
||||
fallback={`[${i18n.t('general:untitled')}]`}
|
||||
isDate={titleFieldConfig?.type === 'date'}
|
||||
/>
|
||||
<DocumentTabs
|
||||
collectionConfig={collectionConfig}
|
||||
config={config}
|
||||
globalConfig={globalConfig}
|
||||
i18n={i18n}
|
||||
/>
|
||||
{!hideTabs && (
|
||||
<DocumentTabs
|
||||
collectionConfig={collectionConfig}
|
||||
config={config}
|
||||
globalConfig={globalConfig}
|
||||
i18n={i18n}
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</Gutter>
|
||||
|
||||
@@ -12,7 +12,9 @@ const baseClass = 'render-title'
|
||||
const RenderTitle: React.FC<Props> = (props) => {
|
||||
const { className, element = 'h1', fallback, title: titleFromProps } = props
|
||||
|
||||
const { id, title: titleFromContext } = useDocumentInfo()
|
||||
const documentInfo = useDocumentInfo()
|
||||
|
||||
const { id, title: titleFromContext } = documentInfo
|
||||
|
||||
const title = titleFromProps || titleFromContext || fallback
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
export type Props = {
|
||||
className?: string
|
||||
dateFormat?: any // TODO: type this
|
||||
element?: React.ElementType
|
||||
fallback?: string
|
||||
isDate?: boolean
|
||||
title?: string
|
||||
// dateFormat?: SanitizedCollectionConfig['fields'][0]['admin']['date']['displayFormat']
|
||||
}
|
||||
|
||||
@@ -28,13 +28,6 @@ export type { DocumentInfo, DocumentInfoContext, DocumentInfoProps }
|
||||
|
||||
export const useDocumentInfo = (): DocumentInfoContext => useContext(Context)
|
||||
|
||||
/**
|
||||
* To initialize documentInfo from the server
|
||||
* use the <SetDocumentInfo /> within a RSC component
|
||||
* to hydrate the documentInfo on the first render.
|
||||
*
|
||||
* Otherwise pass props to initialize the documentInfo.
|
||||
**/
|
||||
export const DocumentInfoProvider: React.FC<
|
||||
DocumentInfoProps & {
|
||||
children: React.ReactNode
|
||||
|
||||
@@ -25,10 +25,10 @@ export type DocumentInfoProps = {
|
||||
docPreferences?: DocumentPreferences
|
||||
globalSlug?: SanitizedGlobalConfig['slug']
|
||||
hasSavePermission?: boolean
|
||||
id?: number | string
|
||||
id: null | number | string
|
||||
initialData?: Data
|
||||
initialState?: FormState
|
||||
onSave?: (data: Data) => Promise<void> | void
|
||||
onSave?: (data: Data) => Promise<void>
|
||||
title?: string
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import { ComponentMapProvider } from '../ComponentMapProvider/index.js'
|
||||
import { ConfigProvider } from '../Config/index.js'
|
||||
import { CustomProvider } from '../CustomProvider/index.js'
|
||||
import { DocumentEventsProvider } from '../DocumentEvents/index.js'
|
||||
import { DocumentInfoProvider } from '../DocumentInfo/index.js'
|
||||
import { LocaleProvider } from '../Locale/index.js'
|
||||
import { ParamsProvider } from '../Params/index.js'
|
||||
import { PreferencesProvider } from '../Preferences/index.js'
|
||||
@@ -77,15 +76,13 @@ export const RootProvider: React.FC<Props> = ({
|
||||
<LocaleProvider>
|
||||
<StepNavProvider>
|
||||
<LoadingOverlayProvider>
|
||||
<DocumentInfoProvider>
|
||||
<DocumentEventsProvider>
|
||||
<ActionsProvider>
|
||||
<NavProvider>
|
||||
<CustomProvider>{children}</CustomProvider>
|
||||
</NavProvider>
|
||||
</ActionsProvider>
|
||||
</DocumentEventsProvider>
|
||||
</DocumentInfoProvider>
|
||||
<DocumentEventsProvider>
|
||||
<ActionsProvider>
|
||||
<NavProvider>
|
||||
<CustomProvider>{children}</CustomProvider>
|
||||
</NavProvider>
|
||||
</ActionsProvider>
|
||||
</DocumentEventsProvider>
|
||||
</LoadingOverlayProvider>
|
||||
</StepNavProvider>
|
||||
</LocaleProvider>
|
||||
|
||||
Reference in New Issue
Block a user