perf: optimize getEntityConfig lookups (#10665)
Replaces array-based lookups in `getEntityConfig` with a map, reducing time complexity from O(n) to O(1).
This commit is contained in:
@@ -831,6 +831,22 @@ const MyComponent: React.FC = () => {
|
||||
}
|
||||
```
|
||||
|
||||
If you need to retrieve a specific collection or global config by its slug, `getEntityConfig` is the most efficient way to do so:
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
import { useConfig } from '@payloadcms/ui'
|
||||
|
||||
const MyComponent: React.FC = () => {
|
||||
// highlight-start
|
||||
const { getEntityConfig } = useConfig()
|
||||
const mediaConfig = getEntityConfig({ collectionSlug: 'media'})
|
||||
// highlight-end
|
||||
|
||||
return <span>The media collection has {mediaConfig.fields.length} fields.</span>
|
||||
}
|
||||
```
|
||||
|
||||
## useEditDepth
|
||||
|
||||
Sends back how many editing levels "deep" the current component is. Edit depth is relevant while adding new documents / editing documents in modal windows and other cases.
|
||||
|
||||
@@ -44,7 +44,7 @@ export function getRouteInfo({
|
||||
let idType = defaultIDType
|
||||
|
||||
if (collectionSlug) {
|
||||
collectionConfig = config.collections.find((collection) => collection.slug === collectionSlug)
|
||||
collectionConfig = payload.collections?.[collectionSlug]?.config
|
||||
}
|
||||
|
||||
if (globalSlug) {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { ClientCollectionConfig, ClientGlobalConfig } from 'payload'
|
||||
|
||||
import {
|
||||
CheckboxField,
|
||||
CopyToClipboard,
|
||||
@@ -41,8 +39,8 @@ export const APIViewClient: React.FC = () => {
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const globalConfig = getEntityConfig({ globalSlug }) as ClientGlobalConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
const globalConfig = getEntityConfig({ globalSlug })
|
||||
|
||||
const localeOptions =
|
||||
localization &&
|
||||
|
||||
@@ -42,7 +42,7 @@ export const Account: React.FC<AdminViewProps> = async ({
|
||||
serverURL,
|
||||
} = config
|
||||
|
||||
const collectionConfig = config.collections.find((collection) => collection.slug === userSlug)
|
||||
const collectionConfig = payload?.collections?.[userSlug]?.config
|
||||
|
||||
if (collectionConfig && user?.id) {
|
||||
// Fetch the data required for the view
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
'use client'
|
||||
import type { FormProps, UserWithToken } from '@payloadcms/ui'
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
DocumentPreferences,
|
||||
FormState,
|
||||
LoginWithUsernameOptions,
|
||||
@@ -45,7 +44,7 @@ export const CreateFirstUserClient: React.FC<{
|
||||
|
||||
const abortOnChangeRef = React.useRef<AbortController>(null)
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: userSlug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: userSlug })
|
||||
|
||||
const onChange: FormProps['onChange'][0] = React.useCallback(
|
||||
async ({ formState: prevFormState }) => {
|
||||
|
||||
@@ -17,15 +17,15 @@ export const CreateFirstUserView: React.FC<AdminViewProps> = async ({ initPageRe
|
||||
req,
|
||||
req: {
|
||||
payload: {
|
||||
collections,
|
||||
config: {
|
||||
admin: { user: userSlug },
|
||||
},
|
||||
config,
|
||||
},
|
||||
},
|
||||
} = initPageResult
|
||||
|
||||
const collectionConfig = config.collections?.find((collection) => collection?.slug === userSlug)
|
||||
const collectionConfig = collections?.[userSlug]?.config
|
||||
const { auth: authOptions } = collectionConfig
|
||||
const loginWithUsername = authOptions.loginWithUsername
|
||||
|
||||
|
||||
@@ -148,9 +148,7 @@ export const renderDocumentHandler = async (args: {
|
||||
importMap: payload.importMap,
|
||||
initialData,
|
||||
initPageResult: {
|
||||
collectionConfig: payload.config.collections.find(
|
||||
(collection) => collection.slug === collectionSlug,
|
||||
),
|
||||
collectionConfig: payload?.collections?.[collectionSlug]?.config,
|
||||
cookies,
|
||||
docID,
|
||||
globalConfig: payload.config.globals.find((global) => global.slug === collectionSlug),
|
||||
|
||||
@@ -10,7 +10,7 @@ import React, { useState } from 'react'
|
||||
import { FormHeader } from '../../../elements/FormHeader/index.js'
|
||||
|
||||
export const ForgotPasswordForm: React.FC = () => {
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
|
||||
const {
|
||||
admin: { user: userSlug },
|
||||
@@ -19,7 +19,7 @@ export const ForgotPasswordForm: React.FC = () => {
|
||||
|
||||
const { t } = useTranslation()
|
||||
const [hasSubmitted, setHasSubmitted] = useState(false)
|
||||
const collectionConfig = config.collections?.find((collection) => collection?.slug === userSlug)
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: userSlug })
|
||||
const loginWithUsername = collectionConfig?.auth?.loginWithUsername
|
||||
|
||||
const handleResponse: FormProps['handleResponse'] = (res, successToast, errorToast) => {
|
||||
|
||||
@@ -139,9 +139,7 @@ export const renderListHandler = async (args: {
|
||||
enableRowSelections,
|
||||
importMap: payload.importMap,
|
||||
initPageResult: {
|
||||
collectionConfig: payload.config.collections.find(
|
||||
(collection) => collection.slug === collectionSlug,
|
||||
),
|
||||
collectionConfig: payload?.collections?.[collectionSlug]?.config,
|
||||
cookies,
|
||||
globalConfig: payload.config.globals.find((global) => global.slug === collectionSlug),
|
||||
languageOptions: undefined, // TODO
|
||||
|
||||
@@ -567,9 +567,9 @@ export const LivePreviewClient: React.FC<
|
||||
url,
|
||||
})
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
|
||||
const globalConfig = getEntityConfig({ globalSlug }) as ClientGlobalConfig
|
||||
const globalConfig = getEntityConfig({ globalSlug })
|
||||
|
||||
const schemaPath = collectionSlug || globalSlug
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export const LoginForm: React.FC<{
|
||||
prefillUsername?: string
|
||||
searchParams: { [key: string]: string | string[] | undefined }
|
||||
}> = ({ prefillEmail, prefillPassword, prefillUsername, searchParams }) => {
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
|
||||
const {
|
||||
admin: {
|
||||
@@ -34,7 +34,7 @@ export const LoginForm: React.FC<{
|
||||
routes: { admin: adminRoute, api: apiRoute },
|
||||
} = config
|
||||
|
||||
const collectionConfig = config.collections?.find((collection) => collection?.slug === userSlug)
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: userSlug })
|
||||
const { auth: authOptions } = collectionConfig
|
||||
const loginWithUsername = authOptions.loginWithUsername
|
||||
const { canLoginWithEmail, canLoginWithUsername } = getLoginOptions(loginWithUsername)
|
||||
|
||||
@@ -32,7 +32,7 @@ export const LoginView: React.FC<AdminViewProps> = ({ initPageResult, params, se
|
||||
redirect((searchParams.redirect as string) || admin)
|
||||
}
|
||||
|
||||
const collectionConfig = collections.find(({ slug }) => slug === userSlug)
|
||||
const collectionConfig = payload?.collections?.[userSlug]?.config
|
||||
|
||||
const prefillAutoLogin =
|
||||
typeof config.admin?.autoLogin === 'object' && config.admin?.autoLogin.prefillOnly
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { ClientCollectionConfig, ClientGlobalConfig, OptionObject } from 'payload'
|
||||
import type { OptionObject } from 'payload'
|
||||
|
||||
import { Gutter, useConfig, useDocumentInfo, usePayloadAPI, useTranslation } from '@payloadcms/ui'
|
||||
import { formatDate } from '@payloadcms/ui/shared'
|
||||
@@ -31,11 +31,9 @@ export const DefaultVersionView: React.FC<DefaultVersionsViewProps> = ({
|
||||
const { i18n } = useTranslation()
|
||||
const { id, collectionSlug, globalSlug } = useDocumentInfo()
|
||||
|
||||
const [collectionConfig] = useState(
|
||||
() => getEntityConfig({ collectionSlug }) as ClientCollectionConfig,
|
||||
)
|
||||
const [collectionConfig] = useState(() => getEntityConfig({ collectionSlug }))
|
||||
|
||||
const [globalConfig] = useState(() => getEntityConfig({ globalSlug }) as ClientGlobalConfig)
|
||||
const [globalConfig] = useState(() => getEntityConfig({ globalSlug }))
|
||||
|
||||
const [locales, setLocales] = useState<OptionObject[]>(localeOptions)
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ const Restore: React.FC<Props> = ({
|
||||
}) => {
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { admin: adminRoute, api: apiRoute },
|
||||
serverURL,
|
||||
},
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = collections.find((collection) => collection.slug === collectionSlug)
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
|
||||
const { toggleModal } = useModal()
|
||||
const [processing, setProcessing] = useState(false)
|
||||
|
||||
@@ -18,9 +18,7 @@ export async function getAccessResults({
|
||||
|
||||
const isLoggedIn = !!user
|
||||
const userCollectionConfig =
|
||||
user && user.collection
|
||||
? payload.config.collections.find((collection) => collection.slug === user.collection)
|
||||
: null
|
||||
user && user.collection ? payload?.collections?.[user.collection]?.config : null
|
||||
|
||||
if (userCollectionConfig && payload.config.admin.user === user?.collection) {
|
||||
results.canAccessAdmin = userCollectionConfig.access.admin
|
||||
|
||||
@@ -23,9 +23,8 @@ export const previewHandler: PayloadHandler = async (req) => {
|
||||
|
||||
let previewURL: string
|
||||
|
||||
const generatePreviewURL = req.payload.config.collections.find(
|
||||
(config) => config.slug === collection.config.slug,
|
||||
)?.admin?.preview
|
||||
const generatePreviewURL =
|
||||
req.payload?.collections?.[collection.config.slug]?.config?.admin?.preview
|
||||
|
||||
const token = extractJWT(req)
|
||||
|
||||
|
||||
@@ -158,9 +158,7 @@ export const promise = async <T>({
|
||||
if (Array.isArray(field.relationTo)) {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((relatedDoc: { relationTo: string; value: JsonValue }, i) => {
|
||||
const relatedCollection = req.payload.config.collections.find(
|
||||
(collection) => collection.slug === relatedDoc.relationTo,
|
||||
)
|
||||
const relatedCollection = req.payload.collections?.[relatedDoc.relationTo]?.config
|
||||
|
||||
if (
|
||||
typeof relatedDoc.value === 'object' &&
|
||||
@@ -185,9 +183,7 @@ export const promise = async <T>({
|
||||
})
|
||||
}
|
||||
if (field.hasMany !== true && valueIsValueWithRelation(value)) {
|
||||
const relatedCollection = req.payload.config.collections.find(
|
||||
(collection) => collection.slug === value.relationTo,
|
||||
)
|
||||
const relatedCollection = req.payload.collections?.[value.relationTo]?.config
|
||||
|
||||
if (typeof value.value === 'object' && value.value && 'id' in value.value) {
|
||||
value.value = (value.value as TypeWithID).id
|
||||
@@ -206,9 +202,9 @@ export const promise = async <T>({
|
||||
} else {
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((relatedDoc: unknown, i) => {
|
||||
const relatedCollection = req.payload.config.collections.find(
|
||||
(collection) => collection.slug === field.relationTo,
|
||||
)
|
||||
const relatedCollection = Array.isArray(field.relationTo)
|
||||
? undefined
|
||||
: req.payload.collections?.[field.relationTo]?.config
|
||||
|
||||
if (typeof relatedDoc === 'object' && relatedDoc && 'id' in relatedDoc) {
|
||||
value[i] = relatedDoc.id
|
||||
@@ -226,9 +222,7 @@ export const promise = async <T>({
|
||||
})
|
||||
}
|
||||
if (field.hasMany !== true && value) {
|
||||
const relatedCollection = req.payload.config.collections.find(
|
||||
(collection) => collection.slug === field.relationTo,
|
||||
)
|
||||
const relatedCollection = req.payload.collections?.[field.relationTo]?.config
|
||||
|
||||
if (typeof value === 'object' && value && 'id' in value) {
|
||||
siblingData[field.name] = value.id
|
||||
|
||||
@@ -166,7 +166,7 @@ export const email: EmailFieldValidation = (
|
||||
{
|
||||
collectionSlug,
|
||||
req: {
|
||||
payload: { config },
|
||||
payload: { collections },
|
||||
t,
|
||||
},
|
||||
required,
|
||||
@@ -174,7 +174,7 @@ export const email: EmailFieldValidation = (
|
||||
},
|
||||
) => {
|
||||
if (collectionSlug) {
|
||||
const collection = config.collections.find(({ slug }) => slug === collectionSlug)
|
||||
const collection = collections?.[collectionSlug]?.config
|
||||
|
||||
if (
|
||||
collection.auth.loginWithUsername &&
|
||||
@@ -201,7 +201,7 @@ export const username: UsernameFieldValidation = (
|
||||
{
|
||||
collectionSlug,
|
||||
req: {
|
||||
payload: { config },
|
||||
payload: { collections, config },
|
||||
t,
|
||||
},
|
||||
required,
|
||||
@@ -211,7 +211,7 @@ export const username: UsernameFieldValidation = (
|
||||
let maxLength: number
|
||||
|
||||
if (collectionSlug) {
|
||||
const collection = config.collections.find(({ slug }) => slug === collectionSlug)
|
||||
const collection = collections?.[collectionSlug]?.config
|
||||
|
||||
if (
|
||||
collection.auth.loginWithUsername &&
|
||||
|
||||
@@ -27,7 +27,7 @@ export const checkDocumentLockStatus = async ({
|
||||
|
||||
// Retrieve the lockDocuments property for either collection or global
|
||||
const lockDocumentsProp = collectionSlug
|
||||
? payload.config?.collections?.find((c) => c.slug === collectionSlug)?.lockDocuments
|
||||
? payload.collections?.[collectionSlug]?.config?.lockDocuments
|
||||
: payload.config?.globals?.find((g) => g.slug === globalSlug)?.lockDocuments
|
||||
|
||||
const isLockingEnabled = lockDocumentsProp !== false
|
||||
|
||||
@@ -36,10 +36,10 @@ export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
|
||||
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
},
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const field: FieldType<string> = useField({ ...props, path } as Options)
|
||||
@@ -109,7 +109,7 @@ export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
|
||||
|
||||
const hasImage = Boolean(value)
|
||||
|
||||
const collection = collections?.find((coll) => coll.slug === relationTo) || undefined
|
||||
const collection = getEntityConfig({ collectionSlug: relationTo })
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -62,7 +62,7 @@ export function LinkEditor({ anchorElem }: { anchorElem: HTMLElement }): React.R
|
||||
uuid,
|
||||
} = useEditorConfigContext()
|
||||
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
|
||||
const { i18n, t } = useTranslation<object, 'lexical:link:loadingWithEllipsis'>()
|
||||
|
||||
@@ -150,7 +150,9 @@ export function LinkEditor({ anchorElem }: { anchorElem: HTMLElement }): React.R
|
||||
}`,
|
||||
)
|
||||
|
||||
const relatedField = config.collections.find((coll) => coll.slug === fields?.doc?.relationTo)
|
||||
const relatedField = fields?.doc?.relationTo
|
||||
? getEntityConfig({ collectionSlug: fields?.doc?.relationTo })
|
||||
: undefined
|
||||
if (!relatedField) {
|
||||
// Usually happens if the user removed all default fields. In this case, we let them specify the label or do not display the label at all.
|
||||
// label could be a virtual field the user added. This is useful if they want to use the link feature for things other than links.
|
||||
|
||||
@@ -59,14 +59,14 @@ const Component: React.FC<Props> = (props) => {
|
||||
} = useEditorConfigContext()
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
},
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const [relatedCollection, setRelatedCollection] = useState(
|
||||
() => collections.find((coll) => coll.slug === relationTo)!,
|
||||
const [relatedCollection, setRelatedCollection] = useState(() =>
|
||||
getEntityConfig({ collectionSlug: relationTo }),
|
||||
)
|
||||
|
||||
const { i18n, t } = useTranslation()
|
||||
|
||||
@@ -64,10 +64,10 @@ const Component: React.FC<ElementProps> = (props) => {
|
||||
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
},
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
const uploadRef = useRef<HTMLDivElement | null>(null)
|
||||
const { uuid } = useEditorConfigContext()
|
||||
@@ -82,8 +82,8 @@ const Component: React.FC<ElementProps> = (props) => {
|
||||
|
||||
const { i18n, t } = useTranslation()
|
||||
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
|
||||
const [relatedCollection] = useState<ClientCollectionConfig>(
|
||||
() => collections.find((coll) => coll.slug === relationTo)!,
|
||||
const [relatedCollection] = useState<ClientCollectionConfig>(() =>
|
||||
getEntityConfig({ collectionSlug: relationTo }),
|
||||
)
|
||||
|
||||
const componentID = useId()
|
||||
|
||||
@@ -69,7 +69,7 @@ export const LinkElement = () => {
|
||||
const { id, collectionSlug, docPermissions, getDocPreferences, globalSlug } = useDocumentInfo()
|
||||
|
||||
const editor = useSlate()
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
const { code: locale } = useLocale()
|
||||
const { i18n, t } = useTranslation()
|
||||
const { closeModal, openModal, toggleModal } = useModal()
|
||||
@@ -179,8 +179,7 @@ export const LinkElement = () => {
|
||||
t={t}
|
||||
variables={{
|
||||
label: getTranslation(
|
||||
config.collections.find(({ slug }) => slug === element.doc.relationTo)?.labels
|
||||
?.singular,
|
||||
getEntityConfig({ collectionSlug: element.doc.relationTo })?.labels?.singular,
|
||||
i18n,
|
||||
),
|
||||
}}
|
||||
|
||||
@@ -40,6 +40,7 @@ const RelationshipElementComponent: React.FC = () => {
|
||||
routes: { api },
|
||||
serverURL,
|
||||
},
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
const [enabledCollectionSlugs] = useState(() =>
|
||||
collections
|
||||
@@ -47,7 +48,7 @@ const RelationshipElementComponent: React.FC = () => {
|
||||
.map(({ slug }) => slug),
|
||||
)
|
||||
const [relatedCollection, setRelatedCollection] = useState(() =>
|
||||
collections.find((coll) => coll.slug === relationTo),
|
||||
getEntityConfig({ collectionSlug: relationTo }),
|
||||
)
|
||||
|
||||
const selected = useSelected()
|
||||
@@ -117,7 +118,7 @@ const RelationshipElementComponent: React.FC = () => {
|
||||
{ at: elementPath },
|
||||
)
|
||||
|
||||
setRelatedCollection(collections.find((coll) => coll.slug === collectionSlug))
|
||||
setRelatedCollection(getEntityConfig({ collectionSlug }))
|
||||
|
||||
setParams({
|
||||
...initialParams,
|
||||
@@ -127,7 +128,7 @@ const RelationshipElementComponent: React.FC = () => {
|
||||
closeListDrawer()
|
||||
dispatchCacheBust()
|
||||
},
|
||||
[closeListDrawer, editor, element, cacheBust, setParams, collections],
|
||||
[closeListDrawer, editor, element, cacheBust, setParams, getEntityConfig],
|
||||
)
|
||||
|
||||
return (
|
||||
|
||||
@@ -46,15 +46,15 @@ const UploadElementComponent: React.FC<{ enabledCollectionSlugs?: string[] }> =
|
||||
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
},
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
const { i18n, t } = useTranslation()
|
||||
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
|
||||
const [relatedCollection, setRelatedCollection] = useState<ClientCollectionConfig>(() =>
|
||||
collections.find((coll) => coll.slug === relationTo),
|
||||
getEntityConfig({ collectionSlug: relationTo }),
|
||||
)
|
||||
|
||||
const drawerSlug = useDrawerSlug('upload-drawer')
|
||||
@@ -121,14 +121,14 @@ const UploadElementComponent: React.FC<{ enabledCollectionSlugs?: string[] }> =
|
||||
|
||||
const elementPath = ReactEditor.findPath(editor, element)
|
||||
|
||||
setRelatedCollection(collections.find((coll) => coll.slug === collectionSlug))
|
||||
setRelatedCollection(getEntityConfig({ collectionSlug }))
|
||||
|
||||
Transforms.setNodes(editor, newNode, { at: elementPath })
|
||||
|
||||
dispatchCacheBust()
|
||||
closeListDrawer()
|
||||
},
|
||||
[closeListDrawer, editor, element, collections],
|
||||
[closeListDrawer, editor, element, getEntityConfig],
|
||||
)
|
||||
|
||||
const relatedFieldSchemaPath = `${uploadFieldsSchemaPath}.${relatedCollection.slug}`
|
||||
|
||||
@@ -6,14 +6,12 @@ import { useState } from 'react'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
|
||||
export const useRelatedCollections = (relationTo: string | string[]): ClientCollectionConfig[] => {
|
||||
const { config } = useConfig()
|
||||
const { getEntityConfig } = useConfig()
|
||||
|
||||
const [relatedCollections] = useState(() => {
|
||||
if (relationTo) {
|
||||
const relations = typeof relationTo === 'string' ? [relationTo] : relationTo
|
||||
return relations.map((relation) =>
|
||||
config.collections.find((collection) => collection.slug === relation),
|
||||
)
|
||||
return relations.map((relation) => getEntityConfig({ collectionSlug: relation }))
|
||||
}
|
||||
return []
|
||||
})
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
'use client'
|
||||
|
||||
import type { ClientCollectionConfig } from 'payload'
|
||||
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { reduceFieldsToValues } from 'payload/shared'
|
||||
@@ -38,7 +36,7 @@ export function AddingFilesView() {
|
||||
const { user } = useAuth()
|
||||
const { openModal } = useModal()
|
||||
|
||||
const collection = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const collection = getEntityConfig({ collectionSlug })
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
|
||||
@@ -58,7 +58,7 @@ export function EditForm({ submitted }: EditFormProps) {
|
||||
|
||||
const abortOnChangeRef = React.useRef<AbortController>(null)
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: docSlug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: docSlug })
|
||||
const router = useRouter()
|
||||
const depth = useEditDepth()
|
||||
const params = useSearchParams()
|
||||
|
||||
@@ -20,10 +20,10 @@ function DrawerContent() {
|
||||
const { addFiles, forms, isInitializing } = useFormsManager()
|
||||
const { closeModal } = useModal()
|
||||
const { collectionSlug, drawerSlug } = useBulkUpload()
|
||||
const { config } = useConfig()
|
||||
const { getEntityConfig } = useConfig()
|
||||
const { t } = useTranslation()
|
||||
|
||||
const uploadCollection = config.collections.find((col) => col.slug === collectionSlug)
|
||||
const uploadCollection = getEntityConfig({ collectionSlug })
|
||||
const uploadConfig = uploadCollection?.upload
|
||||
const uploadMimeTypes = uploadConfig?.mimeTypes
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ export const DeleteDocument: React.FC<Props> = (props) => {
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
|
||||
const { setModified } = useForm()
|
||||
const [deleting, setDeleting] = useState(false)
|
||||
|
||||
@@ -98,9 +98,9 @@ export const DocumentControls: React.FC<{
|
||||
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: slug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: slug })
|
||||
|
||||
const globalConfig = getEntityConfig({ globalSlug: slug }) as ClientGlobalConfig
|
||||
const globalConfig = getEntityConfig({ globalSlug: slug })
|
||||
|
||||
const {
|
||||
admin: { dateFormat },
|
||||
|
||||
@@ -30,14 +30,10 @@ export const DocumentDrawerContent: React.FC<DocumentDrawerProps> = ({
|
||||
redirectAfterDelete,
|
||||
redirectAfterDuplicate,
|
||||
}) => {
|
||||
const {
|
||||
config: { collections },
|
||||
} = useConfig()
|
||||
const { getEntityConfig } = useConfig()
|
||||
const locale = useLocale()
|
||||
|
||||
const [collectionConfig] = useState(() =>
|
||||
collections.find((collection) => collection.slug === collectionSlug),
|
||||
)
|
||||
const [collectionConfig] = useState(() => getEntityConfig({ collectionSlug }))
|
||||
|
||||
const abortGetDocumentViewRef = React.useRef<AbortController>(null)
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export const DuplicateDocument: React.FC<Props> = ({
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: slug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: slug })
|
||||
|
||||
const [hasClicked, setHasClicked] = useState<boolean>(false)
|
||||
const { i18n, t } = useTranslation()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { ClientCollectionConfig, ListQuery } from 'payload'
|
||||
import type { ListQuery } from 'payload'
|
||||
|
||||
import { useModal } from '@faceless-ui/modal'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
@@ -45,7 +45,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
|
||||
const [selectedOption, setSelectedOption] = useState<Option<string>>(() => {
|
||||
const initialSelection = selectedCollectionFromProps || enabledCollections[0]?.slug
|
||||
const found = getEntityConfig({ collectionSlug: initialSelection }) as ClientCollectionConfig
|
||||
const found = getEntityConfig({ collectionSlug: initialSelection })
|
||||
|
||||
return found
|
||||
? {
|
||||
@@ -63,7 +63,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
() => {
|
||||
if (selectedCollectionFromProps && selectedCollectionFromProps !== selectedOption?.value) {
|
||||
setSelectedOption({
|
||||
label: collections.find(({ slug }) => slug === selectedCollectionFromProps).labels,
|
||||
label: getEntityConfig({ collectionSlug: selectedCollectionFromProps })?.labels,
|
||||
value: selectedCollectionFromProps,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ export const Localizer: React.FC<{
|
||||
className?: string
|
||||
}> = (props) => {
|
||||
const { className } = props
|
||||
const { config } = useConfig()
|
||||
const { localization } = config
|
||||
const {
|
||||
config: { localization },
|
||||
} = useConfig()
|
||||
const searchParams = useSearchParams()
|
||||
const { setLocaleIsLoading } = useLocaleLoading()
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export const PublishButton: React.FC<{ label?: string }> = ({ label: labelProp }
|
||||
uploadStatus,
|
||||
} = useDocumentInfo()
|
||||
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
const { submit } = useForm()
|
||||
const modified = useFormModified()
|
||||
const editDepth = useEditDepth()
|
||||
@@ -51,13 +51,13 @@ export const PublishButton: React.FC<{ label?: string }> = ({ label: labelProp }
|
||||
|
||||
const entityConfig = React.useMemo(() => {
|
||||
if (collectionSlug) {
|
||||
return config.collections.find(({ slug }) => slug === collectionSlug)
|
||||
return getEntityConfig({ collectionSlug })
|
||||
}
|
||||
|
||||
if (globalSlug) {
|
||||
return config.globals.find(({ slug }) => slug === globalSlug)
|
||||
return getEntityConfig({ globalSlug })
|
||||
}
|
||||
}, [collectionSlug, globalSlug, config])
|
||||
}, [collectionSlug, globalSlug, getEntityConfig])
|
||||
|
||||
const hasNewerVersions = unpublishedVersionCount > 0
|
||||
|
||||
|
||||
@@ -91,9 +91,7 @@ export const RelationshipTable: React.FC<RelationshipTableComponentProps> = (pro
|
||||
const [query, setQuery] = useState<ListQuery>()
|
||||
const [openColumnSelector, setOpenColumnSelector] = useState(false)
|
||||
|
||||
const [collectionConfig] = useState(
|
||||
() => getEntityConfig({ collectionSlug: relationTo }) as ClientCollectionConfig,
|
||||
)
|
||||
const [collectionConfig] = useState(() => getEntityConfig({ collectionSlug: relationTo }))
|
||||
|
||||
const [isLoadingTable, setIsLoadingTable] = useState(!disableTable)
|
||||
const [data, setData] = useState<PaginatedDocs>(initialData)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use client'
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
DefaultCellComponentProps,
|
||||
JoinFieldClient,
|
||||
RelationshipFieldClient,
|
||||
@@ -98,7 +97,7 @@ export const RelationshipCell: React.FC<RelationshipCellProps> = ({
|
||||
const document = documents[relationTo][value]
|
||||
const relatedCollection = getEntityConfig({
|
||||
collectionSlug: relationTo,
|
||||
}) as ClientCollectionConfig
|
||||
})
|
||||
|
||||
const label = formatDocTitle({
|
||||
collectionConfig: relatedCollection,
|
||||
|
||||
@@ -67,7 +67,7 @@ export const TableColumnsProvider: React.FC<Props> = ({
|
||||
|
||||
const { admin: { defaultColumns, useAsTitle } = {}, fields } = getEntityConfig({
|
||||
collectionSlug,
|
||||
}) as ClientCollectionConfig
|
||||
})
|
||||
|
||||
const prevCollection = React.useRef<SanitizedCollectionConfig['slug']>(collectionSlug)
|
||||
const { getPreference } = usePreferences()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { ClientCollectionConfig, PaginatedDocs, Where } from 'payload'
|
||||
import type { PaginatedDocs, Where } from 'payload'
|
||||
|
||||
import * as qs from 'qs-esm'
|
||||
import React, { useCallback, useEffect, useReducer, useState } from 'react'
|
||||
@@ -28,7 +28,6 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
||||
|
||||
const {
|
||||
config: {
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
},
|
||||
@@ -55,7 +54,7 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
||||
|
||||
const addOptions = useCallback(
|
||||
(data, relation) => {
|
||||
const collection = getEntityConfig({ collectionSlug: relation }) as ClientCollectionConfig
|
||||
const collection = getEntityConfig({ collectionSlug: relation })
|
||||
dispatchOptions({ type: 'ADD', collection, data, hasMultipleRelations, i18n, relation })
|
||||
},
|
||||
[hasMultipleRelations, i18n, getEntityConfig],
|
||||
@@ -72,7 +71,7 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
||||
if (relationSlug && partiallyLoadedRelationshipSlugs.current.includes(relationSlug)) {
|
||||
const collection = getEntityConfig({
|
||||
collectionSlug: relationSlug,
|
||||
}) as ClientCollectionConfig
|
||||
})
|
||||
const fieldToSearch = collection?.admin?.useAsTitle || 'id'
|
||||
const pageIndex = nextPageByRelationshipRef.current.get(relationSlug)
|
||||
|
||||
@@ -135,7 +134,7 @@ export const RelationshipField: React.FC<Props> = (props) => {
|
||||
|
||||
setHasLoadedFirstOptions(true)
|
||||
},
|
||||
[addOptions, api, collections, debouncedSearch, i18n.language, serverURL, t],
|
||||
[addOptions, api, debouncedSearch, getEntityConfig, i18n.language, serverURL, t],
|
||||
)
|
||||
|
||||
const loadMoreOptions = React.useCallback(() => {
|
||||
|
||||
@@ -127,9 +127,7 @@ const JoinFieldComponent: JoinFieldClientComponent = (props) => {
|
||||
|
||||
const { id: docID, docConfig } = useDocumentInfo()
|
||||
|
||||
const {
|
||||
config: { collections },
|
||||
} = useConfig()
|
||||
const { getEntityConfig } = useConfig()
|
||||
|
||||
const { customComponents: { AfterInput, BeforeInput, Description, Label } = {}, value } =
|
||||
useField<PaginatedDocs>({
|
||||
@@ -166,7 +164,7 @@ const JoinFieldComponent: JoinFieldClientComponent = (props) => {
|
||||
}, [docID, field.targetField.relationTo, field.where, on, docConfig.slug])
|
||||
|
||||
const initialDrawerData = useMemo(() => {
|
||||
const relatedCollection = collections.find((collection) => collection.slug === field.collection)
|
||||
const relatedCollection = getEntityConfig({ collectionSlug: field.collection })
|
||||
|
||||
return getInitialDrawerData({
|
||||
collectionSlug: docConfig.slug,
|
||||
@@ -174,7 +172,7 @@ const JoinFieldComponent: JoinFieldClientComponent = (props) => {
|
||||
fields: relatedCollection.fields,
|
||||
segments: field.on.split('.'),
|
||||
})
|
||||
}, [collections, field.on, field.collection, docConfig.slug, docID])
|
||||
}, [getEntityConfig, field.collection, field.on, docConfig.slug, docID])
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@@ -60,10 +60,9 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
|
||||
const {
|
||||
collections,
|
||||
routes: { api },
|
||||
serverURL,
|
||||
} = config
|
||||
@@ -169,7 +168,7 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
||||
}
|
||||
|
||||
if (resultsFetched < 10) {
|
||||
const collection = collections.find((coll) => coll.slug === relation)
|
||||
const collection = getEntityConfig({ collectionSlug: relation })
|
||||
const fieldToSearch = collection?.admin?.useAsTitle || 'id'
|
||||
let fieldToSort = collection?.defaultSort || 'id'
|
||||
if (typeof sortOptions === 'string') {
|
||||
@@ -275,7 +274,7 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
||||
hasMany,
|
||||
errorLoading,
|
||||
search,
|
||||
collections,
|
||||
getEntityConfig,
|
||||
locale,
|
||||
serverURL,
|
||||
sortOptions,
|
||||
@@ -354,7 +353,7 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
||||
method: 'POST',
|
||||
})
|
||||
|
||||
const collection = collections.find((coll) => coll.slug === relation)
|
||||
const collection = getEntityConfig({ collectionSlug: relation })
|
||||
let docs = []
|
||||
|
||||
if (response.ok) {
|
||||
@@ -380,7 +379,7 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
||||
options,
|
||||
hasMany,
|
||||
errorLoading,
|
||||
collections,
|
||||
getEntityConfig,
|
||||
hasMultipleRelations,
|
||||
serverURL,
|
||||
api,
|
||||
@@ -395,12 +394,12 @@ const RelationshipFieldComponent: RelationshipFieldClientComponent = (props) =>
|
||||
useEffect(() => {
|
||||
const relations = Array.isArray(relationTo) ? relationTo : [relationTo]
|
||||
const isIdOnly = relations.reduce((idOnly, relation) => {
|
||||
const collection = collections.find((coll) => coll.slug === relation)
|
||||
const collection = getEntityConfig({ collectionSlug: relation })
|
||||
const fieldToSearch = collection?.admin?.useAsTitle || 'id'
|
||||
return fieldToSearch === 'id' && idOnly
|
||||
}, true)
|
||||
setEnableWordBoundarySearch(!isIdOnly)
|
||||
}, [relationTo, collections])
|
||||
}, [relationTo, getEntityConfig])
|
||||
|
||||
// When (`relationTo` || `filterOptions` || `locale`) changes, reset component
|
||||
// Note - effect should not run on first run
|
||||
|
||||
@@ -1,26 +1,42 @@
|
||||
/* eslint-disable perfectionist/sort-object-types */ // Need to disable this rule because the order of the overloads is important
|
||||
'use client'
|
||||
import type { ClientCollectionConfig, ClientConfig, ClientGlobalConfig } from 'payload'
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
ClientConfig,
|
||||
ClientGlobalConfig,
|
||||
CollectionSlug,
|
||||
GlobalSlug,
|
||||
} from 'payload'
|
||||
|
||||
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'
|
||||
|
||||
type GetEntityConfigFn = {
|
||||
// Overload #1: collectionSlug only
|
||||
// @todo remove "{} |" in 4.0, which would be a breaking change
|
||||
(args: { collectionSlug: {} | CollectionSlug; globalSlug?: never }): ClientCollectionConfig
|
||||
|
||||
// Overload #2: globalSlug only
|
||||
// @todo remove "{} |" in 4.0, which would be a breaking change
|
||||
(args: { collectionSlug?: never; globalSlug: {} | GlobalSlug }): ClientGlobalConfig
|
||||
|
||||
// Overload #3: both/none (fall back to union | null)
|
||||
(args: {
|
||||
collectionSlug?: {} | CollectionSlug
|
||||
globalSlug?: {} | GlobalSlug
|
||||
}): ClientCollectionConfig | ClientGlobalConfig | null
|
||||
}
|
||||
|
||||
export type ClientConfigContext = {
|
||||
config: ClientConfig
|
||||
getEntityConfig: (args: {
|
||||
collectionSlug?: string
|
||||
globalSlug?: string
|
||||
}) => ClientCollectionConfig | ClientGlobalConfig | null
|
||||
/**
|
||||
* Get a collection or global config by its slug. This is preferred over
|
||||
* using `config.collections.find` or `config.globals.find`, because
|
||||
* getEntityConfig uses a lookup map for O(1) lookups.
|
||||
*/
|
||||
getEntityConfig: GetEntityConfigFn
|
||||
setConfig: (config: ClientConfig) => void
|
||||
}
|
||||
|
||||
export type EntityConfigContext = {
|
||||
collectionConfig?: ClientCollectionConfig
|
||||
globalConfig?: ClientGlobalConfig
|
||||
setEntityConfig: (args: {
|
||||
collectionConfig?: ClientCollectionConfig | null
|
||||
globalConfig?: ClientGlobalConfig | null
|
||||
}) => void
|
||||
}
|
||||
|
||||
const RootConfigContext = createContext<ClientConfigContext | undefined>(undefined)
|
||||
|
||||
export const ConfigProvider: React.FC<{
|
||||
@@ -35,19 +51,32 @@ export const ConfigProvider: React.FC<{
|
||||
setConfig(configFromProps)
|
||||
}, [configFromProps])
|
||||
|
||||
const getEntityConfig = useCallback(
|
||||
({ collectionSlug, globalSlug }: { collectionSlug?: string; globalSlug?: string }) => {
|
||||
if (collectionSlug) {
|
||||
return config.collections.find((collection) => collection.slug === collectionSlug)
|
||||
}
|
||||
// Build lookup maps for collections and globals so we can do O(1) lookups by slug
|
||||
const { collectionsBySlug, globalsBySlug } = useMemo(() => {
|
||||
const collectionsBySlug: Record<string, ClientCollectionConfig> = {}
|
||||
const globalsBySlug: Record<string, ClientGlobalConfig> = {}
|
||||
|
||||
if (globalSlug) {
|
||||
return config.globals.find((global) => global.slug === globalSlug)
|
||||
}
|
||||
for (const collection of config.collections) {
|
||||
collectionsBySlug[collection.slug] = collection
|
||||
}
|
||||
for (const global of config.globals) {
|
||||
globalsBySlug[global.slug] = global
|
||||
}
|
||||
|
||||
return null
|
||||
return { collectionsBySlug, globalsBySlug }
|
||||
}, [config])
|
||||
|
||||
const getEntityConfig = useCallback<GetEntityConfigFn>(
|
||||
(args) => {
|
||||
if ('collectionSlug' in args) {
|
||||
return collectionsBySlug[args.collectionSlug] ?? null
|
||||
}
|
||||
if ('globalSlug' in args) {
|
||||
return globalsBySlug[args.globalSlug] ?? null
|
||||
}
|
||||
return null as any
|
||||
},
|
||||
[config],
|
||||
[collectionsBySlug, globalsBySlug],
|
||||
)
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
'use client'
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
ClientGlobalConfig,
|
||||
ClientUser,
|
||||
DocumentPreferences,
|
||||
SanitizedDocumentPermissions,
|
||||
} from 'payload'
|
||||
import type { ClientUser, DocumentPreferences, SanitizedDocumentPermissions } from 'payload'
|
||||
|
||||
import * as qs from 'qs-esm'
|
||||
import React, {
|
||||
@@ -79,8 +73,8 @@ const DocumentInfo: React.FC<
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const globalConfig = getEntityConfig({ globalSlug }) as ClientGlobalConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
const globalConfig = getEntityConfig({ globalSlug })
|
||||
|
||||
const abortControllerRef = useRef(new AbortController())
|
||||
const docConfig = collectionConfig || globalConfig
|
||||
|
||||
@@ -14,6 +14,8 @@ type Result = {
|
||||
user: TypedUser
|
||||
}
|
||||
|
||||
const lockDurationDefault = 300 // Default 5 minutes in seconds
|
||||
|
||||
export const handleFormStateLocking = async ({
|
||||
id,
|
||||
collectionSlug,
|
||||
@@ -39,9 +41,8 @@ export const handleFormStateLocking = async ({
|
||||
}
|
||||
}
|
||||
|
||||
const lockDurationDefault = 300 // Default 5 minutes in seconds
|
||||
const lockDocumentsProp = collectionSlug
|
||||
? req.payload.config.collections.find((c) => c.slug === collectionSlug)?.lockDocuments
|
||||
? req.payload.collections?.[collectionSlug]?.config.lockDocuments
|
||||
: req.payload.config.globals.find((g) => g.slug === globalSlug)?.lockDocuments
|
||||
|
||||
const lockDuration =
|
||||
|
||||
@@ -8,7 +8,6 @@ import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
import { CopyToClipboard } from '../../../elements/CopyToClipboard/index.js'
|
||||
import { GenerateConfirmation } from '../../../elements/GenerateConfirmation/index.js'
|
||||
import { FieldLabel } from '../../../fields/FieldLabel/index.js'
|
||||
import { useFormFields } from '../../../forms/Form/context.js'
|
||||
import { useField } from '../../../forms/useField/index.js'
|
||||
import { useConfig } from '../../../providers/Config/index.js'
|
||||
@@ -26,16 +25,14 @@ export const APIKey: React.FC<{ readonly enabled: boolean; readonly readOnly?: b
|
||||
const [initialAPIKey] = useState(uuidv4())
|
||||
const [highlightedField, setHighlightedField] = useState(false)
|
||||
const { i18n, t } = useTranslation()
|
||||
const { config } = useConfig()
|
||||
const { config, getEntityConfig } = useConfig()
|
||||
const { collectionSlug } = useDocumentInfo()
|
||||
|
||||
const apiKey = useFormFields(([fields]) => (fields && fields[path]) || null)
|
||||
|
||||
const apiKeyField: TextFieldClient = config.collections
|
||||
.find((collection) => {
|
||||
return collection.slug === collectionSlug
|
||||
})
|
||||
?.fields?.find((field) => 'name' in field && field.name === 'apiKey') as TextFieldClient
|
||||
const apiKeyField: TextFieldClient = getEntityConfig({ collectionSlug })?.fields?.find(
|
||||
(field) => 'name' in field && field.name === 'apiKey',
|
||||
) as TextFieldClient
|
||||
|
||||
const validate = (val) =>
|
||||
text(val, {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
ClientGlobalConfig,
|
||||
ClientSideEditViewProps,
|
||||
ClientUser,
|
||||
FormState,
|
||||
} from 'payload'
|
||||
import type { ClientSideEditViewProps, ClientUser, FormState } from 'payload'
|
||||
|
||||
import { useRouter, useSearchParams } from 'next/navigation.js'
|
||||
import React, { Fragment, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
@@ -109,8 +103,8 @@ export const DefaultEditView: React.FC<ClientSideEditViewProps> = ({
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const globalConfig = getEntityConfig({ globalSlug }) as ClientGlobalConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
const globalConfig = getEntityConfig({ globalSlug })
|
||||
|
||||
const depth = useEditDepth()
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@ const ListDrawerHeader: React.FC<ListHeaderProps> = ({
|
||||
}) => {
|
||||
const {
|
||||
config: { collections },
|
||||
getEntityConfig,
|
||||
} = useConfig()
|
||||
|
||||
const { closeModal } = useModal()
|
||||
@@ -102,7 +103,7 @@ const ListDrawerHeader: React.FC<ListHeaderProps> = ({
|
||||
setSelectedOption,
|
||||
} = useListDrawerContext()
|
||||
|
||||
const collectionConfig = collections.find(({ slug }) => slug === selectedOption.value)
|
||||
const collectionConfig = getEntityConfig({ collectionSlug: selectedOption.value })
|
||||
|
||||
const enabledCollectionConfigs = collections.filter(({ slug }) =>
|
||||
enabledCollections.includes(slug),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { ClientCollectionConfig, ListPreferences } from 'payload'
|
||||
import type { ListPreferences } from 'payload'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import LinkImport from 'next/link.js'
|
||||
@@ -113,7 +113,7 @@ export const DefaultListView: React.FC<ListViewClientProps> = (props) => {
|
||||
const { setCollectionSlug, setCurrentActivePath, setOnSuccess } = useBulkUpload()
|
||||
const { drawerSlug: bulkUploadDrawerSlug } = useBulkUpload()
|
||||
|
||||
const collectionConfig = getEntityConfig({ collectionSlug }) as ClientCollectionConfig
|
||||
const collectionConfig = getEntityConfig({ collectionSlug })
|
||||
|
||||
const { labels, upload } = collectionConfig
|
||||
|
||||
|
||||
Reference in New Issue
Block a user