@ai-matrx/design-system 0.19.17 → 0.20.0
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/CHANGELOG.md +14 -0
- package/dist/content-transfer/alchemy.svg +1 -1
- package/dist/content-transfer/icon.cjs +1 -1
- package/dist/content-transfer/icon.cjs.map +1 -1
- package/dist/content-transfer/icon.js +1 -1
- package/dist/content-transfer/icon.js.map +1 -1
- package/dist/content-transfer/portal.svg +1 -1
- package/dist/content-transfer.cjs +692 -407
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.css +15 -0
- package/dist/content-transfer.d.cts +19 -4
- package/dist/content-transfer.d.ts +19 -4
- package/dist/content-transfer.js +684 -396
- package/dist/content-transfer.js.map +1 -1
- package/dist/data-table/copy-helpers.d.cts +3 -1
- package/dist/data-table/copy-helpers.d.ts +3 -1
- package/dist/data-table/copy-types.cjs.map +1 -1
- package/dist/data-table/copy-types.d.cts +4 -0
- package/dist/data-table/copy-types.d.ts +4 -0
- package/dist/data-table/data-row-inspector.cjs +659 -465
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +662 -463
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +657 -463
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +663 -464
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/filter-engine.d.cts +3 -1
- package/dist/data-table/filter-engine.d.ts +3 -1
- package/dist/data-table/host.cjs.map +1 -1
- package/dist/data-table/host.d.cts +6 -1
- package/dist/data-table/host.d.ts +6 -1
- package/dist/data-table/host.js.map +1 -1
- package/dist/data-table/index.cjs +1211 -980
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +4 -2
- package/dist/data-table/index.d.ts +4 -2
- package/dist/data-table/index.js +1350 -1114
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +3 -1
- package/dist/data-table/infer-filter.d.ts +3 -1
- package/dist/data-table/layered-filters.d.cts +3 -1
- package/dist/data-table/layered-filters.d.ts +3 -1
- package/dist/data-table/pagination.cjs +2 -2
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +2 -2
- package/dist/data-table/pagination.js.map +1 -1
- package/dist/data-table/query-control.d.cts +3 -1
- package/dist/data-table/query-control.d.ts +3 -1
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +3 -1
- package/dist/data-table/types.d.ts +3 -1
- package/dist/data-table/url-state.d.cts +3 -1
- package/dist/data-table/url-state.d.ts +3 -1
- package/dist/data-table/uuid-cell.cjs.map +1 -1
- package/dist/data-table/uuid-cell.js.map +1 -1
- package/dist/data-table/xlsx.d.cts +3 -1
- package/dist/data-table/xlsx.d.ts +3 -1
- package/dist/extensions-DCHtNwG3.d.cts +32 -0
- package/dist/extensions-DCHtNwG3.d.ts +32 -0
- package/dist/tap-target.css +2 -2
- package/dist/{types-DqlfNcC5.d.cts → types-C2yaTspG.d.cts} +6 -1
- package/dist/{types-lNw7TnTM.d.ts → types-DB30aCHu.d.ts} +6 -1
- package/package.json +1 -1
|
@@ -44,15 +44,12 @@ function cn(...inputs) {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// src/content-transfer/matrx-copy.tsx
|
|
47
|
-
var
|
|
48
|
-
var
|
|
47
|
+
var React10 = __toESM(require("react"), 1);
|
|
48
|
+
var import_content_transfer3 = require("@ai-matrx/kit/content-transfer");
|
|
49
49
|
var import_format2 = require("@ai-matrx/kit/format");
|
|
50
50
|
|
|
51
|
-
// src/content-transfer/
|
|
52
|
-
var
|
|
53
|
-
var import_react_dom = require("react-dom");
|
|
54
|
-
var import_content_transfer = require("@ai-matrx/kit/content-transfer");
|
|
55
|
-
var import_format = require("@ai-matrx/kit/format");
|
|
51
|
+
// src/content-transfer/email-review.tsx
|
|
52
|
+
var React6 = __toESM(require("react"), 1);
|
|
56
53
|
|
|
57
54
|
// src/button.tsx
|
|
58
55
|
var import_react_slot = require("@radix-ui/react-slot");
|
|
@@ -439,13 +436,133 @@ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
439
436
|
));
|
|
440
437
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
441
438
|
|
|
439
|
+
// src/content-transfer/email-review.tsx
|
|
440
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
441
|
+
var cancelled = () => ({ status: "cancelled" });
|
|
442
|
+
var failed = (error) => ({
|
|
443
|
+
status: "error",
|
|
444
|
+
code: "email-failed",
|
|
445
|
+
message: error instanceof Error ? error.message : "Could not send email.",
|
|
446
|
+
retryable: true
|
|
447
|
+
});
|
|
448
|
+
function useReviewedTransferEmail(email) {
|
|
449
|
+
const [pending, setPending] = React6.useState(null);
|
|
450
|
+
const [sending, setSending] = React6.useState(false);
|
|
451
|
+
const pendingRef = React6.useRef(null);
|
|
452
|
+
const sendingRef = React6.useRef(false);
|
|
453
|
+
const settle = React6.useCallback((request, outcome, render = true) => {
|
|
454
|
+
if (pendingRef.current !== request) return;
|
|
455
|
+
pendingRef.current = null;
|
|
456
|
+
request.context.signal.removeEventListener("abort", request.onAbort);
|
|
457
|
+
request.resolve(outcome);
|
|
458
|
+
sendingRef.current = false;
|
|
459
|
+
if (render) {
|
|
460
|
+
setSending(false);
|
|
461
|
+
setPending(null);
|
|
462
|
+
}
|
|
463
|
+
}, []);
|
|
464
|
+
React6.useEffect(
|
|
465
|
+
() => () => {
|
|
466
|
+
const request = pendingRef.current;
|
|
467
|
+
if (!request) return;
|
|
468
|
+
pendingRef.current = null;
|
|
469
|
+
request.context.signal.removeEventListener("abort", request.onAbort);
|
|
470
|
+
request.resolve(cancelled());
|
|
471
|
+
sendingRef.current = false;
|
|
472
|
+
},
|
|
473
|
+
[]
|
|
474
|
+
);
|
|
475
|
+
const reviewed = React6.useMemo(() => {
|
|
476
|
+
if (!email) return void 0;
|
|
477
|
+
return {
|
|
478
|
+
send: (artifact, context) => {
|
|
479
|
+
if (context.signal.aborted) return Promise.resolve(cancelled());
|
|
480
|
+
if (pendingRef.current)
|
|
481
|
+
return Promise.resolve({
|
|
482
|
+
status: "error",
|
|
483
|
+
code: "email-review-active",
|
|
484
|
+
message: "Finish reviewing the current email before starting another.",
|
|
485
|
+
retryable: true
|
|
486
|
+
});
|
|
487
|
+
return new Promise((resolve2) => {
|
|
488
|
+
const request = {
|
|
489
|
+
artifact,
|
|
490
|
+
context,
|
|
491
|
+
resolve: resolve2,
|
|
492
|
+
onAbort: () => settle(request, cancelled())
|
|
493
|
+
};
|
|
494
|
+
pendingRef.current = request;
|
|
495
|
+
context.signal.addEventListener("abort", request.onAbort, { once: true });
|
|
496
|
+
setSending(false);
|
|
497
|
+
setPending(request);
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
}, [email, settle]);
|
|
502
|
+
const cancel = React6.useCallback(() => {
|
|
503
|
+
const request = pendingRef.current;
|
|
504
|
+
if (request && !sendingRef.current) settle(request, cancelled());
|
|
505
|
+
}, [settle]);
|
|
506
|
+
const confirm = React6.useCallback(() => {
|
|
507
|
+
const request = pendingRef.current;
|
|
508
|
+
if (!request || sendingRef.current || request.context.signal.aborted) return;
|
|
509
|
+
sendingRef.current = true;
|
|
510
|
+
setSending(true);
|
|
511
|
+
void email?.send(request.artifact, request.context).then(
|
|
512
|
+
(outcome) => settle(request, outcome),
|
|
513
|
+
(error) => settle(request, failed(error))
|
|
514
|
+
);
|
|
515
|
+
}, [email, settle]);
|
|
516
|
+
const review = pending ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { open: true, onOpenChange: (open) => {
|
|
517
|
+
if (!open) cancel();
|
|
518
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogContent, { className: "matrx-alchemy-workspace matrx-alchemy-email-review", "aria-busy": sending, children: [
|
|
519
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogHeader, { children: [
|
|
520
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogTitle, { children: "Review email attachment" }),
|
|
521
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogDescription, { children: [
|
|
522
|
+
"Email ",
|
|
523
|
+
pending.artifact.file?.filename ?? `${pending.artifact.format} output`,
|
|
524
|
+
" from ",
|
|
525
|
+
pending.context.label,
|
|
526
|
+
". Review this exact attachment before sending."
|
|
527
|
+
] })
|
|
528
|
+
] }),
|
|
529
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("textarea", { "aria-label": "Email attachment preview", readOnly: true, value: pending.artifact.plainText, className: "matrx-alchemy-preview" }),
|
|
530
|
+
pending.artifact.omissions.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "matrx-alchemy-email-adjustments", open: true, children: [
|
|
531
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("summary", { children: [
|
|
532
|
+
pending.artifact.omissions.length,
|
|
533
|
+
" omission",
|
|
534
|
+
pending.artifact.omissions.length === 1 ? "" : "s",
|
|
535
|
+
" or adjustment",
|
|
536
|
+
pending.artifact.omissions.length === 1 ? "" : "s"
|
|
537
|
+
] }),
|
|
538
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: pending.artifact.omissions.map((omission, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
|
|
539
|
+
omission.path || "/",
|
|
540
|
+
": ",
|
|
541
|
+
omission.reason,
|
|
542
|
+
omission.count == null ? "" : ` (${omission.count})`
|
|
543
|
+
] }, `${omission.path}-${omission.reason}-${index}`)) })
|
|
544
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "matrx-alchemy-meta", children: "No omissions or adjustments." }),
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogFooter, { children: [
|
|
546
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: sending, onClick: cancel, children: "Cancel" }),
|
|
547
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", disabled: sending, onClick: confirm, children: sending ? "Sending email\u2026" : "Send email" })
|
|
548
|
+
] })
|
|
549
|
+
] }) }) : null;
|
|
550
|
+
return { email: reviewed, review };
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// src/content-transfer/index.tsx
|
|
554
|
+
var React9 = __toESM(require("react"), 1);
|
|
555
|
+
var import_react_dom = require("react-dom");
|
|
556
|
+
var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
|
|
557
|
+
var import_format = require("@ai-matrx/kit/format");
|
|
558
|
+
|
|
442
559
|
// src/popover.tsx
|
|
443
560
|
var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"), 1);
|
|
444
|
-
var
|
|
445
|
-
var
|
|
561
|
+
var React7 = __toESM(require("react"), 1);
|
|
562
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
446
563
|
var Popover = PopoverPrimitive.Root;
|
|
447
564
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
448
|
-
var PopoverContent =
|
|
565
|
+
var PopoverContent = React7.forwardRef(
|
|
449
566
|
({
|
|
450
567
|
className,
|
|
451
568
|
align = "center",
|
|
@@ -455,7 +572,7 @@ var PopoverContent = React6.forwardRef(
|
|
|
455
572
|
...props
|
|
456
573
|
}, ref) => {
|
|
457
574
|
const portalContainer = usePortalContainer(container);
|
|
458
|
-
return /* @__PURE__ */ (0,
|
|
575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
459
576
|
PopoverPrimitive.Content,
|
|
460
577
|
{
|
|
461
578
|
ref,
|
|
@@ -484,14 +601,14 @@ var import_react = require("react");
|
|
|
484
601
|
|
|
485
602
|
// src/tooltip.tsx
|
|
486
603
|
var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
|
|
487
|
-
var
|
|
488
|
-
var
|
|
604
|
+
var React8 = __toESM(require("react"), 1);
|
|
605
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
489
606
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
490
607
|
var Tooltip = TooltipPrimitive.Root;
|
|
491
608
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
492
|
-
var TooltipContent =
|
|
609
|
+
var TooltipContent = React8.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
|
|
493
610
|
const resolved = usePortalContainer(container);
|
|
494
|
-
return /* @__PURE__ */ (0,
|
|
611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
495
612
|
TooltipPrimitive.Content,
|
|
496
613
|
{
|
|
497
614
|
ref,
|
|
@@ -520,7 +637,7 @@ function getTapTargetLinkComponent() {
|
|
|
520
637
|
}
|
|
521
638
|
|
|
522
639
|
// src/tap-target/tap-target-button.tsx
|
|
523
|
-
var
|
|
640
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
524
641
|
var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
|
|
525
642
|
var TAP_OUTER_CLASS = "matrx-tap-target group";
|
|
526
643
|
var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
|
|
@@ -536,9 +653,9 @@ function IconContent({
|
|
|
536
653
|
className: cn2(className, icon.props.className)
|
|
537
654
|
});
|
|
538
655
|
}
|
|
539
|
-
return /* @__PURE__ */ (0,
|
|
656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className, children: icon });
|
|
540
657
|
}
|
|
541
|
-
return /* @__PURE__ */ (0,
|
|
658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
542
659
|
"svg",
|
|
543
660
|
{
|
|
544
661
|
className,
|
|
@@ -575,7 +692,7 @@ function buildTapInner({
|
|
|
575
692
|
children,
|
|
576
693
|
strokeWidth = 2
|
|
577
694
|
}) {
|
|
578
|
-
const iconEl = /* @__PURE__ */ (0,
|
|
695
|
+
const iconEl = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
579
696
|
IconContent,
|
|
580
697
|
{
|
|
581
698
|
icon,
|
|
@@ -586,11 +703,11 @@ function buildTapInner({
|
|
|
586
703
|
);
|
|
587
704
|
const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
|
|
588
705
|
if (!label) {
|
|
589
|
-
return /* @__PURE__ */ (0,
|
|
706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: pillClasses, children: iconEl });
|
|
590
707
|
}
|
|
591
|
-
return /* @__PURE__ */ (0,
|
|
708
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: pillClasses, children: [
|
|
592
709
|
iconEl,
|
|
593
|
-
/* @__PURE__ */ (0,
|
|
710
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
|
|
594
711
|
] });
|
|
595
712
|
}
|
|
596
713
|
function renderTapTarget({
|
|
@@ -678,7 +795,7 @@ function renderTrigger({
|
|
|
678
795
|
buttonRef
|
|
679
796
|
}) {
|
|
680
797
|
if (disabled && href) {
|
|
681
|
-
return /* @__PURE__ */ (0,
|
|
798
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
682
799
|
"span",
|
|
683
800
|
{
|
|
684
801
|
"aria-disabled": "true",
|
|
@@ -691,7 +808,7 @@ function renderTrigger({
|
|
|
691
808
|
if (href) {
|
|
692
809
|
const isExternal = EXTERNAL_RE.test(href);
|
|
693
810
|
if (isExternal) {
|
|
694
|
-
return /* @__PURE__ */ (0,
|
|
811
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
695
812
|
"a",
|
|
696
813
|
{
|
|
697
814
|
href,
|
|
@@ -705,7 +822,7 @@ function renderTrigger({
|
|
|
705
822
|
}
|
|
706
823
|
const Link = linkComponent ?? getTapTargetLinkComponent();
|
|
707
824
|
if (Link) {
|
|
708
|
-
return /* @__PURE__ */ (0,
|
|
825
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
709
826
|
Link,
|
|
710
827
|
{
|
|
711
828
|
href,
|
|
@@ -718,7 +835,7 @@ function renderTrigger({
|
|
|
718
835
|
}
|
|
719
836
|
);
|
|
720
837
|
}
|
|
721
|
-
return /* @__PURE__ */ (0,
|
|
838
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
722
839
|
"a",
|
|
723
840
|
{
|
|
724
841
|
href,
|
|
@@ -731,7 +848,7 @@ function renderTrigger({
|
|
|
731
848
|
);
|
|
732
849
|
}
|
|
733
850
|
if (as === "label") {
|
|
734
|
-
return /* @__PURE__ */ (0,
|
|
851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
735
852
|
"label",
|
|
736
853
|
{
|
|
737
854
|
htmlFor,
|
|
@@ -741,7 +858,7 @@ function renderTrigger({
|
|
|
741
858
|
}
|
|
742
859
|
);
|
|
743
860
|
}
|
|
744
|
-
return /* @__PURE__ */ (0,
|
|
861
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
745
862
|
"button",
|
|
746
863
|
{
|
|
747
864
|
ref: buttonRef,
|
|
@@ -765,14 +882,14 @@ function withTooltip(trigger, {
|
|
|
765
882
|
if (tooltip === false) return trigger;
|
|
766
883
|
const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
|
|
767
884
|
if (!label) return trigger;
|
|
768
|
-
return /* @__PURE__ */ (0,
|
|
769
|
-
/* @__PURE__ */ (0,
|
|
885
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
|
|
886
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
|
|
770
887
|
// Radix Tooltip triggers need a hoverable element; a disabled button
|
|
771
888
|
// does not dispatch pointer events, so we wrap in a span for the
|
|
772
889
|
// trigger target while keeping the disabled visual state.
|
|
773
|
-
/* @__PURE__ */ (0,
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "inline-flex", children: trigger })
|
|
774
891
|
) : trigger }),
|
|
775
|
-
/* @__PURE__ */ (0,
|
|
892
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
|
|
776
893
|
] });
|
|
777
894
|
}
|
|
778
895
|
var TapTargetButton = (0, import_react.forwardRef)(function TapTargetButton2({
|
|
@@ -928,7 +1045,7 @@ var TapTargetButtonDestructive = (0, import_react.forwardRef)(function TapTarget
|
|
|
928
1045
|
hoverBgColor = "hover:bg-destructive/90",
|
|
929
1046
|
...rest
|
|
930
1047
|
}, ref) {
|
|
931
|
-
return /* @__PURE__ */ (0,
|
|
1048
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
932
1049
|
TapTargetButtonSolid,
|
|
933
1050
|
{
|
|
934
1051
|
ref,
|
|
@@ -992,7 +1109,7 @@ var TapTargetButtonForGroup = (0, import_react.forwardRef)(function TapTargetBut
|
|
|
992
1109
|
|
|
993
1110
|
// src/content-transfer/icon.ts
|
|
994
1111
|
var ALCHEMY_GLYPH_PATHS = {
|
|
995
|
-
portal: ["M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-
|
|
1112
|
+
portal: ["M10 4H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h4M14 4h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4M12 8v8m-3-3 3 3 3-3"],
|
|
996
1113
|
"copy-transform": ["M8 7V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v8M13 21H5a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v3m-5 4h11m-3-3 3 3-3 3"]
|
|
997
1114
|
};
|
|
998
1115
|
var ALCHEMY_GLYPH_VIEWBOX = { portal: "0 0 24 24", "copy-transform": "0 0 24 24" };
|
|
@@ -1000,20 +1117,38 @@ var svg = (paths, viewBox) => `<svg xmlns="http://www.w3.org/2000/svg" width="18
|
|
|
1000
1117
|
var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal, ALCHEMY_GLYPH_VIEWBOX.portal);
|
|
1001
1118
|
var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"], ALCHEMY_GLYPH_VIEWBOX["copy-transform"]);
|
|
1002
1119
|
|
|
1120
|
+
// src/content-transfer/extensions.ts
|
|
1121
|
+
var import_content_transfer = require("@ai-matrx/kit/content-transfer");
|
|
1122
|
+
var emailArtifact = (draft, format, signal, jsonFormat) => format === "json" && jsonFormat?.supports(draft.payload) ? jsonFormat.build(draft, signal) : Promise.resolve((0, import_content_transfer.serialize)(draft, format, { spreadsheetSafe: format === "csv" }));
|
|
1123
|
+
function createTransferEmailActions(email, options = {}) {
|
|
1124
|
+
return ["csv", "json", "markdown"].map((format) => ({
|
|
1125
|
+
id: `email-${format}`,
|
|
1126
|
+
label: `Email ${format === "csv" ? "CSV" : format === "json" ? "JSON" : "Markdown"}`,
|
|
1127
|
+
prepared: true,
|
|
1128
|
+
group: "email",
|
|
1129
|
+
supports: (_snapshot, draft) => Boolean(draft) && (format !== "csv" || draft?.payload.kind === "rows"),
|
|
1130
|
+
async run({ draft, signal, snapshot }) {
|
|
1131
|
+
if (signal.aborted) return { status: "cancelled" };
|
|
1132
|
+
const artifact = await emailArtifact(draft, format, signal, options.jsonFormat);
|
|
1133
|
+
return email.send(artifact, { label: snapshot.label, signal });
|
|
1134
|
+
}
|
|
1135
|
+
}));
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1003
1138
|
// src/content-transfer/index.tsx
|
|
1004
|
-
var
|
|
1139
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1005
1140
|
function AlchemyGlyph({ icon = "portal", ...props }) {
|
|
1006
|
-
return /* @__PURE__ */ (0,
|
|
1141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { width: "18", height: "18", viewBox: ALCHEMY_GLYPH_VIEWBOX[icon], fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children: ALCHEMY_GLYPH_PATHS[icon].map((d) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d }, d)) });
|
|
1007
1142
|
}
|
|
1008
|
-
var CapabilityContext =
|
|
1009
|
-
var useContentTransferCapabilities = () =>
|
|
1010
|
-
var SurfaceContext =
|
|
1143
|
+
var CapabilityContext = React9.createContext({});
|
|
1144
|
+
var useContentTransferCapabilities = () => React9.useContext(CapabilityContext);
|
|
1145
|
+
var SurfaceContext = React9.createContext(null);
|
|
1011
1146
|
function MenuPresentation({ label, hint, icon: Icon2 }) {
|
|
1012
|
-
return /* @__PURE__ */ (0,
|
|
1013
|
-
Icon2 ? /* @__PURE__ */ (0,
|
|
1014
|
-
/* @__PURE__ */ (0,
|
|
1147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1148
|
+
Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : null,
|
|
1149
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1015
1150
|
label,
|
|
1016
|
-
hint ? /* @__PURE__ */ (0,
|
|
1151
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1017
1152
|
] })
|
|
1018
1153
|
] });
|
|
1019
1154
|
}
|
|
@@ -1031,71 +1166,71 @@ function DestinationPresentation({ action }) {
|
|
|
1031
1166
|
tools: "m14 4 3 3 4-1a6 6 0 0 1-8 7l-7 7-3-3 7-7a6 6 0 0 1 4-6z"
|
|
1032
1167
|
};
|
|
1033
1168
|
const path = paths[action.id.replace(/^matrx:/, "")];
|
|
1034
|
-
return /* @__PURE__ */ (0,
|
|
1035
|
-
!action.icon ? path ? /* @__PURE__ */ (0,
|
|
1036
|
-
/* @__PURE__ */ (0,
|
|
1169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1170
|
+
!action.icon ? path ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { file: true }) : null,
|
|
1171
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...action })
|
|
1037
1172
|
] });
|
|
1038
1173
|
}
|
|
1039
1174
|
function ReceiptLink({ target }) {
|
|
1040
|
-
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0,
|
|
1175
|
+
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
|
|
1041
1176
|
"Open ",
|
|
1042
1177
|
target.kind
|
|
1043
1178
|
] }) : null;
|
|
1044
1179
|
}
|
|
1045
1180
|
function PaletteGlyph({ format, ai = false, file = false, kind }) {
|
|
1046
|
-
if (kind === "ai-copy") return /* @__PURE__ */ (0,
|
|
1047
|
-
/* @__PURE__ */ (0,
|
|
1048
|
-
/* @__PURE__ */ (0,
|
|
1049
|
-
/* @__PURE__ */ (0,
|
|
1181
|
+
if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1182
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
|
|
1183
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
|
|
1184
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
|
|
1050
1185
|
] });
|
|
1051
|
-
if (kind === "sliders") return /* @__PURE__ */ (0,
|
|
1052
|
-
/* @__PURE__ */ (0,
|
|
1053
|
-
/* @__PURE__ */ (0,
|
|
1186
|
+
if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1187
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
|
|
1188
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
|
|
1054
1189
|
] });
|
|
1055
|
-
if (ai) return /* @__PURE__ */ (0,
|
|
1056
|
-
/* @__PURE__ */ (0,
|
|
1057
|
-
/* @__PURE__ */ (0,
|
|
1058
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
if (ai) return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5a3 3 0 1 0-5.997.125A4 4 0 0 0 3.5 10.9a4 4 0 0 0 .556 6.588A4 4 0 0 0 12 19" }),
|
|
1192
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.503 5.775 4 4 0 0 1-.556 6.588A4 4 0 0 1 12 19" }),
|
|
1193
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
|
|
1059
1194
|
] });
|
|
1060
|
-
if (file) return /* @__PURE__ */ (0,
|
|
1061
|
-
/* @__PURE__ */ (0,
|
|
1062
|
-
/* @__PURE__ */ (0,
|
|
1195
|
+
if (file) return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
1196
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
|
|
1197
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
|
|
1063
1198
|
] });
|
|
1064
|
-
const path = format === "json" ? /* @__PURE__ */ (0,
|
|
1065
|
-
/* @__PURE__ */ (0,
|
|
1066
|
-
/* @__PURE__ */ (0,
|
|
1067
|
-
] }) : format === "compact-json" ? /* @__PURE__ */ (0,
|
|
1068
|
-
/* @__PURE__ */ (0,
|
|
1069
|
-
/* @__PURE__ */ (0,
|
|
1070
|
-
/* @__PURE__ */ (0,
|
|
1071
|
-
/* @__PURE__ */ (0,
|
|
1072
|
-
] }) : format === "csv" ? /* @__PURE__ */ (0,
|
|
1073
|
-
/* @__PURE__ */ (0,
|
|
1074
|
-
/* @__PURE__ */ (0,
|
|
1075
|
-
] }) : format === "tsv" ? /* @__PURE__ */ (0,
|
|
1076
|
-
/* @__PURE__ */ (0,
|
|
1077
|
-
/* @__PURE__ */ (0,
|
|
1078
|
-
] }) : format === "xlsx" ? /* @__PURE__ */ (0,
|
|
1079
|
-
/* @__PURE__ */ (0,
|
|
1080
|
-
/* @__PURE__ */ (0,
|
|
1081
|
-
] }) : format === "markdown" ? /* @__PURE__ */ (0,
|
|
1082
|
-
/* @__PURE__ */ (0,
|
|
1083
|
-
/* @__PURE__ */ (0,
|
|
1084
|
-
] }) : format === "html" ? /* @__PURE__ */ (0,
|
|
1085
|
-
return /* @__PURE__ */ (0,
|
|
1199
|
+
const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1200
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
|
|
1201
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 4c2 0 2 3 4 3v3c-2 0-2 1-2 2s0 2 2 2v3c-2 0-2 3-4 3" })
|
|
1202
|
+
] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1203
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m14 10 7-7" }),
|
|
1204
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M20 10h-6V4" }),
|
|
1205
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "m3 21 7-7" }),
|
|
1206
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 14h6v6" })
|
|
1207
|
+
] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1208
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
|
|
1209
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 10h16M10 4v16" })
|
|
1210
|
+
] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1211
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1212
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
|
|
1213
|
+
] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1214
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
|
|
1216
|
+
] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1217
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5z" }),
|
|
1218
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
|
|
1219
|
+
] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
|
|
1220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("svg", { className: "matrx-alchemy-palette-glyph", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: path });
|
|
1086
1221
|
}
|
|
1087
1222
|
function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
|
|
1088
1223
|
if (!items.length && !extra) return null;
|
|
1089
|
-
return /* @__PURE__ */ (0,
|
|
1090
|
-
/* @__PURE__ */ (0,
|
|
1224
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
|
|
1225
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: title }),
|
|
1091
1226
|
items.map((item) => {
|
|
1092
1227
|
const label = item.copyLabel ?? item.label;
|
|
1093
1228
|
const hint = item.hint ?? fallbackHint;
|
|
1094
|
-
return /* @__PURE__ */ (0,
|
|
1095
|
-
item.icon ? /* @__PURE__ */ (0,
|
|
1096
|
-
/* @__PURE__ */ (0,
|
|
1229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: cn("matrx-alchemy-palette-row", ai && "matrx-alchemy-palette-row-ai"), "aria-label": item.ariaLabel ?? `${label}${hint ? ` ${hint}` : ""}`, onClick: () => onRun?.(item), children: [
|
|
1230
|
+
item.icon ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1097
1232
|
label,
|
|
1098
|
-
hint ? /* @__PURE__ */ (0,
|
|
1233
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1099
1234
|
] })
|
|
1100
1235
|
] }, item.id);
|
|
1101
1236
|
}),
|
|
@@ -1138,10 +1273,10 @@ function snapshotContent(snapshot) {
|
|
|
1138
1273
|
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
1139
1274
|
}
|
|
1140
1275
|
function useFence() {
|
|
1141
|
-
const mounted =
|
|
1142
|
-
const nextId =
|
|
1143
|
-
const active =
|
|
1144
|
-
|
|
1276
|
+
const mounted = React9.useRef(true);
|
|
1277
|
+
const nextId = React9.useRef(0);
|
|
1278
|
+
const active = React9.useRef(/* @__PURE__ */ new Set());
|
|
1279
|
+
React9.useEffect(() => {
|
|
1145
1280
|
mounted.current = true;
|
|
1146
1281
|
return () => {
|
|
1147
1282
|
mounted.current = false;
|
|
@@ -1150,14 +1285,14 @@ function useFence() {
|
|
|
1150
1285
|
active.current.clear();
|
|
1151
1286
|
};
|
|
1152
1287
|
}, []);
|
|
1153
|
-
const begin =
|
|
1288
|
+
const begin = React9.useCallback(() => {
|
|
1154
1289
|
const controller = new AbortController();
|
|
1155
1290
|
active.current.add(controller);
|
|
1156
1291
|
return { controller, id: ++nextId.current };
|
|
1157
1292
|
}, []);
|
|
1158
|
-
const finish =
|
|
1159
|
-
const valid =
|
|
1160
|
-
const abortAll =
|
|
1293
|
+
const finish = React9.useCallback((controller) => active.current.delete(controller), []);
|
|
1294
|
+
const valid = React9.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
|
|
1295
|
+
const abortAll = React9.useCallback(() => {
|
|
1161
1296
|
nextId.current += 1;
|
|
1162
1297
|
active.current.forEach((c) => c.abort());
|
|
1163
1298
|
active.current.clear();
|
|
@@ -1169,73 +1304,79 @@ async function xlsxArtifact(draft, label) {
|
|
|
1169
1304
|
const XLSX = await import("xlsx");
|
|
1170
1305
|
const columns = draft.payload.columns.filter((c) => c.visible && c.exportable !== false && c.classification !== "secret" && c.classification !== "credential");
|
|
1171
1306
|
const cells = draft.payload.rows.map((row) => columns.map((column) => {
|
|
1172
|
-
const value = (0,
|
|
1307
|
+
const value = (0, import_content_transfer2.readTransferCell)(row, column);
|
|
1173
1308
|
return value === null || ["string", "number", "boolean"].includes(typeof value) ? value : value === void 0 ? "" : JSON.stringify(value);
|
|
1174
1309
|
}));
|
|
1175
1310
|
const sheet = XLSX.utils.aoa_to_sheet([columns.map((c) => c.label), ...cells]);
|
|
1176
1311
|
const book = XLSX.utils.book_new();
|
|
1177
1312
|
XLSX.utils.book_append_sheet(book, sheet, label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data");
|
|
1178
1313
|
const written = XLSX.write(book, { type: "array", bookType: "xlsx", compression: true });
|
|
1179
|
-
return (0,
|
|
1314
|
+
return (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "xlsx", plainText: (0, import_content_transfer2.serialize)(draft, "tsv", { spreadsheetSafe: true }).plainText, file: { filename: `${filenameFor(label)}.xlsx`, mime: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", bytes: written instanceof Uint8Array ? written : new Uint8Array(written) }, omissions: [...draft.omissions] });
|
|
1180
1315
|
}
|
|
1181
1316
|
async function buildArtifact(draft, format, label) {
|
|
1182
1317
|
if (!supportsBuiltIn(format, draft.payload)) throw new Error(`${LABEL[format]} is available for tabular content only.`);
|
|
1183
1318
|
if (format === "xlsx") return xlsxArtifact(draft, label);
|
|
1184
|
-
if (format === "html" && draft.payload.kind === "markdown") return (0,
|
|
1319
|
+
if (format === "html" && draft.payload.kind === "markdown") return (0, import_content_transfer2.serializeMarkdownRich)(draft, `${filenameFor(label)}.html`);
|
|
1185
1320
|
const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
|
|
1186
|
-
return (0,
|
|
1321
|
+
return (0, import_content_transfer2.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
1187
1322
|
}
|
|
1188
1323
|
function ContentTransferMenu(props) {
|
|
1189
|
-
const inherited =
|
|
1324
|
+
const inherited = React9.useContext(CapabilityContext);
|
|
1190
1325
|
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
1191
|
-
return /* @__PURE__ */ (0,
|
|
1326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
1192
1327
|
}
|
|
1193
|
-
function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, sourceFormats = true, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef, icon = "portal", triggerVariant = "transparent" }) {
|
|
1194
|
-
const triggerRef =
|
|
1195
|
-
const inherited =
|
|
1196
|
-
const nearestSurface =
|
|
1328
|
+
function ContentTransferMenuSession({ references = [], referenceActions = [], source, surface, label, projection, sections, preferences, table, formatSources, sourceFormats = true, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef, icon = "portal", triggerVariant = "transparent", triggerSize = "default" }) {
|
|
1329
|
+
const triggerRef = React9.useRef(null);
|
|
1330
|
+
const inherited = React9.useContext(CapabilityContext);
|
|
1331
|
+
const nearestSurface = React9.useContext(SurfaceContext);
|
|
1197
1332
|
const fence = useFence();
|
|
1198
|
-
const [menuCapture, setMenuCapture] =
|
|
1199
|
-
const [menuStatus, setMenuStatus] =
|
|
1200
|
-
const [workspaces, setWorkspaces] =
|
|
1201
|
-
const [workspaceKey, setWorkspaceKey] =
|
|
1202
|
-
const [workspaceOpen, setWorkspaceOpen] =
|
|
1203
|
-
const workspaceCaptures =
|
|
1204
|
-
const externalWorkspaceKeys =
|
|
1205
|
-
const [notice, setNotice] =
|
|
1206
|
-
const [receiptTarget, setReceiptTarget] =
|
|
1207
|
-
const [paletteOpen, setPaletteOpen] =
|
|
1208
|
-
const [mode, setMode] =
|
|
1209
|
-
const scopes =
|
|
1210
|
-
const
|
|
1333
|
+
const [menuCapture, setMenuCapture] = React9.useState(null);
|
|
1334
|
+
const [menuStatus, setMenuStatus] = React9.useState("idle");
|
|
1335
|
+
const [workspaces, setWorkspaces] = React9.useState({});
|
|
1336
|
+
const [workspaceKey, setWorkspaceKey] = React9.useState(null);
|
|
1337
|
+
const [workspaceOpen, setWorkspaceOpen] = React9.useState(false);
|
|
1338
|
+
const workspaceCaptures = React9.useRef(/* @__PURE__ */ new Map());
|
|
1339
|
+
const externalWorkspaceKeys = React9.useRef(/* @__PURE__ */ new Set());
|
|
1340
|
+
const [notice, setNotice] = React9.useState(null);
|
|
1341
|
+
const [receiptTarget, setReceiptTarget] = React9.useState();
|
|
1342
|
+
const [paletteOpen, setPaletteOpen] = React9.useState(false);
|
|
1343
|
+
const [mode, setMode] = React9.useState("copy");
|
|
1344
|
+
const scopes = React9.useMemo(() => table?.availableScopes ?? ["target"], [table]);
|
|
1345
|
+
const [requestedScope, setRequestedScope] = React9.useState(table?.initialScope ?? "target");
|
|
1346
|
+
const initialScope = scopes.includes(requestedScope) ? requestedScope : table?.initialScope ?? "target";
|
|
1211
1347
|
if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
|
|
1212
1348
|
const primary = surface ?? source ?? nearestSurface;
|
|
1213
1349
|
const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
|
|
1214
|
-
const
|
|
1350
|
+
const primaryWorkspaceBase = `primary:${materialIdentity(primary)}`;
|
|
1351
|
+
const primaryWorkspaceKey = `${primaryWorkspaceBase}:${initialScope}`;
|
|
1215
1352
|
const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
|
|
1216
|
-
const variantWorkspaceKeys =
|
|
1217
|
-
const transport = local?.transport ?? inherited.transport ?? (0,
|
|
1353
|
+
const variantWorkspaceKeys = React9.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
|
|
1354
|
+
const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer2.createBrowserTransport)();
|
|
1218
1355
|
const ai = local?.ai ?? inherited.ai;
|
|
1219
|
-
const
|
|
1220
|
-
const
|
|
1221
|
-
const
|
|
1222
|
-
|
|
1223
|
-
const
|
|
1356
|
+
const referencePort = local?.reference ?? inherited.reference;
|
|
1357
|
+
const { email: emailPort, review: emailReview } = useReviewedTransferEmail(local?.email ?? inherited.email);
|
|
1358
|
+
const providerPreferences = React9.useMemo(() => (0, import_content_transfer2.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
|
|
1359
|
+
const adapters = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
|
|
1360
|
+
const emailJsonFormat = adapters.find((adapter) => adapter.id === "table-data");
|
|
1361
|
+
const emailActions = React9.useMemo(() => emailPort ? createTransferEmailActions(emailPort, emailJsonFormat ? { jsonFormat: emailJsonFormat } : {}) : [], [emailPort, emailJsonFormat]);
|
|
1362
|
+
const registeredActions = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(emailActions, inherited.actions ?? [], local?.actions ?? [], actions), [actions, emailActions, inherited.actions, local?.actions]);
|
|
1363
|
+
React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(variants), [variants]);
|
|
1364
|
+
const report = React9.useCallback((result) => {
|
|
1224
1365
|
inherited.onOutcome?.(result);
|
|
1225
1366
|
local?.onOutcome?.(result);
|
|
1226
1367
|
setNotice(outcomeMessage(result));
|
|
1227
1368
|
setReceiptTarget("target" in result ? result.target : void 0);
|
|
1228
1369
|
}, [inherited, local]);
|
|
1229
|
-
|
|
1230
|
-
const valid = /* @__PURE__ */ new Set([
|
|
1370
|
+
React9.useEffect(() => {
|
|
1371
|
+
const valid = /* @__PURE__ */ new Set([...scopes.map((scope) => `${primaryWorkspaceBase}:${scope}`), ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
|
|
1231
1372
|
setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
|
|
1232
1373
|
for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
|
|
1233
1374
|
if (workspaceKey && !valid.has(workspaceKey)) {
|
|
1234
1375
|
setWorkspaceKey(null);
|
|
1235
1376
|
setWorkspaceOpen(false);
|
|
1236
1377
|
}
|
|
1237
|
-
}, [nearestWorkspaceKey,
|
|
1238
|
-
const captureOne =
|
|
1378
|
+
}, [nearestWorkspaceKey, primaryWorkspaceBase, scopes, variantWorkspaceKeys, workspaceKey]);
|
|
1379
|
+
const captureOne = React9.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
|
|
1239
1380
|
if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
|
|
1240
1381
|
let sourceMaterial;
|
|
1241
1382
|
if ("instanceId" in material) {
|
|
@@ -1243,7 +1384,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1243
1384
|
const captured = await material.capture(signal);
|
|
1244
1385
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
1245
1386
|
} else if ("kind" in material) {
|
|
1246
|
-
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0,
|
|
1387
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0, import_content_transfer2.directSource)(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
1247
1388
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
1248
1389
|
sourceMaterial = {
|
|
1249
1390
|
id: material.id,
|
|
@@ -1261,27 +1402,27 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1261
1402
|
sourceMaterial = material;
|
|
1262
1403
|
}
|
|
1263
1404
|
const raw = await sourceMaterial.capture({ scope, signal });
|
|
1264
|
-
const constrained = (0,
|
|
1265
|
-
const result = await (0,
|
|
1405
|
+
const constrained = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
|
|
1406
|
+
const result = await (0, import_content_transfer2.capture)({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
1266
1407
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
1267
1408
|
if (!result.allMatching) throw new Error("This source cannot provide a stable all-matching export.");
|
|
1268
|
-
const collected = await (0,
|
|
1409
|
+
const collected = await (0, import_content_transfer2.collectAllMatching)(result.allMatching, signal);
|
|
1269
1410
|
if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
|
|
1270
|
-
return { snapshot: (0,
|
|
1411
|
+
return { snapshot: (0, import_content_transfer2.projectSnapshot)({ ...result.snapshot, payload: { kind: "rows", rows: collected.rows, columns: result.snapshot.payload.columns }, coverage: collected.coverage, omissions: [...collected.omissions] }, { rules: [] }), allMatching: result.allMatching, ...collected.error ? { collectionError: collected.error.message } : {} };
|
|
1271
1412
|
}, [preferences, projection, providerPreferences, sections, sourceLabel]);
|
|
1272
|
-
const capturePrimary =
|
|
1413
|
+
const capturePrimary = React9.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
|
|
1273
1414
|
workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
|
|
1274
1415
|
if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
|
|
1275
1416
|
for (const variant of variants) {
|
|
1276
1417
|
const key = variantWorkspaceKeys.get(variant.id);
|
|
1277
1418
|
workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
|
|
1278
1419
|
}
|
|
1279
|
-
const preflight =
|
|
1420
|
+
const preflight = React9.useCallback(async (scope = initialScope) => {
|
|
1280
1421
|
const { controller, id } = fence.begin();
|
|
1281
1422
|
setMenuCapture(null);
|
|
1282
1423
|
setMenuStatus("loading");
|
|
1283
1424
|
try {
|
|
1284
|
-
const result = await captureOne(primary,
|
|
1425
|
+
const result = await captureOne(primary, scope, controller.signal, true, false);
|
|
1285
1426
|
if (fence.valid(id, controller)) {
|
|
1286
1427
|
setMenuCapture(result);
|
|
1287
1428
|
setMenuStatus("idle");
|
|
@@ -1295,7 +1436,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1295
1436
|
fence.finish(controller);
|
|
1296
1437
|
}
|
|
1297
1438
|
}, [captureOne, fence, initialScope, primary]);
|
|
1298
|
-
const transfer =
|
|
1439
|
+
const transfer = React9.useCallback(async (format, download, alternate) => {
|
|
1299
1440
|
const { controller, id } = fence.begin();
|
|
1300
1441
|
try {
|
|
1301
1442
|
const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
|
|
@@ -1305,8 +1446,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1305
1446
|
const reason = result.snapshot.coverage.reason ?? `${result.snapshot.omissions.length} omission${result.snapshot.omissions.length === 1 ? "" : "s"}`;
|
|
1306
1447
|
throw new Error(`Quick transfer is partial (${reason}). Open Prepare for AI to review it before delivery.`);
|
|
1307
1448
|
}
|
|
1308
|
-
const resolved = (0,
|
|
1309
|
-
const draft = (0,
|
|
1449
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, result.snapshot.limits);
|
|
1450
|
+
const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(result.snapshot), resolved.limits);
|
|
1310
1451
|
const revision = draft.revision;
|
|
1311
1452
|
if (draft.omissions.length > result.snapshot.omissions.length) throw new Error("Quick transfer requires content reductions. Open Prepare for AI to review them before delivery.");
|
|
1312
1453
|
const artifact = typeof format === "string" ? await buildArtifact(draft, format, result.snapshot.label) : await format.build(draft, controller.signal);
|
|
@@ -1320,12 +1461,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1320
1461
|
fence.finish(controller);
|
|
1321
1462
|
}
|
|
1322
1463
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
1323
|
-
const openWorkspace =
|
|
1464
|
+
const openWorkspace = React9.useCallback(
|
|
1324
1465
|
async (key = primaryWorkspaceKey, variant) => {
|
|
1325
1466
|
const variantMaterial = variant && "kind" in variant.source ? {
|
|
1326
1467
|
id: `variant:${key}`,
|
|
1327
1468
|
label: variant.label,
|
|
1328
|
-
capture: async () => (0,
|
|
1469
|
+
capture: async () => (0, import_content_transfer2.directSource)(variant.source, {
|
|
1329
1470
|
sourceId: `variant:${key}`,
|
|
1330
1471
|
label: variant.label
|
|
1331
1472
|
})
|
|
@@ -1336,15 +1477,16 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1336
1477
|
const { controller, id } = fence.begin();
|
|
1337
1478
|
if (existing) {
|
|
1338
1479
|
try {
|
|
1339
|
-
const
|
|
1480
|
+
const scopeChanged = existing.scope !== initialScope;
|
|
1481
|
+
const allMatching = initialScope === "all-matching";
|
|
1340
1482
|
const fresh = await captureWorkspace(
|
|
1341
|
-
|
|
1483
|
+
initialScope,
|
|
1342
1484
|
controller.signal,
|
|
1343
|
-
!allMatching
|
|
1485
|
+
scopeChanged || !allMatching
|
|
1344
1486
|
);
|
|
1345
1487
|
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
1346
1488
|
return;
|
|
1347
|
-
if (allMatching && (!
|
|
1489
|
+
if (allMatching && (!fresh.allMatching || !scopeChanged && !existing.allMatching))
|
|
1348
1490
|
throw new Error(
|
|
1349
1491
|
"This source can no longer provide an all-matching snapshot."
|
|
1350
1492
|
);
|
|
@@ -1354,7 +1496,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1354
1496
|
columns: value.columns,
|
|
1355
1497
|
limits: value.limits
|
|
1356
1498
|
};
|
|
1357
|
-
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
1499
|
+
const changed = scopeChanged || (allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot));
|
|
1358
1500
|
setWorkspaces((current) => {
|
|
1359
1501
|
const retained = current[key];
|
|
1360
1502
|
if (!retained) return current;
|
|
@@ -1363,7 +1505,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1363
1505
|
[key]: {
|
|
1364
1506
|
...retained,
|
|
1365
1507
|
error: fresh.collectionError,
|
|
1366
|
-
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope:
|
|
1508
|
+
...allMatching && !scopeChanged ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: initialScope } } : { pending: void 0 }
|
|
1367
1509
|
}
|
|
1368
1510
|
};
|
|
1369
1511
|
});
|
|
@@ -1391,12 +1533,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1391
1533
|
try {
|
|
1392
1534
|
const result = await captureWorkspace(initialScope, controller.signal);
|
|
1393
1535
|
if (!fence.valid(id, controller)) return;
|
|
1394
|
-
const resolved = (0,
|
|
1536
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(
|
|
1395
1537
|
providerPreferences,
|
|
1396
1538
|
preferences,
|
|
1397
1539
|
result.snapshot.limits
|
|
1398
1540
|
);
|
|
1399
|
-
const original = (0,
|
|
1541
|
+
const original = (0, import_content_transfer2.createDraft)(result.snapshot);
|
|
1400
1542
|
const base = {
|
|
1401
1543
|
...result,
|
|
1402
1544
|
key,
|
|
@@ -1432,7 +1574,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1432
1574
|
workspaces
|
|
1433
1575
|
]
|
|
1434
1576
|
);
|
|
1435
|
-
|
|
1577
|
+
React9.useImperativeHandle(controllerRef, () => ({
|
|
1436
1578
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
1437
1579
|
prepare: async (requestedSource, options) => {
|
|
1438
1580
|
const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
|
|
@@ -1441,13 +1583,13 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1441
1583
|
await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
|
|
1442
1584
|
}
|
|
1443
1585
|
}), [openWorkspace]);
|
|
1444
|
-
const runAction =
|
|
1586
|
+
const runAction = React9.useCallback(async (action) => {
|
|
1445
1587
|
const { controller, id } = fence.begin();
|
|
1446
1588
|
try {
|
|
1447
1589
|
const actionSource = action.source;
|
|
1448
1590
|
const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
|
|
1449
|
-
const resolved = (0,
|
|
1450
|
-
const draft = (0,
|
|
1591
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
|
|
1592
|
+
const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(snapshot), resolved.limits);
|
|
1451
1593
|
if (snapshot.coverage.status !== "complete" || draft.omissions.length) throw new Error("This content is partial or requires reductions. Open Prepare for AI to review it before sending it to a destination.");
|
|
1452
1594
|
if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
|
|
1453
1595
|
const result = await action.run({ snapshot, draft, signal: controller.signal });
|
|
@@ -1458,13 +1600,38 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1458
1600
|
fence.finish(controller);
|
|
1459
1601
|
}
|
|
1460
1602
|
}, [captureOne, capturePrimary, fence, initialScope, preferences, providerPreferences, report]);
|
|
1603
|
+
const copyReference = async (reference) => {
|
|
1604
|
+
const { controller, id } = fence.begin();
|
|
1605
|
+
closePalette();
|
|
1606
|
+
try {
|
|
1607
|
+
if (!referencePort?.supports(reference)) throw new Error("This reference is not registered or its identity is incomplete.");
|
|
1608
|
+
const text = await referencePort.build(reference);
|
|
1609
|
+
if (!text.trim()) throw new Error("The reference serializer returned no content.");
|
|
1610
|
+
const artifact = (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: `reference:${reference.id}`, draftRevision: 0, format: "matrx-reference", plainText: text, omissions: [] });
|
|
1611
|
+
if (!fence.valid(id, controller)) return;
|
|
1612
|
+
const outcome = await transport.copy(artifact, controller.signal);
|
|
1613
|
+
if (fence.valid(id, controller)) report(outcome);
|
|
1614
|
+
} catch (error) {
|
|
1615
|
+
if (fence.valid(id, controller)) report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not copy reference"), retryable: true });
|
|
1616
|
+
} finally {
|
|
1617
|
+
fence.finish(controller);
|
|
1618
|
+
}
|
|
1619
|
+
};
|
|
1620
|
+
const openReference = async (action) => {
|
|
1621
|
+
closePalette();
|
|
1622
|
+
try {
|
|
1623
|
+
await action.run();
|
|
1624
|
+
} catch (error) {
|
|
1625
|
+
report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not open reference picker"), retryable: true });
|
|
1626
|
+
}
|
|
1627
|
+
};
|
|
1461
1628
|
if (!enabled) return null;
|
|
1462
1629
|
const payload = menuCapture?.snapshot.payload ?? (source && "kind" in source ? source : void 0);
|
|
1463
1630
|
const quickVariants = (section) => variants.filter((v) => v.copyLabel && (v.section ?? "ai") === section);
|
|
1464
1631
|
const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
|
|
1465
1632
|
const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
|
|
1466
1633
|
const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
|
|
1467
|
-
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0,
|
|
1634
|
+
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(menuCapture.snapshot), (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
|
|
1468
1635
|
const downloadActions = visibleActions.filter((action) => action.placement === "download");
|
|
1469
1636
|
const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
|
|
1470
1637
|
const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
|
|
@@ -1477,8 +1644,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1477
1644
|
label: "AI context",
|
|
1478
1645
|
supports: () => true,
|
|
1479
1646
|
build: async (draft) => {
|
|
1480
|
-
const json = (0,
|
|
1481
|
-
return (0,
|
|
1647
|
+
const json = (0, import_content_transfer2.serialize)(draft, "json");
|
|
1648
|
+
return (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer2.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
|
|
1482
1649
|
}
|
|
1483
1650
|
};
|
|
1484
1651
|
const closePalette = () => setPaletteOpen(false);
|
|
@@ -1486,106 +1653,123 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1486
1653
|
const presentation = options.action;
|
|
1487
1654
|
const Icon2 = presentation?.icon;
|
|
1488
1655
|
const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
|
|
1489
|
-
return /* @__PURE__ */ (0,
|
|
1656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
|
|
1490
1657
|
closePalette();
|
|
1491
1658
|
onClick();
|
|
1492
1659
|
}, children: [
|
|
1493
|
-
Icon2 ? /* @__PURE__ */ (0,
|
|
1494
|
-
/* @__PURE__ */ (0,
|
|
1660
|
+
Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
|
|
1661
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1495
1662
|
label2,
|
|
1496
|
-
presentation?.hint ? /* @__PURE__ */ (0,
|
|
1663
|
+
presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
|
|
1497
1664
|
] })
|
|
1498
1665
|
] }, id);
|
|
1499
1666
|
};
|
|
1500
|
-
return /* @__PURE__ */ (0,
|
|
1501
|
-
/* @__PURE__ */ (0,
|
|
1667
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
|
|
1502
1669
|
setPaletteOpen(open);
|
|
1503
1670
|
if (open) {
|
|
1504
1671
|
setMode("copy");
|
|
1505
1672
|
void preflight();
|
|
1506
1673
|
}
|
|
1507
1674
|
}, children: [
|
|
1508
|
-
/* @__PURE__ */ (0,
|
|
1509
|
-
/* @__PURE__ */ (0,
|
|
1510
|
-
menuStatus === "loading" ? /* @__PURE__ */ (0,
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { ref: triggerRef, variant: "outline", size: "icon-sm", "aria-label": `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "outline", disabled, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }) }) : triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", "data-alchemy-size": triggerSize, disabled }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", "data-alchemy-size": triggerSize, disabled }) }),
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
|
|
1677
|
+
menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
|
|
1678
|
+
table && scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "matrx-alchemy-scope", children: [
|
|
1679
|
+
"Content scope",
|
|
1680
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
|
|
1681
|
+
const next = scopes.find((scope) => scope === event.target.value);
|
|
1682
|
+
if (next) {
|
|
1683
|
+
setRequestedScope(next);
|
|
1684
|
+
void preflight(next);
|
|
1685
|
+
}
|
|
1686
|
+
}, children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
|
|
1687
|
+
] }) : null,
|
|
1688
|
+
copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-output", children: [
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
|
|
1690
|
+
copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
|
|
1691
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
|
|
1692
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
|
|
1516
1693
|
] }) : null,
|
|
1517
|
-
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0,
|
|
1518
|
-
/* @__PURE__ */ (0,
|
|
1694
|
+
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1695
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
1519
1696
|
visibleCopies.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets" }[format], () => void transfer(format, false), { ariaLabel: `Copy ${LABEL[format]}` })),
|
|
1520
1697
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
|
|
1521
1698
|
] }),
|
|
1522
|
-
quickVariants("copy").length ? /* @__PURE__ */ (0,
|
|
1699
|
+
quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
|
|
1523
1700
|
closePalette();
|
|
1524
1701
|
void transfer("markdown", false, variant);
|
|
1525
1702
|
} }) : null
|
|
1526
1703
|
] }) : null,
|
|
1527
|
-
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0,
|
|
1704
|
+
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
1528
1705
|
visibleDownloads.map((format) => tile(format, { plain: "Text", markdown: "Markdown", html: "Formatted", json: "JSON", "compact-json": "Compact", csv: "CSV", tsv: "Sheets", xlsx: "Excel" }[format], () => void transfer(format, true), { ariaLabel: `Download ${LABEL[format]}` })),
|
|
1529
1706
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
|
|
1530
1707
|
downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
|
|
1531
1708
|
] }) }) : null
|
|
1532
1709
|
] }) : null,
|
|
1533
|
-
prepareAvailable ? /* @__PURE__ */ (0,
|
|
1534
|
-
/* @__PURE__ */ (0,
|
|
1710
|
+
prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1711
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
1535
1712
|
closePalette();
|
|
1536
1713
|
void transfer(nativeAiFormat, false);
|
|
1537
1714
|
}, children: [
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1539
|
-
/* @__PURE__ */ (0,
|
|
1715
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "ai-copy" }),
|
|
1716
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1540
1717
|
"Copy with AI context",
|
|
1541
|
-
/* @__PURE__ */ (0,
|
|
1718
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
|
|
1542
1719
|
] })
|
|
1543
1720
|
] }) : null, items: quickVariants("ai"), onRun: (variant) => {
|
|
1544
1721
|
closePalette();
|
|
1545
1722
|
void transfer("markdown", false, variant);
|
|
1546
1723
|
} }),
|
|
1547
|
-
/* @__PURE__ */ (0,
|
|
1724
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
|
|
1548
1725
|
closePalette();
|
|
1549
1726
|
void openWorkspace();
|
|
1550
1727
|
}, children: [
|
|
1551
|
-
/* @__PURE__ */ (0,
|
|
1552
|
-
/* @__PURE__ */ (0,
|
|
1728
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteGlyph, { kind: "sliders" }),
|
|
1729
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1553
1730
|
"Prepare for AI",
|
|
1554
|
-
/* @__PURE__ */ (0,
|
|
1731
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
|
|
1555
1732
|
] })
|
|
1556
1733
|
] }) })
|
|
1557
1734
|
] }) : null,
|
|
1558
|
-
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0,
|
|
1559
|
-
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0,
|
|
1735
|
+
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1736
|
+
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
1560
1737
|
closePalette();
|
|
1561
1738
|
void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
|
|
1562
|
-
}, children: /* @__PURE__ */ (0,
|
|
1563
|
-
variants.map((variant) => /* @__PURE__ */ (0,
|
|
1739
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Prepare this surface" }) }) : null,
|
|
1740
|
+
variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
|
|
1564
1741
|
closePalette();
|
|
1565
1742
|
void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
|
|
1566
|
-
}, children: /* @__PURE__ */ (0,
|
|
1743
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
|
|
1567
1744
|
] }) }) : null,
|
|
1568
|
-
|
|
1745
|
+
references.length || referenceActions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { children: "Live references" }),
|
|
1747
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-menu-hint", children: "Pointers to saved data, independent of filters and edits." }),
|
|
1748
|
+
references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void copyReference(reference), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: reference.label }) }, reference.id)),
|
|
1749
|
+
referenceActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: action.label }) }, action.id))
|
|
1750
|
+
] }) : null,
|
|
1751
|
+
["save", "chat", "email", "other"].map((group) => {
|
|
1569
1752
|
const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
|
|
1570
|
-
return entries.length ? /* @__PURE__ */ (0,
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1572
|
-
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
|
|
1573
|
-
/* @__PURE__ */ (0,
|
|
1753
|
+
return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
|
|
1754
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
1755
|
+
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
|
|
1756
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: entries.length })
|
|
1574
1757
|
] }),
|
|
1575
|
-
/* @__PURE__ */ (0,
|
|
1758
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
|
|
1576
1759
|
closePalette();
|
|
1577
1760
|
void runAction(action);
|
|
1578
|
-
}, children: /* @__PURE__ */ (0,
|
|
1761
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DestinationPresentation, { action }) }, action.id)) })
|
|
1579
1762
|
] }, group) : null;
|
|
1580
1763
|
})
|
|
1581
1764
|
] })
|
|
1582
1765
|
] }),
|
|
1583
|
-
notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0,
|
|
1584
|
-
/* @__PURE__ */ (0,
|
|
1585
|
-
/* @__PURE__ */ (0,
|
|
1586
|
-
/* @__PURE__ */ (0,
|
|
1766
|
+
notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { role: "status", children: notice }),
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ReceiptLink, { target: receiptTarget }),
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
|
|
1587
1770
|
] }), triggerRef.current.ownerDocument.body) : null,
|
|
1588
|
-
Object.values(workspaces).map((saved) => /* @__PURE__ */ (0,
|
|
1771
|
+
Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PreparationWorkspace, { restoreFocus: () => triggerRef.current?.focus(), open: workspaceOpen && workspaceKey === saved.key, state: saved, scopes, scopeLabels: table?.scopeLabels, onClose: () => setWorkspaceOpen(false), onChange: (next) => setWorkspaces((current) => ({ ...current, [saved.key]: next })), transport, adapters, actions: preparedActions, captureScope: workspaceCaptures.current.get(saved.key) ?? capturePrimary, ...ai ? { ai } : {}, onOutcome: report }, saved.key)),
|
|
1772
|
+
emailReview
|
|
1589
1773
|
] });
|
|
1590
1774
|
}
|
|
1591
1775
|
function initialControls(state) {
|
|
@@ -1613,9 +1797,9 @@ function presetLimits(preset, controls, preferences) {
|
|
|
1613
1797
|
return { ...preferences.limits, maxDepth: min(request.maxDepth, preferences.limits.maxDepth), maxStringChars: min(request.maxStringChars, preferences.limits.maxStringChars), maxArrayItems: min(request.maxArrayItems, preferences.limits.maxArrayItems ?? null) };
|
|
1614
1798
|
}
|
|
1615
1799
|
function rebuild(state, controls) {
|
|
1616
|
-
let draft = (0,
|
|
1617
|
-
if (state.snapshot.sections.length) draft = (0,
|
|
1618
|
-
if (draft.payload.kind === "rows") draft = (0,
|
|
1800
|
+
let draft = (0, import_content_transfer2.resetDraft)(state.snapshot);
|
|
1801
|
+
if (state.snapshot.sections.length) draft = (0, import_content_transfer2.applySectionSelection)(draft, state.snapshot, controls.sections);
|
|
1802
|
+
if (draft.payload.kind === "rows") draft = (0, import_content_transfer2.transformRows)(draft, {
|
|
1619
1803
|
search: controls.search,
|
|
1620
1804
|
filters: controls.filters,
|
|
1621
1805
|
...controls.sort ? { sort: { column: controls.sort, direction: controls.direction } } : {},
|
|
@@ -1626,45 +1810,45 @@ function rebuild(state, controls) {
|
|
|
1626
1810
|
});
|
|
1627
1811
|
const limits = presetLimits(controls.preset, controls, state.preferences);
|
|
1628
1812
|
if (draft.payload.kind === "json" || draft.payload.kind === "registered") {
|
|
1629
|
-
draft = (0,
|
|
1813
|
+
draft = (0, import_content_transfer2.reduceJson)(draft, { maxDepth: limits.maxDepth, maxStringChars: limits.maxStringChars, maxArrayItems: limits.maxArrayItems ?? null });
|
|
1630
1814
|
}
|
|
1631
|
-
return (0,
|
|
1815
|
+
return (0, import_content_transfer2.applyTransferLimits)(draft, limits);
|
|
1632
1816
|
}
|
|
1633
1817
|
function isBuiltInFormat(format) {
|
|
1634
1818
|
return format in LABEL;
|
|
1635
1819
|
}
|
|
1636
1820
|
function preview(draft, format) {
|
|
1637
1821
|
const resolved = isBuiltInFormat(format) ? format : "plain";
|
|
1638
|
-
return (0,
|
|
1822
|
+
return (0, import_content_transfer2.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
|
|
1639
1823
|
}
|
|
1640
|
-
function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
1824
|
+
function PreparationWorkspace({ restoreFocus, open, state, scopes, scopeLabels, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
1641
1825
|
const fence = useFence();
|
|
1642
|
-
const latest =
|
|
1826
|
+
const latest = React9.useRef(state);
|
|
1643
1827
|
latest.current = state;
|
|
1644
|
-
const aiSession =
|
|
1828
|
+
const aiSession = React9.useRef(void 0);
|
|
1645
1829
|
if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
|
|
1646
|
-
const [controls, setControls] =
|
|
1647
|
-
const [controlsHistory, setControlsHistory] =
|
|
1648
|
-
const [pendingControls, setPendingControls] =
|
|
1830
|
+
const [controls, setControls] = React9.useState(() => initialControls(state));
|
|
1831
|
+
const [controlsHistory, setControlsHistory] = React9.useState([]);
|
|
1832
|
+
const [pendingControls, setPendingControls] = React9.useState(null);
|
|
1649
1833
|
const requestedFormat = state.preferences.initialFormat;
|
|
1650
|
-
const [format, setFormat] =
|
|
1651
|
-
const [buffer, setBuffer] =
|
|
1652
|
-
const [bufferError, setBufferError] =
|
|
1653
|
-
const [formatError, setFormatError] =
|
|
1654
|
-
const [preparedArtifact, setPreparedArtifact] =
|
|
1655
|
-
const [instruction, setInstruction] =
|
|
1656
|
-
const [busy, setBusy] =
|
|
1657
|
-
const [aiFailed, setAiFailed] =
|
|
1658
|
-
|
|
1834
|
+
const [format, setFormat] = React9.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
|
|
1835
|
+
const [buffer, setBuffer] = React9.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
|
|
1836
|
+
const [bufferError, setBufferError] = React9.useState(null);
|
|
1837
|
+
const [formatError, setFormatError] = React9.useState(null);
|
|
1838
|
+
const [preparedArtifact, setPreparedArtifact] = React9.useState(null);
|
|
1839
|
+
const [instruction, setInstruction] = React9.useState("");
|
|
1840
|
+
const [busy, setBusy] = React9.useState(null);
|
|
1841
|
+
const [aiFailed, setAiFailed] = React9.useState(false);
|
|
1842
|
+
React9.useEffect(() => {
|
|
1659
1843
|
setAiFailed(false);
|
|
1660
1844
|
}, [state.snapshot.id, state.draft.revision]);
|
|
1661
|
-
const handingOff =
|
|
1662
|
-
|
|
1845
|
+
const handingOff = React9.useRef(false);
|
|
1846
|
+
React9.useEffect(() => {
|
|
1663
1847
|
if (open) handingOff.current = false;
|
|
1664
1848
|
}, [open]);
|
|
1665
|
-
const activeAi =
|
|
1666
|
-
const activeCapture =
|
|
1667
|
-
|
|
1849
|
+
const activeAi = React9.useRef(null);
|
|
1850
|
+
const activeCapture = React9.useRef(null);
|
|
1851
|
+
React9.useEffect(() => {
|
|
1668
1852
|
if (bufferError) return;
|
|
1669
1853
|
const adapter = adapters.find((candidate) => candidate.id === format);
|
|
1670
1854
|
const controller = new AbortController();
|
|
@@ -1684,7 +1868,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1684
1868
|
});
|
|
1685
1869
|
return () => controller.abort();
|
|
1686
1870
|
}, [adapters, bufferError, format, state.draft, state.snapshot.id]);
|
|
1687
|
-
const close =
|
|
1871
|
+
const close = React9.useCallback(() => {
|
|
1688
1872
|
activeAi.current?.abort();
|
|
1689
1873
|
activeCapture.current?.abort();
|
|
1690
1874
|
activeAi.current = null;
|
|
@@ -1720,7 +1904,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1720
1904
|
const value = JSON.parse(text);
|
|
1721
1905
|
const next = payload.kind === "json" ? { kind: "json", value } : { kind: "registered", format: payload.format, value };
|
|
1722
1906
|
setBufferError(null);
|
|
1723
|
-
onChange({ ...state, draft: (0,
|
|
1907
|
+
onChange({ ...state, draft: (0, import_content_transfer2.editDraft)(state.draft, next), error: void 0 });
|
|
1724
1908
|
} catch {
|
|
1725
1909
|
setBufferError("JSON is incomplete or invalid. Fix it before copying or downloading.");
|
|
1726
1910
|
}
|
|
@@ -1729,7 +1913,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1729
1913
|
setBufferError(null);
|
|
1730
1914
|
const kind = payload.kind === "markdown" || format === "markdown" ? "markdown" : "text";
|
|
1731
1915
|
if (payload.kind === "rows" || !isBuiltInFormat(format)) setFormat("plain");
|
|
1732
|
-
onChange({ ...state, draft: (0,
|
|
1916
|
+
onChange({ ...state, draft: (0, import_content_transfer2.editDraft)(state.draft, { kind, text }), error: void 0 });
|
|
1733
1917
|
};
|
|
1734
1918
|
const requestCapture = async (scope) => {
|
|
1735
1919
|
activeCapture.current?.abort();
|
|
@@ -1756,8 +1940,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1756
1940
|
return;
|
|
1757
1941
|
}
|
|
1758
1942
|
const pending = state.pending;
|
|
1759
|
-
const preferences = (0,
|
|
1760
|
-
const base = { ...pending, key: state.key, original: (0,
|
|
1943
|
+
const preferences = (0, import_content_transfer2.resolveTransferPreferences)({}, state.preferences, pending.snapshot.limits);
|
|
1944
|
+
const base = { ...pending, key: state.key, original: (0, import_content_transfer2.createDraft)(pending.snapshot), draft: (0, import_content_transfer2.createDraft)(pending.snapshot), scope: pending.scope, preferences, ...pending.collectionError ? { error: pending.collectionError } : {} };
|
|
1761
1945
|
const nextControls = initialControls(base);
|
|
1762
1946
|
setControls(nextControls);
|
|
1763
1947
|
setControlsHistory([]);
|
|
@@ -1780,7 +1964,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1780
1964
|
const current = latest.current;
|
|
1781
1965
|
if (!fence.valid(id, controller) || current.snapshot.id !== snapshotId || current.draft.revision !== revision || next.snapshotId !== snapshotId || next.sourceId !== state.draft.sourceId || next.sourceRevision !== state.draft.sourceRevision || next.revision <= revision) return;
|
|
1782
1966
|
try {
|
|
1783
|
-
(0,
|
|
1967
|
+
(0, import_content_transfer2.serialize)(next, "plain");
|
|
1784
1968
|
} catch {
|
|
1785
1969
|
onChange({ ...current, error: "AI returned an invalid transfer draft." });
|
|
1786
1970
|
setAiFailed(true);
|
|
@@ -1813,8 +1997,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1813
1997
|
if (fence.valid(id, controller)) setBusy(null);
|
|
1814
1998
|
}
|
|
1815
1999
|
};
|
|
1816
|
-
const [deliveryNotice, setDeliveryNotice] =
|
|
1817
|
-
|
|
2000
|
+
const [deliveryNotice, setDeliveryNotice] = React9.useState(null);
|
|
2001
|
+
React9.useEffect(() => {
|
|
1818
2002
|
setDeliveryNotice(null);
|
|
1819
2003
|
}, [state.draft.revision]);
|
|
1820
2004
|
const reportDelivery = (outcome) => {
|
|
@@ -1865,49 +2049,49 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1865
2049
|
const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
|
|
1866
2050
|
const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
|
|
1867
2051
|
const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${(0, import_format.formatCount)(Number(value))}`).join(" \xB7 ");
|
|
1868
|
-
return /* @__PURE__ */ (0,
|
|
2052
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Dialog, { open, onOpenChange: (next) => {
|
|
1869
2053
|
if (!next) close();
|
|
1870
|
-
}, children: /* @__PURE__ */ (0,
|
|
2054
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
|
|
1871
2055
|
event.preventDefault();
|
|
1872
2056
|
if (!handingOff.current) restoreFocus();
|
|
1873
2057
|
}, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
|
|
1874
|
-
/* @__PURE__ */ (0,
|
|
1875
|
-
/* @__PURE__ */ (0,
|
|
2058
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
|
|
2059
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogTitle, { children: [
|
|
1876
2060
|
"Prepare ",
|
|
1877
2061
|
state.snapshot.label
|
|
1878
2062
|
] }),
|
|
1879
|
-
/* @__PURE__ */ (0,
|
|
2063
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogDescription, { children: [
|
|
1880
2064
|
state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
|
|
1881
2065
|
"Review and edit this copy. Your original stays unchanged."
|
|
1882
2066
|
] })
|
|
1883
2067
|
] }),
|
|
1884
|
-
/* @__PURE__ */ (0,
|
|
1885
|
-
/* @__PURE__ */ (0,
|
|
1886
|
-
/* @__PURE__ */ (0,
|
|
1887
|
-
/* @__PURE__ */ (0,
|
|
1888
|
-
scopes.length > 1 ? /* @__PURE__ */ (0,
|
|
2068
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { className: "matrx-alchemy-main", children: [
|
|
2071
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2072
|
+
scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
1889
2073
|
"Scope",
|
|
1890
|
-
/* @__PURE__ */ (0,
|
|
2074
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("select", { "aria-label": "Transfer scope", value: state.scope, disabled: busy !== null, onChange: (e) => void requestCapture(e.target.value), children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: scope, children: scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
|
|
1891
2075
|
] }) : null,
|
|
1892
|
-
/* @__PURE__ */ (0,
|
|
2076
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
1893
2077
|
"Detail",
|
|
1894
|
-
/* @__PURE__ */ (0,
|
|
1895
|
-
/* @__PURE__ */ (0,
|
|
1896
|
-
/* @__PURE__ */ (0,
|
|
1897
|
-
/* @__PURE__ */ (0,
|
|
1898
|
-
/* @__PURE__ */ (0,
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "full", children: "Full" }),
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "compact", children: "Compact" }),
|
|
2081
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "brief", children: "Brief" }),
|
|
2082
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "custom", children: "Custom" })
|
|
1899
2083
|
] })
|
|
1900
2084
|
] }),
|
|
1901
|
-
/* @__PURE__ */ (0,
|
|
2085
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
|
|
1902
2086
|
setBufferError(null);
|
|
1903
2087
|
if (controlsHistory.length) {
|
|
1904
2088
|
const next = controlsHistory[controlsHistory.length - 1];
|
|
1905
2089
|
setControls(next);
|
|
1906
2090
|
setControlsHistory((history) => history.slice(0, -1));
|
|
1907
2091
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
1908
|
-
} else onChange({ ...state, draft: (0,
|
|
2092
|
+
} else onChange({ ...state, draft: (0, import_content_transfer2.undoDraft)(state.draft), error: void 0 });
|
|
1909
2093
|
}, children: "Undo" }),
|
|
1910
|
-
/* @__PURE__ */ (0,
|
|
2094
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
|
|
1911
2095
|
const next = initialControls(state);
|
|
1912
2096
|
setControls(next);
|
|
1913
2097
|
setControlsHistory([]);
|
|
@@ -1915,64 +2099,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1915
2099
|
setBufferError(null);
|
|
1916
2100
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
1917
2101
|
}, children: "Reset" }),
|
|
1918
|
-
/* @__PURE__ */ (0,
|
|
2102
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
|
|
1919
2103
|
] }),
|
|
1920
|
-
controls.preset === "custom" ? /* @__PURE__ */ (0,
|
|
1921
|
-
/* @__PURE__ */ (0,
|
|
1922
|
-
[["maxDepth", "Maximum depth"], ["maxStringChars", state.draft.payload.kind === "rows" ? "Maximum characters per cell" : "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].filter(([key]) => key === "maxStringChars" || state.draft.payload.kind === "json" || state.draft.payload.kind === "registered").map(([key, text]) => /* @__PURE__ */ (0,
|
|
2104
|
+
controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
|
|
2105
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
|
|
2106
|
+
[["maxDepth", "Maximum depth"], ["maxStringChars", state.draft.payload.kind === "rows" ? "Maximum characters per cell" : "Maximum string characters"], ["maxArrayItems", "Maximum array items"]].filter(([key]) => key === "maxStringChars" || state.draft.payload.kind === "json" || state.draft.payload.kind === "registered").map(([key, text]) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
1923
2107
|
text,
|
|
1924
|
-
/* @__PURE__ */ (0,
|
|
2108
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
1925
2109
|
] }, key))
|
|
1926
2110
|
] }) : null,
|
|
1927
|
-
rows ? /* @__PURE__ */ (0,
|
|
1928
|
-
/* @__PURE__ */ (0,
|
|
2111
|
+
rows ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
1929
2113
|
"Data selection \xB7 ",
|
|
1930
2114
|
controls.visibleColumns.length,
|
|
1931
2115
|
" columns",
|
|
1932
2116
|
controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
|
|
1933
2117
|
] }),
|
|
1934
|
-
/* @__PURE__ */ (0,
|
|
2118
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RowControls, { rows, controls, change: changeControls }) })
|
|
1935
2119
|
] }) : null,
|
|
1936
|
-
state.snapshot.sections.length ? /* @__PURE__ */ (0,
|
|
1937
|
-
/* @__PURE__ */ (0,
|
|
2120
|
+
state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2121
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
1938
2122
|
"Sections \xB7 ",
|
|
1939
2123
|
controls.sections.length,
|
|
1940
2124
|
" included"
|
|
1941
2125
|
] }),
|
|
1942
|
-
/* @__PURE__ */ (0,
|
|
1943
|
-
/* @__PURE__ */ (0,
|
|
2126
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2127
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.sections.includes(section.id), onChange: (e) => changeControls({ ...controls, sections: e.target.checked ? [...controls.sections, section.id] : controls.sections.filter((id) => id !== section.id) }) }),
|
|
1944
2128
|
" ",
|
|
1945
2129
|
section.label
|
|
1946
2130
|
] }, section.id)) })
|
|
1947
2131
|
] }) : null,
|
|
1948
|
-
/* @__PURE__ */ (0,
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
|
|
1949
2133
|
"Output format",
|
|
1950
|
-
/* @__PURE__ */ (0,
|
|
1951
|
-
formats.map((f) => /* @__PURE__ */ (0,
|
|
1952
|
-
state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0,
|
|
1953
|
-
workspaceAdapters.map((adapter) => /* @__PURE__ */ (0,
|
|
2134
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
|
|
2135
|
+
formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: f, children: LABEL[f] }, f)),
|
|
2136
|
+
state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
|
|
2137
|
+
workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
|
|
1954
2138
|
] })
|
|
1955
2139
|
] }),
|
|
1956
|
-
/* @__PURE__ */ (0,
|
|
1957
|
-
/* @__PURE__ */ (0,
|
|
1958
|
-
/* @__PURE__ */ (0,
|
|
2140
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { className: "matrx-alchemy-preview", "aria-label": "Prepared output", "aria-invalid": bufferError ? true : void 0, "aria-describedby": bufferError ? "alchemy-buffer-error" : void 0, value: buffer, onChange: (e) => editBuffer(e.target.value) }),
|
|
2141
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1959
2143
|
state.snapshot.coverage.included.toLocaleString(),
|
|
1960
2144
|
" included",
|
|
1961
2145
|
state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
|
|
1962
2146
|
" \xB7 ",
|
|
1963
2147
|
state.snapshot.coverage.status
|
|
1964
2148
|
] }),
|
|
1965
|
-
state.snapshot.coverage.reason ? /* @__PURE__ */ (0,
|
|
1966
|
-
limitText ? /* @__PURE__ */ (0,
|
|
2149
|
+
state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
|
|
2150
|
+
limitText ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
1967
2151
|
"Limits: ",
|
|
1968
2152
|
limitText
|
|
1969
2153
|
] }) : null,
|
|
1970
|
-
displayedOmissions.length ? /* @__PURE__ */ (0,
|
|
1971
|
-
/* @__PURE__ */ (0,
|
|
2154
|
+
displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { children: [
|
|
2155
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
1972
2156
|
displayedOmissions.length,
|
|
1973
2157
|
" omissions or adjustments"
|
|
1974
2158
|
] }),
|
|
1975
|
-
/* @__PURE__ */ (0,
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("li", { children: [
|
|
1976
2160
|
o.path || "/",
|
|
1977
2161
|
": ",
|
|
1978
2162
|
o.reason,
|
|
@@ -1980,79 +2164,86 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1980
2164
|
] }, `${o.path}-${o.reason}-${i}`)) })
|
|
1981
2165
|
] }) : null
|
|
1982
2166
|
] }),
|
|
1983
|
-
bufferError ? /* @__PURE__ */ (0,
|
|
1984
|
-
formatError ? /* @__PURE__ */ (0,
|
|
1985
|
-
bufferError ? /* @__PURE__ */ (0,
|
|
1986
|
-
const fallback = (0,
|
|
2167
|
+
bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
|
|
2168
|
+
formatError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
|
|
2169
|
+
bufferError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
|
|
2170
|
+
const fallback = (0, import_content_transfer2.editDraft)(state.draft, { kind: "text", text: buffer });
|
|
1987
2171
|
setBufferError(null);
|
|
1988
2172
|
onChange({ ...state, draft: fallback, error: void 0 });
|
|
1989
2173
|
setFormat("plain");
|
|
1990
2174
|
}, children: "Use invalid JSON as plain text" }) : null
|
|
1991
2175
|
] }),
|
|
1992
|
-
ai || busy === "capture" || state.error ? /* @__PURE__ */ (0,
|
|
1993
|
-
ai ? /* @__PURE__ */ (0,
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
2176
|
+
ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("aside", { children: [
|
|
2177
|
+
ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
1995
2179
|
"Start with",
|
|
1996
|
-
/* @__PURE__ */ (0,
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
|
|
1997
2181
|
if (event.target.value) setInstruction(event.target.value);
|
|
1998
2182
|
}, children: [
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2000
|
-
/* @__PURE__ */ (0,
|
|
2001
|
-
/* @__PURE__ */ (0,
|
|
2002
|
-
/* @__PURE__ */ (0,
|
|
2003
|
-
/* @__PURE__ */ (0,
|
|
2004
|
-
/* @__PURE__ */ (0,
|
|
2005
|
-
/* @__PURE__ */ (0,
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "Choose an instruction" }),
|
|
2184
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
|
|
2187
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
|
|
2188
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
|
|
2189
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
|
|
2006
2190
|
] })
|
|
2007
2191
|
] }),
|
|
2008
|
-
/* @__PURE__ */ (0,
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2009
2193
|
"AI instruction",
|
|
2010
|
-
/* @__PURE__ */ (0,
|
|
2194
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
|
|
2011
2195
|
] }),
|
|
2012
|
-
/* @__PURE__ */ (0,
|
|
2013
|
-
busy === "ai" ? /* @__PURE__ */ (0,
|
|
2196
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: !aiSession.current || !instruction.trim() || busy !== null || !aiSession.current.supports(state.snapshot), onClick: () => void runAi(false), children: "Generate preview" }),
|
|
2197
|
+
busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
|
|
2014
2198
|
] }) : null,
|
|
2015
|
-
busy === "capture" ? /* @__PURE__ */ (0,
|
|
2199
|
+
busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
|
|
2016
2200
|
activeCapture.current?.abort();
|
|
2017
2201
|
activeCapture.current = null;
|
|
2018
2202
|
setBusy(null);
|
|
2019
2203
|
}, children: "Stop loading rows" }) : null,
|
|
2020
|
-
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0,
|
|
2021
|
-
ai ? /* @__PURE__ */ (0,
|
|
2022
|
-
state.error ? /* @__PURE__ */ (0,
|
|
2204
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
2205
|
+
ai ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "matrx-alchemy-meta", children: "AI updates the preview; copy it when you are ready. Closing this window lets the AI run continue." }) : null,
|
|
2206
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
2023
2207
|
] }) : null
|
|
2024
2208
|
] }),
|
|
2025
|
-
pendingControls ? /* @__PURE__ */ (0,
|
|
2026
|
-
/* @__PURE__ */ (0,
|
|
2027
|
-
/* @__PURE__ */ (0,
|
|
2028
|
-
/* @__PURE__ */ (0,
|
|
2209
|
+
pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "This control would replace your manual edit." }),
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
2212
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
2029
2213
|
] }) : null,
|
|
2030
|
-
state.sourceStale ? /* @__PURE__ */ (0,
|
|
2031
|
-
state.pending ? /* @__PURE__ */ (0,
|
|
2032
|
-
/* @__PURE__ */ (0,
|
|
2033
|
-
/* @__PURE__ */ (0,
|
|
2034
|
-
|
|
2214
|
+
state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
2215
|
+
state.pending ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { children: "A fresh source snapshot is ready." }),
|
|
2217
|
+
state.pending.scope !== state.scope ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { children: [
|
|
2218
|
+
"Switch from ",
|
|
2219
|
+
scopeLabels?.[state.scope] ?? SCOPE_LABEL[state.scope],
|
|
2220
|
+
" to ",
|
|
2221
|
+
scopeLabels?.[state.pending.scope] ?? SCOPE_LABEL[state.pending.scope],
|
|
2222
|
+
" by regenerating. Your current draft is retained until you choose."
|
|
2223
|
+
] }) : null,
|
|
2224
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
2225
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
|
|
2035
2226
|
] }) : null,
|
|
2036
|
-
eligibleActions.length ? /* @__PURE__ */ (0,
|
|
2037
|
-
/* @__PURE__ */ (0,
|
|
2227
|
+
eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
|
|
2228
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
2038
2229
|
"Use prepared content \xB7 ",
|
|
2039
2230
|
eligibleActions.length,
|
|
2040
2231
|
" destinations"
|
|
2041
2232
|
] }),
|
|
2042
|
-
/* @__PURE__ */ (0,
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliverAction(action), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DestinationPresentation, { action }) }, action.id)) })
|
|
2043
2234
|
] }) : null,
|
|
2044
|
-
deliveryNotice ? /* @__PURE__ */ (0,
|
|
2235
|
+
deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
|
|
2045
2236
|
] }),
|
|
2046
|
-
/* @__PURE__ */ (0,
|
|
2047
|
-
/* @__PURE__ */ (0,
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogFooter, { children: [
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "matrx-alchemy-meta", children: [
|
|
2048
2239
|
buffer.length.toLocaleString(),
|
|
2049
2240
|
" characters \xB7 ~",
|
|
2050
2241
|
estimateTokens(buffer).toLocaleString(),
|
|
2051
2242
|
" tokens"
|
|
2052
2243
|
] }),
|
|
2053
|
-
/* @__PURE__ */ (0,
|
|
2054
|
-
/* @__PURE__ */ (0,
|
|
2055
|
-
/* @__PURE__ */ (0,
|
|
2244
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", "aria-label": "Download prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(true), children: "Download" }),
|
|
2246
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", "aria-label": "Copy prepared output", disabled: busy !== null || Boolean(bufferError || formatError) || !preparedArtifact, onClick: () => void deliver(false), children: "Copy" })
|
|
2056
2247
|
] })
|
|
2057
2248
|
] }) });
|
|
2058
2249
|
}
|
|
@@ -2060,59 +2251,59 @@ function RowControls({ rows, controls, change }) {
|
|
|
2060
2251
|
const filterCount = Object.values(controls.filters).filter(Boolean).length;
|
|
2061
2252
|
const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
|
|
2062
2253
|
const dataSummary = [controls.search ? "search active" : "", controls.sort ? `sorted by ${rows.columns.find((column) => column.id === controls.sort)?.label ?? controls.sort}` : "", filterCount ? `${filterCount} filter${filterCount === 1 ? "" : "s"}` : ""].filter(Boolean).join(" \xB7 ");
|
|
2063
|
-
return /* @__PURE__ */ (0,
|
|
2064
|
-
/* @__PURE__ */ (0,
|
|
2065
|
-
/* @__PURE__ */ (0,
|
|
2254
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
2255
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2256
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2066
2257
|
"Search",
|
|
2067
|
-
/* @__PURE__ */ (0,
|
|
2258
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
|
|
2068
2259
|
] }),
|
|
2069
|
-
/* @__PURE__ */ (0,
|
|
2260
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2070
2261
|
"Sort",
|
|
2071
|
-
/* @__PURE__ */ (0,
|
|
2072
|
-
/* @__PURE__ */ (0,
|
|
2073
|
-
rows.columns.map((column) => /* @__PURE__ */ (0,
|
|
2262
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "", children: "None" }),
|
|
2264
|
+
rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: column.id, children: column.label }, column.id))
|
|
2074
2265
|
] })
|
|
2075
2266
|
] }),
|
|
2076
|
-
/* @__PURE__ */ (0,
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2077
2268
|
"Direction",
|
|
2078
|
-
/* @__PURE__ */ (0,
|
|
2079
|
-
/* @__PURE__ */ (0,
|
|
2080
|
-
/* @__PURE__ */ (0,
|
|
2269
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
|
|
2270
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "asc", children: "Ascending" }),
|
|
2271
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "desc", children: "Descending" })
|
|
2081
2272
|
] })
|
|
2082
2273
|
] }),
|
|
2083
|
-
/* @__PURE__ */ (0,
|
|
2274
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2084
2275
|
"Top rows",
|
|
2085
|
-
/* @__PURE__ */ (0,
|
|
2276
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
2086
2277
|
] })
|
|
2087
2278
|
] }),
|
|
2088
|
-
/* @__PURE__ */ (0,
|
|
2089
|
-
/* @__PURE__ */ (0,
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2280
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
2090
2281
|
"Columns and filters",
|
|
2091
2282
|
dataSummary ? ` \u2014 ${dataSummary}` : ""
|
|
2092
2283
|
] }),
|
|
2093
|
-
/* @__PURE__ */ (0,
|
|
2094
|
-
/* @__PURE__ */ (0,
|
|
2095
|
-
/* @__PURE__ */ (0,
|
|
2284
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-column", children: [
|
|
2285
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2286
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.visibleColumns.includes(column.id), onChange: (e) => change({ ...controls, visibleColumns: e.target.checked ? [...controls.visibleColumns, column.id] : controls.visibleColumns.filter((id) => id !== column.id) }) }),
|
|
2096
2287
|
" ",
|
|
2097
2288
|
column.label
|
|
2098
2289
|
] }),
|
|
2099
|
-
/* @__PURE__ */ (0,
|
|
2290
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { "aria-label": `Filter ${column.label}`, placeholder: "Filter", value: controls.filters[column.id] ?? "", onChange: (e) => change({ ...controls, filters: { ...controls.filters, [column.id]: e.target.value } }) })
|
|
2100
2291
|
] }, column.id)) })
|
|
2101
2292
|
] }),
|
|
2102
|
-
/* @__PURE__ */ (0,
|
|
2103
|
-
/* @__PURE__ */ (0,
|
|
2293
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2294
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { children: [
|
|
2104
2295
|
"Rows \u2014 ",
|
|
2105
2296
|
selectionSummary
|
|
2106
2297
|
] }),
|
|
2107
|
-
/* @__PURE__ */ (0,
|
|
2108
|
-
/* @__PURE__ */ (0,
|
|
2109
|
-
/* @__PURE__ */ (0,
|
|
2298
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("fieldset", { "aria-label": "Row selection", children: [
|
|
2299
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2300
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
|
|
2110
2301
|
" Only selected rows"
|
|
2111
2302
|
] }),
|
|
2112
|
-
/* @__PURE__ */ (0,
|
|
2113
|
-
const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0,
|
|
2114
|
-
return /* @__PURE__ */ (0,
|
|
2115
|
-
/* @__PURE__ */ (0,
|
|
2303
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
|
|
2304
|
+
const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0, import_content_transfer2.readTransferCell)(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
|
|
2305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
2306
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("input", { type: "checkbox", checked: controls.selectedIndices.includes(index), onChange: (e) => change({ ...controls, selectedIndices: e.target.checked ? [...controls.selectedIndices, index] : controls.selectedIndices.filter((value) => value !== index) }) }),
|
|
2116
2307
|
" Row ",
|
|
2117
2308
|
index + 1,
|
|
2118
2309
|
summary ? ` \u2014 ${summary}` : ""
|
|
@@ -2124,11 +2315,11 @@ function RowControls({ rows, controls, change }) {
|
|
|
2124
2315
|
}
|
|
2125
2316
|
|
|
2126
2317
|
// src/content-transfer/matrx-copy.tsx
|
|
2127
|
-
var
|
|
2318
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2128
2319
|
var resolve = (value) => typeof value === "function" ? value() : value;
|
|
2129
2320
|
var asPayload = (value) => ({
|
|
2130
2321
|
kind: "markdown",
|
|
2131
|
-
text: typeof value === "string" ? value : (0,
|
|
2322
|
+
text: typeof value === "string" ? value : (0, import_content_transfer3.buildAgentPayload)(value)
|
|
2132
2323
|
});
|
|
2133
2324
|
var structuredPayload = (value) => {
|
|
2134
2325
|
if (typeof value === "string") return { kind: "markdown", text: value };
|
|
@@ -2137,7 +2328,7 @@ var structuredPayload = (value) => {
|
|
|
2137
2328
|
);
|
|
2138
2329
|
return {
|
|
2139
2330
|
kind: "json",
|
|
2140
|
-
value: (0,
|
|
2331
|
+
value: (0, import_content_transfer3.normalizeTransferJson)(
|
|
2141
2332
|
{
|
|
2142
2333
|
kind: value.kind,
|
|
2143
2334
|
location: value.location,
|
|
@@ -2165,12 +2356,12 @@ var sourceFor = (id, label, build) => ({
|
|
|
2165
2356
|
signal.throwIfAborted();
|
|
2166
2357
|
const payload = await build();
|
|
2167
2358
|
signal.throwIfAborted();
|
|
2168
|
-
return (0,
|
|
2359
|
+
return (0, import_content_transfer3.directSource)(payload, { sourceId: id, label });
|
|
2169
2360
|
}
|
|
2170
2361
|
});
|
|
2171
2362
|
function MatrxCopyMenu(props) {
|
|
2172
2363
|
const inherited = useContentTransferCapabilities();
|
|
2173
|
-
return /* @__PURE__ */ (0,
|
|
2364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2174
2365
|
MatrxCopyMenuSession,
|
|
2175
2366
|
{
|
|
2176
2367
|
...props
|
|
@@ -2182,12 +2373,12 @@ function MatrxCopyMenu(props) {
|
|
|
2182
2373
|
);
|
|
2183
2374
|
}
|
|
2184
2375
|
function MatrxCopyMenuSession(props) {
|
|
2185
|
-
const instance =
|
|
2186
|
-
const controller =
|
|
2376
|
+
const instance = React10.useId();
|
|
2377
|
+
const controller = React10.useRef(null);
|
|
2187
2378
|
const capabilities = useContentTransferCapabilities();
|
|
2188
|
-
const transport = capabilities.transport ?? (0,
|
|
2189
|
-
const [modal, setModal] =
|
|
2190
|
-
const [configuration, setConfiguration] =
|
|
2379
|
+
const transport = capabilities.transport ?? (0, import_content_transfer3.createBrowserTransport)();
|
|
2380
|
+
const [modal, setModal] = React10.useState(null);
|
|
2381
|
+
const [configuration, setConfiguration] = React10.useState(null);
|
|
2191
2382
|
const copyVisible = !props.hide?.includes("copy");
|
|
2192
2383
|
const aiVisible = !props.hide?.includes("ai");
|
|
2193
2384
|
const exportVisible = !props.hide?.includes("export");
|
|
@@ -2203,14 +2394,14 @@ function MatrxCopyMenuSession(props) {
|
|
|
2203
2394
|
})) : void 0;
|
|
2204
2395
|
const json = aiVisible && props.json !== void 0 ? make("json", () => ({
|
|
2205
2396
|
kind: "json",
|
|
2206
|
-
value: (0,
|
|
2397
|
+
value: (0, import_content_transfer3.normalizeTransferJson)(resolve(props.json), {
|
|
2207
2398
|
omitUndefinedObjectProperties: true
|
|
2208
2399
|
})
|
|
2209
2400
|
})) : void 0;
|
|
2210
2401
|
const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
|
|
2211
2402
|
const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
|
|
2212
2403
|
const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
|
|
2213
|
-
const value = (0,
|
|
2404
|
+
const value = (0, import_content_transfer3.normalizeTransferJson)(props.export.sheetRows(), {
|
|
2214
2405
|
omitUndefinedObjectProperties: true
|
|
2215
2406
|
});
|
|
2216
2407
|
if (!Array.isArray(value) || value.some(
|
|
@@ -2347,7 +2538,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
2347
2538
|
const bytes = new Uint8Array(value.bytes);
|
|
2348
2539
|
const filename = typeof value.filename === "string" ? value.filename : `${props.label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "export"}.${value.extension.replace(/[^a-zA-Z0-9.-]/g, "") || "bin"}`;
|
|
2349
2540
|
return transport.download(
|
|
2350
|
-
(0,
|
|
2541
|
+
(0, import_content_transfer3.sealTransferArtifact)({
|
|
2351
2542
|
snapshotId: snapshot.id,
|
|
2352
2543
|
draftRevision: draft.revision,
|
|
2353
2544
|
format: `export:${item.id}`,
|
|
@@ -2374,11 +2565,14 @@ function MatrxCopyMenuSession(props) {
|
|
|
2374
2565
|
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
2375
2566
|
if (!source && !actions.length) return null;
|
|
2376
2567
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
2377
|
-
return /* @__PURE__ */ (0,
|
|
2378
|
-
/* @__PURE__ */ (0,
|
|
2568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2569
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2379
2570
|
ContentTransferMenu,
|
|
2380
2571
|
{
|
|
2572
|
+
triggerSize: props.size === "xs" || props.size === "toolbar" ? "compact" : "default",
|
|
2381
2573
|
source: target,
|
|
2574
|
+
...props.references ? { references: props.references } : {},
|
|
2575
|
+
...props.referenceActions ? { referenceActions: props.referenceActions } : {},
|
|
2382
2576
|
...props.icon !== void 0 ? { icon: props.icon } : {},
|
|
2383
2577
|
...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
|
|
2384
2578
|
controllerRef: controller,
|
|
@@ -2412,7 +2606,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
2412
2606
|
if (!open) setModal(null);
|
|
2413
2607
|
}
|
|
2414
2608
|
}),
|
|
2415
|
-
configuration ? /* @__PURE__ */ (0,
|
|
2609
|
+
configuration ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2416
2610
|
SourceConfiguration,
|
|
2417
2611
|
{
|
|
2418
2612
|
restoreFocus: () => controller.current?.focusTrigger(),
|
|
@@ -2439,14 +2633,14 @@ function SourceConfiguration({
|
|
|
2439
2633
|
onPrepare
|
|
2440
2634
|
}) {
|
|
2441
2635
|
const custom = configuration.custom;
|
|
2442
|
-
const handingOff =
|
|
2636
|
+
const handingOff = React10.useRef(false);
|
|
2443
2637
|
const groomer = configuration.groomer;
|
|
2444
|
-
const [values, setValues] =
|
|
2638
|
+
const [values, setValues] = React10.useState(
|
|
2445
2639
|
() => Object.fromEntries(
|
|
2446
2640
|
custom?.options.map((option) => [option.key, option.default]) ?? []
|
|
2447
2641
|
)
|
|
2448
2642
|
);
|
|
2449
|
-
const [sections, setSections] =
|
|
2643
|
+
const [sections, setSections] = React10.useState(
|
|
2450
2644
|
() => Object.fromEntries(
|
|
2451
2645
|
groomer?.sections.map((section) => [
|
|
2452
2646
|
section.id,
|
|
@@ -2454,8 +2648,8 @@ function SourceConfiguration({
|
|
|
2454
2648
|
]) ?? []
|
|
2455
2649
|
)
|
|
2456
2650
|
);
|
|
2457
|
-
const [error, setError] =
|
|
2458
|
-
const [busy, setBusy] =
|
|
2651
|
+
const [error, setError] = React10.useState(null);
|
|
2652
|
+
const [busy, setBusy] = React10.useState(false);
|
|
2459
2653
|
const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
|
|
2460
2654
|
let prepared = null;
|
|
2461
2655
|
let buildError = null;
|
|
@@ -2488,18 +2682,18 @@ function SourceConfiguration({
|
|
|
2488
2682
|
...groomer.context ? { context: groomer.context } : {}
|
|
2489
2683
|
};
|
|
2490
2684
|
}
|
|
2491
|
-
text = prepared ? (0,
|
|
2685
|
+
text = prepared ? (0, import_content_transfer3.buildAgentPayload)(prepared) : "";
|
|
2492
2686
|
} catch (cause) {
|
|
2493
2687
|
buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
|
|
2494
2688
|
}
|
|
2495
|
-
return /* @__PURE__ */ (0,
|
|
2689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2496
2690
|
Dialog,
|
|
2497
2691
|
{
|
|
2498
2692
|
open: true,
|
|
2499
2693
|
onOpenChange: (open) => {
|
|
2500
2694
|
if (!open && !busy) onClose();
|
|
2501
2695
|
},
|
|
2502
|
-
children: /* @__PURE__ */ (0,
|
|
2696
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2503
2697
|
DialogContent,
|
|
2504
2698
|
{
|
|
2505
2699
|
onCloseAutoFocus: (event) => {
|
|
@@ -2508,23 +2702,23 @@ function SourceConfiguration({
|
|
|
2508
2702
|
},
|
|
2509
2703
|
className: "matrx-alchemy-workspace matrx-alchemy-configuration",
|
|
2510
2704
|
children: [
|
|
2511
|
-
/* @__PURE__ */ (0,
|
|
2512
|
-
/* @__PURE__ */ (0,
|
|
2513
|
-
/* @__PURE__ */ (0,
|
|
2705
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogHeader, { children: [
|
|
2706
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogTitle, { children: title }),
|
|
2707
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
|
|
2514
2708
|
] }),
|
|
2515
|
-
/* @__PURE__ */ (0,
|
|
2516
|
-
/* @__PURE__ */ (0,
|
|
2517
|
-
custom?.options.map((option) => /* @__PURE__ */ (0,
|
|
2709
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
2710
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
|
|
2711
|
+
custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2518
2712
|
option.label,
|
|
2519
|
-
"hint" in option && option.hint ? /* @__PURE__ */ (0,
|
|
2520
|
-
option.kind === "toggle" ? /* @__PURE__ */ (0,
|
|
2713
|
+
"hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { children: option.hint }) : null,
|
|
2714
|
+
option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2521
2715
|
"input",
|
|
2522
2716
|
{
|
|
2523
2717
|
type: "checkbox",
|
|
2524
2718
|
checked: Boolean(values[option.key]),
|
|
2525
2719
|
onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
|
|
2526
2720
|
}
|
|
2527
|
-
) : option.kind === "preset" ? /* @__PURE__ */ (0,
|
|
2721
|
+
) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2528
2722
|
"select",
|
|
2529
2723
|
{
|
|
2530
2724
|
value: Number(values[option.key]),
|
|
@@ -2532,10 +2726,10 @@ function SourceConfiguration({
|
|
|
2532
2726
|
...values,
|
|
2533
2727
|
[option.key]: Number(event.target.value)
|
|
2534
2728
|
}),
|
|
2535
|
-
children: option.options.map((choice) => /* @__PURE__ */ (0,
|
|
2729
|
+
children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
|
|
2536
2730
|
}
|
|
2537
|
-
) : option.kind === "slider" ? /* @__PURE__ */ (0,
|
|
2538
|
-
/* @__PURE__ */ (0,
|
|
2731
|
+
) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2732
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2539
2733
|
"input",
|
|
2540
2734
|
{
|
|
2541
2735
|
type: "range",
|
|
@@ -2549,9 +2743,9 @@ function SourceConfiguration({
|
|
|
2549
2743
|
})
|
|
2550
2744
|
}
|
|
2551
2745
|
),
|
|
2552
|
-
/* @__PURE__ */ (0,
|
|
2553
|
-
] }) : /* @__PURE__ */ (0,
|
|
2554
|
-
/* @__PURE__ */ (0,
|
|
2746
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
|
|
2747
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2748
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2555
2749
|
"input",
|
|
2556
2750
|
{
|
|
2557
2751
|
type: "number",
|
|
@@ -2564,7 +2758,7 @@ function SourceConfiguration({
|
|
|
2564
2758
|
})
|
|
2565
2759
|
}
|
|
2566
2760
|
),
|
|
2567
|
-
option.presets?.map((preset) => /* @__PURE__ */ (0,
|
|
2761
|
+
option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2568
2762
|
Button,
|
|
2569
2763
|
{
|
|
2570
2764
|
type: "button",
|
|
@@ -2577,8 +2771,8 @@ function SourceConfiguration({
|
|
|
2577
2771
|
))
|
|
2578
2772
|
] })
|
|
2579
2773
|
] }, option.key)),
|
|
2580
|
-
groomer ? /* @__PURE__ */ (0,
|
|
2581
|
-
/* @__PURE__ */ (0,
|
|
2774
|
+
groomer ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2775
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2582
2776
|
Button,
|
|
2583
2777
|
{
|
|
2584
2778
|
type: "button",
|
|
@@ -2596,9 +2790,9 @@ function SourceConfiguration({
|
|
|
2596
2790
|
},
|
|
2597
2791
|
level
|
|
2598
2792
|
)) }),
|
|
2599
|
-
groomer.sections.map((section) => /* @__PURE__ */ (0,
|
|
2793
|
+
groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2600
2794
|
section.title,
|
|
2601
|
-
/* @__PURE__ */ (0,
|
|
2795
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2602
2796
|
"select",
|
|
2603
2797
|
{
|
|
2604
2798
|
value: sections[section.id],
|
|
@@ -2607,26 +2801,26 @@ function SourceConfiguration({
|
|
|
2607
2801
|
[section.id]: event.target.value
|
|
2608
2802
|
}),
|
|
2609
2803
|
children: [
|
|
2610
|
-
["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0,
|
|
2611
|
-
section.cuttable ? /* @__PURE__ */ (0,
|
|
2804
|
+
["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
|
|
2805
|
+
section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "off", children: "Exclude" }) : null
|
|
2612
2806
|
]
|
|
2613
2807
|
}
|
|
2614
2808
|
),
|
|
2615
|
-
section.description ? /* @__PURE__ */ (0,
|
|
2809
|
+
section.description ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: section.description }) : null
|
|
2616
2810
|
] }, section.id))
|
|
2617
2811
|
] }) : null
|
|
2618
2812
|
] }),
|
|
2619
|
-
/* @__PURE__ */ (0,
|
|
2813
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { children: [
|
|
2620
2814
|
(0, import_format2.formatCount)(text.length),
|
|
2621
2815
|
" characters \xB7 approximately",
|
|
2622
2816
|
" ",
|
|
2623
2817
|
(0, import_format2.formatCount)(Math.ceil(text.length / 4)),
|
|
2624
2818
|
" tokens"
|
|
2625
2819
|
] }),
|
|
2626
|
-
error || buildError ? /* @__PURE__ */ (0,
|
|
2820
|
+
error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", children: error ?? buildError }) : null
|
|
2627
2821
|
] }),
|
|
2628
|
-
/* @__PURE__ */ (0,
|
|
2629
|
-
/* @__PURE__ */ (0,
|
|
2822
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogFooter, { children: [
|
|
2823
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2630
2824
|
Button,
|
|
2631
2825
|
{
|
|
2632
2826
|
type: "button",
|
|
@@ -2637,7 +2831,7 @@ function SourceConfiguration({
|
|
|
2637
2831
|
children: "Cancel"
|
|
2638
2832
|
}
|
|
2639
2833
|
),
|
|
2640
|
-
/* @__PURE__ */ (0,
|
|
2834
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2641
2835
|
Button,
|
|
2642
2836
|
{
|
|
2643
2837
|
type: "button",
|
|
@@ -2672,7 +2866,7 @@ function SourceConfiguration({
|
|
|
2672
2866
|
|
|
2673
2867
|
// src/data-table/host.tsx
|
|
2674
2868
|
var import_react2 = require("react");
|
|
2675
|
-
var
|
|
2869
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2676
2870
|
var HOST_SLOT = /* @__PURE__ */ Symbol.for("ai-matrx.design-system.table-host-context");
|
|
2677
2871
|
var hostRegistry = globalThis;
|
|
2678
2872
|
var HostContext = hostRegistry[HOST_SLOT] ??= (0, import_react2.createContext)({});
|
|
@@ -2681,38 +2875,38 @@ function useMatrxDataTableHost() {
|
|
|
2681
2875
|
}
|
|
2682
2876
|
|
|
2683
2877
|
// src/data-table/copy.tsx
|
|
2684
|
-
var
|
|
2878
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2685
2879
|
function CopyButtons(props) {
|
|
2686
2880
|
const { CopyControls } = useMatrxDataTableHost();
|
|
2687
2881
|
const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
|
|
2688
|
-
if (CopyControls) return /* @__PURE__ */ (0,
|
|
2689
|
-
return /* @__PURE__ */ (0,
|
|
2882
|
+
if (CopyControls) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CopyControls, { ...copyProps });
|
|
2883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MatrxCopyMenu, { ...copyProps });
|
|
2690
2884
|
}
|
|
2691
2885
|
|
|
2692
2886
|
// src/data-table/MatrxUuidCell.tsx
|
|
2693
2887
|
var import_react4 = require("react");
|
|
2694
2888
|
|
|
2695
2889
|
// src/data-table/icons.tsx
|
|
2696
|
-
var
|
|
2890
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2697
2891
|
function Icon({ children, ...props }) {
|
|
2698
|
-
return /* @__PURE__ */ (0,
|
|
2892
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", ...props, children });
|
|
2699
2893
|
}
|
|
2700
|
-
var Check = (p) => /* @__PURE__ */ (0,
|
|
2701
|
-
var PanelRight = (p) => /* @__PURE__ */ (0,
|
|
2702
|
-
/* @__PURE__ */ (0,
|
|
2703
|
-
/* @__PURE__ */ (0,
|
|
2894
|
+
var Check = (p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m5 12 4 4L19 6" }) });
|
|
2895
|
+
var PanelRight = (p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Icon, { ...p, children: [
|
|
2896
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { x: "3", y: "4", width: "18", height: "16", rx: "2" }),
|
|
2897
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M15 4v16" })
|
|
2704
2898
|
] });
|
|
2705
|
-
var ExternalLink = (p) => /* @__PURE__ */ (0,
|
|
2706
|
-
var Copy = (p) => /* @__PURE__ */ (0,
|
|
2707
|
-
/* @__PURE__ */ (0,
|
|
2708
|
-
/* @__PURE__ */ (0,
|
|
2899
|
+
var ExternalLink = (p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M14 4h6v6M20 4l-9 9M19 13v6H5V5h6" }) });
|
|
2900
|
+
var Copy = (p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(Icon, { ...p, children: [
|
|
2901
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("rect", { x: "9", y: "9", width: "11", height: "11", rx: "2" }),
|
|
2902
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M15 9V6a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h3" })
|
|
2709
2903
|
] });
|
|
2710
|
-
var Lightbulb = (p) => /* @__PURE__ */ (0,
|
|
2711
|
-
var ShieldOff = (p) => /* @__PURE__ */ (0,
|
|
2904
|
+
var Lightbulb = (p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "M9 18h6M10 22h4M8 14a6 6 0 1 1 8 0c-1 1-1 2-1 3H9c0-1 0-2-1-3z" }) });
|
|
2905
|
+
var ShieldOff = (p) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Icon, { ...p, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("path", { d: "m3 3 18 18M12 3l7 3v5c0 4-3 7-7 9-4-2-7-5-7-9V6l4-2" }) });
|
|
2712
2906
|
|
|
2713
2907
|
// src/data-table/useTableNotice.tsx
|
|
2714
2908
|
var import_react3 = require("react");
|
|
2715
|
-
var
|
|
2909
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2716
2910
|
function useTableNotice() {
|
|
2717
2911
|
const host = useMatrxDataTableHost();
|
|
2718
2912
|
const [message, setMessage] = (0, import_react3.useState)(null);
|
|
@@ -2726,15 +2920,15 @@ function useTableNotice() {
|
|
|
2726
2920
|
else setMessage({ text, error: true });
|
|
2727
2921
|
}
|
|
2728
2922
|
};
|
|
2729
|
-
const notice = message ? /* @__PURE__ */ (0,
|
|
2923
|
+
const notice = message ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { role: message.error ? "alert" : "status", className: message.error ? "text-xs text-destructive" : "text-xs text-muted-foreground", children: [
|
|
2730
2924
|
message.text,
|
|
2731
|
-
/* @__PURE__ */ (0,
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("button", { type: "button", "aria-label": "Dismiss notification", className: "ml-2 underline", onClick: () => setMessage(null), children: "Dismiss" })
|
|
2732
2926
|
] }) : null;
|
|
2733
2927
|
return { notify, notice };
|
|
2734
2928
|
}
|
|
2735
2929
|
|
|
2736
2930
|
// src/data-table/MatrxUuidCell.tsx
|
|
2737
|
-
var
|
|
2931
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2738
2932
|
var SHORT_LEN = 8;
|
|
2739
2933
|
function shortUuid(id, len = SHORT_LEN) {
|
|
2740
2934
|
return id.slice(0, len);
|
|
@@ -2784,7 +2978,7 @@ function MatrxUuidCell({
|
|
|
2784
2978
|
[]
|
|
2785
2979
|
);
|
|
2786
2980
|
if (!value) {
|
|
2787
|
-
return /* @__PURE__ */ (0,
|
|
2981
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "text-muted-foreground/40", children: "\u2014" });
|
|
2788
2982
|
}
|
|
2789
2983
|
const doors = token ? resolveEntityDoors?.(token, value, href) ?? null : null;
|
|
2790
2984
|
const resolvedHref = doors?.href ?? href ?? null;
|
|
@@ -2827,13 +3021,13 @@ function MatrxUuidCell({
|
|
|
2827
3021
|
};
|
|
2828
3022
|
const idNode = (() => {
|
|
2829
3023
|
if (forbidden) {
|
|
2830
|
-
return /* @__PURE__ */ (0,
|
|
2831
|
-
/* @__PURE__ */ (0,
|
|
2832
|
-
/* @__PURE__ */ (0,
|
|
3024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-muted-foreground/70 tabular-nums", children: [
|
|
3025
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate", children: display }),
|
|
3026
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ShieldOff, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true })
|
|
2833
3027
|
] });
|
|
2834
3028
|
}
|
|
2835
3029
|
if (onOpen) {
|
|
2836
|
-
return /* @__PURE__ */ (0,
|
|
3030
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2837
3031
|
"button",
|
|
2838
3032
|
{
|
|
2839
3033
|
type: "button",
|
|
@@ -2842,14 +3036,14 @@ function MatrxUuidCell({
|
|
|
2842
3036
|
disabled: opening,
|
|
2843
3037
|
className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400 disabled:opacity-60",
|
|
2844
3038
|
children: [
|
|
2845
|
-
/* @__PURE__ */ (0,
|
|
2846
|
-
/* @__PURE__ */ (0,
|
|
3039
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
|
|
3040
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PanelRight, { className: "h-3 w-3 shrink-0 opacity-50" })
|
|
2847
3041
|
]
|
|
2848
3042
|
}
|
|
2849
3043
|
);
|
|
2850
3044
|
}
|
|
2851
3045
|
if (resolvedHref) {
|
|
2852
|
-
return /* @__PURE__ */ (0,
|
|
3046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2853
3047
|
"a",
|
|
2854
3048
|
{
|
|
2855
3049
|
href: resolvedHref,
|
|
@@ -2859,15 +3053,15 @@ function MatrxUuidCell({
|
|
|
2859
3053
|
onClick: stop,
|
|
2860
3054
|
className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400",
|
|
2861
3055
|
children: [
|
|
2862
|
-
/* @__PURE__ */ (0,
|
|
2863
|
-
/* @__PURE__ */ (0,
|
|
3056
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
|
|
3057
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-50" })
|
|
2864
3058
|
]
|
|
2865
3059
|
}
|
|
2866
3060
|
);
|
|
2867
3061
|
}
|
|
2868
|
-
return /* @__PURE__ */ (0,
|
|
3062
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
|
|
2869
3063
|
})();
|
|
2870
|
-
return /* @__PURE__ */ (0,
|
|
3064
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
2871
3065
|
"span",
|
|
2872
3066
|
{
|
|
2873
3067
|
"data-matrx-cell-control": true,
|
|
@@ -2877,12 +3071,12 @@ function MatrxUuidCell({
|
|
|
2877
3071
|
),
|
|
2878
3072
|
onClick: stop,
|
|
2879
3073
|
children: [
|
|
2880
|
-
/* @__PURE__ */ (0,
|
|
2881
|
-
/* @__PURE__ */ (0,
|
|
2882
|
-
/* @__PURE__ */ (0,
|
|
3074
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
|
|
3075
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
|
|
3076
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
|
|
2883
3077
|
] }),
|
|
2884
|
-
/* @__PURE__ */ (0,
|
|
2885
|
-
/* @__PURE__ */ (0,
|
|
3078
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2886
3080
|
"button",
|
|
2887
3081
|
{
|
|
2888
3082
|
type: "button",
|
|
@@ -2892,13 +3086,13 @@ function MatrxUuidCell({
|
|
|
2892
3086
|
"inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
|
|
2893
3087
|
copied && "text-primary"
|
|
2894
3088
|
),
|
|
2895
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
3089
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Copy, { className: "h-3 w-3" })
|
|
2896
3090
|
}
|
|
2897
3091
|
) }),
|
|
2898
|
-
/* @__PURE__ */ (0,
|
|
3092
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipContent, { side: "top", children: copied ? "Copied" : `Copy ${label ?? "id"}: ${value}` })
|
|
2899
3093
|
] }),
|
|
2900
|
-
canPeek ? /* @__PURE__ */ (0,
|
|
2901
|
-
/* @__PURE__ */ (0,
|
|
3094
|
+
canPeek ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
|
|
3095
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2902
3096
|
"button",
|
|
2903
3097
|
{
|
|
2904
3098
|
type: "button",
|
|
@@ -2908,16 +3102,16 @@ function MatrxUuidCell({
|
|
|
2908
3102
|
},
|
|
2909
3103
|
"aria-label": `Quick look at ${label ?? "record"}`,
|
|
2910
3104
|
className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
|
|
2911
|
-
children: /* @__PURE__ */ (0,
|
|
3105
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Lightbulb, { className: "h-3 w-3" })
|
|
2912
3106
|
}
|
|
2913
3107
|
) }),
|
|
2914
|
-
/* @__PURE__ */ (0,
|
|
3108
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(TooltipContent, { side: "top", children: [
|
|
2915
3109
|
"Quick look at ",
|
|
2916
3110
|
label ?? "record"
|
|
2917
3111
|
] })
|
|
2918
3112
|
] }) : null,
|
|
2919
|
-
onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0,
|
|
2920
|
-
/* @__PURE__ */ (0,
|
|
3113
|
+
onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Tooltip, { children: [
|
|
3114
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2921
3115
|
"a",
|
|
2922
3116
|
{
|
|
2923
3117
|
href: resolvedHref,
|
|
@@ -2926,10 +3120,10 @@ function MatrxUuidCell({
|
|
|
2926
3120
|
onClick: stop,
|
|
2927
3121
|
"aria-label": `Open ${label ?? "record"} in a new tab`,
|
|
2928
3122
|
className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
|
|
2929
|
-
children: /* @__PURE__ */ (0,
|
|
3123
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ExternalLink, { className: "h-3 w-3" })
|
|
2930
3124
|
}
|
|
2931
3125
|
) }),
|
|
2932
|
-
/* @__PURE__ */ (0,
|
|
3126
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(TooltipContent, { side: "top", children: [
|
|
2933
3127
|
"Open ",
|
|
2934
3128
|
label ?? "record",
|
|
2935
3129
|
" in a new tab"
|
|
@@ -2937,7 +3131,7 @@ function MatrxUuidCell({
|
|
|
2937
3131
|
] }) : null,
|
|
2938
3132
|
trailing,
|
|
2939
3133
|
notice,
|
|
2940
|
-
canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0,
|
|
3134
|
+
canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2941
3135
|
ResourcePeek,
|
|
2942
3136
|
{
|
|
2943
3137
|
kind: doors?.peekKind ?? token ?? "record",
|
|
@@ -2953,11 +3147,11 @@ function MatrxUuidCell({
|
|
|
2953
3147
|
|
|
2954
3148
|
// src/data-table/entity.ts
|
|
2955
3149
|
function isUuidValue(value) {
|
|
2956
|
-
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[
|
|
3150
|
+
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
|
|
2957
3151
|
}
|
|
2958
3152
|
|
|
2959
3153
|
// src/data-table/DataRowInspector.tsx
|
|
2960
|
-
var
|
|
3154
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2961
3155
|
var noFieldToken = () => null;
|
|
2962
3156
|
function formatValue(value) {
|
|
2963
3157
|
if (value == null) return "\u2014";
|
|
@@ -2986,7 +3180,7 @@ function DataRowInspector({
|
|
|
2986
3180
|
tokenForField = noFieldToken
|
|
2987
3181
|
}) {
|
|
2988
3182
|
const entries = isPlainObject(row) ? Object.entries(row) : [["value", row]];
|
|
2989
|
-
const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ (0,
|
|
3183
|
+
const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "absolute right-1 top-1 opacity-0 transition-opacity focus-within:opacity-100 group-hover/field:opacity-100", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2990
3184
|
CopyButtons,
|
|
2991
3185
|
{
|
|
2992
3186
|
size: "xs",
|
|
@@ -3001,21 +3195,21 @@ function DataRowInspector({
|
|
|
3001
3195
|
})
|
|
3002
3196
|
}
|
|
3003
3197
|
) }) : null;
|
|
3004
|
-
return /* @__PURE__ */ (0,
|
|
3198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3005
3199
|
"div",
|
|
3006
3200
|
{
|
|
3007
3201
|
className: cn("flex h-full min-h-0 flex-col overflow-hidden", className),
|
|
3008
3202
|
children: [
|
|
3009
|
-
title ? /* @__PURE__ */ (0,
|
|
3010
|
-
/* @__PURE__ */ (0,
|
|
3203
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "shrink-0 border-b border-border px-3 py-2 text-sm font-medium", children: title }) : null,
|
|
3204
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "min-h-0 flex-1 overflow-auto p-3", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dl", { className: "space-y-2", children: entries.map(([key, value]) => {
|
|
3011
3205
|
if (isUuidValue(value)) {
|
|
3012
|
-
return /* @__PURE__ */ (0,
|
|
3206
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3013
3207
|
"div",
|
|
3014
3208
|
{
|
|
3015
3209
|
className: "group/field relative grid grid-cols-[minmax(7rem,9rem)_1fr] gap-2 rounded-md border border-border/60 bg-muted/20 px-2.5 py-2",
|
|
3016
3210
|
children: [
|
|
3017
|
-
/* @__PURE__ */ (0,
|
|
3018
|
-
/* @__PURE__ */ (0,
|
|
3211
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dd", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3019
3213
|
MatrxUuidCell,
|
|
3020
3214
|
{
|
|
3021
3215
|
value,
|
|
@@ -3030,13 +3224,13 @@ function DataRowInspector({
|
|
|
3030
3224
|
}
|
|
3031
3225
|
const formatted = formatValue(value);
|
|
3032
3226
|
const multiline = formatted.includes("\n") || formatted.length > 80;
|
|
3033
|
-
return /* @__PURE__ */ (0,
|
|
3227
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3034
3228
|
"div",
|
|
3035
3229
|
{
|
|
3036
3230
|
className: "group/field relative grid grid-cols-[minmax(7rem,9rem)_1fr] gap-2 rounded-md border border-border/60 bg-muted/20 py-2 pl-2.5 pr-12",
|
|
3037
3231
|
children: [
|
|
3038
|
-
/* @__PURE__ */ (0,
|
|
3039
|
-
/* @__PURE__ */ (0,
|
|
3232
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
|
|
3233
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3040
3234
|
"dd",
|
|
3041
3235
|
{
|
|
3042
3236
|
className: cn(
|