feat(plugin-form-builder): pass beforeChange params into beforeEmail hook and add types to it (#7626)
Form Builder Plugin BeforeEmail hook now takes a generic for your
generated types and it has the full hook params available to it.
```ts
import type { BeforeEmail } from '@payloadcms/plugin-form-builder'
// Your generated FormSubmission type
import type {FormSubmission} from '@payload-types'
// Pass it through and 'data' or 'originalDoc' will now be typed
const beforeEmail: BeforeEmail<FormSubmission> = (emailsToSend, beforeChangeParams) => {
// modify the emails in any way before they are sent
return emails.map((email) => ({
...email,
html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
}))
}
```
This commit is contained in:
@@ -109,7 +109,7 @@ The `beforeEmail` property is a [beforeChange](<[beforeChange](https://payloadcm
|
|||||||
// payload.config.ts
|
// payload.config.ts
|
||||||
formBuilder({
|
formBuilder({
|
||||||
// ...
|
// ...
|
||||||
beforeEmail: (emailsToSend) => {
|
beforeEmail: (emailsToSend, beforeChangeParams) => {
|
||||||
// modify the emails in any way before they are sent
|
// modify the emails in any way before they are sent
|
||||||
return emails.map((email) => ({
|
return emails.map((email) => ({
|
||||||
...email,
|
...email,
|
||||||
@@ -119,6 +119,23 @@ formBuilder({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For full types with `beforeChangeParams`, you can import the types from the plugin:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import type { BeforeEmail } from '@payloadcms/plugin-form-builder'
|
||||||
|
// Your generated FormSubmission type
|
||||||
|
import type {FormSubmission} from '@payload-types'
|
||||||
|
|
||||||
|
// Pass it through and 'data' or 'originalDoc' will now be typed
|
||||||
|
const beforeEmail: BeforeEmail<FormSubmission> = (emailsToSend, beforeChangeParams) => {
|
||||||
|
// modify the emails in any way before they are sent
|
||||||
|
return emails.map((email) => ({
|
||||||
|
...email,
|
||||||
|
html: email.html, // transform the html in any way you'd like (maybe wrap it in an html template?)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### `formOverrides`
|
### `formOverrides`
|
||||||
|
|
||||||
Override anything on the `forms` collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections) to the `formOverrides` property.
|
Override anything on the `forms` collection by sending a [Payload Collection Config](https://payloadcms.com/docs/configuration/collections) to the `formOverrides` property.
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
|
import type { CollectionBeforeChangeHook } from 'payload'
|
||||||
|
|
||||||
import type { Email, FormBuilderPluginConfig, FormattedEmail } from '../../../types.js'
|
import type { Email, FormBuilderPluginConfig, FormattedEmail } from '../../../types.js'
|
||||||
|
|
||||||
import { serializeLexical } from '../../../utilities/lexical/serializeLexical.js'
|
import { serializeLexical } from '../../../utilities/lexical/serializeLexical.js'
|
||||||
import { replaceDoubleCurlys } from '../../../utilities/replaceDoubleCurlys.js'
|
import { replaceDoubleCurlys } from '../../../utilities/replaceDoubleCurlys.js'
|
||||||
import { serializeSlate } from '../../../utilities/slate/serializeSlate.js'
|
import { serializeSlate } from '../../../utilities/slate/serializeSlate.js'
|
||||||
|
|
||||||
|
type BeforeChangeParams = Parameters<CollectionBeforeChangeHook>[0]
|
||||||
|
|
||||||
export const sendEmail = async (
|
export const sendEmail = async (
|
||||||
beforeChangeData: any,
|
beforeChangeParameters: BeforeChangeParams,
|
||||||
formConfig: FormBuilderPluginConfig,
|
formConfig: FormBuilderPluginConfig,
|
||||||
): Promise<any> => {
|
): Promise<BeforeChangeParams['data']> => {
|
||||||
const { data, operation, req } = beforeChangeData
|
const { data, operation, req } = beforeChangeParameters
|
||||||
|
|
||||||
if (operation === 'create') {
|
if (operation === 'create') {
|
||||||
const {
|
const {
|
||||||
data: { id: formSubmissionID },
|
data: { id: formSubmissionID },
|
||||||
req: { locale, payload },
|
req: { locale, payload },
|
||||||
} = beforeChangeData
|
} = beforeChangeParameters
|
||||||
|
|
||||||
const { form: formID, submissionData } = data || {}
|
const { form: formID, submissionData } = data || {}
|
||||||
|
|
||||||
@@ -28,7 +32,7 @@ export const sendEmail = async (
|
|||||||
req,
|
req,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { emails } = form
|
const emails = form.emails as Email[]
|
||||||
|
|
||||||
if (emails && emails.length) {
|
if (emails && emails.length) {
|
||||||
const formattedEmails: FormattedEmail[] = await Promise.all(
|
const formattedEmails: FormattedEmail[] = await Promise.all(
|
||||||
@@ -70,11 +74,9 @@ export const sendEmail = async (
|
|||||||
let emailsToSend = formattedEmails
|
let emailsToSend = formattedEmails
|
||||||
|
|
||||||
if (typeof beforeEmail === 'function') {
|
if (typeof beforeEmail === 'function') {
|
||||||
emailsToSend = await beforeEmail(formattedEmails)
|
emailsToSend = await beforeEmail(formattedEmails, beforeChangeParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
// const log = emailsToSend.map(({ html, ...rest }) => ({ ...rest }))
|
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
emailsToSend.map(async (email) => {
|
emailsToSend.map(async (email) => {
|
||||||
const { to } = email
|
const { to } = email
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import type { Block, CollectionConfig, Field } from 'payload'
|
import type {
|
||||||
|
Block,
|
||||||
|
CollectionBeforeChangeHook,
|
||||||
|
CollectionConfig,
|
||||||
|
Field,
|
||||||
|
TypeWithID,
|
||||||
|
} from 'payload'
|
||||||
|
|
||||||
export interface BlockConfig {
|
export interface BlockConfig {
|
||||||
block: Block
|
block: Block
|
||||||
@@ -37,7 +43,11 @@ export interface FieldsConfig {
|
|||||||
textarea?: FieldConfig | boolean
|
textarea?: FieldConfig | boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BeforeEmail = (emails: FormattedEmail[]) => FormattedEmail[] | Promise<FormattedEmail[]>
|
type BeforeChangeParams<T extends TypeWithID = any> = Parameters<CollectionBeforeChangeHook<T>>[0]
|
||||||
|
export type BeforeEmail<T extends TypeWithID = any> = (
|
||||||
|
emails: FormattedEmail[],
|
||||||
|
beforeChangeParams: BeforeChangeParams<T>,
|
||||||
|
) => FormattedEmail[] | Promise<FormattedEmail[]>
|
||||||
export type HandlePayment = (data: any) => void
|
export type HandlePayment = (data: any) => void
|
||||||
export type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]
|
export type FieldsOverride = (args: { defaultFields: Field[] }) => Field[]
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ import { fileURLToPath } from 'node:url'
|
|||||||
import path from 'path'
|
import path from 'path'
|
||||||
const filename = fileURLToPath(import.meta.url)
|
const filename = fileURLToPath(import.meta.url)
|
||||||
const dirname = path.dirname(filename)
|
const dirname = path.dirname(filename)
|
||||||
|
import type { BeforeEmail } from '@payloadcms/plugin-form-builder/types'
|
||||||
import type { Block } from 'payload'
|
import type { Block } from 'payload'
|
||||||
|
|
||||||
import { formBuilderPlugin, fields as formFields } from '@payloadcms/plugin-form-builder'
|
import { formBuilderPlugin, fields as formFields } from '@payloadcms/plugin-form-builder'
|
||||||
import { slateEditor } from '@payloadcms/richtext-slate'
|
import { slateEditor } from '@payloadcms/richtext-slate'
|
||||||
|
|
||||||
|
import type { FormSubmission } from './payload-types.js'
|
||||||
|
|
||||||
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
import { buildConfigWithDefaults } from '../buildConfigWithDefaults.js'
|
||||||
import { devUser } from '../credentials.js'
|
import { devUser } from '../credentials.js'
|
||||||
import { Pages } from './collections/Pages.js'
|
import { Pages } from './collections/Pages.js'
|
||||||
@@ -27,6 +30,10 @@ const colorField: Block = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const beforeEmail: BeforeEmail<FormSubmission> = (emails, { req: { payload }, originalDoc }) => {
|
||||||
|
return emails
|
||||||
|
}
|
||||||
|
|
||||||
export default buildConfigWithDefaults({
|
export default buildConfigWithDefaults({
|
||||||
collections: [Pages, Users],
|
collections: [Pages, Users],
|
||||||
editor: slateEditor({}),
|
editor: slateEditor({}),
|
||||||
@@ -49,7 +56,6 @@ export default buildConfigWithDefaults({
|
|||||||
plugins: [
|
plugins: [
|
||||||
formBuilderPlugin({
|
formBuilderPlugin({
|
||||||
// handlePayment: handleFormPayments,
|
// handlePayment: handleFormPayments,
|
||||||
// beforeEmail: prepareFormEmails,
|
|
||||||
fields: {
|
fields: {
|
||||||
colorField,
|
colorField,
|
||||||
payment: true,
|
payment: true,
|
||||||
@@ -72,6 +78,7 @@ export default buildConfigWithDefaults({
|
|||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
},
|
},
|
||||||
|
beforeEmail,
|
||||||
formOverrides: {
|
formOverrides: {
|
||||||
// labels: {
|
// labels: {
|
||||||
// singular: 'Contact Form',
|
// singular: 'Contact Form',
|
||||||
|
|||||||
Reference in New Issue
Block a user