@arbidocs/blocks 0.4.31 → 0.4.33
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 +256 -214
- package/dist/agents/index.js +7 -5
- package/dist/agents/tasks/ConversationListView.d.ts +58 -0
- package/dist/agents/tasks/ConversationTurnSpeaker.d.ts +16 -0
- package/dist/agents/tasks/NewThreadDialog.d.ts +1 -1
- package/dist/agents/tasks/TaskActivityTimeline.d.ts +1 -1
- package/dist/agents/tasks/TaskFlow.d.ts +22 -0
- package/dist/agents/tasks/TaskInbox.d.ts +26 -0
- package/dist/agents/tasks/TaskReviewDialog.d.ts +22 -0
- package/dist/agents/tasks/TaskRowMenu.d.ts +10 -2
- package/dist/agents/tasks/TaskRunsDialog.d.ts +8 -3
- package/dist/agents/tasks/TaskStartDialog.d.ts +24 -0
- package/dist/agents/tasks/TaskTable.d.ts +1 -1
- package/dist/agents/tasks/ThreadNotifyDialog.d.ts +11 -0
- package/dist/agents/tasks/WorkflowComposer.d.ts +1 -1
- package/dist/agents/tasks/WorkflowsTable.d.ts +7 -0
- package/dist/agents/tasks/compact-thread-activity.d.ts +8 -0
- package/dist/agents/tasks/index.d.ts +10 -0
- package/dist/agents/tasks/taskComposerTypes.d.ts +16 -1
- package/dist/agents/tasks/taskRequest.d.ts +1 -0
- package/dist/agents/tasks/testGrid.d.ts +24 -0
- package/dist/agents/tasks/workflowColumns.d.ts +2 -1
- package/dist/agents/tasks/workflowRows.d.ts +6 -0
- package/dist/agents/workflows/types.d.ts +2 -0
- package/dist/auth/index.cjs +27 -27
- package/dist/auth/index.js +1 -1
- package/dist/chat/Message.d.ts +8 -2
- package/dist/chat/index.cjs +132 -120
- package/dist/chat/index.d.ts +2 -0
- package/dist/chat/index.js +2 -2
- package/dist/chat/participant-tints.d.ts +1 -0
- package/dist/chat/useRecipientDraft.d.ts +14 -0
- package/dist/{chunk-KF4EC5XU.js → chunk-24KQJYSB.js} +3 -3
- package/dist/{chunk-KF4EC5XU.js.map → chunk-24KQJYSB.js.map} +1 -1
- package/dist/{chunk-GVQOBJKR.cjs → chunk-2EAE5JP6.cjs} +7 -4
- package/dist/chunk-2EAE5JP6.cjs.map +1 -0
- package/dist/{chunk-S5HZBXZA.cjs → chunk-2QTT2RZE.cjs} +242 -2
- package/dist/chunk-2QTT2RZE.cjs.map +1 -0
- package/dist/chunk-3AFWGEDJ.cjs +53 -0
- package/dist/chunk-3AFWGEDJ.cjs.map +1 -0
- package/dist/{chunk-4XJZ6AAY.js → chunk-4AWS54US.js} +244 -6
- package/dist/chunk-4AWS54US.js.map +1 -0
- package/dist/{chunk-56BUD74K.cjs → chunk-65THHQVB.cjs} +27 -27
- package/dist/{chunk-56BUD74K.cjs.map → chunk-65THHQVB.cjs.map} +1 -1
- package/dist/{chunk-5B4PXAKI.cjs → chunk-6DNYPLCD.cjs} +21 -7
- package/dist/chunk-6DNYPLCD.cjs.map +1 -0
- package/dist/{chunk-Y2LWA4ZO.js → chunk-6RXUMBTK.js} +1855 -501
- package/dist/chunk-6RXUMBTK.js.map +1 -0
- package/dist/{chunk-UTYQPVIW.cjs → chunk-7QDX2CO4.cjs} +6 -6
- package/dist/{chunk-UTYQPVIW.cjs.map → chunk-7QDX2CO4.cjs.map} +1 -1
- package/dist/{chunk-FRRDPYBR.cjs → chunk-AZ75JUIH.cjs} +74 -5
- package/dist/chunk-AZ75JUIH.cjs.map +1 -0
- package/dist/{chunk-NUPVHEJW.js → chunk-BUHKUKKB.js} +7 -4
- package/dist/chunk-BUHKUKKB.js.map +1 -0
- package/dist/chunk-C7FGONCM.js +124 -0
- package/dist/chunk-C7FGONCM.js.map +1 -0
- package/dist/{chunk-KXMDOTGW.js → chunk-DLBUFHLY.js} +10 -2
- package/dist/chunk-DLBUFHLY.js.map +1 -0
- package/dist/{chunk-ZHLMDJCO.cjs → chunk-DLVX6R6B.cjs} +62 -26
- package/dist/chunk-DLVX6R6B.cjs.map +1 -0
- package/dist/{chunk-JGZTRLKL.cjs → chunk-IA7RTPT3.cjs} +7 -4
- package/dist/chunk-IA7RTPT3.cjs.map +1 -0
- package/dist/{chunk-NJL4LIXX.js → chunk-LFGJAZ5H.js} +11 -8
- package/dist/chunk-LFGJAZ5H.js.map +1 -0
- package/dist/{chunk-IAKUTBPX.js → chunk-LYUO3E6V.js} +3 -3
- package/dist/{chunk-IAKUTBPX.js.map → chunk-LYUO3E6V.js.map} +1 -1
- package/dist/{chunk-EYPPB5CY.cjs → chunk-M2YGPC5N.cjs} +4 -4
- package/dist/{chunk-EYPPB5CY.cjs.map → chunk-M2YGPC5N.cjs.map} +1 -1
- package/dist/{chunk-5ZBP7TCD.cjs → chunk-MJCCBMM5.cjs} +10 -2
- package/dist/chunk-MJCCBMM5.cjs.map +1 -0
- package/dist/chunk-MZL67U2E.cjs +128 -0
- package/dist/chunk-MZL67U2E.cjs.map +1 -0
- package/dist/{chunk-OJSWQM4G.js → chunk-OZJ5PXA6.js} +29 -4
- package/dist/chunk-OZJ5PXA6.js.map +1 -0
- package/dist/{chunk-UBNVIIBT.js → chunk-PXFJDX2C.js} +21 -7
- package/dist/chunk-PXFJDX2C.js.map +1 -0
- package/dist/{chunk-RGHQFJOL.cjs → chunk-QFUF4A4J.cjs} +28 -2
- package/dist/chunk-QFUF4A4J.cjs.map +1 -0
- package/dist/chunk-RFXJYIDV.js +50 -0
- package/dist/chunk-RFXJYIDV.js.map +1 -0
- package/dist/{chunk-CQWRVIJC.cjs → chunk-SEQWI6E4.cjs} +1882 -517
- package/dist/chunk-SEQWI6E4.cjs.map +1 -0
- package/dist/{chunk-QN42OA5J.js → chunk-SFXVNFES.js} +4 -4
- package/dist/chunk-SFXVNFES.js.map +1 -0
- package/dist/{chunk-3NZR6PAG.js → chunk-V6U5KVAR.js} +70 -4
- package/dist/chunk-V6U5KVAR.js.map +1 -0
- package/dist/{chunk-YVIOCITQ.cjs → chunk-VUEZARW5.cjs} +3 -3
- package/dist/chunk-VUEZARW5.cjs.map +1 -0
- package/dist/{chunk-JLOYWXRB.js → chunk-VZGBCBYB.js} +3 -3
- package/dist/chunk-VZGBCBYB.js.map +1 -0
- package/dist/{chunk-ZVPTFTGV.cjs → chunk-WBDK4PIA.cjs} +11 -8
- package/dist/chunk-WBDK4PIA.cjs.map +1 -0
- package/dist/{chunk-ZORQ5M3W.cjs → chunk-WQFGG2BV.cjs} +4 -4
- package/dist/chunk-WQFGG2BV.cjs.map +1 -0
- package/dist/{chunk-C75S6USL.js → chunk-WYVCXY7R.js} +7 -4
- package/dist/chunk-WYVCXY7R.js.map +1 -0
- package/dist/{chunk-WSJVHSGN.js → chunk-XWEJ5LV2.js} +63 -27
- package/dist/chunk-XWEJ5LV2.js.map +1 -0
- package/dist/{chunk-YMHGF6R5.js → chunk-ZCF2JJFA.js} +3 -3
- package/dist/{chunk-YMHGF6R5.js.map → chunk-ZCF2JJFA.js.map} +1 -1
- package/dist/collaboration/index.cjs +45 -41
- package/dist/collaboration/index.js +1 -1
- package/dist/collaboration/mail/MailMessagePreview.d.ts +11 -0
- package/dist/collaboration/mail/index.d.ts +1 -0
- package/dist/connect/index.cjs +33 -33
- package/dist/connect/index.js +4 -4
- package/dist/facts/FactsFilterInput.d.ts +2 -46
- package/dist/facts/FactsToolbar.d.ts +5 -5
- package/dist/facts/index.cjs +27 -124
- package/dist/facts/index.cjs.map +1 -1
- package/dist/facts/index.js +13 -118
- package/dist/facts/index.js.map +1 -1
- package/dist/files/FilesPage.d.ts +1 -1
- package/dist/files/FilesToolbar.d.ts +1 -1
- package/dist/files/FolderPicker.d.ts +2 -1
- package/dist/files/ViewerChrome.d.ts +1 -1
- package/dist/files/bulk/FolderFilterButton.d.ts +3 -2
- package/dist/files/cells/BulkLabelSelect.d.ts +11 -0
- package/dist/files/cells/LabelMultiSelect.d.ts +2 -1
- package/dist/files/cells/index.d.ts +1 -0
- package/dist/files/index.cjs +108 -165
- package/dist/files/index.cjs.map +1 -1
- package/dist/files/index.js +94 -157
- package/dist/files/index.js.map +1 -1
- package/dist/home/index.cjs +19 -19
- package/dist/home/index.cjs.map +1 -1
- package/dist/home/index.js +4 -4
- package/dist/home/index.js.map +1 -1
- package/dist/index.cjs +790 -767
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +20 -68
- package/dist/index.js.map +1 -1
- package/dist/settings/SettingsPanel.d.ts +1 -1
- package/dist/settings/index.cjs +55 -280
- package/dist/settings/index.cjs.map +1 -1
- package/dist/settings/index.js +17 -248
- package/dist/settings/index.js.map +1 -1
- package/dist/shell/FilterInput.d.ts +46 -0
- package/dist/shell/TabHeader.d.ts +5 -1
- package/dist/shell/index.cjs +61 -48
- package/dist/shell/index.d.ts +1 -0
- package/dist/shell/index.js +3 -2
- package/dist/site/index.cjs +62 -62
- package/dist/site/index.js +2 -2
- package/dist/studio/index.cjs +74 -74
- package/dist/studio/index.js +5 -5
- package/dist/workspaces/WorkspaceCard.d.ts +2 -2
- package/dist/workspaces/index.cjs +9 -2
- package/dist/workspaces/index.cjs.map +1 -1
- package/dist/workspaces/index.js +9 -2
- package/dist/workspaces/index.js.map +1 -1
- package/package.json +3 -3
- package/src/blocks.css +4 -0
- package/src/components/grid.css +10 -0
- package/dist/chunk-3NZR6PAG.js.map +0 -1
- package/dist/chunk-4XJZ6AAY.js.map +0 -1
- package/dist/chunk-5B4PXAKI.cjs.map +0 -1
- package/dist/chunk-5ZBP7TCD.cjs.map +0 -1
- package/dist/chunk-C75S6USL.js.map +0 -1
- package/dist/chunk-CQWRVIJC.cjs.map +0 -1
- package/dist/chunk-FRRDPYBR.cjs.map +0 -1
- package/dist/chunk-GVQOBJKR.cjs.map +0 -1
- package/dist/chunk-JGZTRLKL.cjs.map +0 -1
- package/dist/chunk-JLOYWXRB.js.map +0 -1
- package/dist/chunk-KXMDOTGW.js.map +0 -1
- package/dist/chunk-NJL4LIXX.js.map +0 -1
- package/dist/chunk-NUPVHEJW.js.map +0 -1
- package/dist/chunk-OJSWQM4G.js.map +0 -1
- package/dist/chunk-QN42OA5J.js.map +0 -1
- package/dist/chunk-RGHQFJOL.cjs.map +0 -1
- package/dist/chunk-S5HZBXZA.cjs.map +0 -1
- package/dist/chunk-UBNVIIBT.js.map +0 -1
- package/dist/chunk-WSJVHSGN.js.map +0 -1
- package/dist/chunk-Y2LWA4ZO.js.map +0 -1
- package/dist/chunk-YVIOCITQ.cjs.map +0 -1
- package/dist/chunk-ZHLMDJCO.cjs.map +0 -1
- package/dist/chunk-ZORQ5M3W.cjs.map +0 -1
- package/dist/chunk-ZVPTFTGV.cjs.map +0 -1
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { EmptyState } from './chunk-P6GHJSLR.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { FoldSection, QuickActionDialogHeader, AddFilesFirst, ScopePicker, StartTiles } from './chunk-LFGJAZ5H.js';
|
|
4
|
+
import { CellHoverIcon } from './chunk-RFXJYIDV.js';
|
|
5
|
+
import { GridView, SelectionBar, SelectionBarAction } from './chunk-BUHKUKKB.js';
|
|
6
|
+
import { FilterInput } from './chunk-C7FGONCM.js';
|
|
5
7
|
import { ActionLink } from './chunk-S7PSMMRG.js';
|
|
6
|
-
import { DocumentPicker, MultiSelect } from './chunk-
|
|
8
|
+
import { DocumentPicker, TriStateFilterMenu, MultiSelect } from './chunk-4AWS54US.js';
|
|
9
|
+
import { TabHeader } from './chunk-PXFJDX2C.js';
|
|
7
10
|
import { ToneBadge } from './chunk-DPLRHEJZ.js';
|
|
8
|
-
import { TabHeader } from './chunk-UBNVIIBT.js';
|
|
9
11
|
import { useBlocksEnvironment } from './chunk-76JDDMSP.js';
|
|
10
12
|
import { formatCount, initials } from './chunk-OXF2IFXG.js';
|
|
11
13
|
import { ModalHeader } from './chunk-CPMNAJLF.js';
|
|
12
14
|
import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
|
|
13
|
-
import { memo, forwardRef, useState, useMemo, useId, useEffect, useRef, useCallback } from 'react';
|
|
14
|
-
import { cn, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Textarea, Input, Switch, Button, Collapsible, CollapsibleTrigger, CollapsibleContent, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Tooltip, TooltipTrigger, TooltipContent, Badge, Slider, UserEntity, getEntityColorStyles, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Popover, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandItem, VisibilityToggle, EntityPill, DropdownMenuSeparator } from '@arbidocs/react/ui';
|
|
15
|
+
import { memo, forwardRef, useState, useMemo, useId, useEffect, useRef, useCallback, useLayoutEffect } from 'react';
|
|
16
|
+
import { cn, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Textarea, Input, Switch, Button, Collapsible, CollapsibleTrigger, CollapsibleContent, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Tooltip, TooltipTrigger, TooltipContent, Badge, Slider, UserEntity, getEntityColorStyles, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, Popover, PopoverTrigger, PopoverContent, Command, CommandInput, CommandList, CommandEmpty, CommandItem, VisibilityToggle, EntityPill, ThreadVisibilityIcon, DialogClose, DropdownMenuSeparator, badgeVariants, Checkbox } from '@arbidocs/react/ui';
|
|
15
17
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
16
|
-
import { ChevronDown, ChevronRight, Plus, Trash2, Loader2, Play, MessageSquare, Eye, ClipboardList, Pencil, Copy, Bot, Sparkles, Wand2, X, Globe, Download, Lock, ListChecks, AlertTriangle, FileX, SkipForward, Check, FileText, CornerDownRight, MessageSquareReply, UserCheck, AlertCircle, KeyRound, Workflow, ChevronsUpDown, ChevronsDownUp, ListTodo, CheckCheck,
|
|
18
|
+
import { ChevronDown, ChevronRight, Plus, Trash2, Loader2, Play, MessageSquare, Eye, ClipboardList, Pencil, Copy, Bot, Sparkles, Wand2, X, Globe, Download, Lock, ListChecks, AlertTriangle, FileX, SkipForward, Check, FileText, CornerDownRight, MessageSquareReply, UserCheck, AlertCircle, KeyRound, Workflow, ChevronsUpDown, ChevronsDownUp, ListTodo, CheckCheck, MoreHorizontal, CalendarClock, History, ArrowRight, ChevronUp, Pause, Activity, Hourglass, MoreVertical, TriangleAlert, CheckSquare, Square, CheckCircle2, ArrowLeft, LayoutGrid, List, CircleDashed, RotateCcw, ListPlus, UserRoundCog, Link2, Clock, Bell, MousePointerClick, CircleDot, Zap } from 'lucide-react';
|
|
17
19
|
|
|
18
20
|
// src/agents/workflows/types.ts
|
|
19
21
|
var EMPTY_WORKFLOW_SCOPE = { folders: [], labels: [] };
|
|
@@ -3411,144 +3413,6 @@ function TaskReviewActions({
|
|
|
3411
3413
|
] })
|
|
3412
3414
|
] });
|
|
3413
3415
|
}
|
|
3414
|
-
|
|
3415
|
-
// src/agents/tasks/taskRows.ts
|
|
3416
|
-
var MAX_TASK_DEPTH = 5;
|
|
3417
|
-
var ownerExtId = (task) => task.signoff_ext_id || task.owner_ext_id || task.created_by_ext_id || null;
|
|
3418
|
-
var isPlainTodo = (task) => !task.agent_ext_id && !task.has_agent_action && !task.skill_ref;
|
|
3419
|
-
function indexTasks(tasks) {
|
|
3420
|
-
const byId = new Map(tasks.map((t) => [t.external_id, t]));
|
|
3421
|
-
const kids = /* @__PURE__ */ new Map();
|
|
3422
|
-
const parentOf = /* @__PURE__ */ new Map();
|
|
3423
|
-
for (const task of tasks) {
|
|
3424
|
-
const parent = task.parent_conversation_ext_id;
|
|
3425
|
-
if (parent && parent !== task.external_id && byId.has(parent)) {
|
|
3426
|
-
parentOf.set(task.external_id, parent);
|
|
3427
|
-
const list = kids.get(parent);
|
|
3428
|
-
if (list) list.push(task);
|
|
3429
|
-
else kids.set(parent, [task]);
|
|
3430
|
-
}
|
|
3431
|
-
}
|
|
3432
|
-
return { byId, kids, parentOf };
|
|
3433
|
-
}
|
|
3434
|
-
function descendantIds(tree, id) {
|
|
3435
|
-
const out = [];
|
|
3436
|
-
const seen = /* @__PURE__ */ new Set([id]);
|
|
3437
|
-
const stack = [id];
|
|
3438
|
-
while (stack.length) {
|
|
3439
|
-
for (const child of tree.kids.get(stack.pop()) ?? []) {
|
|
3440
|
-
if (seen.has(child.external_id)) continue;
|
|
3441
|
-
seen.add(child.external_id);
|
|
3442
|
-
out.push(child.external_id);
|
|
3443
|
-
stack.push(child.external_id);
|
|
3444
|
-
}
|
|
3445
|
-
}
|
|
3446
|
-
return out;
|
|
3447
|
-
}
|
|
3448
|
-
function subtreeLevels(tree, id, seen = /* @__PURE__ */ new Set()) {
|
|
3449
|
-
if (seen.has(id)) return 0;
|
|
3450
|
-
const next = new Set(seen).add(id);
|
|
3451
|
-
let deepest = 0;
|
|
3452
|
-
for (const child of tree.kids.get(id) ?? []) {
|
|
3453
|
-
deepest = Math.max(deepest, subtreeLevels(tree, child.external_id, next));
|
|
3454
|
-
}
|
|
3455
|
-
return 1 + deepest;
|
|
3456
|
-
}
|
|
3457
|
-
function levelOf(tree, id) {
|
|
3458
|
-
let level = 1;
|
|
3459
|
-
const seen = /* @__PURE__ */ new Set([id]);
|
|
3460
|
-
for (let at = tree.parentOf.get(id); at && !seen.has(at); at = tree.parentOf.get(at)) {
|
|
3461
|
-
seen.add(at);
|
|
3462
|
-
level += 1;
|
|
3463
|
-
}
|
|
3464
|
-
return level;
|
|
3465
|
-
}
|
|
3466
|
-
function moveTargets(tasks, task) {
|
|
3467
|
-
const tree = indexTasks(tasks);
|
|
3468
|
-
const banned = /* @__PURE__ */ new Set([task.external_id, ...descendantIds(tree, task.external_id)]);
|
|
3469
|
-
const height = subtreeLevels(tree, task.external_id);
|
|
3470
|
-
return tasks.filter(
|
|
3471
|
-
(t) => !banned.has(t.external_id) && levelOf(tree, t.external_id) + height <= MAX_TASK_DEPTH
|
|
3472
|
-
);
|
|
3473
|
-
}
|
|
3474
|
-
var sameStats = (a, b) => a === b || a !== void 0 && b !== void 0 && a.done === b.done && a.total === b.total;
|
|
3475
|
-
function buildTaskRows(tasks, filter, collapsed, compare, options = {}) {
|
|
3476
|
-
const tree = indexTasks(tasks);
|
|
3477
|
-
const { kids, parentOf } = tree;
|
|
3478
|
-
const sorted = (list) => compare ? [...list].sort(compare) : list;
|
|
3479
|
-
const query = options.query?.trim().toLowerCase() ?? "";
|
|
3480
|
-
const titleOf = options.titleOf ?? ((t) => t.title ?? "");
|
|
3481
|
-
let included = null;
|
|
3482
|
-
let matched = null;
|
|
3483
|
-
if (filter !== "all" || query) {
|
|
3484
|
-
matched = /* @__PURE__ */ new Set();
|
|
3485
|
-
included = /* @__PURE__ */ new Set();
|
|
3486
|
-
for (const task of tasks) {
|
|
3487
|
-
const statusOk = filter === "all" || asTaskStatus(task.status) === filter;
|
|
3488
|
-
const textOk = !query || `${titleOf(task)} ${task.description ?? ""}`.toLowerCase().includes(query);
|
|
3489
|
-
if (!statusOk || !textOk) continue;
|
|
3490
|
-
matched.add(task.external_id);
|
|
3491
|
-
for (let at = task.external_id; at && !included.has(at); at = parentOf.get(at)) {
|
|
3492
|
-
included.add(at);
|
|
3493
|
-
}
|
|
3494
|
-
}
|
|
3495
|
-
}
|
|
3496
|
-
const shown = (list) => included ? list.filter((t) => included.has(t.external_id)) : list;
|
|
3497
|
-
const build = (task, depth, seen) => {
|
|
3498
|
-
const nextSeen = new Set(seen).add(task.external_id);
|
|
3499
|
-
return {
|
|
3500
|
-
task,
|
|
3501
|
-
depth,
|
|
3502
|
-
context: matched ? !matched.has(task.external_id) : false,
|
|
3503
|
-
children: sorted(shown(kids.get(task.external_id) ?? [])).filter((child) => !nextSeen.has(child.external_id)).map((child) => build(child, depth + 1, nextSeen))
|
|
3504
|
-
};
|
|
3505
|
-
};
|
|
3506
|
-
const sections = new Map([
|
|
3507
|
-
...STATUS_ORDER.map((s) => [s, []]),
|
|
3508
|
-
["sorted", []]
|
|
3509
|
-
]);
|
|
3510
|
-
const sectionOf = (task) => compare ? "sorted" : asTaskStatus(task.status);
|
|
3511
|
-
const roots = tasks.filter((t) => !parentOf.has(t.external_id));
|
|
3512
|
-
for (const task of sorted(shown(roots))) {
|
|
3513
|
-
sections.get(sectionOf(task))?.push(build(task, 0, /* @__PURE__ */ new Set()));
|
|
3514
|
-
}
|
|
3515
|
-
const cache = options.cache;
|
|
3516
|
-
const used = /* @__PURE__ */ new Set();
|
|
3517
|
-
const rows = [];
|
|
3518
|
-
const walk = (node, parentId, setSize, posInSet) => {
|
|
3519
|
-
const id = node.task.external_id;
|
|
3520
|
-
const expanded = !collapsed.has(id);
|
|
3521
|
-
const all = kids.get(id);
|
|
3522
|
-
const childStats = all ? { done: all.filter((c) => asTaskStatus(c.status) === "done").length, total: all.length } : void 0;
|
|
3523
|
-
let row = {
|
|
3524
|
-
external_id: id,
|
|
3525
|
-
task: node.task,
|
|
3526
|
-
depth: node.depth,
|
|
3527
|
-
childStats,
|
|
3528
|
-
expanded,
|
|
3529
|
-
parentId,
|
|
3530
|
-
setSize,
|
|
3531
|
-
posInSet,
|
|
3532
|
-
context: node.context
|
|
3533
|
-
};
|
|
3534
|
-
const prev = cache?.get(id);
|
|
3535
|
-
if (prev && prev.task === row.task && prev.depth === row.depth && prev.expanded === row.expanded && prev.parentId === row.parentId && prev.setSize === row.setSize && prev.posInSet === row.posInSet && prev.context === row.context && sameStats(prev.childStats, row.childStats)) {
|
|
3536
|
-
row = prev;
|
|
3537
|
-
}
|
|
3538
|
-
used.add(id);
|
|
3539
|
-
cache?.set(id, row);
|
|
3540
|
-
rows.push(row);
|
|
3541
|
-
if (expanded) {
|
|
3542
|
-
node.children.forEach((child, i) => walk(child, id, node.children.length, i + 1));
|
|
3543
|
-
}
|
|
3544
|
-
};
|
|
3545
|
-
const ordered = [...STATUS_ORDER, "sorted"].flatMap((s) => sections.get(s) ?? []);
|
|
3546
|
-
ordered.forEach((node, i) => walk(node, null, ordered.length, i + 1));
|
|
3547
|
-
if (cache) {
|
|
3548
|
-
for (const id of [...cache.keys()]) if (!used.has(id)) cache.delete(id);
|
|
3549
|
-
}
|
|
3550
|
-
return rows;
|
|
3551
|
-
}
|
|
3552
3416
|
function TaskRowMenu({
|
|
3553
3417
|
task,
|
|
3554
3418
|
status,
|
|
@@ -3557,6 +3421,10 @@ function TaskRowMenu({
|
|
|
3557
3421
|
canAdmin,
|
|
3558
3422
|
canEdit,
|
|
3559
3423
|
labels,
|
|
3424
|
+
canMarkDone = canEdit,
|
|
3425
|
+
canReopen = canEdit,
|
|
3426
|
+
selected = false,
|
|
3427
|
+
onToggleSelected,
|
|
3560
3428
|
onMarkDone,
|
|
3561
3429
|
onReopen,
|
|
3562
3430
|
onAddSubtask,
|
|
@@ -3565,6 +3433,7 @@ function TaskRowMenu({
|
|
|
3565
3433
|
onMoveTo,
|
|
3566
3434
|
onChangeOwner,
|
|
3567
3435
|
onOpenActivity,
|
|
3436
|
+
onToggleShared,
|
|
3568
3437
|
onGrantAccess,
|
|
3569
3438
|
reviewActions
|
|
3570
3439
|
}) {
|
|
@@ -3585,6 +3454,7 @@ function TaskRowMenu({
|
|
|
3585
3454
|
}
|
|
3586
3455
|
) }),
|
|
3587
3456
|
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
|
|
3457
|
+
onToggleSelected && /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: onToggleSelected, "data-testid": `task-select-${id}`, children: selected ? "Deselect task" : "Select task" }),
|
|
3588
3458
|
reviewActions && /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5", children: typeof reviewActions === "function" ? reviewActions(() => setOpen(false)) : reviewActions }),
|
|
3589
3459
|
isOwner && onGrantAccess && task.pending_auth_request_id && /* @__PURE__ */ jsxs(
|
|
3590
3460
|
DropdownMenuItem,
|
|
@@ -3598,10 +3468,18 @@ function TaskRowMenu({
|
|
|
3598
3468
|
]
|
|
3599
3469
|
}
|
|
3600
3470
|
),
|
|
3601
|
-
isChat || !canEdit ? null : done ? /* @__PURE__ */ jsxs(
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3471
|
+
isChat || !canEdit ? null : done ? canReopen && /* @__PURE__ */ jsxs(
|
|
3472
|
+
DropdownMenuItem,
|
|
3473
|
+
{
|
|
3474
|
+
disabled: busy,
|
|
3475
|
+
onSelect: onReopen,
|
|
3476
|
+
"data-testid": `task-reopen-${id}`,
|
|
3477
|
+
children: [
|
|
3478
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "mr-2 size-4", "aria-hidden": true }),
|
|
3479
|
+
labels.reopen
|
|
3480
|
+
]
|
|
3481
|
+
}
|
|
3482
|
+
) : canMarkDone && /* @__PURE__ */ jsxs(
|
|
3605
3483
|
DropdownMenuItem,
|
|
3606
3484
|
{
|
|
3607
3485
|
disabled: busy,
|
|
@@ -3617,6 +3495,7 @@ function TaskRowMenu({
|
|
|
3617
3495
|
/* @__PURE__ */ jsx(History, { className: "mr-2 size-4", "aria-hidden": true }),
|
|
3618
3496
|
labels.activity
|
|
3619
3497
|
] }),
|
|
3498
|
+
isOwner && onToggleShared && /* @__PURE__ */ jsx(DropdownMenuItem, { disabled: busy, onSelect: onToggleShared, children: task.is_shared ? "Make private" : "Share with workspace" }),
|
|
3620
3499
|
canEdit && onAddSubtask && /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: onAddSubtask, "data-testid": `task-add-subtask-${id}`, children: [
|
|
3621
3500
|
/* @__PURE__ */ jsx(ListPlus, { className: "mr-2 size-4", "aria-hidden": true }),
|
|
3622
3501
|
labels.addSubtask
|
|
@@ -3633,7 +3512,7 @@ function TaskRowMenu({
|
|
|
3633
3512
|
/* @__PURE__ */ jsx(Pencil, { className: "mr-2 size-4", "aria-hidden": true }),
|
|
3634
3513
|
isChat ? labels.rename : labels.edit
|
|
3635
3514
|
] }),
|
|
3636
|
-
canEdit && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3515
|
+
canEdit && onDelete && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3637
3516
|
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
3638
3517
|
/* @__PURE__ */ jsxs(
|
|
3639
3518
|
DropdownMenuItem,
|
|
@@ -3856,6 +3735,144 @@ function applyColumnWidthRules(api, gridWidth, rules) {
|
|
|
3856
3735
|
}
|
|
3857
3736
|
}
|
|
3858
3737
|
|
|
3738
|
+
// src/agents/tasks/taskRows.ts
|
|
3739
|
+
var MAX_TASK_DEPTH = 5;
|
|
3740
|
+
var ownerExtId = (task) => task.signoff_ext_id || task.owner_ext_id || task.created_by_ext_id || null;
|
|
3741
|
+
var isPlainTodo = (task) => !task.agent_ext_id && !task.has_agent_action && !task.skill_ref;
|
|
3742
|
+
function indexTasks(tasks) {
|
|
3743
|
+
const byId = new Map(tasks.map((t) => [t.external_id, t]));
|
|
3744
|
+
const kids = /* @__PURE__ */ new Map();
|
|
3745
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
3746
|
+
for (const task of tasks) {
|
|
3747
|
+
const parent = task.parent_conversation_ext_id;
|
|
3748
|
+
if (parent && parent !== task.external_id && byId.has(parent)) {
|
|
3749
|
+
parentOf.set(task.external_id, parent);
|
|
3750
|
+
const list = kids.get(parent);
|
|
3751
|
+
if (list) list.push(task);
|
|
3752
|
+
else kids.set(parent, [task]);
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
return { byId, kids, parentOf };
|
|
3756
|
+
}
|
|
3757
|
+
function descendantIds(tree, id) {
|
|
3758
|
+
const out = [];
|
|
3759
|
+
const seen = /* @__PURE__ */ new Set([id]);
|
|
3760
|
+
const stack = [id];
|
|
3761
|
+
while (stack.length) {
|
|
3762
|
+
for (const child of tree.kids.get(stack.pop()) ?? []) {
|
|
3763
|
+
if (seen.has(child.external_id)) continue;
|
|
3764
|
+
seen.add(child.external_id);
|
|
3765
|
+
out.push(child.external_id);
|
|
3766
|
+
stack.push(child.external_id);
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
return out;
|
|
3770
|
+
}
|
|
3771
|
+
function subtreeLevels(tree, id, seen = /* @__PURE__ */ new Set()) {
|
|
3772
|
+
if (seen.has(id)) return 0;
|
|
3773
|
+
const next = new Set(seen).add(id);
|
|
3774
|
+
let deepest = 0;
|
|
3775
|
+
for (const child of tree.kids.get(id) ?? []) {
|
|
3776
|
+
deepest = Math.max(deepest, subtreeLevels(tree, child.external_id, next));
|
|
3777
|
+
}
|
|
3778
|
+
return 1 + deepest;
|
|
3779
|
+
}
|
|
3780
|
+
function levelOf(tree, id) {
|
|
3781
|
+
let level = 1;
|
|
3782
|
+
const seen = /* @__PURE__ */ new Set([id]);
|
|
3783
|
+
for (let at = tree.parentOf.get(id); at && !seen.has(at); at = tree.parentOf.get(at)) {
|
|
3784
|
+
seen.add(at);
|
|
3785
|
+
level += 1;
|
|
3786
|
+
}
|
|
3787
|
+
return level;
|
|
3788
|
+
}
|
|
3789
|
+
function moveTargets(tasks, task) {
|
|
3790
|
+
const tree = indexTasks(tasks);
|
|
3791
|
+
const banned = /* @__PURE__ */ new Set([task.external_id, ...descendantIds(tree, task.external_id)]);
|
|
3792
|
+
const height = subtreeLevels(tree, task.external_id);
|
|
3793
|
+
return tasks.filter(
|
|
3794
|
+
(t) => !banned.has(t.external_id) && levelOf(tree, t.external_id) + height <= MAX_TASK_DEPTH
|
|
3795
|
+
);
|
|
3796
|
+
}
|
|
3797
|
+
var sameStats = (a, b) => a === b || a !== void 0 && b !== void 0 && a.done === b.done && a.total === b.total;
|
|
3798
|
+
function buildTaskRows(tasks, filter, collapsed, compare, options = {}) {
|
|
3799
|
+
const tree = indexTasks(tasks);
|
|
3800
|
+
const { kids, parentOf } = tree;
|
|
3801
|
+
const sorted = (list) => compare ? [...list].sort(compare) : list;
|
|
3802
|
+
const query = options.query?.trim().toLowerCase() ?? "";
|
|
3803
|
+
const titleOf = options.titleOf ?? ((t) => t.title ?? "");
|
|
3804
|
+
let included = null;
|
|
3805
|
+
let matched = null;
|
|
3806
|
+
if (filter !== "all" || query) {
|
|
3807
|
+
matched = /* @__PURE__ */ new Set();
|
|
3808
|
+
included = /* @__PURE__ */ new Set();
|
|
3809
|
+
for (const task of tasks) {
|
|
3810
|
+
const statusOk = filter === "all" || asTaskStatus(task.status) === filter;
|
|
3811
|
+
const textOk = !query || `${titleOf(task)} ${task.description ?? ""}`.toLowerCase().includes(query);
|
|
3812
|
+
if (!statusOk || !textOk) continue;
|
|
3813
|
+
matched.add(task.external_id);
|
|
3814
|
+
for (let at = task.external_id; at && !included.has(at); at = parentOf.get(at)) {
|
|
3815
|
+
included.add(at);
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
}
|
|
3819
|
+
const shown = (list) => included ? list.filter((t) => included.has(t.external_id)) : list;
|
|
3820
|
+
const build = (task, depth, seen) => {
|
|
3821
|
+
const nextSeen = new Set(seen).add(task.external_id);
|
|
3822
|
+
return {
|
|
3823
|
+
task,
|
|
3824
|
+
depth,
|
|
3825
|
+
context: matched ? !matched.has(task.external_id) : false,
|
|
3826
|
+
children: sorted(shown(kids.get(task.external_id) ?? [])).filter((child) => !nextSeen.has(child.external_id)).map((child) => build(child, depth + 1, nextSeen))
|
|
3827
|
+
};
|
|
3828
|
+
};
|
|
3829
|
+
const sections = new Map([
|
|
3830
|
+
...STATUS_ORDER.map((s) => [s, []]),
|
|
3831
|
+
["sorted", []]
|
|
3832
|
+
]);
|
|
3833
|
+
const sectionOf = (task) => compare ? "sorted" : asTaskStatus(task.status);
|
|
3834
|
+
const roots = tasks.filter((t) => !parentOf.has(t.external_id));
|
|
3835
|
+
for (const task of sorted(shown(roots))) {
|
|
3836
|
+
sections.get(sectionOf(task))?.push(build(task, 0, /* @__PURE__ */ new Set()));
|
|
3837
|
+
}
|
|
3838
|
+
const cache = options.cache;
|
|
3839
|
+
const used = /* @__PURE__ */ new Set();
|
|
3840
|
+
const rows = [];
|
|
3841
|
+
const walk = (node, parentId, setSize, posInSet) => {
|
|
3842
|
+
const id = node.task.external_id;
|
|
3843
|
+
const expanded = !collapsed.has(id);
|
|
3844
|
+
const all = kids.get(id);
|
|
3845
|
+
const childStats = all ? { done: all.filter((c) => asTaskStatus(c.status) === "done").length, total: all.length } : void 0;
|
|
3846
|
+
let row = {
|
|
3847
|
+
external_id: id,
|
|
3848
|
+
task: node.task,
|
|
3849
|
+
depth: node.depth,
|
|
3850
|
+
childStats,
|
|
3851
|
+
expanded,
|
|
3852
|
+
parentId,
|
|
3853
|
+
setSize,
|
|
3854
|
+
posInSet,
|
|
3855
|
+
context: node.context
|
|
3856
|
+
};
|
|
3857
|
+
const prev = cache?.get(id);
|
|
3858
|
+
if (prev && prev.task === row.task && prev.depth === row.depth && prev.expanded === row.expanded && prev.parentId === row.parentId && prev.setSize === row.setSize && prev.posInSet === row.posInSet && prev.context === row.context && sameStats(prev.childStats, row.childStats)) {
|
|
3859
|
+
row = prev;
|
|
3860
|
+
}
|
|
3861
|
+
used.add(id);
|
|
3862
|
+
cache?.set(id, row);
|
|
3863
|
+
rows.push(row);
|
|
3864
|
+
if (expanded) {
|
|
3865
|
+
node.children.forEach((child, i) => walk(child, id, node.children.length, i + 1));
|
|
3866
|
+
}
|
|
3867
|
+
};
|
|
3868
|
+
const ordered = [...STATUS_ORDER, "sorted"].flatMap((s) => sections.get(s) ?? []);
|
|
3869
|
+
ordered.forEach((node, i) => walk(node, null, ordered.length, i + 1));
|
|
3870
|
+
if (cache) {
|
|
3871
|
+
for (const id of [...cache.keys()]) if (!used.has(id)) cache.delete(id);
|
|
3872
|
+
}
|
|
3873
|
+
return rows;
|
|
3874
|
+
}
|
|
3875
|
+
|
|
3859
3876
|
// src/agents/tasks/taskTableLabels.ts
|
|
3860
3877
|
var DEFAULT_TASK_LIST_LABELS = {
|
|
3861
3878
|
filterAll: "All",
|
|
@@ -4584,29 +4601,819 @@ function TaskTable(props) {
|
|
|
4584
4601
|
empty: l.moveToEmpty,
|
|
4585
4602
|
cancel: l.moveToCancel
|
|
4586
4603
|
},
|
|
4587
|
-
testId: "task-owner"
|
|
4604
|
+
testId: "task-owner"
|
|
4605
|
+
}
|
|
4606
|
+
),
|
|
4607
|
+
moving && props.onMove && /* @__PURE__ */ jsx(
|
|
4608
|
+
TaskMoveDialog,
|
|
4609
|
+
{
|
|
4610
|
+
open: true,
|
|
4611
|
+
onOpenChange: (open) => !open && setMoving(null),
|
|
4612
|
+
options: moveTargets(tasks, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
|
|
4613
|
+
currentParentId: moving.parent_conversation_ext_id,
|
|
4614
|
+
onPick: (parentId) => props.onMove?.(moving, parentId),
|
|
4615
|
+
labels: {
|
|
4616
|
+
title: l.moveToTitle(nameOf(moving)),
|
|
4617
|
+
none: l.moveToNone,
|
|
4618
|
+
search: l.moveToSearch,
|
|
4619
|
+
empty: l.moveToEmpty,
|
|
4620
|
+
cancel: l.moveToCancel
|
|
4621
|
+
}
|
|
4622
|
+
}
|
|
4623
|
+
)
|
|
4624
|
+
]
|
|
4625
|
+
}
|
|
4626
|
+
);
|
|
4627
|
+
}
|
|
4628
|
+
function TaskInbox(p) {
|
|
4629
|
+
const [filterOpen, setFilterOpen] = useState(false);
|
|
4630
|
+
const [statusFilters, setStatusFilters] = useState(
|
|
4631
|
+
() => /* @__PURE__ */ new Map([["done", "exclude"]])
|
|
4632
|
+
);
|
|
4633
|
+
const [localQuery, setLocalQuery] = useState("");
|
|
4634
|
+
const [searchFields, setSearchFields] = useState(["text", "labels"]);
|
|
4635
|
+
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
4636
|
+
const [collapsed, setCollapsed] = useState(/* @__PURE__ */ new Set());
|
|
4637
|
+
const [moving, setMoving] = useState(null);
|
|
4638
|
+
const [handingOff, setHandingOff] = useState(null);
|
|
4639
|
+
const l = { ...DEFAULT_TASK_LIST_LABELS, ...p.labels };
|
|
4640
|
+
const nameOf = (t) => t.title?.trim() || t.workflow_ext_id && p.workflowNames?.[t.workflow_ext_id] || l.untitled;
|
|
4641
|
+
const all = p.tasks.filter((t) => t.status != null);
|
|
4642
|
+
const filterText = p.filterText ?? localQuery;
|
|
4643
|
+
const q = filterText.trim().toLowerCase();
|
|
4644
|
+
const included = [...statusFilters].filter(([, state]) => state === "include").map(([id]) => id);
|
|
4645
|
+
const statusMatches = (t) => statusFilters.get(asTaskStatus(t.status)) !== "exclude" && (!included.length || included.includes(asTaskStatus(t.status)));
|
|
4646
|
+
const rows = all.filter(
|
|
4647
|
+
(t) => statusMatches(t) && (!q || [
|
|
4648
|
+
searchFields.includes("text") ? `${nameOf(t)} ${t.description ?? ""}` : "",
|
|
4649
|
+
searchFields.includes("labels") && t.workflow_ext_id ? p.workflowNames?.[t.workflow_ext_id] ?? "" : ""
|
|
4650
|
+
].join(" ").toLowerCase().includes(q))
|
|
4651
|
+
);
|
|
4652
|
+
const hasActiveFilters = !!q || [...statusFilters.values()].some((state) => state != null);
|
|
4653
|
+
const selectedTasks = all.filter((t) => selected.has(t.external_id));
|
|
4654
|
+
const canEdit = (t) => t.is_owner !== false || Boolean(p.canEditShared);
|
|
4655
|
+
const markable = (t) => t.status !== "done" && t.status !== "generating" && canEdit(t) && !t.in_progress;
|
|
4656
|
+
const markableTasks = selectedTasks.filter(markable);
|
|
4657
|
+
const deletableTasks = selectedTasks.filter((t) => t.is_owner !== false || p.isWorkspaceOwner);
|
|
4658
|
+
const clearSelection = () => setSelected(/* @__PURE__ */ new Set());
|
|
4659
|
+
const toggle = (set, id) => set((old) => {
|
|
4660
|
+
const next = new Set(old);
|
|
4661
|
+
if (next.has(id)) next.delete(id);
|
|
4662
|
+
else next.add(id);
|
|
4663
|
+
return next;
|
|
4664
|
+
});
|
|
4665
|
+
p.renderPerson ?? ((value) => /* @__PURE__ */ jsx(PersonPill, { person: value }));
|
|
4666
|
+
const taskById = new Map(all.map((t) => [t.external_id, t]));
|
|
4667
|
+
const visible = new Set(rows.map((t) => t.external_id));
|
|
4668
|
+
for (const task of rows) {
|
|
4669
|
+
let id = task.parent_conversation_ext_id;
|
|
4670
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4671
|
+
while (id && taskById.has(id) && !seen.has(id)) {
|
|
4672
|
+
seen.add(id);
|
|
4673
|
+
visible.add(id);
|
|
4674
|
+
id = taskById.get(id)?.parent_conversation_ext_id;
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4677
|
+
const listed = all.filter((t) => visible.has(t.external_id));
|
|
4678
|
+
const roots = listed.filter(
|
|
4679
|
+
(t) => !t.parent_conversation_ext_id || !visible.has(t.parent_conversation_ext_id)
|
|
4680
|
+
);
|
|
4681
|
+
const workflows = (p.workflows ?? []).filter((w) => {
|
|
4682
|
+
const runs = roots.filter((t) => t.workflow_ext_id === w.external_id);
|
|
4683
|
+
return runs.length > 0 || !included.length && (!q || w.name.toLowerCase().includes(q));
|
|
4684
|
+
});
|
|
4685
|
+
const workflowIds = new Set(workflows.map((w) => w.external_id));
|
|
4686
|
+
const order = (a, b) => {
|
|
4687
|
+
const weight = (t) => t.pending_auth_request_id || t.last_error ? 0 : t.status === "ready_for_review" ? 1 : t.status === "todo" ? 2 : t.status === "generating" ? 3 : 4;
|
|
4688
|
+
return weight(a) - weight(b) || (b.updated_at ?? "").localeCompare(a.updated_at ?? "");
|
|
4689
|
+
};
|
|
4690
|
+
const renderTask = (task, depth = 0) => {
|
|
4691
|
+
const id = task.external_id;
|
|
4692
|
+
const status = asTaskStatus(task.status);
|
|
4693
|
+
const busy = p.busyId === id;
|
|
4694
|
+
const children = listed.filter((t) => t.parent_conversation_ext_id === id).sort(order);
|
|
4695
|
+
const outputs = p.outputsByTask?.[id] ?? [];
|
|
4696
|
+
return /* @__PURE__ */ jsxs("li", { "data-testid": `task-inbox-row-${id}`, children: [
|
|
4697
|
+
/* @__PURE__ */ jsxs(
|
|
4698
|
+
"div",
|
|
4699
|
+
{
|
|
4700
|
+
className: cn(
|
|
4701
|
+
"relative flex cursor-pointer items-start gap-2 border-b py-3 hover:bg-muted/40",
|
|
4702
|
+
selected.has(id) && "bg-muted/60"
|
|
4703
|
+
),
|
|
4704
|
+
onClick: (event) => {
|
|
4705
|
+
if (!event.target.closest(
|
|
4706
|
+
'button, a, input, select, textarea, [role="menuitem"], [role="checkbox"], [role="combobox"]'
|
|
4707
|
+
)) {
|
|
4708
|
+
p.onOpenThread(id, task);
|
|
4709
|
+
}
|
|
4710
|
+
},
|
|
4711
|
+
style: { paddingLeft: `${Math.min(depth, 5) * 20}px` },
|
|
4712
|
+
children: [
|
|
4713
|
+
children.length > 0 && /* @__PURE__ */ jsx(
|
|
4714
|
+
Button,
|
|
4715
|
+
{
|
|
4716
|
+
variant: "ghost",
|
|
4717
|
+
size: "icon",
|
|
4718
|
+
className: "size-7 shrink-0",
|
|
4719
|
+
"aria-label": `${collapsed.has(id) ? "Expand" : "Collapse"} ${nameOf(task)}`,
|
|
4720
|
+
onClick: () => toggle(setCollapsed, id),
|
|
4721
|
+
children: collapsed.has(id) ? /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "size-4" })
|
|
4722
|
+
}
|
|
4723
|
+
),
|
|
4724
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
4725
|
+
/* @__PURE__ */ jsx(
|
|
4726
|
+
"button",
|
|
4727
|
+
{
|
|
4728
|
+
className: cn(
|
|
4729
|
+
"block w-full text-left text-sm font-medium hover:underline",
|
|
4730
|
+
status === "done" && "text-muted-foreground"
|
|
4731
|
+
),
|
|
4732
|
+
"data-testid": `task-open-${id}`,
|
|
4733
|
+
onClick: () => p.onOpenThread(id, task),
|
|
4734
|
+
children: nameOf(task)
|
|
4735
|
+
}
|
|
4736
|
+
),
|
|
4737
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
|
|
4738
|
+
status !== "todo" && status !== "ready_for_review" && /* @__PURE__ */ jsx(
|
|
4739
|
+
TaskStatusPill,
|
|
4740
|
+
{
|
|
4741
|
+
id,
|
|
4742
|
+
status: task.status,
|
|
4743
|
+
runStartedAt: task.run_started_at,
|
|
4744
|
+
lastError: task.last_error,
|
|
4745
|
+
awaitingAccess: Boolean(task.pending_auth_request_id)
|
|
4746
|
+
}
|
|
4747
|
+
),
|
|
4748
|
+
task.due_at && /* @__PURE__ */ jsxs("span", { children: [
|
|
4749
|
+
"Due ",
|
|
4750
|
+
p.formatDate(task.due_at)
|
|
4751
|
+
] }),
|
|
4752
|
+
children.length > 0 && /* @__PURE__ */ jsxs("span", { children: [
|
|
4753
|
+
all.filter((t) => t.parent_conversation_ext_id === id && t.status === "done").length,
|
|
4754
|
+
"/",
|
|
4755
|
+
all.filter((t) => t.parent_conversation_ext_id === id).length,
|
|
4756
|
+
" steps complete"
|
|
4757
|
+
] })
|
|
4758
|
+
] }),
|
|
4759
|
+
outputs.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-2 flex flex-wrap gap-2", "aria-label": "Outputs", children: outputs.map((output) => /* @__PURE__ */ jsxs(
|
|
4760
|
+
Button,
|
|
4761
|
+
{
|
|
4762
|
+
variant: "link",
|
|
4763
|
+
size: "sm",
|
|
4764
|
+
className: "h-auto max-w-full gap-1 px-0 py-1 text-xs",
|
|
4765
|
+
disabled: !p.onOpenOutput,
|
|
4766
|
+
onClick: () => p.onOpenOutput?.(output.id, task),
|
|
4767
|
+
"data-testid": `task-output-${id}-${output.id}`,
|
|
4768
|
+
children: [
|
|
4769
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-3.5 shrink-0" }),
|
|
4770
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: output.name })
|
|
4771
|
+
]
|
|
4772
|
+
},
|
|
4773
|
+
output.id
|
|
4774
|
+
)) })
|
|
4775
|
+
] }),
|
|
4776
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
4777
|
+
task.pending_auth_request_id && task.is_owner !== false && p.onGrantAccess && /* @__PURE__ */ jsx(
|
|
4778
|
+
Button,
|
|
4779
|
+
{
|
|
4780
|
+
size: "sm",
|
|
4781
|
+
variant: "outline",
|
|
4782
|
+
disabled: busy,
|
|
4783
|
+
onClick: () => p.onGrantAccess?.(task),
|
|
4784
|
+
children: "Allow access"
|
|
4785
|
+
}
|
|
4786
|
+
),
|
|
4787
|
+
/* @__PURE__ */ jsx(
|
|
4788
|
+
TaskRowMenu,
|
|
4789
|
+
{
|
|
4790
|
+
task,
|
|
4791
|
+
status,
|
|
4792
|
+
busy,
|
|
4793
|
+
isOwner: task.is_owner !== false,
|
|
4794
|
+
canAdmin: task.is_owner !== false || Boolean(p.isWorkspaceOwner),
|
|
4795
|
+
canEdit: canEdit(task),
|
|
4796
|
+
canMarkDone: markable(task),
|
|
4797
|
+
canReopen: canEdit(task),
|
|
4798
|
+
selected: selected.has(id),
|
|
4799
|
+
onToggleSelected: p.selectionActions || p.onMarkDoneMany || p.onDeleteMany ? () => toggle(setSelected, id) : void 0,
|
|
4800
|
+
labels: l,
|
|
4801
|
+
onMarkDone: () => p.onMarkDone(task),
|
|
4802
|
+
onNotify: p.onNotify ? () => p.onNotify?.(task) : void 0,
|
|
4803
|
+
onReopen: () => p.onReopen(task),
|
|
4804
|
+
onEdit: () => p.onEdit(task),
|
|
4805
|
+
onAddSubtask: p.onAddSubtask ? () => p.onAddSubtask?.(task) : void 0,
|
|
4806
|
+
onMoveTo: p.onMove ? () => setMoving(task) : void 0,
|
|
4807
|
+
onChangeOwner: status !== "ready_for_review" && p.onChangeOwner && p.people?.length ? () => setHandingOff(task) : void 0,
|
|
4808
|
+
onOpenActivity: p.onOpenActivity ? () => p.onOpenActivity?.(task) : void 0,
|
|
4809
|
+
onToggleShared: p.onToggleShared ? () => p.onToggleShared?.(task, !task.is_shared) : void 0
|
|
4810
|
+
}
|
|
4811
|
+
)
|
|
4812
|
+
] })
|
|
4813
|
+
]
|
|
4814
|
+
}
|
|
4815
|
+
),
|
|
4816
|
+
children.length > 0 && !collapsed.has(id) && /* @__PURE__ */ jsx("ul", { children: children.map((child) => renderTask(child, depth + 1)) })
|
|
4817
|
+
] }, id);
|
|
4818
|
+
};
|
|
4819
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": p.testId ?? "task-inbox", children: [
|
|
4820
|
+
/* @__PURE__ */ jsx(
|
|
4821
|
+
TabHeader,
|
|
4822
|
+
{
|
|
4823
|
+
testId: "tasks-tab-header",
|
|
4824
|
+
tabs: [
|
|
4825
|
+
{
|
|
4826
|
+
id: "tasks",
|
|
4827
|
+
label: "",
|
|
4828
|
+
count: rows.length,
|
|
4829
|
+
countPlacement: "leading",
|
|
4830
|
+
countIcon: /* @__PURE__ */ jsx(ListTodo, { className: "size-3.5" }),
|
|
4831
|
+
hasActiveFilters,
|
|
4832
|
+
testId: "tasks-tab",
|
|
4833
|
+
presentation: "count"
|
|
4834
|
+
}
|
|
4835
|
+
],
|
|
4836
|
+
activeTabId: "tasks",
|
|
4837
|
+
onTabChange: () => {
|
|
4838
|
+
},
|
|
4839
|
+
firstTabContent: /* @__PURE__ */ jsx(
|
|
4840
|
+
FilterInput,
|
|
4841
|
+
{
|
|
4842
|
+
value: filterText,
|
|
4843
|
+
onChange: p.onFilterTextChange ?? setLocalQuery,
|
|
4844
|
+
fields: searchFields,
|
|
4845
|
+
onFieldsChange: setSearchFields,
|
|
4846
|
+
labels: { fieldNames: { text: "Task", labels: "Workflow" } },
|
|
4847
|
+
className: "w-44 max-w-[40vw]",
|
|
4848
|
+
testIds: {
|
|
4849
|
+
root: "tasks-filter",
|
|
4850
|
+
input: "tasks-filter-input",
|
|
4851
|
+
fieldsButton: "tasks-filter-fields"
|
|
4852
|
+
},
|
|
4853
|
+
filter: /* @__PURE__ */ jsx(
|
|
4854
|
+
TriStateFilterMenu,
|
|
4855
|
+
{
|
|
4856
|
+
testId: "tasks-status-filter",
|
|
4857
|
+
open: filterOpen,
|
|
4858
|
+
onOpenChange: setFilterOpen,
|
|
4859
|
+
filterStates: statusFilters,
|
|
4860
|
+
onFiltersChange: setStatusFilters,
|
|
4861
|
+
options: [
|
|
4862
|
+
{
|
|
4863
|
+
id: "todo",
|
|
4864
|
+
label: "To do",
|
|
4865
|
+
count: all.filter((t) => t.status === "todo").length
|
|
4866
|
+
},
|
|
4867
|
+
{
|
|
4868
|
+
id: "generating",
|
|
4869
|
+
label: "Generating",
|
|
4870
|
+
count: all.filter((t) => t.status === "generating").length
|
|
4871
|
+
},
|
|
4872
|
+
{
|
|
4873
|
+
id: "ready_for_review",
|
|
4874
|
+
label: "Ready for review",
|
|
4875
|
+
count: all.filter((t) => t.status === "ready_for_review").length
|
|
4876
|
+
},
|
|
4877
|
+
{
|
|
4878
|
+
id: "done",
|
|
4879
|
+
label: "Completed",
|
|
4880
|
+
count: all.filter((t) => t.status === "done").length
|
|
4881
|
+
}
|
|
4882
|
+
],
|
|
4883
|
+
groups: [
|
|
4884
|
+
{ label: "Status", options: ["todo", "generating", "ready_for_review", "done"] }
|
|
4885
|
+
],
|
|
4886
|
+
triggerClassName: "flex h-5 items-center gap-0.5 rounded px-1 text-muted-foreground hover:text-foreground pointer-coarse:h-11! pointer-coarse:min-w-11 pointer-coarse:justify-center",
|
|
4887
|
+
renderChevron: true,
|
|
4888
|
+
disableHoverOpen: true
|
|
4889
|
+
}
|
|
4890
|
+
)
|
|
4891
|
+
}
|
|
4892
|
+
),
|
|
4893
|
+
rightContent: p.onCreate ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
4894
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { "data-testid": "new-task-button", children: [
|
|
4895
|
+
/* @__PURE__ */ jsx(Plus, { className: "mr-1 size-4" }),
|
|
4896
|
+
"New",
|
|
4897
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "ml-1 size-3" })
|
|
4898
|
+
] }) }),
|
|
4899
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
|
|
4900
|
+
/* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: p.onCreate, children: "Task" }),
|
|
4901
|
+
p.onCreateWorkflow && /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: p.onCreateWorkflow, children: "Saved workflow" })
|
|
4902
|
+
] })
|
|
4903
|
+
] }) : p.header
|
|
4904
|
+
}
|
|
4905
|
+
),
|
|
4906
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", "aria-busy": p.isLoading, children: p.isLoading ? /* @__PURE__ */ jsx("p", { className: "py-12 text-center text-sm text-muted-foreground", children: "Loading work\u2026" }) : !listed.length && !workflows.length ? /* @__PURE__ */ jsx(
|
|
4907
|
+
EmptyState,
|
|
4908
|
+
{
|
|
4909
|
+
title: q ? "No matches" : all.length ? "You\u2019re all caught up" : "No work here yet",
|
|
4910
|
+
description: "Create a task from a prompt or a saved workflow. Keep its drafts, reviews and handoffs together."
|
|
4911
|
+
}
|
|
4912
|
+
) : /* @__PURE__ */ jsxs("ul", { children: [
|
|
4913
|
+
workflows.map((w) => {
|
|
4914
|
+
const runs = roots.filter((t) => t.workflow_ext_id === w.external_id).sort(order);
|
|
4915
|
+
const editable = w.is_owner !== false || p.canEditShared;
|
|
4916
|
+
return /* @__PURE__ */ jsxs("li", { "data-testid": `task-workflow-${w.external_id}`, children: [
|
|
4917
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 border-b py-3", children: [
|
|
4918
|
+
runs.length > 0 ? /* @__PURE__ */ jsx(
|
|
4919
|
+
Button,
|
|
4920
|
+
{
|
|
4921
|
+
variant: "ghost",
|
|
4922
|
+
size: "icon",
|
|
4923
|
+
className: "size-7",
|
|
4924
|
+
"aria-label": `${collapsed.has(w.external_id) ? "Expand" : "Collapse"} ${w.name}`,
|
|
4925
|
+
onClick: () => toggle(setCollapsed, w.external_id),
|
|
4926
|
+
children: collapsed.has(w.external_id) ? /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "size-4" })
|
|
4927
|
+
}
|
|
4928
|
+
) : /* @__PURE__ */ jsx(Workflow, { className: "mx-1 mt-1 size-4 shrink-0 text-muted-foreground" }),
|
|
4929
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
4930
|
+
/* @__PURE__ */ jsx(
|
|
4931
|
+
"button",
|
|
4932
|
+
{
|
|
4933
|
+
className: "block text-left text-sm font-medium hover:underline",
|
|
4934
|
+
disabled: !editable,
|
|
4935
|
+
onClick: () => p.onEditWorkflow?.(w.external_id),
|
|
4936
|
+
children: w.name
|
|
4937
|
+
}
|
|
4938
|
+
),
|
|
4939
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-muted-foreground", children: [
|
|
4940
|
+
"Saved workflow \xB7 ",
|
|
4941
|
+
w.summary ?? "Run when needed",
|
|
4942
|
+
!w.active ? " \xB7 Paused" : "",
|
|
4943
|
+
runs.length ? ` \xB7 ${runs.length} ${runs.length === 1 ? "task" : "tasks"}` : ""
|
|
4944
|
+
] }),
|
|
4945
|
+
w.last_error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-destructive", children: w.last_error })
|
|
4946
|
+
] }),
|
|
4947
|
+
/* @__PURE__ */ jsxs(DropdownMenu, { children: [
|
|
4948
|
+
/* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
4949
|
+
Button,
|
|
4950
|
+
{
|
|
4951
|
+
variant: "ghost",
|
|
4952
|
+
size: "icon",
|
|
4953
|
+
className: "size-8",
|
|
4954
|
+
"aria-label": `Actions for ${w.name}`,
|
|
4955
|
+
children: /* @__PURE__ */ jsx(MoreHorizontal, { className: "size-4" })
|
|
4956
|
+
}
|
|
4957
|
+
) }),
|
|
4958
|
+
/* @__PURE__ */ jsxs(DropdownMenuContent, { align: "end", children: [
|
|
4959
|
+
p.onWorkflowHistory && /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => p.onWorkflowHistory?.(w.external_id), children: "Run history" }),
|
|
4960
|
+
editable && p.onToggleWorkflow && /* @__PURE__ */ jsx(
|
|
4961
|
+
DropdownMenuItem,
|
|
4962
|
+
{
|
|
4963
|
+
onSelect: () => p.onToggleWorkflow?.(w.external_id, !w.active),
|
|
4964
|
+
children: w.active ? "Pause" : "Resume"
|
|
4965
|
+
}
|
|
4966
|
+
),
|
|
4967
|
+
(w.is_owner !== false || p.isWorkspaceOwner) && p.onDeleteWorkflow && /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: () => p.onDeleteWorkflow?.(w.external_id), children: "Delete workflow" })
|
|
4968
|
+
] })
|
|
4969
|
+
] })
|
|
4970
|
+
] }),
|
|
4971
|
+
!collapsed.has(w.external_id) && runs.length > 0 && /* @__PURE__ */ jsx("ul", { children: runs.map((t) => renderTask(t, 1)) })
|
|
4972
|
+
] }, w.external_id);
|
|
4973
|
+
}),
|
|
4974
|
+
roots.filter((t) => !t.workflow_ext_id || !workflowIds.has(t.workflow_ext_id)).sort(order).map((t) => renderTask(t))
|
|
4975
|
+
] }) }),
|
|
4976
|
+
/* @__PURE__ */ jsx(SelectionBar, { count: selectedTasks.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4977
|
+
p.selectionActions?.(selectedTasks, isCompact, clearSelection),
|
|
4978
|
+
p.onMarkDoneMany && /* @__PURE__ */ jsx(
|
|
4979
|
+
SelectionBarAction,
|
|
4980
|
+
{
|
|
4981
|
+
icon: CheckCheck,
|
|
4982
|
+
label: l.markDoneMany,
|
|
4983
|
+
isCompact,
|
|
4984
|
+
disabled: !markableTasks.length,
|
|
4985
|
+
onClick: () => {
|
|
4986
|
+
p.onMarkDoneMany?.(markableTasks);
|
|
4987
|
+
clearSelection();
|
|
4988
|
+
},
|
|
4989
|
+
testId: "task-bulk-done"
|
|
4990
|
+
}
|
|
4991
|
+
),
|
|
4992
|
+
p.onDeleteMany && /* @__PURE__ */ jsx(
|
|
4993
|
+
SelectionBarAction,
|
|
4994
|
+
{
|
|
4995
|
+
icon: Trash2,
|
|
4996
|
+
label: l.deleteMany,
|
|
4997
|
+
isCompact,
|
|
4998
|
+
disabled: !deletableTasks.length,
|
|
4999
|
+
onClick: () => {
|
|
5000
|
+
p.onDeleteMany?.(deletableTasks);
|
|
5001
|
+
clearSelection();
|
|
5002
|
+
},
|
|
5003
|
+
className: "text-red-text hover:bg-red-bg hover:text-red-text",
|
|
5004
|
+
testId: "task-bulk-delete"
|
|
5005
|
+
}
|
|
5006
|
+
)
|
|
5007
|
+
] }) }),
|
|
5008
|
+
moving && p.onMove && /* @__PURE__ */ jsx(
|
|
5009
|
+
TaskMoveDialog,
|
|
5010
|
+
{
|
|
5011
|
+
open: true,
|
|
5012
|
+
onOpenChange: (open) => !open && setMoving(null),
|
|
5013
|
+
options: moveTargets(all, moving).map((t) => ({ id: t.external_id, label: nameOf(t) })),
|
|
5014
|
+
currentParentId: moving.parent_conversation_ext_id,
|
|
5015
|
+
onPick: (id) => p.onMove?.(moving, id),
|
|
5016
|
+
labels: {
|
|
5017
|
+
title: l.moveToTitle(nameOf(moving)),
|
|
5018
|
+
none: l.moveToNone,
|
|
5019
|
+
search: l.moveToSearch,
|
|
5020
|
+
empty: l.moveToEmpty,
|
|
5021
|
+
cancel: l.moveToCancel
|
|
5022
|
+
}
|
|
5023
|
+
}
|
|
5024
|
+
),
|
|
5025
|
+
handingOff && p.onChangeOwner && /* @__PURE__ */ jsx(
|
|
5026
|
+
TaskMoveDialog,
|
|
5027
|
+
{
|
|
5028
|
+
open: true,
|
|
5029
|
+
onOpenChange: (open) => !open && setHandingOff(null),
|
|
5030
|
+
options: p.people ?? [],
|
|
5031
|
+
currentParentId: handingOff.signoff_ext_id,
|
|
5032
|
+
onPick: (id) => p.onChangeOwner?.(handingOff, id),
|
|
5033
|
+
labels: {
|
|
5034
|
+
title: l.changeOwnerTitle(nameOf(handingOff)),
|
|
5035
|
+
none: l.changeOwnerMe,
|
|
5036
|
+
search: l.moveToSearch,
|
|
5037
|
+
empty: l.moveToEmpty,
|
|
5038
|
+
cancel: l.moveToCancel
|
|
5039
|
+
},
|
|
5040
|
+
testId: "task-owner"
|
|
5041
|
+
}
|
|
5042
|
+
)
|
|
5043
|
+
] });
|
|
5044
|
+
}
|
|
5045
|
+
function EntityChip({
|
|
5046
|
+
variant = "pill",
|
|
5047
|
+
icon,
|
|
5048
|
+
label,
|
|
5049
|
+
detail,
|
|
5050
|
+
pillTooltip,
|
|
5051
|
+
showTooltip = true,
|
|
5052
|
+
href,
|
|
5053
|
+
onClick,
|
|
5054
|
+
size = "sm",
|
|
5055
|
+
labelMaxWidth,
|
|
5056
|
+
className,
|
|
5057
|
+
testId
|
|
5058
|
+
}) {
|
|
5059
|
+
if (variant === "icon") {
|
|
5060
|
+
const glyph = /* @__PURE__ */ jsx(
|
|
5061
|
+
"span",
|
|
5062
|
+
{
|
|
5063
|
+
"data-slot": "entity-chip",
|
|
5064
|
+
className: cn("inline-flex items-center", (onClick || href) && "cursor-pointer", className),
|
|
5065
|
+
onClick,
|
|
5066
|
+
"data-testid": testId,
|
|
5067
|
+
children: href ? /* @__PURE__ */ jsx("a", { href, target: "_blank", rel: "noopener noreferrer", children: icon }) : icon
|
|
5068
|
+
}
|
|
5069
|
+
);
|
|
5070
|
+
if (!showTooltip) return glyph;
|
|
5071
|
+
return /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
5072
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { className: "inline-flex", children: glyph }),
|
|
5073
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "bottom", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
5074
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: label }),
|
|
5075
|
+
detail && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: detail })
|
|
5076
|
+
] }) })
|
|
5077
|
+
] });
|
|
5078
|
+
}
|
|
5079
|
+
return /* @__PURE__ */ jsx(
|
|
5080
|
+
EntityPill,
|
|
5081
|
+
{
|
|
5082
|
+
icon,
|
|
5083
|
+
label,
|
|
5084
|
+
size,
|
|
5085
|
+
shape: "rounded",
|
|
5086
|
+
href,
|
|
5087
|
+
onClick,
|
|
5088
|
+
tooltipContent: pillTooltip,
|
|
5089
|
+
labelMaxWidth,
|
|
5090
|
+
className,
|
|
5091
|
+
"data-testid": testId
|
|
5092
|
+
}
|
|
5093
|
+
);
|
|
5094
|
+
}
|
|
5095
|
+
function filterConversationRows(conversations, query, labelText, doneFilter = "exclude", visibilityFilters) {
|
|
5096
|
+
const q = query.trim().toLowerCase();
|
|
5097
|
+
return [...conversations].sort(
|
|
5098
|
+
(a, b) => (Date.parse(b.last_message_updated_at || b.updated_at || b.created_at || "") || 0) - (Date.parse(a.last_message_updated_at || a.updated_at || a.created_at || "") || 0)
|
|
5099
|
+
).filter(
|
|
5100
|
+
(row) => doneFilter === "exclude" ? row.status !== "done" : doneFilter === "include" ? row.status === "done" : true
|
|
5101
|
+
).filter((row) => {
|
|
5102
|
+
const state = row.is_shared ? visibilityFilters?.workspace : visibilityFilters?.me;
|
|
5103
|
+
const hasIncluded = visibilityFilters?.me === "include" || visibilityFilters?.workspace === "include";
|
|
5104
|
+
return state !== "exclude" && (!hasIncluded || state === "include");
|
|
5105
|
+
}).filter((row) => !q || `${row.title ?? ""} ${labelText?.(row) ?? ""}`.toLowerCase().includes(q));
|
|
5106
|
+
}
|
|
5107
|
+
function ConversationListView(p) {
|
|
5108
|
+
const liveProps = useRef(p);
|
|
5109
|
+
liveProps.current = p;
|
|
5110
|
+
const [query, setQuery] = useState("");
|
|
5111
|
+
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
5112
|
+
const q = `${query} ${p.filterText ?? ""}`.trim().toLowerCase();
|
|
5113
|
+
const rows = useMemo(
|
|
5114
|
+
() => filterConversationRows(p.conversations, q, p.labelText, p.doneFilter, p.visibilityFilters),
|
|
5115
|
+
[p.conversations, q, p.labelText, p.doneFilter, p.visibilityFilters]
|
|
5116
|
+
);
|
|
5117
|
+
const selectedRows = p.conversations.filter((c) => selected.has(c.external_id));
|
|
5118
|
+
const columns = useMemo(
|
|
5119
|
+
() => [
|
|
5120
|
+
{
|
|
5121
|
+
colId: "name",
|
|
5122
|
+
headerName: "Thread",
|
|
5123
|
+
flex: 1,
|
|
5124
|
+
minWidth: 180,
|
|
5125
|
+
valueGetter: ({ data }) => data?.title?.trim() || "Untitled thread",
|
|
5126
|
+
cellRenderer: ({ data }) => data && /* @__PURE__ */ jsxs("div", { className: "group flex h-full min-w-0 items-center gap-2", children: [
|
|
5127
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: liveProps.current.renderThread ? liveProps.current.renderThread(data) : /* @__PURE__ */ jsx(
|
|
5128
|
+
EntityChip,
|
|
5129
|
+
{
|
|
5130
|
+
icon: /* @__PURE__ */ jsx(ThreadVisibilityIcon, { shared: data.is_shared ?? false, className: "size-4" }),
|
|
5131
|
+
label: data.title?.trim() || "Untitled thread",
|
|
5132
|
+
pillTooltip: "Open conversation",
|
|
5133
|
+
labelMaxWidth: "max-w-full",
|
|
5134
|
+
onClick: () => liveProps.current.onOpen(data),
|
|
5135
|
+
testId: `thread-open-${data.external_id}`
|
|
5136
|
+
}
|
|
5137
|
+
) }),
|
|
5138
|
+
(data.is_owner !== false || liveProps.current.canEditShared) && /* @__PURE__ */ jsx(
|
|
5139
|
+
"button",
|
|
5140
|
+
{
|
|
5141
|
+
type: "button",
|
|
5142
|
+
"aria-label": `Rename ${data.title?.trim() || "Untitled thread"}`,
|
|
5143
|
+
onClick: () => liveProps.current.onRename(data),
|
|
5144
|
+
"data-testid": `thread-rename-${data.external_id}`,
|
|
5145
|
+
className: "shrink-0 pointer-coarse:flex pointer-coarse:size-11 pointer-coarse:items-center pointer-coarse:justify-center",
|
|
5146
|
+
children: /* @__PURE__ */ jsx(CellHoverIcon, {})
|
|
5147
|
+
}
|
|
5148
|
+
)
|
|
5149
|
+
] })
|
|
5150
|
+
},
|
|
5151
|
+
...liveProps.current.renderLabels ? [
|
|
5152
|
+
{
|
|
5153
|
+
colId: "labels",
|
|
5154
|
+
headerName: "Labels",
|
|
5155
|
+
flex: 0.5,
|
|
5156
|
+
minWidth: 160,
|
|
5157
|
+
valueGetter: ({ data }) => data ? liveProps.current.labelText?.(data) ?? "" : "",
|
|
5158
|
+
cellRenderer: ({ data }) => data && liveProps.current.renderLabels?.(data)
|
|
5159
|
+
}
|
|
5160
|
+
] : [],
|
|
5161
|
+
...liveProps.current.renderBy || liveProps.current.renderOwner ? [
|
|
5162
|
+
{
|
|
5163
|
+
colId: liveProps.current.renderBy ? "by" : "owner",
|
|
5164
|
+
headerName: liveProps.current.renderBy ? "By" : "Owner",
|
|
5165
|
+
width: 160,
|
|
5166
|
+
cellRenderer: ({ data }) => data && (liveProps.current.renderBy || liveProps.current.renderOwner)?.(data)
|
|
5167
|
+
}
|
|
5168
|
+
] : [],
|
|
5169
|
+
{
|
|
5170
|
+
colId: "status",
|
|
5171
|
+
headerName: "Status",
|
|
5172
|
+
width: 150,
|
|
5173
|
+
valueGetter: ({ data }) => data?.status,
|
|
5174
|
+
cellRenderer: ({ data }) => data && (liveProps.current.renderStatus ? liveProps.current.renderStatus(data) : /* @__PURE__ */ jsx(TaskStatusPill, { id: data.external_id, status: data.status }))
|
|
5175
|
+
},
|
|
5176
|
+
{
|
|
5177
|
+
valueGetter: ({ data }) => data?.message_count,
|
|
5178
|
+
colId: "messages",
|
|
5179
|
+
headerName: "Messages",
|
|
5180
|
+
width: 110,
|
|
5181
|
+
valueFormatter: ({ value }) => value == null ? "\u2014" : String(value),
|
|
5182
|
+
cellClass: "text-muted-foreground"
|
|
5183
|
+
},
|
|
5184
|
+
...liveProps.current.onToggleShared ? [
|
|
5185
|
+
{
|
|
5186
|
+
colId: "visibility",
|
|
5187
|
+
headerName: "Visibility",
|
|
5188
|
+
width: 100,
|
|
5189
|
+
cellClass: "cell-hcenter",
|
|
5190
|
+
sortable: false,
|
|
5191
|
+
resizable: false,
|
|
5192
|
+
cellRenderer: ({ data }) => data && /* @__PURE__ */ jsx(
|
|
5193
|
+
VisibilityToggle,
|
|
5194
|
+
{
|
|
5195
|
+
items: [data],
|
|
5196
|
+
showLabel: false,
|
|
5197
|
+
disabled: data.is_owner === false,
|
|
5198
|
+
onToggle: () => liveProps.current.onToggleShared?.(data, !data.is_shared)
|
|
5199
|
+
}
|
|
5200
|
+
)
|
|
5201
|
+
}
|
|
5202
|
+
] : [],
|
|
5203
|
+
{
|
|
5204
|
+
colId: "activity",
|
|
5205
|
+
initialSort: "desc",
|
|
5206
|
+
headerName: "Activity",
|
|
5207
|
+
width: 160,
|
|
5208
|
+
valueGetter: ({ data }) => data?.last_message_updated_at || data?.updated_at || data?.created_at || "",
|
|
5209
|
+
valueFormatter: ({ value }) => value ? liveProps.current.formatDate(value) : "\u2014",
|
|
5210
|
+
cellClass: "text-muted-foreground"
|
|
5211
|
+
}
|
|
5212
|
+
],
|
|
5213
|
+
[
|
|
5214
|
+
Boolean(p.renderThread),
|
|
5215
|
+
Boolean(p.renderLabels),
|
|
5216
|
+
Boolean(p.renderOwner),
|
|
5217
|
+
Boolean(p.renderBy),
|
|
5218
|
+
Boolean(p.renderStatus),
|
|
5219
|
+
Boolean(p.onToggleShared)
|
|
5220
|
+
]
|
|
5221
|
+
);
|
|
5222
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "conversation-list-view", children: [
|
|
5223
|
+
p.showHeader !== false && /* @__PURE__ */ jsx(
|
|
5224
|
+
TabHeader,
|
|
5225
|
+
{
|
|
5226
|
+
testId: "threads-tab-header",
|
|
5227
|
+
tabs: [
|
|
5228
|
+
{
|
|
5229
|
+
id: "threads",
|
|
5230
|
+
label: "",
|
|
5231
|
+
count: rows.length,
|
|
5232
|
+
countIcon: /* @__PURE__ */ jsx(MessageSquare, { className: "size-3.5" }),
|
|
5233
|
+
countPlacement: "leading",
|
|
5234
|
+
presentation: "count",
|
|
5235
|
+
hasActiveFilters: !!q
|
|
5236
|
+
}
|
|
5237
|
+
],
|
|
5238
|
+
activeTabId: "threads",
|
|
5239
|
+
onTabChange: () => {
|
|
5240
|
+
},
|
|
5241
|
+
firstTabContent: /* @__PURE__ */ jsx(
|
|
5242
|
+
FilterInput,
|
|
5243
|
+
{
|
|
5244
|
+
value: query,
|
|
5245
|
+
hideFieldPicker: true,
|
|
5246
|
+
ariaLabel: "Search threads",
|
|
5247
|
+
onChange: setQuery,
|
|
5248
|
+
fields: ["text"],
|
|
5249
|
+
onFieldsChange: () => {
|
|
5250
|
+
},
|
|
5251
|
+
labels: {
|
|
5252
|
+
placeholder: "Find a thread\u2026",
|
|
5253
|
+
fieldNames: { text: "Thread" }
|
|
5254
|
+
},
|
|
5255
|
+
className: "w-44 max-w-[40vw]"
|
|
5256
|
+
}
|
|
5257
|
+
),
|
|
5258
|
+
rightContent: p.header
|
|
5259
|
+
}
|
|
5260
|
+
),
|
|
5261
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
5262
|
+
GridView,
|
|
5263
|
+
{
|
|
5264
|
+
testId: "threads-grid",
|
|
5265
|
+
items: rows,
|
|
5266
|
+
columnDefs: columns,
|
|
5267
|
+
getItemId: (row) => row.external_id,
|
|
5268
|
+
getRowTestId: (row) => `thread-row-${row.external_id}`,
|
|
5269
|
+
onRowClick: p.onOpen,
|
|
5270
|
+
height: "100%",
|
|
5271
|
+
isLoading: p.isLoading,
|
|
5272
|
+
loadingMessage: "Loading threads\u2026",
|
|
5273
|
+
emptyState: {
|
|
5274
|
+
title: q ? "No threads match" : "No conversations yet",
|
|
5275
|
+
message: "Start a conversation with people, ARBI, or both."
|
|
5276
|
+
},
|
|
5277
|
+
selection: p.selectionActions ? {
|
|
5278
|
+
mode: "multiple",
|
|
5279
|
+
controlled: true,
|
|
5280
|
+
selected: selectedRows,
|
|
5281
|
+
onSelectionChange: (items) => setSelected(new Set(items.map((item) => item.external_id)))
|
|
5282
|
+
} : void 0,
|
|
5283
|
+
gridOptions: {
|
|
5284
|
+
suppressClickEdit: true,
|
|
5285
|
+
onCellKeyDown: (event) => {
|
|
5286
|
+
if (event.event?.key === "Enter" && "column" in event && event.column.getColId() === "name" && event.data)
|
|
5287
|
+
p.onOpen(event.data);
|
|
5288
|
+
}
|
|
5289
|
+
}
|
|
5290
|
+
}
|
|
5291
|
+
) }),
|
|
5292
|
+
p.selectionActions && /* @__PURE__ */ jsx(SelectionBar, { count: selectedRows.length, onClear: () => setSelected(/* @__PURE__ */ new Set()), children: (compact) => p.selectionActions?.(selectedRows, compact, () => setSelected(/* @__PURE__ */ new Set())) })
|
|
5293
|
+
] });
|
|
5294
|
+
}
|
|
5295
|
+
function TaskStartDialog({
|
|
5296
|
+
open,
|
|
5297
|
+
onOpenChange,
|
|
5298
|
+
workflows,
|
|
5299
|
+
isPending,
|
|
5300
|
+
error,
|
|
5301
|
+
onStart,
|
|
5302
|
+
onLater
|
|
5303
|
+
}) {
|
|
5304
|
+
const [prompt, setPrompt] = useState("");
|
|
5305
|
+
const [choice, setChoice] = useState("prompt");
|
|
5306
|
+
const [shared, setShared] = useState(false);
|
|
5307
|
+
const todo = choice === "todo";
|
|
5308
|
+
const workflowId = choice === "prompt" || todo ? null : choice;
|
|
5309
|
+
const valid = workflowId ? workflows.some((w) => w.external_id === workflowId) : Boolean(prompt.trim());
|
|
5310
|
+
const values = {
|
|
5311
|
+
prompt: prompt.trim(),
|
|
5312
|
+
workflowId,
|
|
5313
|
+
todo,
|
|
5314
|
+
shared
|
|
5315
|
+
};
|
|
5316
|
+
return /* @__PURE__ */ jsx(Dialog, { modal: false, open, onOpenChange: (next) => !isPending && onOpenChange(next), children: /* @__PURE__ */ jsxs(
|
|
5317
|
+
DialogContent,
|
|
5318
|
+
{
|
|
5319
|
+
presentation: "right",
|
|
5320
|
+
hideCloseButton: true,
|
|
5321
|
+
onInteractOutside: (event) => event.preventDefault(),
|
|
5322
|
+
className: "flex flex-col gap-0 overflow-hidden p-0 shadow-lg",
|
|
5323
|
+
"data-testid": "task-start-dialog",
|
|
5324
|
+
children: [
|
|
5325
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "New task" }),
|
|
5326
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "sr-only", children: "Describe the task, then start it now or schedule it." }),
|
|
5327
|
+
/* @__PURE__ */ jsx(
|
|
5328
|
+
TabHeader,
|
|
5329
|
+
{
|
|
5330
|
+
tabs: [{ id: "new-task", label: "New task", presentation: "count" }],
|
|
5331
|
+
activeTabId: "new-task",
|
|
5332
|
+
onTabChange: () => {
|
|
5333
|
+
},
|
|
5334
|
+
rightContent: /* @__PURE__ */ jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Close", disabled: isPending, children: /* @__PURE__ */ jsx(X, { className: "size-4" }) }) })
|
|
4588
5335
|
}
|
|
4589
5336
|
),
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
5337
|
+
/* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 py-3", children: [
|
|
5338
|
+
!workflowId ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5339
|
+
/* @__PURE__ */ jsx(Label, { className: "sr-only", htmlFor: "task-start-prompt", children: todo ? "What needs doing?" : "What should ARBI do?" }),
|
|
5340
|
+
/* @__PURE__ */ jsx(
|
|
5341
|
+
Textarea,
|
|
5342
|
+
{
|
|
5343
|
+
id: "task-start-prompt",
|
|
5344
|
+
autoFocus: true,
|
|
5345
|
+
value: prompt,
|
|
5346
|
+
onChange: (event) => setPrompt(event.target.value),
|
|
5347
|
+
disabled: isPending,
|
|
5348
|
+
placeholder: "What needs doing?",
|
|
5349
|
+
className: "min-h-44 resize-y shadow-none"
|
|
5350
|
+
}
|
|
5351
|
+
)
|
|
5352
|
+
] }) : /* @__PURE__ */ jsx("p", { className: "text-sm", children: workflows.find((workflow) => workflow.external_id === workflowId)?.name }),
|
|
5353
|
+
/* @__PURE__ */ jsxs(Select, { value: choice, onValueChange: setChoice, disabled: isPending, children: [
|
|
5354
|
+
/* @__PURE__ */ jsx(
|
|
5355
|
+
SelectTrigger,
|
|
5356
|
+
{
|
|
5357
|
+
id: "task-start-source",
|
|
5358
|
+
"aria-label": "Who does the work",
|
|
5359
|
+
className: "mt-3 h-7 w-auto max-w-full border-0 bg-transparent px-1 text-xs font-normal text-muted-foreground shadow-none hover:bg-muted",
|
|
5360
|
+
children: /* @__PURE__ */ jsx(SelectValue, {})
|
|
5361
|
+
}
|
|
5362
|
+
),
|
|
5363
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
5364
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "prompt", children: "With ARBI" }),
|
|
5365
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "todo", children: "People only" }),
|
|
5366
|
+
workflows.map((workflow) => /* @__PURE__ */ jsx(SelectItem, { value: workflow.external_id, children: workflow.name }, workflow.external_id))
|
|
5367
|
+
] })
|
|
5368
|
+
] }),
|
|
5369
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "mt-3 text-sm text-destructive", children: error })
|
|
5370
|
+
] }),
|
|
5371
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 border-t px-3 py-2", children: [
|
|
5372
|
+
/* @__PURE__ */ jsx(
|
|
5373
|
+
Button,
|
|
5374
|
+
{
|
|
5375
|
+
variant: "ghost",
|
|
5376
|
+
disabled: !valid || isPending,
|
|
5377
|
+
onClick: () => onLater(values),
|
|
5378
|
+
"data-testid": "task-start-later",
|
|
5379
|
+
className: "h-8 px-2 text-sm font-medium",
|
|
5380
|
+
children: "Schedule"
|
|
4604
5381
|
}
|
|
4605
|
-
|
|
4606
|
-
|
|
5382
|
+
),
|
|
5383
|
+
/* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-3", children: [
|
|
5384
|
+
/* @__PURE__ */ jsx(
|
|
5385
|
+
VisibilityToggle,
|
|
5386
|
+
{
|
|
5387
|
+
items: { shared },
|
|
5388
|
+
onToggle: setShared,
|
|
5389
|
+
label: shared ? "Workspace" : "Only Me",
|
|
5390
|
+
disabled: isPending,
|
|
5391
|
+
"data-testid": "task-start-visibility"
|
|
5392
|
+
}
|
|
5393
|
+
),
|
|
5394
|
+
/* @__PURE__ */ jsx(
|
|
5395
|
+
Button,
|
|
5396
|
+
{
|
|
5397
|
+
disabled: !valid || isPending,
|
|
5398
|
+
"data-testid": "task-start-now",
|
|
5399
|
+
className: "h-8 px-3 text-sm font-medium",
|
|
5400
|
+
onClick: async () => {
|
|
5401
|
+
try {
|
|
5402
|
+
await onStart(values);
|
|
5403
|
+
setPrompt("");
|
|
5404
|
+
setChoice("prompt");
|
|
5405
|
+
setShared(false);
|
|
5406
|
+
} catch {
|
|
5407
|
+
}
|
|
5408
|
+
},
|
|
5409
|
+
children: isPending ? "Starting\u2026" : "Start now"
|
|
5410
|
+
}
|
|
5411
|
+
)
|
|
5412
|
+
] })
|
|
5413
|
+
] })
|
|
4607
5414
|
]
|
|
4608
5415
|
}
|
|
4609
|
-
);
|
|
5416
|
+
) });
|
|
4610
5417
|
}
|
|
4611
5418
|
var DEFAULT_DUE_DATE_MENU_LABELS = {
|
|
4612
5419
|
today: "Today",
|
|
@@ -4780,6 +5587,25 @@ var hasDocumentInputs = (inputs) => Object.values(inputs).some(
|
|
|
4780
5587
|
(v) => v !== null && typeof v === "object" && Array.isArray(v.documents) && (v.documents.length ?? 0) > 0
|
|
4781
5588
|
);
|
|
4782
5589
|
function workflowTaskFields(workflow, inputs, name, context) {
|
|
5590
|
+
if (workflow.documentAction) {
|
|
5591
|
+
const scope = inputs.scope && typeof inputs.scope === "object" ? inputs.scope : { labels: []};
|
|
5592
|
+
return {
|
|
5593
|
+
name: name?.trim() || workflow.title,
|
|
5594
|
+
prompt: "",
|
|
5595
|
+
skill_ref: null,
|
|
5596
|
+
skill_inputs: inputs,
|
|
5597
|
+
action: {
|
|
5598
|
+
type: workflow.documentAction,
|
|
5599
|
+
documents: {
|
|
5600
|
+
doc_ext_ids: scope.documents ?? [],
|
|
5601
|
+
label_ext_ids: scope.labels ?? [],
|
|
5602
|
+
latest: inputs.latest === true
|
|
5603
|
+
},
|
|
5604
|
+
tag_ext_ids: typeof inputs.output === "string" && inputs.output ? [inputs.output] : [],
|
|
5605
|
+
overwrite: inputs.overwrite === true
|
|
5606
|
+
}
|
|
5607
|
+
};
|
|
5608
|
+
}
|
|
4783
5609
|
for (const value of Object.values(inputs)) {
|
|
4784
5610
|
if (!value || typeof value !== "object") continue;
|
|
4785
5611
|
const scope = value;
|
|
@@ -4892,6 +5718,7 @@ function composerToWorkflowRequest({ workflow, values, plan, documentTitles }, w
|
|
|
4892
5718
|
shared: values.shared,
|
|
4893
5719
|
timezone: values.timezone,
|
|
4894
5720
|
...workflowTrigger(values, false),
|
|
5721
|
+
...fields.action ? { action: fields.action } : {},
|
|
4895
5722
|
prompt: fields.prompt,
|
|
4896
5723
|
skill_ref: fields.skill_ref,
|
|
4897
5724
|
skill_inputs: fields.skill_inputs,
|
|
@@ -4904,7 +5731,7 @@ function composerToWorkflowRequest({ workflow, values, plan, documentTitles }, w
|
|
|
4904
5731
|
});
|
|
4905
5732
|
}
|
|
4906
5733
|
function taskComposerToCreateRequest(ctx, workspaceId, forceWorkflow = false) {
|
|
4907
|
-
if (forceWorkflow || !createsWork(ctx.values)) {
|
|
5734
|
+
if (forceWorkflow || ctx.workflow.documentAction || !createsWork(ctx.values)) {
|
|
4908
5735
|
return { kind: "workflow", body: composerToWorkflowRequest(ctx, workspaceId) };
|
|
4909
5736
|
}
|
|
4910
5737
|
return ctx.values.assignee === "me" || !isAgenticWorkflow(ctx.workflow) ? { kind: "work", body: composerToWorkRequest(ctx, workspaceId) } : { kind: "query", query: composerToTaskQuery(ctx, workspaceId) };
|
|
@@ -4936,6 +5763,7 @@ function composerToWorkflowUpdate({
|
|
|
4936
5763
|
shared: values.shared,
|
|
4937
5764
|
timezone: values.timezone,
|
|
4938
5765
|
...workflowTrigger(values, true),
|
|
5766
|
+
action: fields.action ?? null,
|
|
4939
5767
|
prompt: fields.prompt,
|
|
4940
5768
|
skill_ref: fields.skill_ref,
|
|
4941
5769
|
skill_inputs: fields.skill_inputs,
|
|
@@ -4964,10 +5792,11 @@ function taskToComposerValues(task, workflows) {
|
|
|
4964
5792
|
};
|
|
4965
5793
|
}
|
|
4966
5794
|
function workflowWhen(workflow) {
|
|
5795
|
+
if (workflow.on_demand) return "now";
|
|
4967
5796
|
if (workflow.after_conversation_ext_id) return "task";
|
|
4968
5797
|
if (workflow.event_kind) return "event";
|
|
4969
5798
|
if (workflow.rrule) return "repeat";
|
|
4970
|
-
return "once";
|
|
5799
|
+
return workflow.run_at ? "once" : "now";
|
|
4971
5800
|
}
|
|
4972
5801
|
function workflowToComposerValues(workflow, workflows) {
|
|
4973
5802
|
const reminder = !workflow.prompt && !workflow.skill_ref;
|
|
@@ -4988,6 +5817,25 @@ function workflowToComposerValues(workflow, workflows) {
|
|
|
4988
5817
|
name: workflow.name,
|
|
4989
5818
|
access: workflow.auth_mode === "scheduled_permanent" ? "standing" : "ask_each_run"
|
|
4990
5819
|
};
|
|
5820
|
+
if (workflow.action) {
|
|
5821
|
+
const definition = workflows.definitions?.find(
|
|
5822
|
+
(d) => d.documentAction === workflow.action?.type
|
|
5823
|
+
);
|
|
5824
|
+
return {
|
|
5825
|
+
...base,
|
|
5826
|
+
workflowId: definition?.id ?? workflows.customWorkflowId,
|
|
5827
|
+
inputs: {
|
|
5828
|
+
scope: {
|
|
5829
|
+
folders: [],
|
|
5830
|
+
labels: workflow.action.documents?.label_ext_ids ?? [],
|
|
5831
|
+
documents: workflow.action.documents?.doc_ext_ids ?? []
|
|
5832
|
+
},
|
|
5833
|
+
output: workflow.action.tag_ext_ids?.[0] ?? "",
|
|
5834
|
+
overwrite: workflow.action.overwrite ?? false,
|
|
5835
|
+
latest: workflow.action.documents?.latest ?? false
|
|
5836
|
+
}
|
|
5837
|
+
};
|
|
5838
|
+
}
|
|
4991
5839
|
if (skill) {
|
|
4992
5840
|
return {
|
|
4993
5841
|
...base,
|
|
@@ -5011,7 +5859,7 @@ function workflowToComposerValues(workflow, workflows) {
|
|
|
5011
5859
|
var EMPTY_NEW_THREAD = {
|
|
5012
5860
|
prompt: "",
|
|
5013
5861
|
title: "",
|
|
5014
|
-
shared:
|
|
5862
|
+
shared: false,
|
|
5015
5863
|
ownerId: "",
|
|
5016
5864
|
dueAt: "",
|
|
5017
5865
|
parentId: "",
|
|
@@ -5104,12 +5952,7 @@ function NewThreadDialog({
|
|
|
5104
5952
|
);
|
|
5105
5953
|
const [values, setValues] = useState(seed);
|
|
5106
5954
|
const [detailsOpen, setDetailsOpen] = useState(hasTaskFields(seed));
|
|
5107
|
-
|
|
5108
|
-
if (open) {
|
|
5109
|
-
setValues(seed);
|
|
5110
|
-
setDetailsOpen(hasTaskFields(seed));
|
|
5111
|
-
}
|
|
5112
|
-
}, [open, seed]);
|
|
5955
|
+
const [submitError, setSubmitError] = useState(null);
|
|
5113
5956
|
const id = testIdOr(testId, { testId: "new-thread" });
|
|
5114
5957
|
const set = (key, value) => setValues((v) => ({ ...v, [key]: value }));
|
|
5115
5958
|
const canSubmit = values.prompt.trim() !== "" && !isPending;
|
|
@@ -5125,11 +5968,12 @@ function NewThreadDialog({
|
|
|
5125
5968
|
label: t.name,
|
|
5126
5969
|
icon: /* @__PURE__ */ jsx(CornerDownRight, { className: GLYPH, "aria-hidden": true })
|
|
5127
5970
|
}));
|
|
5128
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
5971
|
+
return /* @__PURE__ */ jsx(Dialog, { modal: false, open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
5129
5972
|
DialogContent,
|
|
5130
5973
|
{
|
|
5131
|
-
presentation: "
|
|
5132
|
-
|
|
5974
|
+
presentation: "right",
|
|
5975
|
+
onInteractOutside: (event) => event.preventDefault(),
|
|
5976
|
+
className: "flex flex-col overflow-hidden p-0",
|
|
5133
5977
|
"data-testid": id,
|
|
5134
5978
|
children: [
|
|
5135
5979
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -5140,9 +5984,17 @@ function NewThreadDialog({
|
|
|
5140
5984
|
"form",
|
|
5141
5985
|
{
|
|
5142
5986
|
className: "flex min-h-0 flex-1 flex-col",
|
|
5143
|
-
onSubmit: (event) => {
|
|
5987
|
+
onSubmit: async (event) => {
|
|
5144
5988
|
event.preventDefault();
|
|
5145
|
-
if (canSubmit)
|
|
5989
|
+
if (!canSubmit) return;
|
|
5990
|
+
setSubmitError(null);
|
|
5991
|
+
try {
|
|
5992
|
+
await onSubmit(values);
|
|
5993
|
+
setValues(EMPTY_NEW_THREAD);
|
|
5994
|
+
setDetailsOpen(false);
|
|
5995
|
+
} catch (error) {
|
|
5996
|
+
setSubmitError(error instanceof Error ? error.message : "Could not create the thread");
|
|
5997
|
+
}
|
|
5146
5998
|
},
|
|
5147
5999
|
children: [
|
|
5148
6000
|
/* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-6 pb-4", children: [
|
|
@@ -5184,6 +6036,7 @@ function NewThreadDialog({
|
|
|
5184
6036
|
items: { shared: values.shared },
|
|
5185
6037
|
onToggle: (share) => set("shared", share),
|
|
5186
6038
|
label: l.visibility,
|
|
6039
|
+
presentation: "select",
|
|
5187
6040
|
"data-testid": `${id}-visibility`
|
|
5188
6041
|
}
|
|
5189
6042
|
) }),
|
|
@@ -5279,6 +6132,7 @@ function NewThreadDialog({
|
|
|
5279
6132
|
] })
|
|
5280
6133
|
] })
|
|
5281
6134
|
] }),
|
|
6135
|
+
submitError && /* @__PURE__ */ jsx("p", { role: "alert", className: "px-6 pb-2 text-sm text-destructive", children: submitError }),
|
|
5282
6136
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col-reverse gap-2 border-t border-border px-6 py-3 sm:flex-row sm:justify-end", children: [
|
|
5283
6137
|
/* @__PURE__ */ jsx(
|
|
5284
6138
|
Button,
|
|
@@ -5315,18 +6169,18 @@ function NewThreadDialog({
|
|
|
5315
6169
|
var DEFAULT_TASK_TRIGGER_CHIP_LABELS = {
|
|
5316
6170
|
after: (name) => `After \u201C${name}\u201D is done`,
|
|
5317
6171
|
afterUnknown: "After another task is done",
|
|
5318
|
-
onDemand: "
|
|
6172
|
+
onDemand: "Manual"
|
|
5319
6173
|
};
|
|
5320
6174
|
function TriggerIcon({ type, chained }) {
|
|
5321
|
-
const cls = "size-3.5 shrink-0";
|
|
6175
|
+
const cls = "size-3.5 shrink-0 text-muted-foreground";
|
|
5322
6176
|
if (chained) return /* @__PURE__ */ jsx(Link2, { className: cls, "aria-hidden": true });
|
|
5323
6177
|
switch (type) {
|
|
5324
6178
|
case "on_demand":
|
|
5325
6179
|
return /* @__PURE__ */ jsx(MousePointerClick, { className: cls, "aria-hidden": true });
|
|
5326
6180
|
case "recurring":
|
|
5327
|
-
return /* @__PURE__ */ jsx(
|
|
6181
|
+
return /* @__PURE__ */ jsx(Clock, { className: cls, "aria-hidden": true });
|
|
5328
6182
|
case "event":
|
|
5329
|
-
return /* @__PURE__ */ jsx(
|
|
6183
|
+
return /* @__PURE__ */ jsx(Bell, { className: cls, "aria-hidden": true });
|
|
5330
6184
|
default:
|
|
5331
6185
|
return /* @__PURE__ */ jsx(Clock, { className: cls, "aria-hidden": true });
|
|
5332
6186
|
}
|
|
@@ -5346,7 +6200,7 @@ function TaskTriggerChip({
|
|
|
5346
6200
|
return /* @__PURE__ */ jsxs(
|
|
5347
6201
|
"span",
|
|
5348
6202
|
{
|
|
5349
|
-
className: "inline-flex min-w-0 items-center gap-1.5 text-
|
|
6203
|
+
className: "inline-flex min-w-0 max-w-full items-center gap-1.5 text-sm font-normal text-foreground",
|
|
5350
6204
|
"data-testid": testIdOr(testId, { testId: `task-trigger-${id}` }),
|
|
5351
6205
|
"data-trigger": chained ? "task" : triggerType,
|
|
5352
6206
|
children: [
|
|
@@ -5372,12 +6226,24 @@ function workflowTriggerType(workflow) {
|
|
|
5372
6226
|
if (workflow.run_at) return "one_time";
|
|
5373
6227
|
return "on_demand";
|
|
5374
6228
|
}
|
|
6229
|
+
function workflowRunStatusLabel(status) {
|
|
6230
|
+
if (!status) return "None";
|
|
6231
|
+
const labels = {
|
|
6232
|
+
completed: "Success",
|
|
6233
|
+
success: "Success",
|
|
6234
|
+
failed: "Failed",
|
|
6235
|
+
running: "In progress",
|
|
6236
|
+
awaiting_authorization: "Awaiting access"
|
|
6237
|
+
};
|
|
6238
|
+
return labels[status] ?? status.replaceAll("_", " ");
|
|
6239
|
+
}
|
|
5375
6240
|
|
|
5376
6241
|
// src/agents/tasks/workflowColumns.tsx
|
|
5377
6242
|
var WORKFLOW_COLUMN_ORDER = [
|
|
5378
6243
|
"name",
|
|
5379
6244
|
"trigger",
|
|
5380
6245
|
"last_run",
|
|
6246
|
+
"result",
|
|
5381
6247
|
"status",
|
|
5382
6248
|
"shared",
|
|
5383
6249
|
"actions"
|
|
@@ -5390,7 +6256,6 @@ function createWorkflowColumns(o) {
|
|
|
5390
6256
|
const l = o.labels;
|
|
5391
6257
|
const base = {
|
|
5392
6258
|
sortable: false,
|
|
5393
|
-
suppressMovable: true,
|
|
5394
6259
|
cellStyle: { display: "flex", alignItems: "center" }
|
|
5395
6260
|
};
|
|
5396
6261
|
return [
|
|
@@ -5400,7 +6265,7 @@ function createWorkflowColumns(o) {
|
|
|
5400
6265
|
sortable: true,
|
|
5401
6266
|
headerName: l.colName,
|
|
5402
6267
|
flex: 3,
|
|
5403
|
-
minWidth:
|
|
6268
|
+
minWidth: 210,
|
|
5404
6269
|
valueGetter: (p) => p.data?.name.toLowerCase() ?? "",
|
|
5405
6270
|
cellRenderer: cell2(o.renderName)
|
|
5406
6271
|
},
|
|
@@ -5409,7 +6274,7 @@ function createWorkflowColumns(o) {
|
|
|
5409
6274
|
colId: "trigger",
|
|
5410
6275
|
headerName: l.colTrigger,
|
|
5411
6276
|
flex: 2.4,
|
|
5412
|
-
minWidth:
|
|
6277
|
+
minWidth: 185,
|
|
5413
6278
|
valueGetter: (p) => p.data ? o.getTriggerText(p.data) : "",
|
|
5414
6279
|
cellRenderer: cell2(o.renderTrigger)
|
|
5415
6280
|
},
|
|
@@ -5419,16 +6284,26 @@ function createWorkflowColumns(o) {
|
|
|
5419
6284
|
sortable: true,
|
|
5420
6285
|
headerName: l.colLastRun,
|
|
5421
6286
|
flex: 1.4,
|
|
5422
|
-
minWidth:
|
|
6287
|
+
minWidth: 140,
|
|
6288
|
+
cellStyle: { display: "flex", alignItems: "center", padding: 0 },
|
|
5423
6289
|
valueGetter: (p) => time(p.data?.last_fired_at),
|
|
5424
6290
|
cellRenderer: cell2(o.renderLastRun)
|
|
5425
6291
|
},
|
|
6292
|
+
{
|
|
6293
|
+
...base,
|
|
6294
|
+
colId: "result",
|
|
6295
|
+
headerName: "Result",
|
|
6296
|
+
width: 130,
|
|
6297
|
+
valueGetter: (p) => p.data?.last_run_status ?? "",
|
|
6298
|
+
cellStyle: { display: "flex", alignItems: "center", padding: 0 },
|
|
6299
|
+
cellRenderer: cell2(o.renderResult)
|
|
6300
|
+
},
|
|
5426
6301
|
{
|
|
5427
6302
|
...base,
|
|
5428
6303
|
colId: "status",
|
|
5429
6304
|
sortable: true,
|
|
5430
6305
|
headerName: l.colStatus,
|
|
5431
|
-
width:
|
|
6306
|
+
width: 120,
|
|
5432
6307
|
valueGetter: (p) => p.data ? workflowStatus(p.data) : "",
|
|
5433
6308
|
cellRenderer: cell2(o.renderStatus)
|
|
5434
6309
|
},
|
|
@@ -5446,10 +6321,8 @@ function createWorkflowColumns(o) {
|
|
|
5446
6321
|
...base,
|
|
5447
6322
|
colId: "actions",
|
|
5448
6323
|
headerName: "",
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
lockPinned: true,
|
|
5452
|
-
width: 140,
|
|
6324
|
+
width: 180,
|
|
6325
|
+
minWidth: 180,
|
|
5453
6326
|
cellStyle: { display: "flex", alignItems: "center", justifyContent: "flex-end" },
|
|
5454
6327
|
cellRenderer: cell2(o.renderActions)
|
|
5455
6328
|
}
|
|
@@ -5463,7 +6336,7 @@ var DEFAULT_WORKFLOW_LIST_LABELS = {
|
|
|
5463
6336
|
colTrigger: "When",
|
|
5464
6337
|
colAction: "What it does",
|
|
5465
6338
|
colAgent: "Agent",
|
|
5466
|
-
colStatus: "
|
|
6339
|
+
colStatus: "Active",
|
|
5467
6340
|
colShared: "Shared",
|
|
5468
6341
|
colLastRun: "Last run",
|
|
5469
6342
|
colNextRun: "Next run",
|
|
@@ -5473,7 +6346,7 @@ var DEFAULT_WORKFLOW_LIST_LABELS = {
|
|
|
5473
6346
|
typeSkill: "Skill",
|
|
5474
6347
|
typeWorkflow: "Workflow",
|
|
5475
6348
|
statusActive: "Active",
|
|
5476
|
-
statusPaused: "
|
|
6349
|
+
statusPaused: "Inactive",
|
|
5477
6350
|
statusOnDemand: "On demand",
|
|
5478
6351
|
activeSwitch: (name) => `Active: \u201C${name}\u201D`,
|
|
5479
6352
|
agent: "Agent",
|
|
@@ -5503,17 +6376,18 @@ var DEFAULT_WORKFLOW_LIST_LABELS = {
|
|
|
5503
6376
|
filterSkills: "Skills",
|
|
5504
6377
|
filterWorkflows: "Workflows",
|
|
5505
6378
|
filterActive: "Active",
|
|
5506
|
-
filterPaused: "
|
|
6379
|
+
filterPaused: "Inactive",
|
|
5507
6380
|
makeActive: "Make active",
|
|
5508
|
-
makePaused: "
|
|
6381
|
+
makePaused: "Deactivate",
|
|
5509
6382
|
selectAll: "Select all",
|
|
5510
6383
|
selectWorkflow: (name) => `Select ${name}`
|
|
5511
6384
|
};
|
|
5512
|
-
var ROW_HEIGHT2 =
|
|
6385
|
+
var ROW_HEIGHT2 = 40;
|
|
5513
6386
|
function WorkflowsTable(props) {
|
|
5514
6387
|
const { workflows, isLoading, busyId, header, testId } = props;
|
|
5515
6388
|
const l = { ...DEFAULT_WORKFLOW_LIST_LABELS, ...props.labels };
|
|
5516
|
-
const [
|
|
6389
|
+
const [filterStates, setFilterStates] = useState(/* @__PURE__ */ new Map());
|
|
6390
|
+
const [filterOpen, setFilterOpen] = useState(false);
|
|
5517
6391
|
const [query, setQuery] = useState("");
|
|
5518
6392
|
const [selected, setSelected] = useState([]);
|
|
5519
6393
|
const apiRef = useRef(null);
|
|
@@ -5529,12 +6403,24 @@ function WorkflowsTable(props) {
|
|
|
5529
6403
|
return out;
|
|
5530
6404
|
}, [workflows, q]);
|
|
5531
6405
|
const shown = useMemo(
|
|
5532
|
-
() => workflows.filter((w) =>
|
|
5533
|
-
|
|
5534
|
-
|
|
6406
|
+
() => workflows.filter((w) => {
|
|
6407
|
+
if (!matches(w)) return false;
|
|
6408
|
+
for (const group of [
|
|
6409
|
+
["skills", "workflows"],
|
|
6410
|
+
["active", "paused"]
|
|
6411
|
+
]) {
|
|
6412
|
+
const included = group.filter((f) => filterStates.get(f) === "include");
|
|
6413
|
+
if (included.length && !included.some((f) => inFilter(w, f))) return false;
|
|
6414
|
+
if (group.some((f) => filterStates.get(f) === "exclude" && inFilter(w, f))) return false;
|
|
6415
|
+
}
|
|
6416
|
+
return true;
|
|
6417
|
+
}),
|
|
6418
|
+
[workflows, filterStates, q]
|
|
5535
6419
|
);
|
|
5536
6420
|
const renderPerson = props.renderPerson ?? ((p) => /* @__PURE__ */ jsx(PersonPill, { person: p }));
|
|
5537
6421
|
const actionText = (w) => {
|
|
6422
|
+
if (w.action)
|
|
6423
|
+
return w.action.type === "email_documents" ? "Email latest documents" : "AI Review";
|
|
5538
6424
|
if (isSkillRow(w))
|
|
5539
6425
|
return w.description || w.skill_ref && props.skillNames?.[w.skill_ref] || w.name;
|
|
5540
6426
|
return w.skill_ref ? props.skillNames?.[w.skill_ref] ?? w.skill_ref : w.prompt?.trim() || l.reminder;
|
|
@@ -5557,7 +6443,7 @@ function WorkflowsTable(props) {
|
|
|
5557
6443
|
"span",
|
|
5558
6444
|
{
|
|
5559
6445
|
className: cn(
|
|
5560
|
-
"truncate text-sm font-
|
|
6446
|
+
"truncate text-sm font-normal",
|
|
5561
6447
|
workflowStatus(w) === "paused" && "text-muted-foreground"
|
|
5562
6448
|
),
|
|
5563
6449
|
"data-testid": `workflow-name-${w.external_id}`,
|
|
@@ -5573,7 +6459,7 @@ function WorkflowsTable(props) {
|
|
|
5573
6459
|
}
|
|
5574
6460
|
)
|
|
5575
6461
|
] }),
|
|
5576
|
-
about && /* @__PURE__ */ jsx(
|
|
6462
|
+
about && !latest.current.props.automationsOnly && /* @__PURE__ */ jsx(
|
|
5577
6463
|
"p",
|
|
5578
6464
|
{
|
|
5579
6465
|
className: "truncate text-xs text-muted-foreground",
|
|
@@ -5584,62 +6470,36 @@ function WorkflowsTable(props) {
|
|
|
5584
6470
|
] });
|
|
5585
6471
|
},
|
|
5586
6472
|
renderTrigger: (w) => {
|
|
5587
|
-
const { props: p
|
|
6473
|
+
const { props: p } = latest.current;
|
|
5588
6474
|
const after = w.after_conversation_ext_id;
|
|
5589
6475
|
const skill = isSkillRow(w);
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
afterTaskId: after,
|
|
5603
|
-
afterTaskName: after ? p.taskNames?.[after] : void 0,
|
|
5604
|
-
labels: p.triggerChipLabels
|
|
5605
|
-
}
|
|
5606
|
-
),
|
|
5607
|
-
detail && /* @__PURE__ */ jsx(
|
|
5608
|
-
"p",
|
|
5609
|
-
{
|
|
5610
|
-
className: "truncate text-xs text-muted-foreground",
|
|
5611
|
-
"data-testid": `workflow-next-run-${w.external_id}`,
|
|
5612
|
-
children: detail
|
|
5613
|
-
}
|
|
5614
|
-
)
|
|
5615
|
-
] });
|
|
6476
|
+
return /* @__PURE__ */ jsx("div", { className: "min-w-0 leading-tight", children: /* @__PURE__ */ jsx(
|
|
6477
|
+
TaskTriggerChip,
|
|
6478
|
+
{
|
|
6479
|
+
id: w.external_id,
|
|
6480
|
+
testId: `workflow-trigger-${w.external_id}`,
|
|
6481
|
+
triggerType: workflowTriggerType(w),
|
|
6482
|
+
summary: skill ? "" : p.describeTrigger(w),
|
|
6483
|
+
afterTaskId: after,
|
|
6484
|
+
afterTaskName: after ? p.taskNames?.[after] : void 0,
|
|
6485
|
+
labels: p.triggerChipLabels
|
|
6486
|
+
}
|
|
6487
|
+
) });
|
|
5616
6488
|
},
|
|
5617
6489
|
renderStatus: (w) => {
|
|
5618
6490
|
const { props: p, l: lb } = latest.current;
|
|
5619
|
-
const status = workflowStatus(w);
|
|
5620
|
-
if (status === "on_demand") return null;
|
|
5621
6491
|
const canEdit = w.is_owner !== false || Boolean(p.canEditShared);
|
|
5622
|
-
return /* @__PURE__ */
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
/* @__PURE__ */ jsx(
|
|
5634
|
-
"span",
|
|
5635
|
-
{
|
|
5636
|
-
className: "text-sm text-muted-foreground",
|
|
5637
|
-
"data-testid": `workflow-status-${w.external_id}`,
|
|
5638
|
-
"data-status": status,
|
|
5639
|
-
children: status === "active" ? lb.statusActive : lb.statusPaused
|
|
5640
|
-
}
|
|
5641
|
-
)
|
|
5642
|
-
] });
|
|
6492
|
+
return /* @__PURE__ */ jsx(
|
|
6493
|
+
Switch,
|
|
6494
|
+
{
|
|
6495
|
+
checked: hasTrigger(w) && !isSkillRow(w) && Boolean(w.active),
|
|
6496
|
+
disabled: !hasTrigger(w) || isSkillRow(w) || !canEdit || p.busyId === w.external_id,
|
|
6497
|
+
onCheckedChange: (next) => p.onToggleActive(w, next),
|
|
6498
|
+
className: "disabled:data-[state=unchecked]:bg-muted dark:disabled:data-[state=unchecked]:bg-muted",
|
|
6499
|
+
"aria-label": lb.activeSwitch(w.name),
|
|
6500
|
+
"data-testid": `workflow-active-${w.external_id}`
|
|
6501
|
+
}
|
|
6502
|
+
);
|
|
5643
6503
|
},
|
|
5644
6504
|
renderShared: (w) => {
|
|
5645
6505
|
const { props: p, l: lb } = latest.current;
|
|
@@ -5659,41 +6519,37 @@ function WorkflowsTable(props) {
|
|
|
5659
6519
|
},
|
|
5660
6520
|
renderLastRun: (w) => {
|
|
5661
6521
|
const { props: p, l: lb } = latest.current;
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
"
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
]
|
|
5694
|
-
}
|
|
5695
|
-
)
|
|
5696
|
-
] });
|
|
6522
|
+
const at = w.last_fired_at ?? p.lastRuns?.[w.external_id]?.at;
|
|
6523
|
+
return /* @__PURE__ */ jsx(
|
|
6524
|
+
"button",
|
|
6525
|
+
{
|
|
6526
|
+
type: "button",
|
|
6527
|
+
className: "h-full w-full truncate px-4 text-left text-sm hover:text-primary",
|
|
6528
|
+
onClick: () => p.onViewRuns?.(w),
|
|
6529
|
+
title: "View run history",
|
|
6530
|
+
"data-testid": `workflow-last-run-${w.external_id}`,
|
|
6531
|
+
children: at ? p.formatDate(at) : lb.never
|
|
6532
|
+
}
|
|
6533
|
+
);
|
|
6534
|
+
},
|
|
6535
|
+
renderResult: (w) => {
|
|
6536
|
+
const status = w.last_run_status;
|
|
6537
|
+
const label = workflowRunStatusLabel(status);
|
|
6538
|
+
return /* @__PURE__ */ jsx(
|
|
6539
|
+
"button",
|
|
6540
|
+
{
|
|
6541
|
+
type: "button",
|
|
6542
|
+
onClick: () => latest.current.props.onViewRuns?.(w),
|
|
6543
|
+
title: "View run history",
|
|
6544
|
+
className: cn(
|
|
6545
|
+
badgeVariants({ variant: "outline" }),
|
|
6546
|
+
"mx-4 cursor-pointer text-xs font-medium",
|
|
6547
|
+
status === "failed" ? "border-red-border bg-red-bg text-red-text hover:bg-red-bg/80" : status === "completed" || status === "success" ? "border-green-border bg-green-bg text-green-text hover:bg-green-bg/80" : status ? "border-primary/20 bg-primary/10 text-primary hover:bg-primary/15" : "border-border bg-muted text-muted-foreground hover:bg-muted/80"
|
|
6548
|
+
),
|
|
6549
|
+
"data-testid": `workflow-result-${w.external_id}`,
|
|
6550
|
+
children: label
|
|
6551
|
+
}
|
|
6552
|
+
);
|
|
5697
6553
|
},
|
|
5698
6554
|
renderActions: (w) => {
|
|
5699
6555
|
const { props: p, l: lb } = latest.current;
|
|
@@ -5821,61 +6677,73 @@ function WorkflowsTable(props) {
|
|
|
5821
6677
|
(w) => hasTrigger(w) && (w.is_owner !== false || props.canEditShared)
|
|
5822
6678
|
);
|
|
5823
6679
|
const clearSelection = () => setSelected([]);
|
|
5824
|
-
const hasSavedWorkflow = workflows.some((w) => !isSkillRow(w));
|
|
5825
6680
|
return /* @__PURE__ */ jsxs(
|
|
5826
6681
|
"div",
|
|
5827
6682
|
{
|
|
5828
|
-
className: "flex min-h-0 flex-1 flex-col
|
|
6683
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
5829
6684
|
"data-testid": testIdOr(testId, { testId: "workflow-list" }),
|
|
5830
6685
|
children: [
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
[
|
|
5836
|
-
["skills", l.filterSkills],
|
|
5837
|
-
["workflows", l.filterWorkflows],
|
|
5838
|
-
["active", l.filterActive],
|
|
5839
|
-
["paused", l.filterPaused]
|
|
5840
|
-
].map(([key, label]) => {
|
|
5841
|
-
const isSelected = filter === key;
|
|
5842
|
-
return /* @__PURE__ */ jsxs(
|
|
5843
|
-
"button",
|
|
6686
|
+
/* @__PURE__ */ jsx(
|
|
6687
|
+
TabHeader,
|
|
6688
|
+
{
|
|
6689
|
+
testId: "automations-tab-header",
|
|
6690
|
+
tabs: [
|
|
5844
6691
|
{
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
|
|
5851
|
-
|
|
5852
|
-
),
|
|
5853
|
-
"data-testid": `workflow-filter-${key}`,
|
|
5854
|
-
children: [
|
|
5855
|
-
label,
|
|
5856
|
-
/* @__PURE__ */ jsx("span", { className: "tabular-nums opacity-70", children: counts[key] })
|
|
5857
|
-
]
|
|
6692
|
+
id: "automations",
|
|
6693
|
+
label: "",
|
|
6694
|
+
count: shown.length,
|
|
6695
|
+
countIcon: /* @__PURE__ */ jsx(Workflow, { className: "size-3.5" }),
|
|
6696
|
+
countPlacement: "leading",
|
|
6697
|
+
presentation: "count",
|
|
6698
|
+
hasActiveFilters: !!q || [...filterStates.values()].some(Boolean)
|
|
5858
6699
|
},
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
/* @__PURE__ */ jsx(
|
|
5865
|
-
|
|
6700
|
+
...props.tabs ?? []
|
|
6701
|
+
],
|
|
6702
|
+
activeTabId: props.activeTabId ?? "automations",
|
|
6703
|
+
onTabChange: props.onTabChange ?? (() => {
|
|
6704
|
+
}),
|
|
6705
|
+
firstTabContent: /* @__PURE__ */ jsx(
|
|
6706
|
+
FilterInput,
|
|
5866
6707
|
{
|
|
5867
|
-
type: "search",
|
|
5868
6708
|
value: query,
|
|
5869
|
-
onChange:
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
6709
|
+
onChange: setQuery,
|
|
6710
|
+
fields: ["text"],
|
|
6711
|
+
onFieldsChange: () => {
|
|
6712
|
+
},
|
|
6713
|
+
hideFieldPicker: true,
|
|
6714
|
+
ariaLabel: l.searchLabel,
|
|
6715
|
+
testIds: { input: "workflow-search" },
|
|
6716
|
+
filter: /* @__PURE__ */ jsx(
|
|
6717
|
+
TriStateFilterMenu,
|
|
6718
|
+
{
|
|
6719
|
+
testId: "automations-filter-button",
|
|
6720
|
+
open: filterOpen,
|
|
6721
|
+
onOpenChange: setFilterOpen,
|
|
6722
|
+
filterStates,
|
|
6723
|
+
onFiltersChange: setFilterStates,
|
|
6724
|
+
triggerClassName: "flex h-5 items-center gap-0.5 rounded px-1 text-muted-foreground hover:text-foreground pointer-coarse:h-11! pointer-coarse:min-w-11 pointer-coarse:justify-center",
|
|
6725
|
+
renderChevron: true,
|
|
6726
|
+
disableHoverOpen: true,
|
|
6727
|
+
options: [
|
|
6728
|
+
...!props.automationsOnly ? [
|
|
6729
|
+
{ id: "skills", label: l.filterSkills, count: counts.skills },
|
|
6730
|
+
{
|
|
6731
|
+
id: "workflows",
|
|
6732
|
+
label: l.filterWorkflows,
|
|
6733
|
+
count: counts.workflows
|
|
6734
|
+
}
|
|
6735
|
+
] : [],
|
|
6736
|
+
{ id: "active", label: l.filterActive, count: counts.active },
|
|
6737
|
+
{ id: "paused", label: l.filterPaused, count: counts.paused }
|
|
6738
|
+
]
|
|
6739
|
+
}
|
|
6740
|
+
)
|
|
5874
6741
|
}
|
|
5875
|
-
)
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
6742
|
+
),
|
|
6743
|
+
rightContent: header
|
|
6744
|
+
}
|
|
6745
|
+
),
|
|
6746
|
+
props.content ? props.content : workflows.length === 0 && !isLoading ? /* @__PURE__ */ jsx(
|
|
5879
6747
|
EmptyState,
|
|
5880
6748
|
{
|
|
5881
6749
|
icon: Workflow,
|
|
@@ -5905,7 +6773,7 @@ function WorkflowsTable(props) {
|
|
|
5905
6773
|
gridOptions: GRID_OPTIONS
|
|
5906
6774
|
}
|
|
5907
6775
|
) }),
|
|
5908
|
-
/* @__PURE__ */ jsx(SelectionBar, { count: selected.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6776
|
+
!props.content && /* @__PURE__ */ jsx(SelectionBar, { count: selected.length, onClear: clearSelection, children: (isCompact) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5909
6777
|
props.onToggleActiveMany && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5910
6778
|
/* @__PURE__ */ jsx(
|
|
5911
6779
|
SelectionBarAction,
|
|
@@ -5956,16 +6824,7 @@ function WorkflowsTable(props) {
|
|
|
5956
6824
|
}
|
|
5957
6825
|
);
|
|
5958
6826
|
}
|
|
5959
|
-
var
|
|
5960
|
-
{ colId: "shared", minWidth: 1060 },
|
|
5961
|
-
{ colId: "last_run", minWidth: 880 }
|
|
5962
|
-
];
|
|
5963
|
-
var GRID_OPTIONS = {
|
|
5964
|
-
suppressClickEdit: true,
|
|
5965
|
-
suppressCellFocus: true,
|
|
5966
|
-
suppressColumnVirtualisation: true,
|
|
5967
|
-
onGridSizeChanged: (event) => applyColumnWidthRules(event.api, event.clientWidth, WIDTH_RULES2)
|
|
5968
|
-
};
|
|
6827
|
+
var GRID_OPTIONS = { suppressClickEdit: true };
|
|
5969
6828
|
var DEFAULT_TASK_ACTIVITY_LABELS = {
|
|
5970
6829
|
title: "Activity",
|
|
5971
6830
|
empty: "Nothing has happened yet.",
|
|
@@ -5995,11 +6854,19 @@ var ICONS = {
|
|
|
5995
6854
|
awaiting_access: /* @__PURE__ */ jsx(Lock, { className: "size-3.5", "aria-hidden": true }),
|
|
5996
6855
|
access_granted: /* @__PURE__ */ jsx(KeyRound, { className: "size-3.5", "aria-hidden": true }),
|
|
5997
6856
|
ready_for_review: /* @__PURE__ */ jsx(CircleDot, { className: "size-3.5", "aria-hidden": true }),
|
|
6857
|
+
reviewed: /* @__PURE__ */ jsx(CheckCircle2, { className: "size-3.5", "aria-hidden": true }),
|
|
5998
6858
|
handed_off: /* @__PURE__ */ jsx(UserRoundCog, { className: "size-3.5", "aria-hidden": true }),
|
|
5999
6859
|
changes_requested: /* @__PURE__ */ jsx(MessageSquareReply, { className: "size-3.5", "aria-hidden": true }),
|
|
6000
6860
|
done: /* @__PURE__ */ jsx(CheckCircle2, { className: "size-3.5", "aria-hidden": true }),
|
|
6001
6861
|
reopened: /* @__PURE__ */ jsx(RotateCcw, { className: "size-3.5", "aria-hidden": true }),
|
|
6002
|
-
failed: /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5", "aria-hidden": true })
|
|
6862
|
+
failed: /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5", "aria-hidden": true }),
|
|
6863
|
+
participant_joined: /* @__PURE__ */ jsx(UserRoundCog, { className: "size-3.5", "aria-hidden": true }),
|
|
6864
|
+
assistant_responded: /* @__PURE__ */ jsx(Sparkles, { className: "size-3.5", "aria-hidden": true }),
|
|
6865
|
+
artifact_created: /* @__PURE__ */ jsx(Sparkles, { className: "size-3.5", "aria-hidden": true }),
|
|
6866
|
+
artifact_edited: /* @__PURE__ */ jsx(MessageSquareReply, { className: "size-3.5", "aria-hidden": true }),
|
|
6867
|
+
document_added: /* @__PURE__ */ jsx(Sparkles, { className: "size-3.5", "aria-hidden": true }),
|
|
6868
|
+
document_removed: /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5", "aria-hidden": true }),
|
|
6869
|
+
notified: /* @__PURE__ */ jsx(UserRoundCog, { className: "size-3.5", "aria-hidden": true })
|
|
6003
6870
|
};
|
|
6004
6871
|
var asString = (v) => typeof v === "string" && v.trim() ? v : null;
|
|
6005
6872
|
function summarizeError(error) {
|
|
@@ -6023,6 +6890,20 @@ function TaskActivityTimeline({
|
|
|
6023
6890
|
const agentId = asString(detail.agent_ext_id);
|
|
6024
6891
|
const agent = agentId ? agentName?.(agentId) : void 0;
|
|
6025
6892
|
switch (e.kind) {
|
|
6893
|
+
case "participant_joined":
|
|
6894
|
+
return { headline: "Joined the conversation" };
|
|
6895
|
+
case "assistant_responded":
|
|
6896
|
+
return { headline: "Responded" };
|
|
6897
|
+
case "artifact_created":
|
|
6898
|
+
return { headline: "Created a document" };
|
|
6899
|
+
case "artifact_edited":
|
|
6900
|
+
return { headline: "Edited a document" };
|
|
6901
|
+
case "document_added":
|
|
6902
|
+
return { headline: "Added a document" };
|
|
6903
|
+
case "document_removed":
|
|
6904
|
+
return { headline: "Removed a document" };
|
|
6905
|
+
case "notified":
|
|
6906
|
+
return { headline: "Sent a notification" };
|
|
6026
6907
|
case "created":
|
|
6027
6908
|
return { headline: detail.from_workflow ? l.createdFromWorkflow : l.created };
|
|
6028
6909
|
case "run_started":
|
|
@@ -6033,6 +6914,8 @@ function TaskActivityTimeline({
|
|
|
6033
6914
|
return { headline: l.accessGranted };
|
|
6034
6915
|
case "ready_for_review":
|
|
6035
6916
|
return { headline: l.readyForReview };
|
|
6917
|
+
case "reviewed":
|
|
6918
|
+
return { headline: "Approved this review stage" };
|
|
6036
6919
|
case "handed_off":
|
|
6037
6920
|
return {
|
|
6038
6921
|
headline: l.handedOff,
|
|
@@ -6044,7 +6927,7 @@ function TaskActivityTimeline({
|
|
|
6044
6927
|
extra: note ? /* @__PURE__ */ jsx(Quote, { text: l.sentBackNote(note) }) : void 0
|
|
6045
6928
|
};
|
|
6046
6929
|
case "done":
|
|
6047
|
-
return { headline: l.done };
|
|
6930
|
+
return { headline: l.done, extra: note ? /* @__PURE__ */ jsx(Quote, { text: note }) : void 0 };
|
|
6048
6931
|
case "reopened":
|
|
6049
6932
|
return { headline: l.reopened };
|
|
6050
6933
|
case "failed": {
|
|
@@ -6112,39 +6995,189 @@ function TaskActivityTimeline({
|
|
|
6112
6995
|
);
|
|
6113
6996
|
}) });
|
|
6114
6997
|
}
|
|
6115
|
-
function Quote({ text }) {
|
|
6116
|
-
return /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 pl-2 text-xs text-muted-foreground whitespace-pre-wrap", children: text });
|
|
6998
|
+
function Quote({ text }) {
|
|
6999
|
+
return /* @__PURE__ */ jsx("blockquote", { className: "border-l-2 pl-2 text-xs text-muted-foreground whitespace-pre-wrap", children: text });
|
|
7000
|
+
}
|
|
7001
|
+
function TaskActivityDialog({
|
|
7002
|
+
open,
|
|
7003
|
+
onOpenChange,
|
|
7004
|
+
taskName,
|
|
7005
|
+
events,
|
|
7006
|
+
isLoading,
|
|
7007
|
+
isError,
|
|
7008
|
+
labels,
|
|
7009
|
+
testId,
|
|
7010
|
+
...timeline
|
|
7011
|
+
}) {
|
|
7012
|
+
const l = { ...DEFAULT_TASK_ACTIVITY_LABELS, ...labels };
|
|
7013
|
+
const id = testIdOr(testId, { testId: "task-activity" });
|
|
7014
|
+
const count = events?.length ?? 0;
|
|
7015
|
+
const scrollToEnd = useCallback(
|
|
7016
|
+
(el) => {
|
|
7017
|
+
if (count >= 0) el?.scrollIntoView?.({ block: "end" });
|
|
7018
|
+
},
|
|
7019
|
+
[count]
|
|
7020
|
+
);
|
|
7021
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { presentation: "sheet", className: "max-h-[80dvh] sm:max-w-lg", "data-testid": id, children: [
|
|
7022
|
+
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
7023
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: l.title }),
|
|
7024
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "truncate", children: taskName })
|
|
7025
|
+
] }),
|
|
7026
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-[55dvh] overflow-y-auto pr-1", "data-testid": `${id}-scroll`, children: [
|
|
7027
|
+
isLoading && !events ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.loading }) : isError && !events ? /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: l.error }) : count === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.empty }) : /* @__PURE__ */ jsx(TaskActivityTimeline, { events: events ?? [], labels, testId: id, ...timeline }),
|
|
7028
|
+
/* @__PURE__ */ jsx("div", { ref: scrollToEnd })
|
|
7029
|
+
] })
|
|
7030
|
+
] }) });
|
|
7031
|
+
}
|
|
7032
|
+
function TaskFlow({
|
|
7033
|
+
items,
|
|
7034
|
+
className
|
|
7035
|
+
}) {
|
|
7036
|
+
const scroll = useRef(null);
|
|
7037
|
+
const following = useRef(true);
|
|
7038
|
+
const latest = items.at(-1)?.id;
|
|
7039
|
+
useLayoutEffect(() => {
|
|
7040
|
+
const el = scroll.current;
|
|
7041
|
+
if (!el) return;
|
|
7042
|
+
const follow = () => {
|
|
7043
|
+
if (following.current) el.scrollLeft = el.scrollWidth;
|
|
7044
|
+
};
|
|
7045
|
+
follow();
|
|
7046
|
+
const resize = new ResizeObserver(follow);
|
|
7047
|
+
resize.observe(el);
|
|
7048
|
+
return () => resize.disconnect();
|
|
7049
|
+
}, [latest]);
|
|
7050
|
+
return /* @__PURE__ */ jsx(
|
|
7051
|
+
"div",
|
|
7052
|
+
{
|
|
7053
|
+
ref: scroll,
|
|
7054
|
+
className: cn("min-w-0 flex-1 overflow-x-auto overscroll-x-contain", className),
|
|
7055
|
+
"data-testid": "thread-flow",
|
|
7056
|
+
role: "region",
|
|
7057
|
+
"aria-label": "Thread activity",
|
|
7058
|
+
tabIndex: 0,
|
|
7059
|
+
onScroll: (e) => {
|
|
7060
|
+
const el = e.currentTarget;
|
|
7061
|
+
following.current = el.scrollWidth - el.scrollLeft - el.clientWidth < 24;
|
|
7062
|
+
},
|
|
7063
|
+
children: /* @__PURE__ */ jsx("ol", { className: "flex w-max min-w-full items-center gap-1", children: items.map((item, i) => {
|
|
7064
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7065
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0", children: item.avatar }),
|
|
7066
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 text-left", children: [
|
|
7067
|
+
/* @__PURE__ */ jsx("span", { className: "block max-w-32 truncate text-[11px] leading-tight font-medium", children: item.label }),
|
|
7068
|
+
/* @__PURE__ */ jsx(
|
|
7069
|
+
"span",
|
|
7070
|
+
{
|
|
7071
|
+
className: "block text-[10px] leading-tight text-muted-foreground",
|
|
7072
|
+
title: item.exactTime,
|
|
7073
|
+
children: item.time
|
|
7074
|
+
}
|
|
7075
|
+
)
|
|
7076
|
+
] })
|
|
7077
|
+
] });
|
|
7078
|
+
const cls = cn(
|
|
7079
|
+
"flex shrink-0 items-center gap-1.5 rounded-md px-1 py-0.5",
|
|
7080
|
+
item.current && "bg-accent text-accent-foreground"
|
|
7081
|
+
);
|
|
7082
|
+
return /* @__PURE__ */ jsxs(
|
|
7083
|
+
"li",
|
|
7084
|
+
{
|
|
7085
|
+
className: "flex shrink-0 items-center gap-1",
|
|
7086
|
+
"data-testid": `thread-flow-${item.id}`,
|
|
7087
|
+
children: [
|
|
7088
|
+
i > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "size-3 shrink-0 text-muted-foreground", "aria-hidden": true }),
|
|
7089
|
+
item.onSelect ? /* @__PURE__ */ jsx(
|
|
7090
|
+
"button",
|
|
7091
|
+
{
|
|
7092
|
+
className: cn(cls, "hover:bg-muted"),
|
|
7093
|
+
onClick: item.onSelect,
|
|
7094
|
+
title: item.description ?? item.label,
|
|
7095
|
+
children: content
|
|
7096
|
+
}
|
|
7097
|
+
) : item.detail ? /* @__PURE__ */ jsxs(Popover, { children: [
|
|
7098
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
7099
|
+
"button",
|
|
7100
|
+
{
|
|
7101
|
+
className: cn(cls, "hover:bg-muted"),
|
|
7102
|
+
title: item.description ?? item.label,
|
|
7103
|
+
children: content
|
|
7104
|
+
}
|
|
7105
|
+
) }),
|
|
7106
|
+
/* @__PURE__ */ jsx(PopoverContent, { className: "max-h-72 overflow-y-auto text-sm whitespace-pre-wrap", children: item.detail })
|
|
7107
|
+
] }) : /* @__PURE__ */ jsx("div", { className: cls, title: item.description ?? item.label, children: content })
|
|
7108
|
+
]
|
|
7109
|
+
},
|
|
7110
|
+
item.id
|
|
7111
|
+
);
|
|
7112
|
+
}) })
|
|
7113
|
+
}
|
|
7114
|
+
);
|
|
7115
|
+
}
|
|
7116
|
+
function ThreadActivity({ item, children }) {
|
|
7117
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-center px-3 py-2", "data-testid": `thread-activity-${item.id}`, children: /* @__PURE__ */ jsxs(
|
|
7118
|
+
"div",
|
|
7119
|
+
{
|
|
7120
|
+
className: "max-w-full text-center text-xs text-muted-foreground",
|
|
7121
|
+
title: item.description,
|
|
7122
|
+
children: [
|
|
7123
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-1.5", children: [
|
|
7124
|
+
item.avatar,
|
|
7125
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
7126
|
+
/* @__PURE__ */ jsx("time", { title: item.exactTime, children: item.time })
|
|
7127
|
+
] }),
|
|
7128
|
+
children,
|
|
7129
|
+
item.detail && /* @__PURE__ */ jsx("div", { className: "mt-1 whitespace-pre-wrap break-words text-left", children: item.detail })
|
|
7130
|
+
]
|
|
7131
|
+
}
|
|
7132
|
+
) });
|
|
6117
7133
|
}
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
7134
|
+
|
|
7135
|
+
// src/agents/tasks/compact-thread-activity.ts
|
|
7136
|
+
function compactThreadActivity(events) {
|
|
7137
|
+
const result = [];
|
|
7138
|
+
const batches = /* @__PURE__ */ new Map();
|
|
7139
|
+
for (const event of events) {
|
|
7140
|
+
if (event.kind === "notified") {
|
|
7141
|
+
if (["conversation_ready_for_review", "conversation_done"].includes(
|
|
7142
|
+
String(event.detail?.notification_type)
|
|
7143
|
+
))
|
|
7144
|
+
continue;
|
|
7145
|
+
const source = event.detail?.batch_ext_id ?? event.detail?.message_ext_id;
|
|
7146
|
+
const key = typeof source === "string" && source ? `${event.actor_ext_id}:${source}` : event.external_id;
|
|
7147
|
+
let entry = batches.get(key);
|
|
7148
|
+
if (!entry) {
|
|
7149
|
+
entry = { event, label: "Notified 1 user", recipients: [] };
|
|
7150
|
+
batches.set(key, entry);
|
|
7151
|
+
result.push(entry);
|
|
7152
|
+
}
|
|
7153
|
+
if (event.to_ext_id && !entry.recipients.includes(event.to_ext_id))
|
|
7154
|
+
entry.recipients.push(event.to_ext_id);
|
|
7155
|
+
const count = Math.max(1, entry.recipients.length);
|
|
7156
|
+
entry.label = `Notified ${count} ${count === 1 ? "user" : "users"}`;
|
|
7157
|
+
} else if (["artifact_created", "artifact_edited", "document_added", "document_removed"].includes(
|
|
7158
|
+
event.kind
|
|
7159
|
+
)) {
|
|
7160
|
+
const labels = {
|
|
7161
|
+
artifact_created: "Generated",
|
|
7162
|
+
artifact_edited: "Edited document",
|
|
7163
|
+
document_added: "Added document",
|
|
7164
|
+
document_removed: "Removed document"
|
|
7165
|
+
};
|
|
7166
|
+
result.push({ event, label: labels[event.kind], recipients: [] });
|
|
7167
|
+
} else if (["created", "participant_joined", "assistant_responded", "done"].includes(event.kind)) {
|
|
7168
|
+
result.push({
|
|
7169
|
+
event,
|
|
7170
|
+
label: {
|
|
7171
|
+
created: "Started Task",
|
|
7172
|
+
participant_joined: "Followed Up",
|
|
7173
|
+
assistant_responded: "Answered",
|
|
7174
|
+
done: "Marked Done"
|
|
7175
|
+
}[event.kind],
|
|
7176
|
+
recipients: []
|
|
7177
|
+
});
|
|
7178
|
+
}
|
|
7179
|
+
}
|
|
7180
|
+
return result;
|
|
6148
7181
|
}
|
|
6149
7182
|
var DEFAULT_TASK_THREAD_CHIP_LABELS = {
|
|
6150
7183
|
open: "Open thread",
|
|
@@ -6206,105 +7239,127 @@ var DEFAULT_TASK_RUNS_DIALOG_LABELS = {
|
|
|
6206
7239
|
var STATUS_STYLE = {
|
|
6207
7240
|
running: "bg-ai-soft text-ai-ink",
|
|
6208
7241
|
success: "bg-green-bg text-green-text",
|
|
7242
|
+
completed: "bg-green-bg text-green-text",
|
|
6209
7243
|
failed: "bg-red-bg text-red-text"
|
|
6210
7244
|
};
|
|
6211
7245
|
function TaskRunsDialog({
|
|
7246
|
+
inline = false,
|
|
7247
|
+
renderErrorReport,
|
|
7248
|
+
hideHeader = false,
|
|
6212
7249
|
open,
|
|
6213
7250
|
onOpenChange,
|
|
6214
7251
|
taskName,
|
|
6215
|
-
error,
|
|
6216
7252
|
runs,
|
|
6217
7253
|
isLoading,
|
|
6218
7254
|
onOpenRun,
|
|
7255
|
+
onOpenResult,
|
|
6219
7256
|
getRunHref,
|
|
6220
7257
|
testIds,
|
|
6221
7258
|
labels
|
|
6222
7259
|
}) {
|
|
6223
7260
|
const l = { ...DEFAULT_TASK_RUNS_DIALOG_LABELS, ...labels };
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
" ",
|
|
6235
|
-
l.title(taskName)
|
|
6236
|
-
] }),
|
|
6237
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: l.description })
|
|
6238
|
-
] }),
|
|
6239
|
-
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "rounded-md bg-red-bg p-3 text-sm text-red-text", children: error }),
|
|
6240
|
-
isLoading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 py-8 text-muted-foreground", children: [
|
|
6241
|
-
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
|
|
6242
|
-
" ",
|
|
6243
|
-
l.loading
|
|
6244
|
-
] }) : runs.length === 0 ? /* @__PURE__ */ jsx(
|
|
6245
|
-
"p",
|
|
7261
|
+
const columns = useMemo(
|
|
7262
|
+
() => [
|
|
7263
|
+
{
|
|
7264
|
+
colId: "status",
|
|
7265
|
+
field: "status",
|
|
7266
|
+
headerName: "Status",
|
|
7267
|
+
width: 160,
|
|
7268
|
+
minWidth: 140,
|
|
7269
|
+
cellRenderer: ({ data }) => data && /* @__PURE__ */ jsx(
|
|
7270
|
+
"span",
|
|
6246
7271
|
{
|
|
6247
|
-
className:
|
|
6248
|
-
|
|
6249
|
-
|
|
7272
|
+
className: cn(
|
|
7273
|
+
"rounded-full px-2 py-0.5 text-xs font-medium capitalize",
|
|
7274
|
+
STATUS_STYLE[data.status] ?? "text-muted-foreground"
|
|
7275
|
+
),
|
|
7276
|
+
children: workflowRunStatusLabel(data.status)
|
|
6250
7277
|
}
|
|
6251
|
-
)
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
7278
|
+
)
|
|
7279
|
+
},
|
|
7280
|
+
{ colId: "when", field: "when", headerName: "Run", flex: 2, minWidth: 240 },
|
|
7281
|
+
{
|
|
7282
|
+
colId: "result",
|
|
7283
|
+
headerName: "",
|
|
7284
|
+
width: 280,
|
|
7285
|
+
minWidth: 220,
|
|
7286
|
+
sortable: false,
|
|
7287
|
+
cellRenderer: ({ data: run }) => {
|
|
7288
|
+
if (!run) return null;
|
|
7289
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full items-center gap-2", children: [
|
|
7290
|
+
run.error && renderErrorReport?.(run),
|
|
7291
|
+
(run.conversationId || run.resultId && onOpenResult) && /* @__PURE__ */ jsx(Button, { asChild: true, variant: "ghost", size: "sm", className: "h-7 gap-1.5", children: /* @__PURE__ */ jsxs(
|
|
7292
|
+
ActionLink,
|
|
6258
7293
|
{
|
|
6259
|
-
|
|
6260
|
-
|
|
7294
|
+
href: getRunHref?.(run),
|
|
7295
|
+
onSelect: () => {
|
|
7296
|
+
if (run.conversationId) onOpenRun(run.conversationId);
|
|
7297
|
+
else if (run.resultId) onOpenResult?.(run.resultId);
|
|
7298
|
+
onOpenChange(false);
|
|
7299
|
+
},
|
|
7300
|
+
"data-testid": testIdOr(testIds?.open, { testId: "task-run-open" }),
|
|
6261
7301
|
children: [
|
|
6262
|
-
/* @__PURE__ */ jsx(
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
className: cn(
|
|
6266
|
-
"shrink-0 rounded-full px-2 py-0.5 text-xs font-medium capitalize",
|
|
6267
|
-
STATUS_STYLE[run.status] ?? "bg-background text-muted-foreground"
|
|
6268
|
-
),
|
|
6269
|
-
children: run.status
|
|
6270
|
-
}
|
|
6271
|
-
),
|
|
6272
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
6273
|
-
/* @__PURE__ */ jsx("p", { className: "truncate text-sm", children: run.when || "\u2014" }),
|
|
6274
|
-
run.error && /* @__PURE__ */ jsx("p", { className: "truncate text-xs text-red-text", title: run.error, children: run.error })
|
|
6275
|
-
] }),
|
|
6276
|
-
run.conversationId && /* @__PURE__ */ jsx(
|
|
6277
|
-
Button,
|
|
6278
|
-
{
|
|
6279
|
-
asChild: true,
|
|
6280
|
-
variant: "outline",
|
|
6281
|
-
size: "sm",
|
|
6282
|
-
className: "h-7 shrink-0 gap-1.5 pointer-coarse:h-11",
|
|
6283
|
-
children: /* @__PURE__ */ jsxs(
|
|
6284
|
-
ActionLink,
|
|
6285
|
-
{
|
|
6286
|
-
href: getRunHref?.(run),
|
|
6287
|
-
onSelect: () => {
|
|
6288
|
-
onOpenRun(run.conversationId);
|
|
6289
|
-
onOpenChange(false);
|
|
6290
|
-
},
|
|
6291
|
-
"data-testid": testIdOr(testIds?.open, { testId: "task-run-open" }),
|
|
6292
|
-
children: [
|
|
6293
|
-
/* @__PURE__ */ jsx(Eye, { size: 13 }),
|
|
6294
|
-
" ",
|
|
6295
|
-
l.open
|
|
6296
|
-
]
|
|
6297
|
-
}
|
|
6298
|
-
)
|
|
6299
|
-
}
|
|
6300
|
-
)
|
|
7302
|
+
/* @__PURE__ */ jsx(Eye, { size: 13 }),
|
|
7303
|
+
" ",
|
|
7304
|
+
l.open
|
|
6301
7305
|
]
|
|
6302
|
-
}
|
|
6303
|
-
|
|
6304
|
-
|
|
7306
|
+
}
|
|
7307
|
+
) })
|
|
7308
|
+
] });
|
|
7309
|
+
}
|
|
7310
|
+
}
|
|
7311
|
+
],
|
|
7312
|
+
[onOpenRun, onOpenResult, getRunHref, onOpenChange, testIds?.open, l.open, renderErrorReport]
|
|
7313
|
+
);
|
|
7314
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7315
|
+
hideHeader ? null : inline ? /* @__PURE__ */ jsx(
|
|
7316
|
+
TabHeader,
|
|
7317
|
+
{
|
|
7318
|
+
tabs: [
|
|
7319
|
+
{
|
|
7320
|
+
id: "history",
|
|
7321
|
+
label: l.title(taskName),
|
|
7322
|
+
count: runs.length,
|
|
7323
|
+
countIcon: /* @__PURE__ */ jsx(History, { size: 14 }),
|
|
7324
|
+
presentation: "count",
|
|
7325
|
+
onClose: () => onOpenChange(false)
|
|
6305
7326
|
}
|
|
6306
|
-
|
|
6307
|
-
|
|
7327
|
+
],
|
|
7328
|
+
activeTabId: "history",
|
|
7329
|
+
onTabChange: () => {
|
|
7330
|
+
}
|
|
7331
|
+
}
|
|
7332
|
+
) : /* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
7333
|
+
/* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
7334
|
+
/* @__PURE__ */ jsx(History, { size: 16 }),
|
|
7335
|
+
" ",
|
|
7336
|
+
l.title(taskName)
|
|
7337
|
+
] }),
|
|
7338
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: l.description })
|
|
7339
|
+
] }),
|
|
7340
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx(
|
|
7341
|
+
GridView,
|
|
7342
|
+
{
|
|
7343
|
+
testId: testIdOr(testIds?.list, { testId: "task-runs-list" }),
|
|
7344
|
+
gridId: "workflow-runs",
|
|
7345
|
+
items: runs,
|
|
7346
|
+
columnDefs: columns,
|
|
7347
|
+
getItemId: (run) => run.id,
|
|
7348
|
+
getRowTestId: () => testIdOr(testIds?.row, { testId: "task-run-row" }),
|
|
7349
|
+
isLoading,
|
|
7350
|
+
loadingMessage: l.loading,
|
|
7351
|
+
emptyState: { title: l.empty },
|
|
7352
|
+
height: "100%"
|
|
7353
|
+
}
|
|
7354
|
+
) })
|
|
7355
|
+
] });
|
|
7356
|
+
return inline ? /* @__PURE__ */ jsx("section", { className: "flex min-h-0 flex-1 flex-col", "data-testid": "automation-history", children: content }) : /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx(
|
|
7357
|
+
DialogContent,
|
|
7358
|
+
{
|
|
7359
|
+
presentation: "sheet",
|
|
7360
|
+
className: "flex h-[min(32rem,calc(100dvh-2rem))] min-h-0 max-w-3xl flex-col",
|
|
7361
|
+
"data-testid": testIdOr(testIds?.modal, { testId: "task-runs-modal" }),
|
|
7362
|
+
children: content
|
|
6308
7363
|
}
|
|
6309
7364
|
) });
|
|
6310
7365
|
}
|
|
@@ -6426,7 +7481,7 @@ var DEFAULT_TASK_COMPOSER_LABELS = {
|
|
|
6426
7481
|
dueClear: "Clear date",
|
|
6427
7482
|
parentTask: "Part of",
|
|
6428
7483
|
parentTaskNone: "Nothing (top-level)",
|
|
6429
|
-
visibility: "
|
|
7484
|
+
visibility: "Visibility",
|
|
6430
7485
|
visibilityWorkspace: "Workspace",
|
|
6431
7486
|
visibilityPrivate: "Only me",
|
|
6432
7487
|
assistant: "Task Assistant",
|
|
@@ -6476,8 +7531,8 @@ var DEFAULT_TASK_COMPOSER_LABELS = {
|
|
|
6476
7531
|
empty: "No match.",
|
|
6477
7532
|
cancel: "Cancel",
|
|
6478
7533
|
addTask: "Add task",
|
|
6479
|
-
addAndStart: "
|
|
6480
|
-
addAndSchedule: "
|
|
7534
|
+
addAndStart: "Start now",
|
|
7535
|
+
addAndSchedule: "Schedule",
|
|
6481
7536
|
save: "Save changes",
|
|
6482
7537
|
saving: "Saving\u2026"
|
|
6483
7538
|
};
|
|
@@ -6496,7 +7551,7 @@ function defaultTaskComposerValues(workflows, initial) {
|
|
|
6496
7551
|
afterTaskId: "",
|
|
6497
7552
|
parentTaskId: "",
|
|
6498
7553
|
signoffUserId: "",
|
|
6499
|
-
shared:
|
|
7554
|
+
shared: false,
|
|
6500
7555
|
description: "",
|
|
6501
7556
|
dueAt: "",
|
|
6502
7557
|
agentId: "",
|
|
@@ -6506,7 +7561,6 @@ function defaultTaskComposerValues(workflows, initial) {
|
|
|
6506
7561
|
...initial
|
|
6507
7562
|
};
|
|
6508
7563
|
}
|
|
6509
|
-
var WHEN_ORDER = ["now", "once", "repeat", "event", "task"];
|
|
6510
7564
|
var GLYPH2 = "size-3.5 shrink-0";
|
|
6511
7565
|
function missingWhen(values, runAtPast) {
|
|
6512
7566
|
if (values.when === "now" || values.when === "manual") return null;
|
|
@@ -6520,6 +7574,8 @@ function WorkflowComposer({
|
|
|
6520
7574
|
open,
|
|
6521
7575
|
onOpenChange,
|
|
6522
7576
|
isEdit = false,
|
|
7577
|
+
saveOnly = false,
|
|
7578
|
+
hideRunLater = false,
|
|
6523
7579
|
workflows,
|
|
6524
7580
|
agents,
|
|
6525
7581
|
people,
|
|
@@ -6528,6 +7584,8 @@ function WorkflowComposer({
|
|
|
6528
7584
|
initialValues,
|
|
6529
7585
|
onValuesChange,
|
|
6530
7586
|
timezones = [],
|
|
7587
|
+
eventOptions,
|
|
7588
|
+
eventWorkflowOptions,
|
|
6531
7589
|
goal,
|
|
6532
7590
|
standingAccess,
|
|
6533
7591
|
scopeSource,
|
|
@@ -6549,7 +7607,11 @@ function WorkflowComposer({
|
|
|
6549
7607
|
const l = {
|
|
6550
7608
|
...DEFAULT_TASK_COMPOSER_LABELS,
|
|
6551
7609
|
...labels,
|
|
6552
|
-
whenOptions: {
|
|
7610
|
+
whenOptions: {
|
|
7611
|
+
...DEFAULT_TASK_COMPOSER_LABELS.whenOptions,
|
|
7612
|
+
...labels?.whenOptions,
|
|
7613
|
+
...saveOnly ? { now: "When needed" } : {}
|
|
7614
|
+
},
|
|
6553
7615
|
accessOptions: { ...DEFAULT_TASK_COMPOSER_LABELS.accessOptions, ...labels?.accessOptions }
|
|
6554
7616
|
};
|
|
6555
7617
|
const seed = useMemo(
|
|
@@ -6563,12 +7625,15 @@ function WorkflowComposer({
|
|
|
6563
7625
|
seed,
|
|
6564
7626
|
onValuesChange
|
|
6565
7627
|
);
|
|
7628
|
+
const [runOnce, setRunOnce] = useState(false);
|
|
7629
|
+
const [automationWhen, setAutomationWhen] = useState(seed.when);
|
|
6566
7630
|
const [planOpen, setPlanOpen] = useState(false);
|
|
6567
7631
|
const [moreOpen, setMoreOpen] = useState(false);
|
|
6568
7632
|
const [agentAutoSet, setAgentAutoSet] = useState(false);
|
|
6569
7633
|
useEffect(() => {
|
|
6570
7634
|
if (open) {
|
|
6571
7635
|
if (valuesProp === void 0) setValues(seed);
|
|
7636
|
+
setRunOnce(false);
|
|
6572
7637
|
setPlanOpen(false);
|
|
6573
7638
|
setAgentAutoSet(false);
|
|
6574
7639
|
}
|
|
@@ -6597,7 +7662,12 @@ function WorkflowComposer({
|
|
|
6597
7662
|
const derivedName = workflow ? deriveWorkflowName(workflow, values.inputs) : "";
|
|
6598
7663
|
const pickWorkflow = (next) => {
|
|
6599
7664
|
const def = workflows.find((w) => w.id === next);
|
|
6600
|
-
setValues({
|
|
7665
|
+
setValues({
|
|
7666
|
+
...values,
|
|
7667
|
+
workflowId: next,
|
|
7668
|
+
inputs: def ? defaultInputs(def) : {},
|
|
7669
|
+
...def?.documentAction ? { access: "standing" } : {}
|
|
7670
|
+
});
|
|
6601
7671
|
};
|
|
6602
7672
|
const pickWhen = (next) => {
|
|
6603
7673
|
const goesScheduled = next !== "now" && next !== "manual";
|
|
@@ -6621,14 +7691,18 @@ function WorkflowComposer({
|
|
|
6621
7691
|
setAgentAutoSet(false);
|
|
6622
7692
|
set("agentId", agentId);
|
|
6623
7693
|
};
|
|
6624
|
-
const submit = () =>
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
|
|
6628
|
-
|
|
6629
|
-
|
|
6630
|
-
|
|
6631
|
-
|
|
7694
|
+
const submit = () => {
|
|
7695
|
+
const submitted = {
|
|
7696
|
+
...values,
|
|
7697
|
+
// A scope pick is bound to explicit file ids before anything is sent.
|
|
7698
|
+
inputs: workflow && !workflow.documentAction ? resolveScopeInputs(workflow, values.inputs, scopeSource) : values.inputs,
|
|
7699
|
+
assignee: "agent",
|
|
7700
|
+
notifyOnComplete: true,
|
|
7701
|
+
name: values.name.trim()
|
|
7702
|
+
};
|
|
7703
|
+
if (runOnce) onSubmit(submitted, { runOnce: true });
|
|
7704
|
+
else onSubmit(submitted);
|
|
7705
|
+
};
|
|
6632
7706
|
const pillLabels = { search: l.search, empty: l.empty };
|
|
6633
7707
|
const personOptions = (people ?? []).map((p) => ({
|
|
6634
7708
|
id: p.id,
|
|
@@ -6641,10 +7715,11 @@ function WorkflowComposer({
|
|
|
6641
7715
|
label: t.name,
|
|
6642
7716
|
icon: /* @__PURE__ */ jsx(CornerDownRight, { className: GLYPH2, "aria-hidden": true })
|
|
6643
7717
|
}));
|
|
6644
|
-
const whenOptions =
|
|
6645
|
-
id:
|
|
6646
|
-
label:
|
|
6647
|
-
|
|
7718
|
+
const whenOptions = [
|
|
7719
|
+
{ id: "manual", label: "Start now" },
|
|
7720
|
+
{ id: "schedule", label: "Schedule" },
|
|
7721
|
+
{ id: "event", label: "Notification" }
|
|
7722
|
+
];
|
|
6648
7723
|
const assistantOptions = agents.map((a) => ({ id: a.id, label: a.label }));
|
|
6649
7724
|
if (values.agentId && !assistantOptions.some((a) => a.id === values.agentId)) {
|
|
6650
7725
|
assistantOptions.push({ id: values.agentId, label: "Assigned agent" });
|
|
@@ -6652,18 +7727,42 @@ function WorkflowComposer({
|
|
|
6652
7727
|
const goalNode = typeof goal === "function" ? goal(values) : goal;
|
|
6653
7728
|
const pickedTemplate = workflows.find((w) => w.id === values.workflowId && !w.generic);
|
|
6654
7729
|
const hint = (key) => l[key];
|
|
6655
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
7730
|
+
return /* @__PURE__ */ jsx(Dialog, { modal: false, open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
6656
7731
|
DialogContent,
|
|
6657
7732
|
{
|
|
6658
|
-
presentation: "
|
|
6659
|
-
|
|
7733
|
+
presentation: "right",
|
|
7734
|
+
hideCloseButton: true,
|
|
7735
|
+
onInteractOutside: (event) => event.preventDefault(),
|
|
7736
|
+
className: "flex flex-col gap-0 overflow-hidden p-0 shadow-lg",
|
|
6660
7737
|
"data-testid": id,
|
|
6661
7738
|
children: [
|
|
6662
|
-
/* @__PURE__ */
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
7739
|
+
/* @__PURE__ */ jsx(DialogTitle, { className: "sr-only", children: "Automation settings" }),
|
|
7740
|
+
/* @__PURE__ */ jsx(DialogDescription, { className: "sr-only", children: l.descriptionWorkflow }),
|
|
7741
|
+
/* @__PURE__ */ jsx(
|
|
7742
|
+
TabHeader,
|
|
7743
|
+
{
|
|
7744
|
+
tabs: [
|
|
7745
|
+
{
|
|
7746
|
+
id: "automation-setup",
|
|
7747
|
+
label: isEdit ? l.titleEditWorkflow : pickedTemplate ? l.titleRunTemplate(pickedTemplate.title) : l.titleNewWorkflow,
|
|
7748
|
+
presentation: "count"
|
|
7749
|
+
},
|
|
7750
|
+
...(saveOnly || isEdit) && !workflow?.documentAction ? [{ id: "start-task", label: "Start task" }] : []
|
|
7751
|
+
],
|
|
7752
|
+
activeTabId: runOnce ? "start-task" : "automation-setup",
|
|
7753
|
+
onTabChange: (tab) => {
|
|
7754
|
+
if (tab === "start-task" && !runOnce) {
|
|
7755
|
+
setAutomationWhen(values.when);
|
|
7756
|
+
set("when", "now");
|
|
7757
|
+
setRunOnce(true);
|
|
7758
|
+
} else if (tab === "automation-setup" && runOnce) {
|
|
7759
|
+
set("when", automationWhen);
|
|
7760
|
+
setRunOnce(false);
|
|
7761
|
+
}
|
|
7762
|
+
},
|
|
7763
|
+
rightContent: /* @__PURE__ */ jsx(DialogClose, { asChild: true, children: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "icon", "aria-label": "Close", children: /* @__PURE__ */ jsx(X, { className: "size-4" }) }) })
|
|
7764
|
+
}
|
|
7765
|
+
),
|
|
6667
7766
|
/* @__PURE__ */ jsxs(
|
|
6668
7767
|
"form",
|
|
6669
7768
|
{
|
|
@@ -6753,7 +7852,7 @@ function WorkflowComposer({
|
|
|
6753
7852
|
goalNode
|
|
6754
7853
|
] })
|
|
6755
7854
|
] }),
|
|
6756
|
-
(scheduled || isEdit) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7855
|
+
!runOnce && (scheduled || isEdit) && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6757
7856
|
/* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-2", "data-testid": `${id}-when-section`, children: [
|
|
6758
7857
|
/* @__PURE__ */ jsx("h3", { className: "text-sm font-medium", children: l.whenHeading }),
|
|
6759
7858
|
/* @__PURE__ */ jsx(
|
|
@@ -6761,14 +7860,30 @@ function WorkflowComposer({
|
|
|
6761
7860
|
{
|
|
6762
7861
|
icon: /* @__PURE__ */ jsx(Play, { className: GLYPH2, "aria-hidden": true }),
|
|
6763
7862
|
prefix: l.start,
|
|
6764
|
-
value: values.when,
|
|
7863
|
+
value: values.when === "once" || values.when === "repeat" ? "schedule" : values.when === "task" ? "event" : values.when === "now" ? "manual" : values.when,
|
|
6765
7864
|
options: whenOptions,
|
|
6766
|
-
onChange: (v) => pickWhen(v),
|
|
7865
|
+
onChange: (v) => pickWhen(v === "schedule" ? "once" : v),
|
|
6767
7866
|
labels: pillLabels,
|
|
6768
7867
|
testId: `${id}-when`,
|
|
6769
7868
|
className: "self-start"
|
|
6770
7869
|
}
|
|
6771
7870
|
),
|
|
7871
|
+
(values.when === "once" || values.when === "repeat") && /* @__PURE__ */ jsx(
|
|
7872
|
+
PillSelect,
|
|
7873
|
+
{
|
|
7874
|
+
icon: /* @__PURE__ */ jsx(Play, { className: GLYPH2, "aria-hidden": true }),
|
|
7875
|
+
prefix: "Schedule",
|
|
7876
|
+
value: values.when,
|
|
7877
|
+
options: [
|
|
7878
|
+
{ id: "once", label: "Once" },
|
|
7879
|
+
{ id: "repeat", label: "Repeat" }
|
|
7880
|
+
],
|
|
7881
|
+
onChange: (value) => pickWhen(value),
|
|
7882
|
+
labels: pillLabels,
|
|
7883
|
+
testId: `${id}-schedule-mode`,
|
|
7884
|
+
className: "self-start"
|
|
7885
|
+
}
|
|
7886
|
+
),
|
|
6772
7887
|
values.when === "once" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
6773
7888
|
/* @__PURE__ */ jsx(Label, { htmlFor: "task-composer-runat", className: "sr-only", children: l.runAt }),
|
|
6774
7889
|
/* @__PURE__ */ jsx(
|
|
@@ -6812,7 +7927,25 @@ function WorkflowComposer({
|
|
|
6812
7927
|
] }),
|
|
6813
7928
|
values.when === "event" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
6814
7929
|
/* @__PURE__ */ jsx(Label, { htmlFor: "task-composer-event", className: "sr-only", children: l.event }),
|
|
6815
|
-
/* @__PURE__ */ jsx(
|
|
7930
|
+
eventOptions ? /* @__PURE__ */ jsx(
|
|
7931
|
+
PillSelect,
|
|
7932
|
+
{
|
|
7933
|
+
icon: /* @__PURE__ */ jsx(Zap, { className: GLYPH2, "aria-hidden": true }),
|
|
7934
|
+
prefix: l.event,
|
|
7935
|
+
value: values.eventKind,
|
|
7936
|
+
options: eventOptions.some((option) => option.id === values.eventKind) || !values.eventKind ? [...eventOptions] : [
|
|
7937
|
+
...eventOptions,
|
|
7938
|
+
{
|
|
7939
|
+
id: values.eventKind,
|
|
7940
|
+
label: values.eventKind.replaceAll("_", " ")
|
|
7941
|
+
}
|
|
7942
|
+
],
|
|
7943
|
+
onChange: (event) => set("eventKind", event),
|
|
7944
|
+
labels: pillLabels,
|
|
7945
|
+
testId: `${id}-event`,
|
|
7946
|
+
className: "self-start"
|
|
7947
|
+
}
|
|
7948
|
+
) : /* @__PURE__ */ jsx(
|
|
6816
7949
|
Input,
|
|
6817
7950
|
{
|
|
6818
7951
|
id: "task-composer-event",
|
|
@@ -6825,6 +7958,22 @@ function WorkflowComposer({
|
|
|
6825
7958
|
),
|
|
6826
7959
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: l.eventHint })
|
|
6827
7960
|
] }),
|
|
7961
|
+
values.when === "event" && values.eventKind === "workflow_completed" && eventWorkflowOptions && /* @__PURE__ */ jsx(
|
|
7962
|
+
PillSelect,
|
|
7963
|
+
{
|
|
7964
|
+
icon: /* @__PURE__ */ jsx(Zap, { className: GLYPH2, "aria-hidden": true }),
|
|
7965
|
+
prefix: "Automation",
|
|
7966
|
+
value: typeof values.eventFilter?.workflow_ext_id === "string" ? values.eventFilter.workflow_ext_id : "",
|
|
7967
|
+
options: [{ id: "", label: "Any automation" }, ...eventWorkflowOptions],
|
|
7968
|
+
onChange: (id2) => set(
|
|
7969
|
+
"eventFilter",
|
|
7970
|
+
id2 ? { ...values.eventFilter, workflow_ext_id: id2 } : null
|
|
7971
|
+
),
|
|
7972
|
+
labels: pillLabels,
|
|
7973
|
+
testId: `${id}-event-workflow`,
|
|
7974
|
+
className: "self-start"
|
|
7975
|
+
}
|
|
7976
|
+
),
|
|
6828
7977
|
values.when === "task" && /* @__PURE__ */ jsx(
|
|
6829
7978
|
PillSelect,
|
|
6830
7979
|
{
|
|
@@ -7019,7 +8168,7 @@ function WorkflowComposer({
|
|
|
7019
8168
|
children: l.cancel
|
|
7020
8169
|
}
|
|
7021
8170
|
),
|
|
7022
|
-
!isEdit && /* @__PURE__ */ jsx(
|
|
8171
|
+
!isEdit && !saveOnly && !hideRunLater && /* @__PURE__ */ jsx(
|
|
7023
8172
|
Button,
|
|
7024
8173
|
{
|
|
7025
8174
|
type: "button",
|
|
@@ -7039,7 +8188,7 @@ function WorkflowComposer({
|
|
|
7039
8188
|
className: "gap-1.5 pointer-coarse:min-h-11",
|
|
7040
8189
|
children: [
|
|
7041
8190
|
isPending && /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
|
|
7042
|
-
isPending ? l.saving : isEdit ? l.save : scheduled ? l.saveWorkflow : l.runNow
|
|
8191
|
+
isPending ? l.saving : runOnce ? "Start now" : isEdit ? l.save : saveOnly || scheduled ? l.saveWorkflow : l.runNow
|
|
7043
8192
|
]
|
|
7044
8193
|
}
|
|
7045
8194
|
)
|
|
@@ -7051,7 +8200,7 @@ function WorkflowComposer({
|
|
|
7051
8200
|
}
|
|
7052
8201
|
) });
|
|
7053
8202
|
}
|
|
7054
|
-
var
|
|
8203
|
+
var WHEN_ORDER = ["now", "once", "repeat", "event", "task"];
|
|
7055
8204
|
function formatDue2(local) {
|
|
7056
8205
|
const d = new Date(local);
|
|
7057
8206
|
if (Number.isNaN(d.getTime())) return local;
|
|
@@ -7154,7 +8303,7 @@ function WorkTaskComposer({
|
|
|
7154
8303
|
label: t.name,
|
|
7155
8304
|
icon: /* @__PURE__ */ jsx(CornerDownRight, { className: GLYPH3, "aria-hidden": true })
|
|
7156
8305
|
}));
|
|
7157
|
-
const whenOptions =
|
|
8306
|
+
const whenOptions = WHEN_ORDER.map((mode) => ({
|
|
7158
8307
|
id: mode,
|
|
7159
8308
|
label: l.whenOptions[mode]
|
|
7160
8309
|
}));
|
|
@@ -7163,8 +8312,8 @@ function WorkTaskComposer({
|
|
|
7163
8312
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(
|
|
7164
8313
|
DialogContent,
|
|
7165
8314
|
{
|
|
7166
|
-
presentation: "
|
|
7167
|
-
className: "flex
|
|
8315
|
+
presentation: "right",
|
|
8316
|
+
className: "flex flex-col overflow-hidden p-0",
|
|
7168
8317
|
"data-testid": id,
|
|
7169
8318
|
children: [
|
|
7170
8319
|
/* @__PURE__ */ jsxs(ModalHeader, { children: [
|
|
@@ -7266,6 +8415,7 @@ function WorkTaskComposer({
|
|
|
7266
8415
|
items: { shared: values.shared },
|
|
7267
8416
|
onToggle: (share) => set("shared", share),
|
|
7268
8417
|
label: l.visibility,
|
|
8418
|
+
presentation: "select",
|
|
7269
8419
|
"data-testid": `${id}-visibility`
|
|
7270
8420
|
}
|
|
7271
8421
|
)
|
|
@@ -7519,6 +8669,210 @@ function WorkTaskComposer({
|
|
|
7519
8669
|
function TaskComposer(props) {
|
|
7520
8670
|
return props.kind === "workflow" ? /* @__PURE__ */ jsx(WorkflowComposer, { ...props }) : /* @__PURE__ */ jsx(WorkTaskComposer, { ...props });
|
|
7521
8671
|
}
|
|
8672
|
+
function TaskReviewDialog(p) {
|
|
8673
|
+
const [action, setAction] = useState("forward");
|
|
8674
|
+
const [userId, setUserId] = useState("");
|
|
8675
|
+
const [note, setNote] = useState("");
|
|
8676
|
+
useEffect(() => {
|
|
8677
|
+
if (p.open) {
|
|
8678
|
+
setAction(p.people.length ? "forward" : p.canApprove ? "finish" : "revise");
|
|
8679
|
+
setUserId("");
|
|
8680
|
+
setNote("");
|
|
8681
|
+
}
|
|
8682
|
+
}, [p.open]);
|
|
8683
|
+
const valid = action === "forward" ? p.people.some((person) => person.id === userId) : action === "revise" ? p.canRevise && Boolean(note.trim()) : p.canApprove;
|
|
8684
|
+
return /* @__PURE__ */ jsx(Dialog, { open: p.open, onOpenChange: (next) => !p.isPending && p.onOpenChange(next), children: /* @__PURE__ */ jsxs(DialogContent, { "data-testid": "task-review-dialog", className: "sm:max-w-lg", children: [
|
|
8685
|
+
/* @__PURE__ */ jsxs(DialogTitle, { children: [
|
|
8686
|
+
"Review: ",
|
|
8687
|
+
p.taskName
|
|
8688
|
+
] }),
|
|
8689
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: p.canApprove ? "Approve your review and send it on, request changes, or finish the task." : "Choose who should review this work next, or ask ARBI for changes." }),
|
|
8690
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4 py-2", children: [
|
|
8691
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8692
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "review-next-step", children: "Next step" }),
|
|
8693
|
+
/* @__PURE__ */ jsxs(
|
|
8694
|
+
Select,
|
|
8695
|
+
{
|
|
8696
|
+
value: action,
|
|
8697
|
+
onValueChange: (value) => setAction(value),
|
|
8698
|
+
disabled: p.isPending,
|
|
8699
|
+
children: [
|
|
8700
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id: "review-next-step", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
8701
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
8702
|
+
p.people.length > 0 && /* @__PURE__ */ jsx(SelectItem, { value: "forward", children: p.canApprove ? "Approve and send for review" : "Send for review" }),
|
|
8703
|
+
p.canRevise && /* @__PURE__ */ jsx(SelectItem, { value: "revise", children: "Ask ARBI for changes" }),
|
|
8704
|
+
p.canApprove && /* @__PURE__ */ jsx(SelectItem, { value: "finish", children: "Approve and finish task" })
|
|
8705
|
+
] })
|
|
8706
|
+
]
|
|
8707
|
+
}
|
|
8708
|
+
)
|
|
8709
|
+
] }),
|
|
8710
|
+
action === "forward" && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8711
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "review-recipient", children: "Next reviewer" }),
|
|
8712
|
+
/* @__PURE__ */ jsxs(Select, { value: userId, onValueChange: setUserId, disabled: p.isPending, children: [
|
|
8713
|
+
/* @__PURE__ */ jsx(SelectTrigger, { id: "review-recipient", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Choose a person" }) }),
|
|
8714
|
+
/* @__PURE__ */ jsx(SelectContent, { children: p.people.map((person) => /* @__PURE__ */ jsx(SelectItem, { value: person.id, children: person.label }, person.id)) })
|
|
8715
|
+
] })
|
|
8716
|
+
] }),
|
|
8717
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8718
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "review-note", children: action === "revise" ? "What should ARBI change?" : "Review note (optional)" }),
|
|
8719
|
+
/* @__PURE__ */ jsx(
|
|
8720
|
+
Textarea,
|
|
8721
|
+
{
|
|
8722
|
+
id: "review-note",
|
|
8723
|
+
value: note,
|
|
8724
|
+
onChange: (e) => setNote(e.target.value),
|
|
8725
|
+
disabled: p.isPending,
|
|
8726
|
+
placeholder: action === "revise" ? "Explain what needs changing in the same draft\u2026" : "Explain what you checked and what the next reviewer should focus on\u2026"
|
|
8727
|
+
}
|
|
8728
|
+
)
|
|
8729
|
+
] }),
|
|
8730
|
+
p.error && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-destructive", children: p.error })
|
|
8731
|
+
] }),
|
|
8732
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
8733
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => p.onOpenChange(false), disabled: p.isPending, children: "Cancel" }),
|
|
8734
|
+
/* @__PURE__ */ jsx(
|
|
8735
|
+
Button,
|
|
8736
|
+
{
|
|
8737
|
+
"data-testid": "task-review-submit",
|
|
8738
|
+
disabled: !valid || p.isPending,
|
|
8739
|
+
onClick: () => p.onSubmit({
|
|
8740
|
+
action,
|
|
8741
|
+
userId,
|
|
8742
|
+
note: note.trim(),
|
|
8743
|
+
approveCurrent: p.canApprove && action === "forward"
|
|
8744
|
+
}),
|
|
8745
|
+
children: p.isPending ? "Saving\u2026" : action === "forward" ? p.canApprove ? "Approve and send" : "Send for review" : action === "revise" ? "Send to ARBI" : "Finish task"
|
|
8746
|
+
}
|
|
8747
|
+
)
|
|
8748
|
+
] })
|
|
8749
|
+
] }) });
|
|
8750
|
+
}
|
|
8751
|
+
function ThreadNotifyDialog({
|
|
8752
|
+
open,
|
|
8753
|
+
onOpenChange,
|
|
8754
|
+
people,
|
|
8755
|
+
isShared,
|
|
8756
|
+
onNotify
|
|
8757
|
+
}) {
|
|
8758
|
+
const [selected, setSelected] = useState([]);
|
|
8759
|
+
const [query, setQuery] = useState("");
|
|
8760
|
+
const [busy, setBusy] = useState(false);
|
|
8761
|
+
const [error, setError] = useState(null);
|
|
8762
|
+
useEffect(() => {
|
|
8763
|
+
if (open) {
|
|
8764
|
+
setSelected([]);
|
|
8765
|
+
setQuery("");
|
|
8766
|
+
setError(null);
|
|
8767
|
+
}
|
|
8768
|
+
}, [open]);
|
|
8769
|
+
return /* @__PURE__ */ jsx(
|
|
8770
|
+
Dialog,
|
|
8771
|
+
{
|
|
8772
|
+
open,
|
|
8773
|
+
onOpenChange: (value) => {
|
|
8774
|
+
if (!busy) onOpenChange(value);
|
|
8775
|
+
},
|
|
8776
|
+
children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-sm", "data-testid": "thread-notify-dialog", children: [
|
|
8777
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Notify" }),
|
|
8778
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: isShared ? "Ask someone to follow up in this thread." : "Notifying someone shares this thread with your workspace." }),
|
|
8779
|
+
/* @__PURE__ */ jsx(
|
|
8780
|
+
Input,
|
|
8781
|
+
{
|
|
8782
|
+
"aria-label": "Find people",
|
|
8783
|
+
placeholder: "Find someone\u2026",
|
|
8784
|
+
value: query,
|
|
8785
|
+
onChange: (event) => setQuery(event.target.value)
|
|
8786
|
+
}
|
|
8787
|
+
),
|
|
8788
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-64 overflow-y-auto space-y-1", children: [
|
|
8789
|
+
people.filter((person) => person.label.toLowerCase().includes(query.toLowerCase())).map((person) => /* @__PURE__ */ jsxs(
|
|
8790
|
+
"label",
|
|
8791
|
+
{
|
|
8792
|
+
className: "flex cursor-pointer items-center gap-2 rounded px-2 py-2 hover:bg-muted",
|
|
8793
|
+
children: [
|
|
8794
|
+
/* @__PURE__ */ jsx(
|
|
8795
|
+
Checkbox,
|
|
8796
|
+
{
|
|
8797
|
+
disabled: busy,
|
|
8798
|
+
checked: selected.includes(person.id),
|
|
8799
|
+
onCheckedChange: (checked) => setSelected(
|
|
8800
|
+
(old) => checked ? [...old, person.id] : old.filter((id) => id !== person.id)
|
|
8801
|
+
)
|
|
8802
|
+
}
|
|
8803
|
+
),
|
|
8804
|
+
person.label
|
|
8805
|
+
]
|
|
8806
|
+
},
|
|
8807
|
+
person.id
|
|
8808
|
+
)),
|
|
8809
|
+
!people.length && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "No other workspace members yet." })
|
|
8810
|
+
] }),
|
|
8811
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "text-sm text-destructive", children: error }),
|
|
8812
|
+
/* @__PURE__ */ jsx(
|
|
8813
|
+
Button,
|
|
8814
|
+
{
|
|
8815
|
+
disabled: busy || !selected.length,
|
|
8816
|
+
"data-testid": "thread-notify-submit",
|
|
8817
|
+
onClick: async () => {
|
|
8818
|
+
setBusy(true);
|
|
8819
|
+
setError(null);
|
|
8820
|
+
try {
|
|
8821
|
+
await onNotify(selected);
|
|
8822
|
+
onOpenChange(false);
|
|
8823
|
+
} catch (failure) {
|
|
8824
|
+
setError(failure instanceof Error ? failure.message : "Could not notify people");
|
|
8825
|
+
} finally {
|
|
8826
|
+
setBusy(false);
|
|
8827
|
+
}
|
|
8828
|
+
},
|
|
8829
|
+
children: busy ? "Notifying\u2026" : "Notify"
|
|
8830
|
+
}
|
|
8831
|
+
)
|
|
8832
|
+
] })
|
|
8833
|
+
}
|
|
8834
|
+
);
|
|
8835
|
+
}
|
|
8836
|
+
function ConversationTurnSpeaker({
|
|
8837
|
+
role,
|
|
8838
|
+
actor,
|
|
8839
|
+
currentUserId,
|
|
8840
|
+
colorClass,
|
|
8841
|
+
platformName = "ARBI",
|
|
8842
|
+
platformLogoSrc = "/favicon.svg"
|
|
8843
|
+
}) {
|
|
8844
|
+
if (!role) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
|
|
8845
|
+
if (role === "assistant" && !actor)
|
|
8846
|
+
return /* @__PURE__ */ jsx(
|
|
8847
|
+
UserEntity,
|
|
8848
|
+
{
|
|
8849
|
+
size: "sm",
|
|
8850
|
+
variant: "pill",
|
|
8851
|
+
interactive: false,
|
|
8852
|
+
picture: platformLogoSrc,
|
|
8853
|
+
avatarImageClassName: "object-contain p-0.5",
|
|
8854
|
+
initials: platformName.charAt(0),
|
|
8855
|
+
displayName: platformName
|
|
8856
|
+
}
|
|
8857
|
+
);
|
|
8858
|
+
if (!actor) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "Unknown participant" });
|
|
8859
|
+
const isMe = actor.external_id === currentUserId;
|
|
8860
|
+
const displayName = isMe ? "You" : [actor.given_name, actor.family_name].filter(Boolean).join(" ");
|
|
8861
|
+
return /* @__PURE__ */ jsx(
|
|
8862
|
+
UserEntity,
|
|
8863
|
+
{
|
|
8864
|
+
size: "sm",
|
|
8865
|
+
variant: "pill",
|
|
8866
|
+
interactive: false,
|
|
8867
|
+
isMe,
|
|
8868
|
+
isAgent: actor.external_id.startsWith("agt-"),
|
|
8869
|
+
displayName,
|
|
8870
|
+
initials: `${actor.given_name.charAt(0)}${actor.family_name?.charAt(0) ?? ""}`.toUpperCase(),
|
|
8871
|
+
picture: actor.picture,
|
|
8872
|
+
colorClass
|
|
8873
|
+
}
|
|
8874
|
+
);
|
|
8875
|
+
}
|
|
7522
8876
|
var DEFAULT_TUPLE_ARRAY_FIELD_LABELS = {
|
|
7523
8877
|
addRow: "Add Row",
|
|
7524
8878
|
empty: 'No examples added yet. Click "Add Row" to start.',
|
|
@@ -9175,6 +10529,6 @@ function AgentCreateView({
|
|
|
9175
10529
|
] });
|
|
9176
10530
|
}
|
|
9177
10531
|
|
|
9178
|
-
export { AgentAvatarField, AgentBar, AgentBarIconButton, AgentBarMenu, AgentBarNotes, AgentBarProbeAnswer, AgentBarQueuedNote, AgentBarStatus, AgentCard, AgentCreateView, AgentCreatedView, AgentCreator, AgentEditView, AgentGallery, AgentMainView, AgentSelect, AgentTypeSelector, CapabilityGrid, CapabilityTile, ConfigField, ConfigForm, ConsentActions, ConsentBulletList, ConsentCard, ConsentFootnote, ConsentHeader, ConsentMessage, ConsentNotice, ConsentPage, ConsentPermissionList, ConsentSection, ConsentStrong, ConsentText, CopyableUrl, DEFAULT_AGENT_AVATAR_FIELD_LABELS, DEFAULT_AGENT_BAR_LABELS, DEFAULT_AGENT_CARD_LABELS, DEFAULT_AGENT_CREATOR_LABELS, DEFAULT_AGENT_GALLERY_LABELS, DEFAULT_AGENT_SELECT_LABELS, DEFAULT_AGENT_STEPS_LABELS, DEFAULT_AGENT_TYPE_SELECTOR_LABELS, DEFAULT_AUTHORIZE_AGENT_LABELS, DEFAULT_CONFIG_FIELD_LABELS, DEFAULT_CONFIG_FORM_LABELS, DEFAULT_CONSENT_ACTIONS_LABELS, DEFAULT_COPYABLE_URL_LABELS, DEFAULT_NEW_THREAD_DIALOG_LABELS, DEFAULT_PILL_SELECT_LABELS, DEFAULT_RECURRENCE, DEFAULT_RECURRENCE_BUILDER_LABELS, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_SKILL_CARD_LABELS, DEFAULT_SKILL_EDIT_FORM_LABELS, DEFAULT_SKILL_GENERATE_FORM_LABELS, DEFAULT_SKILL_GLOBAL_BADGE_LABELS, DEFAULT_SKILL_ROW_LABELS, DEFAULT_SKILL_VIEW_TOGGLE_LABELS, DEFAULT_SUBAGENT_ROSTER_LABELS, DEFAULT_TASKS_CHROME_LABELS, DEFAULT_TASK_ACTIVITY_LABELS, DEFAULT_TASK_COMPOSER_LABELS, DEFAULT_TASK_LIST_LABELS, DEFAULT_TASK_OUTPUTS_CELL_LABELS, DEFAULT_TASK_PLAN_LABELS, DEFAULT_TASK_REVIEW_ACTIONS_LABELS, DEFAULT_TASK_RUNS_DIALOG_LABELS, DEFAULT_TASK_STATUS_PILL_LABELS, DEFAULT_TASK_THREAD_CHIP_LABELS, DEFAULT_TASK_TRIGGER_CHIP_LABELS, DEFAULT_TUPLE_ARRAY_FIELD_LABELS, DEFAULT_UPLOAD_TASK_ITEM_LABELS, DEFAULT_UPLOAD_TASK_LIST_LABELS, DEFAULT_WORKFLOWS_CHROME_LABELS, DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS, DEFAULT_WORKFLOW_LIST_LABELS, DERIVED_NAME_WORDS, EMPTY_NEW_THREAD, EMPTY_WORKFLOW_SCOPE, GoalCriteria, MAX_TASK_DEPTH, NewThreadDialog, PersonPill, PillSelect, RecurrenceBuilder, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, STATUS_LABELS, STATUS_ORDER, STATUS_TONE, SchemaForm, SkillActionButton, SkillCard, SkillDetail, SkillDetailSection, SkillEditForm, SkillFilterChips, SkillGenerateForm, SkillGlobalBadge, SkillRow, SkillTile, SkillTypeBadge, SkillViewToggle, StepDetail, StepNarration, StepOutcome, StepParams, StepRow, StepSummary, StepTrace, StepTraceSummary, SubAgentLane, SubStepGroup, SubagentRoster, TASK_COLUMN_ORDER, TRIGGER_LABELS, TaskActivityDialog, TaskActivityTimeline, TaskComposer, TaskMoveDialog, TaskOutputsCell, TaskPlan, TaskReviewActions, TaskRunsDialog, TaskStatusPill, TaskTable, TaskThreadChip, TaskTriggerChip, TasksToolbar, TupleArrayField, UploadTaskItem, UploadTaskList, WEEKDAYS, WORKFLOW_COLUMN_ORDER, WorkflowConfigDialog, WorkflowDocumentsField, WorkflowLauncher, WorkflowsTable, WorkflowsToolbar, agentConfigSectionToValues, agentCreatorToConfigSection, asTaskStatus, authModeFor, buildLaunch, buildRRule, buildTaskRows, buildWorkflowScopeSource, composePersona, composeWorkflowPrompt, composerToTaskQuery, composerToWorkRequest, composerToWorkflowRequest, composerToWorkflowUpdate, createTaskColumns, createWorkflowColumns, createsWork, defaultInputs, defaultScopeRenderer, defaultTaskComposerValues, deriveAgentName, deriveWorkflowName, descendantIds, describeRRule, firstWords, formatElapsed, goalProgress, hasTaskFields, hasTrigger, humanizeSection, indexTasks, inferType, inputDocumentIds, inputsFromContext, isAgenticWorkflow, isEmptyWorkflowScope, isOutOfBounds, isPlainTodo, isSkillRow, isValidAgentName, isWorkflowScope, isoToLocalInput, localInputToIso, matchWorkflowScope, moveTargets, newThreadToRequest, nextCriterionId, ownerExtId, parseRRule, prettifyKey, promptFieldName, resolveScopeInputs, skillToWorkflow, stripPersonaPreamble, summarizeAgent, summarizeCapabilities, taskComposerToCreateRequest, taskComposerToUpdateRequest, taskNeedsAccess, taskToComposerValues, validateInputs, workflowAccepts, workflowFromFrontmatter, workflowStatus, workflowTaskFields, workflowToComposerValues, workflowTriggerType, workflowWhen, workflowsAccepting, workflowsForHost };
|
|
9179
|
-
//# sourceMappingURL=chunk-
|
|
9180
|
-
//# sourceMappingURL=chunk-
|
|
10532
|
+
export { AgentAvatarField, AgentBar, AgentBarIconButton, AgentBarMenu, AgentBarNotes, AgentBarProbeAnswer, AgentBarQueuedNote, AgentBarStatus, AgentCard, AgentCreateView, AgentCreatedView, AgentCreator, AgentEditView, AgentGallery, AgentMainView, AgentSelect, AgentTypeSelector, CapabilityGrid, CapabilityTile, ConfigField, ConfigForm, ConsentActions, ConsentBulletList, ConsentCard, ConsentFootnote, ConsentHeader, ConsentMessage, ConsentNotice, ConsentPage, ConsentPermissionList, ConsentSection, ConsentStrong, ConsentText, ConversationListView, ConversationTurnSpeaker, CopyableUrl, DEFAULT_AGENT_AVATAR_FIELD_LABELS, DEFAULT_AGENT_BAR_LABELS, DEFAULT_AGENT_CARD_LABELS, DEFAULT_AGENT_CREATOR_LABELS, DEFAULT_AGENT_GALLERY_LABELS, DEFAULT_AGENT_SELECT_LABELS, DEFAULT_AGENT_STEPS_LABELS, DEFAULT_AGENT_TYPE_SELECTOR_LABELS, DEFAULT_AUTHORIZE_AGENT_LABELS, DEFAULT_CONFIG_FIELD_LABELS, DEFAULT_CONFIG_FORM_LABELS, DEFAULT_CONSENT_ACTIONS_LABELS, DEFAULT_COPYABLE_URL_LABELS, DEFAULT_NEW_THREAD_DIALOG_LABELS, DEFAULT_PILL_SELECT_LABELS, DEFAULT_RECURRENCE, DEFAULT_RECURRENCE_BUILDER_LABELS, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_SKILL_CARD_LABELS, DEFAULT_SKILL_EDIT_FORM_LABELS, DEFAULT_SKILL_GENERATE_FORM_LABELS, DEFAULT_SKILL_GLOBAL_BADGE_LABELS, DEFAULT_SKILL_ROW_LABELS, DEFAULT_SKILL_VIEW_TOGGLE_LABELS, DEFAULT_SUBAGENT_ROSTER_LABELS, DEFAULT_TASKS_CHROME_LABELS, DEFAULT_TASK_ACTIVITY_LABELS, DEFAULT_TASK_COMPOSER_LABELS, DEFAULT_TASK_LIST_LABELS, DEFAULT_TASK_OUTPUTS_CELL_LABELS, DEFAULT_TASK_PLAN_LABELS, DEFAULT_TASK_REVIEW_ACTIONS_LABELS, DEFAULT_TASK_RUNS_DIALOG_LABELS, DEFAULT_TASK_STATUS_PILL_LABELS, DEFAULT_TASK_THREAD_CHIP_LABELS, DEFAULT_TASK_TRIGGER_CHIP_LABELS, DEFAULT_TUPLE_ARRAY_FIELD_LABELS, DEFAULT_UPLOAD_TASK_ITEM_LABELS, DEFAULT_UPLOAD_TASK_LIST_LABELS, DEFAULT_WORKFLOWS_CHROME_LABELS, DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS, DEFAULT_WORKFLOW_LIST_LABELS, DERIVED_NAME_WORDS, EMPTY_NEW_THREAD, EMPTY_WORKFLOW_SCOPE, EntityChip, GoalCriteria, MAX_TASK_DEPTH, NewThreadDialog, PersonPill, PillSelect, RecurrenceBuilder, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, STATUS_LABELS, STATUS_ORDER, STATUS_TONE, SchemaForm, SkillActionButton, SkillCard, SkillDetail, SkillDetailSection, SkillEditForm, SkillFilterChips, SkillGenerateForm, SkillGlobalBadge, SkillRow, SkillTile, SkillTypeBadge, SkillViewToggle, StepDetail, StepNarration, StepOutcome, StepParams, StepRow, StepSummary, StepTrace, StepTraceSummary, SubAgentLane, SubStepGroup, SubagentRoster, TASK_COLUMN_ORDER, TRIGGER_LABELS, TaskActivityDialog, TaskActivityTimeline, TaskComposer, TaskFlow, TaskInbox, TaskMoveDialog, TaskOutputsCell, TaskPlan, TaskReviewActions, TaskReviewDialog, TaskRunsDialog, TaskStartDialog, TaskStatusPill, TaskTable, TaskThreadChip, TaskTriggerChip, TasksToolbar, ThreadActivity, ThreadNotifyDialog, TupleArrayField, UploadTaskItem, UploadTaskList, WEEKDAYS, WORKFLOW_COLUMN_ORDER, WorkflowConfigDialog, WorkflowDocumentsField, WorkflowLauncher, WorkflowsTable, WorkflowsToolbar, agentConfigSectionToValues, agentCreatorToConfigSection, asTaskStatus, authModeFor, buildLaunch, buildRRule, buildTaskRows, buildWorkflowScopeSource, compactThreadActivity, composePersona, composeWorkflowPrompt, composerToTaskQuery, composerToWorkRequest, composerToWorkflowRequest, composerToWorkflowUpdate, createTaskColumns, createWorkflowColumns, createsWork, defaultInputs, defaultScopeRenderer, defaultTaskComposerValues, deriveAgentName, deriveWorkflowName, descendantIds, describeRRule, filterConversationRows, firstWords, formatElapsed, goalProgress, hasTaskFields, hasTrigger, humanizeSection, indexTasks, inferType, inputDocumentIds, inputsFromContext, isAgenticWorkflow, isEmptyWorkflowScope, isOutOfBounds, isPlainTodo, isSkillRow, isValidAgentName, isWorkflowScope, isoToLocalInput, localInputToIso, matchWorkflowScope, moveTargets, newThreadToRequest, nextCriterionId, ownerExtId, parseRRule, prettifyKey, promptFieldName, resolveScopeInputs, skillToWorkflow, stripPersonaPreamble, summarizeAgent, summarizeCapabilities, taskComposerToCreateRequest, taskComposerToUpdateRequest, taskNeedsAccess, taskToComposerValues, validateInputs, workflowAccepts, workflowFromFrontmatter, workflowStatus, workflowTaskFields, workflowToComposerValues, workflowTriggerType, workflowWhen, workflowsAccepting, workflowsForHost };
|
|
10533
|
+
//# sourceMappingURL=chunk-6RXUMBTK.js.map
|
|
10534
|
+
//# sourceMappingURL=chunk-6RXUMBTK.js.map
|