diff --git a/src/triggers/collection-trigger.ts b/src/triggers/collection-trigger.ts index f493d96..aa1e496 100644 --- a/src/triggers/collection-trigger.ts +++ b/src/triggers/collection-trigger.ts @@ -1,62 +1,27 @@ -import type { Field } from 'payload' +import type {Field} from 'payload' + import type { WorkflowsPluginConfig } from '../plugin/config-types.js' +import {triggerField} from "./helpers.js" + export function getCollectionTriggerFields( collectionTriggers: WorkflowsPluginConfig['collectionTriggers'] ): Field[] { return [ - { - name: '__builtin_collectionSlug', + triggerField({ + name: 'collectionSlug', type: 'select', - admin: { - condition: (_, siblingData) => siblingData?.type === 'collection-trigger', - description: 'Collection that triggers the workflow', - }, - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.collectionSlug || undefined - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.collectionSlug = value - return undefined // Virtual field, don't store directly - } - ] - }, options: Object.keys(collectionTriggers || {}), - virtual: true, - }, - { - name: '__builtin_operation', + }), + triggerField({ + name: 'operation', type: 'select', - admin: { - condition: (_, siblingData) => siblingData?.type === 'collection-trigger', - description: 'Collection operation that triggers the workflow', - }, - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.operation || undefined - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.operation = value - return undefined // Virtual field, don't store directly - } - ] - }, options: [ 'create', 'delete', 'read', 'update', ], - virtual: true, - } + }) ] -} \ No newline at end of file +} diff --git a/src/triggers/cron-trigger.ts b/src/triggers/cron-trigger.ts index dfca811..8144b1b 100644 --- a/src/triggers/cron-trigger.ts +++ b/src/triggers/cron-trigger.ts @@ -1,29 +1,17 @@ -import type { Field } from 'payload' +import type {Field} from 'payload' + +import {triggerField} from "./helpers.js" export function getCronTriggerFields(): Field[] { return [ - { - name: '__builtin_cronExpression', + triggerField({ + name: 'cronExpression', type: 'text', admin: { condition: (_, siblingData) => siblingData?.type === 'cron-trigger', description: 'Cron expression for scheduled execution (e.g., "0 0 * * *" for daily at midnight)', placeholder: '0 0 * * *' }, - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.cronExpression || undefined - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.cronExpression = value - return undefined // Virtual field, don't store directly - } - ] - }, validate: (value: any, {siblingData}: any) => { const cronValue = value || siblingData?.parameters?.cronExpression if (siblingData?.type === 'cron-trigger' && !cronValue) { @@ -44,10 +32,9 @@ export function getCronTriggerFields(): Field[] { return true }, - virtual: true, - }, - { - name: '__builtin_timezone', + }), + triggerField({ + name: 'timezone', type: 'text', admin: { condition: (_, siblingData) => siblingData?.type === 'cron-trigger', @@ -55,20 +42,6 @@ export function getCronTriggerFields(): Field[] { placeholder: 'UTC' }, defaultValue: 'UTC', - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.timezone || 'UTC' - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.timezone = value || 'UTC' - return undefined // Virtual field, don't store directly - } - ] - }, validate: (value: any, {siblingData}: any) => { const tzValue = value || siblingData?.parameters?.timezone if (siblingData?.type === 'cron-trigger' && tzValue) { @@ -82,7 +55,6 @@ export function getCronTriggerFields(): Field[] { } return true }, - virtual: true, - } + }) ] } \ No newline at end of file diff --git a/src/triggers/global-trigger.ts b/src/triggers/global-trigger.ts index fdaf925..ff4f73f 100644 --- a/src/triggers/global-trigger.ts +++ b/src/triggers/global-trigger.ts @@ -1,56 +1,28 @@ -import type { Field } from 'payload' +import type {Field} from 'payload' + +import {triggerField} from "./helpers.js" export function getGlobalTriggerFields(): Field[] { return [ - { - name: '__builtin_global', + triggerField({ + name: 'global', type: 'select', admin: { condition: (_, siblingData) => siblingData?.type === 'global-trigger', description: 'Global that triggers the workflow', }, - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.global || undefined - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.global = value - return undefined // Virtual field, don't store directly - } - ] - }, options: [], // Will be populated dynamically based on available globals - virtual: true, - }, - { - name: '__builtin_globalOperation', + }), + triggerField({ + name: 'globalOperation', type: 'select', admin: { condition: (_, siblingData) => siblingData?.type === 'global-trigger', description: 'Global operation that triggers the workflow', }, - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.globalOperation || undefined - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.globalOperation = value - return undefined // Virtual field, don't store directly - } - ] - }, options: [ 'update' ], - virtual: true, - } + }) ] } \ No newline at end of file diff --git a/src/triggers/helpers.ts b/src/triggers/helpers.ts index e69de29..1f82c92 100644 --- a/src/triggers/helpers.ts +++ b/src/triggers/helpers.ts @@ -0,0 +1,50 @@ +import type {Field, TextField, SelectField} from "payload" + +import type {Trigger} from "./types.js" + +type FieldWithName = TextField | SelectField | (Field & { name: string }) + +type Options = { + slug: string, + fields?: FieldWithName[] +} + +export const trigger = ({ + slug, + fields + }: Options): Trigger => { + return { + slug, + fields: (fields || []).map(triggerField) as Field[] + } +} + +export const triggerField = (field: FieldWithName): Field => ({ + ...field, + name: '__trigger_' + field.name, + admin: { + ...(field.admin as any || {}), + condition: (_, siblingData, __) => { + const previous = field.admin?.condition?.call(null, _, siblingData, __) + return previous !== false // Preserve existing condition if it exists + }, + }, + hooks: { + afterRead: [ + ({ siblingData }) => { + const parameters = siblingData?.parameters || {} + return parameters[field.name] + } + ], + beforeChange: [ + ({ siblingData, value }) => { + if (!siblingData.parameters) { + siblingData.parameters = {} + } + siblingData.parameters[field.name] = value + return undefined // Virtual field, don't store directly + } + ] + }, + virtual: true, +} as Field) diff --git a/src/triggers/types.ts b/src/triggers/types.ts index e69de29..965b86f 100644 --- a/src/triggers/types.ts +++ b/src/triggers/types.ts @@ -0,0 +1,6 @@ +import type {Field} from "payload" + +export type Trigger = { + slug: string + fields: Field[] +} diff --git a/src/triggers/webhook-trigger.ts b/src/triggers/webhook-trigger.ts index 7fbbfa2..7c9d290 100644 --- a/src/triggers/webhook-trigger.ts +++ b/src/triggers/webhook-trigger.ts @@ -1,35 +1,22 @@ -import type { Field } from 'payload' +import type {Field} from 'payload' + +import {triggerField} from "./helpers.js" export function getWebhookTriggerFields(): Field[] { return [ - { - name: '__builtin_webhookPath', + triggerField({ + name: 'webhookPath', type: 'text', admin: { condition: (_, siblingData) => siblingData?.type === 'webhook-trigger', description: 'URL path for the webhook (e.g., "my-webhook"). Full URL will be /api/workflows-webhook/my-webhook', }, - hooks: { - afterRead: [ - ({ siblingData }) => { - return siblingData?.parameters?.webhookPath || undefined - } - ], - beforeChange: [ - ({ siblingData, value }) => { - if (!siblingData.parameters) {siblingData.parameters = {}} - siblingData.parameters.webhookPath = value - return undefined // Virtual field, don't store directly - } - ] - }, validate: (value: any, {siblingData}: any) => { if (siblingData?.type === 'webhook-trigger' && !value && !siblingData?.parameters?.webhookPath) { return 'Webhook path is required for webhook triggers' } return true }, - virtual: true, - } + }) ] } \ No newline at end of file