Compare commits
4 Commits
payload/2.
...
payload/2.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa3833ec83 | ||
|
|
2972af2af1 | ||
|
|
857b9a4ac3 | ||
|
|
f829b084ba |
12
CHANGELOG.md
12
CHANGELOG.md
@@ -1,3 +1,15 @@
|
||||
## [2.16.1](https://github.com/payloadcms/payload/compare/v2.16.0...v2.16.1) (2024-05-07)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **richtext-lexical:** add maxDepth property to various lexical features ([#6250](https://github.com/payloadcms/payload/issues/6250)) ([857b9a4](https://github.com/payloadcms/payload/commit/857b9a4ac3236c740458750f156a3a4274eda210)), closes [#6242](https://github.com/payloadcms/payload/issues/6242)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **richtext-lexical:** export missing HorizontalRuleFeature ([#6236](https://github.com/payloadcms/payload/issues/6236)) ([f829b08](https://github.com/payloadcms/payload/commit/f829b084ba9649ef596cce4a7bf6ae8c7ccf57e3))
|
||||
|
||||
## [2.16.0](https://github.com/payloadcms/payload/compare/v2.15.0...v2.16.0) (2024-05-06)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "payload",
|
||||
"version": "2.16.0",
|
||||
"version": "2.16.1",
|
||||
"description": "Node, React and MongoDB Headless CMS and Application Framework",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
|
||||
@@ -477,6 +477,7 @@ export const richText = baseField.keys({
|
||||
validate: joi.func().required(),
|
||||
})
|
||||
.unknown(),
|
||||
maxDepth: joi.number(),
|
||||
})
|
||||
|
||||
export const date = baseField.keys({
|
||||
|
||||
@@ -551,6 +551,10 @@ export type RichTextField<
|
||||
}
|
||||
}
|
||||
editor?: RichTextAdapter<Value, AdapterProps, AdapterProps>
|
||||
/**
|
||||
* Sets a maximum population depth for this field, regardless of the remaining depth when this field is reached.
|
||||
*/
|
||||
maxDepth?: number
|
||||
type: 'richText'
|
||||
} & ExtraProperties
|
||||
|
||||
|
||||
@@ -143,10 +143,13 @@ export const promise = async ({
|
||||
const editor: RichTextAdapter = field?.editor
|
||||
// This is run here AND in the GraphQL Resolver
|
||||
if (editor?.populationPromise) {
|
||||
const populateDepth =
|
||||
field?.maxDepth !== undefined && field?.maxDepth < depth ? field?.maxDepth : depth
|
||||
|
||||
const populationPromise = editor.populationPromise({
|
||||
context,
|
||||
currentDepth,
|
||||
depth,
|
||||
depth: populateDepth,
|
||||
draft,
|
||||
field,
|
||||
findMany,
|
||||
|
||||
@@ -476,9 +476,12 @@ function buildObjectType({
|
||||
// In the graphql find.ts resolver, the depth is then hard-coded to 0.
|
||||
// Effectively, this means that the populationPromise for GraphQL is only run here, and not in the find.ts resolver / normal population promise.
|
||||
if (editor?.populationPromise) {
|
||||
const populateDepth =
|
||||
field?.maxDepth !== undefined && field?.maxDepth < depth ? field?.maxDepth : depth
|
||||
|
||||
await editor?.populationPromise({
|
||||
context,
|
||||
depth,
|
||||
depth: populateDepth,
|
||||
draft: args.draft,
|
||||
field,
|
||||
findMany: false,
|
||||
|
||||
@@ -18,6 +18,7 @@ export const statuses = [
|
||||
const baseVersionFields: Field[] = [
|
||||
{
|
||||
name: '_status',
|
||||
type: 'select',
|
||||
admin: {
|
||||
components: {
|
||||
Field: () => null,
|
||||
@@ -25,9 +26,9 @@ const baseVersionFields: Field[] = [
|
||||
disableBulkEdit: true,
|
||||
},
|
||||
defaultValue: 'draft',
|
||||
index: true,
|
||||
label: labels['version:status'],
|
||||
options: statuses,
|
||||
type: 'select',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ export const getBaseFields = (
|
||||
config: Config,
|
||||
enabledCollections: false | string[],
|
||||
disabledCollections: false | string[],
|
||||
maxDepth?: number,
|
||||
): Field[] => {
|
||||
let enabledRelations: string[]
|
||||
|
||||
@@ -48,12 +49,13 @@ export const getBaseFields = (
|
||||
const baseFields = [
|
||||
{
|
||||
name: 'text',
|
||||
type: 'text',
|
||||
label: translations['fields:textToDisplay'],
|
||||
required: true,
|
||||
type: 'text',
|
||||
},
|
||||
{
|
||||
name: 'fields',
|
||||
type: 'group',
|
||||
admin: {
|
||||
style: {
|
||||
borderBottom: 0,
|
||||
@@ -65,6 +67,7 @@ export const getBaseFields = (
|
||||
fields: [
|
||||
{
|
||||
name: 'linkType',
|
||||
type: 'radio',
|
||||
admin: {
|
||||
description: translations['fields:chooseBetweenCustomTextOrDocument'],
|
||||
},
|
||||
@@ -77,13 +80,12 @@ export const getBaseFields = (
|
||||
},
|
||||
],
|
||||
required: true,
|
||||
type: 'radio',
|
||||
},
|
||||
{
|
||||
name: 'url',
|
||||
type: 'text',
|
||||
label: translations['fields:enterURL'],
|
||||
required: true,
|
||||
type: 'text',
|
||||
validate: (value: string) => {
|
||||
if (value && !validateUrl(value)) {
|
||||
return 'Invalid URL'
|
||||
@@ -91,7 +93,6 @@ export const getBaseFields = (
|
||||
},
|
||||
},
|
||||
] as Field[],
|
||||
type: 'group',
|
||||
},
|
||||
]
|
||||
|
||||
@@ -113,6 +114,7 @@ export const getBaseFields = (
|
||||
},
|
||||
},
|
||||
// when admin.hidden is a function we need to dynamically call hidden with the user to know if the collection should be shown
|
||||
type: 'relationship',
|
||||
filterOptions:
|
||||
!enabledCollections && !disabledCollections
|
||||
? ({ relationTo, user }) => {
|
||||
@@ -123,16 +125,16 @@ export const getBaseFields = (
|
||||
}
|
||||
: null,
|
||||
label: translations['fields:chooseDocumentToLink'],
|
||||
maxDepth,
|
||||
relationTo: enabledRelations,
|
||||
required: true,
|
||||
type: 'relationship',
|
||||
})
|
||||
}
|
||||
|
||||
baseFields[1].fields.push({
|
||||
name: 'newTab',
|
||||
label: translations['fields:openInNewTab'],
|
||||
type: 'checkbox',
|
||||
label: translations['fields:openInNewTab'],
|
||||
})
|
||||
|
||||
return baseFields as Field[]
|
||||
|
||||
@@ -52,6 +52,11 @@ export type LinkFeatureProps = ExclusiveLinkCollectionsProps & {
|
||||
i18n: i18n
|
||||
}) => FieldWithRichTextRequiredEditor[])
|
||||
| FieldWithRichTextRequiredEditor[]
|
||||
/**
|
||||
* Sets a maximum population depth for the internal doc default field of link, regardless of the remaining depth when the field is reached.
|
||||
* This behaves exactly like the maxDepth properties of relationship and upload fields.
|
||||
*/
|
||||
maxDepth?: number
|
||||
}
|
||||
|
||||
export const LinkFeature = (props: LinkFeatureProps): FeatureProvider => {
|
||||
|
||||
@@ -45,6 +45,7 @@ export function LinkEditor({
|
||||
disabledCollections,
|
||||
enabledCollections,
|
||||
fields: customFieldSchema,
|
||||
maxDepth,
|
||||
}: { anchorElem: HTMLElement } & LinkFeatureProps): JSX.Element {
|
||||
const [editor] = useLexicalComposerContext()
|
||||
|
||||
@@ -71,6 +72,7 @@ export function LinkEditor({
|
||||
i18n,
|
||||
enabledCollections,
|
||||
disabledCollections,
|
||||
maxDepth,
|
||||
)
|
||||
// Sanitize custom fields here
|
||||
const validRelationships = config.collections.map((c) => c.slug) || []
|
||||
|
||||
@@ -15,8 +15,14 @@ export function transformExtraFields(
|
||||
i18n: i18n,
|
||||
enabledCollections?: false | string[],
|
||||
disabledCollections?: false | string[],
|
||||
maxDepth?: number,
|
||||
): Field[] {
|
||||
const baseFields: Field[] = getBaseFields(config, enabledCollections, disabledCollections)
|
||||
const baseFields: Field[] = getBaseFields(
|
||||
config,
|
||||
enabledCollections,
|
||||
disabledCollections,
|
||||
maxDepth,
|
||||
)
|
||||
|
||||
const fields =
|
||||
typeof customFieldSchema === 'function'
|
||||
|
||||
@@ -3,9 +3,9 @@ import type { FeatureProvider } from '../types'
|
||||
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
|
||||
import { INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND } from './drawer/commands'
|
||||
import { RelationshipNode } from './nodes/RelationshipNode'
|
||||
import { relationshipPopulationPromise } from './populationPromise'
|
||||
import { relationshipPopulationPromiseHOC } from './populationPromise'
|
||||
|
||||
export type RelationshipFeatureProps =
|
||||
export type ExclusiveRelationshipFeatureProps =
|
||||
| {
|
||||
/**
|
||||
* The collections that should be disabled. Overrides the `enableRichTextRelationship` property in the collection config.
|
||||
@@ -27,15 +27,23 @@ export type RelationshipFeatureProps =
|
||||
enabledCollections?: string[]
|
||||
}
|
||||
|
||||
export type RelationshipFeatureProps = ExclusiveRelationshipFeatureProps & {
|
||||
/**
|
||||
* Sets a maximum population depth for this relationship, regardless of the remaining depth when the respective field is reached.
|
||||
* This behaves exactly like the maxDepth properties of relationship and upload fields.
|
||||
*/
|
||||
maxDepth?: number
|
||||
}
|
||||
|
||||
export const RelationshipFeature = (props?: RelationshipFeatureProps): FeatureProvider => {
|
||||
return {
|
||||
feature: () => {
|
||||
return {
|
||||
nodes: [
|
||||
{
|
||||
node: RelationshipNode,
|
||||
populationPromises: [relationshipPopulationPromise],
|
||||
type: RelationshipNode.getType(),
|
||||
node: RelationshipNode,
|
||||
populationPromises: [relationshipPopulationPromiseHOC(props)],
|
||||
// TODO: Add validation similar to upload
|
||||
},
|
||||
],
|
||||
@@ -55,7 +63,7 @@ export const RelationshipFeature = (props?: RelationshipFeatureProps): FeaturePr
|
||||
position: 'normal',
|
||||
},
|
||||
],
|
||||
props: props,
|
||||
props,
|
||||
slashMenu: {
|
||||
options: [
|
||||
{
|
||||
|
||||
@@ -1,41 +1,50 @@
|
||||
import type { PopulationPromise } from '../types'
|
||||
import type { RelationshipFeatureProps } from './index'
|
||||
import type { SerializedRelationshipNode } from './nodes/RelationshipNode'
|
||||
|
||||
import { populate } from '../../../populate/populate'
|
||||
|
||||
export const relationshipPopulationPromise: PopulationPromise<SerializedRelationshipNode> = ({
|
||||
currentDepth,
|
||||
depth,
|
||||
draft,
|
||||
field,
|
||||
node,
|
||||
overrideAccess,
|
||||
req,
|
||||
showHiddenFields,
|
||||
}) => {
|
||||
const promises: Promise<void>[] = []
|
||||
export const relationshipPopulationPromiseHOC = (
|
||||
props: RelationshipFeatureProps,
|
||||
): PopulationPromise<SerializedRelationshipNode> => {
|
||||
const relationshipPopulationPromise: PopulationPromise<SerializedRelationshipNode> = ({
|
||||
currentDepth,
|
||||
depth,
|
||||
draft,
|
||||
field,
|
||||
node,
|
||||
overrideAccess,
|
||||
req,
|
||||
showHiddenFields,
|
||||
}) => {
|
||||
const promises: Promise<void>[] = []
|
||||
|
||||
if (node?.value?.id) {
|
||||
const collection = req.payload.collections[node?.relationTo]
|
||||
if (node?.value?.id) {
|
||||
const collection = req.payload.collections[node?.relationTo]
|
||||
|
||||
if (collection) {
|
||||
promises.push(
|
||||
populate({
|
||||
id: node.value.id,
|
||||
collection,
|
||||
currentDepth,
|
||||
data: node,
|
||||
depth,
|
||||
draft,
|
||||
field,
|
||||
key: 'value',
|
||||
overrideAccess,
|
||||
req,
|
||||
showHiddenFields,
|
||||
}),
|
||||
)
|
||||
if (collection) {
|
||||
const populateDepth =
|
||||
props?.maxDepth !== undefined && props?.maxDepth < depth ? props?.maxDepth : depth
|
||||
|
||||
promises.push(
|
||||
populate({
|
||||
id: node.value.id,
|
||||
collection,
|
||||
currentDepth,
|
||||
data: node,
|
||||
depth: populateDepth,
|
||||
draft,
|
||||
field,
|
||||
key: 'value',
|
||||
overrideAccess,
|
||||
req,
|
||||
showHiddenFields,
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return promises
|
||||
return promises
|
||||
}
|
||||
return relationshipPopulationPromise
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@ export type UploadFeatureProps = {
|
||||
fields: FieldWithRichTextRequiredEditor[]
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Sets a maximum population depth for this upload (not the fields for this upload), regardless of the remaining depth when the respective field is reached.
|
||||
* This behaves exactly like the maxDepth properties of relationship and upload fields.
|
||||
*/
|
||||
maxDepth?: number
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,13 +29,16 @@ export const uploadPopulationPromiseHOC = (
|
||||
const collection = req.payload.collections[node?.relationTo]
|
||||
|
||||
if (collection) {
|
||||
const populateDepth =
|
||||
props?.maxDepth !== undefined && props?.maxDepth < depth ? props?.maxDepth : depth
|
||||
|
||||
promises.push(
|
||||
populate({
|
||||
id: node?.value?.id,
|
||||
collection,
|
||||
currentDepth,
|
||||
data: node,
|
||||
depth,
|
||||
depth: populateDepth,
|
||||
draft: false,
|
||||
field,
|
||||
key: 'value',
|
||||
|
||||
@@ -249,6 +249,7 @@ export {
|
||||
|
||||
export { ParagraphFeature } from './field/features/Paragraph'
|
||||
export { RelationshipFeature } from './field/features/Relationship'
|
||||
|
||||
export {
|
||||
$createRelationshipNode,
|
||||
$isRelationshipNode,
|
||||
@@ -283,11 +284,11 @@ export { defaultHTMLConverters } from './field/features/converters/html/converte
|
||||
export type { HTMLConverter } from './field/features/converters/html/converter/types'
|
||||
export { consolidateHTMLConverters } from './field/features/converters/html/field'
|
||||
export { lexicalHTML } from './field/features/converters/html/field'
|
||||
|
||||
export { TestRecorderFeature } from './field/features/debug/TestRecorder'
|
||||
export { TreeViewFeature } from './field/features/debug/TreeView'
|
||||
|
||||
export { TreeViewFeature } from './field/features/debug/TreeView'
|
||||
export { BoldTextFeature } from './field/features/format/Bold'
|
||||
|
||||
export { InlineCodeTextFeature } from './field/features/format/InlineCode'
|
||||
export { ItalicTextFeature } from './field/features/format/Italic'
|
||||
export { SectionWithEntries as FormatSectionWithEntries } from './field/features/format/common/floatingSelectToolbarSection'
|
||||
@@ -295,6 +296,7 @@ export { StrikethroughTextFeature } from './field/features/format/strikethrough'
|
||||
export { SubscriptTextFeature } from './field/features/format/subscript'
|
||||
export { SuperscriptTextFeature } from './field/features/format/superscript'
|
||||
export { UnderlineTextFeature } from './field/features/format/underline'
|
||||
export { HorizontalRuleFeature } from './field/features/horizontalrule'
|
||||
export { IndentFeature } from './field/features/indent'
|
||||
export { CheckListFeature } from './field/features/lists/CheckList'
|
||||
export { OrderedListFeature } from './field/features/lists/OrderedList'
|
||||
|
||||
Reference in New Issue
Block a user