chore(next): moves document info provider from root to page

This commit is contained in:
Jacob Fletcher
2024-03-07 12:52:15 -05:00
parent 36f88b198c
commit 1d4ec9cd71
10 changed files with 87 additions and 81 deletions

View File

@@ -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,9 +92,7 @@ export const Account: React.FC<AdminViewProps> = async ({ initPageResult, search
}
return (
<Fragment>
<HydrateClientUser permissions={permissions} user={user} />
<SetDocumentInfo
<DocumentInfoProvider
AfterFields={<Settings />}
action={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
apiURL={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
@@ -102,7 +103,20 @@ export const Account: React.FC<AdminViewProps> = async ({ initPageResult, search
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>
)
}

View File

@@ -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,15 +186,7 @@ export const Document: React.FC<AdminViewProps> = async ({
}
return (
<Fragment>
<DocumentHeader
collectionConfig={collectionConfig}
config={payload.config}
globalConfig={globalConfig}
i18n={i18n}
/>
<HydrateClientUser permissions={permissions} user={user} />
<SetDocumentInfo
<DocumentInfoProvider
action={action}
apiURL={apiURL}
collectionSlug={collectionConfig?.slug}
@@ -203,7 +195,7 @@ export const Document: React.FC<AdminViewProps> = async ({
docPreferences={docPreferences}
globalSlug={globalConfig?.slug}
hasSavePermission={hasSavePermission}
id={id || ''}
id={id}
initialData={data}
initialState={initialState}
title={formatTitle({
@@ -213,7 +205,14 @@ export const Document: React.FC<AdminViewProps> = async ({
i18n,
value: data?.[collectionConfig?.admin?.useAsTitle] || id?.toString(),
})}
>
<DocumentHeader
collectionConfig={collectionConfig}
config={payload.config}
globalConfig={globalConfig}
i18n={i18n}
/>
<HydrateClientUser permissions={permissions} user={user} />
<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>
)
}

View File

@@ -39,5 +39,9 @@ export const formatTitle = ({
title = getTranslation(globalConfig?.label, i18n) || globalConfig?.slug
}
if (!title) {
title = `[${i18n.t('general:untitled')}]`
}
return title
}

View File

@@ -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])

View File

@@ -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'}
/>
{!hideTabs && (
<DocumentTabs
collectionConfig={collectionConfig}
config={config}
globalConfig={globalConfig}
i18n={i18n}
/>
)}
</Fragment>
)}
</Gutter>

View File

@@ -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

View File

@@ -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']
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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,7 +76,6 @@ export const RootProvider: React.FC<Props> = ({
<LocaleProvider>
<StepNavProvider>
<LoadingOverlayProvider>
<DocumentInfoProvider>
<DocumentEventsProvider>
<ActionsProvider>
<NavProvider>
@@ -85,7 +83,6 @@ export const RootProvider: React.FC<Props> = ({
</NavProvider>
</ActionsProvider>
</DocumentEventsProvider>
</DocumentInfoProvider>
</LoadingOverlayProvider>
</StepNavProvider>
</LocaleProvider>