Compare commits
47 Commits
chore/bump
...
feat/live-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea1af337f0 | ||
|
|
2157450805 | ||
|
|
2cfce43dcf | ||
|
|
3bf3ed37b9 | ||
|
|
4ebbbb02f4 | ||
|
|
dc911ceacf | ||
|
|
034a26754f | ||
|
|
92380bff87 | ||
|
|
9b1dd2a8d8 | ||
|
|
9955818503 | ||
|
|
2c20051dbf | ||
|
|
d91478cd24 | ||
|
|
6dc61ae642 | ||
|
|
fdff5871f6 | ||
|
|
df7a3692f7 | ||
|
|
b750ba4509 | ||
|
|
d55306980e | ||
|
|
34ea6ec14f | ||
|
|
17d5168728 | ||
|
|
ed50a79643 | ||
|
|
0a59707ea0 | ||
|
|
b0fa1e9768 | ||
|
|
fcc4b22715 | ||
|
|
8abeca5568 | ||
|
|
68a3ae80f2 | ||
|
|
bcbb912d50 | ||
|
|
1c99f46e4f | ||
|
|
c877b1ad43 | ||
|
|
4426625b83 | ||
|
|
23628996d0 | ||
|
|
b9832f40e4 | ||
|
|
a675c04c99 | ||
|
|
e79b20363e | ||
|
|
21599b87f5 | ||
|
|
d51c6d4f52 | ||
|
|
e90ff72b37 | ||
|
|
babf4f965d | ||
|
|
313bfff781 | ||
|
|
6572bf4ae1 | ||
|
|
da7be35a15 | ||
|
|
55d00e2b1d | ||
|
|
5b554e5256 | ||
|
|
85e6edf21e | ||
|
|
b354d00aa4 | ||
|
|
c661d33b13 | ||
|
|
6b349378e0 | ||
|
|
39462bc6b9 |
@@ -158,7 +158,7 @@ mutation {
|
||||
|
||||
```ts
|
||||
const result = await payload.login({
|
||||
collection: '[collection-slug]',
|
||||
collection: 'collection-slug',
|
||||
data: {
|
||||
email: 'dev@payloadcms.com',
|
||||
password: 'get-out',
|
||||
@@ -166,6 +166,13 @@ const result = await payload.login({
|
||||
})
|
||||
```
|
||||
|
||||
<Banner type="success">
|
||||
**Server Functions:** Payload offers a ready-to-use `login` server function
|
||||
that utilizes the Local API. For integration details and examples, check out
|
||||
the [Server Function
|
||||
docs](../local-api/server-functions#reusable-payload-server-functions).
|
||||
</Banner>
|
||||
|
||||
## Logout
|
||||
|
||||
As Payload sets HTTP-only cookies, logging out cannot be done by just removing a cookie in JavaScript, as HTTP-only cookies are inaccessible by JS within the browser. So, Payload exposes a `logout` operation to delete the token in a safe way.
|
||||
@@ -189,6 +196,13 @@ mutation {
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="success">
|
||||
**Server Functions:** Payload provides a ready-to-use `logout` server function
|
||||
that manages the user's cookie for a seamless logout. For integration details
|
||||
and examples, check out the [Server Function
|
||||
docs](../local-api/server-functions#reusable-payload-server-functions).
|
||||
</Banner>
|
||||
|
||||
## Refresh
|
||||
|
||||
Allows for "refreshing" JWTs. If your user has a token that is about to expire, but the user is still active and using the app, you might want to use the `refresh` operation to receive a new token by executing this operation via the authenticated user.
|
||||
@@ -240,6 +254,13 @@ mutation {
|
||||
}
|
||||
```
|
||||
|
||||
<Banner type="success">
|
||||
**Server Functions:** Payload exports a ready-to-use `refresh` server function
|
||||
that automatically renews the user's token and updates the associated cookie.
|
||||
For integration details and examples, check out the [Server Function
|
||||
docs](../local-api/server-functions#reusable-payload-server-functions).
|
||||
</Banner>
|
||||
|
||||
## Verify by Email
|
||||
|
||||
If your collection supports email verification, the Verify operation will be exposed which accepts a verification token and sets the user's `_verified` property to `true`, thereby allowing the user to authenticate with the Payload API.
|
||||
@@ -270,7 +291,7 @@ mutation {
|
||||
|
||||
```ts
|
||||
const result = await payload.verifyEmail({
|
||||
collection: '[collection-slug]',
|
||||
collection: 'collection-slug',
|
||||
token: 'TOKEN_HERE',
|
||||
})
|
||||
```
|
||||
@@ -308,7 +329,7 @@ mutation {
|
||||
|
||||
```ts
|
||||
const result = await payload.unlock({
|
||||
collection: '[collection-slug]',
|
||||
collection: 'collection-slug',
|
||||
})
|
||||
```
|
||||
|
||||
@@ -349,7 +370,7 @@ mutation {
|
||||
|
||||
```ts
|
||||
const token = await payload.forgotPassword({
|
||||
collection: '[collection-slug]',
|
||||
collection: 'collection-slug',
|
||||
data: {
|
||||
email: 'dev@payloadcms.com',
|
||||
},
|
||||
|
||||
@@ -120,25 +120,25 @@ export const MyCollection: CollectionConfig = {
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text or localization object used to group Collection and Global links in the admin navigation. Set to `false` to hide the link from the navigation while keeping its routes accessible. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this Collection from navigation and admin routing. |
|
||||
| `hooks` | Admin-specific hooks for this Collection. [More details](../hooks/collections). |
|
||||
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin Panel. If no field is defined, the ID of the document is used as the title. A field with `virtual: true` cannot be used as the title. |
|
||||
| `description` | Text to display below the Collection label in the List View to give editors more information. Alternatively, you can use the `admin.components.Description` to render a React component. [More details](#custom-components). |
|
||||
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this Collection's List View. |
|
||||
| `disableCopyToLocale` | Disables the "Copy to Locale" button while editing documents within this Collection. Only applicable when localization is enabled. |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this Collection. |
|
||||
| `enableRichTextLink` | The [Rich Text](../fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `enableRichTextRelationship` | The [Rich Text](../fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `meta` | Page metadata overrides to apply to this Collection within the Admin Panel. [More details](../admin/metadata). |
|
||||
| `preview` | Function to generate preview URLs within the Admin Panel that can point to your app. [More details](../admin/preview). |
|
||||
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
|
||||
| `components` | Swap in your own React components to be used within this Collection. [More details](#custom-components). |
|
||||
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More details](#list-searchable-fields). |
|
||||
| `pagination` | Set pagination-specific options for this Collection. [More details](#pagination). |
|
||||
| `baseListFilter` | You can define a default base filter for this collection's List view, which will be merged into any filters that the user performs. |
|
||||
| Option | Description |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `group` | Text or localization object used to group Collection and Global links in the admin navigation. Set to `false` to hide the link from the navigation while keeping its routes accessible. |
|
||||
| `hidden` | Set to true or a function, called with the current user, returning true to exclude this Collection from navigation and admin routing. |
|
||||
| `hooks` | Admin-specific hooks for this Collection. [More details](../hooks/collections). |
|
||||
| `useAsTitle` | Specify a top-level field to use for a document title throughout the Admin Panel. If no field is defined, the ID of the document is used as the title. A field with `virtual: true` cannot be used as the title, unless it's linked to a relationship'. |
|
||||
| `description` | Text to display below the Collection label in the List View to give editors more information. Alternatively, you can use the `admin.components.Description` to render a React component. [More details](#custom-components). |
|
||||
| `defaultColumns` | Array of field names that correspond to which columns to show by default in this Collection's List View. |
|
||||
| `disableCopyToLocale` | Disables the "Copy to Locale" button while editing documents within this Collection. Only applicable when localization is enabled. |
|
||||
| `hideAPIURL` | Hides the "API URL" meta field while editing documents within this Collection. |
|
||||
| `enableRichTextLink` | The [Rich Text](../fields/rich-text) field features a `Link` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `enableRichTextRelationship` | The [Rich Text](../fields/rich-text) field features a `Relationship` element which allows for users to automatically reference related documents within their rich text. Set to `true` by default. |
|
||||
| `meta` | Page metadata overrides to apply to this Collection within the Admin Panel. [More details](../admin/metadata). |
|
||||
| `preview` | Function to generate preview URLs within the Admin Panel that can point to your app. [More details](../admin/preview). |
|
||||
| `livePreview` | Enable real-time editing for instant visual feedback of your front-end application. [More details](../live-preview/overview). |
|
||||
| `components` | Swap in your own React components to be used within this Collection. [More details](#custom-components). |
|
||||
| `listSearchableFields` | Specify which fields should be searched in the List search view. [More details](#list-searchable-fields). |
|
||||
| `pagination` | Set pagination-specific options for this Collection. [More details](#pagination). |
|
||||
| `baseListFilter` | You can define a default base filter for this collection's List view, which will be merged into any filters that the user performs. |
|
||||
|
||||
### Custom Components
|
||||
|
||||
@@ -193,13 +193,13 @@ export const MyCollection: CollectionConfig = {
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `SaveButton` | Replace the default Save Button within the Edit View. [Drafts](../versions/drafts) must be disabled. [More details](../custom-components/edit-view#save-button). |
|
||||
| `SaveDraftButton` | Replace the default Save Draft Button within the Edit View. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. [More details](../custom-components/edit-view#save-draft-button). |
|
||||
| `PublishButton` | Replace the default Publish Button within the Edit View. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#publish-button). |
|
||||
| `PreviewButton` | Replace the default Preview Button within the Edit View. [Preview](../admin/preview) must be enabled. [More details](../custom-components/edit-view#preview-button). |
|
||||
| `Upload` | Replace the default Upload component within the Edit View. [Upload](../upload/overview) must be enabled. [More details](../custom-components/edit-view#upload). |
|
||||
| Option | Description |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `SaveButton` | Replace the default Save Button within the Edit View. [Drafts](../versions/drafts) must be disabled. [More details](../custom-components/edit-view#savebutton). |
|
||||
| `SaveDraftButton` | Replace the default Save Draft Button within the Edit View. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. [More details](../custom-components/edit-view#savedraftbutton). |
|
||||
| `PublishButton` | Replace the default Publish Button within the Edit View. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#publishbutton). |
|
||||
| `PreviewButton` | Replace the default Preview Button within the Edit View. [Preview](../admin/preview) must be enabled. [More details](../custom-components/edit-view#previewbutton). |
|
||||
| `Upload` | Replace the default Upload component within the Edit View. [Upload](../upload/overview) must be enabled. [More details](../custom-components/edit-view#upload). |
|
||||
|
||||
<Banner type="success">
|
||||
**Note:** For details on how to build Custom Components, see [Building Custom
|
||||
|
||||
@@ -179,12 +179,12 @@ export const MyGlobal: SanitizedGlobalConfig = {
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `SaveButton` | Replace the default Save Button with a Custom Component. [Drafts](../versions/drafts) must be disabled. [More details](../custom-components/edit-view#save-button). |
|
||||
| `SaveDraftButton` | Replace the default Save Draft Button with a Custom Component. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. [More details](../custom-components/edit-view#save-draft-button). |
|
||||
| `PublishButton` | Replace the default Publish Button with a Custom Component. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#publish-button). |
|
||||
| `PreviewButton` | Replace the default Preview Button with a Custom Component. [Preview](../admin/preview) must be enabled. [More details](../custom-components/edit-view#preview-button). |
|
||||
| Option | Description |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `SaveButton` | Replace the default Save Button with a Custom Component. [Drafts](../versions/drafts) must be disabled. [More details](../custom-components/edit-view#savebutton). |
|
||||
| `SaveDraftButton` | Replace the default Save Draft Button with a Custom Component. [Drafts](../versions/drafts) must be enabled and autosave must be disabled. [More details](../custom-components/edit-view#savedraftbutton). |
|
||||
| `PublishButton` | Replace the default Publish Button with a Custom Component. [Drafts](../versions/drafts) must be enabled. [More details](../custom-components/edit-view#publishbutton). |
|
||||
| `PreviewButton` | Replace the default Preview Button with a Custom Component. [Preview](../admin/preview) must be enabled. [More details](../custom-components/edit-view#previewbutton). |
|
||||
|
||||
<Banner type="success">
|
||||
**Note:** For details on how to build Custom Components, see [Building Custom
|
||||
|
||||
@@ -240,8 +240,8 @@ export default buildConfig({
|
||||
// highlight-start
|
||||
cors: {
|
||||
origins: ['http://localhost:3000'],
|
||||
headers: ['x-custom-header']
|
||||
}
|
||||
headers: ['x-custom-header'],
|
||||
},
|
||||
// highlight-end
|
||||
})
|
||||
```
|
||||
|
||||
@@ -101,14 +101,15 @@ export const MyCollection: CollectionConfig = {
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Path | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------------------- |
|
||||
| `SaveButton` | A button that saves the current document. [More details](#savebutton). |
|
||||
| `SaveDraftButton` | A button that saves the current document as a draft. [More details](#savedraftbutton). |
|
||||
| `PublishButton` | A button that publishes the current document. [More details](#publishbutton). |
|
||||
| `PreviewButton` | A button that previews the current document. [More details](#previewbutton). |
|
||||
| `Description` | A description of the Collection. [More details](#description). |
|
||||
| `Upload` | A file upload component. [More details](#upload). |
|
||||
| Path | Description |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------------------------- |
|
||||
| `beforeDocumentControls` | Inject custom components before the Save / Publish buttons. [More details](#beforedocumentcontrols). |
|
||||
| `SaveButton` | A button that saves the current document. [More details](#savebutton). |
|
||||
| `SaveDraftButton` | A button that saves the current document as a draft. [More details](#savedraftbutton). |
|
||||
| `PublishButton` | A button that publishes the current document. [More details](#publishbutton). |
|
||||
| `PreviewButton` | A button that previews the current document. [More details](#previewbutton). |
|
||||
| `Description` | A description of the Collection. [More details](#description). |
|
||||
| `Upload` | A file upload component. [More details](#upload). |
|
||||
|
||||
#### Globals
|
||||
|
||||
@@ -133,13 +134,14 @@ export const MyGlobal: GlobalConfig = {
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Path | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------------------- |
|
||||
| `SaveButton` | A button that saves the current document. [More details](#savebutton). |
|
||||
| `SaveDraftButton` | A button that saves the current document as a draft. [More details](#savedraftbutton). |
|
||||
| `PublishButton` | A button that publishes the current document. [More details](#publishbutton). |
|
||||
| `PreviewButton` | A button that previews the current document. [More details](#previewbutton). |
|
||||
| `Description` | A description of the Global. [More details](#description). |
|
||||
| Path | Description |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------------------------- |
|
||||
| `beforeDocumentControls` | Inject custom components before the Save / Publish buttons. [More details](#beforedocumentcontrols). |
|
||||
| `SaveButton` | A button that saves the current document. [More details](#savebutton). |
|
||||
| `SaveDraftButton` | A button that saves the current document as a draft. [More details](#savedraftbutton). |
|
||||
| `PublishButton` | A button that publishes the current document. [More details](#publishbutton). |
|
||||
| `PreviewButton` | A button that previews the current document. [More details](#previewbutton). |
|
||||
| `Description` | A description of the Global. [More details](#description). |
|
||||
|
||||
### SaveButton
|
||||
|
||||
@@ -191,6 +193,73 @@ export function MySaveButton(props: SaveButtonClientProps) {
|
||||
}
|
||||
```
|
||||
|
||||
### beforeDocumentControls
|
||||
|
||||
The `beforeDocumentControls` property allows you to render custom components just before the default document action buttons (like Save, Publish, or Preview). This is useful for injecting custom buttons, status indicators, or any other UI elements before the built-in controls.
|
||||
|
||||
To add `beforeDocumentControls` components, use the `components.edit.beforeDocumentControls` property in you [Collection Config](../configuration/collections) or `components.elements.beforeDocumentControls` in your [Global Config](../configuration/globals):
|
||||
|
||||
#### Collections
|
||||
|
||||
```
|
||||
export const MyCollection: CollectionConfig = {
|
||||
admin: {
|
||||
components: {
|
||||
edit: {
|
||||
// highlight-start
|
||||
beforeDocumentControls: ['/path/to/CustomComponent'],
|
||||
// highlight-end
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
#### Globals
|
||||
|
||||
```
|
||||
export const MyGlobal: GlobalConfig = {
|
||||
admin: {
|
||||
components: {
|
||||
elements: {
|
||||
// highlight-start
|
||||
beforeDocumentControls: ['/path/to/CustomComponent'],
|
||||
// highlight-end
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Here's an example of a custom `beforeDocumentControls` component:
|
||||
|
||||
#### Server Component
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import type { BeforeDocumentControlsServerProps } from 'payload'
|
||||
|
||||
export function MyCustomDocumentControlButton(
|
||||
props: BeforeDocumentControlsServerProps,
|
||||
) {
|
||||
return <div>This is a custom beforeDocumentControl button (Server)</div>
|
||||
}
|
||||
```
|
||||
|
||||
#### Client Component
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import type { BeforeDocumentControlsClientProps } from 'payload'
|
||||
|
||||
export function MyCustomDocumentControlButton(
|
||||
props: BeforeDocumentControlsClientProps,
|
||||
) {
|
||||
return <div>This is a custom beforeDocumentControl button (Client)</div>
|
||||
}
|
||||
```
|
||||
|
||||
### SaveDraftButton
|
||||
|
||||
The `SaveDraftButton` property allows you to render a custom Save Draft Button in the Edit View.
|
||||
|
||||
@@ -39,28 +39,28 @@ export const MyArrayField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as the heading in the [Admin Panel](../admin/overview) or an object with keys for each language. Auto-generated from name if not defined. |
|
||||
| **`fields`** \* | Array of field types to correspond to each row of the Array. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the [Admin Panel](../admin/overview) and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide an array of row data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`labels`** | Customize the row labels appearing in the Admin dashboard. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`dbName`** | Custom table name for the field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as the heading in the [Admin Panel](../admin/overview) or an object with keys for each language. Auto-generated from name if not defined. |
|
||||
| **`fields`** \* | Array of field types to correspond to each row of the Array. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the [Admin Panel](../admin/overview) and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide an array of row data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this Array will be kept, so there is no need to specify each nested field as `localized`. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`labels`** | Customize the row labels appearing in the Admin dashboard. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`dbName`** | Custom table name for the field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -39,26 +39,26 @@ export const MyBlocksField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as the heading in the Admin Panel or an object with keys for each language. Auto-generated from name if not defined. |
|
||||
| **`blocks`** \* | Array of [block configs](/docs/fields/blocks#block-configs) to be made available to this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API response or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide an array of block data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this field will be kept, so there is no need to specify each nested field as `localized`. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`labels`** | Customize the block row labels appearing in the Admin dashboard. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as the heading in the Admin Panel or an object with keys for each language. Auto-generated from name if not defined. |
|
||||
| **`blocks`** \* | Array of [block configs](/docs/fields/blocks#block-configs) to be made available to this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API response or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide an array of block data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. If enabled, a separate, localized set of all data within this field will be kept, so there is no need to specify each nested field as `localized`. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`labels`** | Customize the block row labels appearing in the Admin dashboard. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -352,18 +352,20 @@ const config = buildConfig({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
{
|
||||
slug: 'collection2',
|
||||
fields: [
|
||||
{
|
||||
name: 'editor',
|
||||
type: 'richText',
|
||||
editor: lexicalEditor({
|
||||
BlocksFeature({
|
||||
// Same reference can be reused anywhere, even in the lexical editor, without incurred performance hit
|
||||
blocks: ['TextBlock'],
|
||||
})
|
||||
})
|
||||
features: [
|
||||
BlocksFeature({
|
||||
// Same reference can be reused anywhere, even in the lexical editor, without incurred performance hit
|
||||
blocks: ['TextBlock'],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -28,23 +28,23 @@ export const MyCheckboxField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](./overview#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value, will default to false if field is also `required`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](./overview#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -29,26 +29,26 @@ export const MyBlocksField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See below for [more detail](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -28,24 +28,24 @@ export const MyDateField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`timezone`** \* | Set to `true` to enable timezone selection on this field. [More details](#timezones). |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`timezone`** \* | Set to `true` to enable timezone selection on this field. [More details](#timezones). |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -28,24 +28,24 @@ export const MyEmailField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -29,25 +29,25 @@ export const MyJSONField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`jsonSchema`** | Provide a JSON schema that will be used for validation. [JSON schemas](https://json-schema.org/learn/getting-started-step-by-step) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`jsonSchema`** | Provide a JSON schema that will be used for validation. [JSON schemas](https://json-schema.org/learn/getting-started-step-by-step) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -28,29 +28,29 @@ export const MyNumberField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
|
||||
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
|
||||
| **`hasMany`** | Makes this field an ordered array of numbers instead of just a single number. |
|
||||
| **`minRows`** | Minimum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`min`** | Minimum value accepted. Used in the default `validation` function. |
|
||||
| **`max`** | Maximum value accepted. Used in the default `validation` function. |
|
||||
| **`hasMany`** | Makes this field an ordered array of numbers instead of just a single number. |
|
||||
| **`minRows`** | Minimum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of numbers in the numbers array, if `hasMany` is set to true. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -541,6 +541,7 @@ The `ctx` object:
|
||||
| Property | Description |
|
||||
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`blockData`** | The nearest parent block's data. If the field is not inside a block, this will be `undefined`. |
|
||||
| **`operation`** | A string relating to which operation the field type is currently executing within. |
|
||||
| **`path`** | The full path to the field in the schema, represented as an array of string segments, including array indexes. I.e `['group', 'myArray', '1', 'textField']`. |
|
||||
| **`user`** | The currently authenticated user object. |
|
||||
|
||||
|
||||
@@ -32,24 +32,24 @@ export const MyPointField: Field = {
|
||||
|
||||
## Config
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Used as a field label in the Admin Panel and to name the generated GraphQL type. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. To support location queries, point index defaults to `2dsphere`, to disable the index set to `false`. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](./overview#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Used as a field label in the Admin Panel and to name the generated GraphQL type. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. To support location queries, point index defaults to `2dsphere`, to disable the index set to `false`. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](./overview#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -33,26 +33,26 @@ export const MyRadioField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing an `label` string and a `value` string. |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. The default value must exist within provided values in `options`. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -37,31 +37,31 @@ export const MyRelationshipField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxDepth`** | Sets a maximum population depth for this field, regardless of the remaining depth when this field is reached. [Max Depth](/docs/queries/depth#max-depth) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| **`graphQL`** | Custom graphQL configuration for the field. [More details](/docs/graphql/overview#field-complexity) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide one or many collection `slug`s to be able to assign relationships to. |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-relationship-options). |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with `hasMany`. |
|
||||
| **`maxDepth`** | Sets a maximum population depth for this field, regardless of the remaining depth when this field is reached. [Max Depth](/docs/queries/depth#max-depth) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| **`graphQL`** | Custom graphQL configuration for the field. [More details](/docs/graphql/overview#field-complexity) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
@@ -94,6 +94,7 @@ The Relationship Field inherits all of the default options from the base [Field
|
||||
| **`allowCreate`** | Set to `false` if you'd like to disable the ability to create new documents from within the relationship field. |
|
||||
| **`allowEdit`** | Set to `false` if you'd like to disable the ability to edit documents from within the relationship field. |
|
||||
| **`sortOptions`** | Define a default sorting order for the options within a Relationship field's dropdown. [More](#sort-options) |
|
||||
| **`appearance`** | Set to `drawer` or `select` to change the behavior of the field. Defaults to `select`. |
|
||||
|
||||
### Sort Options
|
||||
|
||||
@@ -375,6 +376,45 @@ non-polymorphic relationship.
|
||||
|
||||
</Banner>
|
||||
|
||||
### Linking virtual fields with relationships
|
||||
|
||||
You can link virtual fields to fields in other collections through a relationship (or upload) field, for example:
|
||||
|
||||
```ts
|
||||
{
|
||||
collections: [
|
||||
{
|
||||
slug: 'categories',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'posts',
|
||||
fields: [
|
||||
{
|
||||
type: 'relationship',
|
||||
name: 'category',
|
||||
relationTo: 'categories',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
name: 'categoryTitle',
|
||||
virtual: 'category.title',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
Here, `categoryTitle` will _always_ be populated with the corresponding value, even if the current `depth` is `0`, You can also query and sort by this field.
|
||||
The relationship must not be `hasMany: true` or polymorphic.
|
||||
The path can be deeply nested into 2 or more relationship fields, for example `post.category.title` as long as all the relationship fields meet the above requirement.
|
||||
|
||||
## Custom Components
|
||||
|
||||
### Field
|
||||
|
||||
@@ -21,23 +21,23 @@ Instead, you can invest your time and effort into learning the underlying open-s
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](./overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](./overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](../authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](./overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](../configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`editor`** | Customize or override the rich text editor. [More details](../rich-text/overview). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](./overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](./overview#validation) |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](../authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](./overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](../configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`editor`** | Customize or override the rich text editor. [More details](../rich-text/overview). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
\*_ An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -33,29 +33,29 @@ export const MySelectField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-options) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`dbName`** | Custom table name (if `hasMany` set to `true`) for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`options`** \* | Array of options to allow the field to store. Can either be an array of strings, or an array of objects containing a `label` string and a `value` string. |
|
||||
| **`hasMany`** | Boolean when, if set to `true`, allows this field to have many selections instead of only one. |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. See the [default field admin config](/docs/fields/overview#admin-options) for more details. |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`enumName`** | Custom enum name for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`dbName`** | Custom table name (if `hasMany` set to `true`) for this field when using SQL Database Adapter ([Postgres](/docs/database/postgres)). Auto-generated from name if not defined. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -43,14 +43,14 @@ export const MyTabsField: Field = {
|
||||
|
||||
Each tab must have either a `name` or `label` and the required `fields` array. You can also optionally pass a `description` to render within each individual tab.
|
||||
|
||||
| Option | Description |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **`name`** | Groups field data into an object when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | The label to render on the tab itself. Required when name is undefined, defaults to name converted to words. |
|
||||
| **`fields`** \* | The fields to render within this tab. |
|
||||
| **`description`** | Optionally render a description within this tab to describe the contents of the tab itself. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). (`name` must be present) |
|
||||
| **`virtual`** | Provide `true` to disable field in the database (`name` must be present). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** | Groups field data into an object when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | The label to render on the tab itself. Required when name is undefined, defaults to name converted to words. |
|
||||
| **`fields`** \* | The fields to render within this tab. |
|
||||
| **`description`** | Optionally render a description within this tab to describe the contents of the tab itself. |
|
||||
| **`interfaceName`** | Create a top level, reusable [Typescript interface](/docs/typescript/generating-types#custom-field-interfaces) & [GraphQL type](/docs/graphql/graphql-schema#custom-field-schemas). (`name` must be present) |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -28,29 +28,29 @@ export const MyTextField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
|
||||
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`hasMany`** | Makes this field an ordered array of text instead of just a single text. |
|
||||
| **`minRows`** | Minimum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`maxRows`** | Maximum number of texts in the array, if `hasMany` is set to true. |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -28,26 +28,26 @@ export const MyTextareaField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`minLength`** | Used by the default validation function to ensure values are of a minimum character length. |
|
||||
| **`maxLength`** | Used by the default validation function to ensure values are of a maximum character length. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [More details](#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -44,32 +44,32 @@ export const MyUploadField: Field = {
|
||||
|
||||
## Config Options
|
||||
|
||||
| Option | Description |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. **Note: the related collection must be configured to support Uploads.** |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
|
||||
| **`hasMany`** | Boolean which, if set to true, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with hasMany. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with hasMany. |
|
||||
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](../queries/depth) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`displayPreview`** | Enable displaying preview of the uploaded file. Overrides related Collection's `displayPreview` option. [More](/docs/upload/overview#collection-upload-options). |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [Admin Options](./overview#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database. See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| **`graphQL`** | Custom graphQL configuration for the field. [More details](/docs/graphql/overview#field-complexity) |
|
||||
| Option | Description |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`name`** \* | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||
| **`relationTo`** \* | Provide a single collection `slug` to allow this field to accept a relation to. **Note: the related collection must be configured to support Uploads.** |
|
||||
| **`filterOptions`** | A query to filter which options appear in the UI and validate against. [More](#filtering-upload-options). |
|
||||
| **`hasMany`** | Boolean which, if set to true, allows this field to have many relations instead of only one. |
|
||||
| **`minRows`** | A number for the fewest allowed items during validation when a value is present. Used with hasMany. |
|
||||
| **`maxRows`** | A number for the most allowed items during validation when a value is present. Used with hasMany. |
|
||||
| **`maxDepth`** | Sets a number limit on iterations of related documents to populate when queried. [Depth](../queries/depth) |
|
||||
| **`label`** | Text used as a field label in the Admin Panel or an object with keys for each language. |
|
||||
| **`unique`** | Enforce that each entry in the Collection has a unique value for this field. |
|
||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||
| **`index`** | Build an [index](/docs/database/overview) for this field to produce faster queries. Set this field to `true` if your users will perform queries on this field's data often. |
|
||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||
| **`access`** | Provide Field Access Control to denote what users can see and do with this field's data. [More details](../access-control/fields). |
|
||||
| **`hidden`** | Restrict this field's visibility from all APIs entirely. Will still be saved to the database, but will not appear in any API or the Admin Panel. |
|
||||
| **`defaultValue`** | Provide data to be used for this field's default value. [More](/docs/fields/overview#default-values) |
|
||||
| **`displayPreview`** | Enable displaying preview of the uploaded file. Overrides related Collection's `displayPreview` option. [More](/docs/upload/overview#collection-upload-options). |
|
||||
| **`localized`** | Enable localization for this field. Requires [localization to be enabled](/docs/configuration/localization) in the Base config. |
|
||||
| **`required`** | Require this field to have a value. |
|
||||
| **`admin`** | Admin-specific configuration. [Admin Options](./overview#admin-options). |
|
||||
| **`custom`** | Extension point for adding custom data (e.g. for plugins) |
|
||||
| **`typescriptSchema`** | Override field type generation with providing a JSON schema |
|
||||
| **`virtual`** | Provide `true` to disable field in the database, or provide a string path to [link the field with a relationship](/docs/fields/relationship#linking-virtual-fields-with-relationships). See [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) |
|
||||
| **`graphQL`** | Custom graphQL configuration for the field. [More details](/docs/graphql/overview#field-complexity) |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ To install a Database Adapter, you can run **one** of the following commands:
|
||||
```
|
||||
|
||||
- To install the [Postgres Adapter](../database/postgres), run:
|
||||
|
||||
```bash
|
||||
pnpm i @payloadcms/db-postgres
|
||||
```
|
||||
@@ -80,7 +81,7 @@ To install a Database Adapter, you can run **one** of the following commands:
|
||||
|
||||
#### 2. Copy Payload files into your Next.js app folder
|
||||
|
||||
Payload installs directly in your Next.js `/app` folder, and you'll need to place some files into that folder for Payload to run. You can copy these files from the [Blank Template](https://github.com/payloadcms/payload/tree/main/templates/blank/src/app/(payload)) on GitHub. Once you have the required Payload files in place in your `/app` folder, you should have something like this:
|
||||
Payload installs directly in your Next.js `/app` folder, and you'll need to place some files into that folder for Payload to run. You can copy these files from the [Blank Template](<https://github.com/payloadcms/payload/tree/main/templates/blank/src/app/(payload)>) on GitHub. Once you have the required Payload files in place in your `/app` folder, you should have something like this:
|
||||
|
||||
```plaintext
|
||||
app/
|
||||
|
||||
@@ -43,12 +43,13 @@ Setting up Live Preview is easy. This can be done either globally through the [R
|
||||
|
||||
The following options are available:
|
||||
|
||||
| Path | Description |
|
||||
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`url`** \* | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
||||
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
|
||||
| **`collections`** | Array of collection slugs to enable Live Preview on. |
|
||||
| **`globals`** | Array of global slugs to enable Live Preview on. |
|
||||
| Path | Description |
|
||||
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **`url`** \* | String, or function that returns a string, pointing to your front-end application. This value is used as the iframe `src`. [More details](#url). |
|
||||
| **`breakpoints`** | Array of breakpoints to be used as “device sizes” in the preview window. Each item appears as an option in the toolbar. [More details](#breakpoints). |
|
||||
| **`collections`** | Array of collection slugs to enable Live Preview on. |
|
||||
| **`globals`** | Array of global slugs to enable Live Preview on. |
|
||||
| **`defaultTab`** | Boolean to set Live Preview as the default tab when editing documents. Applies to all collections and globals where Live Preview is enabled. Defaults to `false`. |
|
||||
|
||||
_\* An asterisk denotes that a property is required._
|
||||
|
||||
|
||||
@@ -310,7 +310,171 @@ export const PostForm: React.FC = () => {
|
||||
|
||||
## Reusable Payload Server Functions
|
||||
|
||||
Coming soon…
|
||||
Managing authentication with the Local API can be tricky as you have to handle cookies and tokens yourself, and there aren't built-in logout or refresh functions since these only modify cookies. To make this easier, we provide `login`, `logout`, and `refresh` as ready-to-use server functions. They take care of the underlying complexity so you don't have to.
|
||||
|
||||
### Login
|
||||
|
||||
Logs in a user by verifying credentials and setting the authentication cookie. This function allows login via username or email, depending on the collection auth configuration.
|
||||
|
||||
#### Importing the `login` function
|
||||
|
||||
```ts
|
||||
import { login } from '@payloadcms/next/auth'
|
||||
```
|
||||
|
||||
The login function needs your Payload config, which cannot be imported in a client component. To work around this, create a simple server function like the one below, and call it from your client.
|
||||
|
||||
```ts
|
||||
'use server'
|
||||
|
||||
import { login } from '@payloadcms/next/auth'
|
||||
import config from '@payload-config'
|
||||
|
||||
export async function loginAction({
|
||||
email,
|
||||
password,
|
||||
}: {
|
||||
email: string
|
||||
password: string
|
||||
}) {
|
||||
try {
|
||||
const result = await login({
|
||||
collection: 'users',
|
||||
config,
|
||||
email,
|
||||
password,
|
||||
})
|
||||
return result
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Login failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Login from the React Client Component
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { loginAction } from '../loginAction'
|
||||
|
||||
export default function LoginForm() {
|
||||
const [email, setEmail] = useState<string>('')
|
||||
const [password, setPassword] = useState<string>('')
|
||||
|
||||
return (
|
||||
<form onSubmit={() => loginAction({ email, password })}>
|
||||
<label htmlFor="email">Email</label>
|
||||
<input
|
||||
id="email"
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
setEmail(e.target.value)
|
||||
}
|
||||
type="email"
|
||||
value={email}
|
||||
/>
|
||||
<label htmlFor="password">Password</label>
|
||||
<input
|
||||
id="password"
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
setPassword(e.target.value)
|
||||
}
|
||||
type="password"
|
||||
value={password}
|
||||
/>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Logout
|
||||
|
||||
Logs out the current user by clearing the authentication cookie.
|
||||
|
||||
#### Importing the `logout` function
|
||||
|
||||
```ts
|
||||
import { logout } from '@payloadcms/next/auth'
|
||||
```
|
||||
|
||||
Similar to the login function, you now need to pass your Payload config to this function and this cannot be done in a client component. Use a helper server function as shown below.
|
||||
|
||||
```ts
|
||||
'use server'
|
||||
|
||||
import { logout } from '@payloadcms/next/auth'
|
||||
import config from '@payload-config'
|
||||
|
||||
export async function logoutAction() {
|
||||
try {
|
||||
return await logout({ config })
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Logout failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Logout from the React Client Component
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
|
||||
import { logoutAction } from '../logoutAction'
|
||||
|
||||
export default function LogoutButton() {
|
||||
return <button onClick={() => logoutFunction()}>Logout</button>
|
||||
}
|
||||
```
|
||||
|
||||
### Refresh
|
||||
|
||||
Refreshes the authentication token for the logged-in user.
|
||||
|
||||
#### Importing the `refresh` function
|
||||
|
||||
```ts
|
||||
import { refresh } from '@payloadcms/next/auth'
|
||||
```
|
||||
|
||||
As with login and logout, you need to pass your Payload config to this function. Create a helper server function like the one below. Passing the config directly to the client is not possible and will throw errors.
|
||||
|
||||
```ts
|
||||
'use server'
|
||||
|
||||
import { refresh } from '@payloadcms/next/auth'
|
||||
import config from '@payload-config'
|
||||
|
||||
export async function refreshAction() {
|
||||
try {
|
||||
return await refresh({
|
||||
collection: 'users', // pass your collection slug
|
||||
config,
|
||||
})
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`Refresh failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Using Refresh from the React Client Component
|
||||
|
||||
```tsx
|
||||
'use client'
|
||||
|
||||
import { refreshAction } from '../actions/refreshAction'
|
||||
|
||||
export default function RefreshTokenButton() {
|
||||
return <button onClick={() => refreshFunction()}>Refresh</button>
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling in Server Functions
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ keywords: query, documents, pagination, documentation, Content Management System
|
||||
|
||||
Documents in Payload can be easily sorted by a specific [Field](../fields/overview). When querying Documents, you can pass the name of any top-level field, and the response will sort the Documents by that field in _ascending_ order. If prefixed with a minus symbol ("-"), they will be sorted in _descending_ order. In Local API multiple fields can be specified by using an array of strings. In REST API multiple fields can be specified by separating fields with comma. The minus symbol can be in front of individual fields.
|
||||
|
||||
Because sorting is handled by the database, the field cannot be a [Virtual Field](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges). It must be stored in the database to be searchable.
|
||||
Because sorting is handled by the database, the field cannot be a [Virtual Field](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges) unless it's [linked with a relationship field](/docs/fields/relationship#linking-virtual-fields-with-relationships). It must be stored in the database to be searchable.
|
||||
|
||||
<Banner type="success">
|
||||
**Tip:** For performance reasons, it is recommended to enable `index: true`
|
||||
|
||||
@@ -117,7 +117,7 @@ Adding custom access control rules requires:
|
||||
2. A set of fields to conditionally render when that option is selected
|
||||
3. A function that returns the access control rules for that option
|
||||
|
||||
To do this, use the `queryPresets.constraints` property in your [Payload Config](../configuration/payload-config).
|
||||
To do this, use the `queryPresets.constraints` property in your [Payload Config](../configuration/overview).
|
||||
|
||||
```ts
|
||||
import { buildConfig } from 'payload'
|
||||
@@ -128,26 +128,28 @@ const config = buildConfig({
|
||||
// ...
|
||||
// highlight-start
|
||||
constraints: {
|
||||
read: {
|
||||
label: 'Specific Roles',
|
||||
value: 'specificRoles',
|
||||
fields: [
|
||||
{
|
||||
name: 'roles',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
options: [
|
||||
{ label: 'Admin', value: 'admin' },
|
||||
{ label: 'User', value: 'user' },
|
||||
],
|
||||
},
|
||||
],
|
||||
access: ({ req: { user } }) => ({
|
||||
'access.read.roles': {
|
||||
in: [user?.roles],
|
||||
},
|
||||
}),
|
||||
},
|
||||
read: [
|
||||
{
|
||||
label: 'Specific Roles',
|
||||
value: 'specificRoles',
|
||||
fields: [
|
||||
{
|
||||
name: 'roles',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
options: [
|
||||
{ label: 'Admin', value: 'admin' },
|
||||
{ label: 'User', value: 'user' },
|
||||
],
|
||||
},
|
||||
],
|
||||
access: ({ req: { user } }) => ({
|
||||
'access.read.roles': {
|
||||
in: [user?.roles],
|
||||
},
|
||||
}),
|
||||
},
|
||||
],
|
||||
// highlight-end
|
||||
},
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@ Collections and Globals both support the same options for configuring autosave.
|
||||
| Drafts Autosave Options | Description |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `interval` | Define an `interval` in milliseconds to automatically save progress while documents are edited. Document updates are "debounced" at this interval. Defaults to `800`. |
|
||||
| `showSaveDraftButton` | Set this to `true` to show the "Save as draft" button even while autosave is enabled. Defaults to `false`. |
|
||||
|
||||
**Example config with versions, drafts, and autosave enabled:**
|
||||
|
||||
@@ -50,9 +51,13 @@ export const Pages: CollectionConfig = {
|
||||
drafts: {
|
||||
autosave: true,
|
||||
|
||||
// Alternatively, you can specify an `interval`:
|
||||
// Alternatively, you can specify an object to customize autosave:
|
||||
// autosave: {
|
||||
// Define how often the document should be autosaved (in milliseconds)
|
||||
// interval: 1500,
|
||||
//
|
||||
// Show the "Save as draft" button even while autosave is enabled
|
||||
// showSaveDraftButton: true,
|
||||
// },
|
||||
},
|
||||
},
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"payload": "3.11.0",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"sharp": "0.34.0"
|
||||
"sharp": "0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"react-hook-form": "7.45.4",
|
||||
"sharp": "0.34.0",
|
||||
"sharp": "0.32.6",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
"qs-esm": "7.0.2",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"sharp": "0.34.0"
|
||||
"sharp": "0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@payloadcms/graphql": "latest",
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"payload": "latest",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"sharp": "0.34.0"
|
||||
"sharp": "0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"payload-app": "workspace:*",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"sharp": "0.34.0"
|
||||
"sharp": "0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@remix-run/dev": "^2.15.2",
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
"payload": "beta",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"sharp": "0.34.0",
|
||||
"sharp": "0.32.6",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"payload": "latest",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"sharp": "0.34.0"
|
||||
"sharp": "0.32.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@payloadcms/graphql": "latest",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload-monorepo",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -165,7 +165,7 @@
|
||||
"react": "19.1.0",
|
||||
"react-dom": "19.1.0",
|
||||
"rimraf": "6.0.1",
|
||||
"sharp": "0.34.0",
|
||||
"sharp": "0.32.6",
|
||||
"shelljs": "0.8.5",
|
||||
"slash": "3.0.0",
|
||||
"sort-package-json": "^2.10.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/admin-bar",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "An admin bar for React apps using Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-payload-app",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-mongodb",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The officially supported MongoDB database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -166,7 +166,7 @@ export const queryDrafts: QueryDrafts = async function queryDrafts(
|
||||
|
||||
for (let i = 0; i < result.docs.length; i++) {
|
||||
const id = result.docs[i].parent
|
||||
result.docs[i] = result.docs[i].version
|
||||
result.docs[i] = result.docs[i].version ?? {}
|
||||
result.docs[i].id = id
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-postgres",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The officially supported Postgres database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { Connect, Migration, Payload } from 'payload'
|
||||
|
||||
import { pushDevSchema } from '@payloadcms/drizzle'
|
||||
import { drizzle } from 'drizzle-orm/node-postgres'
|
||||
import pg from 'pg'
|
||||
|
||||
import type { PostgresAdapter } from './types.js'
|
||||
|
||||
@@ -61,7 +60,7 @@ export const connect: Connect = async function connect(
|
||||
|
||||
try {
|
||||
if (!this.pool) {
|
||||
this.pool = new pg.Pool(this.poolOptions)
|
||||
this.pool = new this.pg.Pool(this.poolOptions)
|
||||
await connectWithReconnect({ adapter: this, payload: this.payload })
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ import {
|
||||
} from '@payloadcms/drizzle/postgres'
|
||||
import { pgEnum, pgSchema, pgTable } from 'drizzle-orm/pg-core'
|
||||
import { createDatabaseAdapter, defaultBeginTransaction } from 'payload'
|
||||
import pgDependency from 'pg'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { Args, PostgresAdapter } from './types.js'
|
||||
@@ -130,6 +131,7 @@ export function postgresAdapter(args: Args): DatabaseAdapterObj<PostgresAdapter>
|
||||
localesSuffix: args.localesSuffix || '_locales',
|
||||
logger: args.logger,
|
||||
operators: operatorMap,
|
||||
pg: args.pg || pgDependency,
|
||||
pgSchema: adapterSchema,
|
||||
// @ts-expect-error - vestiges of when tsconfig was not strict. Feel free to improve
|
||||
pool: undefined,
|
||||
|
||||
@@ -12,6 +12,8 @@ import type { NodePgDatabase } from 'drizzle-orm/node-postgres'
|
||||
import type { PgSchema, PgTableFn, PgTransactionConfig } from 'drizzle-orm/pg-core'
|
||||
import type { Pool, PoolConfig } from 'pg'
|
||||
|
||||
type PgDependency = typeof import('pg')
|
||||
|
||||
export type Args = {
|
||||
/**
|
||||
* Transform the schema after it's built.
|
||||
@@ -45,6 +47,7 @@ export type Args = {
|
||||
localesSuffix?: string
|
||||
logger?: DrizzleConfig['logger']
|
||||
migrationDir?: string
|
||||
pg?: PgDependency
|
||||
pool: PoolConfig
|
||||
prodMigrations?: {
|
||||
down: (args: MigrateDownArgs) => Promise<void>
|
||||
@@ -74,6 +77,7 @@ type ResolveSchemaType<T> = 'schema' extends keyof T
|
||||
type Drizzle = NodePgDatabase<ResolveSchemaType<GeneratedDatabaseSchema>>
|
||||
export type PostgresAdapter = {
|
||||
drizzle: Drizzle
|
||||
pg: PgDependency
|
||||
pool: Pool
|
||||
poolOptions: PoolConfig
|
||||
} & BasePostgresAdapter
|
||||
@@ -98,6 +102,8 @@ declare module 'payload' {
|
||||
initializing: Promise<void>
|
||||
localesSuffix?: string
|
||||
logger: DrizzleConfig['logger']
|
||||
/** Optionally inject your own node-postgres. This is required if you wish to instrument the driver with @payloadcms/plugin-sentry. */
|
||||
pg?: PgDependency
|
||||
pgSchema?: { table: PgTableFn } | PgSchema
|
||||
pool: Pool
|
||||
poolOptions: Args['pool']
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-sqlite",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The officially supported SQLite database adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/db-vercel-postgres",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "Vercel Postgres adapter for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/drizzle",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "A library of shared functions used by different payload database adapters",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -78,7 +78,9 @@ export const createTableName = ({
|
||||
|
||||
if (result.length > 63) {
|
||||
throw new APIError(
|
||||
`Exceeded max identifier length for table or enum name of 63 characters. Invalid name: ${result}`,
|
||||
`Exceeded max identifier length for table or enum name of 63 characters. Invalid name: ${result}.
|
||||
Tip: You can use the dbName property to reduce the table name length.
|
||||
`,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ import type { FlattenedField, Where } from 'payload'
|
||||
|
||||
import type { DrizzleAdapter, GenericColumn } from '../types.js'
|
||||
import type { BuildQueryJoinAliases } from './buildQuery.js'
|
||||
import type { QueryContext } from './parseParams.js'
|
||||
|
||||
import { parseParams } from './parseParams.js'
|
||||
|
||||
export function buildAndOrConditions({
|
||||
adapter,
|
||||
aliasTable,
|
||||
context,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
@@ -21,6 +23,7 @@ export function buildAndOrConditions({
|
||||
adapter: DrizzleAdapter
|
||||
aliasTable?: Table
|
||||
collectionSlug?: string
|
||||
context: QueryContext
|
||||
fields: FlattenedField[]
|
||||
globalSlug?: string
|
||||
joins: BuildQueryJoinAliases
|
||||
@@ -41,6 +44,7 @@ export function buildAndOrConditions({
|
||||
const result = parseParams({
|
||||
adapter,
|
||||
aliasTable,
|
||||
context,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { PgTableWithColumns } from 'drizzle-orm/pg-core'
|
||||
import type { FlattenedField, Sort, Where } from 'payload'
|
||||
|
||||
import type { DrizzleAdapter, GenericColumn, GenericTable } from '../types.js'
|
||||
import type { QueryContext } from './parseParams.js'
|
||||
|
||||
import { buildOrderBy } from './buildOrderBy.js'
|
||||
import { parseParams } from './parseParams.js'
|
||||
@@ -52,24 +53,14 @@ const buildQuery = function buildQuery({
|
||||
id: adapter.tables[tableName].id,
|
||||
}
|
||||
|
||||
const orderBy = buildOrderBy({
|
||||
adapter,
|
||||
aliasTable,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
parentIsLocalized,
|
||||
selectFields,
|
||||
sort,
|
||||
tableName,
|
||||
})
|
||||
|
||||
let where: SQL
|
||||
|
||||
const context: QueryContext = { sort }
|
||||
if (incomingWhere && Object.keys(incomingWhere).length > 0) {
|
||||
where = parseParams({
|
||||
adapter,
|
||||
aliasTable,
|
||||
context,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
@@ -81,6 +72,18 @@ const buildQuery = function buildQuery({
|
||||
})
|
||||
}
|
||||
|
||||
const orderBy = buildOrderBy({
|
||||
adapter,
|
||||
aliasTable,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
parentIsLocalized,
|
||||
selectFields,
|
||||
sort: context.sort,
|
||||
tableName,
|
||||
})
|
||||
|
||||
return {
|
||||
joins,
|
||||
orderBy,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { SQL, Table } from 'drizzle-orm'
|
||||
import type { FlattenedField, Operator, Where } from 'payload'
|
||||
import type { FlattenedField, Operator, Sort, Where } from 'payload'
|
||||
|
||||
import { and, isNotNull, isNull, ne, notInArray, or, sql } from 'drizzle-orm'
|
||||
import { PgUUID } from 'drizzle-orm/pg-core'
|
||||
@@ -14,9 +14,12 @@ import { buildAndOrConditions } from './buildAndOrConditions.js'
|
||||
import { getTableColumnFromPath } from './getTableColumnFromPath.js'
|
||||
import { sanitizeQueryValue } from './sanitizeQueryValue.js'
|
||||
|
||||
export type QueryContext = { sort: Sort }
|
||||
|
||||
type Args = {
|
||||
adapter: DrizzleAdapter
|
||||
aliasTable?: Table
|
||||
context: QueryContext
|
||||
fields: FlattenedField[]
|
||||
joins: BuildQueryJoinAliases
|
||||
locale?: string
|
||||
@@ -30,6 +33,7 @@ type Args = {
|
||||
export function parseParams({
|
||||
adapter,
|
||||
aliasTable,
|
||||
context,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
@@ -57,6 +61,7 @@ export function parseParams({
|
||||
const builtConditions = buildAndOrConditions({
|
||||
adapter,
|
||||
aliasTable,
|
||||
context,
|
||||
fields,
|
||||
joins,
|
||||
locale,
|
||||
@@ -342,6 +347,7 @@ export function parseParams({
|
||||
)
|
||||
}
|
||||
if (geoConstraints.length) {
|
||||
context.sort = relationOrPath
|
||||
constraints.push(and(...geoConstraints))
|
||||
}
|
||||
break
|
||||
|
||||
@@ -496,6 +496,10 @@ export const traverseFields = ({
|
||||
formattedValue = sql`ST_GeomFromGeoJSON(${JSON.stringify(value)})`
|
||||
}
|
||||
|
||||
if (field.type === 'text' && value && typeof value !== 'string') {
|
||||
formattedValue = JSON.stringify(value)
|
||||
}
|
||||
|
||||
if (field.type === 'date') {
|
||||
if (typeof value === 'number' && !Number.isNaN(value)) {
|
||||
formattedValue = new Date(value).toISOString()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-nodemailer",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "Payload Nodemailer Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/email-resend",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "Payload Resend Email Adapter",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/graphql",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-react",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The official React SDK for Payload Live Preview",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview-vue",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The official Vue SDK for Payload Live Preview",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/live-preview",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The official live preview JavaScript SDK for Payload",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/next",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -37,6 +37,11 @@
|
||||
"types": "./src/exports/routes.ts",
|
||||
"default": "./src/exports/routes.ts"
|
||||
},
|
||||
"./auth": {
|
||||
"import": "./src/exports/auth.ts",
|
||||
"types": "./src/exports/auth.ts",
|
||||
"default": "./src/exports/auth.ts"
|
||||
},
|
||||
"./templates": {
|
||||
"import": "./src/exports/templates.ts",
|
||||
"types": "./src/exports/templates.ts",
|
||||
@@ -151,6 +156,11 @@
|
||||
"types": "./dist/exports/templates.d.ts",
|
||||
"default": "./dist/exports/templates.js"
|
||||
},
|
||||
"./auth": {
|
||||
"import": "./dist/exports/auth.js",
|
||||
"types": "./dist/exports/auth.d.ts",
|
||||
"default": "./dist/exports/auth.js"
|
||||
},
|
||||
"./utilities": {
|
||||
"import": "./dist/exports/utilities.js",
|
||||
"types": "./dist/exports/utilities.d.ts",
|
||||
|
||||
87
packages/next/src/auth/login.ts
Normal file
87
packages/next/src/auth/login.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
'use server'
|
||||
|
||||
import type { CollectionSlug } from 'payload'
|
||||
|
||||
import { cookies as getCookies } from 'next/headers.js'
|
||||
import { generatePayloadCookie, getPayload } from 'payload'
|
||||
|
||||
import { setPayloadAuthCookie } from '../utilities/setPayloadAuthCookie.js'
|
||||
|
||||
type LoginWithEmail = {
|
||||
collection: CollectionSlug
|
||||
config: any
|
||||
email: string
|
||||
password: string
|
||||
username?: never
|
||||
}
|
||||
|
||||
type LoginWithUsername = {
|
||||
collection: CollectionSlug
|
||||
config: any
|
||||
email?: never
|
||||
password: string
|
||||
username: string
|
||||
}
|
||||
type LoginArgs = LoginWithEmail | LoginWithUsername
|
||||
|
||||
export async function login({ collection, config, email, password, username }: LoginArgs): Promise<{
|
||||
token?: string
|
||||
user: any
|
||||
}> {
|
||||
const payload = await getPayload({ config })
|
||||
|
||||
const authConfig = payload.collections[collection]?.config.auth
|
||||
if (!authConfig) {
|
||||
throw new Error(`No auth config found for collection: ${collection}`)
|
||||
}
|
||||
|
||||
const loginWithUsername = authConfig?.loginWithUsername ?? false
|
||||
|
||||
if (loginWithUsername) {
|
||||
if (loginWithUsername.allowEmailLogin) {
|
||||
if (!email && !username) {
|
||||
throw new Error('Email or username is required.')
|
||||
}
|
||||
} else {
|
||||
if (!username) {
|
||||
throw new Error('Username is required.')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!email) {
|
||||
throw new Error('Email is required.')
|
||||
}
|
||||
}
|
||||
|
||||
let loginData
|
||||
|
||||
if (loginWithUsername) {
|
||||
loginData = username ? { password, username } : { email, password }
|
||||
} else {
|
||||
loginData = { email, password }
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await payload.login({
|
||||
collection,
|
||||
data: loginData,
|
||||
})
|
||||
|
||||
if (result.token) {
|
||||
await setPayloadAuthCookie({
|
||||
authConfig,
|
||||
cookiePrefix: payload.config.cookiePrefix,
|
||||
token: result.token,
|
||||
})
|
||||
}
|
||||
|
||||
if ('removeTokenFromResponses' in config && config.removeTokenFromResponses) {
|
||||
delete result.token
|
||||
}
|
||||
|
||||
return result
|
||||
} catch (e) {
|
||||
console.error('Login error:', e)
|
||||
throw new Error(`${e}`)
|
||||
}
|
||||
}
|
||||
29
packages/next/src/auth/logout.ts
Normal file
29
packages/next/src/auth/logout.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
'use server'
|
||||
|
||||
import { cookies as getCookies, headers as nextHeaders } from 'next/headers.js'
|
||||
import { getPayload } from 'payload'
|
||||
|
||||
import { getExistingAuthToken } from '../utilities/getExistingAuthToken.js'
|
||||
|
||||
export async function logout({ config }: { config: any }) {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
const headers = await nextHeaders()
|
||||
const result = await payload.auth({ headers })
|
||||
|
||||
if (!result.user) {
|
||||
return { message: 'User already logged out', success: true }
|
||||
}
|
||||
|
||||
const existingCookie = await getExistingAuthToken(payload.config.cookiePrefix)
|
||||
|
||||
if (existingCookie) {
|
||||
const cookies = await getCookies()
|
||||
cookies.delete(existingCookie.name)
|
||||
return { message: 'User logged out successfully', success: true }
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Logout error:', e)
|
||||
throw new Error(`${e}`)
|
||||
}
|
||||
}
|
||||
42
packages/next/src/auth/refresh.ts
Normal file
42
packages/next/src/auth/refresh.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
'use server'
|
||||
|
||||
import type { CollectionSlug } from 'payload'
|
||||
|
||||
import { headers as nextHeaders } from 'next/headers.js'
|
||||
import { getPayload } from 'payload'
|
||||
|
||||
import { getExistingAuthToken } from '../utilities/getExistingAuthToken.js'
|
||||
import { setPayloadAuthCookie } from '../utilities/setPayloadAuthCookie.js'
|
||||
|
||||
export async function refresh({ collection, config }: { collection: CollectionSlug; config: any }) {
|
||||
try {
|
||||
const payload = await getPayload({ config })
|
||||
const authConfig = payload.collections[collection]?.config.auth
|
||||
|
||||
if (!authConfig) {
|
||||
throw new Error(`No auth config found for collection: ${collection}`)
|
||||
}
|
||||
|
||||
const { user } = await payload.auth({ headers: await nextHeaders() })
|
||||
if (!user) {
|
||||
throw new Error('User not authenticated')
|
||||
}
|
||||
|
||||
const existingCookie = await getExistingAuthToken(payload.config.cookiePrefix)
|
||||
|
||||
if (!existingCookie) {
|
||||
return { message: 'No valid token found', success: false }
|
||||
}
|
||||
|
||||
await setPayloadAuthCookie({
|
||||
authConfig,
|
||||
cookiePrefix: payload.config.cookiePrefix,
|
||||
token: existingCookie.value,
|
||||
})
|
||||
|
||||
return { message: 'Token refreshed successfully', success: true }
|
||||
} catch (e) {
|
||||
console.error('Refresh error:', e)
|
||||
throw new Error(`${e}`)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { DocumentTabConfig } from 'payload'
|
||||
import type React from 'react'
|
||||
|
||||
import { isLivePreviewEnabled } from './isLivePreviewEnabled.js'
|
||||
import { VersionsPill } from './VersionsPill/index.js'
|
||||
|
||||
export const documentViewKeys = [
|
||||
@@ -31,34 +32,39 @@ export const tabs: Record<
|
||||
order: 1000,
|
||||
},
|
||||
default: {
|
||||
condition: ({ collectionConfig, config, globalConfig }) => {
|
||||
return !isLivePreviewEnabled({ collectionConfig, config, globalConfig })
|
||||
},
|
||||
href: '',
|
||||
// isActive: ({ href, location }) =>
|
||||
// location.pathname === href || location.pathname === `${href}/create`,
|
||||
label: ({ t }) => t('general:edit'),
|
||||
order: 0,
|
||||
},
|
||||
edit: {
|
||||
condition: ({ collectionConfig, config, globalConfig }) => {
|
||||
return isLivePreviewEnabled({ collectionConfig, config, globalConfig })
|
||||
},
|
||||
href: '/edit',
|
||||
label: ({ t }) => t('general:edit'),
|
||||
order: 200,
|
||||
},
|
||||
livePreview: {
|
||||
condition: ({ collectionConfig, config, globalConfig }) => {
|
||||
if (collectionConfig) {
|
||||
return Boolean(
|
||||
config?.admin?.livePreview?.collections?.includes(collectionConfig.slug) ||
|
||||
collectionConfig?.admin?.livePreview,
|
||||
)
|
||||
}
|
||||
|
||||
if (globalConfig) {
|
||||
return Boolean(
|
||||
config?.admin?.livePreview?.globals?.includes(globalConfig.slug) ||
|
||||
globalConfig?.admin?.livePreview,
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
return !isLivePreviewEnabled({ collectionConfig, config, globalConfig })
|
||||
},
|
||||
href: '/preview',
|
||||
label: ({ t }) => t('general:livePreview'),
|
||||
order: 100,
|
||||
},
|
||||
livePreviewDefault: {
|
||||
condition: ({ collectionConfig, config, globalConfig }) => {
|
||||
return isLivePreviewEnabled({ collectionConfig, config, globalConfig })
|
||||
},
|
||||
href: '',
|
||||
label: ({ t }) => t('general:livePreview'),
|
||||
order: 0,
|
||||
},
|
||||
references: {
|
||||
condition: () => false,
|
||||
},
|
||||
@@ -77,7 +83,7 @@ export const tabs: Record<
|
||||
),
|
||||
href: '/versions',
|
||||
label: ({ t }) => t('version:versions'),
|
||||
order: 200,
|
||||
order: 300,
|
||||
Pill_Component: VersionsPill,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import type { CollectionConfig, Config, GlobalConfig, SanitizedConfig } from 'payload'
|
||||
|
||||
export function isLivePreviewEnabled({
|
||||
collectionConfig,
|
||||
config,
|
||||
globalConfig,
|
||||
}: {
|
||||
collectionConfig?: CollectionConfig
|
||||
config?: Config | SanitizedConfig
|
||||
globalConfig?: GlobalConfig
|
||||
}): boolean {
|
||||
let isLivePreview = false
|
||||
|
||||
if (collectionConfig) {
|
||||
isLivePreview = Boolean(
|
||||
config?.admin?.livePreview?.collections?.includes(collectionConfig.slug) ||
|
||||
collectionConfig?.admin?.livePreview,
|
||||
)
|
||||
}
|
||||
|
||||
if (globalConfig) {
|
||||
isLivePreview = Boolean(
|
||||
config?.admin?.livePreview?.globals?.includes(globalConfig.slug) ||
|
||||
globalConfig?.admin?.livePreview,
|
||||
)
|
||||
}
|
||||
|
||||
return Boolean(config?.admin?.livePreview?.defaultTab && isLivePreview)
|
||||
}
|
||||
3
packages/next/src/exports/auth.ts
Normal file
3
packages/next/src/exports/auth.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export { login } from '../auth/login.js'
|
||||
export { logout } from '../auth/logout.js'
|
||||
export { refresh } from '../auth/refresh.js'
|
||||
10
packages/next/src/utilities/getExistingAuthToken.ts
Normal file
10
packages/next/src/utilities/getExistingAuthToken.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { cookies as getCookies } from 'next/headers.js'
|
||||
|
||||
type Cookie = {
|
||||
name: string
|
||||
value: string
|
||||
}
|
||||
export async function getExistingAuthToken(cookiePrefix: string): Promise<Cookie | undefined> {
|
||||
const cookies = await getCookies()
|
||||
return cookies.getAll().find((cookie) => cookie.name.startsWith(cookiePrefix))
|
||||
}
|
||||
42
packages/next/src/utilities/setPayloadAuthCookie.ts
Normal file
42
packages/next/src/utilities/setPayloadAuthCookie.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import type { Auth } from 'payload'
|
||||
|
||||
import { cookies as getCookies } from 'next/headers.js'
|
||||
import { generatePayloadCookie } from 'payload'
|
||||
|
||||
type SetPayloadAuthCookieArgs = {
|
||||
authConfig: Auth
|
||||
cookiePrefix: string
|
||||
token: string
|
||||
}
|
||||
|
||||
export async function setPayloadAuthCookie({
|
||||
authConfig,
|
||||
cookiePrefix,
|
||||
token,
|
||||
}: SetPayloadAuthCookieArgs): Promise<void> {
|
||||
const cookies = await getCookies()
|
||||
|
||||
const cookieExpiration = authConfig.tokenExpiration
|
||||
? new Date(Date.now() + authConfig.tokenExpiration)
|
||||
: undefined
|
||||
|
||||
const payloadCookie = generatePayloadCookie({
|
||||
collectionAuthConfig: authConfig,
|
||||
cookiePrefix,
|
||||
expires: cookieExpiration,
|
||||
returnCookieAsObject: true,
|
||||
token,
|
||||
})
|
||||
|
||||
if (payloadCookie.value) {
|
||||
cookies.set(payloadCookie.name, payloadCookie.value, {
|
||||
domain: authConfig.cookies.domain,
|
||||
expires: payloadCookie.expires ? new Date(payloadCookie.expires) : undefined,
|
||||
httpOnly: true,
|
||||
sameSite: (typeof authConfig.cookies.sameSite === 'string'
|
||||
? authConfig.cookies.sameSite.toLowerCase()
|
||||
: 'lax') as 'lax' | 'none' | 'strict',
|
||||
secure: authConfig.cookies.secure || false,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ export const APIViewClient: React.FC = () => {
|
||||
|
||||
const {
|
||||
config: {
|
||||
defaultDepth,
|
||||
localization,
|
||||
routes: { api: apiRoute },
|
||||
serverURL,
|
||||
@@ -62,7 +63,9 @@ export const APIViewClient: React.FC = () => {
|
||||
const [data, setData] = React.useState<any>(initialData)
|
||||
const [draft, setDraft] = React.useState<boolean>(searchParams.get('draft') === 'true')
|
||||
const [locale, setLocale] = React.useState<string>(searchParams?.get('locale') || code)
|
||||
const [depth, setDepth] = React.useState<string>(searchParams.get('depth') || '1')
|
||||
const [depth, setDepth] = React.useState<string>(
|
||||
searchParams.get('depth') || defaultDepth.toString(),
|
||||
)
|
||||
const [authenticated, setAuthenticated] = React.useState<boolean>(true)
|
||||
const [fullscreen, setFullscreen] = React.useState<boolean>(false)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { EditConfig, SanitizedCollectionConfig, SanitizedGlobalConfig } fro
|
||||
|
||||
import type { GenerateViewMetadata } from '../Root/index.js'
|
||||
|
||||
import { isLivePreviewEnabled } from '../../elements/DocumentHeader/Tabs/tabs/isLivePreviewEnabled.js'
|
||||
import { getNextRequestI18n } from '../../utilities/getNextRequestI18n.js'
|
||||
import { generateAPIViewMetadata } from '../API/metadata.js'
|
||||
import { generateEditViewMetadata } from '../Edit/metadata.js'
|
||||
@@ -37,10 +38,16 @@ export const getMetaBySegment: GenerateEditViewMetadata = async ({
|
||||
const isEditing =
|
||||
isGlobal || Boolean(isCollection && segments?.length > 2 && segments[2] !== 'create')
|
||||
|
||||
const isLivePreview = isLivePreviewEnabled({
|
||||
collectionConfig,
|
||||
config,
|
||||
globalConfig,
|
||||
})
|
||||
|
||||
if (isCollection) {
|
||||
// `/:collection/:id`
|
||||
if (params.segments.length === 3) {
|
||||
fn = generateEditViewMetadata
|
||||
fn = isLivePreview ? generateLivePreviewViewMetadata : generateEditViewMetadata
|
||||
}
|
||||
|
||||
// `/:collection/:id/:view`
|
||||
@@ -50,6 +57,10 @@ export const getMetaBySegment: GenerateEditViewMetadata = async ({
|
||||
// `/:collection/:id/api`
|
||||
fn = generateAPIViewMetadata
|
||||
break
|
||||
case 'edit':
|
||||
// `/:collection/:id/edit`
|
||||
fn = generateEditViewMetadata
|
||||
break
|
||||
case 'preview':
|
||||
// `/:collection/:id/preview`
|
||||
fn = generateLivePreviewViewMetadata
|
||||
@@ -79,7 +90,7 @@ export const getMetaBySegment: GenerateEditViewMetadata = async ({
|
||||
if (isGlobal) {
|
||||
// `/:global`
|
||||
if (params.segments?.length === 2) {
|
||||
fn = generateEditViewMetadata
|
||||
fn = isLivePreview ? generateLivePreviewViewMetadata : generateEditViewMetadata
|
||||
}
|
||||
|
||||
// `/:global/:view`
|
||||
@@ -89,6 +100,10 @@ export const getMetaBySegment: GenerateEditViewMetadata = async ({
|
||||
// `/:global/api`
|
||||
fn = generateAPIViewMetadata
|
||||
break
|
||||
case 'edit':
|
||||
// `/:collection/:id/edit`
|
||||
fn = generateEditViewMetadata
|
||||
break
|
||||
case 'preview':
|
||||
// `/:global/preview`
|
||||
fn = generateLivePreviewViewMetadata
|
||||
|
||||
@@ -74,6 +74,8 @@ export const getViewsFromConfig = ({
|
||||
(globalConfig && globalConfig?.admin?.livePreview) ||
|
||||
config?.admin?.livePreview?.globals?.includes(globalConfig?.slug)
|
||||
|
||||
const useLivePreviewAsDefault = config?.admin?.livePreview?.defaultTab && livePreviewEnabled
|
||||
|
||||
if (collectionConfig) {
|
||||
const [collectionEntity, collectionSlug, segment3, segment4, segment5, ...remainingSegments] =
|
||||
routeSegments
|
||||
@@ -130,11 +132,14 @@ export const getViewsFromConfig = ({
|
||||
}
|
||||
} else {
|
||||
CustomView = {
|
||||
ComponentConfig: getCustomViewByKey(views, 'default'),
|
||||
ComponentConfig: getCustomViewByKey(
|
||||
views,
|
||||
useLivePreviewAsDefault ? 'live-preview' : 'default',
|
||||
),
|
||||
}
|
||||
|
||||
DefaultView = {
|
||||
Component: DefaultEditView,
|
||||
Component: useLivePreviewAsDefault ? DefaultLivePreviewView : DefaultEditView,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,8 +164,21 @@ export const getViewsFromConfig = ({
|
||||
break
|
||||
}
|
||||
|
||||
case 'edit': {
|
||||
if (useLivePreviewAsDefault) {
|
||||
CustomView = {
|
||||
ComponentConfig: getCustomViewByKey(views, 'default'),
|
||||
}
|
||||
|
||||
DefaultView = {
|
||||
Component: DefaultEditView,
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'preview': {
|
||||
if (livePreviewEnabled) {
|
||||
if (livePreviewEnabled && !useLivePreviewAsDefault) {
|
||||
DefaultView = {
|
||||
Component: DefaultLivePreviewView,
|
||||
}
|
||||
@@ -283,10 +301,14 @@ export const getViewsFromConfig = ({
|
||||
switch (routeSegments.length) {
|
||||
case 2: {
|
||||
CustomView = {
|
||||
ComponentConfig: getCustomViewByKey(views, 'default'),
|
||||
ComponentConfig: getCustomViewByKey(
|
||||
views,
|
||||
useLivePreviewAsDefault ? 'live-preview' : 'default',
|
||||
),
|
||||
}
|
||||
|
||||
DefaultView = {
|
||||
Component: DefaultEditView,
|
||||
Component: useLivePreviewAsDefault ? DefaultLivePreviewView : DefaultEditView,
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -306,8 +328,21 @@ export const getViewsFromConfig = ({
|
||||
break
|
||||
}
|
||||
|
||||
case 'edit': {
|
||||
if (useLivePreviewAsDefault) {
|
||||
CustomView = {
|
||||
ComponentConfig: getCustomViewByKey(views, 'default'),
|
||||
}
|
||||
|
||||
DefaultView = {
|
||||
Component: DefaultEditView,
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'preview': {
|
||||
if (livePreviewEnabled) {
|
||||
if (livePreviewEnabled && !useLivePreviewAsDefault) {
|
||||
DefaultView = {
|
||||
Component: DefaultLivePreviewView,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type {
|
||||
BeforeDocumentControlsServerPropsOnly,
|
||||
DefaultServerFunctionArgs,
|
||||
DocumentSlots,
|
||||
PayloadRequest,
|
||||
@@ -42,6 +43,18 @@ export const renderDocumentSlots: (args: {
|
||||
// TODO: Add remaining serverProps
|
||||
}
|
||||
|
||||
const BeforeDocumentControls =
|
||||
collectionConfig?.admin?.components?.edit?.beforeDocumentControls ||
|
||||
globalConfig?.admin?.components?.elements?.beforeDocumentControls
|
||||
|
||||
if (BeforeDocumentControls) {
|
||||
components.BeforeDocumentControls = RenderServerComponent({
|
||||
Component: BeforeDocumentControls,
|
||||
importMap: req.payload.importMap,
|
||||
serverProps: serverProps satisfies BeforeDocumentControlsServerPropsOnly,
|
||||
})
|
||||
}
|
||||
|
||||
const CustomPreviewButton =
|
||||
collectionConfig?.admin?.components?.edit?.PreviewButton ||
|
||||
globalConfig?.admin?.components?.elements?.PreviewButton
|
||||
|
||||
@@ -31,7 +31,6 @@ export const ToolbarControls: React.FC<EditViewProps> = () => {
|
||||
<span>
|
||||
{breakpoints.find((bp) => bp.name == breakpoint)?.label ?? customOption.label}
|
||||
</span>
|
||||
|
||||
<ChevronIcon className={`${baseClass}__chevron`} />
|
||||
</React.Fragment>
|
||||
}
|
||||
@@ -82,7 +81,6 @@ export const ToolbarControls: React.FC<EditViewProps> = () => {
|
||||
button={
|
||||
<React.Fragment>
|
||||
<span>{zoom * 100}%</span>
|
||||
|
||||
<ChevronIcon className={`${baseClass}__chevron`} />
|
||||
</React.Fragment>
|
||||
}
|
||||
|
||||
@@ -140,6 +140,13 @@ export const withPayload = (nextConfig = {}, options = {}) => {
|
||||
{ module: /node_modules\/mongodb\/lib\/bson\.js/ },
|
||||
{ file: /node_modules\/mongodb\/lib\/bson\.js/ },
|
||||
],
|
||||
plugins: [
|
||||
...(incomingWebpackConfig?.plugins || []),
|
||||
// Fix cloudflare:sockets error: https://github.com/vercel/next.js/discussions/50177
|
||||
new webpackOptions.webpack.IgnorePlugin({
|
||||
resourceRegExp: /^pg-native$|^cloudflare:sockets$/,
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
...(incomingWebpackConfig?.resolve || {}),
|
||||
alias: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/payload-cloud",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The official Payload Cloud plugin",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "Node, React, Headless CMS and Application Framework built on Next.js",
|
||||
"keywords": [
|
||||
"admin panel",
|
||||
@@ -131,7 +131,7 @@
|
||||
"graphql-http": "^1.22.0",
|
||||
"react-datepicker": "7.6.0",
|
||||
"rimraf": "6.0.1",
|
||||
"sharp": "0.34.0",
|
||||
"sharp": "0.32.6",
|
||||
"typescript-strict-plugin": "2.4.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -553,6 +553,7 @@ export type FieldRow = {
|
||||
}
|
||||
|
||||
export type DocumentSlots = {
|
||||
BeforeDocumentControls?: React.ReactNode
|
||||
Description?: React.ReactNode
|
||||
PreviewButton?: React.ReactNode
|
||||
PublishButton?: React.ReactNode
|
||||
@@ -578,6 +579,9 @@ export type { LanguageOptions } from './LanguageOptions.js'
|
||||
export type { RichTextAdapter, RichTextAdapterProvider, RichTextHooks } from './RichText.js'
|
||||
|
||||
export type {
|
||||
BeforeDocumentControlsClientProps,
|
||||
BeforeDocumentControlsServerProps,
|
||||
BeforeDocumentControlsServerPropsOnly,
|
||||
DocumentSubViewTypes,
|
||||
DocumentTabClientProps,
|
||||
/**
|
||||
|
||||
@@ -36,12 +36,12 @@ export type DocumentTabServerPropsOnly = {
|
||||
readonly permissions: SanitizedPermissions
|
||||
} & ServerProps
|
||||
|
||||
export type DocumentTabServerProps = DocumentTabClientProps & DocumentTabServerPropsOnly
|
||||
|
||||
export type DocumentTabClientProps = {
|
||||
path: string
|
||||
}
|
||||
|
||||
export type DocumentTabServerProps = DocumentTabClientProps & DocumentTabServerPropsOnly
|
||||
|
||||
export type DocumentTabCondition = (args: {
|
||||
collectionConfig: SanitizedCollectionConfig
|
||||
config: SanitizedConfig
|
||||
@@ -75,3 +75,10 @@ export type DocumentTabConfig = {
|
||||
export type DocumentTabComponent = PayloadComponent<{
|
||||
path: string
|
||||
}>
|
||||
|
||||
// BeforeDocumentControls
|
||||
|
||||
export type BeforeDocumentControlsClientProps = {}
|
||||
export type BeforeDocumentControlsServerPropsOnly = {} & ServerProps
|
||||
export type BeforeDocumentControlsServerProps = BeforeDocumentControlsClientProps &
|
||||
BeforeDocumentControlsServerPropsOnly
|
||||
|
||||
@@ -36,6 +36,7 @@ export function iterateCollections({
|
||||
addToImportMap(collection.admin?.components?.beforeListTable)
|
||||
addToImportMap(collection.admin?.components?.Description)
|
||||
|
||||
addToImportMap(collection.admin?.components?.edit?.beforeDocumentControls)
|
||||
addToImportMap(collection.admin?.components?.edit?.PreviewButton)
|
||||
addToImportMap(collection.admin?.components?.edit?.PublishButton)
|
||||
addToImportMap(collection.admin?.components?.edit?.SaveButton)
|
||||
|
||||
@@ -279,6 +279,10 @@ export type CollectionAdminOptions = {
|
||||
* Components within the edit view
|
||||
*/
|
||||
edit?: {
|
||||
/**
|
||||
* Inject custom components before the document controls
|
||||
*/
|
||||
beforeDocumentControls?: CustomComponent[]
|
||||
/**
|
||||
* Replaces the "Preview" button
|
||||
*/
|
||||
|
||||
@@ -33,9 +33,9 @@ export const validateUseAsTitle = (config: CollectionConfig) => {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (useAsTitleField && fieldIsVirtual(useAsTitleField)) {
|
||||
if (useAsTitleField && 'virtual' in useAsTitleField && useAsTitleField.virtual === true) {
|
||||
throw new InvalidConfiguration(
|
||||
`The field "${config.admin.useAsTitle}" specified in "admin.useAsTitle" in the collection "${config.slug}" is virtual. A virtual field cannot be used as the title.`,
|
||||
`The field "${config.admin.useAsTitle}" specified in "admin.useAsTitle" in the collection "${config.slug}" is virtual. A virtual field can be used as the title only when linked to a relationship field.`,
|
||||
)
|
||||
}
|
||||
if (!useAsTitleField) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import { buildVersionCollectionFields } from '../../versions/buildCollectionFiel
|
||||
import { appendVersionToQueryKey } from '../../versions/drafts/appendVersionToQueryKey.js'
|
||||
import { getQueryDraftsSelect } from '../../versions/drafts/getQueryDraftsSelect.js'
|
||||
import { getQueryDraftsSort } from '../../versions/drafts/getQueryDraftsSort.js'
|
||||
import { sanitizeSortQuery } from './utilities/sanitizeSortQuery.js'
|
||||
import { buildAfterOperation } from './utils.js'
|
||||
|
||||
export type Arguments = {
|
||||
@@ -96,7 +97,7 @@ export const findOperation = async <
|
||||
req,
|
||||
select: incomingSelect,
|
||||
showHiddenFields,
|
||||
sort,
|
||||
sort: incomingSort,
|
||||
where,
|
||||
} = args
|
||||
|
||||
@@ -143,6 +144,11 @@ export const findOperation = async <
|
||||
|
||||
let fullWhere = combineQueries(where, accessResult)
|
||||
|
||||
const sort = sanitizeSortQuery({
|
||||
fields: collection.config.flattenedFields,
|
||||
sort: incomingSort,
|
||||
})
|
||||
|
||||
const sanitizedJoins = await sanitizeJoinQuery({
|
||||
collectionConfig,
|
||||
joins,
|
||||
@@ -170,7 +176,10 @@ export const findOperation = async <
|
||||
pagination: usePagination,
|
||||
req,
|
||||
select: getQueryDraftsSelect({ select }),
|
||||
sort: getQueryDraftsSort({ collectionConfig, sort }),
|
||||
sort: getQueryDraftsSort({
|
||||
collectionConfig,
|
||||
sort,
|
||||
}),
|
||||
where: fullWhere,
|
||||
})
|
||||
} else {
|
||||
|
||||
@@ -27,6 +27,7 @@ import { sanitizeSelect } from '../../utilities/sanitizeSelect.js'
|
||||
import { buildVersionCollectionFields } from '../../versions/buildCollectionFields.js'
|
||||
import { appendVersionToQueryKey } from '../../versions/drafts/appendVersionToQueryKey.js'
|
||||
import { getQueryDraftsSort } from '../../versions/drafts/getQueryDraftsSort.js'
|
||||
import { sanitizeSortQuery } from './utilities/sanitizeSortQuery.js'
|
||||
import { updateDocument } from './utilities/update.js'
|
||||
import { buildAfterOperation } from './utils.js'
|
||||
|
||||
@@ -103,7 +104,7 @@ export const updateOperation = async <
|
||||
req,
|
||||
select: incomingSelect,
|
||||
showHiddenFields,
|
||||
sort,
|
||||
sort: incomingSort,
|
||||
where,
|
||||
} = args
|
||||
|
||||
@@ -136,6 +137,11 @@ export const updateOperation = async <
|
||||
|
||||
const fullWhere = combineQueries(where, accessResult)
|
||||
|
||||
const sort = sanitizeSortQuery({
|
||||
fields: collection.config.flattenedFields,
|
||||
sort: incomingSort,
|
||||
})
|
||||
|
||||
let docs
|
||||
|
||||
if (collectionConfig.versions?.drafts && shouldSaveDraft) {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import type { FlattenedField } from '../../../fields/config/types.js'
|
||||
|
||||
const sanitizeSort = ({ fields, sort }: { fields: FlattenedField[]; sort: string }): string => {
|
||||
let sortProperty = sort
|
||||
let desc = false
|
||||
if (sort.indexOf('-') === 0) {
|
||||
desc = true
|
||||
sortProperty = sortProperty.substring(1)
|
||||
}
|
||||
|
||||
const segments = sortProperty.split('.')
|
||||
|
||||
for (const segment of segments) {
|
||||
const field = fields.find((each) => each.name === segment)
|
||||
if (!field) {
|
||||
return sort
|
||||
}
|
||||
|
||||
if ('fields' in field) {
|
||||
fields = field.flattenedFields
|
||||
continue
|
||||
}
|
||||
|
||||
if ('virtual' in field && typeof field.virtual === 'string') {
|
||||
return `${desc ? '-' : ''}${field.virtual}`
|
||||
}
|
||||
}
|
||||
|
||||
return sort
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the sort parameter, for example virtual fields linked to relationships are replaced with the full path.
|
||||
*/
|
||||
export const sanitizeSortQuery = ({
|
||||
fields,
|
||||
sort,
|
||||
}: {
|
||||
fields: FlattenedField[]
|
||||
sort?: string | string[]
|
||||
}): string | string[] | undefined => {
|
||||
if (!sort) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (Array.isArray(sort)) {
|
||||
return sort.map((sort) => sanitizeSort({ fields, sort }))
|
||||
}
|
||||
|
||||
return sanitizeSort({ fields, sort })
|
||||
}
|
||||
@@ -257,7 +257,6 @@ export const addOrderableEndpoint = (config: SanitizedConfig) => {
|
||||
},
|
||||
depth: 0,
|
||||
req,
|
||||
select: { id: true },
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -148,6 +148,13 @@ export type LivePreviewConfig = {
|
||||
name: string
|
||||
width: number | string
|
||||
}[]
|
||||
/**
|
||||
* Set Live Preview as the default tab when editing documents.
|
||||
* If enabled, the Live Preview tab will be shown first instead of the Edit tab.
|
||||
* This applies to all collections or globals where Live Preview is enabled.
|
||||
* False by default.
|
||||
*/
|
||||
defaultTab?: boolean
|
||||
/**
|
||||
The URL of the frontend application. This will be rendered within an `iframe` as its `src`.
|
||||
Payload will send a `window.postMessage()` to this URL with the document data in real-time.
|
||||
|
||||
@@ -28,22 +28,6 @@ type Args = {
|
||||
}
|
||||
)
|
||||
|
||||
const flattenWhere = (query: Where): WhereField[] => {
|
||||
const flattenedConstraints: WhereField[] = []
|
||||
|
||||
for (const [key, val] of Object.entries(query)) {
|
||||
if ((key === 'and' || key === 'or') && Array.isArray(val)) {
|
||||
for (const subVal of val) {
|
||||
flattenedConstraints.push(...flattenWhere(subVal))
|
||||
}
|
||||
} else {
|
||||
flattenedConstraints.push({ [key]: val })
|
||||
}
|
||||
}
|
||||
|
||||
return flattenedConstraints
|
||||
}
|
||||
|
||||
export async function validateQueryPaths({
|
||||
collectionConfig,
|
||||
errors = [],
|
||||
@@ -61,17 +45,47 @@ export async function validateQueryPaths({
|
||||
const fields = versionFields || (globalConfig || collectionConfig).flattenedFields
|
||||
|
||||
if (typeof where === 'object') {
|
||||
const whereFields = flattenWhere(where)
|
||||
// We need to determine if the whereKey is an AND, OR, or a schema path
|
||||
const promises = []
|
||||
for (const constraint of whereFields) {
|
||||
for (const path in constraint) {
|
||||
for (const operator in constraint[path]) {
|
||||
const val = constraint[path][operator]
|
||||
for (const path in where) {
|
||||
const constraint = where[path]
|
||||
|
||||
if ((path === 'and' || path === 'or') && Array.isArray(constraint)) {
|
||||
for (const item of constraint) {
|
||||
if (collectionConfig) {
|
||||
promises.push(
|
||||
validateQueryPaths({
|
||||
collectionConfig,
|
||||
errors,
|
||||
overrideAccess,
|
||||
policies,
|
||||
req,
|
||||
versionFields,
|
||||
where: item,
|
||||
}),
|
||||
)
|
||||
} else {
|
||||
promises.push(
|
||||
validateQueryPaths({
|
||||
errors,
|
||||
globalConfig,
|
||||
overrideAccess,
|
||||
policies,
|
||||
req,
|
||||
versionFields,
|
||||
where: item,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (!Array.isArray(constraint)) {
|
||||
for (const operator in constraint) {
|
||||
const val = constraint[operator]
|
||||
if (validOperatorSet.has(operator as Operator)) {
|
||||
promises.push(
|
||||
validateSearchParam({
|
||||
collectionConfig,
|
||||
constraint: where as WhereField,
|
||||
errors,
|
||||
fields,
|
||||
globalConfig,
|
||||
|
||||
@@ -2,17 +2,19 @@
|
||||
import type { SanitizedCollectionConfig } from '../../collections/config/types.js'
|
||||
import type { FlattenedField } from '../../fields/config/types.js'
|
||||
import type { SanitizedGlobalConfig } from '../../globals/config/types.js'
|
||||
import type { PayloadRequest } from '../../types/index.js'
|
||||
import type { PayloadRequest, WhereField } from '../../types/index.js'
|
||||
import type { EntityPolicies, PathToQuery } from './types.js'
|
||||
|
||||
import { fieldAffectsData, fieldIsVirtual } from '../../fields/config/types.js'
|
||||
import { getEntityPolicies } from '../../utilities/getEntityPolicies.js'
|
||||
import { getFieldByPath } from '../../utilities/getFieldByPath.js'
|
||||
import isolateObjectProperty from '../../utilities/isolateObjectProperty.js'
|
||||
import { getLocalizedPaths } from '../getLocalizedPaths.js'
|
||||
import { validateQueryPaths } from './validateQueryPaths.js'
|
||||
|
||||
type Args = {
|
||||
collectionConfig?: SanitizedCollectionConfig
|
||||
constraint: WhereField
|
||||
errors: { path: string }[]
|
||||
fields: FlattenedField[]
|
||||
globalConfig?: SanitizedGlobalConfig
|
||||
@@ -32,6 +34,7 @@ type Args = {
|
||||
*/
|
||||
export async function validateSearchParam({
|
||||
collectionConfig,
|
||||
constraint,
|
||||
errors,
|
||||
fields,
|
||||
globalConfig,
|
||||
@@ -100,8 +103,13 @@ export async function validateSearchParam({
|
||||
return
|
||||
}
|
||||
|
||||
if (fieldIsVirtual(field)) {
|
||||
errors.push({ path })
|
||||
if ('virtual' in field && field.virtual) {
|
||||
if (field.virtual === true) {
|
||||
errors.push({ path })
|
||||
} else {
|
||||
constraint[`${field.virtual}`] = constraint[path]
|
||||
delete constraint[path]
|
||||
}
|
||||
}
|
||||
|
||||
if (polymorphicJoin && path === 'relationTo') {
|
||||
|
||||
@@ -269,6 +269,7 @@ export type Condition<TData extends TypeWithID = any, TSiblingData = any> = (
|
||||
siblingData: Partial<TSiblingData>,
|
||||
{
|
||||
blockData,
|
||||
operation,
|
||||
path,
|
||||
user,
|
||||
}: {
|
||||
@@ -276,6 +277,10 @@ export type Condition<TData extends TypeWithID = any, TSiblingData = any> = (
|
||||
* The data of the nearest parent block. If the field is not within a block, `blockData` will be equal to `undefined`.
|
||||
*/
|
||||
blockData: Partial<TData>
|
||||
/**
|
||||
* A string relating to which operation the field type is currently executing within.
|
||||
*/
|
||||
operation: Operation
|
||||
/**
|
||||
* The path of the field, e.g. ["group", "myArray", 1, "textField"]. The path is the schemaPath but with indexes and would be used in the context of field data, not field schemas.
|
||||
*/
|
||||
@@ -509,9 +514,9 @@ export interface FieldBase {
|
||||
/**
|
||||
* Pass `true` to disable field in the DB
|
||||
* for [Virtual Fields](https://payloadcms.com/blog/learn-how-virtual-fields-can-help-solve-common-cms-challenges):
|
||||
* A virtual field cannot be used in `admin.useAsTitle`
|
||||
* A virtual field can be used in `admin.useAsTitle` only when linked to a relationship.
|
||||
*/
|
||||
virtual?: boolean
|
||||
virtual?: boolean | string
|
||||
}
|
||||
|
||||
export interface FieldBaseClient {
|
||||
@@ -1143,6 +1148,7 @@ type SharedRelationshipPropertiesClient = FieldBaseClient &
|
||||
type RelationshipAdmin = {
|
||||
allowCreate?: boolean
|
||||
allowEdit?: boolean
|
||||
appearance?: 'drawer' | 'select'
|
||||
components?: {
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
@@ -1157,7 +1163,7 @@ type RelationshipAdmin = {
|
||||
} & Admin
|
||||
|
||||
type RelationshipAdminClient = AdminClient &
|
||||
Pick<RelationshipAdmin, 'allowCreate' | 'allowEdit' | 'isSortable'>
|
||||
Pick<RelationshipAdmin, 'allowCreate' | 'allowEdit' | 'appearance' | 'isSortable'>
|
||||
|
||||
export type PolymorphicRelationshipField = {
|
||||
admin?: {
|
||||
@@ -1949,7 +1955,7 @@ export function fieldShouldBeLocalized({
|
||||
}
|
||||
|
||||
export function fieldIsVirtual(field: Field | Tab): boolean {
|
||||
return 'virtual' in field && field.virtual
|
||||
return 'virtual' in field && Boolean(field.virtual)
|
||||
}
|
||||
|
||||
export type HookName =
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import type { RichTextAdapter } from '../../../admin/RichText.js'
|
||||
import type { SanitizedCollectionConfig } from '../../../collections/config/types.js'
|
||||
import type { SanitizedGlobalConfig } from '../../../globals/config/types.js'
|
||||
import type { RequestContext } from '../../../index.js'
|
||||
import type {
|
||||
JsonObject,
|
||||
PayloadRequest,
|
||||
@@ -13,6 +12,7 @@ import type {
|
||||
import type { Block, Field, TabAsField } from '../../config/types.js'
|
||||
|
||||
import { MissingEditorProp } from '../../../errors/index.js'
|
||||
import { type RequestContext } from '../../../index.js'
|
||||
import { getBlockSelect } from '../../../utilities/getBlockSelect.js'
|
||||
import { stripUnselectedFields } from '../../../utilities/stripUnselectedFields.js'
|
||||
import { fieldAffectsData, fieldShouldBeLocalized, tabHasName } from '../../config/types.js'
|
||||
@@ -20,6 +20,7 @@ import { getDefaultValue } from '../../getDefaultValue.js'
|
||||
import { getFieldPathsModified as getFieldPaths } from '../../getFieldPaths.js'
|
||||
import { relationshipPopulationPromise } from './relationshipPopulationPromise.js'
|
||||
import { traverseFields } from './traverseFields.js'
|
||||
import { virtualFieldPopulationPromise } from './virtualFieldPopulationPromise.js'
|
||||
|
||||
type Args = {
|
||||
/**
|
||||
@@ -306,6 +307,24 @@ export const promise = async ({
|
||||
}
|
||||
}
|
||||
|
||||
if ('virtual' in field && typeof field.virtual === 'string') {
|
||||
populationPromises.push(
|
||||
virtualFieldPopulationPromise({
|
||||
name: field.name,
|
||||
draft,
|
||||
fallbackLocale,
|
||||
fields: (collection || global).flattenedFields,
|
||||
locale,
|
||||
overrideAccess,
|
||||
ref: doc,
|
||||
req,
|
||||
segments: field.virtual.split('.'),
|
||||
showHiddenFields,
|
||||
siblingDoc,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// Execute access control
|
||||
let allowDefaultValue = true
|
||||
if (triggerAccessControl && field.access && field.access.read) {
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
import type { PayloadRequest } from '../../../types/index.js'
|
||||
import type { FlattenedField } from '../../config/types.js'
|
||||
|
||||
import { createDataloaderCacheKey } from '../../../collections/dataloader.js'
|
||||
|
||||
export const virtualFieldPopulationPromise = async ({
|
||||
name,
|
||||
draft,
|
||||
fallbackLocale,
|
||||
fields,
|
||||
locale,
|
||||
overrideAccess,
|
||||
ref,
|
||||
req,
|
||||
segments,
|
||||
showHiddenFields,
|
||||
siblingDoc,
|
||||
}: {
|
||||
draft: boolean
|
||||
fallbackLocale: string
|
||||
fields: FlattenedField[]
|
||||
locale: string
|
||||
name: string
|
||||
overrideAccess: boolean
|
||||
ref: any
|
||||
req: PayloadRequest
|
||||
segments: string[]
|
||||
showHiddenFields: boolean
|
||||
siblingDoc: Record<string, unknown>
|
||||
}): Promise<void> => {
|
||||
const currentSegment = segments.shift()
|
||||
|
||||
if (!currentSegment) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentValue = ref[currentSegment]
|
||||
|
||||
if (typeof currentValue === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
// Final step
|
||||
if (segments.length === 0) {
|
||||
siblingDoc[name] = currentValue
|
||||
return
|
||||
}
|
||||
|
||||
const currentField = fields.find((each) => each.name === currentSegment)
|
||||
|
||||
if (!currentField) {
|
||||
return
|
||||
}
|
||||
|
||||
if (currentField.type === 'group' || currentField.type === 'tab') {
|
||||
if (!currentValue || typeof currentValue !== 'object') {
|
||||
return
|
||||
}
|
||||
|
||||
return virtualFieldPopulationPromise({
|
||||
name,
|
||||
draft,
|
||||
fallbackLocale,
|
||||
fields: currentField.flattenedFields,
|
||||
locale,
|
||||
overrideAccess,
|
||||
ref: currentValue,
|
||||
req,
|
||||
segments,
|
||||
showHiddenFields,
|
||||
siblingDoc,
|
||||
})
|
||||
}
|
||||
|
||||
if (
|
||||
(currentField.type === 'relationship' || currentField.type === 'upload') &&
|
||||
typeof currentField.relationTo === 'string' &&
|
||||
!currentField.hasMany
|
||||
) {
|
||||
let docID: number | string
|
||||
|
||||
if (typeof currentValue === 'object' && currentValue) {
|
||||
docID = currentValue.id
|
||||
} else {
|
||||
docID = currentValue
|
||||
}
|
||||
|
||||
if (segments[0] === 'id' && segments.length === 0) {
|
||||
siblingDoc[name] = docID
|
||||
return
|
||||
}
|
||||
|
||||
if (typeof docID !== 'string' && typeof docID !== 'number') {
|
||||
return
|
||||
}
|
||||
|
||||
const select = {}
|
||||
let currentSelectRef: any = select
|
||||
const currentFields = req.payload.collections[currentField.relationTo].config.flattenedFields
|
||||
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
const field = currentFields.find((each) => each.name === segments[i])
|
||||
|
||||
const shouldBreak =
|
||||
i === segments.length - 1 || field?.type === 'relationship' || field?.type === 'upload'
|
||||
|
||||
currentSelectRef[segments[i]] = shouldBreak ? true : {}
|
||||
currentSelectRef = currentSelectRef[segments[i]]
|
||||
|
||||
if (shouldBreak) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const populatedDoc = await req.payloadDataLoader.load(
|
||||
createDataloaderCacheKey({
|
||||
collectionSlug: currentField.relationTo,
|
||||
currentDepth: 0,
|
||||
depth: 0,
|
||||
docID,
|
||||
draft,
|
||||
fallbackLocale,
|
||||
locale,
|
||||
overrideAccess,
|
||||
select,
|
||||
showHiddenFields,
|
||||
transactionID: req.transactionID as number,
|
||||
}),
|
||||
)
|
||||
|
||||
if (!populatedDoc) {
|
||||
return
|
||||
}
|
||||
|
||||
return virtualFieldPopulationPromise({
|
||||
name,
|
||||
draft,
|
||||
fallbackLocale,
|
||||
fields: req.payload.collections[currentField.relationTo].config.flattenedFields,
|
||||
locale,
|
||||
overrideAccess,
|
||||
ref: populatedDoc,
|
||||
req,
|
||||
segments,
|
||||
showHiddenFields,
|
||||
siblingDoc,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,12 @@ export const promise = async ({
|
||||
|
||||
const passesCondition = field.admin?.condition
|
||||
? Boolean(
|
||||
field.admin.condition(data, siblingData, { blockData, path: pathSegments, user: req.user }),
|
||||
field.admin.condition(data, siblingData, {
|
||||
blockData,
|
||||
operation,
|
||||
path: pathSegments,
|
||||
user: req.user,
|
||||
}),
|
||||
)
|
||||
: true
|
||||
let skipValidationFromHere = skipValidation || !passesCondition
|
||||
|
||||
@@ -9,6 +9,7 @@ import type {
|
||||
} from '../../admin/types.js'
|
||||
import type {
|
||||
Access,
|
||||
CustomComponent,
|
||||
EditConfig,
|
||||
Endpoint,
|
||||
EntityDescription,
|
||||
@@ -80,6 +81,10 @@ export type GlobalAdminOptions = {
|
||||
*/
|
||||
components?: {
|
||||
elements?: {
|
||||
/**
|
||||
* Inject custom components before the document controls
|
||||
*/
|
||||
beforeDocumentControls?: CustomComponent[]
|
||||
Description?: EntityDescriptionComponent
|
||||
/**
|
||||
* Replaces the "Preview" button
|
||||
|
||||
@@ -71,7 +71,17 @@ export const getAccess = (config: Config): Record<Operation, Access> =>
|
||||
|
||||
return {
|
||||
and: [
|
||||
...(typeof constraintAccess === 'object' ? [constraintAccess] : []),
|
||||
...(typeof constraintAccess === 'object'
|
||||
? [constraintAccess]
|
||||
: constraintAccess === false
|
||||
? [
|
||||
{
|
||||
id: {
|
||||
equals: null,
|
||||
},
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
[`access.${operation}.constraint`]: {
|
||||
equals: constraint.value,
|
||||
|
||||
@@ -78,7 +78,7 @@ export const getConstraints = (config: Config): Field => ({
|
||||
},
|
||||
...(config?.queryPresets?.constraints?.[operation]?.reduce(
|
||||
(acc: Field[], option: QueryPresetConstraint) => {
|
||||
option.fields.forEach((field, index) => {
|
||||
option.fields?.forEach((field, index) => {
|
||||
acc.push({ ...field })
|
||||
|
||||
if (fieldAffectsData(field)) {
|
||||
|
||||
@@ -25,7 +25,7 @@ export type QueryPreset = {
|
||||
|
||||
export type QueryPresetConstraint = {
|
||||
access: Access<QueryPreset>
|
||||
fields: Field[]
|
||||
fields?: Field[]
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
@@ -222,8 +222,12 @@ export const handleEndpoints = async ({
|
||||
}
|
||||
|
||||
const response = await handler(req)
|
||||
|
||||
return new Response(response.body, {
|
||||
headers: mergeHeaders(req.responseHeaders ?? new Headers(), response.headers),
|
||||
headers: headersWithCors({
|
||||
headers: mergeHeaders(req.responseHeaders ?? new Headers(), response.headers),
|
||||
req,
|
||||
}),
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
})
|
||||
|
||||
@@ -6,6 +6,13 @@ export type Autosave = {
|
||||
* @default 800
|
||||
*/
|
||||
interval?: number
|
||||
/**
|
||||
* When set to `true`, the "Save as draft" button will be displayed even while autosave is enabled.
|
||||
* By default, this button is hidden to avoid redundancy with autosave behavior.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
showSaveDraftButton?: boolean
|
||||
}
|
||||
|
||||
export type SchedulePublish = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-cloud-storage",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "The official cloud storage plugin for Payload CMS",
|
||||
"homepage": "https://payloadcms.com",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@payloadcms/plugin-form-builder",
|
||||
"version": "3.34.0",
|
||||
"version": "3.35.1",
|
||||
"description": "Form builder plugin for Payload CMS",
|
||||
"keywords": [
|
||||
"payload",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user