@xtr-dev/payload-automation 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -0
- package/dist/collections/Workflow.d.ts +3 -0
- package/dist/collections/Workflow.js +223 -0
- package/dist/collections/Workflow.js.map +1 -0
- package/dist/collections/WorkflowRuns.d.ts +2 -0
- package/dist/collections/WorkflowRuns.js +157 -0
- package/dist/collections/WorkflowRuns.js.map +1 -0
- package/dist/components/TriggerWorkflowButton.d.ts +7 -0
- package/dist/components/TriggerWorkflowButton.js +46 -0
- package/dist/components/TriggerWorkflowButton.js.map +1 -0
- package/dist/core/trigger-custom-workflow.d.ts +52 -0
- package/dist/core/trigger-custom-workflow.js +205 -0
- package/dist/core/trigger-custom-workflow.js.map +1 -0
- package/dist/core/workflow-executor.d.ts +86 -0
- package/dist/core/workflow-executor.js +456 -0
- package/dist/core/workflow-executor.js.map +1 -0
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/client.js +7 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/fields.d.ts +1 -0
- package/dist/exports/fields.js +6 -0
- package/dist/exports/fields.js.map +1 -0
- package/dist/exports/rsc.d.ts +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/exports/views.d.ts +1 -0
- package/dist/exports/views.js +7 -0
- package/dist/exports/views.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/config-types.d.ts +21 -0
- package/dist/plugin/config-types.js +3 -0
- package/dist/plugin/config-types.js.map +1 -0
- package/dist/plugin/cron-scheduler.d.ts +32 -0
- package/dist/plugin/cron-scheduler.js +537 -0
- package/dist/plugin/cron-scheduler.js.map +1 -0
- package/dist/plugin/index.d.ts +4 -0
- package/dist/plugin/index.js +66 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/init-collection-hooks.d.ts +4 -0
- package/dist/plugin/init-collection-hooks.js +63 -0
- package/dist/plugin/init-collection-hooks.js.map +1 -0
- package/dist/plugin/init-global-hooks.d.ts +3 -0
- package/dist/plugin/init-global-hooks.js +83 -0
- package/dist/plugin/init-global-hooks.js.map +1 -0
- package/dist/plugin/init-step-tasks.d.ts +3 -0
- package/dist/plugin/init-step-tasks.js +8 -0
- package/dist/plugin/init-step-tasks.js.map +1 -0
- package/dist/plugin/init-webhook.d.ts +2 -0
- package/dist/plugin/init-webhook.js +154 -0
- package/dist/plugin/init-webhook.js.map +1 -0
- package/dist/plugin/init-workflow-hooks.d.ts +6 -0
- package/dist/plugin/init-workflow-hooks.js +46 -0
- package/dist/plugin/init-workflow-hooks.js.map +1 -0
- package/dist/plugin/logger.d.ts +20 -0
- package/dist/plugin/logger.js +47 -0
- package/dist/plugin/logger.js.map +1 -0
- package/dist/steps/create-document-handler.d.ts +2 -0
- package/dist/steps/create-document-handler.js +36 -0
- package/dist/steps/create-document-handler.js.map +1 -0
- package/dist/steps/create-document.d.ts +46 -0
- package/dist/steps/create-document.js +55 -0
- package/dist/steps/create-document.js.map +1 -0
- package/dist/steps/delete-document-handler.d.ts +2 -0
- package/dist/steps/delete-document-handler.js +62 -0
- package/dist/steps/delete-document-handler.js.map +1 -0
- package/dist/steps/delete-document.d.ts +39 -0
- package/dist/steps/delete-document.js +47 -0
- package/dist/steps/delete-document.js.map +1 -0
- package/dist/steps/http-request-handler.d.ts +2 -0
- package/dist/steps/http-request-handler.js +14 -0
- package/dist/steps/http-request-handler.js.map +1 -0
- package/dist/steps/http-request.d.ts +12 -0
- package/dist/steps/http-request.js +19 -0
- package/dist/steps/http-request.js.map +1 -0
- package/dist/steps/index.d.ts +12 -0
- package/dist/steps/index.js +14 -0
- package/dist/steps/index.js.map +1 -0
- package/dist/steps/read-document-handler.d.ts +2 -0
- package/dist/steps/read-document-handler.js +53 -0
- package/dist/steps/read-document-handler.js.map +1 -0
- package/dist/steps/read-document.d.ts +46 -0
- package/dist/steps/read-document.js +75 -0
- package/dist/steps/read-document.js.map +1 -0
- package/dist/steps/send-email-handler.d.ts +2 -0
- package/dist/steps/send-email-handler.js +48 -0
- package/dist/steps/send-email-handler.js.map +1 -0
- package/dist/steps/send-email.d.ts +44 -0
- package/dist/steps/send-email.js +78 -0
- package/dist/steps/send-email.js.map +1 -0
- package/dist/steps/update-document-handler.d.ts +2 -0
- package/dist/steps/update-document-handler.js +40 -0
- package/dist/steps/update-document-handler.js.map +1 -0
- package/dist/steps/update-document.d.ts +46 -0
- package/dist/steps/update-document.js +63 -0
- package/dist/steps/update-document.js.map +1 -0
- package/package.json +133 -0
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# @xtr-dev/payload-automation
|
|
2
|
+
|
|
3
|
+
A comprehensive workflow automation plugin for PayloadCMS 3.x that enables visual workflow building, execution tracking, and parallel processing.
|
|
4
|
+
|
|
5
|
+
⚠️ **Pre-release Warning**: This package is currently in active development (v0.0.x). Breaking changes may occur before v1.0.0. Not recommended for production use.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🔄 **Visual Workflow Builder** - Create complex workflows with drag-and-drop interface
|
|
10
|
+
- ⚡ **Parallel Execution** - Smart dependency resolution for optimal performance
|
|
11
|
+
- 🎯 **Multiple Triggers** - Collection hooks, webhooks, manual execution
|
|
12
|
+
- 📊 **Execution Tracking** - Complete history and monitoring of workflow runs
|
|
13
|
+
- 🔧 **Extensible Steps** - HTTP requests, document CRUD, email notifications
|
|
14
|
+
- 🔍 **JSONPath Integration** - Dynamic data interpolation and transformation
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @xtr-dev/payload-automation
|
|
20
|
+
# or
|
|
21
|
+
pnpm add @xtr-dev/payload-automation
|
|
22
|
+
# or
|
|
23
|
+
yarn add @xtr-dev/payload-automation
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { buildConfig } from 'payload'
|
|
30
|
+
import { payloadAutomation } from '@xtr-dev/payload-automation'
|
|
31
|
+
|
|
32
|
+
export default buildConfig({
|
|
33
|
+
// ... your config
|
|
34
|
+
plugins: [
|
|
35
|
+
payloadAutomation({
|
|
36
|
+
collections: ['posts', 'users'], // Collections to monitor
|
|
37
|
+
globals: ['settings'], // Globals to monitor
|
|
38
|
+
enabled: true,
|
|
39
|
+
}),
|
|
40
|
+
],
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Step Types
|
|
45
|
+
|
|
46
|
+
- **HTTP Request** - Make external API calls
|
|
47
|
+
- **Create Document** - Create PayloadCMS documents
|
|
48
|
+
- **Read Document** - Query documents with filters
|
|
49
|
+
- **Update Document** - Modify existing documents
|
|
50
|
+
- **Delete Document** - Remove documents
|
|
51
|
+
- **Send Email** - Send notifications via PayloadCMS email
|
|
52
|
+
|
|
53
|
+
## Data Resolution
|
|
54
|
+
|
|
55
|
+
Use JSONPath to access workflow data:
|
|
56
|
+
|
|
57
|
+
- `$.trigger.doc.id` - Access trigger document
|
|
58
|
+
- `$.steps.stepName.output` - Use previous step outputs
|
|
59
|
+
- `$.context` - Access workflow context
|
|
60
|
+
|
|
61
|
+
## Requirements
|
|
62
|
+
|
|
63
|
+
- PayloadCMS ^3.45.0
|
|
64
|
+
- Node.js ^18.20.2 || >=20.9.0
|
|
65
|
+
- pnpm ^9 || ^10
|
|
66
|
+
|
|
67
|
+
## Documentation
|
|
68
|
+
|
|
69
|
+
Full documentation coming soon. For now, explore the development environment in the repository for examples and patterns.
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
export const createWorkflowCollection = ({ collectionTriggers, steps, triggers })=>({
|
|
2
|
+
slug: 'workflows',
|
|
3
|
+
access: {
|
|
4
|
+
create: ()=>true,
|
|
5
|
+
delete: ()=>true,
|
|
6
|
+
read: ()=>true,
|
|
7
|
+
update: ()=>true
|
|
8
|
+
},
|
|
9
|
+
admin: {
|
|
10
|
+
defaultColumns: [
|
|
11
|
+
'name',
|
|
12
|
+
'updatedAt'
|
|
13
|
+
],
|
|
14
|
+
description: 'Create and manage automated workflows.',
|
|
15
|
+
group: 'Automation',
|
|
16
|
+
useAsTitle: 'name'
|
|
17
|
+
},
|
|
18
|
+
fields: [
|
|
19
|
+
{
|
|
20
|
+
name: 'name',
|
|
21
|
+
type: 'text',
|
|
22
|
+
admin: {
|
|
23
|
+
description: 'Human-readable name for the workflow'
|
|
24
|
+
},
|
|
25
|
+
required: true
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'description',
|
|
29
|
+
type: 'textarea',
|
|
30
|
+
admin: {
|
|
31
|
+
description: 'Optional description of what this workflow does'
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'triggers',
|
|
36
|
+
type: 'array',
|
|
37
|
+
fields: [
|
|
38
|
+
{
|
|
39
|
+
name: 'type',
|
|
40
|
+
type: 'select',
|
|
41
|
+
options: [
|
|
42
|
+
'collection-trigger',
|
|
43
|
+
'webhook-trigger',
|
|
44
|
+
'global-trigger',
|
|
45
|
+
'cron-trigger',
|
|
46
|
+
...(triggers || []).map((t)=>t.slug)
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'collection',
|
|
51
|
+
type: 'select',
|
|
52
|
+
admin: {
|
|
53
|
+
condition: (_, siblingData)=>siblingData?.type === 'collection-trigger',
|
|
54
|
+
description: 'Collection that triggers the workflow'
|
|
55
|
+
},
|
|
56
|
+
options: Object.keys(collectionTriggers || {})
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'operation',
|
|
60
|
+
type: 'select',
|
|
61
|
+
admin: {
|
|
62
|
+
condition: (_, siblingData)=>siblingData?.type === 'collection-trigger',
|
|
63
|
+
description: 'Collection operation that triggers the workflow'
|
|
64
|
+
},
|
|
65
|
+
options: [
|
|
66
|
+
'create',
|
|
67
|
+
'delete',
|
|
68
|
+
'read',
|
|
69
|
+
'update'
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'webhookPath',
|
|
74
|
+
type: 'text',
|
|
75
|
+
admin: {
|
|
76
|
+
condition: (_, siblingData)=>siblingData?.type === 'webhook-trigger',
|
|
77
|
+
description: 'URL path for the webhook (e.g., "my-webhook"). Full URL will be /api/workflows/webhook/my-webhook'
|
|
78
|
+
},
|
|
79
|
+
validate: (value, { siblingData })=>{
|
|
80
|
+
if (siblingData?.type === 'webhook-trigger' && !value) {
|
|
81
|
+
return 'Webhook path is required for webhook triggers';
|
|
82
|
+
}
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'global',
|
|
88
|
+
type: 'select',
|
|
89
|
+
admin: {
|
|
90
|
+
condition: (_, siblingData)=>siblingData?.type === 'global-trigger',
|
|
91
|
+
description: 'Global that triggers the workflow'
|
|
92
|
+
},
|
|
93
|
+
options: [] // Will be populated dynamically based on available globals
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'globalOperation',
|
|
97
|
+
type: 'select',
|
|
98
|
+
admin: {
|
|
99
|
+
condition: (_, siblingData)=>siblingData?.type === 'global-trigger',
|
|
100
|
+
description: 'Global operation that triggers the workflow'
|
|
101
|
+
},
|
|
102
|
+
options: [
|
|
103
|
+
'update'
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'cronExpression',
|
|
108
|
+
type: 'text',
|
|
109
|
+
admin: {
|
|
110
|
+
condition: (_, siblingData)=>siblingData?.type === 'cron-trigger',
|
|
111
|
+
description: 'Cron expression for scheduled execution (e.g., "0 0 * * *" for daily at midnight)',
|
|
112
|
+
placeholder: '0 0 * * *'
|
|
113
|
+
},
|
|
114
|
+
validate: (value, { siblingData })=>{
|
|
115
|
+
if (siblingData?.type === 'cron-trigger' && !value) {
|
|
116
|
+
return 'Cron expression is required for cron triggers';
|
|
117
|
+
}
|
|
118
|
+
// Validate cron expression format if provided
|
|
119
|
+
if (siblingData?.type === 'cron-trigger' && value) {
|
|
120
|
+
// Basic format validation - should be 5 parts separated by spaces
|
|
121
|
+
const cronParts = value.trim().split(/\s+/);
|
|
122
|
+
if (cronParts.length !== 5) {
|
|
123
|
+
return 'Invalid cron expression format. Expected 5 parts: "minute hour day month weekday" (e.g., "0 9 * * 1")';
|
|
124
|
+
}
|
|
125
|
+
// Additional validation could use node-cron but we avoid dynamic imports here
|
|
126
|
+
// The main validation happens at runtime in the cron scheduler
|
|
127
|
+
}
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'timezone',
|
|
133
|
+
type: 'text',
|
|
134
|
+
admin: {
|
|
135
|
+
condition: (_, siblingData)=>siblingData?.type === 'cron-trigger',
|
|
136
|
+
description: 'Timezone for cron execution (e.g., "America/New_York", "Europe/London"). Defaults to UTC.',
|
|
137
|
+
placeholder: 'UTC'
|
|
138
|
+
},
|
|
139
|
+
defaultValue: 'UTC',
|
|
140
|
+
validate: (value, { siblingData })=>{
|
|
141
|
+
if (siblingData?.type === 'cron-trigger' && value) {
|
|
142
|
+
try {
|
|
143
|
+
// Test if timezone is valid by trying to create a date with it
|
|
144
|
+
new Intl.DateTimeFormat('en', {
|
|
145
|
+
timeZone: value
|
|
146
|
+
});
|
|
147
|
+
return true;
|
|
148
|
+
} catch {
|
|
149
|
+
return `Invalid timezone: ${value}. Please use a valid IANA timezone identifier (e.g., "America/New_York", "Europe/London")`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'condition',
|
|
157
|
+
type: 'text',
|
|
158
|
+
admin: {
|
|
159
|
+
description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., "$.doc.status == \'published\'")'
|
|
160
|
+
},
|
|
161
|
+
required: false
|
|
162
|
+
},
|
|
163
|
+
...(triggers || []).flatMap((t)=>(t.inputs || []).map((f)=>({
|
|
164
|
+
...f,
|
|
165
|
+
admin: {
|
|
166
|
+
...f.admin || {},
|
|
167
|
+
condition: (...args)=>args[1]?.type === t.slug && (f.admin?.condition ? f.admin.condition.call(this, ...args) : true)
|
|
168
|
+
}
|
|
169
|
+
})))
|
|
170
|
+
]
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: 'steps',
|
|
174
|
+
type: 'array',
|
|
175
|
+
fields: [
|
|
176
|
+
{
|
|
177
|
+
type: 'row',
|
|
178
|
+
fields: [
|
|
179
|
+
{
|
|
180
|
+
name: 'step',
|
|
181
|
+
type: 'select',
|
|
182
|
+
options: steps.map((t)=>t.slug)
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: 'name',
|
|
186
|
+
type: 'text'
|
|
187
|
+
}
|
|
188
|
+
]
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
name: 'input',
|
|
192
|
+
type: 'json',
|
|
193
|
+
required: false
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'dependencies',
|
|
197
|
+
type: 'text',
|
|
198
|
+
admin: {
|
|
199
|
+
description: 'Step names that must complete before this step can run'
|
|
200
|
+
},
|
|
201
|
+
hasMany: true,
|
|
202
|
+
required: false
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'condition',
|
|
206
|
+
type: 'text',
|
|
207
|
+
admin: {
|
|
208
|
+
description: 'JSONPath expression that must evaluate to true for this step to execute (e.g., "$.trigger.doc.status == \'published\'")'
|
|
209
|
+
},
|
|
210
|
+
required: false
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
versions: {
|
|
216
|
+
drafts: {
|
|
217
|
+
autosave: false
|
|
218
|
+
},
|
|
219
|
+
maxPerDoc: 10
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
//# sourceMappingURL=Workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/collections/Workflow.ts"],"sourcesContent":["import type {CollectionConfig, Field} from 'payload'\n\nimport type {WorkflowsPluginConfig} from \"../plugin/config-types.js\"\n\nexport const createWorkflowCollection: <T extends string>(options: WorkflowsPluginConfig<T>) => CollectionConfig = ({\n collectionTriggers,\n steps,\n triggers\n }) => ({\n slug: 'workflows',\n access: {\n create: () => true,\n delete: () => true,\n read: () => true,\n update: () => true,\n },\n admin: {\n defaultColumns: ['name', 'updatedAt'],\n description: 'Create and manage automated workflows.',\n group: 'Automation',\n useAsTitle: 'name',\n },\n fields: [\n {\n name: 'name',\n type: 'text',\n admin: {\n description: 'Human-readable name for the workflow',\n },\n required: true,\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n description: 'Optional description of what this workflow does',\n },\n },\n {\n name: 'triggers',\n type: 'array',\n fields: [\n {\n name: 'type',\n type: 'select',\n options: [\n 'collection-trigger',\n 'webhook-trigger',\n 'global-trigger',\n 'cron-trigger',\n ...(triggers || []).map(t => t.slug)\n ]\n },\n {\n name: 'collection',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'collection-trigger',\n description: 'Collection that triggers the workflow',\n },\n options: Object.keys(collectionTriggers || {})\n },\n {\n name: 'operation',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'collection-trigger',\n description: 'Collection operation that triggers the workflow',\n },\n options: [\n 'create',\n 'delete',\n 'read',\n 'update',\n ]\n },\n {\n name: 'webhookPath',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'webhook-trigger',\n description: 'URL path for the webhook (e.g., \"my-webhook\"). Full URL will be /api/workflows/webhook/my-webhook',\n },\n validate: (value: any, {siblingData}: any) => {\n if (siblingData?.type === 'webhook-trigger' && !value) {\n return 'Webhook path is required for webhook triggers'\n }\n return true\n }\n },\n {\n name: 'global',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'global-trigger',\n description: 'Global that triggers the workflow',\n },\n options: [] // Will be populated dynamically based on available globals\n },\n {\n name: 'globalOperation',\n type: 'select',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'global-trigger',\n description: 'Global operation that triggers the workflow',\n },\n options: [\n 'update'\n ]\n },\n {\n name: 'cronExpression',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'cron-trigger',\n description: 'Cron expression for scheduled execution (e.g., \"0 0 * * *\" for daily at midnight)',\n placeholder: '0 0 * * *'\n },\n validate: (value: any, {siblingData}: any) => {\n if (siblingData?.type === 'cron-trigger' && !value) {\n return 'Cron expression is required for cron triggers'\n }\n\n // Validate cron expression format if provided\n if (siblingData?.type === 'cron-trigger' && value) {\n // Basic format validation - should be 5 parts separated by spaces\n const cronParts = value.trim().split(/\\s+/)\n if (cronParts.length !== 5) {\n return 'Invalid cron expression format. Expected 5 parts: \"minute hour day month weekday\" (e.g., \"0 9 * * 1\")'\n }\n\n // Additional validation could use node-cron but we avoid dynamic imports here\n // The main validation happens at runtime in the cron scheduler\n }\n\n return true\n }\n },\n {\n name: 'timezone',\n type: 'text',\n admin: {\n condition: (_, siblingData) => siblingData?.type === 'cron-trigger',\n description: 'Timezone for cron execution (e.g., \"America/New_York\", \"Europe/London\"). Defaults to UTC.',\n placeholder: 'UTC'\n },\n defaultValue: 'UTC',\n validate: (value: any, {siblingData}: any) => {\n if (siblingData?.type === 'cron-trigger' && value) {\n try {\n // Test if timezone is valid by trying to create a date with it\n new Intl.DateTimeFormat('en', {timeZone: value})\n return true\n } catch {\n return `Invalid timezone: ${value}. Please use a valid IANA timezone identifier (e.g., \"America/New_York\", \"Europe/London\")`\n }\n }\n return true\n }\n },\n {\n name: 'condition',\n type: 'text',\n admin: {\n description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., \"$.doc.status == \\'published\\'\")'\n },\n required: false\n },\n ...(triggers || []).flatMap(t => (t.inputs || []).map(f => ({\n ...f,\n admin: {\n ...(f.admin || {}),\n condition: (...args) => args[1]?.type === t.slug && (\n f.admin?.condition ?\n f.admin.condition.call(this, ...args) :\n true\n ),\n },\n } as Field)))\n ]\n },\n {\n name: 'steps',\n type: 'array',\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'step',\n type: 'select',\n options: steps.map(t => t.slug)\n },\n {\n name: 'name',\n type: 'text',\n }\n ]\n },\n {\n name: 'input',\n type: 'json',\n required: false\n },\n {\n name: 'dependencies',\n type: 'text',\n admin: {\n description: 'Step names that must complete before this step can run'\n },\n hasMany: true,\n required: false\n },\n {\n name: 'condition',\n type: 'text',\n admin: {\n description: 'JSONPath expression that must evaluate to true for this step to execute (e.g., \"$.trigger.doc.status == \\'published\\'\")'\n },\n required: false\n },\n ],\n }\n ],\n versions: {\n drafts: {\n autosave: false,\n },\n maxPerDoc: 10,\n },\n})\n"],"names":["createWorkflowCollection","collectionTriggers","steps","triggers","slug","access","create","delete","read","update","admin","defaultColumns","description","group","useAsTitle","fields","name","type","required","options","map","t","condition","_","siblingData","Object","keys","validate","value","placeholder","cronParts","trim","split","length","defaultValue","Intl","DateTimeFormat","timeZone","flatMap","inputs","f","args","call","hasMany","versions","drafts","autosave","maxPerDoc"],"mappings":"AAIA,OAAO,MAAMA,2BAAsG,CAAC,EACZC,kBAAkB,EAClBC,KAAK,EACLC,QAAQ,EACT,GAAM,CAAA;QAC3GC,MAAM;QACNC,QAAQ;YACNC,QAAQ,IAAM;YACdC,QAAQ,IAAM;YACdC,MAAM,IAAM;YACZC,QAAQ,IAAM;QAChB;QACAC,OAAO;YACLC,gBAAgB;gBAAC;gBAAQ;aAAY;YACrCC,aAAa;YACbC,OAAO;YACPC,YAAY;QACd;QACAC,QAAQ;YACN;gBACEC,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLE,aAAa;gBACf;gBACAM,UAAU;YACZ;YACA;gBACEF,MAAM;gBACNC,MAAM;gBACNP,OAAO;oBACLE,aAAa;gBACf;YACF;YACA;gBACEI,MAAM;gBACNC,MAAM;gBACNF,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNE,SAAS;4BACP;4BACA;4BACA;4BACA;+BACG,AAAChB,CAAAA,YAAY,EAAE,AAAD,EAAGiB,GAAG,CAACC,CAAAA,IAAKA,EAAEjB,IAAI;yBACpC;oBACH;oBACA;wBACEY,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;wBACf;wBACAO,SAASM,OAAOC,IAAI,CAACzB,sBAAsB,CAAC;oBAC9C;oBACA;wBACEe,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;wBACf;wBACAO,SAAS;4BACP;4BACA;4BACA;4BACA;yBACD;oBACH;oBACA;wBACEH,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;wBACf;wBACAe,UAAU,CAACC,OAAY,EAACJ,WAAW,EAAM;4BACvC,IAAIA,aAAaP,SAAS,qBAAqB,CAACW,OAAO;gCACrD,OAAO;4BACT;4BACA,OAAO;wBACT;oBACF;oBACA;wBACEZ,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;wBACf;wBACAO,SAAS,EAAE,CAAC,2DAA2D;oBACzE;oBACA;wBACEH,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;wBACf;wBACAO,SAAS;4BACP;yBACD;oBACH;oBACA;wBACEH,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;4BACbiB,aAAa;wBACf;wBACAF,UAAU,CAACC,OAAY,EAACJ,WAAW,EAAM;4BACvC,IAAIA,aAAaP,SAAS,kBAAkB,CAACW,OAAO;gCAClD,OAAO;4BACT;4BAEA,8CAA8C;4BAC9C,IAAIJ,aAAaP,SAAS,kBAAkBW,OAAO;gCACjD,kEAAkE;gCAClE,MAAME,YAAYF,MAAMG,IAAI,GAAGC,KAAK,CAAC;gCACrC,IAAIF,UAAUG,MAAM,KAAK,GAAG;oCAC1B,OAAO;gCACT;4BAEA,8EAA8E;4BAC9E,+DAA+D;4BACjE;4BAEA,OAAO;wBACT;oBACF;oBACA;wBACEjB,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLY,WAAW,CAACC,GAAGC,cAAgBA,aAAaP,SAAS;4BACrDL,aAAa;4BACbiB,aAAa;wBACf;wBACAK,cAAc;wBACdP,UAAU,CAACC,OAAY,EAACJ,WAAW,EAAM;4BACvC,IAAIA,aAAaP,SAAS,kBAAkBW,OAAO;gCACjD,IAAI;oCACF,+DAA+D;oCAC/D,IAAIO,KAAKC,cAAc,CAAC,MAAM;wCAACC,UAAUT;oCAAK;oCAC9C,OAAO;gCACT,EAAE,OAAM;oCACN,OAAO,CAAC,kBAAkB,EAAEA,MAAM,yFAAyF,CAAC;gCAC9H;4BACF;4BACA,OAAO;wBACT;oBACF;oBACA;wBACEZ,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAM,UAAU;oBACZ;uBACG,AAACf,CAAAA,YAAY,EAAE,AAAD,EAAGmC,OAAO,CAACjB,CAAAA,IAAK,AAACA,CAAAA,EAAEkB,MAAM,IAAI,EAAE,AAAD,EAAGnB,GAAG,CAACoB,CAAAA,IAAM,CAAA;gCAC1D,GAAGA,CAAC;gCACJ9B,OAAO;oCACL,GAAI8B,EAAE9B,KAAK,IAAI,CAAC,CAAC;oCACjBY,WAAW,CAAC,GAAGmB,OAASA,IAAI,CAAC,EAAE,EAAExB,SAASI,EAAEjB,IAAI,IAC9CoC,CAAAA,EAAE9B,KAAK,EAAEY,YACPkB,EAAE9B,KAAK,CAACY,SAAS,CAACoB,IAAI,CAAC,IAAI,KAAKD,QAChC,IAAG;gCAET;4BACF,CAAA;iBACD;YACH;YACA;gBACEzB,MAAM;gBACNC,MAAM;gBACNF,QAAQ;oBACN;wBACEE,MAAM;wBACNF,QAAQ;4BACN;gCACEC,MAAM;gCACNC,MAAM;gCACNE,SAASjB,MAAMkB,GAAG,CAACC,CAAAA,IAAKA,EAAEjB,IAAI;4BAChC;4BACA;gCACEY,MAAM;gCACNC,MAAM;4BACR;yBACD;oBACH;oBACA;wBACED,MAAM;wBACNC,MAAM;wBACNC,UAAU;oBACZ;oBACA;wBACEF,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACA+B,SAAS;wBACTzB,UAAU;oBACZ;oBACA;wBACEF,MAAM;wBACNC,MAAM;wBACNP,OAAO;4BACLE,aAAa;wBACf;wBACAM,UAAU;oBACZ;iBACD;YACH;SACD;QACD0B,UAAU;YACRC,QAAQ;gBACNC,UAAU;YACZ;YACAC,WAAW;QACb;IACF,CAAA,EAAE"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
export const WorkflowRunsCollection = {
|
|
2
|
+
slug: 'workflow-runs',
|
|
3
|
+
access: {
|
|
4
|
+
create: ()=>true,
|
|
5
|
+
delete: ()=>true,
|
|
6
|
+
read: ()=>true,
|
|
7
|
+
update: ()=>true
|
|
8
|
+
},
|
|
9
|
+
admin: {
|
|
10
|
+
defaultColumns: [
|
|
11
|
+
'workflow',
|
|
12
|
+
'status',
|
|
13
|
+
'triggeredBy',
|
|
14
|
+
'startedAt',
|
|
15
|
+
'duration'
|
|
16
|
+
],
|
|
17
|
+
group: 'Automation',
|
|
18
|
+
pagination: {
|
|
19
|
+
defaultLimit: 50
|
|
20
|
+
},
|
|
21
|
+
useAsTitle: 'id'
|
|
22
|
+
},
|
|
23
|
+
fields: [
|
|
24
|
+
{
|
|
25
|
+
name: 'workflow',
|
|
26
|
+
type: 'relationship',
|
|
27
|
+
admin: {
|
|
28
|
+
description: 'Reference to the workflow that was executed'
|
|
29
|
+
},
|
|
30
|
+
relationTo: 'workflows',
|
|
31
|
+
required: true
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'workflowVersion',
|
|
35
|
+
type: 'number',
|
|
36
|
+
admin: {
|
|
37
|
+
description: 'Version of the workflow that was executed'
|
|
38
|
+
},
|
|
39
|
+
required: true
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'status',
|
|
43
|
+
type: 'select',
|
|
44
|
+
admin: {
|
|
45
|
+
description: 'Current execution status'
|
|
46
|
+
},
|
|
47
|
+
defaultValue: 'pending',
|
|
48
|
+
options: [
|
|
49
|
+
{
|
|
50
|
+
label: 'Pending',
|
|
51
|
+
value: 'pending'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
label: 'Running',
|
|
55
|
+
value: 'running'
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
label: 'Completed',
|
|
59
|
+
value: 'completed'
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'Failed',
|
|
63
|
+
value: 'failed'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
label: 'Cancelled',
|
|
67
|
+
value: 'cancelled'
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
required: true
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'startedAt',
|
|
74
|
+
type: 'date',
|
|
75
|
+
admin: {
|
|
76
|
+
date: {
|
|
77
|
+
displayFormat: 'yyyy-MM-dd HH:mm:ss'
|
|
78
|
+
},
|
|
79
|
+
description: 'When execution began'
|
|
80
|
+
},
|
|
81
|
+
required: true
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'completedAt',
|
|
85
|
+
type: 'date',
|
|
86
|
+
admin: {
|
|
87
|
+
date: {
|
|
88
|
+
displayFormat: 'yyyy-MM-dd HH:mm:ss'
|
|
89
|
+
},
|
|
90
|
+
description: 'When execution finished'
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'duration',
|
|
95
|
+
type: 'number',
|
|
96
|
+
admin: {
|
|
97
|
+
description: 'Total execution time in milliseconds',
|
|
98
|
+
readOnly: true
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'context',
|
|
103
|
+
type: 'json'
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'inputs',
|
|
107
|
+
type: 'json',
|
|
108
|
+
admin: {
|
|
109
|
+
description: 'Input data provided when the workflow was triggered'
|
|
110
|
+
},
|
|
111
|
+
defaultValue: {},
|
|
112
|
+
required: true
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'outputs',
|
|
116
|
+
type: 'json',
|
|
117
|
+
admin: {
|
|
118
|
+
description: 'Final output data from completed steps'
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'triggeredBy',
|
|
123
|
+
type: 'text',
|
|
124
|
+
admin: {
|
|
125
|
+
description: 'User, system, or trigger type that initiated execution'
|
|
126
|
+
},
|
|
127
|
+
required: true
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'steps',
|
|
131
|
+
type: 'json',
|
|
132
|
+
admin: {
|
|
133
|
+
description: 'Array of step execution results'
|
|
134
|
+
},
|
|
135
|
+
defaultValue: [],
|
|
136
|
+
required: true
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'error',
|
|
140
|
+
type: 'textarea',
|
|
141
|
+
admin: {
|
|
142
|
+
description: 'Error message if workflow execution failed'
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'logs',
|
|
147
|
+
type: 'json',
|
|
148
|
+
admin: {
|
|
149
|
+
description: 'Detailed execution logs'
|
|
150
|
+
},
|
|
151
|
+
defaultValue: [],
|
|
152
|
+
required: true
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
//# sourceMappingURL=WorkflowRuns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/collections/WorkflowRuns.ts"],"sourcesContent":["import type { CollectionConfig } from 'payload'\n\nexport const WorkflowRunsCollection: CollectionConfig = {\n slug: 'workflow-runs',\n access: {\n create: () => true,\n delete: () => true,\n read: () => true,\n update: () => true,\n },\n admin: {\n defaultColumns: ['workflow', 'status', 'triggeredBy', 'startedAt', 'duration'],\n group: 'Automation',\n pagination: {\n defaultLimit: 50,\n },\n useAsTitle: 'id',\n },\n fields: [\n {\n name: 'workflow',\n type: 'relationship',\n admin: {\n description: 'Reference to the workflow that was executed',\n },\n relationTo: 'workflows',\n required: true,\n },\n {\n name: 'workflowVersion',\n type: 'number',\n admin: {\n description: 'Version of the workflow that was executed',\n },\n required: true,\n },\n {\n name: 'status',\n type: 'select',\n admin: {\n description: 'Current execution status',\n },\n defaultValue: 'pending',\n options: [\n {\n label: 'Pending',\n value: 'pending',\n },\n {\n label: 'Running',\n value: 'running',\n },\n {\n label: 'Completed',\n value: 'completed',\n },\n {\n label: 'Failed',\n value: 'failed',\n },\n {\n label: 'Cancelled',\n value: 'cancelled',\n },\n ],\n required: true,\n },\n {\n name: 'startedAt',\n type: 'date',\n admin: {\n date: {\n displayFormat: 'yyyy-MM-dd HH:mm:ss',\n },\n description: 'When execution began',\n },\n required: true,\n },\n {\n name: 'completedAt',\n type: 'date',\n admin: {\n date: {\n displayFormat: 'yyyy-MM-dd HH:mm:ss',\n },\n description: 'When execution finished',\n },\n },\n {\n name: 'duration',\n type: 'number',\n admin: {\n description: 'Total execution time in milliseconds',\n readOnly: true,\n },\n },\n {\n name: 'context',\n type: 'json'\n },\n {\n name: 'inputs',\n type: 'json',\n admin: {\n description: 'Input data provided when the workflow was triggered',\n },\n defaultValue: {},\n required: true,\n },\n {\n name: 'outputs',\n type: 'json',\n admin: {\n description: 'Final output data from completed steps',\n },\n },\n {\n name: 'triggeredBy',\n type: 'text',\n admin: {\n description: 'User, system, or trigger type that initiated execution',\n },\n required: true,\n },\n {\n name: 'steps',\n type: 'json',\n admin: {\n description: 'Array of step execution results',\n },\n defaultValue: [],\n required: true,\n },\n {\n name: 'error',\n type: 'textarea',\n admin: {\n description: 'Error message if workflow execution failed',\n },\n },\n {\n name: 'logs',\n type: 'json',\n admin: {\n description: 'Detailed execution logs',\n },\n defaultValue: [],\n required: true,\n },\n ],\n}\n"],"names":["WorkflowRunsCollection","slug","access","create","delete","read","update","admin","defaultColumns","group","pagination","defaultLimit","useAsTitle","fields","name","type","description","relationTo","required","defaultValue","options","label","value","date","displayFormat","readOnly"],"mappings":"AAEA,OAAO,MAAMA,yBAA2C;IACtDC,MAAM;IACNC,QAAQ;QACNC,QAAQ,IAAM;QACdC,QAAQ,IAAM;QACdC,MAAM,IAAM;QACZC,QAAQ,IAAM;IAChB;IACAC,OAAO;QACLC,gBAAgB;YAAC;YAAY;YAAU;YAAe;YAAa;SAAW;QAC9EC,OAAO;QACPC,YAAY;YACVC,cAAc;QAChB;QACAC,YAAY;IACd;IACAC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAC,YAAY;YACZC,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAE,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAG,cAAc;YACdC,SAAS;gBACP;oBACEC,OAAO;oBACPC,OAAO;gBACT;gBACA;oBACED,OAAO;oBACPC,OAAO;gBACT;gBACA;oBACED,OAAO;oBACPC,OAAO;gBACT;gBACA;oBACED,OAAO;oBACPC,OAAO;gBACT;gBACA;oBACED,OAAO;oBACPC,OAAO;gBACT;aACD;YACDJ,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLgB,MAAM;oBACJC,eAAe;gBACjB;gBACAR,aAAa;YACf;YACAE,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLgB,MAAM;oBACJC,eAAe;gBACjB;gBACAR,aAAa;YACf;QACF;QACA;YACEF,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;gBACbS,UAAU;YACZ;QACF;QACA;YACEX,MAAM;YACNC,MAAM;QACR;QACA;YACED,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAG,cAAc,CAAC;YACfD,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;QACF;QACA;YACEF,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAE,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAG,cAAc,EAAE;YAChBD,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;QACF;QACA;YACEF,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAG,cAAc,EAAE;YAChBD,UAAU;QACZ;KACD;AACH,EAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Button, toast } from '@payloadcms/ui';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
export const TriggerWorkflowButton = ({ workflowId, workflowName, triggerSlug = 'manual-trigger' })=>{
|
|
6
|
+
const [loading, setLoading] = useState(false);
|
|
7
|
+
const handleTrigger = async ()=>{
|
|
8
|
+
setLoading(true);
|
|
9
|
+
try {
|
|
10
|
+
const response = await fetch('/api/workflows/trigger-custom', {
|
|
11
|
+
method: 'POST',
|
|
12
|
+
headers: {
|
|
13
|
+
'Content-Type': 'application/json'
|
|
14
|
+
},
|
|
15
|
+
body: JSON.stringify({
|
|
16
|
+
workflowId,
|
|
17
|
+
triggerSlug,
|
|
18
|
+
data: {
|
|
19
|
+
triggeredAt: new Date().toISOString(),
|
|
20
|
+
source: 'admin-button'
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
const error = await response.json();
|
|
26
|
+
throw new Error(error.message || 'Failed to trigger workflow');
|
|
27
|
+
}
|
|
28
|
+
const result = await response.json();
|
|
29
|
+
toast.success(`Workflow "${workflowName}" triggered successfully! Run ID: ${result.runId}`);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('Error triggering workflow:', error);
|
|
32
|
+
toast.error(`Failed to trigger workflow: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
33
|
+
} finally{
|
|
34
|
+
setLoading(false);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return /*#__PURE__*/ _jsx(Button, {
|
|
38
|
+
onClick: handleTrigger,
|
|
39
|
+
disabled: loading,
|
|
40
|
+
size: "small",
|
|
41
|
+
buttonStyle: "secondary",
|
|
42
|
+
children: loading ? 'Triggering...' : 'Trigger Workflow'
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
//# sourceMappingURL=TriggerWorkflowButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TriggerWorkflowButton.tsx"],"sourcesContent":["'use client'\n\nimport { Button, toast } from '@payloadcms/ui'\nimport { useState } from 'react'\n\ninterface TriggerWorkflowButtonProps {\n workflowId: string\n workflowName: string\n triggerSlug?: string\n}\n\nexport const TriggerWorkflowButton: React.FC<TriggerWorkflowButtonProps> = ({\n workflowId,\n workflowName,\n triggerSlug = 'manual-trigger'\n}) => {\n const [loading, setLoading] = useState(false)\n\n const handleTrigger = async () => {\n setLoading(true)\n \n try {\n const response = await fetch('/api/workflows/trigger-custom', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n workflowId,\n triggerSlug,\n data: {\n triggeredAt: new Date().toISOString(),\n source: 'admin-button'\n }\n }),\n })\n\n if (!response.ok) {\n const error = await response.json()\n throw new Error(error.message || 'Failed to trigger workflow')\n }\n\n const result = await response.json()\n \n toast.success(`Workflow \"${workflowName}\" triggered successfully! Run ID: ${result.runId}`)\n } catch (error) {\n console.error('Error triggering workflow:', error)\n toast.error(`Failed to trigger workflow: ${error instanceof Error ? error.message : 'Unknown error'}`)\n } finally {\n setLoading(false)\n }\n }\n\n return (\n <Button\n onClick={handleTrigger}\n disabled={loading}\n size=\"small\"\n buttonStyle=\"secondary\"\n >\n {loading ? 'Triggering...' : 'Trigger Workflow'}\n </Button>\n )\n}"],"names":["Button","toast","useState","TriggerWorkflowButton","workflowId","workflowName","triggerSlug","loading","setLoading","handleTrigger","response","fetch","method","headers","body","JSON","stringify","data","triggeredAt","Date","toISOString","source","ok","error","json","Error","message","result","success","runId","console","onClick","disabled","size","buttonStyle"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,KAAK,QAAQ,iBAAgB;AAC9C,SAASC,QAAQ,QAAQ,QAAO;AAQhC,OAAO,MAAMC,wBAA8D,CAAC,EAC1EC,UAAU,EACVC,YAAY,EACZC,cAAc,gBAAgB,EAC/B;IACC,MAAM,CAACC,SAASC,WAAW,GAAGN,SAAS;IAEvC,MAAMO,gBAAgB;QACpBD,WAAW;QAEX,IAAI;YACF,MAAME,WAAW,MAAMC,MAAM,iCAAiC;gBAC5DC,QAAQ;gBACRC,SAAS;oBACP,gBAAgB;gBAClB;gBACAC,MAAMC,KAAKC,SAAS,CAAC;oBACnBZ;oBACAE;oBACAW,MAAM;wBACJC,aAAa,IAAIC,OAAOC,WAAW;wBACnCC,QAAQ;oBACV;gBACF;YACF;YAEA,IAAI,CAACX,SAASY,EAAE,EAAE;gBAChB,MAAMC,QAAQ,MAAMb,SAASc,IAAI;gBACjC,MAAM,IAAIC,MAAMF,MAAMG,OAAO,IAAI;YACnC;YAEA,MAAMC,SAAS,MAAMjB,SAASc,IAAI;YAElCvB,MAAM2B,OAAO,CAAC,CAAC,UAAU,EAAEvB,aAAa,kCAAkC,EAAEsB,OAAOE,KAAK,EAAE;QAC5F,EAAE,OAAON,OAAO;YACdO,QAAQP,KAAK,CAAC,8BAA8BA;YAC5CtB,MAAMsB,KAAK,CAAC,CAAC,4BAA4B,EAAEA,iBAAiBE,QAAQF,MAAMG,OAAO,GAAG,iBAAiB;QACvG,SAAU;YACRlB,WAAW;QACb;IACF;IAEA,qBACE,KAACR;QACC+B,SAAStB;QACTuB,UAAUzB;QACV0B,MAAK;QACLC,aAAY;kBAEX3B,UAAU,kBAAkB;;AAGnC,EAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Payload, PayloadRequest } from 'payload';
|
|
2
|
+
export interface CustomTriggerOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Data to pass to the workflow execution context
|
|
5
|
+
*/
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Optional PayloadRequest to use for the workflow execution
|
|
9
|
+
* If not provided, a minimal request will be created
|
|
10
|
+
*/
|
|
11
|
+
req?: PayloadRequest;
|
|
12
|
+
/**
|
|
13
|
+
* The slug of the custom trigger to execute
|
|
14
|
+
*/
|
|
15
|
+
slug: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional user information for tracking who triggered the workflow
|
|
18
|
+
*/
|
|
19
|
+
user?: {
|
|
20
|
+
email?: string;
|
|
21
|
+
id?: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface TriggerResult {
|
|
25
|
+
error?: string;
|
|
26
|
+
runId: number | string;
|
|
27
|
+
status: 'failed' | 'triggered';
|
|
28
|
+
workflowId: string;
|
|
29
|
+
workflowName: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Programmatically trigger workflows that have a matching custom trigger
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // In your onInit or elsewhere in your code
|
|
37
|
+
* await triggerCustomWorkflow(payload, {
|
|
38
|
+
* slug: 'data-import',
|
|
39
|
+
* data: {
|
|
40
|
+
* source: 'external-api',
|
|
41
|
+
* recordCount: 100,
|
|
42
|
+
* importedAt: new Date().toISOString()
|
|
43
|
+
* }
|
|
44
|
+
* })
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function triggerCustomWorkflow(payload: Payload, options: CustomTriggerOptions): Promise<TriggerResult[]>;
|
|
48
|
+
/**
|
|
49
|
+
* Helper function to trigger a single workflow by ID with custom trigger data
|
|
50
|
+
* This is useful when you know exactly which workflow you want to trigger
|
|
51
|
+
*/
|
|
52
|
+
export declare function triggerWorkflowById(payload: Payload, workflowId: string, triggerSlug: string, data?: Record<string, unknown>, req?: PayloadRequest): Promise<TriggerResult>;
|