@arbidocs/blocks 0.4.76 → 0.4.77
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/dist/agents/index.cjs +331 -255
- package/dist/agents/index.js +2 -2
- package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
- package/dist/agents/tasks/WorkflowThreadStrip.d.ts +7 -1
- package/dist/agents/workflows/SchemaForm.d.ts +6 -1
- package/dist/agents/workflows/StepParts.d.ts +109 -0
- package/dist/agents/workflows/WorkflowRunner.d.ts +11 -2
- package/dist/agents/workflows/index.d.ts +3 -2
- package/dist/agents/workflows/planSteps.d.ts +8 -1
- package/dist/agents/workflows/run.d.ts +61 -8
- package/dist/agents/workflows/types.d.ts +133 -4
- package/dist/agents/workflows/useWorkflowPreview.d.ts +2 -1
- package/dist/agents/workflows/useWorkflowView.d.ts +19 -0
- package/dist/chat/ChatPage.d.ts +1 -1
- package/dist/chat/WorkflowStepChip.d.ts +24 -0
- package/dist/chat/chat-page-types.d.ts +4 -0
- package/dist/chat/index.cjs +130 -122
- package/dist/chat/index.d.ts +1 -0
- package/dist/chat/index.js +2 -2
- package/dist/{chunk-22P5KNIM.js → chunk-34UW6XUQ.js} +928 -38
- package/dist/chunk-34UW6XUQ.js.map +1 -0
- package/dist/{chunk-VYRKO3XU.cjs → chunk-3XR3IEGU.cjs} +944 -35
- package/dist/chunk-3XR3IEGU.cjs.map +1 -0
- package/dist/{chunk-ZWA7UUZL.cjs → chunk-7YUFMNFW.cjs} +2 -54
- package/dist/chunk-7YUFMNFW.cjs.map +1 -0
- package/dist/chunk-A24C6BNA.js +92 -0
- package/dist/chunk-A24C6BNA.js.map +1 -0
- package/dist/chunk-AINNADMT.cjs +62 -0
- package/dist/chunk-AINNADMT.cjs.map +1 -0
- package/dist/{chunk-7CVF3DK2.cjs → chunk-EKIUMNCN.cjs} +5 -5
- package/dist/{chunk-7CVF3DK2.cjs.map → chunk-EKIUMNCN.cjs.map} +1 -1
- package/dist/chunk-FE4ULGOR.js +151 -0
- package/dist/chunk-FE4ULGOR.js.map +1 -0
- package/dist/chunk-FT5FFXSJ.js +60 -0
- package/dist/chunk-FT5FFXSJ.js.map +1 -0
- package/dist/{chunk-HITAN7JF.cjs → chunk-GTXOV7IJ.cjs} +4 -4
- package/dist/{chunk-HITAN7JF.cjs.map → chunk-GTXOV7IJ.cjs.map} +1 -1
- package/dist/{chunk-TKB7TVMW.js → chunk-HEVVT6IT.js} +78 -14
- package/dist/chunk-HEVVT6IT.js.map +1 -0
- package/dist/{chunk-IPGKTUF7.cjs → chunk-HOD6OM7L.cjs} +68 -3
- package/dist/chunk-HOD6OM7L.cjs.map +1 -0
- package/dist/{chunk-7FKARMA3.cjs → chunk-JFUN4D7D.cjs} +101 -37
- package/dist/chunk-JFUN4D7D.cjs.map +1 -0
- package/dist/{chunk-UIWLDSTF.js → chunk-NIP5BOP7.js} +68 -5
- package/dist/chunk-NIP5BOP7.js.map +1 -0
- package/dist/{chunk-MK6NJQGF.js → chunk-OEM5ARVM.js} +3 -3
- package/dist/{chunk-MK6NJQGF.js.map → chunk-OEM5ARVM.js.map} +1 -1
- package/dist/{chunk-5EBGRG3X.js → chunk-OPA2Y6YZ.js} +3 -54
- package/dist/chunk-OPA2Y6YZ.js.map +1 -0
- package/dist/chunk-TZR36PPP.cjs +95 -0
- package/dist/chunk-TZR36PPP.cjs.map +1 -0
- package/dist/{chunk-WJEKRSPH.js → chunk-UEU23PTW.js} +3 -3
- package/dist/{chunk-WJEKRSPH.js.map → chunk-UEU23PTW.js.map} +1 -1
- package/dist/chunk-ZVBPRMHJ.cjs +153 -0
- package/dist/chunk-ZVBPRMHJ.cjs.map +1 -0
- package/dist/connect/docx.cjs +10 -88
- package/dist/connect/docx.cjs.map +1 -1
- package/dist/connect/docx.js +6 -86
- package/dist/connect/docx.js.map +1 -1
- package/dist/connect/index.cjs +293 -30
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +278 -15
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/ConnectedWorkflowRunner.d.ts +16 -2
- package/dist/connection/WorkflowRunnerDialogs.d.ts +37 -0
- package/dist/connection/useWorkflowThread.d.ts +12 -0
- package/dist/document-tools/index.cjs +7 -143
- package/dist/document-tools/index.cjs.map +1 -1
- package/dist/document-tools/index.js +5 -144
- package/dist/document-tools/index.js.map +1 -1
- package/dist/docx/index.cjs +18 -17
- package/dist/docx/index.cjs.map +1 -1
- package/dist/docx/index.js +3 -2
- package/dist/docx/index.js.map +1 -1
- package/dist/index.cjs +467 -383
- package/dist/index.js +5 -5
- package/dist/studio/index.cjs +3 -3
- package/dist/studio/index.js +2 -2
- package/dist/workflow-canvas/StepActionSettings.d.ts +132 -0
- package/dist/workflow-canvas/StepInspector.d.ts +25 -2
- package/dist/workflow-canvas/WorkflowBuilder.d.ts +11 -3
- package/dist/workflow-canvas/WorkflowCanvas.d.ts +27 -2
- package/dist/workflow-canvas/edit.d.ts +9 -1
- package/dist/workflow-canvas/index.cjs +879 -99
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.js +846 -66
- package/dist/workflow-canvas/index.js.map +1 -1
- package/package.json +4 -4
- package/src/workflow-canvas/canvas.css +9 -0
- package/dist/chunk-22P5KNIM.js.map +0 -1
- package/dist/chunk-5EBGRG3X.js.map +0 -1
- package/dist/chunk-7FKARMA3.cjs.map +0 -1
- package/dist/chunk-IPGKTUF7.cjs.map +0 -1
- package/dist/chunk-TKB7TVMW.js.map +0 -1
- package/dist/chunk-UIWLDSTF.js.map +0 -1
- package/dist/chunk-VYRKO3XU.cjs.map +0 -1
- package/dist/chunk-ZWA7UUZL.cjs.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useConnection } from '../chunk-OYMWV45N.js';
|
|
3
|
-
import { workflowWhen, isoToLocalInput, describeRRule, RecurrenceBuilder, AgentSelect, useWorkflowPreview, localInputToIso } from '../chunk-
|
|
3
|
+
import { workflowWhen, isoToLocalInput, describeRRule, RecurrenceBuilder, AgentSelect, useWorkflowPreview, localInputToIso } from '../chunk-HEVVT6IT.js';
|
|
4
4
|
import '../chunk-CKB64Z4R.js';
|
|
5
5
|
import '../chunk-P6GHJSLR.js';
|
|
6
|
-
import { workflowSteps, dependsOn, stepLevels, isIncompleteSignal, stepDependencies,
|
|
6
|
+
import { workflowSteps, dependsOn, stepLevels, isIncompleteSignal, runFields, upstreamSteps, stepDependencies, canAssign, fromPlanSteps, layoutFromPlanSteps, validateWorkflowGraph, stepConfigProblems, WorkflowRunner, skillToWorkflow, assigneeName, orderSteps, toPlanSteps } from '../chunk-34UW6XUQ.js';
|
|
7
7
|
import '../chunk-4WWM3GQ5.js';
|
|
8
8
|
import '../chunk-RFXJYIDV.js';
|
|
9
9
|
import '../chunk-DPLRHEJZ.js';
|
|
@@ -24,13 +24,23 @@ import '../chunk-TX2ZICS7.js';
|
|
|
24
24
|
import '../chunk-7F6CBP3Z.js';
|
|
25
25
|
import '../chunk-VUNV25KB.js';
|
|
26
26
|
import { useMemo, useState, useEffect, useCallback, useRef } from 'react';
|
|
27
|
-
import { useWorkflows, useSkills, useAgents, useConversations, useCreateWorkflow, useUpdateWorkflow, useRunWorkflow } from '@arbidocs/react';
|
|
27
|
+
import { useWorkspaceUsers, useTags, useDocuments, useWorkflows, useSkills, useAgents, useConversations, useCreateWorkflow, useUpdateWorkflow, useRunWorkflow } from '@arbidocs/react';
|
|
28
28
|
import { Label, Input, cn, Button, Textarea, Checkbox, Popover, PopoverTrigger, PopoverContent } from '@arbidocs/react/ui';
|
|
29
|
-
import { X, Plus, Trash2, Maximize, ClipboardCheck, Bot, Upload, FileInput, PencilRuler, Eye, LayoutGrid, Settings2, Play, Loader2, Save, Zap, GitBranch, Check, AlertTriangle, MinusCircle } from 'lucide-react';
|
|
29
|
+
import { X, Plus, Trash2, Maximize, Table2, Mail, PenLine, ClipboardCheck, Bot, Upload, FileInput, PencilRuler, Eye, LayoutGrid, Settings2, Play, Loader2, Save, Zap, GitBranch, FilePenLine, UserRound, Hourglass, Check, AlertTriangle, MinusCircle } from 'lucide-react';
|
|
30
30
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
31
31
|
import { MarkerType, applyNodeChanges, ReactFlow, Background, BackgroundVariant, Controls, ControlButton, MiniMap, Handle, Position } from '@xyflow/react';
|
|
32
32
|
|
|
33
33
|
// src/workflow-canvas/edit.ts
|
|
34
|
+
var WORKFLOW_STEP_KINDS = [
|
|
35
|
+
"form",
|
|
36
|
+
"upload",
|
|
37
|
+
"agent",
|
|
38
|
+
"review",
|
|
39
|
+
"sign",
|
|
40
|
+
"email_draft",
|
|
41
|
+
"tabular_review"
|
|
42
|
+
];
|
|
43
|
+
var stepKindOf = (step) => step.kind === "action" ? step.action.type : step.kind;
|
|
34
44
|
function newSteppedWorkflow(id, title) {
|
|
35
45
|
return {
|
|
36
46
|
id,
|
|
@@ -63,7 +73,10 @@ var DEFAULT_TITLES = {
|
|
|
63
73
|
form: "Details",
|
|
64
74
|
upload: "Upload files",
|
|
65
75
|
agent: "Agent step",
|
|
66
|
-
review: "Review"
|
|
76
|
+
review: "Review",
|
|
77
|
+
sign: "Sign",
|
|
78
|
+
email_draft: "Email draft",
|
|
79
|
+
tabular_review: "Tabular review"
|
|
67
80
|
};
|
|
68
81
|
function blankStep(kind, id, title) {
|
|
69
82
|
switch (kind) {
|
|
@@ -75,6 +88,22 @@ function blankStep(kind, id, title) {
|
|
|
75
88
|
return { id, kind, title };
|
|
76
89
|
case "review":
|
|
77
90
|
return { id, kind, title, instructions: "" };
|
|
91
|
+
case "sign":
|
|
92
|
+
return { id, kind: "action", title, action: { type: "sign", signers: [] } };
|
|
93
|
+
case "email_draft":
|
|
94
|
+
return {
|
|
95
|
+
id,
|
|
96
|
+
kind: "action",
|
|
97
|
+
title,
|
|
98
|
+
action: { type: "email_draft", to: [], subject: "", body: "" }
|
|
99
|
+
};
|
|
100
|
+
case "tabular_review":
|
|
101
|
+
return {
|
|
102
|
+
id,
|
|
103
|
+
kind: "action",
|
|
104
|
+
title,
|
|
105
|
+
action: { type: "tabular_review", tags: [], documents: "run_uploads" }
|
|
106
|
+
};
|
|
78
107
|
}
|
|
79
108
|
}
|
|
80
109
|
function addStep(workflow, kind, options = {}) {
|
|
@@ -139,14 +168,49 @@ function renameInput(workflow, from, to) {
|
|
|
139
168
|
return {
|
|
140
169
|
...s,
|
|
141
170
|
with: s.with ? Object.fromEntries(Object.entries(s.with).map(([k, v]) => [k, renameIn(v, from, to)])) : s.with,
|
|
142
|
-
run: s.run?.kind === "prompt" ? { ...s.run, promptTemplate: renameIn(s.run.promptTemplate, from, to) } : s.run
|
|
171
|
+
run: s.run?.kind === "prompt" ? { ...s.run, promptTemplate: renameIn(s.run.promptTemplate, from, to) } : s.run,
|
|
172
|
+
...s.editDocument ? { editDocument: renameRef(s.editDocument, from, to) } : {}
|
|
143
173
|
};
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
174
|
+
const assignee = s.assignee && renamePerson(s.assignee, from, to);
|
|
175
|
+
const base = assignee ? { ...s, assignee } : s;
|
|
176
|
+
if (base.kind === "review" && base.instructions)
|
|
177
|
+
return { ...base, instructions: renameIn(base.instructions, from, to) };
|
|
178
|
+
if (base.kind === "action") {
|
|
179
|
+
const a = base.action;
|
|
180
|
+
if (a.type === "sign")
|
|
181
|
+
return {
|
|
182
|
+
...base,
|
|
183
|
+
action: {
|
|
184
|
+
...a,
|
|
185
|
+
document: a.document && renameRef(a.document, from, to),
|
|
186
|
+
signers: a.signers.map((x) => renamePerson(x, from, to)),
|
|
187
|
+
...a.message ? { message: renameIn(a.message, from, to) } : {}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
if (a.type === "email_draft")
|
|
191
|
+
return {
|
|
192
|
+
...base,
|
|
193
|
+
action: {
|
|
194
|
+
...a,
|
|
195
|
+
to: a.to.map((t) => renameIn(t, from, to)),
|
|
196
|
+
...a.cc ? { cc: a.cc.map((t) => renameIn(t, from, to)) } : {},
|
|
197
|
+
subject: renameIn(a.subject, from, to),
|
|
198
|
+
body: renameIn(a.body, from, to),
|
|
199
|
+
...a.attachments ? { attachments: a.attachments.map((r) => renameRef(r, from, to)) } : {}
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
if (Array.isArray(a.documents))
|
|
203
|
+
return {
|
|
204
|
+
...base,
|
|
205
|
+
action: { ...a, documents: a.documents.map((r) => renameRef(r, from, to)) }
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return base;
|
|
147
209
|
});
|
|
148
210
|
return withSteps(workflow, steps);
|
|
149
211
|
}
|
|
212
|
+
var renamePerson = (a, from, to) => "input" in a && a.input === from ? { input: to } : a;
|
|
213
|
+
var renameRef = (r, from, to) => "input" in r && r.input === from ? { input: to } : r;
|
|
150
214
|
function moveStep(workflow, id, position) {
|
|
151
215
|
return withSteps(workflow, workflowSteps(workflow), { ...layoutOf(workflow), [id]: position });
|
|
152
216
|
}
|
|
@@ -381,6 +445,537 @@ function SignalsEditor({
|
|
|
381
445
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: l.hint })
|
|
382
446
|
] });
|
|
383
447
|
}
|
|
448
|
+
var DEFAULT_STEP_ACTION_SETTINGS_LABELS = {
|
|
449
|
+
assignee: "Who does it",
|
|
450
|
+
assigneeAnyone: "Anyone on the run",
|
|
451
|
+
assigneeRunOwner: "Whoever started the run",
|
|
452
|
+
assigneeProjectLead: "The project lead",
|
|
453
|
+
assigneeFields: "The person in a form field",
|
|
454
|
+
assigneePeople: "A person",
|
|
455
|
+
remind: "Remind after (hours)",
|
|
456
|
+
remindHint: "Left that long, they are told again. Blank: no reminder.",
|
|
457
|
+
documentFrom: "Document",
|
|
458
|
+
docFromStep: "From an earlier step",
|
|
459
|
+
docFromInput: "From a run input",
|
|
460
|
+
docById: "A document",
|
|
461
|
+
chooseStep: "Choose a step\u2026",
|
|
462
|
+
chooseInput: "Choose an input\u2026",
|
|
463
|
+
chooseDocument: "Choose a document\u2026",
|
|
464
|
+
documentIdPlaceholder: "doc-\u2026",
|
|
465
|
+
signDocument: "Document to sign",
|
|
466
|
+
signers: "Signers",
|
|
467
|
+
addSigner: "Add signer",
|
|
468
|
+
signMessage: "Message to the signers",
|
|
469
|
+
expires: "Expires after (hours)",
|
|
470
|
+
expiresHint: "Unsigned by then, the step fails. Blank: no expiry.",
|
|
471
|
+
emailTo: "To",
|
|
472
|
+
emailCc: "Cc",
|
|
473
|
+
emailSubject: "Subject",
|
|
474
|
+
emailBody: "Body",
|
|
475
|
+
addressesHint: "Separate several with commas.",
|
|
476
|
+
variablesHint: "Variables (click to add to the body):",
|
|
477
|
+
attachments: "Attachments",
|
|
478
|
+
addAttachment: "Add attachment",
|
|
479
|
+
reviewColumns: "Columns (labels)",
|
|
480
|
+
noTags: "No labels in this workspace yet.",
|
|
481
|
+
reviewDocuments: "Documents",
|
|
482
|
+
reviewRunUploads: "The files this run collects",
|
|
483
|
+
reviewWorkspace: "Every document in the workspace",
|
|
484
|
+
reviewChosen: "Chosen documents",
|
|
485
|
+
addDocument: "Add document",
|
|
486
|
+
overwrite: "Fill cells that already have a value again",
|
|
487
|
+
editDocument: "Edit this document (tracked changes)",
|
|
488
|
+
editDocumentHint: "The instruction says what to change; the edited copy is saved as its next version, to accept or reject change by change."
|
|
489
|
+
};
|
|
490
|
+
var selectClass2 = "flex h-9 w-full rounded-md border border-input bg-background px-2 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring";
|
|
491
|
+
function Field({
|
|
492
|
+
label,
|
|
493
|
+
children,
|
|
494
|
+
hint
|
|
495
|
+
}) {
|
|
496
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
497
|
+
/* @__PURE__ */ jsx(Label, { className: "text-xs", children: label }),
|
|
498
|
+
children,
|
|
499
|
+
hint && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: hint })
|
|
500
|
+
] });
|
|
501
|
+
}
|
|
502
|
+
var assigneeValue = (a) => !a ? "" : "user" in a ? `user:${a.user}` : "input" in a ? `input:${a.input}` : "runOwner" in a ? "owner" : "lead";
|
|
503
|
+
var parseAssignee = (v) => v === "owner" ? { runOwner: true } : v === "lead" ? { projectLead: true } : v.startsWith("user:") ? { user: v.slice(5) } : v.startsWith("input:") ? { input: v.slice(6) } : void 0;
|
|
504
|
+
function AssigneeSelect({
|
|
505
|
+
value,
|
|
506
|
+
onChange,
|
|
507
|
+
ctx,
|
|
508
|
+
l,
|
|
509
|
+
anyone,
|
|
510
|
+
testId,
|
|
511
|
+
ariaLabel
|
|
512
|
+
}) {
|
|
513
|
+
const personFields = ctx.fields.filter((f) => f.type === "person");
|
|
514
|
+
const v = assigneeValue(value);
|
|
515
|
+
const known = !v.startsWith("user:") || ctx.people.some((p) => `user:${p.value}` === v) ? null : v.slice(5);
|
|
516
|
+
return /* @__PURE__ */ jsxs(
|
|
517
|
+
"select",
|
|
518
|
+
{
|
|
519
|
+
className: selectClass2,
|
|
520
|
+
value: v,
|
|
521
|
+
"aria-label": ariaLabel,
|
|
522
|
+
onChange: (e) => onChange(parseAssignee(e.target.value)),
|
|
523
|
+
"data-testid": testId,
|
|
524
|
+
children: [
|
|
525
|
+
anyone !== void 0 ? /* @__PURE__ */ jsx("option", { value: "", children: anyone }) : /* @__PURE__ */ jsx("option", { value: "", disabled: true }),
|
|
526
|
+
/* @__PURE__ */ jsx("option", { value: "owner", children: l.assigneeRunOwner }),
|
|
527
|
+
/* @__PURE__ */ jsx("option", { value: "lead", children: l.assigneeProjectLead }),
|
|
528
|
+
personFields.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: l.assigneeFields, children: personFields.map((f) => /* @__PURE__ */ jsx("option", { value: `input:${f.name}`, children: f.label }, f.name)) }),
|
|
529
|
+
(ctx.people.length > 0 || known) && /* @__PURE__ */ jsxs("optgroup", { label: l.assigneePeople, children: [
|
|
530
|
+
ctx.people.map((p) => /* @__PURE__ */ jsx("option", { value: `user:${p.value}`, children: p.label }, p.value)),
|
|
531
|
+
known && /* @__PURE__ */ jsx("option", { value: v, children: known })
|
|
532
|
+
] })
|
|
533
|
+
]
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
function AssigneeSettings({
|
|
538
|
+
step,
|
|
539
|
+
patch,
|
|
540
|
+
ctx,
|
|
541
|
+
l,
|
|
542
|
+
testId
|
|
543
|
+
}) {
|
|
544
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
545
|
+
/* @__PURE__ */ jsx(Field, { label: l.assignee, children: /* @__PURE__ */ jsx(
|
|
546
|
+
AssigneeSelect,
|
|
547
|
+
{
|
|
548
|
+
value: step.assignee,
|
|
549
|
+
onChange: (assignee) => patch({ assignee }),
|
|
550
|
+
ctx,
|
|
551
|
+
l,
|
|
552
|
+
anyone: l.assigneeAnyone,
|
|
553
|
+
testId: `${testId}-assignee`
|
|
554
|
+
}
|
|
555
|
+
) }),
|
|
556
|
+
/* @__PURE__ */ jsx(Field, { label: l.remind, hint: l.remindHint, children: /* @__PURE__ */ jsx(
|
|
557
|
+
Input,
|
|
558
|
+
{
|
|
559
|
+
type: "number",
|
|
560
|
+
min: 1,
|
|
561
|
+
value: step.remindAfterHours ?? "",
|
|
562
|
+
onChange: (e) => {
|
|
563
|
+
const n = Number(e.target.value);
|
|
564
|
+
patch({ remindAfterHours: e.target.value && n > 0 ? n : void 0 });
|
|
565
|
+
},
|
|
566
|
+
className: "w-28",
|
|
567
|
+
"data-testid": `${testId}-remind`
|
|
568
|
+
}
|
|
569
|
+
) })
|
|
570
|
+
] });
|
|
571
|
+
}
|
|
572
|
+
var modeOf = (ref) => !ref ? "step" : "step" in ref ? "step" : "input" in ref ? "input" : "id";
|
|
573
|
+
function DocumentRefPicker({
|
|
574
|
+
value,
|
|
575
|
+
onChange,
|
|
576
|
+
ctx,
|
|
577
|
+
l,
|
|
578
|
+
testId
|
|
579
|
+
}) {
|
|
580
|
+
const mode = modeOf(value);
|
|
581
|
+
const inputs = ctx.fields.filter((f) => f.type === "documents" || f.type === "text");
|
|
582
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", "data-testid": testId, children: [
|
|
583
|
+
/* @__PURE__ */ jsxs(
|
|
584
|
+
"select",
|
|
585
|
+
{
|
|
586
|
+
className: cn(selectClass2, "h-8"),
|
|
587
|
+
value: mode,
|
|
588
|
+
"aria-label": l.documentFrom,
|
|
589
|
+
onChange: (e) => {
|
|
590
|
+
const m = e.target.value;
|
|
591
|
+
onChange(m === "step" ? { step: "" } : m === "input" ? { input: "" } : { id: "" });
|
|
592
|
+
},
|
|
593
|
+
"data-testid": `${testId}-mode`,
|
|
594
|
+
children: [
|
|
595
|
+
/* @__PURE__ */ jsx("option", { value: "step", children: l.docFromStep }),
|
|
596
|
+
/* @__PURE__ */ jsx("option", { value: "input", children: l.docFromInput }),
|
|
597
|
+
/* @__PURE__ */ jsx("option", { value: "id", children: l.docById })
|
|
598
|
+
]
|
|
599
|
+
}
|
|
600
|
+
),
|
|
601
|
+
mode === "step" && /* @__PURE__ */ jsxs(
|
|
602
|
+
"select",
|
|
603
|
+
{
|
|
604
|
+
className: cn(selectClass2, "h-8"),
|
|
605
|
+
value: value && "step" in value ? value.step : "",
|
|
606
|
+
onChange: (e) => onChange({ step: e.target.value }),
|
|
607
|
+
"data-testid": `${testId}-step`,
|
|
608
|
+
children: [
|
|
609
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: l.chooseStep }),
|
|
610
|
+
ctx.earlier.map((s) => /* @__PURE__ */ jsx("option", { value: s.id, children: s.title }, s.id))
|
|
611
|
+
]
|
|
612
|
+
}
|
|
613
|
+
),
|
|
614
|
+
mode === "input" && /* @__PURE__ */ jsxs(
|
|
615
|
+
"select",
|
|
616
|
+
{
|
|
617
|
+
className: cn(selectClass2, "h-8"),
|
|
618
|
+
value: value && "input" in value ? value.input : "",
|
|
619
|
+
onChange: (e) => onChange({ input: e.target.value }),
|
|
620
|
+
"data-testid": `${testId}-input`,
|
|
621
|
+
children: [
|
|
622
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: l.chooseInput }),
|
|
623
|
+
inputs.map((f) => /* @__PURE__ */ jsx("option", { value: f.name, children: f.label }, f.name))
|
|
624
|
+
]
|
|
625
|
+
}
|
|
626
|
+
),
|
|
627
|
+
mode === "id" && (ctx.documents.length ? /* @__PURE__ */ jsxs(
|
|
628
|
+
"select",
|
|
629
|
+
{
|
|
630
|
+
className: cn(selectClass2, "h-8"),
|
|
631
|
+
value: value && "id" in value ? value.id : "",
|
|
632
|
+
onChange: (e) => onChange({ id: e.target.value }),
|
|
633
|
+
"data-testid": `${testId}-id`,
|
|
634
|
+
children: [
|
|
635
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: l.chooseDocument }),
|
|
636
|
+
ctx.documents.map((d) => /* @__PURE__ */ jsx("option", { value: d.value, children: d.label }, d.value))
|
|
637
|
+
]
|
|
638
|
+
}
|
|
639
|
+
) : /* @__PURE__ */ jsx(
|
|
640
|
+
Input,
|
|
641
|
+
{
|
|
642
|
+
className: "h-8",
|
|
643
|
+
value: value && "id" in value ? value.id : "",
|
|
644
|
+
placeholder: l.documentIdPlaceholder,
|
|
645
|
+
onChange: (e) => onChange({ id: e.target.value }),
|
|
646
|
+
"data-testid": `${testId}-id`
|
|
647
|
+
}
|
|
648
|
+
))
|
|
649
|
+
] });
|
|
650
|
+
}
|
|
651
|
+
function DocumentRefList({
|
|
652
|
+
value,
|
|
653
|
+
onChange,
|
|
654
|
+
ctx,
|
|
655
|
+
l,
|
|
656
|
+
addLabel,
|
|
657
|
+
testId
|
|
658
|
+
}) {
|
|
659
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
660
|
+
value.map((ref, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-1.5", children: [
|
|
661
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
662
|
+
DocumentRefPicker,
|
|
663
|
+
{
|
|
664
|
+
value: ref,
|
|
665
|
+
onChange: (next) => onChange(value.map((r, j) => j === i ? next : r)),
|
|
666
|
+
ctx,
|
|
667
|
+
l,
|
|
668
|
+
testId: `${testId}-${i}`
|
|
669
|
+
}
|
|
670
|
+
) }),
|
|
671
|
+
/* @__PURE__ */ jsx(
|
|
672
|
+
"button",
|
|
673
|
+
{
|
|
674
|
+
type: "button",
|
|
675
|
+
className: "mt-2",
|
|
676
|
+
"aria-label": `${addLabel} \xD7`,
|
|
677
|
+
onClick: () => onChange(value.filter((_, j) => j !== i)),
|
|
678
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4 text-muted-foreground" })
|
|
679
|
+
}
|
|
680
|
+
)
|
|
681
|
+
] }, i)),
|
|
682
|
+
/* @__PURE__ */ jsxs(
|
|
683
|
+
Button,
|
|
684
|
+
{
|
|
685
|
+
variant: "outline",
|
|
686
|
+
size: "sm",
|
|
687
|
+
onClick: () => onChange([...value, { step: "" }]),
|
|
688
|
+
"data-testid": `${testId}-add`,
|
|
689
|
+
children: [
|
|
690
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-4" }),
|
|
691
|
+
" ",
|
|
692
|
+
addLabel
|
|
693
|
+
]
|
|
694
|
+
}
|
|
695
|
+
)
|
|
696
|
+
] });
|
|
697
|
+
}
|
|
698
|
+
var optionalNumber = (raw) => {
|
|
699
|
+
const n = Number(raw);
|
|
700
|
+
return raw && n > 0 ? n : void 0;
|
|
701
|
+
};
|
|
702
|
+
function SignSettings({
|
|
703
|
+
action,
|
|
704
|
+
onChange,
|
|
705
|
+
ctx,
|
|
706
|
+
l,
|
|
707
|
+
testId
|
|
708
|
+
}) {
|
|
709
|
+
const set = (p) => onChange({ ...action, ...p });
|
|
710
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
711
|
+
/* @__PURE__ */ jsx(Field, { label: l.signDocument, children: /* @__PURE__ */ jsx(
|
|
712
|
+
DocumentRefPicker,
|
|
713
|
+
{
|
|
714
|
+
value: action.document,
|
|
715
|
+
onChange: (document) => set({ document }),
|
|
716
|
+
ctx,
|
|
717
|
+
l,
|
|
718
|
+
testId: `${testId}-document`
|
|
719
|
+
}
|
|
720
|
+
) }),
|
|
721
|
+
/* @__PURE__ */ jsx(Field, { label: l.signers, children: /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", "data-testid": `${testId}-signers`, children: [
|
|
722
|
+
action.signers.map((s, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
723
|
+
/* @__PURE__ */ jsx(
|
|
724
|
+
AssigneeSelect,
|
|
725
|
+
{
|
|
726
|
+
value: s,
|
|
727
|
+
onChange: (next) => set({
|
|
728
|
+
signers: next ? action.signers.map((x, j) => j === i ? next : x) : action.signers.filter((_, j) => j !== i)
|
|
729
|
+
}),
|
|
730
|
+
ctx,
|
|
731
|
+
l,
|
|
732
|
+
ariaLabel: `${l.signers} ${i + 1}`,
|
|
733
|
+
testId: `${testId}-signer-${i}`
|
|
734
|
+
}
|
|
735
|
+
),
|
|
736
|
+
/* @__PURE__ */ jsx(
|
|
737
|
+
"button",
|
|
738
|
+
{
|
|
739
|
+
type: "button",
|
|
740
|
+
"aria-label": `${l.signers} ${i + 1} \xD7`,
|
|
741
|
+
onClick: () => set({ signers: action.signers.filter((_, j) => j !== i) }),
|
|
742
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4 text-muted-foreground" })
|
|
743
|
+
}
|
|
744
|
+
)
|
|
745
|
+
] }, i)),
|
|
746
|
+
/* @__PURE__ */ jsxs(
|
|
747
|
+
Button,
|
|
748
|
+
{
|
|
749
|
+
variant: "outline",
|
|
750
|
+
size: "sm",
|
|
751
|
+
onClick: () => set({ signers: [...action.signers, { runOwner: true }] }),
|
|
752
|
+
"data-testid": `${testId}-add-signer`,
|
|
753
|
+
children: [
|
|
754
|
+
/* @__PURE__ */ jsx(Plus, { className: "size-4" }),
|
|
755
|
+
" ",
|
|
756
|
+
l.addSigner
|
|
757
|
+
]
|
|
758
|
+
}
|
|
759
|
+
)
|
|
760
|
+
] }) }),
|
|
761
|
+
/* @__PURE__ */ jsx(Field, { label: l.signMessage, children: /* @__PURE__ */ jsx(
|
|
762
|
+
Textarea,
|
|
763
|
+
{
|
|
764
|
+
rows: 3,
|
|
765
|
+
value: action.message ?? "",
|
|
766
|
+
onChange: (e) => set({ message: e.target.value || void 0 }),
|
|
767
|
+
"data-testid": `${testId}-message`
|
|
768
|
+
}
|
|
769
|
+
) }),
|
|
770
|
+
/* @__PURE__ */ jsx(Field, { label: l.expires, hint: l.expiresHint, children: /* @__PURE__ */ jsx(
|
|
771
|
+
Input,
|
|
772
|
+
{
|
|
773
|
+
type: "number",
|
|
774
|
+
min: 1,
|
|
775
|
+
className: "w-28",
|
|
776
|
+
value: action.expiresAfterHours ?? "",
|
|
777
|
+
onChange: (e) => set({ expiresAfterHours: optionalNumber(e.target.value) }),
|
|
778
|
+
"data-testid": `${testId}-expires`
|
|
779
|
+
}
|
|
780
|
+
) })
|
|
781
|
+
] });
|
|
782
|
+
}
|
|
783
|
+
var addresses = (list) => (list ?? []).join(", ");
|
|
784
|
+
var parseAddresses = (text) => text.split(",").map((t) => t.trim());
|
|
785
|
+
function templateVariables(ctx) {
|
|
786
|
+
return [
|
|
787
|
+
...ctx.fields.map((f) => `{{${f.name}}}`),
|
|
788
|
+
...ctx.earlier.filter((s) => s.kind === "agent").map((s) => `{{${s.id}.answer}}`)
|
|
789
|
+
];
|
|
790
|
+
}
|
|
791
|
+
function EmailDraftSettings({
|
|
792
|
+
action,
|
|
793
|
+
onChange,
|
|
794
|
+
ctx,
|
|
795
|
+
l,
|
|
796
|
+
testId
|
|
797
|
+
}) {
|
|
798
|
+
const set = (p) => onChange({ ...action, ...p });
|
|
799
|
+
const vars = templateVariables(ctx);
|
|
800
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
801
|
+
/* @__PURE__ */ jsx(Field, { label: l.emailTo, hint: l.addressesHint, children: /* @__PURE__ */ jsx(
|
|
802
|
+
Input,
|
|
803
|
+
{
|
|
804
|
+
value: addresses(action.to),
|
|
805
|
+
onChange: (e) => set({ to: parseAddresses(e.target.value) }),
|
|
806
|
+
placeholder: "{{client_email}}",
|
|
807
|
+
"data-testid": `${testId}-to`
|
|
808
|
+
}
|
|
809
|
+
) }),
|
|
810
|
+
/* @__PURE__ */ jsx(Field, { label: l.emailCc, children: /* @__PURE__ */ jsx(
|
|
811
|
+
Input,
|
|
812
|
+
{
|
|
813
|
+
value: addresses(action.cc),
|
|
814
|
+
onChange: (e) => {
|
|
815
|
+
const cc = parseAddresses(e.target.value);
|
|
816
|
+
set({ cc: cc.some(Boolean) ? cc : void 0 });
|
|
817
|
+
},
|
|
818
|
+
"data-testid": `${testId}-cc`
|
|
819
|
+
}
|
|
820
|
+
) }),
|
|
821
|
+
/* @__PURE__ */ jsx(Field, { label: l.emailSubject, children: /* @__PURE__ */ jsx(
|
|
822
|
+
Input,
|
|
823
|
+
{
|
|
824
|
+
value: action.subject,
|
|
825
|
+
onChange: (e) => set({ subject: e.target.value }),
|
|
826
|
+
"data-testid": `${testId}-subject`
|
|
827
|
+
}
|
|
828
|
+
) }),
|
|
829
|
+
/* @__PURE__ */ jsx(Field, { label: l.emailBody, children: /* @__PURE__ */ jsx(
|
|
830
|
+
Textarea,
|
|
831
|
+
{
|
|
832
|
+
rows: 6,
|
|
833
|
+
value: action.body,
|
|
834
|
+
onChange: (e) => set({ body: e.target.value }),
|
|
835
|
+
"data-testid": `${testId}-body`
|
|
836
|
+
}
|
|
837
|
+
) }),
|
|
838
|
+
vars.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", "data-testid": `${testId}-variables`, children: [
|
|
839
|
+
/* @__PURE__ */ jsx("span", { className: "w-full text-xs text-muted-foreground", children: l.variablesHint }),
|
|
840
|
+
vars.map((v) => /* @__PURE__ */ jsx(
|
|
841
|
+
"button",
|
|
842
|
+
{
|
|
843
|
+
type: "button",
|
|
844
|
+
onClick: () => set({ body: `${action.body}${action.body ? " " : ""}${v}` }),
|
|
845
|
+
className: "rounded bg-muted px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground hover:text-foreground",
|
|
846
|
+
title: v,
|
|
847
|
+
children: v
|
|
848
|
+
},
|
|
849
|
+
v
|
|
850
|
+
))
|
|
851
|
+
] }),
|
|
852
|
+
/* @__PURE__ */ jsx(Field, { label: l.attachments, children: /* @__PURE__ */ jsx(
|
|
853
|
+
DocumentRefList,
|
|
854
|
+
{
|
|
855
|
+
value: action.attachments ?? [],
|
|
856
|
+
onChange: (attachments) => set({ attachments: attachments.length ? attachments : void 0 }),
|
|
857
|
+
ctx,
|
|
858
|
+
l,
|
|
859
|
+
addLabel: l.addAttachment,
|
|
860
|
+
testId: `${testId}-attachments`
|
|
861
|
+
}
|
|
862
|
+
) })
|
|
863
|
+
] });
|
|
864
|
+
}
|
|
865
|
+
function TabularReviewSettings({
|
|
866
|
+
action,
|
|
867
|
+
onChange,
|
|
868
|
+
ctx,
|
|
869
|
+
l,
|
|
870
|
+
testId
|
|
871
|
+
}) {
|
|
872
|
+
const set = (p) => onChange({ ...action, ...p });
|
|
873
|
+
const mode = Array.isArray(action.documents) ? "chosen" : action.documents;
|
|
874
|
+
const toggle = (id) => set({
|
|
875
|
+
tags: action.tags.includes(id) ? action.tags.filter((t) => t !== id) : [...action.tags, id]
|
|
876
|
+
});
|
|
877
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
878
|
+
/* @__PURE__ */ jsx(Field, { label: l.reviewColumns, children: /* @__PURE__ */ jsxs(
|
|
879
|
+
"div",
|
|
880
|
+
{
|
|
881
|
+
className: "max-h-44 space-y-1 overflow-y-auto rounded-md border border-border p-2",
|
|
882
|
+
"data-testid": `${testId}-tags`,
|
|
883
|
+
children: [
|
|
884
|
+
ctx.tags.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: l.noTags }),
|
|
885
|
+
ctx.tags.map((t) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
|
|
886
|
+
/* @__PURE__ */ jsx(
|
|
887
|
+
Checkbox,
|
|
888
|
+
{
|
|
889
|
+
checked: action.tags.includes(t.value),
|
|
890
|
+
onCheckedChange: () => toggle(t.value),
|
|
891
|
+
"data-testid": `${testId}-tag-${t.value}`
|
|
892
|
+
}
|
|
893
|
+
),
|
|
894
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: t.label })
|
|
895
|
+
] }, t.value)),
|
|
896
|
+
action.tags.filter((t) => !ctx.tags.some((x) => x.value === t)).map((t) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
|
|
897
|
+
/* @__PURE__ */ jsx(Checkbox, { checked: true, onCheckedChange: () => toggle(t) }),
|
|
898
|
+
/* @__PURE__ */ jsx("code", { className: "text-xs", children: t })
|
|
899
|
+
] }, t))
|
|
900
|
+
]
|
|
901
|
+
}
|
|
902
|
+
) }),
|
|
903
|
+
/* @__PURE__ */ jsx(Field, { label: l.reviewDocuments, children: /* @__PURE__ */ jsxs(
|
|
904
|
+
"select",
|
|
905
|
+
{
|
|
906
|
+
className: selectClass2,
|
|
907
|
+
value: mode,
|
|
908
|
+
onChange: (e) => {
|
|
909
|
+
const v = e.target.value;
|
|
910
|
+
set({ documents: v === "chosen" ? [] : v });
|
|
911
|
+
},
|
|
912
|
+
"data-testid": `${testId}-documents`,
|
|
913
|
+
children: [
|
|
914
|
+
/* @__PURE__ */ jsx("option", { value: "run_uploads", children: l.reviewRunUploads }),
|
|
915
|
+
/* @__PURE__ */ jsx("option", { value: "workspace", children: l.reviewWorkspace }),
|
|
916
|
+
/* @__PURE__ */ jsx("option", { value: "chosen", children: l.reviewChosen })
|
|
917
|
+
]
|
|
918
|
+
}
|
|
919
|
+
) }),
|
|
920
|
+
Array.isArray(action.documents) && /* @__PURE__ */ jsx(
|
|
921
|
+
DocumentRefList,
|
|
922
|
+
{
|
|
923
|
+
value: action.documents,
|
|
924
|
+
onChange: (documents) => set({ documents }),
|
|
925
|
+
ctx,
|
|
926
|
+
l,
|
|
927
|
+
addLabel: l.addDocument,
|
|
928
|
+
testId: `${testId}-chosen`
|
|
929
|
+
}
|
|
930
|
+
),
|
|
931
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
|
|
932
|
+
/* @__PURE__ */ jsx(
|
|
933
|
+
Checkbox,
|
|
934
|
+
{
|
|
935
|
+
checked: !!action.overwrite,
|
|
936
|
+
onCheckedChange: (v) => set({ overwrite: v === true || void 0 })
|
|
937
|
+
}
|
|
938
|
+
),
|
|
939
|
+
l.overwrite
|
|
940
|
+
] })
|
|
941
|
+
] });
|
|
942
|
+
}
|
|
943
|
+
function EditDocumentSettings({
|
|
944
|
+
step,
|
|
945
|
+
patch,
|
|
946
|
+
ctx,
|
|
947
|
+
l,
|
|
948
|
+
testId
|
|
949
|
+
}) {
|
|
950
|
+
const on = !!step.editDocument;
|
|
951
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
952
|
+
/* @__PURE__ */ jsxs("label", { className: "flex items-start gap-2 text-sm", children: [
|
|
953
|
+
/* @__PURE__ */ jsx(
|
|
954
|
+
Checkbox,
|
|
955
|
+
{
|
|
956
|
+
checked: on,
|
|
957
|
+
disabled: !!step.branch,
|
|
958
|
+
onCheckedChange: (v) => patch({ editDocument: v === true ? { step: "" } : void 0 }),
|
|
959
|
+
"data-testid": `${testId}-edit-document`
|
|
960
|
+
}
|
|
961
|
+
),
|
|
962
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
963
|
+
l.editDocument,
|
|
964
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: l.editDocumentHint })
|
|
965
|
+
] })
|
|
966
|
+
] }),
|
|
967
|
+
on && /* @__PURE__ */ jsx(
|
|
968
|
+
DocumentRefPicker,
|
|
969
|
+
{
|
|
970
|
+
value: step.editDocument,
|
|
971
|
+
onChange: (editDocument) => patch({ editDocument }),
|
|
972
|
+
ctx,
|
|
973
|
+
l,
|
|
974
|
+
testId: `${testId}-edit-document-ref`
|
|
975
|
+
}
|
|
976
|
+
)
|
|
977
|
+
] });
|
|
978
|
+
}
|
|
384
979
|
var DEFAULT_STEP_INSPECTOR_LABELS = {
|
|
385
980
|
workflow: "Workflow",
|
|
386
981
|
title: "Title",
|
|
@@ -410,17 +1005,19 @@ var DEFAULT_STEP_INSPECTOR_LABELS = {
|
|
|
410
1005
|
hint: "Hint",
|
|
411
1006
|
instructions: "What to review",
|
|
412
1007
|
instructionsHint: "Shown on the review task; {{field}} and {{steps.<id>}} work here.",
|
|
1008
|
+
reviewFields: "Filled in when approving",
|
|
1009
|
+
reviewFieldsHint: "E.g. a rating or a comment; the answers join the run\u2019s inputs.",
|
|
413
1010
|
deleteStep: "Delete step"
|
|
414
1011
|
};
|
|
415
|
-
var FIELD_TYPES = [
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
1012
|
+
var FIELD_TYPES = [
|
|
1013
|
+
"text",
|
|
1014
|
+
"longtext",
|
|
1015
|
+
"boolean",
|
|
1016
|
+
"number",
|
|
1017
|
+
"date",
|
|
1018
|
+
"scope",
|
|
1019
|
+
"person"
|
|
1020
|
+
];
|
|
424
1021
|
var fieldName = (label, taken) => {
|
|
425
1022
|
const base = label.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").replace(/^[^a-z]+/, "") || "field";
|
|
426
1023
|
let name = base;
|
|
@@ -434,7 +1031,11 @@ function StepInspector({
|
|
|
434
1031
|
onChange,
|
|
435
1032
|
onSelect,
|
|
436
1033
|
workflows = [],
|
|
1034
|
+
people = [],
|
|
1035
|
+
tags = [],
|
|
1036
|
+
documents = [],
|
|
437
1037
|
labels,
|
|
1038
|
+
actionLabels,
|
|
438
1039
|
signalLabels,
|
|
439
1040
|
testId = "step-inspector"
|
|
440
1041
|
}) {
|
|
@@ -464,6 +1065,30 @@ function StepInspector({
|
|
|
464
1065
|
] });
|
|
465
1066
|
}
|
|
466
1067
|
const patch = (p) => onChange(updateStep(workflow, step.id, p));
|
|
1068
|
+
const al = { ...DEFAULT_STEP_ACTION_SETTINGS_LABELS, ...actionLabels };
|
|
1069
|
+
const ctx = {
|
|
1070
|
+
earlier: upstreamSteps(steps, step.id),
|
|
1071
|
+
fields: runFields(workflow),
|
|
1072
|
+
people,
|
|
1073
|
+
tags,
|
|
1074
|
+
documents
|
|
1075
|
+
};
|
|
1076
|
+
const takenBy = (id) => steps.flatMap(
|
|
1077
|
+
(s) => s.id === id ? [] : s.kind === "form" ? s.inputs : s.kind === "review" ? s.fields ?? [] : []
|
|
1078
|
+
).map((f) => f.name);
|
|
1079
|
+
const setFields = (before, after, key) => {
|
|
1080
|
+
const renamed = before.flatMap(
|
|
1081
|
+
(f, i) => after[i] && after[i].name !== f.name ? [[f.name, after[i].name]] : []
|
|
1082
|
+
);
|
|
1083
|
+
onChange(
|
|
1084
|
+
renamed.reduce(
|
|
1085
|
+
(w, [from, to]) => renameInput(w, from, to),
|
|
1086
|
+
updateStep(workflow, step.id, {
|
|
1087
|
+
[key]: key === "fields" && !after.length ? void 0 : after
|
|
1088
|
+
})
|
|
1089
|
+
)
|
|
1090
|
+
);
|
|
1091
|
+
};
|
|
467
1092
|
const deps = stepDependencies(steps, step.id);
|
|
468
1093
|
const titleOf = (id) => steps.find((s) => s.id === id)?.title ?? id;
|
|
469
1094
|
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", "data-testid": `${testId}-step`, children: [
|
|
@@ -513,18 +1138,8 @@ function StepInspector({
|
|
|
513
1138
|
FormFields,
|
|
514
1139
|
{
|
|
515
1140
|
fields: step.inputs,
|
|
516
|
-
taken:
|
|
517
|
-
onChange: (inputs) =>
|
|
518
|
-
const renamed = step.inputs.flatMap(
|
|
519
|
-
(f, i) => inputs[i] && inputs[i].name !== f.name ? [[f.name, inputs[i].name]] : []
|
|
520
|
-
);
|
|
521
|
-
onChange(
|
|
522
|
-
renamed.reduce(
|
|
523
|
-
(w, [from, to]) => renameInput(w, from, to),
|
|
524
|
-
updateStep(workflow, step.id, { inputs })
|
|
525
|
-
)
|
|
526
|
-
);
|
|
527
|
-
},
|
|
1141
|
+
taken: takenBy(step.id),
|
|
1142
|
+
onChange: (inputs) => setFields(step.inputs, inputs, "inputs"),
|
|
528
1143
|
l,
|
|
529
1144
|
testId
|
|
530
1145
|
}
|
|
@@ -548,26 +1163,73 @@ function StepInspector({
|
|
|
548
1163
|
}
|
|
549
1164
|
) })
|
|
550
1165
|
] }),
|
|
551
|
-
step.kind === "agent" && /* @__PURE__ */
|
|
552
|
-
|
|
1166
|
+
step.kind === "agent" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1167
|
+
/* @__PURE__ */ jsx(
|
|
1168
|
+
AgentSettings,
|
|
1169
|
+
{
|
|
1170
|
+
step,
|
|
1171
|
+
workflows,
|
|
1172
|
+
fields: runFields(workflow).map((f) => f.name),
|
|
1173
|
+
patch,
|
|
1174
|
+
l,
|
|
1175
|
+
testId
|
|
1176
|
+
}
|
|
1177
|
+
),
|
|
1178
|
+
/* @__PURE__ */ jsx(EditDocumentSettings, { step, patch, ctx, l: al, testId })
|
|
1179
|
+
] }),
|
|
1180
|
+
step.kind === "review" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1181
|
+
/* @__PURE__ */ jsx(Field, { label: l.instructions, hint: l.instructionsHint, children: /* @__PURE__ */ jsx(
|
|
1182
|
+
Textarea,
|
|
1183
|
+
{
|
|
1184
|
+
value: step.instructions ?? "",
|
|
1185
|
+
rows: 4,
|
|
1186
|
+
onChange: (e) => patch({ instructions: e.target.value || void 0 }),
|
|
1187
|
+
"data-testid": `${testId}-instructions`
|
|
1188
|
+
}
|
|
1189
|
+
) }),
|
|
1190
|
+
/* @__PURE__ */ jsx(
|
|
1191
|
+
FormFields,
|
|
1192
|
+
{
|
|
1193
|
+
fields: step.fields ?? [],
|
|
1194
|
+
taken: takenBy(step.id),
|
|
1195
|
+
onChange: (fields) => setFields(step.fields ?? [], fields, "fields"),
|
|
1196
|
+
l: { ...l, fields: l.reviewFields },
|
|
1197
|
+
hint: l.reviewFieldsHint,
|
|
1198
|
+
testId: `${testId}-review`
|
|
1199
|
+
}
|
|
1200
|
+
)
|
|
1201
|
+
] }),
|
|
1202
|
+
step.kind === "action" && step.action.type === "sign" && /* @__PURE__ */ jsx(
|
|
1203
|
+
SignSettings,
|
|
553
1204
|
{
|
|
554
|
-
step,
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
testId
|
|
1205
|
+
action: step.action,
|
|
1206
|
+
onChange: (action) => patch({ action }),
|
|
1207
|
+
ctx,
|
|
1208
|
+
l: al,
|
|
1209
|
+
testId: `${testId}-sign`
|
|
560
1210
|
}
|
|
561
1211
|
),
|
|
562
|
-
step.kind === "
|
|
563
|
-
|
|
1212
|
+
step.kind === "action" && step.action.type === "email_draft" && /* @__PURE__ */ jsx(
|
|
1213
|
+
EmailDraftSettings,
|
|
564
1214
|
{
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
1215
|
+
action: step.action,
|
|
1216
|
+
onChange: (action) => patch({ action }),
|
|
1217
|
+
ctx,
|
|
1218
|
+
l: al,
|
|
1219
|
+
testId: `${testId}-email`
|
|
569
1220
|
}
|
|
570
|
-
)
|
|
1221
|
+
),
|
|
1222
|
+
step.kind === "action" && step.action.type === "tabular_review" && /* @__PURE__ */ jsx(
|
|
1223
|
+
TabularReviewSettings,
|
|
1224
|
+
{
|
|
1225
|
+
action: step.action,
|
|
1226
|
+
onChange: (action) => patch({ action }),
|
|
1227
|
+
ctx,
|
|
1228
|
+
l: al,
|
|
1229
|
+
testId: `${testId}-review-grid`
|
|
1230
|
+
}
|
|
1231
|
+
),
|
|
1232
|
+
canAssign(step) && /* @__PURE__ */ jsx(AssigneeSettings, { step, patch, ctx, l: al, testId }),
|
|
571
1233
|
/* @__PURE__ */ jsx(
|
|
572
1234
|
SignalsEditor,
|
|
573
1235
|
{
|
|
@@ -602,10 +1264,11 @@ function FormFields({
|
|
|
602
1264
|
taken,
|
|
603
1265
|
onChange,
|
|
604
1266
|
l,
|
|
1267
|
+
hint,
|
|
605
1268
|
testId
|
|
606
1269
|
}) {
|
|
607
1270
|
const set = (i, p) => onChange(fields.map((f, j) => j === i ? { ...f, ...p } : f));
|
|
608
|
-
return /* @__PURE__ */ jsx(Field, { label: l.fields, children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", "data-testid": `${testId}-fields`, children: [
|
|
1271
|
+
return /* @__PURE__ */ jsx(Field, { label: l.fields, hint, children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", "data-testid": `${testId}-fields`, children: [
|
|
609
1272
|
fields.map((f, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 rounded-md border border-border p-2", children: [
|
|
610
1273
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
611
1274
|
/* @__PURE__ */ jsx(
|
|
@@ -641,7 +1304,9 @@ function FormFields({
|
|
|
641
1304
|
className: cn(selectClass2, "h-8"),
|
|
642
1305
|
value: f.type,
|
|
643
1306
|
onChange: (e) => set(i, { type: e.target.value }),
|
|
644
|
-
children: FIELD_TYPES.
|
|
1307
|
+
children: (FIELD_TYPES.includes(f.type) ? FIELD_TYPES : [...FIELD_TYPES, f.type]).map(
|
|
1308
|
+
(t) => /* @__PURE__ */ jsx("option", { value: t, children: t }, t)
|
|
1309
|
+
)
|
|
645
1310
|
}
|
|
646
1311
|
),
|
|
647
1312
|
/* @__PURE__ */ jsxs("label", { className: "flex shrink-0 items-center gap-1.5 text-xs", children: [
|
|
@@ -1132,12 +1797,19 @@ var DEFAULT_WORKFLOW_CANVAS_LABELS = {
|
|
|
1132
1797
|
upload: "Upload",
|
|
1133
1798
|
agent: "AI step",
|
|
1134
1799
|
review: "Approval",
|
|
1800
|
+
sign: "Sign",
|
|
1801
|
+
email_draft: "Email draft",
|
|
1802
|
+
tabular_review: "Tabular review",
|
|
1803
|
+
redline: "Tracked changes",
|
|
1135
1804
|
branch: "Branch",
|
|
1136
1805
|
kindHints: {
|
|
1137
1806
|
form: "Ask for details",
|
|
1138
1807
|
upload: "Collect files",
|
|
1139
1808
|
agent: "Run a skill or an instruction",
|
|
1140
|
-
review: "A person approves"
|
|
1809
|
+
review: "A person approves",
|
|
1810
|
+
sign: "People e-sign a document",
|
|
1811
|
+
email_draft: "Prepare an email to send",
|
|
1812
|
+
tabular_review: "Review documents in a grid"
|
|
1141
1813
|
},
|
|
1142
1814
|
addNext: "Add the next step",
|
|
1143
1815
|
runs: "Runs \u201C{name}\u201D",
|
|
@@ -1145,6 +1817,14 @@ var DEFAULT_WORKFLOW_CANVAS_LABELS = {
|
|
|
1145
1817
|
fields: "{count} fields",
|
|
1146
1818
|
noFields: "No fields yet",
|
|
1147
1819
|
approvedBy: "A person approves",
|
|
1820
|
+
signers: "{count} signers",
|
|
1821
|
+
chooseDocument: "Choose the document to sign",
|
|
1822
|
+
emailTo: "To {to}",
|
|
1823
|
+
noRecipients: "Add a recipient",
|
|
1824
|
+
reviewColumns: "{count} columns",
|
|
1825
|
+
noColumns: "Choose the columns",
|
|
1826
|
+
assignee: "{name}",
|
|
1827
|
+
remind: "Reminds after {hours}h",
|
|
1148
1828
|
emptyTitle: "Start your workflow",
|
|
1149
1829
|
emptyHint: "Add the first step: what should happen when it starts?",
|
|
1150
1830
|
fitView: "Fit view"
|
|
@@ -1154,9 +1834,12 @@ var STEP_KIND_ICONS = {
|
|
|
1154
1834
|
form: FileInput,
|
|
1155
1835
|
upload: Upload,
|
|
1156
1836
|
agent: Bot,
|
|
1157
|
-
review: ClipboardCheck
|
|
1837
|
+
review: ClipboardCheck,
|
|
1838
|
+
sign: PenLine,
|
|
1839
|
+
email_draft: Mail,
|
|
1840
|
+
tabular_review: Table2
|
|
1158
1841
|
};
|
|
1159
|
-
var KINDS =
|
|
1842
|
+
var KINDS = WORKFLOW_STEP_KINDS;
|
|
1160
1843
|
function AddNext({
|
|
1161
1844
|
from,
|
|
1162
1845
|
onAdd,
|
|
@@ -1209,20 +1892,23 @@ function AddNext({
|
|
|
1209
1892
|
}
|
|
1210
1893
|
function PhaseMark({ phase }) {
|
|
1211
1894
|
if (phase === "running") return /* @__PURE__ */ jsx(Loader2, { className: "wf-kind-text size-4 animate-spin" });
|
|
1895
|
+
if (phase === "waiting") return /* @__PURE__ */ jsx(Hourglass, { className: "wf-kind-text size-4" });
|
|
1212
1896
|
if (phase === "done") return /* @__PURE__ */ jsx(Check, { className: "wf-kind-text size-4" });
|
|
1213
1897
|
if (phase === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-4 text-destructive" });
|
|
1214
1898
|
if (phase === "skipped") return /* @__PURE__ */ jsx(MinusCircle, { className: "size-4 text-muted-foreground" });
|
|
1215
1899
|
return null;
|
|
1216
1900
|
}
|
|
1217
1901
|
function StepNode({ data }) {
|
|
1218
|
-
const { step, phase, summary, icon, l, onAdd, testId } = data;
|
|
1219
|
-
const
|
|
1902
|
+
const { step, phase, summary, assignee, icon, l, onAdd, testId } = data;
|
|
1903
|
+
const kind = stepKindOf(step);
|
|
1904
|
+
const KindIcon = STEP_KIND_ICONS[kind];
|
|
1905
|
+
const redline = step.kind === "agent" && !!step.editDocument;
|
|
1220
1906
|
return /* @__PURE__ */ jsxs(
|
|
1221
1907
|
"div",
|
|
1222
1908
|
{
|
|
1223
1909
|
className: cn(
|
|
1224
1910
|
"wf-node w-64 py-3 pl-4 pr-3 text-left",
|
|
1225
|
-
`wf-kind-${
|
|
1911
|
+
`wf-kind-${kind}`,
|
|
1226
1912
|
phase && `wf-phase-${phase}`
|
|
1227
1913
|
),
|
|
1228
1914
|
"data-testid": `${testId}-node-${step.id}`,
|
|
@@ -1233,15 +1919,44 @@ function StepNode({ data }) {
|
|
|
1233
1919
|
/* @__PURE__ */ jsx("span", { className: "wf-badge flex size-8 shrink-0 items-center justify-center rounded-lg [&_svg]:size-4", children: icon ?? /* @__PURE__ */ jsx(KindIcon, {}) }),
|
|
1234
1920
|
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1235
1921
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
1236
|
-
/* @__PURE__ */ jsx("span", { className: "wf-kind-text text-[10px] font-semibold uppercase tracking-wider", children: l[
|
|
1922
|
+
/* @__PURE__ */ jsx("span", { className: "wf-kind-text text-[10px] font-semibold uppercase tracking-wider", children: l[kind] }),
|
|
1237
1923
|
/* @__PURE__ */ jsx(PhaseMark, { phase })
|
|
1238
1924
|
] }),
|
|
1239
1925
|
/* @__PURE__ */ jsx("p", { className: "truncate text-sm font-semibold leading-snug", children: step.title }),
|
|
1240
1926
|
summary && /* @__PURE__ */ jsx("p", { className: "mt-0.5 line-clamp-2 text-xs leading-snug text-muted-foreground", children: summary }),
|
|
1241
|
-
step.kind === "agent" && step.branch && /* @__PURE__ */ jsxs("
|
|
1242
|
-
/* @__PURE__ */
|
|
1243
|
-
|
|
1244
|
-
|
|
1927
|
+
(redline || step.kind === "agent" && step.branch || assignee) && /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex flex-wrap gap-1", children: [
|
|
1928
|
+
step.kind === "agent" && step.branch && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground", children: [
|
|
1929
|
+
/* @__PURE__ */ jsx(GitBranch, { className: "size-3" }),
|
|
1930
|
+
" ",
|
|
1931
|
+
l.branch
|
|
1932
|
+
] }),
|
|
1933
|
+
redline && /* @__PURE__ */ jsxs(
|
|
1934
|
+
"span",
|
|
1935
|
+
{
|
|
1936
|
+
className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground",
|
|
1937
|
+
"data-testid": `${testId}-node-${step.id}-redline`,
|
|
1938
|
+
children: [
|
|
1939
|
+
/* @__PURE__ */ jsx(FilePenLine, { className: "size-3" }),
|
|
1940
|
+
" ",
|
|
1941
|
+
l.redline
|
|
1942
|
+
]
|
|
1943
|
+
}
|
|
1944
|
+
),
|
|
1945
|
+
assignee && /* @__PURE__ */ jsxs(
|
|
1946
|
+
"span",
|
|
1947
|
+
{
|
|
1948
|
+
className: "inline-flex max-w-full items-center gap-1 truncate rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground",
|
|
1949
|
+
title: assignee,
|
|
1950
|
+
"data-testid": `${testId}-node-${step.id}-assignee`,
|
|
1951
|
+
children: [
|
|
1952
|
+
/* @__PURE__ */ jsx(UserRound, { className: "size-3 shrink-0" }),
|
|
1953
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: l.assignee.replace(
|
|
1954
|
+
"{name}",
|
|
1955
|
+
assignee.charAt(0).toUpperCase() + assignee.slice(1)
|
|
1956
|
+
) })
|
|
1957
|
+
]
|
|
1958
|
+
}
|
|
1959
|
+
)
|
|
1245
1960
|
] })
|
|
1246
1961
|
] })
|
|
1247
1962
|
] }),
|
|
@@ -1290,6 +2005,16 @@ function summaryOf(step, l, workflowTitle) {
|
|
|
1290
2005
|
return step.hint;
|
|
1291
2006
|
case "review":
|
|
1292
2007
|
return step.instructions ? firstWords(step.instructions) : l.approvedBy;
|
|
2008
|
+
case "action": {
|
|
2009
|
+
const a = step.action;
|
|
2010
|
+
if (a.type === "sign")
|
|
2011
|
+
return !a.document ? l.chooseDocument : a.signers.length ? l.signers.replace("{count}", String(a.signers.length)) : void 0;
|
|
2012
|
+
if (a.type === "email_draft") {
|
|
2013
|
+
const to = a.to.find((t) => t.trim());
|
|
2014
|
+
return to ? l.emailTo.replace("{to}", to) : l.noRecipients;
|
|
2015
|
+
}
|
|
2016
|
+
return a.tags.length ? l.reviewColumns.replace("{count}", String(a.tags.length)) : l.noColumns;
|
|
2017
|
+
}
|
|
1293
2018
|
}
|
|
1294
2019
|
}
|
|
1295
2020
|
function WorkflowCanvas({
|
|
@@ -1301,6 +2026,7 @@ function WorkflowCanvas({
|
|
|
1301
2026
|
onAddAfter,
|
|
1302
2027
|
phases,
|
|
1303
2028
|
workflowTitle,
|
|
2029
|
+
assigneeOf,
|
|
1304
2030
|
trigger,
|
|
1305
2031
|
renderIcon,
|
|
1306
2032
|
labels,
|
|
@@ -1339,6 +2065,7 @@ function WorkflowCanvas({
|
|
|
1339
2065
|
step,
|
|
1340
2066
|
phase: phases?.[step.id],
|
|
1341
2067
|
summary: summaryOf(step, l, workflowTitle),
|
|
2068
|
+
assignee: assigneeOf?.(step),
|
|
1342
2069
|
icon: step.icon && renderIcon ? renderIcon(step.icon) : void 0,
|
|
1343
2070
|
l,
|
|
1344
2071
|
onAdd: onAddAfter,
|
|
@@ -1346,7 +2073,18 @@ function WorkflowCanvas({
|
|
|
1346
2073
|
}
|
|
1347
2074
|
}))
|
|
1348
2075
|
];
|
|
1349
|
-
}, [
|
|
2076
|
+
}, [
|
|
2077
|
+
workflow,
|
|
2078
|
+
selected,
|
|
2079
|
+
phases,
|
|
2080
|
+
workflowTitle,
|
|
2081
|
+
assigneeOf,
|
|
2082
|
+
trigger,
|
|
2083
|
+
renderIcon,
|
|
2084
|
+
l,
|
|
2085
|
+
onAddAfter,
|
|
2086
|
+
testId
|
|
2087
|
+
]);
|
|
1350
2088
|
const [nodes, setNodes] = useState(built);
|
|
1351
2089
|
useEffect(() => setNodes(built), [built]);
|
|
1352
2090
|
const edges = useMemo(
|
|
@@ -1560,10 +2298,17 @@ var DEFAULT_WORKFLOW_BUILDER_LABELS = {
|
|
|
1560
2298
|
unknown: "\u201C{step}\u201D waits for a step that does not exist.",
|
|
1561
2299
|
cycle: "\u201C{step}\u201D waits for itself (a loop).",
|
|
1562
2300
|
order: "\u201C{step}\u201D is listed before a step it waits for."
|
|
2301
|
+
},
|
|
2302
|
+
missing: {
|
|
2303
|
+
document: "\u201C{step}\u201D needs a document.",
|
|
2304
|
+
signers: "\u201C{step}\u201D needs at least one signer.",
|
|
2305
|
+
recipients: "\u201C{step}\u201D needs a recipient.",
|
|
2306
|
+
tags: "\u201C{step}\u201D needs at least one column.",
|
|
2307
|
+
documents: "\u201C{step}\u201D needs documents to review."
|
|
1563
2308
|
}
|
|
1564
2309
|
};
|
|
1565
2310
|
var PANEL_WIDTH = 344;
|
|
1566
|
-
var KINDS2 =
|
|
2311
|
+
var KINDS2 = WORKFLOW_STEP_KINDS;
|
|
1567
2312
|
function WorkflowBuilder({
|
|
1568
2313
|
value,
|
|
1569
2314
|
onChange,
|
|
@@ -1572,6 +2317,9 @@ function WorkflowBuilder({
|
|
|
1572
2317
|
eventKinds = [],
|
|
1573
2318
|
tasks = [],
|
|
1574
2319
|
signals = [],
|
|
2320
|
+
people = [],
|
|
2321
|
+
tags = [],
|
|
2322
|
+
documents = [],
|
|
1575
2323
|
compose,
|
|
1576
2324
|
renderIcon,
|
|
1577
2325
|
actions,
|
|
@@ -1594,6 +2342,10 @@ function WorkflowBuilder({
|
|
|
1594
2342
|
const { workflow, trigger } = value;
|
|
1595
2343
|
const steps = workflowSteps(workflow);
|
|
1596
2344
|
const problems = validateWorkflowGraph(steps);
|
|
2345
|
+
const missing = stepConfigProblems(steps);
|
|
2346
|
+
const nameOf = (id) => people.find((p) => p.value === id)?.label;
|
|
2347
|
+
const fields = runFields(workflow);
|
|
2348
|
+
const assigneeOf = (step) => canAssign(step) ? assigneeName(step.assignee, { nameOf, fields }) : void 0;
|
|
1597
2349
|
const titles = useMemo(() => new Map(workflows.map((w) => [w.id, w.title])), [workflows]);
|
|
1598
2350
|
const setWorkflow = (next) => onChange({ ...value, workflow: next });
|
|
1599
2351
|
const addAfter = (from, kind) => {
|
|
@@ -1706,10 +2458,16 @@ function WorkflowBuilder({
|
|
|
1706
2458
|
] }),
|
|
1707
2459
|
actions && /* @__PURE__ */ jsx("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: actions })
|
|
1708
2460
|
] }),
|
|
1709
|
-
problems.length > 0 && /* @__PURE__ */
|
|
1710
|
-
"
|
|
1711
|
-
|
|
1712
|
-
|
|
2461
|
+
problems.length + missing.length > 0 && /* @__PURE__ */ jsxs("ul", { className: "space-y-1 text-sm text-destructive", "data-testid": `${testId}-problems`, children: [
|
|
2462
|
+
problems.map((p, i) => /* @__PURE__ */ jsx("li", { children: l.problems[p.code].replace(
|
|
2463
|
+
"{step}",
|
|
2464
|
+
steps.find((s) => s.id === p.step)?.title ?? p.step
|
|
2465
|
+
) }, i)),
|
|
2466
|
+
missing.map((p, i) => /* @__PURE__ */ jsx("li", { "data-testid": `${testId}-missing-${p.step}-${p.missing}`, children: l.missing[p.missing].replace(
|
|
2467
|
+
"{step}",
|
|
2468
|
+
steps.find((s) => s.id === p.step)?.title ?? p.step
|
|
2469
|
+
) }, `m${i}`))
|
|
2470
|
+
] }),
|
|
1713
2471
|
mode === "design" ? /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
1714
2472
|
/* @__PURE__ */ jsx(
|
|
1715
2473
|
WorkflowCanvas,
|
|
@@ -1722,6 +2480,7 @@ function WorkflowBuilder({
|
|
|
1722
2480
|
onAddAfter: addAfter,
|
|
1723
2481
|
trigger: { title: l.start, summary },
|
|
1724
2482
|
workflowTitle: (id) => titles.get(id),
|
|
2483
|
+
assigneeOf,
|
|
1725
2484
|
renderIcon,
|
|
1726
2485
|
labels: canvasLabels,
|
|
1727
2486
|
reserveRight: panelOpen ? PANEL_WIDTH : 0,
|
|
@@ -1771,6 +2530,9 @@ function WorkflowBuilder({
|
|
|
1771
2530
|
onChange: setWorkflow,
|
|
1772
2531
|
onSelect: setSelected,
|
|
1773
2532
|
workflows,
|
|
2533
|
+
people,
|
|
2534
|
+
tags,
|
|
2535
|
+
documents,
|
|
1774
2536
|
labels: inspectorLabels,
|
|
1775
2537
|
testId: `${testId}-inspector`
|
|
1776
2538
|
}
|
|
@@ -1866,7 +2628,22 @@ function ConnectedWorkflowBuilder({
|
|
|
1866
2628
|
...builderProps
|
|
1867
2629
|
}) {
|
|
1868
2630
|
const l = { ...DEFAULT_CONNECTED_WORKFLOW_BUILDER_LABELS, ...connectedLabels };
|
|
1869
|
-
const { workspaceId } = useConnection();
|
|
2631
|
+
const { workspaceId, status, ensureWorkspaceOpen } = useConnection();
|
|
2632
|
+
const members = useWorkspaceUsers(workspaceId ?? void 0, {
|
|
2633
|
+
enabled: status === "authenticated" && !!workspaceId,
|
|
2634
|
+
beforeFetch: ensureWorkspaceOpen
|
|
2635
|
+
});
|
|
2636
|
+
const tagsQuery = useTags(workspaceId ?? void 0);
|
|
2637
|
+
const docsQuery = useDocuments(workspaceId ?? void 0);
|
|
2638
|
+
const people = (members.data ?? []).map((m) => ({
|
|
2639
|
+
value: m.user.external_id,
|
|
2640
|
+
label: [m.user.given_name, m.user.family_name].filter(Boolean).join(" ") || m.user.email
|
|
2641
|
+
}));
|
|
2642
|
+
const tagOptions = (tagsQuery.data ?? []).map((t) => ({ value: t.external_id, label: t.name }));
|
|
2643
|
+
const documentOptions = (docsQuery.data ?? []).map((d) => ({
|
|
2644
|
+
value: d.external_id,
|
|
2645
|
+
label: d.file_name ?? d.external_id
|
|
2646
|
+
}));
|
|
1870
2647
|
const saved = useWorkflows();
|
|
1871
2648
|
const skills = useSkills();
|
|
1872
2649
|
const agentsQuery = useAgents();
|
|
@@ -1905,7 +2682,7 @@ function ConnectedWorkflowBuilder({
|
|
|
1905
2682
|
}));
|
|
1906
2683
|
const tasks = (conversations.data ?? []).filter((c) => c.status && c.status !== "done").map((c) => ({ value: c.external_id, label: c.title || c.external_id }));
|
|
1907
2684
|
const options = { resolveWorkflow: (wid) => workflows.find((w) => w.id === wid), compose };
|
|
1908
|
-
const problem = triggerProblem(value.trigger) ?? (validateWorkflowGraph(workflowSteps(value.workflow)).length ? "graph" : null);
|
|
2685
|
+
const problem = triggerProblem(value.trigger) ?? (validateWorkflowGraph(workflowSteps(value.workflow)).length || stepConfigProblems(workflowSteps(value.workflow)).length ? "graph" : null);
|
|
1909
2686
|
const busy = create.isPending || update.isPending || run.isPending;
|
|
1910
2687
|
const save = async () => {
|
|
1911
2688
|
if (!workspaceId) return void 0;
|
|
@@ -1927,6 +2704,9 @@ function ConnectedWorkflowBuilder({
|
|
|
1927
2704
|
agents,
|
|
1928
2705
|
eventKinds,
|
|
1929
2706
|
tasks,
|
|
2707
|
+
people,
|
|
2708
|
+
tags: tagOptions,
|
|
2709
|
+
documents: documentOptions,
|
|
1930
2710
|
signals: declaredSignals(saved.data ?? []),
|
|
1931
2711
|
compose,
|
|
1932
2712
|
testId,
|