perf: significantly reduce HTML we send to the client. Up to 4x smaller (#9321)
The biggest difference comes from calling `RenderServerComponent` as a function, instead of rendering it by using `<RenderServerComponent`. This gets rid of wasteful blocks of codes sent to the client that look like this:  HTML size comparison: ## Admin test suite | View | Before | After | |------|---------|--------| | Dashboard | 331 kB | 83 kB | | collections/custom-views-one Edit | 285 kB | 76.6 kB | ## Fields test suite | View | Before | After | |------|---------|--------| | collections/lexical Edit | 189 kB | 94.4 kB | | collections/lexical List | 152 kB | 62.9 kB | ## Community test suite | View | Before | After | |------|---------|--------| | Dashboard | 78.9 kB | 43.1 kB |
This commit is contained in:
@@ -75,16 +75,16 @@ export const DocumentTab: React.FC<
|
||||
{Pill || Pill_Component ? (
|
||||
<Fragment>
|
||||
|
||||
<RenderServerComponent
|
||||
Component={Pill}
|
||||
Fallback={Pill_Component}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
Component: Pill,
|
||||
Fallback: Pill_Component,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
payload,
|
||||
permissions,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
</Fragment>
|
||||
) : null}
|
||||
</span>
|
||||
|
||||
@@ -80,23 +80,21 @@ export const DocumentTabs: React.FC<{
|
||||
const { path, tab } = CustomView
|
||||
|
||||
if (tab.Component) {
|
||||
return (
|
||||
<RenderServerComponent
|
||||
clientProps={{
|
||||
path,
|
||||
}}
|
||||
Component={tab.Component}
|
||||
importMap={payload.importMap}
|
||||
key={`tab-custom-${index}`}
|
||||
serverProps={{
|
||||
collectionConfig,
|
||||
globalConfig,
|
||||
i18n,
|
||||
payload,
|
||||
permissions,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
return RenderServerComponent({
|
||||
clientProps: {
|
||||
path,
|
||||
},
|
||||
Component: tab.Component,
|
||||
importMap: payload.importMap,
|
||||
key: `tab-custom-${index}`,
|
||||
serverProps: {
|
||||
collectionConfig,
|
||||
globalConfig,
|
||||
i18n,
|
||||
payload,
|
||||
permissions,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { ServerProps } from 'payload'
|
||||
import type React from 'react'
|
||||
|
||||
import { RenderServerComponent } from '@payloadcms/ui/elements/RenderServerComponent'
|
||||
import { PayloadLogo } from '@payloadcms/ui/shared'
|
||||
import React from 'react'
|
||||
|
||||
export const Logo: React.FC<ServerProps> = (props) => {
|
||||
const { i18n, locale, params, payload, permissions, searchParams, user } = props
|
||||
@@ -17,20 +17,18 @@ export const Logo: React.FC<ServerProps> = (props) => {
|
||||
} = {},
|
||||
} = payload.config
|
||||
|
||||
return (
|
||||
<RenderServerComponent
|
||||
Component={CustomLogo}
|
||||
Fallback={PayloadLogo}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
return RenderServerComponent({
|
||||
Component: CustomLogo,
|
||||
Fallback: PayloadLogo,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,13 +59,28 @@ export const DefaultNav: React.FC<NavProps> = async (props) => {
|
||||
|
||||
const navPreferences = await getNavPrefs({ payload, user })
|
||||
|
||||
const LogoutComponent = RenderServerComponent({
|
||||
Component: logout?.Button,
|
||||
Fallback: Logout,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<NavWrapper baseClass={baseClass}>
|
||||
<nav className={`${baseClass}__wrap`}>
|
||||
<RenderServerComponent
|
||||
Component={beforeNavLinks}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
Component: beforeNavLinks,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -73,13 +88,13 @@ export const DefaultNav: React.FC<NavProps> = async (props) => {
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
<DefaultNavClient groups={groups} navPreferences={navPreferences} />
|
||||
<RenderServerComponent
|
||||
Component={afterNavLinks}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
Component: afterNavLinks,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -87,24 +102,9 @@ export const DefaultNav: React.FC<NavProps> = async (props) => {
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
<div className={`${baseClass}__controls`}>
|
||||
<RenderServerComponent
|
||||
Component={logout?.Button}
|
||||
Fallback={Logout}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
},
|
||||
})}
|
||||
<div className={`${baseClass}__controls`}>{LogoutComponent}</div>
|
||||
</nav>
|
||||
<div className={`${baseClass}__header`}>
|
||||
<div className={`${baseClass}__header-content`}>
|
||||
|
||||
@@ -11,20 +11,18 @@ type Args = {
|
||||
}
|
||||
|
||||
export function NestProviders({ children, importMap, providers }: Args): React.ReactNode {
|
||||
return (
|
||||
<RenderServerComponent
|
||||
clientProps={{
|
||||
children:
|
||||
providers.length > 1 ? (
|
||||
<NestProviders importMap={importMap} providers={providers.slice(1)}>
|
||||
{children}
|
||||
</NestProviders>
|
||||
) : (
|
||||
children
|
||||
),
|
||||
}}
|
||||
Component={providers[0]}
|
||||
importMap={importMap}
|
||||
/>
|
||||
)
|
||||
return RenderServerComponent({
|
||||
clientProps: {
|
||||
children:
|
||||
providers.length > 1 ? (
|
||||
<NestProviders importMap={importMap} providers={providers.slice(1)}>
|
||||
{children}
|
||||
</NestProviders>
|
||||
) : (
|
||||
children
|
||||
),
|
||||
},
|
||||
Component: providers[0],
|
||||
importMap,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -20,6 +20,14 @@ export const OGImage: React.FC<{
|
||||
leader,
|
||||
title,
|
||||
}) => {
|
||||
const IconComponent = RenderServerComponent({
|
||||
clientProps: {
|
||||
fill: 'white',
|
||||
},
|
||||
Component: Icon,
|
||||
Fallback,
|
||||
importMap,
|
||||
})
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
@@ -95,14 +103,7 @@ export const OGImage: React.FC<{
|
||||
width: '38px',
|
||||
}}
|
||||
>
|
||||
<RenderServerComponent
|
||||
clientProps={{
|
||||
fill: 'white',
|
||||
}}
|
||||
Component={Icon}
|
||||
Fallback={Fallback}
|
||||
importMap={importMap}
|
||||
/>
|
||||
{IconComponent}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -56,13 +56,15 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
|
||||
? viewActions.reduce((acc, action) => {
|
||||
if (action) {
|
||||
if (typeof action === 'object') {
|
||||
acc[action.path] = (
|
||||
<RenderServerComponent Component={action} importMap={payload.importMap} />
|
||||
)
|
||||
acc[action.path] = RenderServerComponent({
|
||||
Component: action,
|
||||
importMap: payload.importMap,
|
||||
})
|
||||
} else {
|
||||
acc[action] = (
|
||||
<RenderServerComponent Component={action} importMap={payload.importMap} />
|
||||
)
|
||||
acc[action] = RenderServerComponent({
|
||||
Component: action,
|
||||
importMap: payload.importMap,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,15 +74,32 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
|
||||
}
|
||||
}, [viewActions, payload])
|
||||
|
||||
const NavComponent = RenderServerComponent({
|
||||
clientProps: { clientProps: { visibleEntities } },
|
||||
Component: CustomNav,
|
||||
Fallback: DefaultNav,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
visibleEntities,
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<EntityVisibilityProvider visibleEntities={visibleEntities}>
|
||||
<BulkUploadProvider>
|
||||
<ActionsProvider Actions={Actions}>
|
||||
<RenderServerComponent
|
||||
clientProps={{ clientProps: { visibleEntities } }}
|
||||
Component={CustomHeader}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
clientProps: { clientProps: { visibleEntities } },
|
||||
Component: CustomHeader,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -89,8 +108,8 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
|
||||
searchParams,
|
||||
user,
|
||||
visibleEntities,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
<div style={{ position: 'relative' }}>
|
||||
<div className={`${baseClass}__nav-toggler-wrapper`} id="nav-toggler">
|
||||
<div className={`${baseClass}__nav-toggler-container`} id="nav-toggler">
|
||||
@@ -100,39 +119,24 @@ export const DefaultTemplate: React.FC<DefaultTemplateProps> = ({
|
||||
</div>
|
||||
</div>
|
||||
<Wrapper baseClass={baseClass} className={className}>
|
||||
<RenderServerComponent
|
||||
clientProps={{ clientProps: { visibleEntities } }}
|
||||
Component={CustomNav}
|
||||
Fallback={DefaultNav}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
payload,
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
visibleEntities,
|
||||
}}
|
||||
/>
|
||||
{NavComponent}
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<AppHeader
|
||||
CustomAvatar={
|
||||
avatar !== 'gravatar' && avatar !== 'default' ? (
|
||||
<RenderServerComponent
|
||||
Component={avatar.Component}
|
||||
importMap={payload.importMap}
|
||||
/>
|
||||
) : undefined
|
||||
avatar !== 'gravatar' && avatar !== 'default'
|
||||
? RenderServerComponent({
|
||||
Component: avatar.Component,
|
||||
importMap: payload.importMap,
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
CustomIcon={
|
||||
components?.graphics?.Icon ? (
|
||||
<RenderServerComponent
|
||||
Component={components.graphics.Icon}
|
||||
importMap={payload.importMap}
|
||||
/>
|
||||
) : undefined
|
||||
components?.graphics?.Icon
|
||||
? RenderServerComponent({
|
||||
Component: components.graphics.Icon,
|
||||
importMap: payload.importMap,
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
{children}
|
||||
|
||||
@@ -137,11 +137,11 @@ export const Account: React.FC<AdminViewProps> = async ({
|
||||
permissions={permissions}
|
||||
/>
|
||||
<HydrateAuthProvider permissions={permissions} />
|
||||
<RenderServerComponent
|
||||
Component={config.admin?.components?.views?.account?.Component}
|
||||
Fallback={EditView}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
Component: config.admin?.components?.views?.account?.Component,
|
||||
Fallback: EditView,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
initPageResult,
|
||||
locale,
|
||||
@@ -151,8 +151,8 @@ export const Account: React.FC<AdminViewProps> = async ({
|
||||
routeSegments: [],
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
<AccountClient />
|
||||
</EditDepthProvider>
|
||||
</DocumentInfoProvider>
|
||||
|
||||
@@ -49,11 +49,11 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<Gutter className={`${baseClass}__wrap`}>
|
||||
{beforeDashboard && (
|
||||
<RenderServerComponent
|
||||
Component={beforeDashboard}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{beforeDashboard &&
|
||||
RenderServerComponent({
|
||||
Component: beforeDashboard,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -61,9 +61,9 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
},
|
||||
})}
|
||||
|
||||
<Fragment>
|
||||
{!navGroups || navGroups?.length === 0 ? (
|
||||
<p>no nav groups....</p>
|
||||
@@ -168,11 +168,11 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
|
||||
})
|
||||
)}
|
||||
</Fragment>
|
||||
{afterDashboard && (
|
||||
<RenderServerComponent
|
||||
Component={afterDashboard}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{afterDashboard &&
|
||||
RenderServerComponent({
|
||||
Component: afterDashboard,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -180,9 +180,8 @@ export const DefaultDashboard: React.FC<DashboardProps> = (props) => {
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
},
|
||||
})}
|
||||
</Gutter>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -108,15 +108,15 @@ export const Dashboard: React.FC<AdminViewProps> = async ({
|
||||
<Fragment>
|
||||
<HydrateAuthProvider permissions={permissions} />
|
||||
<SetStepNav nav={[]} />
|
||||
<RenderServerComponent
|
||||
clientProps={{
|
||||
{RenderServerComponent({
|
||||
clientProps: {
|
||||
Link,
|
||||
locale,
|
||||
}}
|
||||
Component={config.admin?.components?.views?.dashboard?.Component}
|
||||
Fallback={DefaultDashboard}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
},
|
||||
Component: config.admin?.components?.views?.dashboard?.Component,
|
||||
Fallback: DefaultDashboard,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
globalData,
|
||||
i18n,
|
||||
Link,
|
||||
@@ -128,8 +128,8 @@ export const Dashboard: React.FC<AdminViewProps> = async ({
|
||||
searchParams,
|
||||
user,
|
||||
visibleEntities,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -345,27 +345,23 @@ export const renderDocument = async ({
|
||||
)}
|
||||
<HydrateAuthProvider permissions={permissions} />
|
||||
<EditDepthProvider>
|
||||
{ErrorView ? (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={ErrorView.ComponentConfig || ErrorView.Component}
|
||||
importMap={importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
) : (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={
|
||||
RootViewOverride
|
||||
{ErrorView
|
||||
? RenderServerComponent({
|
||||
clientProps,
|
||||
Component: ErrorView.ComponentConfig || ErrorView.Component,
|
||||
importMap,
|
||||
serverProps,
|
||||
})
|
||||
: RenderServerComponent({
|
||||
clientProps,
|
||||
Component: RootViewOverride
|
||||
? RootViewOverride
|
||||
: CustomView?.ComponentConfig || CustomView?.Component
|
||||
? CustomView?.ComponentConfig || CustomView?.Component
|
||||
: DefaultView?.ComponentConfig || DefaultView?.Component
|
||||
}
|
||||
importMap={importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)}
|
||||
: DefaultView?.ComponentConfig || DefaultView?.Component,
|
||||
importMap,
|
||||
serverProps,
|
||||
})}
|
||||
</EditDepthProvider>
|
||||
</DocumentInfoProvider>
|
||||
),
|
||||
|
||||
@@ -34,9 +34,10 @@ export const renderDocumentSlots: (args: {
|
||||
globalConfig?.admin?.components?.elements?.PreviewButton
|
||||
|
||||
if (isPreviewEnabled && CustomPreviewButton) {
|
||||
components.PreviewButton = (
|
||||
<RenderServerComponent Component={CustomPreviewButton} importMap={req.payload.importMap} />
|
||||
)
|
||||
components.PreviewButton = RenderServerComponent({
|
||||
Component: CustomPreviewButton,
|
||||
importMap: req.payload.importMap,
|
||||
})
|
||||
}
|
||||
|
||||
const descriptionFromConfig =
|
||||
@@ -54,14 +55,12 @@ export const renderDocumentSlots: (args: {
|
||||
const hasDescription = CustomDescription || staticDescription
|
||||
|
||||
if (hasDescription) {
|
||||
components.Description = (
|
||||
<RenderServerComponent
|
||||
clientProps={{ description: staticDescription }}
|
||||
Component={CustomDescription}
|
||||
Fallback={ViewDescription}
|
||||
importMap={req.payload.importMap}
|
||||
/>
|
||||
)
|
||||
components.Description = RenderServerComponent({
|
||||
clientProps: { description: staticDescription },
|
||||
Component: CustomDescription,
|
||||
Fallback: ViewDescription,
|
||||
importMap: req.payload.importMap,
|
||||
})
|
||||
}
|
||||
|
||||
if (hasSavePermission) {
|
||||
@@ -71,12 +70,10 @@ export const renderDocumentSlots: (args: {
|
||||
globalConfig?.admin?.components?.elements?.PublishButton
|
||||
|
||||
if (CustomPublishButton) {
|
||||
components.PublishButton = (
|
||||
<RenderServerComponent
|
||||
Component={CustomPublishButton}
|
||||
importMap={req.payload.importMap}
|
||||
/>
|
||||
)
|
||||
components.PublishButton = RenderServerComponent({
|
||||
Component: CustomPublishButton,
|
||||
importMap: req.payload.importMap,
|
||||
})
|
||||
}
|
||||
const CustomSaveDraftButton =
|
||||
collectionConfig?.admin?.components?.edit?.SaveDraftButton ||
|
||||
@@ -87,12 +84,10 @@ export const renderDocumentSlots: (args: {
|
||||
(globalConfig?.versions?.drafts && !globalConfig?.versions?.drafts?.autosave)
|
||||
|
||||
if ((draftsEnabled || unsavedDraftWithValidations) && CustomSaveDraftButton) {
|
||||
components.SaveDraftButton = (
|
||||
<RenderServerComponent
|
||||
Component={CustomSaveDraftButton}
|
||||
importMap={req.payload.importMap}
|
||||
/>
|
||||
)
|
||||
components.SaveDraftButton = RenderServerComponent({
|
||||
Component: CustomSaveDraftButton,
|
||||
importMap: req.payload.importMap,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
const CustomSaveButton =
|
||||
@@ -100,9 +95,10 @@ export const renderDocumentSlots: (args: {
|
||||
globalConfig?.admin?.components?.elements?.SaveButton
|
||||
|
||||
if (CustomSaveButton) {
|
||||
components.SaveButton = (
|
||||
<RenderServerComponent Component={CustomSaveButton} importMap={req.payload.importMap} />
|
||||
)
|
||||
components.SaveButton = RenderServerComponent({
|
||||
Component: CustomSaveButton,
|
||||
importMap: req.payload.importMap,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,18 +243,18 @@ export const renderListView = async (
|
||||
modifySearchParams={!isInDrawer}
|
||||
preferenceKey={preferenceKey}
|
||||
>
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={collectionConfig?.admin?.components?.views?.list?.Component}
|
||||
Fallback={DefaultListView}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
clientProps,
|
||||
Component: collectionConfig?.admin?.components?.views?.list?.Component,
|
||||
Fallback: DefaultListView,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
...sharedServerProps,
|
||||
data,
|
||||
listPreferences,
|
||||
listSearchableFields: collectionConfig.admin.listSearchableFields,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
</ListQueryProvider>
|
||||
</Fragment>
|
||||
),
|
||||
|
||||
@@ -24,61 +24,51 @@ export const renderListViewSlots = ({
|
||||
const result: ListViewSlots = {} as ListViewSlots
|
||||
|
||||
if (collectionConfig.admin.components?.afterList) {
|
||||
result.AfterList = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={collectionConfig.admin.components.afterList}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
result.AfterList = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: collectionConfig.admin.components.afterList,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if (collectionConfig.admin.components?.afterListTable) {
|
||||
result.AfterListTable = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={collectionConfig.admin.components.afterListTable}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
result.AfterListTable = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: collectionConfig.admin.components.afterListTable,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if (collectionConfig.admin.components?.beforeList) {
|
||||
result.BeforeList = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={collectionConfig.admin.components.beforeList}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
result.BeforeList = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: collectionConfig.admin.components.beforeList,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if (collectionConfig.admin.components?.beforeListTable) {
|
||||
result.BeforeListTable = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={collectionConfig.admin.components.beforeListTable}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
result.BeforeListTable = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: collectionConfig.admin.components.beforeListTable,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if (collectionConfig.admin.components?.Description) {
|
||||
result.Description = (
|
||||
<RenderServerComponent
|
||||
clientProps={{
|
||||
description,
|
||||
...clientProps,
|
||||
}}
|
||||
Component={collectionConfig.admin.components.Description}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
result.Description = RenderServerComponent({
|
||||
clientProps: {
|
||||
description,
|
||||
...clientProps,
|
||||
},
|
||||
Component: collectionConfig.admin.components.Description,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -65,10 +65,10 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
user={user}
|
||||
/>
|
||||
</div>
|
||||
<RenderServerComponent
|
||||
Component={beforeLogin}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
Component: beforeLogin,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -76,8 +76,9 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
|
||||
{!collectionConfig?.auth?.disableLocalStrategy && (
|
||||
<LoginForm
|
||||
prefillEmail={prefillEmail}
|
||||
@@ -86,10 +87,10 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
searchParams={searchParams}
|
||||
/>
|
||||
)}
|
||||
<RenderServerComponent
|
||||
Component={afterLogin}
|
||||
importMap={payload.importMap}
|
||||
serverProps={{
|
||||
{RenderServerComponent({
|
||||
Component: afterLogin,
|
||||
importMap: payload.importMap,
|
||||
serverProps: {
|
||||
i18n,
|
||||
locale,
|
||||
params,
|
||||
@@ -97,8 +98,8 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
permissions,
|
||||
searchParams,
|
||||
user,
|
||||
}}
|
||||
/>
|
||||
},
|
||||
})}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,24 +127,22 @@ export const RootPage = async ({
|
||||
importMap,
|
||||
})
|
||||
|
||||
const RenderedView = (
|
||||
<RenderServerComponent
|
||||
clientProps={{ clientConfig }}
|
||||
Component={DefaultView.payloadComponent}
|
||||
Fallback={DefaultView.Component}
|
||||
importMap={importMap}
|
||||
serverProps={{
|
||||
...serverProps,
|
||||
clientConfig,
|
||||
i18n: initPageResult?.req.i18n,
|
||||
importMap,
|
||||
initPageResult,
|
||||
params,
|
||||
payload: initPageResult?.req.payload,
|
||||
searchParams,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
const RenderedView = RenderServerComponent({
|
||||
clientProps: { clientConfig },
|
||||
Component: DefaultView.payloadComponent,
|
||||
Fallback: DefaultView.Component,
|
||||
importMap,
|
||||
serverProps: {
|
||||
...serverProps,
|
||||
clientConfig,
|
||||
i18n: initPageResult?.req.i18n,
|
||||
importMap,
|
||||
initPageResult,
|
||||
params,
|
||||
payload: initPageResult?.req.payload,
|
||||
searchParams,
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
@@ -175,10 +175,6 @@ export const sanitizeFields = async ({
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof field.virtual === 'undefined') {
|
||||
field.virtual = false
|
||||
}
|
||||
|
||||
if (!field.hooks) {
|
||||
field.hooks = {}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { renderField } from '@payloadcms/ui/forms/renderField'
|
||||
import React from 'react'
|
||||
|
||||
import type { SanitizedServerEditorConfig } from '../lexical/config/types.js'
|
||||
import type { LexicalFieldAdminProps } from '../types.js'
|
||||
import type { LexicalFieldAdminProps, LexicalRichTextFieldProps } from '../types.js'
|
||||
|
||||
// eslint-disable-next-line payload/no-imports-from-exports-dir
|
||||
import { RichTextField } from '../exports/client/index.js'
|
||||
@@ -57,20 +57,26 @@ export const RscEntryLexicalField: React.FC<
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<RichTextField
|
||||
admin={args.admin}
|
||||
clientFeatures={clientFeatures}
|
||||
featureClientSchemaMap={featureClientSchemaMap}
|
||||
field={args.clientField as RichTextFieldClient}
|
||||
forceRender={args.forceRender}
|
||||
initialLexicalFormState={initialLexicalFormState}
|
||||
lexicalEditorConfig={args.sanitizedEditorConfig.lexical}
|
||||
path={path}
|
||||
permissions={args.permissions}
|
||||
readOnly={args.readOnly}
|
||||
renderedBlocks={args.renderedBlocks}
|
||||
schemaPath={schemaPath}
|
||||
/>
|
||||
)
|
||||
const props: LexicalRichTextFieldProps = {
|
||||
admin: args.admin,
|
||||
clientFeatures,
|
||||
featureClientSchemaMap,
|
||||
field: args.clientField as RichTextFieldClient,
|
||||
forceRender: args.forceRender,
|
||||
initialLexicalFormState,
|
||||
lexicalEditorConfig: args.sanitizedEditorConfig.lexical,
|
||||
path,
|
||||
permissions: args.permissions,
|
||||
readOnly: args.readOnly,
|
||||
renderedBlocks: args.renderedBlocks,
|
||||
schemaPath,
|
||||
}
|
||||
|
||||
for (const key in props) {
|
||||
if (!props[key]) {
|
||||
delete props[key]
|
||||
}
|
||||
}
|
||||
|
||||
return <RichTextField {...props} />
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ import type {
|
||||
Field,
|
||||
FieldPaths,
|
||||
RichTextFieldClient,
|
||||
ServerComponentProps } from 'payload'
|
||||
ServerComponentProps,
|
||||
} from 'payload'
|
||||
|
||||
import { RenderServerComponent } from '@payloadcms/ui/elements/RenderServerComponent'
|
||||
import { createClientFields, deepCopyObjectSimple } from 'payload'
|
||||
@@ -56,31 +57,31 @@ export const RscEntrySlateField: React.FC<
|
||||
|
||||
componentMap.set(
|
||||
`leaf.button.${leafObject.name}`,
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={LeafButton}
|
||||
importMap={payload.importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: LeafButton,
|
||||
importMap: payload.importMap,
|
||||
}),
|
||||
)
|
||||
|
||||
componentMap.set(
|
||||
`leaf.component.${leafObject.name}`,
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={LeafComponent}
|
||||
importMap={payload.importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: LeafComponent,
|
||||
importMap: payload.importMap,
|
||||
}),
|
||||
)
|
||||
|
||||
if (Array.isArray(leafObject.plugins)) {
|
||||
leafObject.plugins.forEach((Plugin, i) => {
|
||||
componentMap.set(
|
||||
`leaf.plugin.${leafObject.name}.${i}`,
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={Plugin}
|
||||
importMap={payload.importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: Plugin,
|
||||
importMap: payload.importMap,
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -102,31 +103,31 @@ export const RscEntrySlateField: React.FC<
|
||||
if (ElementButton) {
|
||||
componentMap.set(
|
||||
`element.button.${element.name}`,
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={ElementButton}
|
||||
importMap={payload.importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: ElementButton,
|
||||
importMap: payload.importMap,
|
||||
}),
|
||||
)
|
||||
}
|
||||
componentMap.set(
|
||||
`element.component.${element.name}`,
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={ElementComponent}
|
||||
importMap={payload.importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: ElementComponent,
|
||||
importMap: payload.importMap,
|
||||
}),
|
||||
)
|
||||
|
||||
if (Array.isArray(element.plugins)) {
|
||||
element.plugins.forEach((Plugin, i) => {
|
||||
componentMap.set(
|
||||
`element.plugin.${element.name}.${i}`,
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={Plugin}
|
||||
importMap={payload.importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: Plugin,
|
||||
importMap: payload.importMap,
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@ import React from 'react'
|
||||
|
||||
import { removeUndefined } from '../../utilities/removeUndefined.js'
|
||||
|
||||
/**
|
||||
* Can be used to render both MappedComponents and React Components.
|
||||
*/
|
||||
export const RenderServerComponent: React.FC<{
|
||||
type RenderServerComponentFn = (args: {
|
||||
readonly clientProps?: object
|
||||
readonly Component?:
|
||||
| PayloadComponent
|
||||
@@ -17,18 +14,31 @@ export const RenderServerComponent: React.FC<{
|
||||
| React.ComponentType[]
|
||||
readonly Fallback?: React.ComponentType
|
||||
readonly importMap: ImportMap
|
||||
readonly key?: string
|
||||
readonly serverProps?: object
|
||||
}> = ({ clientProps = {}, Component, Fallback, importMap, serverProps }) => {
|
||||
}) => React.ReactNode
|
||||
|
||||
/**
|
||||
* Can be used to render both MappedComponents and React Components.
|
||||
*/
|
||||
export const RenderServerComponent: RenderServerComponentFn = ({
|
||||
clientProps = {},
|
||||
Component,
|
||||
Fallback,
|
||||
importMap,
|
||||
key,
|
||||
serverProps,
|
||||
}) => {
|
||||
if (Array.isArray(Component)) {
|
||||
return Component.map((c, index) => (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={c}
|
||||
importMap={importMap}
|
||||
key={index}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
))
|
||||
return Component.map((c, index) =>
|
||||
RenderServerComponent({
|
||||
clientProps,
|
||||
Component: c,
|
||||
importMap,
|
||||
key: index,
|
||||
serverProps,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
if (typeof Component === 'function') {
|
||||
@@ -40,7 +50,7 @@ export const RenderServerComponent: React.FC<{
|
||||
...(isRSC ? serverProps : {}),
|
||||
})
|
||||
|
||||
return <Component {...sanitizedProps} />
|
||||
return <Component key={key} {...sanitizedProps} />
|
||||
}
|
||||
|
||||
if (typeof Component === 'string' || isPlainObject(Component)) {
|
||||
@@ -63,16 +73,17 @@ export const RenderServerComponent: React.FC<{
|
||||
...(typeof Component === 'object' && Component?.clientProps ? Component.clientProps : {}),
|
||||
})
|
||||
|
||||
return <ResolvedComponent {...sanitizedProps} />
|
||||
return <ResolvedComponent key={key} {...sanitizedProps} />
|
||||
}
|
||||
}
|
||||
|
||||
return Fallback ? (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={Fallback}
|
||||
importMap={importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
) : null
|
||||
return Fallback
|
||||
? RenderServerComponent({
|
||||
clientProps,
|
||||
Component: Fallback,
|
||||
importMap,
|
||||
key,
|
||||
serverProps,
|
||||
})
|
||||
: null
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import type {
|
||||
Field,
|
||||
PaginatedDocs,
|
||||
Payload,
|
||||
PayloadComponent,
|
||||
SanitizedCollectionConfig,
|
||||
StaticLabel,
|
||||
} from 'payload'
|
||||
@@ -151,9 +150,9 @@ export const buildColumnState = (args: Args): Column[] => {
|
||||
? _field.admin.components.Label
|
||||
: undefined
|
||||
|
||||
const CustomLabel = CustomLabelToRender ? (
|
||||
<RenderServerComponent Component={CustomLabelToRender} importMap={payload.importMap} />
|
||||
) : undefined
|
||||
const CustomLabel = CustomLabelToRender
|
||||
? RenderServerComponent({ Component: CustomLabelToRender, importMap: payload.importMap })
|
||||
: undefined
|
||||
|
||||
const fieldAffectsDataSubFields =
|
||||
field &&
|
||||
@@ -220,41 +219,25 @@ export const buildColumnState = (args: Args): Column[] => {
|
||||
_field.admin.components = {}
|
||||
}
|
||||
|
||||
/**
|
||||
* We have to deep copy all the props we send to the client (= CellComponent.clientProps).
|
||||
* That way, every editor's field / cell props we send to the client have their own object references.
|
||||
*
|
||||
* If we send the same object reference to the client twice (e.g. through some configurations where 2 or more fields
|
||||
* reference the same editor object, like the root editor), the admin panel may hang indefinitely. This has been happening since
|
||||
* a newer Next.js update that made it break when sending the same object reference to the client twice.
|
||||
*
|
||||
* We can use deepCopyObjectSimple as client props should be JSON-serializable.
|
||||
*/
|
||||
const CellComponent: PayloadComponent = _field.editor.CellComponent
|
||||
if (typeof CellComponent === 'object' && CellComponent.clientProps) {
|
||||
CellComponent.clientProps = deepCopyObjectSimple(CellComponent.clientProps)
|
||||
}
|
||||
|
||||
CustomCell = (
|
||||
<RenderServerComponent
|
||||
clientProps={cellClientProps}
|
||||
Component={CellComponent}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
CustomCell = RenderServerComponent({
|
||||
clientProps: cellClientProps,
|
||||
Component: _field.editor.CellComponent,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
} else {
|
||||
CustomCell =
|
||||
_field?.admin && 'components' in _field.admin && _field.admin.components?.Cell ? (
|
||||
<RenderServerComponent
|
||||
clientProps={cellClientProps}
|
||||
Component={
|
||||
_field?.admin && 'components' in _field.admin && _field.admin.components?.Cell
|
||||
}
|
||||
importMap={payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
) : undefined
|
||||
_field?.admin && 'components' in _field.admin && _field.admin.components?.Cell
|
||||
? RenderServerComponent({
|
||||
clientProps: cellClientProps,
|
||||
Component:
|
||||
_field?.admin &&
|
||||
'components' in _field.admin &&
|
||||
_field.admin.components?.Cell,
|
||||
importMap: payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -18,7 +18,7 @@ export const WithServerSideProps: WithServerSidePropsComponent = ({
|
||||
return <Component {...propsWithServerOnlyProps} />
|
||||
}
|
||||
|
||||
return <WithServerSideProps {...rest} />
|
||||
return WithServerSideProps(rest)
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@@ -2,7 +2,6 @@ import type {
|
||||
ClientComponentProps,
|
||||
ClientField,
|
||||
FieldPaths,
|
||||
PayloadComponent,
|
||||
SanitizedFieldPermissions,
|
||||
ServerComponentProps,
|
||||
} from 'payload'
|
||||
@@ -109,20 +108,18 @@ export const renderField: RenderFieldMethod = ({
|
||||
fieldState.customComponents.RowLabels = []
|
||||
}
|
||||
|
||||
fieldState.customComponents.RowLabels[rowIndex] = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.RowLabel}
|
||||
importMap={req.payload.importMap}
|
||||
serverProps={{
|
||||
...serverProps,
|
||||
rowLabel: `${getTranslation(fieldConfig.labels.singular, req.i18n)} ${String(
|
||||
rowIndex + 1,
|
||||
).padStart(2, '0')}`,
|
||||
rowNumber: rowIndex + 1,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.RowLabels[rowIndex] = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.RowLabel,
|
||||
importMap: req.payload.importMap,
|
||||
serverProps: {
|
||||
...serverProps,
|
||||
rowLabel: `${getTranslation(fieldConfig.labels.singular, req.i18n)} ${String(
|
||||
rowIndex + 1,
|
||||
).padStart(2, '0')}`,
|
||||
rowNumber: rowIndex + 1,
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -146,30 +143,12 @@ export const renderField: RenderFieldMethod = ({
|
||||
fieldConfig.admin.components = {}
|
||||
}
|
||||
|
||||
/**
|
||||
* We have to deep copy all the props we send to the client (= FieldComponent.clientProps).
|
||||
* That way, every editor's field / cell props we send to the client have their own object references.
|
||||
*
|
||||
* If we send the same object reference to the client twice (e.g. through some configurations where 2 or more fields
|
||||
* reference the same editor object, like the root editor), the admin panel may hang indefinitely. This has been happening since
|
||||
* a newer Next.js update that made it break when sending the same object reference to the client twice.
|
||||
*
|
||||
* We can use deepCopyObjectSimple as client props should be JSON-serializable.
|
||||
*/
|
||||
const FieldComponent: PayloadComponent = fieldConfig.editor.FieldComponent
|
||||
if (typeof FieldComponent === 'object' && FieldComponent.clientProps) {
|
||||
FieldComponent.clientProps = deepCopyObjectSimple(FieldComponent.clientProps)
|
||||
}
|
||||
|
||||
fieldState.customComponents.Field = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={FieldComponent}
|
||||
Fallback={undefined}
|
||||
importMap={req.payload.importMap}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.Field = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.editor.FieldComponent,
|
||||
importMap: req.payload.importMap,
|
||||
serverProps,
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
@@ -182,15 +161,13 @@ export const renderField: RenderFieldMethod = ({
|
||||
continue
|
||||
}
|
||||
const Component = fieldConfig.admin.components[key]
|
||||
fieldState.customComponents[key] = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={Component}
|
||||
importMap={req.payload.importMap}
|
||||
key={`field.admin.components.${key}`}
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents[key] = RenderServerComponent({
|
||||
clientProps,
|
||||
Component,
|
||||
importMap: req.payload.importMap,
|
||||
key: `field.admin.components.${key}`,
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
@@ -217,75 +194,63 @@ export const renderField: RenderFieldMethod = ({
|
||||
|
||||
if (fieldConfig.admin?.components) {
|
||||
if ('afterInput' in fieldConfig.admin.components) {
|
||||
fieldState.customComponents.AfterInput = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.afterInput}
|
||||
importMap={req.payload.importMap}
|
||||
key="field.admin.components.afterInput"
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.AfterInput = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.afterInput,
|
||||
importMap: req.payload.importMap,
|
||||
key: 'field.admin.components.afterInput',
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if ('beforeInput' in fieldConfig.admin.components) {
|
||||
fieldState.customComponents.BeforeInput = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.beforeInput}
|
||||
importMap={req.payload.importMap}
|
||||
key="field.admin.components.beforeInput"
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.BeforeInput = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.beforeInput,
|
||||
importMap: req.payload.importMap,
|
||||
key: 'field.admin.components.beforeInput',
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if ('Description' in fieldConfig.admin.components) {
|
||||
fieldState.customComponents.Description = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.Description}
|
||||
importMap={req.payload.importMap}
|
||||
key="field.admin.components.Description"
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.Description = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.Description,
|
||||
importMap: req.payload.importMap,
|
||||
key: 'field.admin.components.Description',
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if ('Error' in fieldConfig.admin.components) {
|
||||
fieldState.customComponents.Error = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.Error}
|
||||
importMap={req.payload.importMap}
|
||||
key="field.admin.components.Error"
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.Error = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.Error,
|
||||
importMap: req.payload.importMap,
|
||||
key: 'field.admin.components.Error',
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if ('Label' in fieldConfig.admin.components) {
|
||||
fieldState.customComponents.Label = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.Label}
|
||||
importMap={req.payload.importMap}
|
||||
key="field.admin.components.Label"
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.Label = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.Label,
|
||||
importMap: req.payload.importMap,
|
||||
key: 'field.admin.components.Label',
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
|
||||
if ('Field' in fieldConfig.admin.components) {
|
||||
fieldState.customComponents.Field = (
|
||||
<RenderServerComponent
|
||||
clientProps={clientProps}
|
||||
Component={fieldConfig.admin.components.Field}
|
||||
importMap={req.payload.importMap}
|
||||
key="field.admin.components.Field"
|
||||
serverProps={serverProps}
|
||||
/>
|
||||
)
|
||||
fieldState.customComponents.Field = RenderServerComponent({
|
||||
clientProps,
|
||||
Component: fieldConfig.admin.components.Field,
|
||||
importMap: req.payload.importMap,
|
||||
key: 'field.admin.components.Field',
|
||||
serverProps,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ export const renderFilters = (
|
||||
if ('name' in field && field.admin?.components?.Filter) {
|
||||
acc.set(
|
||||
field.name,
|
||||
<RenderServerComponent
|
||||
Component={field.admin.components?.Filter}
|
||||
importMap={importMap}
|
||||
/>,
|
||||
RenderServerComponent({
|
||||
Component: field.admin.components?.Filter,
|
||||
importMap,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ export const AfterDashboardClient: PayloadServerReactComponent<CustomComponent>
|
||||
return (
|
||||
<Banner>
|
||||
<p>Admin Dependency test component:</p>
|
||||
<RenderServerComponent
|
||||
Component={payload.config.admin.dependencies?.myTestComponent}
|
||||
importMap={payload.importMap}
|
||||
/>
|
||||
{RenderServerComponent({
|
||||
Component: payload.config.admin.dependencies?.myTestComponent,
|
||||
importMap: payload.importMap,
|
||||
})}
|
||||
</Banner>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user