@invana/ui 0.0.24 → 0.0.26
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/index.cjs +410 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +247 -2
- package/dist/index.d.ts +247 -2
- package/dist/index.js +407 -12
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3984,6 +3984,56 @@ var CitationRow = React23__namespace.forwardRef(
|
|
|
3984
3984
|
)
|
|
3985
3985
|
);
|
|
3986
3986
|
CitationRow.displayName = "CitationRow";
|
|
3987
|
+
var ClampedText = React23__namespace.forwardRef(
|
|
3988
|
+
({
|
|
3989
|
+
lines = 3,
|
|
3990
|
+
moreLabel = "Show more",
|
|
3991
|
+
lessLabel = "Show less",
|
|
3992
|
+
className,
|
|
3993
|
+
children,
|
|
3994
|
+
...props
|
|
3995
|
+
}, ref) => {
|
|
3996
|
+
const [expanded, setExpanded] = React23__namespace.useState(false);
|
|
3997
|
+
const [clipped, setClipped] = React23__namespace.useState(false);
|
|
3998
|
+
const bodyRef = React23__namespace.useRef(null);
|
|
3999
|
+
React23__namespace.useLayoutEffect(() => {
|
|
4000
|
+
const el = bodyRef.current;
|
|
4001
|
+
if (!el || expanded) return;
|
|
4002
|
+
const measure = () => setClipped(el.scrollHeight - el.clientHeight > 1);
|
|
4003
|
+
measure();
|
|
4004
|
+
const observer = new ResizeObserver(measure);
|
|
4005
|
+
observer.observe(el);
|
|
4006
|
+
return () => observer.disconnect();
|
|
4007
|
+
}, [expanded, children, lines]);
|
|
4008
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("min-w-0", className), ...props, children: [
|
|
4009
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4010
|
+
"p",
|
|
4011
|
+
{
|
|
4012
|
+
ref: bodyRef,
|
|
4013
|
+
className: cn(
|
|
4014
|
+
"whitespace-pre-line",
|
|
4015
|
+
!expanded && "overflow-hidden [-webkit-box-orient:vertical] [-webkit-line-clamp:var(--clamped-lines)] [display:-webkit-box]"
|
|
4016
|
+
),
|
|
4017
|
+
style: { "--clamped-lines": lines },
|
|
4018
|
+
children
|
|
4019
|
+
}
|
|
4020
|
+
),
|
|
4021
|
+
clipped ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4022
|
+
Button,
|
|
4023
|
+
{
|
|
4024
|
+
type: "button",
|
|
4025
|
+
variant: "link",
|
|
4026
|
+
size: "sm",
|
|
4027
|
+
className: "h-auto p-0",
|
|
4028
|
+
"aria-expanded": expanded,
|
|
4029
|
+
onClick: () => setExpanded((open) => !open),
|
|
4030
|
+
children: expanded ? lessLabel : moreLabel
|
|
4031
|
+
}
|
|
4032
|
+
) : null
|
|
4033
|
+
] });
|
|
4034
|
+
}
|
|
4035
|
+
);
|
|
4036
|
+
ClampedText.displayName = "ClampedText";
|
|
3987
4037
|
var ClarifyCard = React23__namespace.forwardRef(
|
|
3988
4038
|
({
|
|
3989
4039
|
step,
|
|
@@ -4669,6 +4719,8 @@ function PanelContent({
|
|
|
4669
4719
|
}
|
|
4670
4720
|
function PanelStack({
|
|
4671
4721
|
sections,
|
|
4722
|
+
stackRef,
|
|
4723
|
+
onCollapsedChange,
|
|
4672
4724
|
headerHeight = 35,
|
|
4673
4725
|
withHandle = false,
|
|
4674
4726
|
className,
|
|
@@ -4713,19 +4765,26 @@ function PanelStack({
|
|
|
4713
4765
|
for (const s of targets) refs.current[s.id]?.collapse();
|
|
4714
4766
|
group.setLayout(next);
|
|
4715
4767
|
}, []);
|
|
4716
|
-
const
|
|
4768
|
+
const notify = React23__namespace.useRef(onCollapsedChange);
|
|
4769
|
+
React23__namespace.useEffect(() => {
|
|
4770
|
+
notify.current = onCollapsedChange;
|
|
4771
|
+
}, [onCollapsedChange]);
|
|
4772
|
+
const collapsedRef = React23__namespace.useRef(collapsed);
|
|
4773
|
+
collapsedRef.current = collapsed;
|
|
4774
|
+
const collapsePanel = React23__namespace.useCallback((id) => {
|
|
4717
4775
|
const ref = refs.current[id];
|
|
4718
|
-
if (!ref) return;
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4776
|
+
if (!ref || ref.isCollapsed()) return;
|
|
4777
|
+
ref.collapse();
|
|
4778
|
+
}, []);
|
|
4779
|
+
const expandPanel = React23__namespace.useCallback((id) => {
|
|
4780
|
+
const ref = refs.current[id];
|
|
4781
|
+
if (!ref || !ref.isCollapsed()) return;
|
|
4723
4782
|
ref.expand();
|
|
4724
4783
|
if (!ref.isCollapsed()) return;
|
|
4725
4784
|
const group = groupRef.current;
|
|
4726
4785
|
if (!group) return;
|
|
4727
4786
|
const layout = group.getLayout();
|
|
4728
|
-
const donor = Object.entries(layout).filter(([panelId]) => panelId !== id && !
|
|
4787
|
+
const donor = Object.entries(layout).filter(([panelId]) => panelId !== id && !collapsedRef.current[panelId]).sort((a, b) => b[1] - a[1])[0];
|
|
4729
4788
|
if (!donor) return;
|
|
4730
4789
|
const [donorId, donorPct] = donor;
|
|
4731
4790
|
const share = donorPct / 2;
|
|
@@ -4734,7 +4793,26 @@ function PanelStack({
|
|
|
4734
4793
|
[id]: (layout[id] ?? 0) + share,
|
|
4735
4794
|
[donorId]: donorPct - share
|
|
4736
4795
|
});
|
|
4737
|
-
};
|
|
4796
|
+
}, []);
|
|
4797
|
+
const toggle = React23__namespace.useCallback(
|
|
4798
|
+
(id) => {
|
|
4799
|
+
const ref = refs.current[id];
|
|
4800
|
+
if (!ref) return;
|
|
4801
|
+
if (ref.isCollapsed()) expandPanel(id);
|
|
4802
|
+
else collapsePanel(id);
|
|
4803
|
+
},
|
|
4804
|
+
[expandPanel, collapsePanel]
|
|
4805
|
+
);
|
|
4806
|
+
React23__namespace.useImperativeHandle(
|
|
4807
|
+
stackRef,
|
|
4808
|
+
() => ({
|
|
4809
|
+
expand: expandPanel,
|
|
4810
|
+
collapse: collapsePanel,
|
|
4811
|
+
toggle,
|
|
4812
|
+
isCollapsed: (id) => !!collapsedRef.current[id]
|
|
4813
|
+
}),
|
|
4814
|
+
[expandPanel, collapsePanel, toggle]
|
|
4815
|
+
);
|
|
4738
4816
|
return (
|
|
4739
4817
|
// Header actions are nav items, and those carry tooltips — provide the
|
|
4740
4818
|
// context here so a `PanelStack` works outside an app shell too. Nesting
|
|
@@ -4772,9 +4850,12 @@ function PanelStack({
|
|
|
4772
4850
|
},
|
|
4773
4851
|
onResize: (size) => {
|
|
4774
4852
|
const next = size.inPixels <= headerHeight + 1;
|
|
4775
|
-
setCollapsed(
|
|
4776
|
-
(prev
|
|
4777
|
-
|
|
4853
|
+
setCollapsed((prev) => {
|
|
4854
|
+
if (prev[section.id] === next) return prev;
|
|
4855
|
+
const map = { ...prev, [section.id]: next };
|
|
4856
|
+
notify.current?.(map);
|
|
4857
|
+
return map;
|
|
4858
|
+
});
|
|
4778
4859
|
},
|
|
4779
4860
|
className: "flex flex-col overflow-hidden",
|
|
4780
4861
|
children: [
|
|
@@ -5192,6 +5273,27 @@ var SearchInput = ({
|
|
|
5192
5273
|
}
|
|
5193
5274
|
);
|
|
5194
5275
|
};
|
|
5276
|
+
var Eyebrow = React23__namespace.forwardRef(
|
|
5277
|
+
({ aside, tone = "muted", className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5278
|
+
"div",
|
|
5279
|
+
{
|
|
5280
|
+
ref,
|
|
5281
|
+
className: cn(
|
|
5282
|
+
"flex items-baseline gap-2 text-meta font-semibold uppercase tracking-wide",
|
|
5283
|
+
tone === "muted" && "text-muted-foreground",
|
|
5284
|
+
tone === "foreground" && "text-foreground",
|
|
5285
|
+
tone === "accent" && "text-primary",
|
|
5286
|
+
className
|
|
5287
|
+
),
|
|
5288
|
+
...props,
|
|
5289
|
+
children: [
|
|
5290
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children }),
|
|
5291
|
+
aside != null ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto shrink-0 font-normal normal-case tracking-normal text-muted-foreground", children: aside }) : null
|
|
5292
|
+
]
|
|
5293
|
+
}
|
|
5294
|
+
)
|
|
5295
|
+
);
|
|
5296
|
+
Eyebrow.displayName = "Eyebrow";
|
|
5195
5297
|
var SectionHeader = React23__namespace.forwardRef(({ icon, title, count, actions, bare, className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5196
5298
|
"div",
|
|
5197
5299
|
{
|
|
@@ -5365,6 +5467,299 @@ function TabbedPanel({
|
|
|
5365
5467
|
footerContent && /* @__PURE__ */ jsxRuntime.jsx(CardFooter, { className: cn("shrink-0", footerClassName), children: footerContent })
|
|
5366
5468
|
] }) }) });
|
|
5367
5469
|
}
|
|
5470
|
+
var BAR = {
|
|
5471
|
+
succeeded: "bg-success",
|
|
5472
|
+
running: "bg-info",
|
|
5473
|
+
failed: "bg-destructive",
|
|
5474
|
+
needs_input: "bg-warning",
|
|
5475
|
+
stopped: "bg-muted-foreground",
|
|
5476
|
+
skipped: "bg-transparent",
|
|
5477
|
+
queued: "bg-transparent"
|
|
5478
|
+
};
|
|
5479
|
+
var DOT = {
|
|
5480
|
+
succeeded: "success",
|
|
5481
|
+
running: "running",
|
|
5482
|
+
failed: "error",
|
|
5483
|
+
needs_input: "warning",
|
|
5484
|
+
stopped: "muted",
|
|
5485
|
+
skipped: "muted",
|
|
5486
|
+
queued: "queued"
|
|
5487
|
+
};
|
|
5488
|
+
var STATUS_LABEL = {
|
|
5489
|
+
succeeded: "succeeded",
|
|
5490
|
+
running: "running",
|
|
5491
|
+
failed: "failed",
|
|
5492
|
+
needs_input: "needs input",
|
|
5493
|
+
stopped: "stopped",
|
|
5494
|
+
skipped: "never ran",
|
|
5495
|
+
queued: "not started"
|
|
5496
|
+
};
|
|
5497
|
+
function renderResult(result) {
|
|
5498
|
+
if (result == null) return null;
|
|
5499
|
+
if (React23__namespace.isValidElement(result)) return result;
|
|
5500
|
+
if (typeof result !== "object") {
|
|
5501
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-meta", children: String(result) });
|
|
5502
|
+
}
|
|
5503
|
+
const entries = Object.entries(result);
|
|
5504
|
+
const scalars = entries.filter(([, v]) => v == null || typeof v !== "object");
|
|
5505
|
+
const nested = entries.filter(([, v]) => v != null && typeof v === "object");
|
|
5506
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5507
|
+
scalars.length ? /* @__PURE__ */ jsxRuntime.jsx(PropertyList, { labelWidth: 96, children: scalars.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsx(PropertyRow, { label: k, mono: true, className: "py-0.5", children: v == null ? "\u2014" : String(v) }, k)) }) : null,
|
|
5508
|
+
nested.map(([k, v]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
5509
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-meta text-muted-foreground", children: k }),
|
|
5510
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-40 overflow-auto border border-border bg-muted/40 p-1.5 font-mono text-meta", children: JSON.stringify(v, null, 2) })
|
|
5511
|
+
] }, k))
|
|
5512
|
+
] });
|
|
5513
|
+
}
|
|
5514
|
+
var TaskGanttDetailCard = React23__namespace.forwardRef(({ task, elapsedMs, formatDuration = defaultFormatDuration, className, ...props }, ref) => {
|
|
5515
|
+
const status = task.status ?? "succeeded";
|
|
5516
|
+
const ms = task.durationMs ?? elapsedMs;
|
|
5517
|
+
const duration = task.duration ?? (ms != null ? formatDuration(ms) : "\u2014");
|
|
5518
|
+
const attempts = task.attempts ?? [];
|
|
5519
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex flex-col gap-2", className), ...props, children: [
|
|
5520
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
5521
|
+
/* @__PURE__ */ jsxRuntime.jsx(StatusDot, { tone: DOT[status], size: "md", className: "translate-y-px" }),
|
|
5522
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate font-mono text-meta font-medium", children: task.key }),
|
|
5523
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 font-mono text-meta text-muted-foreground tabular-nums", children: duration })
|
|
5524
|
+
] }),
|
|
5525
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-meta text-muted-foreground", children: [
|
|
5526
|
+
STATUS_LABEL[status],
|
|
5527
|
+
task.summary != null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5528
|
+
" \xB7 ",
|
|
5529
|
+
task.summary
|
|
5530
|
+
] }) : null
|
|
5531
|
+
] }),
|
|
5532
|
+
attempts.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-0.5", children: attempts.map((a, i) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-meta text-muted-foreground", children: [
|
|
5533
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium text-warning", children: [
|
|
5534
|
+
"attempt ",
|
|
5535
|
+
i + 1
|
|
5536
|
+
] }),
|
|
5537
|
+
" ",
|
|
5538
|
+
a.title ?? `${a.status ?? "failed"}${a.durationMs != null ? ` \xB7 ${formatDuration(a.durationMs)}` : ""}`
|
|
5539
|
+
] }, i)) }) : null,
|
|
5540
|
+
task.error != null ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5541
|
+
"div",
|
|
5542
|
+
{
|
|
5543
|
+
style: { borderColor: "var(--color-destructive)" },
|
|
5544
|
+
className: "border-l-2 bg-destructive/10 px-2 py-1.5",
|
|
5545
|
+
children: [
|
|
5546
|
+
task.error.code != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-meta font-medium text-destructive", children: task.error.code }) : null,
|
|
5547
|
+
task.error.message != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-meta", children: task.error.message }) : null,
|
|
5548
|
+
task.error.detail != null ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-1 max-h-32 overflow-auto whitespace-pre-wrap font-mono text-meta text-muted-foreground", children: task.error.detail }) : null
|
|
5549
|
+
]
|
|
5550
|
+
}
|
|
5551
|
+
) : null,
|
|
5552
|
+
task.result != null ? renderResult(task.result) : null,
|
|
5553
|
+
task.log != null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border pt-1.5 font-mono text-meta text-muted-foreground", children: task.log }) : null
|
|
5554
|
+
] });
|
|
5555
|
+
});
|
|
5556
|
+
TaskGanttDetailCard.displayName = "TaskGanttDetailCard";
|
|
5557
|
+
var toMs = (t) => t instanceof Date ? t.getTime() : typeof t === "number" ? t : Date.parse(t);
|
|
5558
|
+
var defaultFormatDuration = (ms) => {
|
|
5559
|
+
if (ms < 100) return `${Math.round(ms)}ms`;
|
|
5560
|
+
const s = ms / 1e3;
|
|
5561
|
+
return s < 10 ? `${(Math.round(s * 10) / 10).toFixed(1)}s` : `${Math.round(s)}s`;
|
|
5562
|
+
};
|
|
5563
|
+
var defaultFormatTick = (ms) => {
|
|
5564
|
+
if (ms === 0) return "0s";
|
|
5565
|
+
const s = ms / 1e3;
|
|
5566
|
+
return Number.isInteger(s) ? `${s}s` : `${(Math.round(s * 10) / 10).toFixed(1)}s`;
|
|
5567
|
+
};
|
|
5568
|
+
function place(seg, origin) {
|
|
5569
|
+
let start = seg.startMs;
|
|
5570
|
+
if (start == null && seg.startedAt != null && origin != null) {
|
|
5571
|
+
start = toMs(seg.startedAt) - origin;
|
|
5572
|
+
}
|
|
5573
|
+
if (start == null || Number.isNaN(start)) return null;
|
|
5574
|
+
let duration = seg.durationMs;
|
|
5575
|
+
if (duration == null && seg.startedAt != null && seg.finishedAt != null) {
|
|
5576
|
+
duration = toMs(seg.finishedAt) - toMs(seg.startedAt);
|
|
5577
|
+
}
|
|
5578
|
+
return { start, duration: duration != null && duration > 0 ? duration : 0 };
|
|
5579
|
+
}
|
|
5580
|
+
var TaskGantt = React23__namespace.forwardRef(
|
|
5581
|
+
({
|
|
5582
|
+
tasks,
|
|
5583
|
+
origin,
|
|
5584
|
+
spanMs,
|
|
5585
|
+
nowMs,
|
|
5586
|
+
openEnded,
|
|
5587
|
+
ticks = 4,
|
|
5588
|
+
formatTick = defaultFormatTick,
|
|
5589
|
+
formatDuration = defaultFormatDuration,
|
|
5590
|
+
labelWidth = 112,
|
|
5591
|
+
density = "comfortable",
|
|
5592
|
+
showDetail = true,
|
|
5593
|
+
renderDetail,
|
|
5594
|
+
detailProps,
|
|
5595
|
+
selectedKey,
|
|
5596
|
+
onSelectTask,
|
|
5597
|
+
className,
|
|
5598
|
+
...props
|
|
5599
|
+
}, ref) => {
|
|
5600
|
+
const barHeight = density === "compact" ? 11 : 13;
|
|
5601
|
+
const durationWidth = 40;
|
|
5602
|
+
const rows = React23__namespace.useMemo(() => {
|
|
5603
|
+
const stamps = [];
|
|
5604
|
+
for (const t of [...tasks, ...tasks.flatMap((t2) => t2.attempts ?? [])]) {
|
|
5605
|
+
if (t.startedAt != null) stamps.push(toMs(t.startedAt));
|
|
5606
|
+
}
|
|
5607
|
+
const zero = origin != null ? toMs(origin) : stamps.length ? Math.min(...stamps) : void 0;
|
|
5608
|
+
return tasks.map((task) => {
|
|
5609
|
+
const segments = [...task.attempts ?? [], task].map((seg) => {
|
|
5610
|
+
const at = place(seg, zero);
|
|
5611
|
+
return at ? { ...at, status: seg.status ?? task.status ?? "succeeded", title: seg.title } : null;
|
|
5612
|
+
}).filter((s) => s !== null);
|
|
5613
|
+
const last = segments[segments.length - 1];
|
|
5614
|
+
return { task, segments, end: last ? last.start + last.duration : 0 };
|
|
5615
|
+
});
|
|
5616
|
+
}, [tasks, origin]);
|
|
5617
|
+
const span = Math.max(
|
|
5618
|
+
spanMs ?? Math.max(nowMs ?? 0, ...rows.map((r) => r.end)),
|
|
5619
|
+
1
|
|
5620
|
+
);
|
|
5621
|
+
const pct = (ms) => `${Math.max(0, Math.min(100, ms / span * 100))}%`;
|
|
5622
|
+
const axis = Array.from(
|
|
5623
|
+
{ length: ticks + 1 },
|
|
5624
|
+
(_, i) => formatTick(span / ticks * i)
|
|
5625
|
+
);
|
|
5626
|
+
const lastLabel = openEnded ? `${axis[axis.length - 1]}+` : axis[axis.length - 1];
|
|
5627
|
+
const detailFor = (task, elapsedMs) => {
|
|
5628
|
+
if (!showDetail) return null;
|
|
5629
|
+
if (renderDetail) return renderDetail(task);
|
|
5630
|
+
if (task.detail != null) return task.detail;
|
|
5631
|
+
const hasBody = task.result != null || task.error != null || task.log != null || task.summary != null || (task.attempts?.length ?? 0) > 0;
|
|
5632
|
+
if (!hasBody) return null;
|
|
5633
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5634
|
+
TaskGanttDetailCard,
|
|
5635
|
+
{
|
|
5636
|
+
task,
|
|
5637
|
+
elapsedMs,
|
|
5638
|
+
formatDuration
|
|
5639
|
+
}
|
|
5640
|
+
);
|
|
5641
|
+
};
|
|
5642
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, className: cn("flex flex-col", className), ...props, children: [
|
|
5643
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pt-0.5 pb-1", "aria-hidden": true, children: [
|
|
5644
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0", style: { width: labelWidth } }),
|
|
5645
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex flex-1", children: axis.slice(0, -1).map((label, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5646
|
+
"span",
|
|
5647
|
+
{
|
|
5648
|
+
className: "flex-1 border-l border-border pl-1 text-meta text-muted-foreground tabular-nums",
|
|
5649
|
+
children: label
|
|
5650
|
+
},
|
|
5651
|
+
i
|
|
5652
|
+
)) }),
|
|
5653
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5654
|
+
"span",
|
|
5655
|
+
{
|
|
5656
|
+
className: "shrink-0 text-right text-meta text-muted-foreground tabular-nums",
|
|
5657
|
+
style: { width: durationWidth },
|
|
5658
|
+
children: lastLabel
|
|
5659
|
+
}
|
|
5660
|
+
)
|
|
5661
|
+
] }),
|
|
5662
|
+
rows.map(({ task, segments }) => {
|
|
5663
|
+
const neverRan = segments.length === 0;
|
|
5664
|
+
const selected = selectedKey != null && selectedKey === task.key;
|
|
5665
|
+
const pickable = onSelectTask != null;
|
|
5666
|
+
const elapsed = task.durationMs ?? segments[segments.length - 1]?.duration;
|
|
5667
|
+
const duration = task.duration ?? (neverRan || elapsed == null ? "\u2014" : formatDuration(elapsed));
|
|
5668
|
+
const detail = detailFor(task, elapsed);
|
|
5669
|
+
const row = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 py-[3px]", children: [
|
|
5670
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5671
|
+
"span",
|
|
5672
|
+
{
|
|
5673
|
+
className: cn(
|
|
5674
|
+
"shrink-0 truncate font-mono text-meta",
|
|
5675
|
+
neverRan && "text-muted-foreground"
|
|
5676
|
+
),
|
|
5677
|
+
style: { width: labelWidth },
|
|
5678
|
+
title: task.key,
|
|
5679
|
+
children: task.label ?? task.key
|
|
5680
|
+
}
|
|
5681
|
+
),
|
|
5682
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5683
|
+
"span",
|
|
5684
|
+
{
|
|
5685
|
+
className: "relative min-w-0 flex-1 bg-muted/55",
|
|
5686
|
+
style: { height: barHeight },
|
|
5687
|
+
children: [
|
|
5688
|
+
neverRan ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 border border-dashed border-border" }) : segments.map((seg, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5689
|
+
"span",
|
|
5690
|
+
{
|
|
5691
|
+
title: seg.title ?? `${task.key} \xB7 ${seg.status} \xB7 ${formatDuration(seg.duration)}`,
|
|
5692
|
+
className: cn("absolute inset-y-0 rounded-[1px]", BAR[seg.status]),
|
|
5693
|
+
style: {
|
|
5694
|
+
left: pct(seg.start),
|
|
5695
|
+
width: pct(seg.duration),
|
|
5696
|
+
minWidth: 2
|
|
5697
|
+
}
|
|
5698
|
+
},
|
|
5699
|
+
i
|
|
5700
|
+
)),
|
|
5701
|
+
nowMs != null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5702
|
+
"span",
|
|
5703
|
+
{
|
|
5704
|
+
className: "absolute -top-0.5 -bottom-0.5 w-px bg-info/70",
|
|
5705
|
+
style: { left: pct(nowMs) },
|
|
5706
|
+
"aria-hidden": true
|
|
5707
|
+
}
|
|
5708
|
+
) : null
|
|
5709
|
+
]
|
|
5710
|
+
}
|
|
5711
|
+
),
|
|
5712
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5713
|
+
"span",
|
|
5714
|
+
{
|
|
5715
|
+
className: "shrink-0 text-right font-mono text-meta text-muted-foreground tabular-nums",
|
|
5716
|
+
style: { width: durationWidth },
|
|
5717
|
+
children: duration
|
|
5718
|
+
}
|
|
5719
|
+
)
|
|
5720
|
+
] }) });
|
|
5721
|
+
const trigger = pickable ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5722
|
+
"button",
|
|
5723
|
+
{
|
|
5724
|
+
type: "button",
|
|
5725
|
+
"aria-pressed": selected,
|
|
5726
|
+
onClick: () => onSelectTask(task.key),
|
|
5727
|
+
className: cn(
|
|
5728
|
+
"w-full cursor-pointer text-left focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
5729
|
+
"hover:bg-accent/60",
|
|
5730
|
+
selected && "bg-accent"
|
|
5731
|
+
),
|
|
5732
|
+
children: row
|
|
5733
|
+
}
|
|
5734
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(detail != null && "hover:bg-accent/60"), children: row });
|
|
5735
|
+
if (detail == null) return /* @__PURE__ */ jsxRuntime.jsx("div", { children: trigger }, task.key);
|
|
5736
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5737
|
+
HoverCard,
|
|
5738
|
+
{
|
|
5739
|
+
openDelay: detailProps?.openDelay ?? 200,
|
|
5740
|
+
closeDelay: detailProps?.closeDelay ?? 80,
|
|
5741
|
+
children: [
|
|
5742
|
+
/* @__PURE__ */ jsxRuntime.jsx(HoverCardTrigger, { asChild: true, children: trigger }),
|
|
5743
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5744
|
+
HoverCardContent,
|
|
5745
|
+
{
|
|
5746
|
+
side: detailProps?.side ?? "right",
|
|
5747
|
+
align: detailProps?.align ?? "start",
|
|
5748
|
+
sideOffset: detailProps?.sideOffset ?? 8,
|
|
5749
|
+
style: detailProps?.width != null ? { width: detailProps.width } : void 0,
|
|
5750
|
+
className: cn("w-72 p-3", detailProps?.className),
|
|
5751
|
+
children: detail
|
|
5752
|
+
}
|
|
5753
|
+
)
|
|
5754
|
+
]
|
|
5755
|
+
},
|
|
5756
|
+
task.key
|
|
5757
|
+
);
|
|
5758
|
+
})
|
|
5759
|
+
] });
|
|
5760
|
+
}
|
|
5761
|
+
);
|
|
5762
|
+
TaskGantt.displayName = "TaskGantt";
|
|
5368
5763
|
var TemplatePicker = React23__namespace.forwardRef(({ heading, options, value, onSelect, footnote, className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5369
5764
|
"div",
|
|
5370
5765
|
{
|
|
@@ -6215,6 +6610,7 @@ exports.ChatSessionTaskRow = ChatSessionTaskRow;
|
|
|
6215
6610
|
exports.CitationList = CitationList;
|
|
6216
6611
|
exports.CitationMarker = CitationMarker;
|
|
6217
6612
|
exports.CitationRow = CitationRow;
|
|
6613
|
+
exports.ClampedText = ClampedText;
|
|
6218
6614
|
exports.ClarifyCard = ClarifyCard;
|
|
6219
6615
|
exports.Command = Command;
|
|
6220
6616
|
exports.CommandDialog = CommandDialog;
|
|
@@ -6261,6 +6657,7 @@ exports.EmissionHeader = EmissionHeader;
|
|
|
6261
6657
|
exports.EmptyState = EmptyState;
|
|
6262
6658
|
exports.EmptyStateLock = EmptyStateLock;
|
|
6263
6659
|
exports.ErrorBoundary = ErrorBoundary;
|
|
6660
|
+
exports.Eyebrow = Eyebrow;
|
|
6264
6661
|
exports.FilterBar = FilterBar;
|
|
6265
6662
|
exports.FilterChip = FilterChip;
|
|
6266
6663
|
exports.HeatStrip = HeatStrip;
|
|
@@ -6393,6 +6790,8 @@ exports.Tabs = Tabs;
|
|
|
6393
6790
|
exports.TabsContent = TabsContent;
|
|
6394
6791
|
exports.TabsList = TabsList;
|
|
6395
6792
|
exports.TabsTrigger = TabsTrigger;
|
|
6793
|
+
exports.TaskGantt = TaskGantt;
|
|
6794
|
+
exports.TaskGanttDetailCard = TaskGanttDetailCard;
|
|
6396
6795
|
exports.TemplatePicker = TemplatePicker;
|
|
6397
6796
|
exports.Terminal = Terminal;
|
|
6398
6797
|
exports.TerminalLine = TerminalLine;
|