@aglyn/plugins-workflows 1.0.0-beta.221 → 1.0.0-beta.223
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 +22 -14
- package/package.json +12 -12
- package/src/lib/components/automation-step-fields.component.d.ts +16 -16
- package/src/lib/components/automation-step-fields.component.js +146 -12
- package/src/lib/components/automation-step-fields.component.js.map +1 -1
- package/src/lib/components/automation-trigger-conditions.component.d.ts +25 -3
- package/src/lib/components/automation-trigger-conditions.component.js +89 -10
- package/src/lib/components/automation-trigger-conditions.component.js.map +1 -1
- package/src/lib/components/host-actions-card.component.js +126 -84
- package/src/lib/components/host-actions-card.component.js.map +1 -1
- package/src/lib/components/host-webhooks-card.component.js +2 -1
- package/src/lib/components/host-webhooks-card.component.js.map +1 -1
- package/src/lib/components/host-workflows-card.component.js +31 -10
- package/src/lib/components/host-workflows-card.component.js.map +1 -1
- package/src/lib/components/org-automation-editor.component.d.ts +2 -1
- package/src/lib/components/org-automation-editor.component.js +20 -11
- package/src/lib/components/org-automation-editor.component.js.map +1 -1
- package/src/lib/components/org-automations-card.component.js +2 -1
- package/src/lib/components/org-automations-card.component.js.map +1 -1
- package/src/lib/components/run-quota-line.component.d.ts +17 -4
- package/src/lib/components/run-quota-line.component.js +16 -7
- package/src/lib/components/run-quota-line.component.js.map +1 -1
- package/src/lib/components/site-org-automations-panel.component.js +2 -1
- package/src/lib/components/site-org-automations-panel.component.js.map +1 -1
- package/src/lib/components/workflows-console-page.js +18 -7
- package/src/lib/components/workflows-console-page.js.map +1 -1
- package/src/lib/declarations.d.ts +28 -0
- package/src/lib/declarations.js +37 -0
- package/src/lib/declarations.js.map +1 -0
- package/src/lib/declarations.server.js +17 -0
- package/src/lib/declarations.server.js.map +1 -1
- package/src/lib/engine/email-merge.d.ts +69 -0
- package/src/lib/engine/email-merge.js +98 -0
- package/src/lib/engine/email-merge.js.map +1 -0
- package/src/lib/engine/run-event-actions.d.ts +35 -10
- package/src/lib/engine/run-event-actions.js +256 -369
- package/src/lib/engine/run-event-actions.js.map +1 -1
- package/src/lib/engine/run-event-automations.d.ts +1 -1
- package/src/lib/engine/run-event-automations.js.map +1 -1
- package/src/lib/engine/run-event-workflows.d.ts +2 -1
- package/src/lib/engine/run-event-workflows.js +71 -30
- package/src/lib/engine/run-event-workflows.js.map +1 -1
- package/src/lib/engine/run-meter.d.ts +98 -0
- package/src/lib/engine/run-meter.js +121 -0
- package/src/lib/engine/run-meter.js.map +1 -0
- package/src/lib/engine/run-org-automations.d.ts +3 -2
- package/src/lib/engine/run-org-automations.js +17 -12
- package/src/lib/engine/run-org-automations.js.map +1 -1
- package/src/lib/engine/triggered-docs.d.ts +39 -0
- package/src/lib/engine/triggered-docs.js +47 -0
- package/src/lib/engine/triggered-docs.js.map +1 -0
- package/src/lib/engine/workflow-steps.d.ts +1 -1
- package/src/lib/engine/workflow-steps.js +3 -2
- package/src/lib/engine/workflow-steps.js.map +1 -1
- package/src/lib/model/host-actions.d.ts +284 -0
- package/src/lib/model/host-actions.js +316 -0
- package/src/lib/model/host-actions.js.map +1 -0
- package/src/lib/model/org-automations.d.ts +8 -5
- package/src/lib/model/org-automations.js +14 -8
- package/src/lib/model/org-automations.js.map +1 -1
- package/src/lib/model/step-outcomes.d.ts +2 -2
- package/src/lib/model/step-outcomes.js +1 -1
- package/src/lib/model/step-outcomes.js.map +1 -1
- package/src/lib/plugin.js +10 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/server/action-test-run-route.d.ts +3 -2
- package/src/lib/server/action-test-run-route.js +3 -2
- package/src/lib/server/action-test-run-route.js.map +1 -1
- package/src/lib/server/org-automations-routes.d.ts +42 -1
- package/src/lib/server/org-automations-routes.js +120 -72
- package/src/lib/server/org-automations-routes.js.map +1 -1
- package/src/lib/server-automation-drafts.d.ts +2 -2
- package/src/lib/server-automation-drafts.js +11 -7
- package/src/lib/server-automation-drafts.js.map +1 -1
- package/src/lib/server.js +19 -13
- package/src/lib/server.js.map +1 -1
- package/src/lib/testing/stand-in-crm-steps.d.ts +45 -0
- package/src/lib/testing/stand-in-crm-steps.js +97 -0
- package/src/lib/testing/stand-in-crm-steps.js.map +1 -0
- package/src/lib/testing/stand-in-dataset-list.js +11 -3
- package/src/lib/testing/stand-in-dataset-list.js.map +1 -1
- package/src/lib/testing/stand-in-dataset-steps.d.ts +43 -0
- package/src/lib/testing/stand-in-dataset-steps.js +65 -0
- package/src/lib/testing/stand-in-dataset-steps.js.map +1 -0
- package/src/lib/testing/stand-in-person-records.d.ts +35 -0
- package/src/lib/testing/stand-in-person-records.js +54 -0
- package/src/lib/testing/stand-in-person-records.js.map +1 -0
- package/src/lib/testing/stand-in-recipes.d.ts +36 -0
- package/src/lib/testing/stand-in-recipes.js +206 -0
- package/src/lib/testing/stand-in-recipes.js.map +1 -0
- package/src/lib/transfer/org-automations-package.d.ts +54 -0
- package/src/lib/transfer/org-automations-package.js +167 -0
- package/src/lib/transfer/org-automations-package.js.map +1 -0
- package/src/lib/transfer/org-automations-package.server.d.ts +38 -0
- package/src/lib/transfer/org-automations-package.server.js +296 -0
- package/src/lib/transfer/org-automations-package.server.js.map +1 -0
- package/src/lib/usage-axes.js +5 -1
- package/src/lib/usage-axes.js.map +1 -1
- package/src/lib/engine/crm-action-steps.d.ts +0 -142
- package/src/lib/engine/crm-action-steps.js +0 -452
- package/src/lib/engine/crm-action-steps.js.map +0 -1
|
@@ -19,6 +19,22 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
19
19
|
import { ACTION_MAX_CONDITIONS, normalizeTriggerConditions } from "@aglyn/aglyn";
|
|
20
20
|
import { Button, IconButton, MenuItem, Stack, TextField, Typography } from "@mui/material";
|
|
21
21
|
import { placeholderState } from "./automation-step-fields.component.js";
|
|
22
|
+
/**
|
|
23
|
+
* ONE TRIGGER-CONDITION EDITOR FOR EVERY AUTOMATION THAT HAS A TRIGGER.
|
|
24
|
+
*
|
|
25
|
+
* The structured payload conditions (AGL-557), chainable with AND/OR
|
|
26
|
+
* (AGL-565): the no-code sibling of the filter expression — "only when
|
|
27
|
+
* `subscribe` is not empty". A site action and an org automation (AGL-3302)
|
|
28
|
+
* take the same clauses and are judged by the same evaluator, so they are
|
|
29
|
+
* edited by the same rows.
|
|
30
|
+
*/ /**
|
|
31
|
+
* "Form is …" (AGL-3458): a row that picks ONE FORM by id. Stored as the
|
|
32
|
+
* plain clause `formId equals <id>` — the evaluator has no form operator and
|
|
33
|
+
* needs none — and read back into this row, so a condition on which form it
|
|
34
|
+
* was is chosen from the site's forms rather than typed, and survives the
|
|
35
|
+
* form being renamed where `formName equals …` silently stops matching.
|
|
36
|
+
*/ export const FORM_IS_OP = 'formIs';
|
|
37
|
+
/** The payload key a "Form is" row compares. */ export const FORM_ID_FIELD = 'formId';
|
|
22
38
|
export const EMPTY_CONDITION_ROW = {
|
|
23
39
|
op: '',
|
|
24
40
|
field: '',
|
|
@@ -30,11 +46,16 @@ export const EMPTY_CONDITION_ROW = {
|
|
|
30
46
|
* row.
|
|
31
47
|
*/ export function conditionRowsFromTrigger(trigger) {
|
|
32
48
|
const rows = normalizeTriggerConditions(trigger).map((condition)=>{
|
|
33
|
-
var _condition_op, _condition_field,
|
|
34
|
-
|
|
49
|
+
var _condition_value, _condition_op, _condition_field, _condition_value1;
|
|
50
|
+
var _condition_field1;
|
|
51
|
+
return ((_condition_field1 = condition.field) == null ? void 0 : _condition_field1.trim()) === FORM_ID_FIELD && condition.op === 'equals' ? {
|
|
52
|
+
op: FORM_IS_OP,
|
|
53
|
+
field: FORM_ID_FIELD,
|
|
54
|
+
value: (_condition_value = condition.value) != null ? _condition_value : ''
|
|
55
|
+
} : {
|
|
35
56
|
op: (_condition_op = condition.op) != null ? _condition_op : '',
|
|
36
57
|
field: (_condition_field = condition.field) != null ? _condition_field : '',
|
|
37
|
-
value: (
|
|
58
|
+
value: (_condition_value1 = condition.value) != null ? _condition_value1 : ''
|
|
38
59
|
};
|
|
39
60
|
});
|
|
40
61
|
return rows.length ? rows : [
|
|
@@ -47,7 +68,11 @@ export const EMPTY_CONDITION_ROW = {
|
|
|
47
68
|
*/ export function conditionsFromRows(rows, combinator) {
|
|
48
69
|
if (!rows.some((row)=>row.op)) return {};
|
|
49
70
|
return {
|
|
50
|
-
conditions: rows.filter((row)=>row.op).map((row)=>
|
|
71
|
+
conditions: rows.filter((row)=>row.op).map((row)=>row.op === FORM_IS_OP ? {
|
|
72
|
+
field: FORM_ID_FIELD,
|
|
73
|
+
op: 'equals',
|
|
74
|
+
value: row.value.trim()
|
|
75
|
+
} : _extends({
|
|
51
76
|
field: row.field.trim(),
|
|
52
77
|
op: row.op
|
|
53
78
|
}, row.op !== 'notEmpty' ? {
|
|
@@ -56,7 +81,8 @@ export const EMPTY_CONDITION_ROW = {
|
|
|
56
81
|
combinator
|
|
57
82
|
};
|
|
58
83
|
}
|
|
59
|
-
/** The condition rows, "Add condition", and the AND/OR choice once there are two. */ export function TriggerConditionRows({ rows, combinator, onRowsChange, onCombinatorChange }) {
|
|
84
|
+
/** The condition rows, "Add condition", and the AND/OR choice once there are two. */ export function TriggerConditionRows({ rows, combinator, onRowsChange, onCombinatorChange, formOptions }) {
|
|
85
|
+
const offerForms = Boolean(formOptions) || rows.some((row)=>row.op === FORM_IS_OP);
|
|
60
86
|
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
61
87
|
children: [
|
|
62
88
|
rows.map((row, index)=>/*#__PURE__*/ _jsxs(Stack, {
|
|
@@ -75,9 +101,25 @@ export const EMPTY_CONDITION_ROW = {
|
|
|
75
101
|
select: true,
|
|
76
102
|
label: index === 0 ? 'Only run when' : 'Condition',
|
|
77
103
|
value: row.op,
|
|
78
|
-
onChange: (event)=>onRowsChange((previous)=>previous.map((previousRow, index2)=>
|
|
79
|
-
|
|
80
|
-
|
|
104
|
+
onChange: (event)=>onRowsChange((previous)=>previous.map((previousRow, index2)=>{
|
|
105
|
+
if (index2 !== index) return previousRow;
|
|
106
|
+
const op = event.target.value;
|
|
107
|
+
// Into and out of "Form is", the field is the form's id or
|
|
108
|
+
// nothing — never a leftover the author did not type.
|
|
109
|
+
if (op === FORM_IS_OP) return {
|
|
110
|
+
op,
|
|
111
|
+
field: FORM_ID_FIELD,
|
|
112
|
+
value: ''
|
|
113
|
+
};
|
|
114
|
+
if (previousRow.op === FORM_IS_OP) return {
|
|
115
|
+
op,
|
|
116
|
+
field: '',
|
|
117
|
+
value: ''
|
|
118
|
+
};
|
|
119
|
+
return _extends({}, previousRow, {
|
|
120
|
+
op
|
|
121
|
+
});
|
|
122
|
+
})),
|
|
81
123
|
size: "small",
|
|
82
124
|
sx: {
|
|
83
125
|
minWidth: 180
|
|
@@ -98,10 +140,47 @@ export const EMPTY_CONDITION_ROW = {
|
|
|
98
140
|
/*#__PURE__*/ _jsx(MenuItem, {
|
|
99
141
|
value: "contains",
|
|
100
142
|
children: 'A field contains…'
|
|
101
|
-
})
|
|
143
|
+
}),
|
|
144
|
+
offerForms ? /*#__PURE__*/ _jsx(MenuItem, {
|
|
145
|
+
value: FORM_IS_OP,
|
|
146
|
+
children: 'Form is…'
|
|
147
|
+
}) : null
|
|
102
148
|
]
|
|
103
149
|
}),
|
|
104
|
-
row.op ? /*#__PURE__*/
|
|
150
|
+
row.op === FORM_IS_OP ? formOptions ? /*#__PURE__*/ _jsxs(TextField, {
|
|
151
|
+
select: true,
|
|
152
|
+
label: "Form",
|
|
153
|
+
value: row.value,
|
|
154
|
+
error: !row.value,
|
|
155
|
+
helperText: row.value ? undefined : 'Pick the form',
|
|
156
|
+
onChange: (event)=>onRowsChange((previous)=>previous.map((previousRow, index2)=>index2 === index ? _extends({}, previousRow, {
|
|
157
|
+
value: event.target.value
|
|
158
|
+
}) : previousRow)),
|
|
159
|
+
size: "small",
|
|
160
|
+
sx: {
|
|
161
|
+
flex: 1
|
|
162
|
+
},
|
|
163
|
+
children: [
|
|
164
|
+
row.value && !formOptions.some((form)=>form.id === row.value) ? /*#__PURE__*/ _jsx(MenuItem, {
|
|
165
|
+
value: row.value,
|
|
166
|
+
children: `A form that is gone (${row.value})`
|
|
167
|
+
}) : null,
|
|
168
|
+
formOptions.map((form)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
169
|
+
value: form.id,
|
|
170
|
+
children: form.name
|
|
171
|
+
}, form.id))
|
|
172
|
+
]
|
|
173
|
+
}) : /*#__PURE__*/ _jsx(TextField, {
|
|
174
|
+
label: "Form id",
|
|
175
|
+
value: row.value,
|
|
176
|
+
onChange: (event)=>onRowsChange((previous)=>previous.map((previousRow, index2)=>index2 === index ? _extends({}, previousRow, {
|
|
177
|
+
value: event.target.value
|
|
178
|
+
}) : previousRow)),
|
|
179
|
+
size: "small",
|
|
180
|
+
sx: {
|
|
181
|
+
flex: 1
|
|
182
|
+
}
|
|
183
|
+
}) : row.op ? /*#__PURE__*/ _jsx(TextField, {
|
|
105
184
|
label: "Field",
|
|
106
185
|
placeholder: "subscribe",
|
|
107
186
|
value: row.field,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/automation-trigger-conditions.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n ACTION_MAX_CONDITIONS,\n type HostActionTrigger,\n type HostActionTriggerCondition,\n normalizeTriggerConditions,\n type TriggerCombinator,\n type TriggerConditionOp,\n} from '@aglyn/aglyn'\nimport {\n Button,\n IconButton,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { placeholderState } from './automation-step-fields.component'\n\n/**\n * ONE TRIGGER-CONDITION EDITOR FOR EVERY AUTOMATION THAT HAS A TRIGGER.\n *\n * The structured payload conditions (AGL-557), chainable with AND/OR\n * (AGL-565): the no-code sibling of the filter expression — \"only when\n * `subscribe` is not empty\". A site action and an org automation (AGL-3302)\n * take the same clauses and are judged by the same evaluator, so they are\n * edited by the same rows.\n */\n\n/** One editable condition row; a lone row with an empty op means \"always run\". */\nexport interface ConditionRowDraft {\n op: '' | TriggerConditionOp\n field: string\n value: string\n}\n\nexport const EMPTY_CONDITION_ROW: ConditionRowDraft = {\n op: '',\n field: '',\n value: '',\n}\n\n/**\n * A stored trigger's clauses as editor rows. A legacy single-condition trigger\n * normalizes to one row, and a trigger with none opens on the lone \"always\"\n * row.\n */\nexport function conditionRowsFromTrigger(\n trigger:\n | Pick<HostActionTrigger, 'condition' | 'conditions'>\n | null\n | undefined,\n): ConditionRowDraft[] {\n const rows = normalizeTriggerConditions(trigger).map(\n (condition): ConditionRowDraft => ({\n op: condition.op ?? '',\n field: condition.field ?? '',\n value: condition.value ?? '',\n }),\n )\n return rows.length ? rows : [EMPTY_CONDITION_ROW]\n}\n\n/**\n * The rows as the stored clause list, or nothing when every row says\n * \"always\". Blank fields are kept, so the validator names what is missing.\n */\nexport function conditionsFromRows(\n rows: readonly ConditionRowDraft[],\n combinator: TriggerCombinator,\n): { conditions?: HostActionTriggerCondition[]; combinator?: TriggerCombinator } {\n if (!rows.some((row) => row.op)) return {}\n return {\n conditions: rows\n .filter((row) => row.op)\n .map((row) => ({\n field: row.field.trim(),\n op: row.op as TriggerConditionOp,\n ...(row.op !== 'notEmpty' ? { value: row.value.trim() } : {}),\n })),\n combinator,\n }\n}\n\nexport interface TriggerConditionRowsProps {\n rows: readonly ConditionRowDraft[]\n combinator: TriggerCombinator\n /** Replaces the rows, from the rows as they stand. */\n onRowsChange: (\n update: (previous: ConditionRowDraft[]) => ConditionRowDraft[],\n ) => void\n onCombinatorChange: (combinator: TriggerCombinator) => void\n}\n\n/** The condition rows, \"Add condition\", and the AND/OR choice once there are two. */\nexport function TriggerConditionRows({\n rows,\n combinator,\n onRowsChange,\n onCombinatorChange,\n}: TriggerConditionRowsProps) {\n return (\n <>\n {rows.map((row, index) => (\n <Stack\n key={index}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n {index > 0 ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {combinator === 'or' ? 'or' : 'and'}\n </Typography>\n ) : null}\n <TextField\n select\n label={index === 0 ? 'Only run when' : 'Condition'}\n value={row.op}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index\n ? {\n ...previousRow,\n op: event.target.value as ConditionRowDraft['op'],\n }\n : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ minWidth: 180 }}\n >\n {/* \"Always\" only exists while this is the sole row —\n multi-row chains clear by removing rows instead. */}\n {rows.length === 1 ? (\n <MenuItem value=\"\">{'Always (no condition)'}</MenuItem>\n ) : null}\n <MenuItem value=\"notEmpty\">{'A field is not empty'}</MenuItem>\n <MenuItem value=\"equals\">{'A field equals…'}</MenuItem>\n <MenuItem value=\"contains\">{'A field contains…'}</MenuItem>\n </TextField>\n {row.op ? (\n <TextField\n label=\"Field\"\n placeholder=\"subscribe\"\n value={row.field}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index\n ? { ...previousRow, field: event.target.value }\n : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n ) : null}\n {row.op === 'equals' || row.op === 'contains' ? (\n <TextField\n label=\"Value\"\n placeholder=\"Yes\"\n {...placeholderState(\n row.value,\n 'Replace the placeholder with the value to match',\n )}\n value={row.value}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index\n ? { ...previousRow, value: event.target.value }\n : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n ) : null}\n {rows.length > 1 ? (\n <IconButton\n size=\"small\"\n aria-label=\"remove condition\"\n onClick={() =>\n onRowsChange((previous) =>\n previous.length > 1\n ? previous.filter((_, index2) => index2 !== index)\n : [EMPTY_CONDITION_ROW],\n )\n }\n >\n {'×'}\n </IconButton>\n ) : null}\n </Stack>\n ))}\n {rows.every((row) => row.op) ? (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button\n size=\"small\"\n disabled={rows.length >= ACTION_MAX_CONDITIONS}\n onClick={() =>\n onRowsChange((previous) => [\n ...previous,\n // New rows start on the simplest operator so the field input\n // is immediately visible.\n { op: 'notEmpty', field: '', value: '' },\n ])\n }\n >\n {'Add condition'}\n </Button>\n {rows.length >= 2 ? (\n // AND/OR combinator (AGL-565); applies to every row.\n <TextField\n select\n label=\"Match\"\n value={combinator}\n onChange={(event) =>\n onCombinatorChange(event.target.value as TriggerCombinator)\n }\n size=\"small\"\n sx={{ minWidth: 220 }}\n >\n <MenuItem value=\"and\">{'All conditions match (AND)'}</MenuItem>\n <MenuItem value=\"or\">{'Any condition matches (OR)'}</MenuItem>\n </TextField>\n ) : null}\n </Stack>\n ) : null}\n </>\n )\n}\nTriggerConditionRows.displayName = 'TriggerConditionRows'\n"],"names":["ACTION_MAX_CONDITIONS","normalizeTriggerConditions","Button","IconButton","MenuItem","Stack","TextField","Typography","placeholderState","EMPTY_CONDITION_ROW","op","field","value","conditionRowsFromTrigger","trigger","rows","map","condition","length","conditionsFromRows","combinator","some","row","conditions","filter","trim","TriggerConditionRows","onRowsChange","onCombinatorChange","index","direction","spacing","sx","alignItems","variant","color","select","label","onChange","event","previous","previousRow","index2","target","size","minWidth","placeholder","flex","aria-label","onClick","_","every","disabled","displayName"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/workflows/src/lib/components/automation-trigger-conditions.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport {\n ACTION_MAX_CONDITIONS,\n normalizeTriggerConditions,\n type TriggerCombinator,\n type TriggerConditionOp,\n} from '@aglyn/aglyn'\nimport {\n Button,\n IconButton,\n MenuItem,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { placeholderState } from './automation-step-fields.component'\nimport type { HostActionTrigger, HostActionTriggerCondition } from '../model/host-actions'\n\n/**\n * ONE TRIGGER-CONDITION EDITOR FOR EVERY AUTOMATION THAT HAS A TRIGGER.\n *\n * The structured payload conditions (AGL-557), chainable with AND/OR\n * (AGL-565): the no-code sibling of the filter expression — \"only when\n * `subscribe` is not empty\". A site action and an org automation (AGL-3302)\n * take the same clauses and are judged by the same evaluator, so they are\n * edited by the same rows.\n */\n\n/**\n * \"Form is …\" (AGL-3458): a row that picks ONE FORM by id. Stored as the\n * plain clause `formId equals <id>` — the evaluator has no form operator and\n * needs none — and read back into this row, so a condition on which form it\n * was is chosen from the site's forms rather than typed, and survives the\n * form being renamed where `formName equals …` silently stops matching.\n */\nexport const FORM_IS_OP = 'formIs'\n\n/** The payload key a \"Form is\" row compares. */\nexport const FORM_ID_FIELD = 'formId'\n\n/** One editable condition row; a lone row with an empty op means \"always run\". */\nexport interface ConditionRowDraft {\n op: '' | TriggerConditionOp | typeof FORM_IS_OP\n field: string\n value: string\n}\n\n/** A form a \"Form is\" row can pick. */\nexport interface ConditionFormOption {\n id: string\n name: string\n}\n\nexport const EMPTY_CONDITION_ROW: ConditionRowDraft = {\n op: '',\n field: '',\n value: '',\n}\n\n/**\n * A stored trigger's clauses as editor rows. A legacy single-condition trigger\n * normalizes to one row, and a trigger with none opens on the lone \"always\"\n * row.\n */\nexport function conditionRowsFromTrigger(\n trigger:\n | Pick<HostActionTrigger, 'condition' | 'conditions'>\n | null\n | undefined,\n): ConditionRowDraft[] {\n const rows = normalizeTriggerConditions(trigger).map(\n (condition): ConditionRowDraft =>\n condition.field?.trim() === FORM_ID_FIELD && condition.op === 'equals'\n ? { op: FORM_IS_OP, field: FORM_ID_FIELD, value: condition.value ?? '' }\n : {\n op: condition.op ?? '',\n field: condition.field ?? '',\n value: condition.value ?? '',\n },\n )\n return rows.length ? rows : [EMPTY_CONDITION_ROW]\n}\n\n/**\n * The rows as the stored clause list, or nothing when every row says\n * \"always\". Blank fields are kept, so the validator names what is missing.\n */\nexport function conditionsFromRows(\n rows: readonly ConditionRowDraft[],\n combinator: TriggerCombinator,\n): { conditions?: HostActionTriggerCondition[]; combinator?: TriggerCombinator } {\n if (!rows.some((row) => row.op)) return {}\n return {\n conditions: rows\n .filter((row) => row.op)\n .map((row) =>\n row.op === FORM_IS_OP\n ? { field: FORM_ID_FIELD, op: 'equals' as const, value: row.value.trim() }\n : {\n field: row.field.trim(),\n op: row.op as TriggerConditionOp,\n ...(row.op !== 'notEmpty' ? { value: row.value.trim() } : {}),\n },\n ),\n combinator,\n }\n}\n\nexport interface TriggerConditionRowsProps {\n rows: readonly ConditionRowDraft[]\n combinator: TriggerCombinator\n /** Replaces the rows, from the rows as they stand. */\n onRowsChange: (\n update: (previous: ConditionRowDraft[]) => ConditionRowDraft[],\n ) => void\n onCombinatorChange: (combinator: TriggerCombinator) => void\n /**\n * The site's forms, for a \"Form is\" row — given only where the trigger's\n * event carries the form's id. Absent, the row is offered only to show a\n * stored one, and its form is typed by id.\n */\n formOptions?: readonly ConditionFormOption[]\n}\n\n/** The condition rows, \"Add condition\", and the AND/OR choice once there are two. */\nexport function TriggerConditionRows({\n rows,\n combinator,\n onRowsChange,\n onCombinatorChange,\n formOptions,\n}: TriggerConditionRowsProps) {\n const offerForms = Boolean(formOptions) || rows.some((row) => row.op === FORM_IS_OP)\n return (\n <>\n {rows.map((row, index) => (\n <Stack\n key={index}\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'center' }}\n >\n {index > 0 ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {combinator === 'or' ? 'or' : 'and'}\n </Typography>\n ) : null}\n <TextField\n select\n label={index === 0 ? 'Only run when' : 'Condition'}\n value={row.op}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) => {\n if (index2 !== index) return previousRow\n const op = event.target.value as ConditionRowDraft['op']\n // Into and out of \"Form is\", the field is the form's id or\n // nothing — never a leftover the author did not type.\n if (op === FORM_IS_OP) return { op, field: FORM_ID_FIELD, value: '' }\n if (previousRow.op === FORM_IS_OP) return { op, field: '', value: '' }\n return { ...previousRow, op }\n }),\n )\n }\n size=\"small\"\n sx={{ minWidth: 180 }}\n >\n {/* \"Always\" only exists while this is the sole row —\n multi-row chains clear by removing rows instead. */}\n {rows.length === 1 ? (\n <MenuItem value=\"\">{'Always (no condition)'}</MenuItem>\n ) : null}\n <MenuItem value=\"notEmpty\">{'A field is not empty'}</MenuItem>\n <MenuItem value=\"equals\">{'A field equals…'}</MenuItem>\n <MenuItem value=\"contains\">{'A field contains…'}</MenuItem>\n {offerForms ? <MenuItem value={FORM_IS_OP}>{'Form is…'}</MenuItem> : null}\n </TextField>\n {row.op === FORM_IS_OP ? (\n formOptions ? (\n <TextField\n select\n label=\"Form\"\n value={row.value}\n error={!row.value}\n helperText={row.value ? undefined : 'Pick the form'}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index ? { ...previousRow, value: event.target.value } : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ flex: 1 }}\n >\n {/* A stored id that is no longer among the site's live forms\n stays visible, so a save does not silently drop it. */}\n {row.value && !formOptions.some((form) => form.id === row.value) ? (\n <MenuItem value={row.value}>{`A form that is gone (${row.value})`}</MenuItem>\n ) : null}\n {formOptions.map((form) => (\n <MenuItem key={form.id} value={form.id}>\n {form.name}\n </MenuItem>\n ))}\n </TextField>\n ) : (\n <TextField\n label=\"Form id\"\n value={row.value}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index ? { ...previousRow, value: event.target.value } : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n )\n ) : row.op ? (\n <TextField\n label=\"Field\"\n placeholder=\"subscribe\"\n value={row.field}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index\n ? { ...previousRow, field: event.target.value }\n : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n ) : null}\n {row.op === 'equals' || row.op === 'contains' ? (\n <TextField\n label=\"Value\"\n placeholder=\"Yes\"\n {...placeholderState(\n row.value,\n 'Replace the placeholder with the value to match',\n )}\n value={row.value}\n onChange={(event) =>\n onRowsChange((previous) =>\n previous.map((previousRow, index2) =>\n index2 === index\n ? { ...previousRow, value: event.target.value }\n : previousRow,\n ),\n )\n }\n size=\"small\"\n sx={{ flex: 1 }}\n />\n ) : null}\n {rows.length > 1 ? (\n <IconButton\n size=\"small\"\n aria-label=\"remove condition\"\n onClick={() =>\n onRowsChange((previous) =>\n previous.length > 1\n ? previous.filter((_, index2) => index2 !== index)\n : [EMPTY_CONDITION_ROW],\n )\n }\n >\n {'×'}\n </IconButton>\n ) : null}\n </Stack>\n ))}\n {rows.every((row) => row.op) ? (\n <Stack direction=\"row\" spacing={1} sx={{ alignItems: 'center' }}>\n <Button\n size=\"small\"\n disabled={rows.length >= ACTION_MAX_CONDITIONS}\n onClick={() =>\n onRowsChange((previous) => [\n ...previous,\n // New rows start on the simplest operator so the field input\n // is immediately visible.\n { op: 'notEmpty', field: '', value: '' },\n ])\n }\n >\n {'Add condition'}\n </Button>\n {rows.length >= 2 ? (\n // AND/OR combinator (AGL-565); applies to every row.\n <TextField\n select\n label=\"Match\"\n value={combinator}\n onChange={(event) =>\n onCombinatorChange(event.target.value as TriggerCombinator)\n }\n size=\"small\"\n sx={{ minWidth: 220 }}\n >\n <MenuItem value=\"and\">{'All conditions match (AND)'}</MenuItem>\n <MenuItem value=\"or\">{'Any condition matches (OR)'}</MenuItem>\n </TextField>\n ) : null}\n </Stack>\n ) : null}\n </>\n )\n}\nTriggerConditionRows.displayName = 'TriggerConditionRows'\n"],"names":["ACTION_MAX_CONDITIONS","normalizeTriggerConditions","Button","IconButton","MenuItem","Stack","TextField","Typography","placeholderState","FORM_IS_OP","FORM_ID_FIELD","EMPTY_CONDITION_ROW","op","field","value","conditionRowsFromTrigger","trigger","rows","map","condition","trim","length","conditionsFromRows","combinator","some","row","conditions","filter","TriggerConditionRows","onRowsChange","onCombinatorChange","formOptions","offerForms","Boolean","index","direction","spacing","sx","alignItems","variant","color","select","label","onChange","event","previous","previousRow","index2","target","size","minWidth","error","helperText","undefined","flex","form","id","name","placeholder","aria-label","onClick","_","every","disabled","displayName"],"mappings":"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"}
|