Merge branch 'feat/next/qs' into feat/next-poc
This commit is contained in:
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -3,13 +3,7 @@
|
||||
// Hover to view descriptions of existing attributes.
|
||||
"configurations": [
|
||||
{
|
||||
"command": "pnpm dev",
|
||||
"name": "Run Dev 3.0",
|
||||
"request": "launch",
|
||||
"type": "node-terminal"
|
||||
},
|
||||
{
|
||||
"command": "pnpm run dev _community",
|
||||
"command": "pnpm run dev _community -- --no-turbo",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"name": "Run Dev Community",
|
||||
"request": "launch",
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
"graphql-http": "^1.22.0",
|
||||
"graphql-playground-html": "1.6.30",
|
||||
"path-to-regexp": "^6.2.1",
|
||||
"qs": "6.11.2",
|
||||
"react-diff-viewer-continued": "3.2.6",
|
||||
"react-toastify": "8.2.0",
|
||||
"sass": "^1.71.1",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { translations } from '@payloadcms/translations/api'
|
||||
import { getAuthenticatedUser } from 'payload/auth'
|
||||
import { parseCookies } from 'payload/auth'
|
||||
import { getDataLoader } from 'payload/utilities'
|
||||
import QueryString from 'qs'
|
||||
import { URL } from 'url'
|
||||
|
||||
import { getDataAndFile } from './getDataAndFile'
|
||||
@@ -95,6 +96,7 @@ export const createPayloadRequest = async ({
|
||||
payloadUploadSizes: {},
|
||||
port: urlProperties.port,
|
||||
protocol: urlProperties.protocol,
|
||||
query: urlProperties.search ? QueryString.parse(urlProperties.search) : {},
|
||||
routeParams: params || {},
|
||||
search: urlProperties.search,
|
||||
searchParams: urlProperties.searchParams,
|
||||
|
||||
@@ -19,7 +19,6 @@ export { generateAccountMetadata } from './meta'
|
||||
|
||||
export const Account: React.FC<AdminViewProps> = async ({ initPageResult, searchParams }) => {
|
||||
const {
|
||||
locale,
|
||||
permissions,
|
||||
req: {
|
||||
payload,
|
||||
@@ -94,8 +93,8 @@ export const Account: React.FC<AdminViewProps> = async ({ initPageResult, search
|
||||
<HydrateClientUser permissions={permissions} user={user} />
|
||||
<SetDocumentInfo
|
||||
AfterFields={<Settings />}
|
||||
action={`${serverURL}${api}/${userSlug}/${data?.id}?locale=${locale.code}`}
|
||||
apiURL={`${serverURL}${api}/${userSlug}/${data?.id}?locale=${locale.code}`}
|
||||
action={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
|
||||
apiURL={`${serverURL}${api}/${userSlug}${data?.id ? `/${data.id}` : ''}`}
|
||||
collectionSlug={userSlug}
|
||||
docPermissions={collectionPermissions}
|
||||
docPreferences={docPreferences}
|
||||
|
||||
@@ -181,13 +181,6 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
req,
|
||||
})
|
||||
|
||||
const formQueryParams: QueryParamTypes = {
|
||||
depth: 0,
|
||||
'fallback-locale': 'null',
|
||||
locale: locale.code,
|
||||
uploadEdits: undefined,
|
||||
}
|
||||
|
||||
const serverSideProps: ServerSideEditViewProps = {
|
||||
initPageResult,
|
||||
routeSegments: segments,
|
||||
@@ -204,7 +197,7 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
/>
|
||||
<HydrateClientUser permissions={permissions} user={user} />
|
||||
<SetDocumentInfo
|
||||
action={`${action}?${queryString.stringify(formQueryParams)}`}
|
||||
action={action}
|
||||
apiURL={apiURL}
|
||||
collectionSlug={collectionConfig?.slug}
|
||||
disableActions={false}
|
||||
@@ -224,7 +217,14 @@ export const Document: React.FC<AdminViewProps> = async ({
|
||||
})}
|
||||
/>
|
||||
<EditDepthProvider depth={1} key={`${collectionSlug || globalSlug}-${locale.code}`}>
|
||||
<FormQueryParamsProvider formQueryParams={formQueryParams}>
|
||||
<FormQueryParamsProvider
|
||||
initialParams={{
|
||||
depth: 0,
|
||||
'fallback-locale': 'null',
|
||||
locale: locale.code,
|
||||
uploadEdits: undefined,
|
||||
}}
|
||||
>
|
||||
<RenderCustomComponent
|
||||
CustomComponent={typeof CustomView === 'function' ? CustomView : undefined}
|
||||
DefaultComponent={DefaultView}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
useComponentMap,
|
||||
useConfig,
|
||||
useDocumentInfo,
|
||||
useFormQueryParams,
|
||||
} from '@payloadcms/ui'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import React, { Fragment, useEffect } from 'react'
|
||||
@@ -20,6 +21,7 @@ export const EditViewClient: React.FC = () => {
|
||||
} = useConfig()
|
||||
|
||||
const router = useRouter()
|
||||
const { dispatchFormQueryParams } = useFormQueryParams()
|
||||
|
||||
const { getComponentMap } = useComponentMap()
|
||||
|
||||
@@ -38,16 +40,23 @@ export const EditViewClient: React.FC = () => {
|
||||
if (!isEditing) {
|
||||
router.push(`${adminRoute}/collections/${collectionSlug}/${json?.doc?.id}`)
|
||||
} else {
|
||||
// buildState(json.doc, {
|
||||
// fieldSchema: collection.fields,
|
||||
// })
|
||||
// setFormQueryParams((params) => ({
|
||||
// ...params,
|
||||
// uploadEdits: undefined,
|
||||
// }))
|
||||
dispatchFormQueryParams({
|
||||
type: 'SET',
|
||||
params: {
|
||||
uploadEdits: null,
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
[getVersions, isEditing, getDocPermissions, collectionSlug, adminRoute, router],
|
||||
[
|
||||
adminRoute,
|
||||
collectionSlug,
|
||||
dispatchFormQueryParams,
|
||||
getDocPermissions,
|
||||
getVersions,
|
||||
isEditing,
|
||||
router,
|
||||
],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -54,6 +54,8 @@ export type CustomPayloadRequest<U = any> = {
|
||||
payloadDataLoader?: DataLoader<string, TypeWithID>
|
||||
/** Resized versions of the image that was uploaded during this request */
|
||||
payloadUploadSizes?: Record<string, Buffer>
|
||||
/** Query params on the request */
|
||||
query: Record<string, unknown>
|
||||
/** The route parameters
|
||||
* @example
|
||||
* /:collection/:id -> /posts/123
|
||||
|
||||
@@ -52,8 +52,7 @@ export const generateFileData = async <T>({
|
||||
|
||||
let file = req.file
|
||||
|
||||
const { searchParams } = req
|
||||
const uploadEdits = searchParams.get('uploadEdits') || {}
|
||||
const uploadEdits = req.query['uploadEdits'] || {}
|
||||
|
||||
const { disableLocalStorage, formatOptions, imageSizes, resizeOptions, staticDir, trimOptions } =
|
||||
collectionConfig.upload
|
||||
|
||||
@@ -94,6 +94,7 @@ export const createLocalReq: CreateLocalReq = async (
|
||||
req.user = user || req?.user || null
|
||||
req.payloadDataLoader = req?.payloadDataLoader || getDataLoader(req)
|
||||
req.routeParams = req?.routeParams || {}
|
||||
req.query = req?.query || {}
|
||||
|
||||
if (!req?.url) attachFakeURLProperties(req)
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ export const DeleteMany: React.FC<Props> = (props) => {
|
||||
toast.success(json.message || t('general:deletedSuccessfully'), { autoClose: 3000 })
|
||||
toggleAll()
|
||||
dispatchSearchParams({
|
||||
type: 'set',
|
||||
type: 'SET',
|
||||
browserHistory: 'replace',
|
||||
params: { page: selectAll ? '1' : undefined },
|
||||
})
|
||||
|
||||
@@ -154,7 +154,7 @@ export const EditMany: React.FC<Props> = (props) => {
|
||||
|
||||
const onSuccess = () => {
|
||||
dispatchSearchParams({
|
||||
type: 'set',
|
||||
type: 'SET',
|
||||
browserHistory: 'replace',
|
||||
params: { page: selectAll === SelectAllStatus.AllAvailable ? '1' : undefined },
|
||||
})
|
||||
|
||||
@@ -36,7 +36,7 @@ export const EditUpload: React.FC<{
|
||||
}> = ({ fileName, fileSrc, imageCacheTag, showCrop, showFocalPoint }) => {
|
||||
const { closeModal } = useModal()
|
||||
const { t } = useTranslation()
|
||||
const { formQueryParams, setFormQueryParams } = useFormQueryParams()
|
||||
const { dispatchFormQueryParams, formQueryParams } = useFormQueryParams()
|
||||
const { uploadEdits } = formQueryParams || {}
|
||||
const [crop, setCrop] = useState<CropType>({
|
||||
height: uploadEdits?.crop?.height || 100,
|
||||
@@ -81,11 +81,16 @@ export const EditUpload: React.FC<{
|
||||
}
|
||||
|
||||
const saveEdits = () => {
|
||||
setFormQueryParams({
|
||||
...formQueryParams,
|
||||
uploadEdits: {
|
||||
crop: crop || undefined,
|
||||
focalPoint: pointPosition ? pointPosition : undefined,
|
||||
dispatchFormQueryParams({
|
||||
type: 'SET',
|
||||
params: {
|
||||
uploadEdits:
|
||||
crop || pointPosition
|
||||
? {
|
||||
crop: crop || null,
|
||||
focalPoint: pointPosition ? pointPosition : null,
|
||||
}
|
||||
: null,
|
||||
},
|
||||
})
|
||||
closeModal(editDrawerSlug)
|
||||
|
||||
@@ -49,7 +49,7 @@ const Localizer: React.FC<{
|
||||
onClick={() => {
|
||||
close()
|
||||
dispatchSearchParams({
|
||||
type: 'set',
|
||||
type: 'SET',
|
||||
params: {
|
||||
locale: searchParams.locale,
|
||||
},
|
||||
|
||||
@@ -64,7 +64,7 @@ export const PublishMany: React.FC<Props> = (props) => {
|
||||
if (res.status < 400) {
|
||||
toast.success(t('general:updatedSuccessfully'))
|
||||
dispatchSearchParams({
|
||||
type: 'set',
|
||||
type: 'SET',
|
||||
browserHistory: 'replace',
|
||||
params: { page: selectAll ? '1' : undefined },
|
||||
})
|
||||
|
||||
@@ -61,7 +61,7 @@ export const UnpublishMany: React.FC<Props> = (props) => {
|
||||
if (res.status < 400) {
|
||||
toast.success(t('general:updatedSuccessfully'))
|
||||
dispatchSearchParams({
|
||||
type: 'set',
|
||||
type: 'SET',
|
||||
browserHistory: 'replace',
|
||||
params: { page: selectAll ? '1' : undefined },
|
||||
})
|
||||
|
||||
@@ -9,7 +9,6 @@ import { useFormSubmitted } from '../../forms/Form/context'
|
||||
import reduceFieldsToValues from '../../forms/Form/reduceFieldsToValues'
|
||||
import { fieldBaseClass } from '../../forms/fields/shared'
|
||||
import useField from '../../forms/useField'
|
||||
import { useClientFunctions } from '../../providers/ClientFunction'
|
||||
import { useDocumentInfo } from '../../providers/DocumentInfo'
|
||||
import { useTranslation } from '../../providers/Translation'
|
||||
import { Button } from '../Button'
|
||||
@@ -53,7 +52,6 @@ export const UploadActions = ({ canEdit, showSizePreviews }) => {
|
||||
|
||||
export const Upload: React.FC<Props> = (props) => {
|
||||
const { collectionSlug, initialState, onChange, updatedAt, uploadConfig } = props
|
||||
const clientFunctions = useClientFunctions()
|
||||
|
||||
const submitted = useFormSubmitted()
|
||||
const [replacingFile, setReplacingFile] = useState(false)
|
||||
|
||||
@@ -6,11 +6,13 @@ import isDeepEqual from 'deep-equal'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { serialize } from 'object-to-formdata'
|
||||
import { wait } from 'payload/utilities'
|
||||
import QueryString from 'qs'
|
||||
import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react'
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
import type { Context as FormContextType, GetDataByPath, Props, SubmitOptions } from './types'
|
||||
|
||||
import { useFormQueryParams } from '../..'
|
||||
import { useDebouncedEffect } from '../../hooks/useDebouncedEffect'
|
||||
import useThrottledEffect from '../../hooks/useThrottledEffect'
|
||||
import { useAuth } from '../../providers/Auth'
|
||||
@@ -69,6 +71,7 @@ const Form: React.FC<Props> = (props) => {
|
||||
const { i18n, t } = useTranslation()
|
||||
const { refreshCookie, user } = useAuth()
|
||||
const operation = useOperation()
|
||||
const { formQueryParams } = useFormQueryParams()
|
||||
|
||||
const config = useConfig()
|
||||
const {
|
||||
@@ -221,7 +224,8 @@ const Form: React.FC<Props> = (props) => {
|
||||
let res
|
||||
|
||||
if (typeof actionToUse === 'string') {
|
||||
res = await requests[methodToUse.toLowerCase()](actionToUse, {
|
||||
const actionEndpoint = `${actionToUse}${QueryString.stringify(formQueryParams, { addQueryPrefix: true })}`
|
||||
res = await requests[methodToUse.toLowerCase()](actionEndpoint, {
|
||||
body: formData,
|
||||
headers: {
|
||||
'Accept-Language': i18n.language,
|
||||
@@ -352,6 +356,7 @@ const Form: React.FC<Props> = (props) => {
|
||||
i18n,
|
||||
waitForAutocomplete,
|
||||
beforeSubmit,
|
||||
formQueryParams,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -562,9 +567,14 @@ const Form: React.FC<Props> = (props) => {
|
||||
[fields, dispatchFields, onChange],
|
||||
)
|
||||
|
||||
const actionString =
|
||||
typeof action === 'string'
|
||||
? `${action}${QueryString.stringify(formQueryParams, { addQueryPrefix: true })}`
|
||||
: ''
|
||||
|
||||
return (
|
||||
<form
|
||||
action={action}
|
||||
action={method ? actionString : action}
|
||||
className={classes}
|
||||
method={method}
|
||||
noValidate
|
||||
|
||||
@@ -1,38 +1,65 @@
|
||||
'use client'
|
||||
import type { UploadEdits } from 'payload/types'
|
||||
|
||||
import React, { createContext, useContext, useState } from 'react'
|
||||
import React, { createContext, useContext } from 'react'
|
||||
|
||||
export type QueryParamTypes = {
|
||||
depth: number
|
||||
'fallback-locale': string
|
||||
locale: string
|
||||
uploadEdits?: UploadEdits
|
||||
}
|
||||
export const FormQueryParams = createContext(
|
||||
{} as {
|
||||
formQueryParams: QueryParamTypes
|
||||
setFormQueryParams: (params: QueryParamTypes) => void
|
||||
},
|
||||
)
|
||||
import type { Action, FormQueryParamsContext, State } from './types'
|
||||
|
||||
import { useLocale } from '../Locale'
|
||||
|
||||
export const FormQueryParams = createContext({} as FormQueryParamsContext)
|
||||
|
||||
export const FormQueryParamsProvider: React.FC<{
|
||||
children: React.ReactNode
|
||||
formQueryParams?: QueryParamTypes
|
||||
setFormQueryParams?: (params: QueryParamTypes) => void
|
||||
}> = ({ children, formQueryParams: formQueryParamsFromProps }) => {
|
||||
const [formQueryParams, setFormQueryParams] = useState(
|
||||
formQueryParamsFromProps || ({} as QueryParamTypes),
|
||||
initialParams?: State
|
||||
}> = ({ children, initialParams: formQueryParamsFromProps }) => {
|
||||
const [formQueryParams, dispatchFormQueryParams] = React.useReducer(
|
||||
(state: State, action: Action) => {
|
||||
const newState = { ...state }
|
||||
|
||||
switch (action.type) {
|
||||
case 'SET':
|
||||
if (action.params?.uploadEdits === null && newState?.uploadEdits) {
|
||||
delete newState.uploadEdits
|
||||
}
|
||||
if (action.params?.uploadEdits?.crop === null && newState?.uploadEdits?.crop) {
|
||||
delete newState.uploadEdits.crop
|
||||
}
|
||||
if (
|
||||
action.params?.uploadEdits?.focalPoint === null &&
|
||||
newState?.uploadEdits?.focalPoint
|
||||
) {
|
||||
delete newState.uploadEdits.focalPoint
|
||||
}
|
||||
return {
|
||||
...newState,
|
||||
...action.params,
|
||||
}
|
||||
default:
|
||||
return state
|
||||
}
|
||||
},
|
||||
formQueryParamsFromProps || ({} as State),
|
||||
)
|
||||
|
||||
const locale = useLocale()
|
||||
|
||||
React.useEffect(() => {
|
||||
dispatchFormQueryParams({
|
||||
type: 'SET',
|
||||
params: {
|
||||
locale: locale.code,
|
||||
},
|
||||
})
|
||||
}, [locale.code])
|
||||
|
||||
return (
|
||||
<FormQueryParams.Provider value={{ formQueryParams, setFormQueryParams }}>
|
||||
<FormQueryParams.Provider value={{ dispatchFormQueryParams, formQueryParams }}>
|
||||
{children}
|
||||
</FormQueryParams.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useFormQueryParams = (): {
|
||||
formQueryParams: QueryParamTypes
|
||||
setFormQueryParams: (params: QueryParamTypes) => void
|
||||
dispatchFormQueryParams: React.Dispatch<Action>
|
||||
formQueryParams: State
|
||||
} => useContext(FormQueryParams)
|
||||
|
||||
18
packages/ui/src/providers/FormQueryParams/types.ts
Normal file
18
packages/ui/src/providers/FormQueryParams/types.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { UploadEdits } from 'payload/types'
|
||||
|
||||
export type FormQueryParamsContext = {
|
||||
dispatchFormQueryParams: (action: Action) => void
|
||||
formQueryParams: State
|
||||
}
|
||||
|
||||
export type State = {
|
||||
depth: number
|
||||
'fallback-locale': string
|
||||
locale: string
|
||||
uploadEdits?: UploadEdits
|
||||
}
|
||||
|
||||
export type Action = {
|
||||
params: Partial<State>
|
||||
type: 'SET'
|
||||
}
|
||||
@@ -75,7 +75,7 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
|
||||
useEffect(() => {
|
||||
if (searchParams?.locale) {
|
||||
dispatchSearchParams({
|
||||
type: 'set',
|
||||
type: 'SET',
|
||||
params: {
|
||||
locale: searchParams.locale,
|
||||
},
|
||||
|
||||
@@ -26,16 +26,16 @@ export const SearchParamsProvider: React.FC<{ children?: React.ReactNode }> = ({
|
||||
let paramsToSet
|
||||
|
||||
switch (action.type) {
|
||||
case 'set':
|
||||
case 'SET':
|
||||
paramsToSet = {
|
||||
...state,
|
||||
...action.params,
|
||||
}
|
||||
break
|
||||
case 'replace':
|
||||
case 'REPLACE':
|
||||
paramsToSet = action.params
|
||||
break
|
||||
case 'clear':
|
||||
case 'CLEAR':
|
||||
paramsToSet = {}
|
||||
break
|
||||
default:
|
||||
|
||||
@@ -8,14 +8,14 @@ export type State = qs.ParsedQs
|
||||
export type Action = (
|
||||
| {
|
||||
params: qs.ParsedQs
|
||||
type: 'replace'
|
||||
type: 'REPLACE'
|
||||
}
|
||||
| {
|
||||
params: qs.ParsedQs
|
||||
type: 'set'
|
||||
type: 'SET'
|
||||
}
|
||||
| {
|
||||
type: 'clear'
|
||||
type: 'CLEAR'
|
||||
}
|
||||
) & {
|
||||
/**
|
||||
|
||||
44
pnpm-lock.yaml
generated
44
pnpm-lock.yaml
generated
@@ -574,6 +574,9 @@ importers:
|
||||
path-to-regexp:
|
||||
specifier: ^6.2.1
|
||||
version: 6.2.1
|
||||
qs:
|
||||
specifier: 6.11.2
|
||||
version: 6.11.2
|
||||
react-diff-viewer-continued:
|
||||
specifier: 3.2.6
|
||||
version: 3.2.6(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -1330,7 +1333,7 @@ importers:
|
||||
version: 2.3.0
|
||||
next:
|
||||
specifier: 14.1.1-canary.26
|
||||
version: 14.1.1-canary.26(@babel/core@7.24.0)(react-dom@18.2.0)(react@18.2.0)(sass@1.71.1)
|
||||
version: 14.1.1-canary.26(@babel/core@7.24.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
object-to-formdata:
|
||||
specifier: 4.5.1
|
||||
version: 4.5.1
|
||||
@@ -13512,6 +13515,45 @@ packages:
|
||||
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
|
||||
dev: false
|
||||
|
||||
/next@14.1.1-canary.26(@babel/core@7.24.0)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-vHj7hCL9qn8AhRXNEC1ujTO55w3IjckEE1tkmxwyqA3ypTH9PtxSnU6eFfC9C67Xf/Q2C5Btug7Yqvw7pxGkhg==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.1.0
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
sass: ^1.3.0
|
||||
peerDependenciesMeta:
|
||||
'@opentelemetry/api':
|
||||
optional: true
|
||||
sass:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@next/env': 14.1.1-canary.26
|
||||
'@swc/helpers': 0.5.2
|
||||
busboy: 1.6.0
|
||||
caniuse-lite: 1.0.30001591
|
||||
graceful-fs: 4.2.11
|
||||
postcss: 8.4.31
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
styled-jsx: 5.1.1(@babel/core@7.24.0)(react@18.2.0)
|
||||
optionalDependencies:
|
||||
'@next/swc-darwin-arm64': 14.1.1-canary.26
|
||||
'@next/swc-darwin-x64': 14.1.1-canary.26
|
||||
'@next/swc-linux-arm64-gnu': 14.1.1-canary.26
|
||||
'@next/swc-linux-arm64-musl': 14.1.1-canary.26
|
||||
'@next/swc-linux-x64-gnu': 14.1.1-canary.26
|
||||
'@next/swc-linux-x64-musl': 14.1.1-canary.26
|
||||
'@next/swc-win32-arm64-msvc': 14.1.1-canary.26
|
||||
'@next/swc-win32-ia32-msvc': 14.1.1-canary.26
|
||||
'@next/swc-win32-x64-msvc': 14.1.1-canary.26
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
dev: false
|
||||
|
||||
/next@14.1.1-canary.26(@babel/core@7.24.0)(react-dom@18.2.0)(react@18.2.0)(sass@1.71.1):
|
||||
resolution: {integrity: sha512-vHj7hCL9qn8AhRXNEC1ujTO55w3IjckEE1tkmxwyqA3ypTH9PtxSnU6eFfC9C67Xf/Q2C5Btug7Yqvw7pxGkhg==}
|
||||
engines: {node: '>=18.17.0'}
|
||||
|
||||
@@ -4,7 +4,27 @@ export const mediaSlug = 'media'
|
||||
|
||||
export const MediaCollection: CollectionConfig = {
|
||||
slug: mediaSlug,
|
||||
upload: true,
|
||||
upload: {
|
||||
crop: true,
|
||||
focalPoint: true,
|
||||
imageSizes: [
|
||||
{
|
||||
name: 'thumbnail',
|
||||
width: 200,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
name: 'medium',
|
||||
width: 800,
|
||||
height: 800,
|
||||
},
|
||||
{
|
||||
name: 'large',
|
||||
width: 1200,
|
||||
height: 1200,
|
||||
},
|
||||
],
|
||||
},
|
||||
access: {
|
||||
read: () => true,
|
||||
create: () => true,
|
||||
|
||||
Reference in New Issue
Block a user