diff --git a/packages/next/src/views/Document/getViewsFromConfig.tsx b/packages/next/src/views/Document/getViewsFromConfig.tsx index 0d3355d5a..673312516 100644 --- a/packages/next/src/views/Document/getViewsFromConfig.tsx +++ b/packages/next/src/views/Document/getViewsFromConfig.tsx @@ -28,6 +28,7 @@ export const getViewsFromConfig = ({ }: { collectionConfig?: SanitizedCollectionConfig config: SanitizedConfig + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents docPermissions: CollectionPermission | GlobalPermission globalConfig?: SanitizedGlobalConfig routeSegments: string[] @@ -56,50 +57,46 @@ export const getViewsFromConfig = ({ config?.admin?.livePreview?.globals?.includes(globalConfig?.slug) if (collectionConfig) { - const [collectionEntity, collectionSlug, createOrID, nestedViewSlug, segmentFive] = - routeSegments + const editConfig = collectionConfig?.admin?.components?.views?.Edit + const EditOverride = typeof editConfig === 'function' ? editConfig : null - const { - admin: { hidden }, - } = collectionConfig - - if (isEntityHidden({ hidden, user })) { - return null + if (EditOverride) { + CustomView = EditOverride } - // `../:id`, or `../create` - if (!nestedViewSlug) { - switch (createOrID) { - case 'create': { - if ('create' in docPermissions && docPermissions?.create?.permission) { - CustomView = getCustomViewByKey(views, 'Default') - DefaultView = DefaultEditView - } else { - ErrorView = Unauthorized - } - break - } + if (!EditOverride) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [collectionEntity, collectionSlug, createOrID, nestedViewSlug, segmentFive] = + routeSegments - default: { - if (docPermissions?.read?.permission) { - CustomView = getCustomViewByKey(views, 'Default') - DefaultView = DefaultEditView - } else { - ErrorView = Unauthorized - } - } + const { + admin: { hidden }, + } = collectionConfig + + if (isEntityHidden({ hidden, user })) { + return null } - } - if (nestedViewSlug) { - // `../:id/versions/:version`, etc - if (segmentFive) { - if (nestedViewSlug === 'versions') { - if (docPermissions?.readVersions?.permission) { - CustomView = getCustomViewByKey(views, 'Version') - DefaultView = DefaultVersionView - } else { - ErrorView = Unauthorized + // `../:id`, or `../create` + if (routeSegments.length === 3) { + switch (createOrID) { + case 'create': { + if ('create' in docPermissions && docPermissions?.create?.permission) { + CustomView = getCustomViewByKey(views, 'Default') + DefaultView = DefaultEditView + } else { + ErrorView = Unauthorized + } + break + } + + default: { + if (docPermissions?.read?.permission) { + CustomView = getCustomViewByKey(views, 'Default') + DefaultView = DefaultEditView + } else { + ErrorView = Unauthorized + } } } } @@ -139,75 +136,101 @@ export const getViewsFromConfig = ({ } } } + + // `../:id/versions/:version`, etc + if (routeSegments.length === 5) { + if (nestedViewSlug === 'versions') { + if (docPermissions?.readVersions?.permission) { + CustomView = getCustomViewByKey(views, 'Version') + DefaultView = DefaultVersionView + } else { + ErrorView = Unauthorized + } + } + } } } if (globalConfig) { - const [globalEntity, globalSlug, nestedViewSlug] = routeSegments + const editConfig = globalConfig?.admin?.components?.views?.Edit + const EditOverride = typeof editConfig === 'function' ? editConfig : null - const { - admin: { hidden }, - } = globalConfig - - if (isEntityHidden({ hidden, user })) { - return null + if (EditOverride) { + CustomView = EditOverride } - if (routeSegments?.length === 2) { - if (docPermissions?.read?.permission) { - CustomView = getCustomViewByKey(views, 'Default') - DefaultView = DefaultEditView - } else { - ErrorView = Unauthorized + if (!EditOverride) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [globalEntity, globalSlug, nestedViewSlug] = routeSegments + + const { + admin: { hidden }, + } = globalConfig + + if (isEntityHidden({ hidden, user })) { + return null } - } else if (routeSegments?.length === 3) { - // `../:slug/api`, `../:slug/preview`, `../:slug/versions`, etc - switch (nestedViewSlug) { - case 'api': { - if (globalConfig?.admin?.hideAPIURL !== true) { - CustomView = getCustomViewByKey(views, 'API') - DefaultView = DefaultAPIView - } - break - } - case 'preview': { - if (livePreviewEnabled) { - DefaultView = DefaultLivePreviewView - } - break - } - - case 'versions': { - if (docPermissions?.readVersions?.permission) { - CustomView = getCustomViewByKey(views, 'Versions') - DefaultView = DefaultVersionsView - } else { - ErrorView = Unauthorized - } - break - } - - default: { - if (docPermissions?.read?.permission) { - CustomView = getCustomViewByKey(views, 'Default') - DefaultView = DefaultEditView - } else { - ErrorView = Unauthorized - } - break - } - } - } else if (routeSegments?.length === 4) { - // `../:slug/versions/:version`, etc - if (nestedViewSlug === 'versions') { - if (docPermissions?.readVersions?.permission) { - CustomView = getCustomViewByKey(views, 'Version') - DefaultView = DefaultVersionView + if (routeSegments?.length === 2) { + if (docPermissions?.read?.permission) { + CustomView = getCustomViewByKey(views, 'Default') + DefaultView = DefaultEditView } else { ErrorView = Unauthorized } } + + if (routeSegments?.length === 3) { + // `../:slug/api`, `../:slug/preview`, `../:slug/versions`, etc + switch (nestedViewSlug) { + case 'api': { + if (globalConfig?.admin?.hideAPIURL !== true) { + CustomView = getCustomViewByKey(views, 'API') + DefaultView = DefaultAPIView + } + break + } + + case 'preview': { + if (livePreviewEnabled) { + DefaultView = DefaultLivePreviewView + } + break + } + + case 'versions': { + if (docPermissions?.readVersions?.permission) { + CustomView = getCustomViewByKey(views, 'Versions') + DefaultView = DefaultVersionsView + } else { + ErrorView = Unauthorized + } + break + } + + default: { + if (docPermissions?.read?.permission) { + CustomView = getCustomViewByKey(views, 'Default') + DefaultView = DefaultEditView + } else { + ErrorView = Unauthorized + } + break + } + } + } + + if (routeSegments?.length === 4) { + // `../:slug/versions/:version`, etc + if (nestedViewSlug === 'versions') { + if (docPermissions?.readVersions?.permission) { + CustomView = getCustomViewByKey(views, 'Version') + DefaultView = DefaultVersionView + } else { + ErrorView = Unauthorized + } + } + } } } diff --git a/packages/next/src/views/Document/index.tsx b/packages/next/src/views/Document/index.tsx index f244ae1b2..f2a06d2a5 100644 --- a/packages/next/src/views/Document/index.tsx +++ b/packages/next/src/views/Document/index.tsx @@ -1,5 +1,6 @@ import type { EditViewComponent } from 'payload/config' import type { + AdminViewComponent, DocumentPreferences, Document as DocumentType, Field, @@ -25,6 +26,7 @@ import React from 'react' import type { GenerateEditViewMetadata } from './getMetaBySegment.js' import { NotFoundClient } from '../NotFound/index.client.js' +import { NotFoundView } from '../NotFound/index.js' import { getMetaBySegment } from './getMetaBySegment.js' import { getViewsFromConfig } from './getViewsFromConfig.js' @@ -62,8 +64,11 @@ export const Document: React.FC = async ({ const isEditing = Boolean(globalSlug || (collectionSlug && !!id)) + let ViewOverride: EditViewComponent let CustomView: EditViewComponent let DefaultView: EditViewComponent + let ErrorView: AdminViewComponent = NotFoundView + let data: DocumentType let docPermissions: DocumentPermissions let preferencesKey: string @@ -92,19 +97,24 @@ export const Document: React.FC = async ({ collectionConfig.versions?.drafts ? '&draft=true' : '' }` - const collectionViews = getViewsFromConfig({ - collectionConfig, - config, - docPermissions, - routeSegments: segments, - user, - }) + const editConfig = collectionConfig?.admin?.components?.views?.Edit + ViewOverride = typeof editConfig === 'function' ? editConfig : null - CustomView = collectionViews?.CustomView - DefaultView = collectionViews?.DefaultView + if (!ViewOverride) { + const collectionViews = getViewsFromConfig({ + collectionConfig, + config, + docPermissions, + routeSegments: segments, + user, + }) - if (!CustomView && !DefaultView) { - const ErrorView = collectionViews?.ErrorView || NotFoundClient + CustomView = collectionViews?.CustomView + DefaultView = collectionViews?.DefaultView + ErrorView = collectionViews?.ErrorView + } + + if (!CustomView && !DefaultView && !ViewOverride) { return } @@ -139,38 +149,43 @@ export const Document: React.FC = async ({ globalConfig.versions?.drafts ? '&draft=true' : '' }` - const globalViews = getViewsFromConfig({ - config, - docPermissions, - globalConfig, - routeSegments: segments, - user, - }) + const editConfig = globalConfig?.admin?.components?.views?.Edit + ViewOverride = typeof editConfig === 'function' ? editConfig : null - CustomView = globalViews?.CustomView - DefaultView = globalViews?.DefaultView - - if (!CustomView && !DefaultView) { - const ErrorView = globalViews?.ErrorView || NotFoundClient - return - } - - try { - data = await payload.findGlobal({ - slug: globalSlug, - depth: 0, - fallbackLocale: null, - locale: locale.code, - overrideAccess: false, + if (!ViewOverride) { + const globalViews = getViewsFromConfig({ + config, + docPermissions, + globalConfig, + routeSegments: segments, user, }) - } catch (error) {} // eslint-disable-line no-empty - if (!data) { - return + CustomView = globalViews?.CustomView + DefaultView = globalViews?.DefaultView + ErrorView = globalViews?.ErrorView + + if (!CustomView && !DefaultView && !ViewOverride) { + return + } + + try { + data = await payload.findGlobal({ + slug: globalSlug, + depth: 0, + fallbackLocale: null, + locale: locale.code, + overrideAccess: false, + user, + }) + } catch (error) {} // eslint-disable-line no-empty + + if (!data) { + return + } + + preferencesKey = `global-${globalSlug}` } - - preferencesKey = `global-${globalSlug}` } const { docs: [{ value: docPreferences } = { value: null }] = [] } = (await payload.find({ @@ -222,12 +237,14 @@ export const Document: React.FC = async ({ i18n, })} > - + {!ViewOverride && ( + + )} = async ({ }} > diff --git a/packages/next/src/views/NotFound/index.tsx b/packages/next/src/views/NotFound/index.tsx index ccc2c1f13..04fec72f5 100644 --- a/packages/next/src/views/NotFound/index.tsx +++ b/packages/next/src/views/NotFound/index.tsx @@ -1,38 +1,17 @@ -import type { SanitizedConfig } from 'payload/types' +import type { AdminViewComponent } from 'payload/types' import { DefaultTemplate } from '@payloadcms/ui' import React from 'react' -import { initPage } from '../../utilities/initPage.js' import { NotFoundClient } from './index.client.js' -export const NotFoundView = async ({ - config: configPromise, - params, - searchParams, -}: { - config: Promise - params: { - [key: string]: string | string[] - } - searchParams: { - [key: string]: string | string[] - } -}) => { - const config = await configPromise - - const initPageResult = await initPage({ - config, - route: '', - searchParams, - }) - +export const NotFoundView: AdminViewComponent = ({ initPageResult }) => { return ( diff --git a/packages/ui/src/elements/Nav/index.tsx b/packages/ui/src/elements/Nav/index.tsx index 3d6ceb68a..9844a79f7 100644 --- a/packages/ui/src/elements/Nav/index.tsx +++ b/packages/ui/src/elements/Nav/index.tsx @@ -27,6 +27,10 @@ export const DefaultNav: React.FC<{ }> = (props) => { const { config, i18n, permissions, user } = props + if (!config) { + return null + } + const { admin: { components: { afterNavLinks, beforeNavLinks }, diff --git a/packages/ui/src/templates/Default/index.tsx b/packages/ui/src/templates/Default/index.tsx index cec6e5c6b..a6ea9cb94 100644 --- a/packages/ui/src/templates/Default/index.tsx +++ b/packages/ui/src/templates/Default/index.tsx @@ -28,7 +28,7 @@ export const DefaultTemplate: React.FC = async ({ Nav: undefined, }, } = {}, - } = config + } = config || {} return (