@xtr-dev/payload-automation 0.0.21 → 0.0.23
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 -2
- package/dist/collections/Workflow.js +19 -7
- package/dist/collections/Workflow.js.map +1 -1
- package/dist/collections/WorkflowRuns.js +14 -7
- package/dist/collections/WorkflowRuns.js.map +1 -1
- package/dist/components/StatusCell.d.ts +6 -0
- package/dist/components/StatusCell.js +75 -0
- package/dist/components/StatusCell.js.map +1 -0
- package/dist/components/WorkflowExecutionStatus.d.ts +6 -0
- package/dist/components/WorkflowExecutionStatus.js +287 -0
- package/dist/components/WorkflowExecutionStatus.js.map +1 -0
- package/dist/core/workflow-executor.d.ts +32 -0
- package/dist/core/workflow-executor.js +162 -7
- package/dist/core/workflow-executor.js.map +1 -1
- package/dist/exports/client.d.ts +2 -0
- package/dist/exports/client.js +4 -1
- package/dist/exports/client.js.map +1 -1
- package/dist/plugin/index.js +131 -42
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/init-step-tasks.js +15 -1
- package/dist/plugin/init-step-tasks.js.map +1 -1
- package/dist/steps/create-document.js +1 -1
- package/dist/steps/create-document.js.map +1 -1
- package/dist/steps/delete-document.js +2 -2
- package/dist/steps/delete-document.js.map +1 -1
- package/dist/steps/http-request-handler.js +229 -10
- package/dist/steps/http-request-handler.js.map +1 -1
- package/dist/steps/http-request.d.ts +147 -4
- package/dist/steps/http-request.js +189 -3
- package/dist/steps/http-request.js.map +1 -1
- package/dist/steps/read-document.js +2 -2
- package/dist/steps/read-document.js.map +1 -1
- package/dist/steps/send-email.js +5 -5
- package/dist/steps/send-email.js.map +1 -1
- package/dist/steps/update-document.js +2 -2
- package/dist/steps/update-document.js.map +1 -1
- package/dist/test/create-document-step.test.js +378 -0
- package/dist/test/create-document-step.test.js.map +1 -0
- package/dist/test/http-request-step.test.js +361 -0
- package/dist/test/http-request-step.test.js.map +1 -0
- package/dist/test/workflow-executor.test.js +530 -0
- package/dist/test/workflow-executor.test.js.map +1 -0
- package/package.json +4 -1
- package/dist/test/basic.test.d.ts +0 -1
package/README.md
CHANGED
|
@@ -63,11 +63,82 @@ import type { WorkflowsPluginConfig } from '@xtr-dev/payload-automation'
|
|
|
63
63
|
|
|
64
64
|
## Step Types
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
### HTTP Request
|
|
67
|
+
Make external API calls with comprehensive error handling and retry logic.
|
|
68
|
+
|
|
69
|
+
**Key Features:**
|
|
70
|
+
- Support for GET, POST, PUT, DELETE, PATCH methods
|
|
71
|
+
- Authentication: Bearer token, Basic auth, API key headers
|
|
72
|
+
- Configurable timeouts and retry logic
|
|
73
|
+
- JSONPath integration for dynamic URLs and request bodies
|
|
74
|
+
|
|
75
|
+
**Error Handling:**
|
|
76
|
+
HTTP Request steps use a **response-based success model** rather than status-code-based failures:
|
|
77
|
+
|
|
78
|
+
- ✅ **Successful completion**: All HTTP requests that receive a response (including 4xx/5xx status codes) are marked as "succeeded"
|
|
79
|
+
- ❌ **Failed execution**: Only network errors, timeouts, DNS failures, and connection issues cause step failure
|
|
80
|
+
- 📊 **Error information preserved**: HTTP error status codes (404, 500, etc.) are captured in the step output for workflow conditional logic
|
|
81
|
+
|
|
82
|
+
**Example workflow logic:**
|
|
83
|
+
```typescript
|
|
84
|
+
// Step outputs for a 404 response:
|
|
85
|
+
{
|
|
86
|
+
"status": 404,
|
|
87
|
+
"statusText": "Not Found",
|
|
88
|
+
"body": "Resource not found",
|
|
89
|
+
"headers": {...},
|
|
90
|
+
"duration": 1200
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Use in workflow conditions:
|
|
94
|
+
// "$.steps.apiRequest.output.status >= 400" to handle errors
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This design allows workflows to handle HTTP errors gracefully rather than failing completely, enabling robust error handling and retry logic.
|
|
98
|
+
|
|
99
|
+
**Enhanced Error Tracking:**
|
|
100
|
+
For network failures (timeouts, DNS errors, connection failures), the plugin provides detailed error information through an independent storage system that bypasses PayloadCMS's output limitations:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// Timeout error details preserved in workflow context:
|
|
104
|
+
{
|
|
105
|
+
"steps": {
|
|
106
|
+
"httpStep": {
|
|
107
|
+
"state": "failed",
|
|
108
|
+
"error": "Task handler returned a failed state",
|
|
109
|
+
"errorDetails": {
|
|
110
|
+
"errorType": "timeout",
|
|
111
|
+
"duration": 2006,
|
|
112
|
+
"attempts": 1,
|
|
113
|
+
"finalError": "Request timeout after 2000ms",
|
|
114
|
+
"context": {
|
|
115
|
+
"url": "https://api.example.com/data",
|
|
116
|
+
"method": "GET",
|
|
117
|
+
"timeout": 2000
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"executionInfo": {
|
|
121
|
+
"completed": true,
|
|
122
|
+
"success": false,
|
|
123
|
+
"executedAt": "2025-09-04T15:16:10.000Z",
|
|
124
|
+
"duration": 2006
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Access in workflow conditions:
|
|
131
|
+
// "$.steps.httpStep.errorDetails.errorType == 'timeout'"
|
|
132
|
+
// "$.steps.httpStep.errorDetails.duration > 5000"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Document Operations
|
|
67
136
|
- **Create Document** - Create PayloadCMS documents
|
|
68
137
|
- **Read Document** - Query documents with filters
|
|
69
|
-
- **Update Document** - Modify existing documents
|
|
138
|
+
- **Update Document** - Modify existing documents
|
|
70
139
|
- **Delete Document** - Remove documents
|
|
140
|
+
|
|
141
|
+
### Communication
|
|
71
142
|
- **Send Email** - Send notifications via PayloadCMS email
|
|
72
143
|
|
|
73
144
|
## Data Resolution
|
|
@@ -31,6 +31,16 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
31
31
|
description: 'Optional description of what this workflow does'
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
|
+
{
|
|
35
|
+
name: 'executionStatus',
|
|
36
|
+
type: 'ui',
|
|
37
|
+
admin: {
|
|
38
|
+
components: {
|
|
39
|
+
Field: '@/components/WorkflowExecutionStatus'
|
|
40
|
+
},
|
|
41
|
+
condition: (data)=>!!data?.id // Only show for existing workflows
|
|
42
|
+
}
|
|
43
|
+
},
|
|
34
44
|
{
|
|
35
45
|
name: 'triggers',
|
|
36
46
|
type: 'array',
|
|
@@ -74,7 +84,7 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
74
84
|
type: 'text',
|
|
75
85
|
admin: {
|
|
76
86
|
condition: (_, siblingData)=>siblingData?.type === 'webhook-trigger',
|
|
77
|
-
description: 'URL path for the webhook (e.g., "my-webhook"). Full URL will be /api/workflows
|
|
87
|
+
description: 'URL path for the webhook (e.g., "my-webhook"). Full URL will be /api/workflows-webhook/my-webhook'
|
|
78
88
|
},
|
|
79
89
|
validate: (value, { siblingData })=>{
|
|
80
90
|
if (siblingData?.type === 'webhook-trigger' && !value) {
|
|
@@ -156,7 +166,7 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
156
166
|
name: 'condition',
|
|
157
167
|
type: 'text',
|
|
158
168
|
admin: {
|
|
159
|
-
description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., "$.doc.status == \'published\'")'
|
|
169
|
+
description: 'JSONPath expression that must evaluate to true for this trigger to execute the workflow (e.g., "$.trigger.doc.status == \'published\'")'
|
|
160
170
|
},
|
|
161
171
|
required: false
|
|
162
172
|
},
|
|
@@ -187,11 +197,13 @@ export const createWorkflowCollection = ({ collectionTriggers, steps, triggers }
|
|
|
187
197
|
}
|
|
188
198
|
]
|
|
189
199
|
},
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
...(steps || []).flatMap((step)=>(step.inputSchema || []).map((field)=>({
|
|
201
|
+
...field,
|
|
202
|
+
admin: {
|
|
203
|
+
...field.admin || {},
|
|
204
|
+
condition: (...args)=>args[1]?.step === step.slug && (field.admin?.condition ? field.admin.condition.call(this, ...args) : true)
|
|
205
|
+
}
|
|
206
|
+
}))),
|
|
195
207
|
{
|
|
196
208
|
name: 'dependencies',
|
|
197
209
|
type: 'text',
|
|
@@ -1 +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: 'collectionSlug',\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":"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"}
|
|
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: 'executionStatus',\n type: 'ui',\n admin: {\n components: {\n Field: '@/components/WorkflowExecutionStatus'\n },\n condition: (data) => !!data?.id // Only show for existing workflows\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: 'collectionSlug',\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., \"$.trigger.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 ...(steps || []).flatMap(step => (step.inputSchema || []).map(field => ({\n ...field,\n admin: {\n ...(field.admin || {}),\n condition: (...args) => args[1]?.step === step.slug && (\n field.admin?.condition ?\n field.admin.condition.call(this, ...args) :\n true\n ),\n },\n } as Field))),\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","components","Field","condition","data","id","options","map","t","_","siblingData","Object","keys","validate","value","placeholder","cronParts","trim","split","length","defaultValue","Intl","DateTimeFormat","timeZone","flatMap","inputs","f","args","call","step","inputSchema","field","hasMany","versions","drafts","autosave","maxPerDoc"],"mappings":"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"}
|
|
@@ -42,28 +42,31 @@ export const WorkflowRunsCollection = {
|
|
|
42
42
|
name: 'status',
|
|
43
43
|
type: 'select',
|
|
44
44
|
admin: {
|
|
45
|
-
description: 'Current execution status'
|
|
45
|
+
description: 'Current execution status',
|
|
46
|
+
components: {
|
|
47
|
+
Cell: '@/components/StatusCell'
|
|
48
|
+
}
|
|
46
49
|
},
|
|
47
50
|
defaultValue: 'pending',
|
|
48
51
|
options: [
|
|
49
52
|
{
|
|
50
|
-
label: 'Pending',
|
|
53
|
+
label: '⏳ Pending',
|
|
51
54
|
value: 'pending'
|
|
52
55
|
},
|
|
53
56
|
{
|
|
54
|
-
label: 'Running',
|
|
57
|
+
label: '🔄 Running',
|
|
55
58
|
value: 'running'
|
|
56
59
|
},
|
|
57
60
|
{
|
|
58
|
-
label: 'Completed',
|
|
61
|
+
label: '✅ Completed',
|
|
59
62
|
value: 'completed'
|
|
60
63
|
},
|
|
61
64
|
{
|
|
62
|
-
label: 'Failed',
|
|
65
|
+
label: '❌ Failed',
|
|
63
66
|
value: 'failed'
|
|
64
67
|
},
|
|
65
68
|
{
|
|
66
|
-
label: 'Cancelled',
|
|
69
|
+
label: '⏹️ Cancelled',
|
|
67
70
|
value: 'cancelled'
|
|
68
71
|
}
|
|
69
72
|
],
|
|
@@ -139,7 +142,11 @@ export const WorkflowRunsCollection = {
|
|
|
139
142
|
name: 'error',
|
|
140
143
|
type: 'textarea',
|
|
141
144
|
admin: {
|
|
142
|
-
description: 'Error message if workflow execution failed'
|
|
145
|
+
description: 'Error message if workflow execution failed',
|
|
146
|
+
condition: (_, siblingData)=>siblingData?.status === 'failed',
|
|
147
|
+
components: {
|
|
148
|
+
Field: '@/components/ErrorDisplay'
|
|
149
|
+
}
|
|
143
150
|
}
|
|
144
151
|
},
|
|
145
152
|
{
|
|
@@ -1 +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;
|
|
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 components: {\n Cell: '@/components/StatusCell'\n }\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 condition: (_, siblingData) => siblingData?.status === 'failed',\n components: {\n Field: '@/components/ErrorDisplay'\n }\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","components","Cell","defaultValue","options","label","value","date","displayFormat","readOnly","condition","_","siblingData","status","Field"],"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;gBACbG,YAAY;oBACVC,MAAM;gBACR;YACF;YACAC,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;YACDN,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLkB,MAAM;oBACJC,eAAe;gBACjB;gBACAV,aAAa;YACf;YACAE,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLkB,MAAM;oBACJC,eAAe;gBACjB;gBACAV,aAAa;YACf;QACF;QACA;YACEF,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;gBACbW,UAAU;YACZ;QACF;QACA;YACEb,MAAM;YACNC,MAAM;QACR;QACA;YACED,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAK,cAAc,CAAC;YACfH,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;YACAK,cAAc,EAAE;YAChBH,UAAU;QACZ;QACA;YACEJ,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;gBACbY,WAAW,CAACC,GAAGC,cAAgBA,aAAaC,WAAW;gBACvDZ,YAAY;oBACVa,OAAO;gBACT;YACF;QACF;QACA;YACElB,MAAM;YACNC,MAAM;YACNR,OAAO;gBACLS,aAAa;YACf;YACAK,cAAc,EAAE;YAChBH,UAAU;QACZ;KACD;AACH,EAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export const StatusCell = ({ cellData })=>{
|
|
5
|
+
const getStatusDisplay = (status)=>{
|
|
6
|
+
switch(status){
|
|
7
|
+
case 'pending':
|
|
8
|
+
return {
|
|
9
|
+
icon: '⏳',
|
|
10
|
+
color: '#6B7280',
|
|
11
|
+
label: 'Pending'
|
|
12
|
+
};
|
|
13
|
+
case 'running':
|
|
14
|
+
return {
|
|
15
|
+
icon: '🔄',
|
|
16
|
+
color: '#3B82F6',
|
|
17
|
+
label: 'Running'
|
|
18
|
+
};
|
|
19
|
+
case 'completed':
|
|
20
|
+
return {
|
|
21
|
+
icon: '✅',
|
|
22
|
+
color: '#10B981',
|
|
23
|
+
label: 'Completed'
|
|
24
|
+
};
|
|
25
|
+
case 'failed':
|
|
26
|
+
return {
|
|
27
|
+
icon: '❌',
|
|
28
|
+
color: '#EF4444',
|
|
29
|
+
label: 'Failed'
|
|
30
|
+
};
|
|
31
|
+
case 'cancelled':
|
|
32
|
+
return {
|
|
33
|
+
icon: '⏹️',
|
|
34
|
+
color: '#F59E0B',
|
|
35
|
+
label: 'Cancelled'
|
|
36
|
+
};
|
|
37
|
+
default:
|
|
38
|
+
return {
|
|
39
|
+
icon: '❓',
|
|
40
|
+
color: '#6B7280',
|
|
41
|
+
label: status || 'Unknown'
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const { icon, color, label } = getStatusDisplay(cellData);
|
|
46
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
47
|
+
style: {
|
|
48
|
+
display: 'flex',
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
gap: '8px',
|
|
51
|
+
padding: '4px 8px',
|
|
52
|
+
borderRadius: '6px',
|
|
53
|
+
backgroundColor: `${color}15`,
|
|
54
|
+
border: `1px solid ${color}30`,
|
|
55
|
+
fontSize: '14px',
|
|
56
|
+
fontWeight: '500'
|
|
57
|
+
},
|
|
58
|
+
children: [
|
|
59
|
+
/*#__PURE__*/ _jsx("span", {
|
|
60
|
+
style: {
|
|
61
|
+
fontSize: '16px'
|
|
62
|
+
},
|
|
63
|
+
children: icon
|
|
64
|
+
}),
|
|
65
|
+
/*#__PURE__*/ _jsx("span", {
|
|
66
|
+
style: {
|
|
67
|
+
color
|
|
68
|
+
},
|
|
69
|
+
children: label
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=StatusCell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/StatusCell.tsx"],"sourcesContent":["'use client'\n\nimport React from 'react'\n\ninterface StatusCellProps {\n cellData: string\n}\n\nexport const StatusCell: React.FC<StatusCellProps> = ({ cellData }) => {\n const getStatusDisplay = (status: string) => {\n switch (status) {\n case 'pending':\n return { icon: '⏳', color: '#6B7280', label: 'Pending' }\n case 'running':\n return { icon: '🔄', color: '#3B82F6', label: 'Running' }\n case 'completed':\n return { icon: '✅', color: '#10B981', label: 'Completed' }\n case 'failed':\n return { icon: '❌', color: '#EF4444', label: 'Failed' }\n case 'cancelled':\n return { icon: '⏹️', color: '#F59E0B', label: 'Cancelled' }\n default:\n return { icon: '❓', color: '#6B7280', label: status || 'Unknown' }\n }\n }\n\n const { icon, color, label } = getStatusDisplay(cellData)\n\n return (\n <div style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '4px 8px',\n borderRadius: '6px',\n backgroundColor: `${color}15`,\n border: `1px solid ${color}30`,\n fontSize: '14px',\n fontWeight: '500'\n }}>\n <span style={{ fontSize: '16px' }}>{icon}</span>\n <span style={{ color }}>{label}</span>\n </div>\n )\n}"],"names":["React","StatusCell","cellData","getStatusDisplay","status","icon","color","label","div","style","display","alignItems","gap","padding","borderRadius","backgroundColor","border","fontSize","fontWeight","span"],"mappings":"AAAA;;AAEA,OAAOA,WAAW,QAAO;AAMzB,OAAO,MAAMC,aAAwC,CAAC,EAAEC,QAAQ,EAAE;IAChE,MAAMC,mBAAmB,CAACC;QACxB,OAAQA;YACN,KAAK;gBACH,OAAO;oBAAEC,MAAM;oBAAKC,OAAO;oBAAWC,OAAO;gBAAU;YACzD,KAAK;gBACH,OAAO;oBAAEF,MAAM;oBAAMC,OAAO;oBAAWC,OAAO;gBAAU;YAC1D,KAAK;gBACH,OAAO;oBAAEF,MAAM;oBAAKC,OAAO;oBAAWC,OAAO;gBAAY;YAC3D,KAAK;gBACH,OAAO;oBAAEF,MAAM;oBAAKC,OAAO;oBAAWC,OAAO;gBAAS;YACxD,KAAK;gBACH,OAAO;oBAAEF,MAAM;oBAAMC,OAAO;oBAAWC,OAAO;gBAAY;YAC5D;gBACE,OAAO;oBAAEF,MAAM;oBAAKC,OAAO;oBAAWC,OAAOH,UAAU;gBAAU;QACrE;IACF;IAEA,MAAM,EAAEC,IAAI,EAAEC,KAAK,EAAEC,KAAK,EAAE,GAAGJ,iBAAiBD;IAEhD,qBACE,MAACM;QAAIC,OAAO;YACVC,SAAS;YACTC,YAAY;YACZC,KAAK;YACLC,SAAS;YACTC,cAAc;YACdC,iBAAiB,GAAGT,MAAM,EAAE,CAAC;YAC7BU,QAAQ,CAAC,UAAU,EAAEV,MAAM,EAAE,CAAC;YAC9BW,UAAU;YACVC,YAAY;QACd;;0BACE,KAACC;gBAAKV,OAAO;oBAAEQ,UAAU;gBAAO;0BAAIZ;;0BACpC,KAACc;gBAAKV,OAAO;oBAAEH;gBAAM;0BAAIC;;;;AAG/B,EAAC"}
|