diff --git a/packages/next/src/views/Account/index.tsx b/packages/next/src/views/Account/index.tsx index e3970b16e..003ba6351 100644 --- a/packages/next/src/views/Account/index.tsx +++ b/packages/next/src/views/Account/index.tsx @@ -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 = async ({ initPageResult, search const { permissions, req: { + i18n, payload, payload: { config }, user, @@ -89,20 +92,31 @@ export const Account: React.FC = async ({ initPageResult, search } return ( - - - } - 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} + } + 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(), + })} + > + + = async ({ initPageResult, search DefaultComponent={EditView} componentProps={serverSideProps} /> - + ) } diff --git a/packages/next/src/views/Document/index.tsx b/packages/next/src/views/Document/index.tsx index acb263e91..c9cab0b8a 100644 --- a/packages/next/src/views/Document/index.tsx +++ b/packages/next/src/views/Document/index.tsx @@ -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 = async ({ } return ( - + = async ({ i18n={i18n} /> - = async ({ /> - + ) } diff --git a/packages/next/src/views/Edit/Default/SetDocumentTitle/formatTitle.ts b/packages/next/src/views/Edit/Default/SetDocumentTitle/formatTitle.ts index d1004df81..8039d0a91 100644 --- a/packages/next/src/views/Edit/Default/SetDocumentTitle/formatTitle.ts +++ b/packages/next/src/views/Edit/Default/SetDocumentTitle/formatTitle.ts @@ -39,5 +39,9 @@ export const formatTitle = ({ title = getTranslation(globalConfig?.label, i18n) || globalConfig?.slug } + if (!title) { + title = `[${i18n.t('general:untitled')}]` + } + return title } diff --git a/packages/next/src/views/Edit/Default/SetDocumentTitle/index.tsx b/packages/next/src/views/Edit/Default/SetDocumentTitle/index.tsx index baf949465..0c7836efa 100644 --- a/packages/next/src/views/Edit/Default/SetDocumentTitle/index.tsx +++ b/packages/next/src/views/Edit/Default/SetDocumentTitle/index.tsx @@ -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]) diff --git a/packages/ui/src/elements/DocumentHeader/index.tsx b/packages/ui/src/elements/DocumentHeader/index.tsx index 902d1b3bf..b7f2fb4bd 100644 --- a/packages/ui/src/elements/DocumentHeader/index.tsx +++ b/packages/ui/src/elements/DocumentHeader/index.tsx @@ -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 ( @@ -34,20 +31,16 @@ export const DocumentHeader: React.FC<{ - + {!hideTabs && ( + + )} )} diff --git a/packages/ui/src/elements/RenderTitle/index.tsx b/packages/ui/src/elements/RenderTitle/index.tsx index 57707d6a4..6bcd1bc7b 100644 --- a/packages/ui/src/elements/RenderTitle/index.tsx +++ b/packages/ui/src/elements/RenderTitle/index.tsx @@ -12,7 +12,9 @@ const baseClass = 'render-title' const RenderTitle: React.FC = (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 diff --git a/packages/ui/src/elements/RenderTitle/types.ts b/packages/ui/src/elements/RenderTitle/types.ts index 592e38127..e33075f3e 100644 --- a/packages/ui/src/elements/RenderTitle/types.ts +++ b/packages/ui/src/elements/RenderTitle/types.ts @@ -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'] } diff --git a/packages/ui/src/providers/DocumentInfo/index.tsx b/packages/ui/src/providers/DocumentInfo/index.tsx index ddde12e9c..eac35e4e4 100644 --- a/packages/ui/src/providers/DocumentInfo/index.tsx +++ b/packages/ui/src/providers/DocumentInfo/index.tsx @@ -28,13 +28,6 @@ export type { DocumentInfo, DocumentInfoContext, DocumentInfoProps } export const useDocumentInfo = (): DocumentInfoContext => useContext(Context) -/** - * To initialize documentInfo from the server - * use the 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 diff --git a/packages/ui/src/providers/DocumentInfo/types.ts b/packages/ui/src/providers/DocumentInfo/types.ts index 687d967d4..1ffcdfd6a 100644 --- a/packages/ui/src/providers/DocumentInfo/types.ts +++ b/packages/ui/src/providers/DocumentInfo/types.ts @@ -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 + onSave?: (data: Data) => Promise title?: string } diff --git a/packages/ui/src/providers/Root/index.tsx b/packages/ui/src/providers/Root/index.tsx index bbc59b1fd..67095ff0f 100644 --- a/packages/ui/src/providers/Root/index.tsx +++ b/packages/ui/src/providers/Root/index.tsx @@ -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 = ({ - - - - - {children} - - - - + + + + {children} + + +