@ai-matrx/design-system 0.19.18 → 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 +8 -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 +1204 -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 +1343 -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-CRCy-Zy_.d.cts → types-C2yaTspG.d.cts} +5 -0
- package/dist/{types-Ch60uNn-.d.ts → types-DB30aCHu.d.ts} +5 -0
- package/package.json +1 -1
|
@@ -409,15 +409,12 @@ function useMatrxDataTableHost() {
|
|
|
409
409
|
}
|
|
410
410
|
|
|
411
411
|
// src/content-transfer/matrx-copy.tsx
|
|
412
|
-
var
|
|
413
|
-
var
|
|
412
|
+
var React10 = __toESM(require("react"), 1);
|
|
413
|
+
var import_content_transfer3 = require("@ai-matrx/kit/content-transfer");
|
|
414
414
|
var import_format2 = require("@ai-matrx/kit/format");
|
|
415
415
|
|
|
416
|
-
// src/content-transfer/
|
|
417
|
-
var
|
|
418
|
-
var import_react_dom = require("react-dom");
|
|
419
|
-
var import_content_transfer = require("@ai-matrx/kit/content-transfer");
|
|
420
|
-
var import_format = require("@ai-matrx/kit/format");
|
|
416
|
+
// src/content-transfer/email-review.tsx
|
|
417
|
+
var React6 = __toESM(require("react"), 1);
|
|
421
418
|
|
|
422
419
|
// src/button.tsx
|
|
423
420
|
var import_react_slot = require("@radix-ui/react-slot");
|
|
@@ -490,13 +487,133 @@ var Button = React5.forwardRef(
|
|
|
490
487
|
);
|
|
491
488
|
Button.displayName = "Button";
|
|
492
489
|
|
|
490
|
+
// src/content-transfer/email-review.tsx
|
|
491
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
492
|
+
var cancelled = () => ({ status: "cancelled" });
|
|
493
|
+
var failed = (error) => ({
|
|
494
|
+
status: "error",
|
|
495
|
+
code: "email-failed",
|
|
496
|
+
message: error instanceof Error ? error.message : "Could not send email.",
|
|
497
|
+
retryable: true
|
|
498
|
+
});
|
|
499
|
+
function useReviewedTransferEmail(email) {
|
|
500
|
+
const [pending, setPending] = React6.useState(null);
|
|
501
|
+
const [sending, setSending] = React6.useState(false);
|
|
502
|
+
const pendingRef = React6.useRef(null);
|
|
503
|
+
const sendingRef = React6.useRef(false);
|
|
504
|
+
const settle = React6.useCallback((request, outcome, render = true) => {
|
|
505
|
+
if (pendingRef.current !== request) return;
|
|
506
|
+
pendingRef.current = null;
|
|
507
|
+
request.context.signal.removeEventListener("abort", request.onAbort);
|
|
508
|
+
request.resolve(outcome);
|
|
509
|
+
sendingRef.current = false;
|
|
510
|
+
if (render) {
|
|
511
|
+
setSending(false);
|
|
512
|
+
setPending(null);
|
|
513
|
+
}
|
|
514
|
+
}, []);
|
|
515
|
+
React6.useEffect(
|
|
516
|
+
() => () => {
|
|
517
|
+
const request = pendingRef.current;
|
|
518
|
+
if (!request) return;
|
|
519
|
+
pendingRef.current = null;
|
|
520
|
+
request.context.signal.removeEventListener("abort", request.onAbort);
|
|
521
|
+
request.resolve(cancelled());
|
|
522
|
+
sendingRef.current = false;
|
|
523
|
+
},
|
|
524
|
+
[]
|
|
525
|
+
);
|
|
526
|
+
const reviewed = React6.useMemo(() => {
|
|
527
|
+
if (!email) return void 0;
|
|
528
|
+
return {
|
|
529
|
+
send: (artifact, context) => {
|
|
530
|
+
if (context.signal.aborted) return Promise.resolve(cancelled());
|
|
531
|
+
if (pendingRef.current)
|
|
532
|
+
return Promise.resolve({
|
|
533
|
+
status: "error",
|
|
534
|
+
code: "email-review-active",
|
|
535
|
+
message: "Finish reviewing the current email before starting another.",
|
|
536
|
+
retryable: true
|
|
537
|
+
});
|
|
538
|
+
return new Promise((resolve2) => {
|
|
539
|
+
const request = {
|
|
540
|
+
artifact,
|
|
541
|
+
context,
|
|
542
|
+
resolve: resolve2,
|
|
543
|
+
onAbort: () => settle(request, cancelled())
|
|
544
|
+
};
|
|
545
|
+
pendingRef.current = request;
|
|
546
|
+
context.signal.addEventListener("abort", request.onAbort, { once: true });
|
|
547
|
+
setSending(false);
|
|
548
|
+
setPending(request);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
}, [email, settle]);
|
|
553
|
+
const cancel = React6.useCallback(() => {
|
|
554
|
+
const request = pendingRef.current;
|
|
555
|
+
if (request && !sendingRef.current) settle(request, cancelled());
|
|
556
|
+
}, [settle]);
|
|
557
|
+
const confirm = React6.useCallback(() => {
|
|
558
|
+
const request = pendingRef.current;
|
|
559
|
+
if (!request || sendingRef.current || request.context.signal.aborted) return;
|
|
560
|
+
sendingRef.current = true;
|
|
561
|
+
setSending(true);
|
|
562
|
+
void email?.send(request.artifact, request.context).then(
|
|
563
|
+
(outcome) => settle(request, outcome),
|
|
564
|
+
(error) => settle(request, failed(error))
|
|
565
|
+
);
|
|
566
|
+
}, [email, settle]);
|
|
567
|
+
const review = pending ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dialog, { open: true, onOpenChange: (open) => {
|
|
568
|
+
if (!open) cancel();
|
|
569
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogContent, { className: "matrx-alchemy-workspace matrx-alchemy-email-review", "aria-busy": sending, children: [
|
|
570
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogHeader, { children: [
|
|
571
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DialogTitle, { children: "Review email attachment" }),
|
|
572
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogDescription, { children: [
|
|
573
|
+
"Email ",
|
|
574
|
+
pending.artifact.file?.filename ?? `${pending.artifact.format} output`,
|
|
575
|
+
" from ",
|
|
576
|
+
pending.context.label,
|
|
577
|
+
". Review this exact attachment before sending."
|
|
578
|
+
] })
|
|
579
|
+
] }),
|
|
580
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("textarea", { "aria-label": "Email attachment preview", readOnly: true, value: pending.artifact.plainText, className: "matrx-alchemy-preview" }),
|
|
581
|
+
pending.artifact.omissions.length ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("details", { className: "matrx-alchemy-email-adjustments", open: true, children: [
|
|
582
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("summary", { children: [
|
|
583
|
+
pending.artifact.omissions.length,
|
|
584
|
+
" omission",
|
|
585
|
+
pending.artifact.omissions.length === 1 ? "" : "s",
|
|
586
|
+
" or adjustment",
|
|
587
|
+
pending.artifact.omissions.length === 1 ? "" : "s"
|
|
588
|
+
] }),
|
|
589
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { children: pending.artifact.omissions.map((omission, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { children: [
|
|
590
|
+
omission.path || "/",
|
|
591
|
+
": ",
|
|
592
|
+
omission.reason,
|
|
593
|
+
omission.count == null ? "" : ` (${omission.count})`
|
|
594
|
+
] }, `${omission.path}-${omission.reason}-${index}`)) })
|
|
595
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "matrx-alchemy-meta", children: "No omissions or adjustments." }),
|
|
596
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DialogFooter, { children: [
|
|
597
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: sending, onClick: cancel, children: "Cancel" }),
|
|
598
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", disabled: sending, onClick: confirm, children: sending ? "Sending email\u2026" : "Send email" })
|
|
599
|
+
] })
|
|
600
|
+
] }) }) : null;
|
|
601
|
+
return { email: reviewed, review };
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// src/content-transfer/index.tsx
|
|
605
|
+
var React9 = __toESM(require("react"), 1);
|
|
606
|
+
var import_react_dom = require("react-dom");
|
|
607
|
+
var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
|
|
608
|
+
var import_format = require("@ai-matrx/kit/format");
|
|
609
|
+
|
|
493
610
|
// src/popover.tsx
|
|
494
611
|
var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"), 1);
|
|
495
|
-
var
|
|
496
|
-
var
|
|
612
|
+
var React7 = __toESM(require("react"), 1);
|
|
613
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
497
614
|
var Popover = PopoverPrimitive.Root;
|
|
498
615
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
499
|
-
var PopoverContent =
|
|
616
|
+
var PopoverContent = React7.forwardRef(
|
|
500
617
|
({
|
|
501
618
|
className,
|
|
502
619
|
align = "center",
|
|
@@ -506,7 +623,7 @@ var PopoverContent = React6.forwardRef(
|
|
|
506
623
|
...props
|
|
507
624
|
}, ref) => {
|
|
508
625
|
const portalContainer = usePortalContainer(container);
|
|
509
|
-
return /* @__PURE__ */ (0,
|
|
626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
510
627
|
PopoverPrimitive.Content,
|
|
511
628
|
{
|
|
512
629
|
ref,
|
|
@@ -535,14 +652,14 @@ var import_react2 = require("react");
|
|
|
535
652
|
|
|
536
653
|
// src/tooltip.tsx
|
|
537
654
|
var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
|
|
538
|
-
var
|
|
539
|
-
var
|
|
655
|
+
var React8 = __toESM(require("react"), 1);
|
|
656
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
540
657
|
var TooltipProvider = TooltipPrimitive.Provider;
|
|
541
658
|
var Tooltip = TooltipPrimitive.Root;
|
|
542
659
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
543
|
-
var TooltipContent =
|
|
660
|
+
var TooltipContent = React8.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
|
|
544
661
|
const resolved = usePortalContainer(container);
|
|
545
|
-
return /* @__PURE__ */ (0,
|
|
662
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
546
663
|
TooltipPrimitive.Content,
|
|
547
664
|
{
|
|
548
665
|
ref,
|
|
@@ -571,7 +688,7 @@ function getTapTargetLinkComponent() {
|
|
|
571
688
|
}
|
|
572
689
|
|
|
573
690
|
// src/tap-target/tap-target-button.tsx
|
|
574
|
-
var
|
|
691
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
575
692
|
var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
|
|
576
693
|
var TAP_OUTER_CLASS = "matrx-tap-target group";
|
|
577
694
|
var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
|
|
@@ -587,9 +704,9 @@ function IconContent({
|
|
|
587
704
|
className: cn2(className, icon.props.className)
|
|
588
705
|
});
|
|
589
706
|
}
|
|
590
|
-
return /* @__PURE__ */ (0,
|
|
707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className, children: icon });
|
|
591
708
|
}
|
|
592
|
-
return /* @__PURE__ */ (0,
|
|
709
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
593
710
|
"svg",
|
|
594
711
|
{
|
|
595
712
|
className,
|
|
@@ -626,7 +743,7 @@ function buildTapInner({
|
|
|
626
743
|
children,
|
|
627
744
|
strokeWidth = 2
|
|
628
745
|
}) {
|
|
629
|
-
const iconEl = /* @__PURE__ */ (0,
|
|
746
|
+
const iconEl = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
630
747
|
IconContent,
|
|
631
748
|
{
|
|
632
749
|
icon,
|
|
@@ -637,11 +754,11 @@ function buildTapInner({
|
|
|
637
754
|
);
|
|
638
755
|
const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
|
|
639
756
|
if (!label) {
|
|
640
|
-
return /* @__PURE__ */ (0,
|
|
757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: pillClasses, children: iconEl });
|
|
641
758
|
}
|
|
642
|
-
return /* @__PURE__ */ (0,
|
|
759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: pillClasses, children: [
|
|
643
760
|
iconEl,
|
|
644
|
-
/* @__PURE__ */ (0,
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
|
|
645
762
|
] });
|
|
646
763
|
}
|
|
647
764
|
function renderTapTarget({
|
|
@@ -729,7 +846,7 @@ function renderTrigger({
|
|
|
729
846
|
buttonRef
|
|
730
847
|
}) {
|
|
731
848
|
if (disabled && href) {
|
|
732
|
-
return /* @__PURE__ */ (0,
|
|
849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
733
850
|
"span",
|
|
734
851
|
{
|
|
735
852
|
"aria-disabled": "true",
|
|
@@ -742,7 +859,7 @@ function renderTrigger({
|
|
|
742
859
|
if (href) {
|
|
743
860
|
const isExternal = EXTERNAL_RE.test(href);
|
|
744
861
|
if (isExternal) {
|
|
745
|
-
return /* @__PURE__ */ (0,
|
|
862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
746
863
|
"a",
|
|
747
864
|
{
|
|
748
865
|
href,
|
|
@@ -756,7 +873,7 @@ function renderTrigger({
|
|
|
756
873
|
}
|
|
757
874
|
const Link = linkComponent ?? getTapTargetLinkComponent();
|
|
758
875
|
if (Link) {
|
|
759
|
-
return /* @__PURE__ */ (0,
|
|
876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
760
877
|
Link,
|
|
761
878
|
{
|
|
762
879
|
href,
|
|
@@ -769,7 +886,7 @@ function renderTrigger({
|
|
|
769
886
|
}
|
|
770
887
|
);
|
|
771
888
|
}
|
|
772
|
-
return /* @__PURE__ */ (0,
|
|
889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
773
890
|
"a",
|
|
774
891
|
{
|
|
775
892
|
href,
|
|
@@ -782,7 +899,7 @@ function renderTrigger({
|
|
|
782
899
|
);
|
|
783
900
|
}
|
|
784
901
|
if (as === "label") {
|
|
785
|
-
return /* @__PURE__ */ (0,
|
|
902
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
786
903
|
"label",
|
|
787
904
|
{
|
|
788
905
|
htmlFor,
|
|
@@ -792,7 +909,7 @@ function renderTrigger({
|
|
|
792
909
|
}
|
|
793
910
|
);
|
|
794
911
|
}
|
|
795
|
-
return /* @__PURE__ */ (0,
|
|
912
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
796
913
|
"button",
|
|
797
914
|
{
|
|
798
915
|
ref: buttonRef,
|
|
@@ -816,14 +933,14 @@ function withTooltip(trigger, {
|
|
|
816
933
|
if (tooltip === false) return trigger;
|
|
817
934
|
const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
|
|
818
935
|
if (!label) return trigger;
|
|
819
|
-
return /* @__PURE__ */ (0,
|
|
820
|
-
/* @__PURE__ */ (0,
|
|
936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Tooltip, { children: [
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
|
|
821
938
|
// Radix Tooltip triggers need a hoverable element; a disabled button
|
|
822
939
|
// does not dispatch pointer events, so we wrap in a span for the
|
|
823
940
|
// trigger target while keeping the disabled visual state.
|
|
824
|
-
/* @__PURE__ */ (0,
|
|
941
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "inline-flex", children: trigger })
|
|
825
942
|
) : trigger }),
|
|
826
|
-
/* @__PURE__ */ (0,
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
|
|
827
944
|
] });
|
|
828
945
|
}
|
|
829
946
|
var TapTargetButton = (0, import_react2.forwardRef)(function TapTargetButton2({
|
|
@@ -979,7 +1096,7 @@ var TapTargetButtonDestructive = (0, import_react2.forwardRef)(function TapTarge
|
|
|
979
1096
|
hoverBgColor = "hover:bg-destructive/90",
|
|
980
1097
|
...rest
|
|
981
1098
|
}, ref) {
|
|
982
|
-
return /* @__PURE__ */ (0,
|
|
1099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
983
1100
|
TapTargetButtonSolid,
|
|
984
1101
|
{
|
|
985
1102
|
ref,
|
|
@@ -1043,7 +1160,7 @@ var TapTargetButtonForGroup = (0, import_react2.forwardRef)(function TapTargetBu
|
|
|
1043
1160
|
|
|
1044
1161
|
// src/content-transfer/icon.ts
|
|
1045
1162
|
var ALCHEMY_GLYPH_PATHS = {
|
|
1046
|
-
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-
|
|
1163
|
+
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"],
|
|
1047
1164
|
"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"]
|
|
1048
1165
|
};
|
|
1049
1166
|
var ALCHEMY_GLYPH_VIEWBOX = { portal: "0 0 24 24", "copy-transform": "0 0 24 24" };
|
|
@@ -1051,20 +1168,38 @@ var svg = (paths, viewBox) => `<svg xmlns="http://www.w3.org/2000/svg" width="18
|
|
|
1051
1168
|
var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal, ALCHEMY_GLYPH_VIEWBOX.portal);
|
|
1052
1169
|
var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"], ALCHEMY_GLYPH_VIEWBOX["copy-transform"]);
|
|
1053
1170
|
|
|
1171
|
+
// src/content-transfer/extensions.ts
|
|
1172
|
+
var import_content_transfer = require("@ai-matrx/kit/content-transfer");
|
|
1173
|
+
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" }));
|
|
1174
|
+
function createTransferEmailActions(email, options = {}) {
|
|
1175
|
+
return ["csv", "json", "markdown"].map((format) => ({
|
|
1176
|
+
id: `email-${format}`,
|
|
1177
|
+
label: `Email ${format === "csv" ? "CSV" : format === "json" ? "JSON" : "Markdown"}`,
|
|
1178
|
+
prepared: true,
|
|
1179
|
+
group: "email",
|
|
1180
|
+
supports: (_snapshot, draft) => Boolean(draft) && (format !== "csv" || draft?.payload.kind === "rows"),
|
|
1181
|
+
async run({ draft, signal, snapshot }) {
|
|
1182
|
+
if (signal.aborted) return { status: "cancelled" };
|
|
1183
|
+
const artifact = await emailArtifact(draft, format, signal, options.jsonFormat);
|
|
1184
|
+
return email.send(artifact, { label: snapshot.label, signal });
|
|
1185
|
+
}
|
|
1186
|
+
}));
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1054
1189
|
// src/content-transfer/index.tsx
|
|
1055
|
-
var
|
|
1190
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1056
1191
|
function AlchemyGlyph({ icon = "portal", ...props }) {
|
|
1057
|
-
return /* @__PURE__ */ (0,
|
|
1192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.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_runtime13.jsx)("path", { d }, d)) });
|
|
1058
1193
|
}
|
|
1059
|
-
var CapabilityContext =
|
|
1060
|
-
var useContentTransferCapabilities = () =>
|
|
1061
|
-
var SurfaceContext =
|
|
1194
|
+
var CapabilityContext = React9.createContext({});
|
|
1195
|
+
var useContentTransferCapabilities = () => React9.useContext(CapabilityContext);
|
|
1196
|
+
var SurfaceContext = React9.createContext(null);
|
|
1062
1197
|
function MenuPresentation({ label, hint, icon: Icon2 }) {
|
|
1063
|
-
return /* @__PURE__ */ (0,
|
|
1064
|
-
Icon2 ? /* @__PURE__ */ (0,
|
|
1065
|
-
/* @__PURE__ */ (0,
|
|
1198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1199
|
+
Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : null,
|
|
1200
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1066
1201
|
label,
|
|
1067
|
-
hint ? /* @__PURE__ */ (0,
|
|
1202
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1068
1203
|
] })
|
|
1069
1204
|
] });
|
|
1070
1205
|
}
|
|
@@ -1082,71 +1217,71 @@ function DestinationPresentation({ action }) {
|
|
|
1082
1217
|
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"
|
|
1083
1218
|
};
|
|
1084
1219
|
const path = paths[action.id.replace(/^matrx:/, "")];
|
|
1085
|
-
return /* @__PURE__ */ (0,
|
|
1086
|
-
!action.icon ? path ? /* @__PURE__ */ (0,
|
|
1087
|
-
/* @__PURE__ */ (0,
|
|
1220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1221
|
+
!action.icon ? path ? /* @__PURE__ */ (0, import_jsx_runtime13.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_runtime13.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteGlyph, { file: true }) : null,
|
|
1222
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MenuPresentation, { ...action })
|
|
1088
1223
|
] });
|
|
1089
1224
|
}
|
|
1090
1225
|
function ReceiptLink({ target }) {
|
|
1091
|
-
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0,
|
|
1226
|
+
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
|
|
1092
1227
|
"Open ",
|
|
1093
1228
|
target.kind
|
|
1094
1229
|
] }) : null;
|
|
1095
1230
|
}
|
|
1096
1231
|
function PaletteGlyph({ format, ai = false, file = false, kind }) {
|
|
1097
|
-
if (kind === "ai-copy") return /* @__PURE__ */ (0,
|
|
1098
|
-
/* @__PURE__ */ (0,
|
|
1099
|
-
/* @__PURE__ */ (0,
|
|
1100
|
-
/* @__PURE__ */ (0,
|
|
1232
|
+
if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime13.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: [
|
|
1233
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
|
|
1235
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
|
|
1101
1236
|
] });
|
|
1102
|
-
if (kind === "sliders") return /* @__PURE__ */ (0,
|
|
1103
|
-
/* @__PURE__ */ (0,
|
|
1104
|
-
/* @__PURE__ */ (0,
|
|
1237
|
+
if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime13.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: [
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
|
|
1239
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
|
|
1105
1240
|
] });
|
|
1106
|
-
if (ai) return /* @__PURE__ */ (0,
|
|
1107
|
-
/* @__PURE__ */ (0,
|
|
1108
|
-
/* @__PURE__ */ (0,
|
|
1109
|
-
/* @__PURE__ */ (0,
|
|
1241
|
+
if (ai) return /* @__PURE__ */ (0, import_jsx_runtime13.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: [
|
|
1242
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" }),
|
|
1243
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" }),
|
|
1244
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
|
|
1110
1245
|
] });
|
|
1111
|
-
if (file) return /* @__PURE__ */ (0,
|
|
1112
|
-
/* @__PURE__ */ (0,
|
|
1113
|
-
/* @__PURE__ */ (0,
|
|
1246
|
+
if (file) return /* @__PURE__ */ (0, import_jsx_runtime13.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: [
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
|
|
1248
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
|
|
1114
1249
|
] });
|
|
1115
|
-
const path = format === "json" ? /* @__PURE__ */ (0,
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1117
|
-
/* @__PURE__ */ (0,
|
|
1118
|
-
] }) : format === "compact-json" ? /* @__PURE__ */ (0,
|
|
1119
|
-
/* @__PURE__ */ (0,
|
|
1120
|
-
/* @__PURE__ */ (0,
|
|
1121
|
-
/* @__PURE__ */ (0,
|
|
1122
|
-
/* @__PURE__ */ (0,
|
|
1123
|
-
] }) : format === "csv" ? /* @__PURE__ */ (0,
|
|
1124
|
-
/* @__PURE__ */ (0,
|
|
1125
|
-
/* @__PURE__ */ (0,
|
|
1126
|
-
] }) : format === "tsv" ? /* @__PURE__ */ (0,
|
|
1127
|
-
/* @__PURE__ */ (0,
|
|
1128
|
-
/* @__PURE__ */ (0,
|
|
1129
|
-
] }) : format === "xlsx" ? /* @__PURE__ */ (0,
|
|
1130
|
-
/* @__PURE__ */ (0,
|
|
1131
|
-
/* @__PURE__ */ (0,
|
|
1132
|
-
] }) : format === "markdown" ? /* @__PURE__ */ (0,
|
|
1133
|
-
/* @__PURE__ */ (0,
|
|
1134
|
-
/* @__PURE__ */ (0,
|
|
1135
|
-
] }) : format === "html" ? /* @__PURE__ */ (0,
|
|
1136
|
-
return /* @__PURE__ */ (0,
|
|
1250
|
+
const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1251
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
|
|
1252
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" })
|
|
1253
|
+
] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1254
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m14 10 7-7" }),
|
|
1255
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M20 10h-6V4" }),
|
|
1256
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "m3 21 7-7" }),
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 14h6v6" })
|
|
1258
|
+
] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1259
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
|
|
1260
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 10h16M10 4v16" })
|
|
1261
|
+
] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1262
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1263
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
|
|
1264
|
+
] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1265
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1266
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
|
|
1267
|
+
] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1268
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" }),
|
|
1269
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
|
|
1270
|
+
] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
|
|
1271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.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 });
|
|
1137
1272
|
}
|
|
1138
1273
|
function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
|
|
1139
1274
|
if (!items.length && !extra) return null;
|
|
1140
|
-
return /* @__PURE__ */ (0,
|
|
1141
|
-
/* @__PURE__ */ (0,
|
|
1275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
|
|
1276
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { children: title }),
|
|
1142
1277
|
items.map((item) => {
|
|
1143
1278
|
const label = item.copyLabel ?? item.label;
|
|
1144
1279
|
const hint = item.hint ?? fallbackHint;
|
|
1145
|
-
return /* @__PURE__ */ (0,
|
|
1146
|
-
item.icon ? /* @__PURE__ */ (0,
|
|
1147
|
-
/* @__PURE__ */ (0,
|
|
1280
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.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: [
|
|
1281
|
+
item.icon ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
|
|
1282
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1148
1283
|
label,
|
|
1149
|
-
hint ? /* @__PURE__ */ (0,
|
|
1284
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1150
1285
|
] })
|
|
1151
1286
|
] }, item.id);
|
|
1152
1287
|
}),
|
|
@@ -1189,10 +1324,10 @@ function snapshotContent(snapshot) {
|
|
|
1189
1324
|
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
1190
1325
|
}
|
|
1191
1326
|
function useFence() {
|
|
1192
|
-
const mounted =
|
|
1193
|
-
const nextId =
|
|
1194
|
-
const active =
|
|
1195
|
-
|
|
1327
|
+
const mounted = React9.useRef(true);
|
|
1328
|
+
const nextId = React9.useRef(0);
|
|
1329
|
+
const active = React9.useRef(/* @__PURE__ */ new Set());
|
|
1330
|
+
React9.useEffect(() => {
|
|
1196
1331
|
mounted.current = true;
|
|
1197
1332
|
return () => {
|
|
1198
1333
|
mounted.current = false;
|
|
@@ -1201,14 +1336,14 @@ function useFence() {
|
|
|
1201
1336
|
active.current.clear();
|
|
1202
1337
|
};
|
|
1203
1338
|
}, []);
|
|
1204
|
-
const begin =
|
|
1339
|
+
const begin = React9.useCallback(() => {
|
|
1205
1340
|
const controller = new AbortController();
|
|
1206
1341
|
active.current.add(controller);
|
|
1207
1342
|
return { controller, id: ++nextId.current };
|
|
1208
1343
|
}, []);
|
|
1209
|
-
const finish =
|
|
1210
|
-
const valid =
|
|
1211
|
-
const abortAll =
|
|
1344
|
+
const finish = React9.useCallback((controller) => active.current.delete(controller), []);
|
|
1345
|
+
const valid = React9.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
|
|
1346
|
+
const abortAll = React9.useCallback(() => {
|
|
1212
1347
|
nextId.current += 1;
|
|
1213
1348
|
active.current.forEach((c) => c.abort());
|
|
1214
1349
|
active.current.clear();
|
|
@@ -1220,73 +1355,79 @@ async function xlsxArtifact(draft, label) {
|
|
|
1220
1355
|
const XLSX = await import("xlsx");
|
|
1221
1356
|
const columns = draft.payload.columns.filter((c) => c.visible && c.exportable !== false && c.classification !== "secret" && c.classification !== "credential");
|
|
1222
1357
|
const cells = draft.payload.rows.map((row) => columns.map((column) => {
|
|
1223
|
-
const value = (0,
|
|
1358
|
+
const value = (0, import_content_transfer2.readTransferCell)(row, column);
|
|
1224
1359
|
return value === null || ["string", "number", "boolean"].includes(typeof value) ? value : value === void 0 ? "" : JSON.stringify(value);
|
|
1225
1360
|
}));
|
|
1226
1361
|
const sheet = XLSX.utils.aoa_to_sheet([columns.map((c) => c.label), ...cells]);
|
|
1227
1362
|
const book = XLSX.utils.book_new();
|
|
1228
1363
|
XLSX.utils.book_append_sheet(book, sheet, label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data");
|
|
1229
1364
|
const written = XLSX.write(book, { type: "array", bookType: "xlsx", compression: true });
|
|
1230
|
-
return (0,
|
|
1365
|
+
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] });
|
|
1231
1366
|
}
|
|
1232
1367
|
async function buildArtifact(draft, format, label) {
|
|
1233
1368
|
if (!supportsBuiltIn(format, draft.payload)) throw new Error(`${LABEL[format]} is available for tabular content only.`);
|
|
1234
1369
|
if (format === "xlsx") return xlsxArtifact(draft, label);
|
|
1235
|
-
if (format === "html" && draft.payload.kind === "markdown") return (0,
|
|
1370
|
+
if (format === "html" && draft.payload.kind === "markdown") return (0, import_content_transfer2.serializeMarkdownRich)(draft, `${filenameFor(label)}.html`);
|
|
1236
1371
|
const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
|
|
1237
|
-
return (0,
|
|
1372
|
+
return (0, import_content_transfer2.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
1238
1373
|
}
|
|
1239
1374
|
function ContentTransferMenu(props) {
|
|
1240
|
-
const inherited =
|
|
1375
|
+
const inherited = React9.useContext(CapabilityContext);
|
|
1241
1376
|
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
1242
|
-
return /* @__PURE__ */ (0,
|
|
1377
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
1243
1378
|
}
|
|
1244
|
-
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" }) {
|
|
1245
|
-
const triggerRef =
|
|
1246
|
-
const inherited =
|
|
1247
|
-
const nearestSurface =
|
|
1379
|
+
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" }) {
|
|
1380
|
+
const triggerRef = React9.useRef(null);
|
|
1381
|
+
const inherited = React9.useContext(CapabilityContext);
|
|
1382
|
+
const nearestSurface = React9.useContext(SurfaceContext);
|
|
1248
1383
|
const fence = useFence();
|
|
1249
|
-
const [menuCapture, setMenuCapture] =
|
|
1250
|
-
const [menuStatus, setMenuStatus] =
|
|
1251
|
-
const [workspaces, setWorkspaces] =
|
|
1252
|
-
const [workspaceKey, setWorkspaceKey] =
|
|
1253
|
-
const [workspaceOpen, setWorkspaceOpen] =
|
|
1254
|
-
const workspaceCaptures =
|
|
1255
|
-
const externalWorkspaceKeys =
|
|
1256
|
-
const [notice, setNotice] =
|
|
1257
|
-
const [receiptTarget, setReceiptTarget] =
|
|
1258
|
-
const [paletteOpen, setPaletteOpen] =
|
|
1259
|
-
const [mode, setMode] =
|
|
1260
|
-
const scopes =
|
|
1261
|
-
const
|
|
1384
|
+
const [menuCapture, setMenuCapture] = React9.useState(null);
|
|
1385
|
+
const [menuStatus, setMenuStatus] = React9.useState("idle");
|
|
1386
|
+
const [workspaces, setWorkspaces] = React9.useState({});
|
|
1387
|
+
const [workspaceKey, setWorkspaceKey] = React9.useState(null);
|
|
1388
|
+
const [workspaceOpen, setWorkspaceOpen] = React9.useState(false);
|
|
1389
|
+
const workspaceCaptures = React9.useRef(/* @__PURE__ */ new Map());
|
|
1390
|
+
const externalWorkspaceKeys = React9.useRef(/* @__PURE__ */ new Set());
|
|
1391
|
+
const [notice, setNotice] = React9.useState(null);
|
|
1392
|
+
const [receiptTarget, setReceiptTarget] = React9.useState();
|
|
1393
|
+
const [paletteOpen, setPaletteOpen] = React9.useState(false);
|
|
1394
|
+
const [mode, setMode] = React9.useState("copy");
|
|
1395
|
+
const scopes = React9.useMemo(() => table?.availableScopes ?? ["target"], [table]);
|
|
1396
|
+
const [requestedScope, setRequestedScope] = React9.useState(table?.initialScope ?? "target");
|
|
1397
|
+
const initialScope = scopes.includes(requestedScope) ? requestedScope : table?.initialScope ?? "target";
|
|
1262
1398
|
if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
|
|
1263
1399
|
const primary = surface ?? source ?? nearestSurface;
|
|
1264
1400
|
const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
|
|
1265
|
-
const
|
|
1401
|
+
const primaryWorkspaceBase = `primary:${materialIdentity(primary)}`;
|
|
1402
|
+
const primaryWorkspaceKey = `${primaryWorkspaceBase}:${initialScope}`;
|
|
1266
1403
|
const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
|
|
1267
|
-
const variantWorkspaceKeys =
|
|
1268
|
-
const transport = local?.transport ?? inherited.transport ?? (0,
|
|
1404
|
+
const variantWorkspaceKeys = React9.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
|
|
1405
|
+
const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer2.createBrowserTransport)();
|
|
1269
1406
|
const ai = local?.ai ?? inherited.ai;
|
|
1270
|
-
const
|
|
1271
|
-
const
|
|
1272
|
-
const
|
|
1273
|
-
|
|
1274
|
-
const
|
|
1407
|
+
const referencePort = local?.reference ?? inherited.reference;
|
|
1408
|
+
const { email: emailPort, review: emailReview } = useReviewedTransferEmail(local?.email ?? inherited.email);
|
|
1409
|
+
const providerPreferences = React9.useMemo(() => (0, import_content_transfer2.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
|
|
1410
|
+
const adapters = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
|
|
1411
|
+
const emailJsonFormat = adapters.find((adapter) => adapter.id === "table-data");
|
|
1412
|
+
const emailActions = React9.useMemo(() => emailPort ? createTransferEmailActions(emailPort, emailJsonFormat ? { jsonFormat: emailJsonFormat } : {}) : [], [emailPort, emailJsonFormat]);
|
|
1413
|
+
const registeredActions = React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(emailActions, inherited.actions ?? [], local?.actions ?? [], actions), [actions, emailActions, inherited.actions, local?.actions]);
|
|
1414
|
+
React9.useMemo(() => (0, import_content_transfer2.resolveTransferRegistry)(variants), [variants]);
|
|
1415
|
+
const report = React9.useCallback((result) => {
|
|
1275
1416
|
inherited.onOutcome?.(result);
|
|
1276
1417
|
local?.onOutcome?.(result);
|
|
1277
1418
|
setNotice(outcomeMessage(result));
|
|
1278
1419
|
setReceiptTarget("target" in result ? result.target : void 0);
|
|
1279
1420
|
}, [inherited, local]);
|
|
1280
|
-
|
|
1281
|
-
const valid = /* @__PURE__ */ new Set([
|
|
1421
|
+
React9.useEffect(() => {
|
|
1422
|
+
const valid = /* @__PURE__ */ new Set([...scopes.map((scope) => `${primaryWorkspaceBase}:${scope}`), ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
|
|
1282
1423
|
setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
|
|
1283
1424
|
for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
|
|
1284
1425
|
if (workspaceKey && !valid.has(workspaceKey)) {
|
|
1285
1426
|
setWorkspaceKey(null);
|
|
1286
1427
|
setWorkspaceOpen(false);
|
|
1287
1428
|
}
|
|
1288
|
-
}, [nearestWorkspaceKey,
|
|
1289
|
-
const captureOne =
|
|
1429
|
+
}, [nearestWorkspaceKey, primaryWorkspaceBase, scopes, variantWorkspaceKeys, workspaceKey]);
|
|
1430
|
+
const captureOne = React9.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
|
|
1290
1431
|
if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
|
|
1291
1432
|
let sourceMaterial;
|
|
1292
1433
|
if ("instanceId" in material) {
|
|
@@ -1294,7 +1435,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1294
1435
|
const captured = await material.capture(signal);
|
|
1295
1436
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
1296
1437
|
} else if ("kind" in material) {
|
|
1297
|
-
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0,
|
|
1438
|
+
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 } : {} }) };
|
|
1298
1439
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
1299
1440
|
sourceMaterial = {
|
|
1300
1441
|
id: material.id,
|
|
@@ -1312,27 +1453,27 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1312
1453
|
sourceMaterial = material;
|
|
1313
1454
|
}
|
|
1314
1455
|
const raw = await sourceMaterial.capture({ scope, signal });
|
|
1315
|
-
const constrained = (0,
|
|
1316
|
-
const result = await (0,
|
|
1456
|
+
const constrained = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
|
|
1457
|
+
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);
|
|
1317
1458
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
1318
1459
|
if (!result.allMatching) throw new Error("This source cannot provide a stable all-matching export.");
|
|
1319
|
-
const collected = await (0,
|
|
1460
|
+
const collected = await (0, import_content_transfer2.collectAllMatching)(result.allMatching, signal);
|
|
1320
1461
|
if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
|
|
1321
|
-
return { snapshot: (0,
|
|
1462
|
+
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 } : {} };
|
|
1322
1463
|
}, [preferences, projection, providerPreferences, sections, sourceLabel]);
|
|
1323
|
-
const capturePrimary =
|
|
1464
|
+
const capturePrimary = React9.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
|
|
1324
1465
|
workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
|
|
1325
1466
|
if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
|
|
1326
1467
|
for (const variant of variants) {
|
|
1327
1468
|
const key = variantWorkspaceKeys.get(variant.id);
|
|
1328
1469
|
workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
|
|
1329
1470
|
}
|
|
1330
|
-
const preflight =
|
|
1471
|
+
const preflight = React9.useCallback(async (scope = initialScope) => {
|
|
1331
1472
|
const { controller, id } = fence.begin();
|
|
1332
1473
|
setMenuCapture(null);
|
|
1333
1474
|
setMenuStatus("loading");
|
|
1334
1475
|
try {
|
|
1335
|
-
const result = await captureOne(primary,
|
|
1476
|
+
const result = await captureOne(primary, scope, controller.signal, true, false);
|
|
1336
1477
|
if (fence.valid(id, controller)) {
|
|
1337
1478
|
setMenuCapture(result);
|
|
1338
1479
|
setMenuStatus("idle");
|
|
@@ -1346,7 +1487,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1346
1487
|
fence.finish(controller);
|
|
1347
1488
|
}
|
|
1348
1489
|
}, [captureOne, fence, initialScope, primary]);
|
|
1349
|
-
const transfer =
|
|
1490
|
+
const transfer = React9.useCallback(async (format, download, alternate) => {
|
|
1350
1491
|
const { controller, id } = fence.begin();
|
|
1351
1492
|
try {
|
|
1352
1493
|
const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
|
|
@@ -1356,8 +1497,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1356
1497
|
const reason = result.snapshot.coverage.reason ?? `${result.snapshot.omissions.length} omission${result.snapshot.omissions.length === 1 ? "" : "s"}`;
|
|
1357
1498
|
throw new Error(`Quick transfer is partial (${reason}). Open Prepare for AI to review it before delivery.`);
|
|
1358
1499
|
}
|
|
1359
|
-
const resolved = (0,
|
|
1360
|
-
const draft = (0,
|
|
1500
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, result.snapshot.limits);
|
|
1501
|
+
const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(result.snapshot), resolved.limits);
|
|
1361
1502
|
const revision = draft.revision;
|
|
1362
1503
|
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.");
|
|
1363
1504
|
const artifact = typeof format === "string" ? await buildArtifact(draft, format, result.snapshot.label) : await format.build(draft, controller.signal);
|
|
@@ -1371,12 +1512,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1371
1512
|
fence.finish(controller);
|
|
1372
1513
|
}
|
|
1373
1514
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
1374
|
-
const openWorkspace =
|
|
1515
|
+
const openWorkspace = React9.useCallback(
|
|
1375
1516
|
async (key = primaryWorkspaceKey, variant) => {
|
|
1376
1517
|
const variantMaterial = variant && "kind" in variant.source ? {
|
|
1377
1518
|
id: `variant:${key}`,
|
|
1378
1519
|
label: variant.label,
|
|
1379
|
-
capture: async () => (0,
|
|
1520
|
+
capture: async () => (0, import_content_transfer2.directSource)(variant.source, {
|
|
1380
1521
|
sourceId: `variant:${key}`,
|
|
1381
1522
|
label: variant.label
|
|
1382
1523
|
})
|
|
@@ -1387,15 +1528,16 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1387
1528
|
const { controller, id } = fence.begin();
|
|
1388
1529
|
if (existing) {
|
|
1389
1530
|
try {
|
|
1390
|
-
const
|
|
1531
|
+
const scopeChanged = existing.scope !== initialScope;
|
|
1532
|
+
const allMatching = initialScope === "all-matching";
|
|
1391
1533
|
const fresh = await captureWorkspace(
|
|
1392
|
-
|
|
1534
|
+
initialScope,
|
|
1393
1535
|
controller.signal,
|
|
1394
|
-
!allMatching
|
|
1536
|
+
scopeChanged || !allMatching
|
|
1395
1537
|
);
|
|
1396
1538
|
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
1397
1539
|
return;
|
|
1398
|
-
if (allMatching && (!
|
|
1540
|
+
if (allMatching && (!fresh.allMatching || !scopeChanged && !existing.allMatching))
|
|
1399
1541
|
throw new Error(
|
|
1400
1542
|
"This source can no longer provide an all-matching snapshot."
|
|
1401
1543
|
);
|
|
@@ -1405,7 +1547,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1405
1547
|
columns: value.columns,
|
|
1406
1548
|
limits: value.limits
|
|
1407
1549
|
};
|
|
1408
|
-
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
1550
|
+
const changed = scopeChanged || (allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot));
|
|
1409
1551
|
setWorkspaces((current) => {
|
|
1410
1552
|
const retained = current[key];
|
|
1411
1553
|
if (!retained) return current;
|
|
@@ -1414,7 +1556,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1414
1556
|
[key]: {
|
|
1415
1557
|
...retained,
|
|
1416
1558
|
error: fresh.collectionError,
|
|
1417
|
-
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope:
|
|
1559
|
+
...allMatching && !scopeChanged ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: initialScope } } : { pending: void 0 }
|
|
1418
1560
|
}
|
|
1419
1561
|
};
|
|
1420
1562
|
});
|
|
@@ -1442,12 +1584,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1442
1584
|
try {
|
|
1443
1585
|
const result = await captureWorkspace(initialScope, controller.signal);
|
|
1444
1586
|
if (!fence.valid(id, controller)) return;
|
|
1445
|
-
const resolved = (0,
|
|
1587
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(
|
|
1446
1588
|
providerPreferences,
|
|
1447
1589
|
preferences,
|
|
1448
1590
|
result.snapshot.limits
|
|
1449
1591
|
);
|
|
1450
|
-
const original = (0,
|
|
1592
|
+
const original = (0, import_content_transfer2.createDraft)(result.snapshot);
|
|
1451
1593
|
const base = {
|
|
1452
1594
|
...result,
|
|
1453
1595
|
key,
|
|
@@ -1483,7 +1625,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1483
1625
|
workspaces
|
|
1484
1626
|
]
|
|
1485
1627
|
);
|
|
1486
|
-
|
|
1628
|
+
React9.useImperativeHandle(controllerRef, () => ({
|
|
1487
1629
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
1488
1630
|
prepare: async (requestedSource, options) => {
|
|
1489
1631
|
const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
|
|
@@ -1492,13 +1634,13 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1492
1634
|
await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
|
|
1493
1635
|
}
|
|
1494
1636
|
}), [openWorkspace]);
|
|
1495
|
-
const runAction =
|
|
1637
|
+
const runAction = React9.useCallback(async (action) => {
|
|
1496
1638
|
const { controller, id } = fence.begin();
|
|
1497
1639
|
try {
|
|
1498
1640
|
const actionSource = action.source;
|
|
1499
1641
|
const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
|
|
1500
|
-
const resolved = (0,
|
|
1501
|
-
const draft = (0,
|
|
1642
|
+
const resolved = (0, import_content_transfer2.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
|
|
1643
|
+
const draft = (0, import_content_transfer2.applyTransferLimits)((0, import_content_transfer2.createDraft)(snapshot), resolved.limits);
|
|
1502
1644
|
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.");
|
|
1503
1645
|
if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
|
|
1504
1646
|
const result = await action.run({ snapshot, draft, signal: controller.signal });
|
|
@@ -1509,13 +1651,38 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1509
1651
|
fence.finish(controller);
|
|
1510
1652
|
}
|
|
1511
1653
|
}, [captureOne, capturePrimary, fence, initialScope, preferences, providerPreferences, report]);
|
|
1654
|
+
const copyReference = async (reference) => {
|
|
1655
|
+
const { controller, id } = fence.begin();
|
|
1656
|
+
closePalette();
|
|
1657
|
+
try {
|
|
1658
|
+
if (!referencePort?.supports(reference)) throw new Error("This reference is not registered or its identity is incomplete.");
|
|
1659
|
+
const text = await referencePort.build(reference);
|
|
1660
|
+
if (!text.trim()) throw new Error("The reference serializer returned no content.");
|
|
1661
|
+
const artifact = (0, import_content_transfer2.sealTransferArtifact)({ snapshotId: `reference:${reference.id}`, draftRevision: 0, format: "matrx-reference", plainText: text, omissions: [] });
|
|
1662
|
+
if (!fence.valid(id, controller)) return;
|
|
1663
|
+
const outcome = await transport.copy(artifact, controller.signal);
|
|
1664
|
+
if (fence.valid(id, controller)) report(outcome);
|
|
1665
|
+
} catch (error) {
|
|
1666
|
+
if (fence.valid(id, controller)) report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not copy reference"), retryable: true });
|
|
1667
|
+
} finally {
|
|
1668
|
+
fence.finish(controller);
|
|
1669
|
+
}
|
|
1670
|
+
};
|
|
1671
|
+
const openReference = async (action) => {
|
|
1672
|
+
closePalette();
|
|
1673
|
+
try {
|
|
1674
|
+
await action.run();
|
|
1675
|
+
} catch (error) {
|
|
1676
|
+
report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not open reference picker"), retryable: true });
|
|
1677
|
+
}
|
|
1678
|
+
};
|
|
1512
1679
|
if (!enabled) return null;
|
|
1513
1680
|
const payload = menuCapture?.snapshot.payload ?? (source && "kind" in source ? source : void 0);
|
|
1514
1681
|
const quickVariants = (section) => variants.filter((v) => v.copyLabel && (v.section ?? "ai") === section);
|
|
1515
1682
|
const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
|
|
1516
1683
|
const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
|
|
1517
1684
|
const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
|
|
1518
|
-
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0,
|
|
1685
|
+
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))) : [];
|
|
1519
1686
|
const downloadActions = visibleActions.filter((action) => action.placement === "download");
|
|
1520
1687
|
const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
|
|
1521
1688
|
const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
|
|
@@ -1528,8 +1695,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1528
1695
|
label: "AI context",
|
|
1529
1696
|
supports: () => true,
|
|
1530
1697
|
build: async (draft) => {
|
|
1531
|
-
const json = (0,
|
|
1532
|
-
return (0,
|
|
1698
|
+
const json = (0, import_content_transfer2.serialize)(draft, "json");
|
|
1699
|
+
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] });
|
|
1533
1700
|
}
|
|
1534
1701
|
};
|
|
1535
1702
|
const closePalette = () => setPaletteOpen(false);
|
|
@@ -1537,106 +1704,123 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1537
1704
|
const presentation = options.action;
|
|
1538
1705
|
const Icon2 = presentation?.icon;
|
|
1539
1706
|
const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
|
|
1540
|
-
return /* @__PURE__ */ (0,
|
|
1707
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
|
|
1541
1708
|
closePalette();
|
|
1542
1709
|
onClick();
|
|
1543
1710
|
}, children: [
|
|
1544
|
-
Icon2 ? /* @__PURE__ */ (0,
|
|
1545
|
-
/* @__PURE__ */ (0,
|
|
1711
|
+
Icon2 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon2, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
|
|
1712
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1546
1713
|
label2,
|
|
1547
|
-
presentation?.hint ? /* @__PURE__ */ (0,
|
|
1714
|
+
presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
|
|
1548
1715
|
] })
|
|
1549
1716
|
] }, id);
|
|
1550
1717
|
};
|
|
1551
|
-
return /* @__PURE__ */ (0,
|
|
1552
|
-
/* @__PURE__ */ (0,
|
|
1718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
|
|
1719
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
|
|
1553
1720
|
setPaletteOpen(open);
|
|
1554
1721
|
if (open) {
|
|
1555
1722
|
setMode("copy");
|
|
1556
1723
|
void preflight();
|
|
1557
1724
|
}
|
|
1558
1725
|
}, children: [
|
|
1559
|
-
/* @__PURE__ */ (0,
|
|
1560
|
-
/* @__PURE__ */ (0,
|
|
1561
|
-
menuStatus === "loading" ? /* @__PURE__ */ (0,
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1726
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime13.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_runtime13.jsx)(AlchemyGlyph, { icon }) }) : triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", "data-alchemy-size": triggerSize, disabled }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", "data-alchemy-size": triggerSize, disabled }) }),
|
|
1727
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
|
|
1728
|
+
menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
|
|
1729
|
+
table && scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "matrx-alchemy-scope", children: [
|
|
1730
|
+
"Content scope",
|
|
1731
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
|
|
1732
|
+
const next = scopes.find((scope) => scope === event.target.value);
|
|
1733
|
+
if (next) {
|
|
1734
|
+
setRequestedScope(next);
|
|
1735
|
+
void preflight(next);
|
|
1736
|
+
}
|
|
1737
|
+
}, children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
|
|
1738
|
+
] }) : null,
|
|
1739
|
+
copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: "matrx-alchemy-output", children: [
|
|
1740
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
|
|
1741
|
+
copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
|
|
1742
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
|
|
1743
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
|
|
1567
1744
|
] }) : null,
|
|
1568
|
-
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0,
|
|
1569
|
-
/* @__PURE__ */ (0,
|
|
1745
|
+
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1746
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
1570
1747
|
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]}` })),
|
|
1571
1748
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
|
|
1572
1749
|
] }),
|
|
1573
|
-
quickVariants("copy").length ? /* @__PURE__ */ (0,
|
|
1750
|
+
quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
|
|
1574
1751
|
closePalette();
|
|
1575
1752
|
void transfer("markdown", false, variant);
|
|
1576
1753
|
} }) : null
|
|
1577
1754
|
] }) : null,
|
|
1578
|
-
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0,
|
|
1755
|
+
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_jsx_runtime13.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
1579
1756
|
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]}` })),
|
|
1580
1757
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
|
|
1581
1758
|
downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
|
|
1582
1759
|
] }) }) : null
|
|
1583
1760
|
] }) : null,
|
|
1584
|
-
prepareAvailable ? /* @__PURE__ */ (0,
|
|
1585
|
-
/* @__PURE__ */ (0,
|
|
1761
|
+
prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1762
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
1586
1763
|
closePalette();
|
|
1587
1764
|
void transfer(nativeAiFormat, false);
|
|
1588
1765
|
}, children: [
|
|
1589
|
-
/* @__PURE__ */ (0,
|
|
1590
|
-
/* @__PURE__ */ (0,
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteGlyph, { kind: "ai-copy" }),
|
|
1767
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1591
1768
|
"Copy with AI context",
|
|
1592
|
-
/* @__PURE__ */ (0,
|
|
1769
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
|
|
1593
1770
|
] })
|
|
1594
1771
|
] }) : null, items: quickVariants("ai"), onRun: (variant) => {
|
|
1595
1772
|
closePalette();
|
|
1596
1773
|
void transfer("markdown", false, variant);
|
|
1597
1774
|
} }),
|
|
1598
|
-
/* @__PURE__ */ (0,
|
|
1775
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
|
|
1599
1776
|
closePalette();
|
|
1600
1777
|
void openWorkspace();
|
|
1601
1778
|
}, children: [
|
|
1602
|
-
/* @__PURE__ */ (0,
|
|
1603
|
-
/* @__PURE__ */ (0,
|
|
1779
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteGlyph, { kind: "sliders" }),
|
|
1780
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
1604
1781
|
"Prepare for AI",
|
|
1605
|
-
/* @__PURE__ */ (0,
|
|
1782
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
|
|
1606
1783
|
] })
|
|
1607
1784
|
] }) })
|
|
1608
1785
|
] }) : null,
|
|
1609
|
-
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0,
|
|
1610
|
-
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0,
|
|
1786
|
+
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1787
|
+
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
1611
1788
|
closePalette();
|
|
1612
1789
|
void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
|
|
1613
|
-
}, children: /* @__PURE__ */ (0,
|
|
1614
|
-
variants.map((variant) => /* @__PURE__ */ (0,
|
|
1790
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: "Prepare this surface" }) }) : null,
|
|
1791
|
+
variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
|
|
1615
1792
|
closePalette();
|
|
1616
1793
|
void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
|
|
1617
|
-
}, children: /* @__PURE__ */ (0,
|
|
1794
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
|
|
1618
1795
|
] }) }) : null,
|
|
1619
|
-
|
|
1796
|
+
references.length || referenceActions.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
|
|
1797
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { children: "Live references" }),
|
|
1798
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "matrx-alchemy-menu-hint", children: "Pointers to saved data, independent of filters and edits." }),
|
|
1799
|
+
references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void copyReference(reference), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: reference.label }) }, reference.id)),
|
|
1800
|
+
referenceActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: action.label }) }, action.id))
|
|
1801
|
+
] }) : null,
|
|
1802
|
+
["save", "chat", "email", "other"].map((group) => {
|
|
1620
1803
|
const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
|
|
1621
|
-
return entries.length ? /* @__PURE__ */ (0,
|
|
1622
|
-
/* @__PURE__ */ (0,
|
|
1623
|
-
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1804
|
+
return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
|
|
1805
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
1806
|
+
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
|
|
1807
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: entries.length })
|
|
1625
1808
|
] }),
|
|
1626
|
-
/* @__PURE__ */ (0,
|
|
1809
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
|
|
1627
1810
|
closePalette();
|
|
1628
1811
|
void runAction(action);
|
|
1629
|
-
}, children: /* @__PURE__ */ (0,
|
|
1812
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DestinationPresentation, { action }) }, action.id)) })
|
|
1630
1813
|
] }, group) : null;
|
|
1631
1814
|
})
|
|
1632
1815
|
] })
|
|
1633
1816
|
] }),
|
|
1634
|
-
notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0,
|
|
1635
|
-
/* @__PURE__ */ (0,
|
|
1636
|
-
/* @__PURE__ */ (0,
|
|
1637
|
-
/* @__PURE__ */ (0,
|
|
1817
|
+
notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
|
|
1818
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { role: "status", children: notice }),
|
|
1819
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ReceiptLink, { target: receiptTarget }),
|
|
1820
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
|
|
1638
1821
|
] }), triggerRef.current.ownerDocument.body) : null,
|
|
1639
|
-
Object.values(workspaces).map((saved) => /* @__PURE__ */ (0,
|
|
1822
|
+
Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime13.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)),
|
|
1823
|
+
emailReview
|
|
1640
1824
|
] });
|
|
1641
1825
|
}
|
|
1642
1826
|
function initialControls(state) {
|
|
@@ -1664,9 +1848,9 @@ function presetLimits(preset, controls, preferences) {
|
|
|
1664
1848
|
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) };
|
|
1665
1849
|
}
|
|
1666
1850
|
function rebuild(state, controls) {
|
|
1667
|
-
let draft = (0,
|
|
1668
|
-
if (state.snapshot.sections.length) draft = (0,
|
|
1669
|
-
if (draft.payload.kind === "rows") draft = (0,
|
|
1851
|
+
let draft = (0, import_content_transfer2.resetDraft)(state.snapshot);
|
|
1852
|
+
if (state.snapshot.sections.length) draft = (0, import_content_transfer2.applySectionSelection)(draft, state.snapshot, controls.sections);
|
|
1853
|
+
if (draft.payload.kind === "rows") draft = (0, import_content_transfer2.transformRows)(draft, {
|
|
1670
1854
|
search: controls.search,
|
|
1671
1855
|
filters: controls.filters,
|
|
1672
1856
|
...controls.sort ? { sort: { column: controls.sort, direction: controls.direction } } : {},
|
|
@@ -1677,45 +1861,45 @@ function rebuild(state, controls) {
|
|
|
1677
1861
|
});
|
|
1678
1862
|
const limits = presetLimits(controls.preset, controls, state.preferences);
|
|
1679
1863
|
if (draft.payload.kind === "json" || draft.payload.kind === "registered") {
|
|
1680
|
-
draft = (0,
|
|
1864
|
+
draft = (0, import_content_transfer2.reduceJson)(draft, { maxDepth: limits.maxDepth, maxStringChars: limits.maxStringChars, maxArrayItems: limits.maxArrayItems ?? null });
|
|
1681
1865
|
}
|
|
1682
|
-
return (0,
|
|
1866
|
+
return (0, import_content_transfer2.applyTransferLimits)(draft, limits);
|
|
1683
1867
|
}
|
|
1684
1868
|
function isBuiltInFormat(format) {
|
|
1685
1869
|
return format in LABEL;
|
|
1686
1870
|
}
|
|
1687
1871
|
function preview(draft, format) {
|
|
1688
1872
|
const resolved = isBuiltInFormat(format) ? format : "plain";
|
|
1689
|
-
return (0,
|
|
1873
|
+
return (0, import_content_transfer2.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
|
|
1690
1874
|
}
|
|
1691
|
-
function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
1875
|
+
function PreparationWorkspace({ restoreFocus, open, state, scopes, scopeLabels, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
1692
1876
|
const fence = useFence();
|
|
1693
|
-
const latest =
|
|
1877
|
+
const latest = React9.useRef(state);
|
|
1694
1878
|
latest.current = state;
|
|
1695
|
-
const aiSession =
|
|
1879
|
+
const aiSession = React9.useRef(void 0);
|
|
1696
1880
|
if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
|
|
1697
|
-
const [controls, setControls] =
|
|
1698
|
-
const [controlsHistory, setControlsHistory] =
|
|
1699
|
-
const [pendingControls, setPendingControls] =
|
|
1881
|
+
const [controls, setControls] = React9.useState(() => initialControls(state));
|
|
1882
|
+
const [controlsHistory, setControlsHistory] = React9.useState([]);
|
|
1883
|
+
const [pendingControls, setPendingControls] = React9.useState(null);
|
|
1700
1884
|
const requestedFormat = state.preferences.initialFormat;
|
|
1701
|
-
const [format, setFormat] =
|
|
1702
|
-
const [buffer, setBuffer] =
|
|
1703
|
-
const [bufferError, setBufferError] =
|
|
1704
|
-
const [formatError, setFormatError] =
|
|
1705
|
-
const [preparedArtifact, setPreparedArtifact] =
|
|
1706
|
-
const [instruction, setInstruction] =
|
|
1707
|
-
const [busy, setBusy] =
|
|
1708
|
-
const [aiFailed, setAiFailed] =
|
|
1709
|
-
|
|
1885
|
+
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");
|
|
1886
|
+
const [buffer, setBuffer] = React9.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
|
|
1887
|
+
const [bufferError, setBufferError] = React9.useState(null);
|
|
1888
|
+
const [formatError, setFormatError] = React9.useState(null);
|
|
1889
|
+
const [preparedArtifact, setPreparedArtifact] = React9.useState(null);
|
|
1890
|
+
const [instruction, setInstruction] = React9.useState("");
|
|
1891
|
+
const [busy, setBusy] = React9.useState(null);
|
|
1892
|
+
const [aiFailed, setAiFailed] = React9.useState(false);
|
|
1893
|
+
React9.useEffect(() => {
|
|
1710
1894
|
setAiFailed(false);
|
|
1711
1895
|
}, [state.snapshot.id, state.draft.revision]);
|
|
1712
|
-
const handingOff =
|
|
1713
|
-
|
|
1896
|
+
const handingOff = React9.useRef(false);
|
|
1897
|
+
React9.useEffect(() => {
|
|
1714
1898
|
if (open) handingOff.current = false;
|
|
1715
1899
|
}, [open]);
|
|
1716
|
-
const activeAi =
|
|
1717
|
-
const activeCapture =
|
|
1718
|
-
|
|
1900
|
+
const activeAi = React9.useRef(null);
|
|
1901
|
+
const activeCapture = React9.useRef(null);
|
|
1902
|
+
React9.useEffect(() => {
|
|
1719
1903
|
if (bufferError) return;
|
|
1720
1904
|
const adapter = adapters.find((candidate) => candidate.id === format);
|
|
1721
1905
|
const controller = new AbortController();
|
|
@@ -1735,7 +1919,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1735
1919
|
});
|
|
1736
1920
|
return () => controller.abort();
|
|
1737
1921
|
}, [adapters, bufferError, format, state.draft, state.snapshot.id]);
|
|
1738
|
-
const close =
|
|
1922
|
+
const close = React9.useCallback(() => {
|
|
1739
1923
|
activeAi.current?.abort();
|
|
1740
1924
|
activeCapture.current?.abort();
|
|
1741
1925
|
activeAi.current = null;
|
|
@@ -1771,7 +1955,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1771
1955
|
const value = JSON.parse(text);
|
|
1772
1956
|
const next = payload.kind === "json" ? { kind: "json", value } : { kind: "registered", format: payload.format, value };
|
|
1773
1957
|
setBufferError(null);
|
|
1774
|
-
onChange({ ...state, draft: (0,
|
|
1958
|
+
onChange({ ...state, draft: (0, import_content_transfer2.editDraft)(state.draft, next), error: void 0 });
|
|
1775
1959
|
} catch {
|
|
1776
1960
|
setBufferError("JSON is incomplete or invalid. Fix it before copying or downloading.");
|
|
1777
1961
|
}
|
|
@@ -1780,7 +1964,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1780
1964
|
setBufferError(null);
|
|
1781
1965
|
const kind = payload.kind === "markdown" || format === "markdown" ? "markdown" : "text";
|
|
1782
1966
|
if (payload.kind === "rows" || !isBuiltInFormat(format)) setFormat("plain");
|
|
1783
|
-
onChange({ ...state, draft: (0,
|
|
1967
|
+
onChange({ ...state, draft: (0, import_content_transfer2.editDraft)(state.draft, { kind, text }), error: void 0 });
|
|
1784
1968
|
};
|
|
1785
1969
|
const requestCapture = async (scope) => {
|
|
1786
1970
|
activeCapture.current?.abort();
|
|
@@ -1807,8 +1991,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1807
1991
|
return;
|
|
1808
1992
|
}
|
|
1809
1993
|
const pending = state.pending;
|
|
1810
|
-
const preferences = (0,
|
|
1811
|
-
const base = { ...pending, key: state.key, original: (0,
|
|
1994
|
+
const preferences = (0, import_content_transfer2.resolveTransferPreferences)({}, state.preferences, pending.snapshot.limits);
|
|
1995
|
+
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 } : {} };
|
|
1812
1996
|
const nextControls = initialControls(base);
|
|
1813
1997
|
setControls(nextControls);
|
|
1814
1998
|
setControlsHistory([]);
|
|
@@ -1831,7 +2015,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1831
2015
|
const current = latest.current;
|
|
1832
2016
|
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;
|
|
1833
2017
|
try {
|
|
1834
|
-
(0,
|
|
2018
|
+
(0, import_content_transfer2.serialize)(next, "plain");
|
|
1835
2019
|
} catch {
|
|
1836
2020
|
onChange({ ...current, error: "AI returned an invalid transfer draft." });
|
|
1837
2021
|
setAiFailed(true);
|
|
@@ -1864,8 +2048,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1864
2048
|
if (fence.valid(id, controller)) setBusy(null);
|
|
1865
2049
|
}
|
|
1866
2050
|
};
|
|
1867
|
-
const [deliveryNotice, setDeliveryNotice] =
|
|
1868
|
-
|
|
2051
|
+
const [deliveryNotice, setDeliveryNotice] = React9.useState(null);
|
|
2052
|
+
React9.useEffect(() => {
|
|
1869
2053
|
setDeliveryNotice(null);
|
|
1870
2054
|
}, [state.draft.revision]);
|
|
1871
2055
|
const reportDelivery = (outcome) => {
|
|
@@ -1916,49 +2100,49 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1916
2100
|
const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
|
|
1917
2101
|
const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
|
|
1918
2102
|
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 ");
|
|
1919
|
-
return /* @__PURE__ */ (0,
|
|
2103
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Dialog, { open, onOpenChange: (next) => {
|
|
1920
2104
|
if (!next) close();
|
|
1921
|
-
}, children: /* @__PURE__ */ (0,
|
|
2105
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
|
|
1922
2106
|
event.preventDefault();
|
|
1923
2107
|
if (!handingOff.current) restoreFocus();
|
|
1924
2108
|
}, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
|
|
1925
|
-
/* @__PURE__ */ (0,
|
|
1926
|
-
/* @__PURE__ */ (0,
|
|
2109
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogHeader, { children: [
|
|
2110
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogTitle, { children: [
|
|
1927
2111
|
"Prepare ",
|
|
1928
2112
|
state.snapshot.label
|
|
1929
2113
|
] }),
|
|
1930
|
-
/* @__PURE__ */ (0,
|
|
2114
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogDescription, { children: [
|
|
1931
2115
|
state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
|
|
1932
2116
|
"Review and edit this copy. Your original stays unchanged."
|
|
1933
2117
|
] })
|
|
1934
2118
|
] }),
|
|
1935
|
-
/* @__PURE__ */ (0,
|
|
1936
|
-
/* @__PURE__ */ (0,
|
|
1937
|
-
/* @__PURE__ */ (0,
|
|
1938
|
-
/* @__PURE__ */ (0,
|
|
1939
|
-
scopes.length > 1 ? /* @__PURE__ */ (0,
|
|
2119
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
2120
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
|
|
2121
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: "matrx-alchemy-main", children: [
|
|
2122
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2123
|
+
scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
1940
2124
|
"Scope",
|
|
1941
|
-
/* @__PURE__ */ (0,
|
|
2125
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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_runtime13.jsx)("option", { value: scope, children: scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
|
|
1942
2126
|
] }) : null,
|
|
1943
|
-
/* @__PURE__ */ (0,
|
|
2127
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
1944
2128
|
"Detail",
|
|
1945
|
-
/* @__PURE__ */ (0,
|
|
1946
|
-
/* @__PURE__ */ (0,
|
|
1947
|
-
/* @__PURE__ */ (0,
|
|
1948
|
-
/* @__PURE__ */ (0,
|
|
1949
|
-
/* @__PURE__ */ (0,
|
|
2129
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
|
|
2130
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "full", children: "Full" }),
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "compact", children: "Compact" }),
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "brief", children: "Brief" }),
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "custom", children: "Custom" })
|
|
1950
2134
|
] })
|
|
1951
2135
|
] }),
|
|
1952
|
-
/* @__PURE__ */ (0,
|
|
2136
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
|
|
1953
2137
|
setBufferError(null);
|
|
1954
2138
|
if (controlsHistory.length) {
|
|
1955
2139
|
const next = controlsHistory[controlsHistory.length - 1];
|
|
1956
2140
|
setControls(next);
|
|
1957
2141
|
setControlsHistory((history) => history.slice(0, -1));
|
|
1958
2142
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
1959
|
-
} else onChange({ ...state, draft: (0,
|
|
2143
|
+
} else onChange({ ...state, draft: (0, import_content_transfer2.undoDraft)(state.draft), error: void 0 });
|
|
1960
2144
|
}, children: "Undo" }),
|
|
1961
|
-
/* @__PURE__ */ (0,
|
|
2145
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
|
|
1962
2146
|
const next = initialControls(state);
|
|
1963
2147
|
setControls(next);
|
|
1964
2148
|
setControlsHistory([]);
|
|
@@ -1966,64 +2150,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1966
2150
|
setBufferError(null);
|
|
1967
2151
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
1968
2152
|
}, children: "Reset" }),
|
|
1969
|
-
/* @__PURE__ */ (0,
|
|
2153
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
|
|
1970
2154
|
] }),
|
|
1971
|
-
controls.preset === "custom" ? /* @__PURE__ */ (0,
|
|
1972
|
-
/* @__PURE__ */ (0,
|
|
1973
|
-
[["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,
|
|
2155
|
+
controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
|
|
2157
|
+
[["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_runtime13.jsxs)("label", { children: [
|
|
1974
2158
|
text,
|
|
1975
|
-
/* @__PURE__ */ (0,
|
|
2159
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
1976
2160
|
] }, key))
|
|
1977
2161
|
] }) : null,
|
|
1978
|
-
rows ? /* @__PURE__ */ (0,
|
|
1979
|
-
/* @__PURE__ */ (0,
|
|
2162
|
+
rows ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
1980
2164
|
"Data selection \xB7 ",
|
|
1981
2165
|
controls.visibleColumns.length,
|
|
1982
2166
|
" columns",
|
|
1983
2167
|
controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
|
|
1984
2168
|
] }),
|
|
1985
|
-
/* @__PURE__ */ (0,
|
|
2169
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(RowControls, { rows, controls, change: changeControls }) })
|
|
1986
2170
|
] }) : null,
|
|
1987
|
-
state.snapshot.sections.length ? /* @__PURE__ */ (0,
|
|
1988
|
-
/* @__PURE__ */ (0,
|
|
2171
|
+
state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2172
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
1989
2173
|
"Sections \xB7 ",
|
|
1990
2174
|
controls.sections.length,
|
|
1991
2175
|
" included"
|
|
1992
2176
|
] }),
|
|
1993
|
-
/* @__PURE__ */ (0,
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2178
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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) }) }),
|
|
1995
2179
|
" ",
|
|
1996
2180
|
section.label
|
|
1997
2181
|
] }, section.id)) })
|
|
1998
2182
|
] }) : null,
|
|
1999
|
-
/* @__PURE__ */ (0,
|
|
2183
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
|
|
2000
2184
|
"Output format",
|
|
2001
|
-
/* @__PURE__ */ (0,
|
|
2002
|
-
formats.map((f) => /* @__PURE__ */ (0,
|
|
2003
|
-
state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0,
|
|
2004
|
-
workspaceAdapters.map((adapter) => /* @__PURE__ */ (0,
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
|
|
2186
|
+
formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: f, children: LABEL[f] }, f)),
|
|
2187
|
+
state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
|
|
2188
|
+
workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
|
|
2005
2189
|
] })
|
|
2006
2190
|
] }),
|
|
2007
|
-
/* @__PURE__ */ (0,
|
|
2008
|
-
/* @__PURE__ */ (0,
|
|
2009
|
-
/* @__PURE__ */ (0,
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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) }),
|
|
2192
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
2010
2194
|
state.snapshot.coverage.included.toLocaleString(),
|
|
2011
2195
|
" included",
|
|
2012
2196
|
state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
|
|
2013
2197
|
" \xB7 ",
|
|
2014
2198
|
state.snapshot.coverage.status
|
|
2015
2199
|
] }),
|
|
2016
|
-
state.snapshot.coverage.reason ? /* @__PURE__ */ (0,
|
|
2017
|
-
limitText ? /* @__PURE__ */ (0,
|
|
2200
|
+
state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
|
|
2201
|
+
limitText ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { children: [
|
|
2018
2202
|
"Limits: ",
|
|
2019
2203
|
limitText
|
|
2020
2204
|
] }) : null,
|
|
2021
|
-
displayedOmissions.length ? /* @__PURE__ */ (0,
|
|
2022
|
-
/* @__PURE__ */ (0,
|
|
2205
|
+
displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { children: [
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
2023
2207
|
displayedOmissions.length,
|
|
2024
2208
|
" omissions or adjustments"
|
|
2025
2209
|
] }),
|
|
2026
|
-
/* @__PURE__ */ (0,
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("li", { children: [
|
|
2027
2211
|
o.path || "/",
|
|
2028
2212
|
": ",
|
|
2029
2213
|
o.reason,
|
|
@@ -2031,79 +2215,86 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2031
2215
|
] }, `${o.path}-${o.reason}-${i}`)) })
|
|
2032
2216
|
] }) : null
|
|
2033
2217
|
] }),
|
|
2034
|
-
bufferError ? /* @__PURE__ */ (0,
|
|
2035
|
-
formatError ? /* @__PURE__ */ (0,
|
|
2036
|
-
bufferError ? /* @__PURE__ */ (0,
|
|
2037
|
-
const fallback = (0,
|
|
2218
|
+
bufferError ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
|
|
2219
|
+
formatError ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
|
|
2220
|
+
bufferError ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
|
|
2221
|
+
const fallback = (0, import_content_transfer2.editDraft)(state.draft, { kind: "text", text: buffer });
|
|
2038
2222
|
setBufferError(null);
|
|
2039
2223
|
onChange({ ...state, draft: fallback, error: void 0 });
|
|
2040
2224
|
setFormat("plain");
|
|
2041
2225
|
}, children: "Use invalid JSON as plain text" }) : null
|
|
2042
2226
|
] }),
|
|
2043
|
-
ai || busy === "capture" || state.error ? /* @__PURE__ */ (0,
|
|
2044
|
-
ai ? /* @__PURE__ */ (0,
|
|
2045
|
-
/* @__PURE__ */ (0,
|
|
2227
|
+
ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("aside", { children: [
|
|
2228
|
+
ai ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2046
2230
|
"Start with",
|
|
2047
|
-
/* @__PURE__ */ (0,
|
|
2231
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
|
|
2048
2232
|
if (event.target.value) setInstruction(event.target.value);
|
|
2049
2233
|
}, children: [
|
|
2050
|
-
/* @__PURE__ */ (0,
|
|
2051
|
-
/* @__PURE__ */ (0,
|
|
2052
|
-
/* @__PURE__ */ (0,
|
|
2053
|
-
/* @__PURE__ */ (0,
|
|
2054
|
-
/* @__PURE__ */ (0,
|
|
2055
|
-
/* @__PURE__ */ (0,
|
|
2056
|
-
/* @__PURE__ */ (0,
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "Choose an instruction" }),
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
|
|
2237
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
|
|
2239
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
|
|
2240
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
|
|
2057
2241
|
] })
|
|
2058
2242
|
] }),
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2060
2244
|
"AI instruction",
|
|
2061
|
-
/* @__PURE__ */ (0,
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
|
|
2062
2246
|
] }),
|
|
2063
|
-
/* @__PURE__ */ (0,
|
|
2064
|
-
busy === "ai" ? /* @__PURE__ */ (0,
|
|
2247
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" }),
|
|
2248
|
+
busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
|
|
2065
2249
|
] }) : null,
|
|
2066
|
-
busy === "capture" ? /* @__PURE__ */ (0,
|
|
2250
|
+
busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
|
|
2067
2251
|
activeCapture.current?.abort();
|
|
2068
2252
|
activeCapture.current = null;
|
|
2069
2253
|
setBusy(null);
|
|
2070
2254
|
}, children: "Stop loading rows" }) : null,
|
|
2071
|
-
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0,
|
|
2072
|
-
ai ? /* @__PURE__ */ (0,
|
|
2073
|
-
state.error ? /* @__PURE__ */ (0,
|
|
2255
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime13.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,
|
|
2256
|
+
ai ? /* @__PURE__ */ (0, import_jsx_runtime13.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,
|
|
2257
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
2074
2258
|
] }) : null
|
|
2075
2259
|
] }),
|
|
2076
|
-
pendingControls ? /* @__PURE__ */ (0,
|
|
2077
|
-
/* @__PURE__ */ (0,
|
|
2078
|
-
/* @__PURE__ */ (0,
|
|
2079
|
-
/* @__PURE__ */ (0,
|
|
2260
|
+
pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2261
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: "This control would replace your manual edit." }),
|
|
2262
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
2080
2264
|
] }) : null,
|
|
2081
|
-
state.sourceStale ? /* @__PURE__ */ (0,
|
|
2082
|
-
state.pending ? /* @__PURE__ */ (0,
|
|
2083
|
-
/* @__PURE__ */ (0,
|
|
2084
|
-
/* @__PURE__ */ (0,
|
|
2085
|
-
|
|
2265
|
+
state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
2266
|
+
state.pending ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2267
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { children: "A fresh source snapshot is ready." }),
|
|
2268
|
+
state.pending.scope !== state.scope ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { children: [
|
|
2269
|
+
"Switch from ",
|
|
2270
|
+
scopeLabels?.[state.scope] ?? SCOPE_LABEL[state.scope],
|
|
2271
|
+
" to ",
|
|
2272
|
+
scopeLabels?.[state.pending.scope] ?? SCOPE_LABEL[state.pending.scope],
|
|
2273
|
+
" by regenerating. Your current draft is retained until you choose."
|
|
2274
|
+
] }) : null,
|
|
2275
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
2276
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
|
|
2086
2277
|
] }) : null,
|
|
2087
|
-
eligibleActions.length ? /* @__PURE__ */ (0,
|
|
2088
|
-
/* @__PURE__ */ (0,
|
|
2278
|
+
eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
|
|
2279
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
2089
2280
|
"Use prepared content \xB7 ",
|
|
2090
2281
|
eligibleActions.length,
|
|
2091
2282
|
" destinations"
|
|
2092
2283
|
] }),
|
|
2093
|
-
/* @__PURE__ */ (0,
|
|
2284
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime13.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_runtime13.jsx)(DestinationPresentation, { action }) }, action.id)) })
|
|
2094
2285
|
] }) : null,
|
|
2095
|
-
deliveryNotice ? /* @__PURE__ */ (0,
|
|
2286
|
+
deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
|
|
2096
2287
|
] }),
|
|
2097
|
-
/* @__PURE__ */ (0,
|
|
2098
|
-
/* @__PURE__ */ (0,
|
|
2288
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogFooter, { children: [
|
|
2289
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "matrx-alchemy-meta", children: [
|
|
2099
2290
|
buffer.length.toLocaleString(),
|
|
2100
2291
|
" characters \xB7 ~",
|
|
2101
2292
|
estimateTokens(buffer).toLocaleString(),
|
|
2102
2293
|
" tokens"
|
|
2103
2294
|
] }),
|
|
2104
|
-
/* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2295
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
|
|
2296
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" }),
|
|
2297
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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" })
|
|
2107
2298
|
] })
|
|
2108
2299
|
] }) });
|
|
2109
2300
|
}
|
|
@@ -2111,59 +2302,59 @@ function RowControls({ rows, controls, change }) {
|
|
|
2111
2302
|
const filterCount = Object.values(controls.filters).filter(Boolean).length;
|
|
2112
2303
|
const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
|
|
2113
2304
|
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 ");
|
|
2114
|
-
return /* @__PURE__ */ (0,
|
|
2115
|
-
/* @__PURE__ */ (0,
|
|
2116
|
-
/* @__PURE__ */ (0,
|
|
2305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
2306
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2307
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2117
2308
|
"Search",
|
|
2118
|
-
/* @__PURE__ */ (0,
|
|
2309
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
|
|
2119
2310
|
] }),
|
|
2120
|
-
/* @__PURE__ */ (0,
|
|
2311
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2121
2312
|
"Sort",
|
|
2122
|
-
/* @__PURE__ */ (0,
|
|
2123
|
-
/* @__PURE__ */ (0,
|
|
2124
|
-
rows.columns.map((column) => /* @__PURE__ */ (0,
|
|
2313
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
|
|
2314
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "None" }),
|
|
2315
|
+
rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: column.id, children: column.label }, column.id))
|
|
2125
2316
|
] })
|
|
2126
2317
|
] }),
|
|
2127
|
-
/* @__PURE__ */ (0,
|
|
2318
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2128
2319
|
"Direction",
|
|
2129
|
-
/* @__PURE__ */ (0,
|
|
2130
|
-
/* @__PURE__ */ (0,
|
|
2131
|
-
/* @__PURE__ */ (0,
|
|
2320
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
|
|
2321
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "asc", children: "Ascending" }),
|
|
2322
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "desc", children: "Descending" })
|
|
2132
2323
|
] })
|
|
2133
2324
|
] }),
|
|
2134
|
-
/* @__PURE__ */ (0,
|
|
2325
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2135
2326
|
"Top rows",
|
|
2136
|
-
/* @__PURE__ */ (0,
|
|
2327
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
2137
2328
|
] })
|
|
2138
2329
|
] }),
|
|
2139
|
-
/* @__PURE__ */ (0,
|
|
2140
|
-
/* @__PURE__ */ (0,
|
|
2330
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2331
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
2141
2332
|
"Columns and filters",
|
|
2142
2333
|
dataSummary ? ` \u2014 ${dataSummary}` : ""
|
|
2143
2334
|
] }),
|
|
2144
|
-
/* @__PURE__ */ (0,
|
|
2145
|
-
/* @__PURE__ */ (0,
|
|
2146
|
-
/* @__PURE__ */ (0,
|
|
2335
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "matrx-alchemy-column", children: [
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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) }) }),
|
|
2147
2338
|
" ",
|
|
2148
2339
|
column.label
|
|
2149
2340
|
] }),
|
|
2150
|
-
/* @__PURE__ */ (0,
|
|
2341
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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 } }) })
|
|
2151
2342
|
] }, column.id)) })
|
|
2152
2343
|
] }),
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2154
|
-
/* @__PURE__ */ (0,
|
|
2344
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2345
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("summary", { children: [
|
|
2155
2346
|
"Rows \u2014 ",
|
|
2156
2347
|
selectionSummary
|
|
2157
2348
|
] }),
|
|
2158
|
-
/* @__PURE__ */ (0,
|
|
2159
|
-
/* @__PURE__ */ (0,
|
|
2160
|
-
/* @__PURE__ */ (0,
|
|
2349
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("fieldset", { "aria-label": "Row selection", children: [
|
|
2350
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2351
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
|
|
2161
2352
|
" Only selected rows"
|
|
2162
2353
|
] }),
|
|
2163
|
-
/* @__PURE__ */ (0,
|
|
2164
|
-
const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0,
|
|
2165
|
-
return /* @__PURE__ */ (0,
|
|
2166
|
-
/* @__PURE__ */ (0,
|
|
2354
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
|
|
2355
|
+
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 ");
|
|
2356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { children: [
|
|
2357
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.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) }) }),
|
|
2167
2358
|
" Row ",
|
|
2168
2359
|
index + 1,
|
|
2169
2360
|
summary ? ` \u2014 ${summary}` : ""
|
|
@@ -2175,11 +2366,11 @@ function RowControls({ rows, controls, change }) {
|
|
|
2175
2366
|
}
|
|
2176
2367
|
|
|
2177
2368
|
// src/content-transfer/matrx-copy.tsx
|
|
2178
|
-
var
|
|
2369
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2179
2370
|
var resolve = (value) => typeof value === "function" ? value() : value;
|
|
2180
2371
|
var asPayload = (value) => ({
|
|
2181
2372
|
kind: "markdown",
|
|
2182
|
-
text: typeof value === "string" ? value : (0,
|
|
2373
|
+
text: typeof value === "string" ? value : (0, import_content_transfer3.buildAgentPayload)(value)
|
|
2183
2374
|
});
|
|
2184
2375
|
var structuredPayload = (value) => {
|
|
2185
2376
|
if (typeof value === "string") return { kind: "markdown", text: value };
|
|
@@ -2188,7 +2379,7 @@ var structuredPayload = (value) => {
|
|
|
2188
2379
|
);
|
|
2189
2380
|
return {
|
|
2190
2381
|
kind: "json",
|
|
2191
|
-
value: (0,
|
|
2382
|
+
value: (0, import_content_transfer3.normalizeTransferJson)(
|
|
2192
2383
|
{
|
|
2193
2384
|
kind: value.kind,
|
|
2194
2385
|
location: value.location,
|
|
@@ -2216,12 +2407,12 @@ var sourceFor = (id, label, build) => ({
|
|
|
2216
2407
|
signal.throwIfAborted();
|
|
2217
2408
|
const payload = await build();
|
|
2218
2409
|
signal.throwIfAborted();
|
|
2219
|
-
return (0,
|
|
2410
|
+
return (0, import_content_transfer3.directSource)(payload, { sourceId: id, label });
|
|
2220
2411
|
}
|
|
2221
2412
|
});
|
|
2222
2413
|
function MatrxCopyMenu(props) {
|
|
2223
2414
|
const inherited = useContentTransferCapabilities();
|
|
2224
|
-
return /* @__PURE__ */ (0,
|
|
2415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2225
2416
|
MatrxCopyMenuSession,
|
|
2226
2417
|
{
|
|
2227
2418
|
...props
|
|
@@ -2233,12 +2424,12 @@ function MatrxCopyMenu(props) {
|
|
|
2233
2424
|
);
|
|
2234
2425
|
}
|
|
2235
2426
|
function MatrxCopyMenuSession(props) {
|
|
2236
|
-
const instance =
|
|
2237
|
-
const controller =
|
|
2427
|
+
const instance = React10.useId();
|
|
2428
|
+
const controller = React10.useRef(null);
|
|
2238
2429
|
const capabilities = useContentTransferCapabilities();
|
|
2239
|
-
const transport = capabilities.transport ?? (0,
|
|
2240
|
-
const [modal, setModal] =
|
|
2241
|
-
const [configuration, setConfiguration] =
|
|
2430
|
+
const transport = capabilities.transport ?? (0, import_content_transfer3.createBrowserTransport)();
|
|
2431
|
+
const [modal, setModal] = React10.useState(null);
|
|
2432
|
+
const [configuration, setConfiguration] = React10.useState(null);
|
|
2242
2433
|
const copyVisible = !props.hide?.includes("copy");
|
|
2243
2434
|
const aiVisible = !props.hide?.includes("ai");
|
|
2244
2435
|
const exportVisible = !props.hide?.includes("export");
|
|
@@ -2254,14 +2445,14 @@ function MatrxCopyMenuSession(props) {
|
|
|
2254
2445
|
})) : void 0;
|
|
2255
2446
|
const json = aiVisible && props.json !== void 0 ? make("json", () => ({
|
|
2256
2447
|
kind: "json",
|
|
2257
|
-
value: (0,
|
|
2448
|
+
value: (0, import_content_transfer3.normalizeTransferJson)(resolve(props.json), {
|
|
2258
2449
|
omitUndefinedObjectProperties: true
|
|
2259
2450
|
})
|
|
2260
2451
|
})) : void 0;
|
|
2261
2452
|
const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
|
|
2262
2453
|
const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
|
|
2263
2454
|
const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
|
|
2264
|
-
const value = (0,
|
|
2455
|
+
const value = (0, import_content_transfer3.normalizeTransferJson)(props.export.sheetRows(), {
|
|
2265
2456
|
omitUndefinedObjectProperties: true
|
|
2266
2457
|
});
|
|
2267
2458
|
if (!Array.isArray(value) || value.some(
|
|
@@ -2398,7 +2589,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
2398
2589
|
const bytes = new Uint8Array(value.bytes);
|
|
2399
2590
|
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"}`;
|
|
2400
2591
|
return transport.download(
|
|
2401
|
-
(0,
|
|
2592
|
+
(0, import_content_transfer3.sealTransferArtifact)({
|
|
2402
2593
|
snapshotId: snapshot.id,
|
|
2403
2594
|
draftRevision: draft.revision,
|
|
2404
2595
|
format: `export:${item.id}`,
|
|
@@ -2425,11 +2616,14 @@ function MatrxCopyMenuSession(props) {
|
|
|
2425
2616
|
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
2426
2617
|
if (!source && !actions.length) return null;
|
|
2427
2618
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
2428
|
-
return /* @__PURE__ */ (0,
|
|
2429
|
-
/* @__PURE__ */ (0,
|
|
2619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2620
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2430
2621
|
ContentTransferMenu,
|
|
2431
2622
|
{
|
|
2623
|
+
triggerSize: props.size === "xs" || props.size === "toolbar" ? "compact" : "default",
|
|
2432
2624
|
source: target,
|
|
2625
|
+
...props.references ? { references: props.references } : {},
|
|
2626
|
+
...props.referenceActions ? { referenceActions: props.referenceActions } : {},
|
|
2433
2627
|
...props.icon !== void 0 ? { icon: props.icon } : {},
|
|
2434
2628
|
...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
|
|
2435
2629
|
controllerRef: controller,
|
|
@@ -2463,7 +2657,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
2463
2657
|
if (!open) setModal(null);
|
|
2464
2658
|
}
|
|
2465
2659
|
}),
|
|
2466
|
-
configuration ? /* @__PURE__ */ (0,
|
|
2660
|
+
configuration ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2467
2661
|
SourceConfiguration,
|
|
2468
2662
|
{
|
|
2469
2663
|
restoreFocus: () => controller.current?.focusTrigger(),
|
|
@@ -2490,14 +2684,14 @@ function SourceConfiguration({
|
|
|
2490
2684
|
onPrepare
|
|
2491
2685
|
}) {
|
|
2492
2686
|
const custom = configuration.custom;
|
|
2493
|
-
const handingOff =
|
|
2687
|
+
const handingOff = React10.useRef(false);
|
|
2494
2688
|
const groomer = configuration.groomer;
|
|
2495
|
-
const [values, setValues] =
|
|
2689
|
+
const [values, setValues] = React10.useState(
|
|
2496
2690
|
() => Object.fromEntries(
|
|
2497
2691
|
custom?.options.map((option) => [option.key, option.default]) ?? []
|
|
2498
2692
|
)
|
|
2499
2693
|
);
|
|
2500
|
-
const [sections, setSections] =
|
|
2694
|
+
const [sections, setSections] = React10.useState(
|
|
2501
2695
|
() => Object.fromEntries(
|
|
2502
2696
|
groomer?.sections.map((section) => [
|
|
2503
2697
|
section.id,
|
|
@@ -2505,8 +2699,8 @@ function SourceConfiguration({
|
|
|
2505
2699
|
]) ?? []
|
|
2506
2700
|
)
|
|
2507
2701
|
);
|
|
2508
|
-
const [error, setError] =
|
|
2509
|
-
const [busy, setBusy] =
|
|
2702
|
+
const [error, setError] = React10.useState(null);
|
|
2703
|
+
const [busy, setBusy] = React10.useState(false);
|
|
2510
2704
|
const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
|
|
2511
2705
|
let prepared = null;
|
|
2512
2706
|
let buildError = null;
|
|
@@ -2539,18 +2733,18 @@ function SourceConfiguration({
|
|
|
2539
2733
|
...groomer.context ? { context: groomer.context } : {}
|
|
2540
2734
|
};
|
|
2541
2735
|
}
|
|
2542
|
-
text = prepared ? (0,
|
|
2736
|
+
text = prepared ? (0, import_content_transfer3.buildAgentPayload)(prepared) : "";
|
|
2543
2737
|
} catch (cause) {
|
|
2544
2738
|
buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
|
|
2545
2739
|
}
|
|
2546
|
-
return /* @__PURE__ */ (0,
|
|
2740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2547
2741
|
Dialog,
|
|
2548
2742
|
{
|
|
2549
2743
|
open: true,
|
|
2550
2744
|
onOpenChange: (open) => {
|
|
2551
2745
|
if (!open && !busy) onClose();
|
|
2552
2746
|
},
|
|
2553
|
-
children: /* @__PURE__ */ (0,
|
|
2747
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2554
2748
|
DialogContent,
|
|
2555
2749
|
{
|
|
2556
2750
|
onCloseAutoFocus: (event) => {
|
|
@@ -2559,23 +2753,23 @@ function SourceConfiguration({
|
|
|
2559
2753
|
},
|
|
2560
2754
|
className: "matrx-alchemy-workspace matrx-alchemy-configuration",
|
|
2561
2755
|
children: [
|
|
2562
|
-
/* @__PURE__ */ (0,
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2564
|
-
/* @__PURE__ */ (0,
|
|
2756
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogHeader, { children: [
|
|
2757
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogTitle, { children: title }),
|
|
2758
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
|
|
2565
2759
|
] }),
|
|
2566
|
-
/* @__PURE__ */ (0,
|
|
2567
|
-
/* @__PURE__ */ (0,
|
|
2568
|
-
custom?.options.map((option) => /* @__PURE__ */ (0,
|
|
2760
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
2761
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
|
|
2762
|
+
custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { children: [
|
|
2569
2763
|
option.label,
|
|
2570
|
-
"hint" in option && option.hint ? /* @__PURE__ */ (0,
|
|
2571
|
-
option.kind === "toggle" ? /* @__PURE__ */ (0,
|
|
2764
|
+
"hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("small", { children: option.hint }) : null,
|
|
2765
|
+
option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2572
2766
|
"input",
|
|
2573
2767
|
{
|
|
2574
2768
|
type: "checkbox",
|
|
2575
2769
|
checked: Boolean(values[option.key]),
|
|
2576
2770
|
onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
|
|
2577
2771
|
}
|
|
2578
|
-
) : option.kind === "preset" ? /* @__PURE__ */ (0,
|
|
2772
|
+
) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2579
2773
|
"select",
|
|
2580
2774
|
{
|
|
2581
2775
|
value: Number(values[option.key]),
|
|
@@ -2583,10 +2777,10 @@ function SourceConfiguration({
|
|
|
2583
2777
|
...values,
|
|
2584
2778
|
[option.key]: Number(event.target.value)
|
|
2585
2779
|
}),
|
|
2586
|
-
children: option.options.map((choice) => /* @__PURE__ */ (0,
|
|
2780
|
+
children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
|
|
2587
2781
|
}
|
|
2588
|
-
) : option.kind === "slider" ? /* @__PURE__ */ (0,
|
|
2589
|
-
/* @__PURE__ */ (0,
|
|
2782
|
+
) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2783
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2590
2784
|
"input",
|
|
2591
2785
|
{
|
|
2592
2786
|
type: "range",
|
|
@@ -2600,9 +2794,9 @@ function SourceConfiguration({
|
|
|
2600
2794
|
})
|
|
2601
2795
|
}
|
|
2602
2796
|
),
|
|
2603
|
-
/* @__PURE__ */ (0,
|
|
2604
|
-
] }) : /* @__PURE__ */ (0,
|
|
2605
|
-
/* @__PURE__ */ (0,
|
|
2797
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
|
|
2798
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2799
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2606
2800
|
"input",
|
|
2607
2801
|
{
|
|
2608
2802
|
type: "number",
|
|
@@ -2615,7 +2809,7 @@ function SourceConfiguration({
|
|
|
2615
2809
|
})
|
|
2616
2810
|
}
|
|
2617
2811
|
),
|
|
2618
|
-
option.presets?.map((preset) => /* @__PURE__ */ (0,
|
|
2812
|
+
option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2619
2813
|
Button,
|
|
2620
2814
|
{
|
|
2621
2815
|
type: "button",
|
|
@@ -2628,8 +2822,8 @@ function SourceConfiguration({
|
|
|
2628
2822
|
))
|
|
2629
2823
|
] })
|
|
2630
2824
|
] }, option.key)),
|
|
2631
|
-
groomer ? /* @__PURE__ */ (0,
|
|
2632
|
-
/* @__PURE__ */ (0,
|
|
2825
|
+
groomer ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
2826
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2633
2827
|
Button,
|
|
2634
2828
|
{
|
|
2635
2829
|
type: "button",
|
|
@@ -2647,9 +2841,9 @@ function SourceConfiguration({
|
|
|
2647
2841
|
},
|
|
2648
2842
|
level
|
|
2649
2843
|
)) }),
|
|
2650
|
-
groomer.sections.map((section) => /* @__PURE__ */ (0,
|
|
2844
|
+
groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("label", { children: [
|
|
2651
2845
|
section.title,
|
|
2652
|
-
/* @__PURE__ */ (0,
|
|
2846
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2653
2847
|
"select",
|
|
2654
2848
|
{
|
|
2655
2849
|
value: sections[section.id],
|
|
@@ -2658,26 +2852,26 @@ function SourceConfiguration({
|
|
|
2658
2852
|
[section.id]: event.target.value
|
|
2659
2853
|
}),
|
|
2660
2854
|
children: [
|
|
2661
|
-
["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0,
|
|
2662
|
-
section.cuttable ? /* @__PURE__ */ (0,
|
|
2855
|
+
["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
|
|
2856
|
+
section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("option", { value: "off", children: "Exclude" }) : null
|
|
2663
2857
|
]
|
|
2664
2858
|
}
|
|
2665
2859
|
),
|
|
2666
|
-
section.description ? /* @__PURE__ */ (0,
|
|
2860
|
+
section.description ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: section.description }) : null
|
|
2667
2861
|
] }, section.id))
|
|
2668
2862
|
] }) : null
|
|
2669
2863
|
] }),
|
|
2670
|
-
/* @__PURE__ */ (0,
|
|
2864
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { children: [
|
|
2671
2865
|
(0, import_format2.formatCount)(text.length),
|
|
2672
2866
|
" characters \xB7 approximately",
|
|
2673
2867
|
" ",
|
|
2674
2868
|
(0, import_format2.formatCount)(Math.ceil(text.length / 4)),
|
|
2675
2869
|
" tokens"
|
|
2676
2870
|
] }),
|
|
2677
|
-
error || buildError ? /* @__PURE__ */ (0,
|
|
2871
|
+
error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { role: "alert", children: error ?? buildError }) : null
|
|
2678
2872
|
] }),
|
|
2679
|
-
/* @__PURE__ */ (0,
|
|
2680
|
-
/* @__PURE__ */ (0,
|
|
2873
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogFooter, { children: [
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2681
2875
|
Button,
|
|
2682
2876
|
{
|
|
2683
2877
|
type: "button",
|
|
@@ -2688,7 +2882,7 @@ function SourceConfiguration({
|
|
|
2688
2882
|
children: "Cancel"
|
|
2689
2883
|
}
|
|
2690
2884
|
),
|
|
2691
|
-
/* @__PURE__ */ (0,
|
|
2885
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2692
2886
|
Button,
|
|
2693
2887
|
{
|
|
2694
2888
|
type: "button",
|
|
@@ -2722,12 +2916,12 @@ function SourceConfiguration({
|
|
|
2722
2916
|
}
|
|
2723
2917
|
|
|
2724
2918
|
// src/data-table/copy.tsx
|
|
2725
|
-
var
|
|
2919
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2726
2920
|
function CopyButtons(props) {
|
|
2727
2921
|
const { CopyControls } = useMatrxDataTableHost();
|
|
2728
2922
|
const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
|
|
2729
|
-
if (CopyControls) return /* @__PURE__ */ (0,
|
|
2730
|
-
return /* @__PURE__ */ (0,
|
|
2923
|
+
if (CopyControls) return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CopyControls, { ...copyProps });
|
|
2924
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MatrxCopyMenu, { ...copyProps });
|
|
2731
2925
|
}
|
|
2732
2926
|
|
|
2733
2927
|
// src/data-table/MatrxUuidCell.tsx
|
|
@@ -2735,7 +2929,7 @@ var import_react4 = require("react");
|
|
|
2735
2929
|
|
|
2736
2930
|
// src/data-table/useTableNotice.tsx
|
|
2737
2931
|
var import_react3 = require("react");
|
|
2738
|
-
var
|
|
2932
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2739
2933
|
function useTableNotice() {
|
|
2740
2934
|
const host = useMatrxDataTableHost();
|
|
2741
2935
|
const [message, setMessage] = (0, import_react3.useState)(null);
|
|
@@ -2749,15 +2943,15 @@ function useTableNotice() {
|
|
|
2749
2943
|
else setMessage({ text, error: true });
|
|
2750
2944
|
}
|
|
2751
2945
|
};
|
|
2752
|
-
const notice = message ? /* @__PURE__ */ (0,
|
|
2946
|
+
const notice = message ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { role: message.error ? "alert" : "status", className: message.error ? "text-xs text-destructive" : "text-xs text-muted-foreground", children: [
|
|
2753
2947
|
message.text,
|
|
2754
|
-
/* @__PURE__ */ (0,
|
|
2948
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("button", { type: "button", "aria-label": "Dismiss notification", className: "ml-2 underline", onClick: () => setMessage(null), children: "Dismiss" })
|
|
2755
2949
|
] }) : null;
|
|
2756
2950
|
return { notify, notice };
|
|
2757
2951
|
}
|
|
2758
2952
|
|
|
2759
2953
|
// src/data-table/MatrxUuidCell.tsx
|
|
2760
|
-
var
|
|
2954
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2761
2955
|
var SHORT_LEN = 8;
|
|
2762
2956
|
function shortUuid(id, len = SHORT_LEN) {
|
|
2763
2957
|
return id.slice(0, len);
|
|
@@ -2807,7 +3001,7 @@ function MatrxUuidCell({
|
|
|
2807
3001
|
[]
|
|
2808
3002
|
);
|
|
2809
3003
|
if (!value) {
|
|
2810
|
-
return /* @__PURE__ */ (0,
|
|
3004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "text-muted-foreground/40", children: "\u2014" });
|
|
2811
3005
|
}
|
|
2812
3006
|
const doors = token ? resolveEntityDoors?.(token, value, href) ?? null : null;
|
|
2813
3007
|
const resolvedHref = doors?.href ?? href ?? null;
|
|
@@ -2850,13 +3044,13 @@ function MatrxUuidCell({
|
|
|
2850
3044
|
};
|
|
2851
3045
|
const idNode = (() => {
|
|
2852
3046
|
if (forbidden) {
|
|
2853
|
-
return /* @__PURE__ */ (0,
|
|
2854
|
-
/* @__PURE__ */ (0,
|
|
2855
|
-
/* @__PURE__ */ (0,
|
|
3047
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-muted-foreground/70 tabular-nums", children: [
|
|
3048
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 truncate", children: display }),
|
|
3049
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ShieldOff, { className: "h-3 w-3 shrink-0 opacity-60", "aria-hidden": true })
|
|
2856
3050
|
] });
|
|
2857
3051
|
}
|
|
2858
3052
|
if (onOpen) {
|
|
2859
|
-
return /* @__PURE__ */ (0,
|
|
3053
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2860
3054
|
"button",
|
|
2861
3055
|
{
|
|
2862
3056
|
type: "button",
|
|
@@ -2865,14 +3059,14 @@ function MatrxUuidCell({
|
|
|
2865
3059
|
disabled: opening,
|
|
2866
3060
|
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",
|
|
2867
3061
|
children: [
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
3062
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
|
|
3063
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PanelRight, { className: "h-3 w-3 shrink-0 opacity-50" })
|
|
2870
3064
|
]
|
|
2871
3065
|
}
|
|
2872
3066
|
);
|
|
2873
3067
|
}
|
|
2874
3068
|
if (resolvedHref) {
|
|
2875
|
-
return /* @__PURE__ */ (0,
|
|
3069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2876
3070
|
"a",
|
|
2877
3071
|
{
|
|
2878
3072
|
href: resolvedHref,
|
|
@@ -2882,15 +3076,15 @@ function MatrxUuidCell({
|
|
|
2882
3076
|
onClick: stop,
|
|
2883
3077
|
className: "inline-flex min-w-0 items-center gap-1 font-mono text-xs text-sky-600 hover:underline dark:text-sky-400",
|
|
2884
3078
|
children: [
|
|
2885
|
-
/* @__PURE__ */ (0,
|
|
2886
|
-
/* @__PURE__ */ (0,
|
|
3079
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 truncate tabular-nums", children: display }),
|
|
3080
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ExternalLink, { className: "h-3 w-3 shrink-0 opacity-50" })
|
|
2887
3081
|
]
|
|
2888
3082
|
}
|
|
2889
3083
|
);
|
|
2890
3084
|
}
|
|
2891
|
-
return /* @__PURE__ */ (0,
|
|
3085
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
|
|
2892
3086
|
})();
|
|
2893
|
-
return /* @__PURE__ */ (0,
|
|
3087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
2894
3088
|
"span",
|
|
2895
3089
|
{
|
|
2896
3090
|
"data-matrx-cell-control": true,
|
|
@@ -2900,12 +3094,12 @@ function MatrxUuidCell({
|
|
|
2900
3094
|
),
|
|
2901
3095
|
onClick: stop,
|
|
2902
3096
|
children: [
|
|
2903
|
-
/* @__PURE__ */ (0,
|
|
2904
|
-
/* @__PURE__ */ (0,
|
|
2905
|
-
/* @__PURE__ */ (0,
|
|
3097
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Tooltip, { children: [
|
|
3098
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
|
|
3099
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
|
|
2906
3100
|
] }),
|
|
2907
|
-
/* @__PURE__ */ (0,
|
|
2908
|
-
/* @__PURE__ */ (0,
|
|
3101
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Tooltip, { children: [
|
|
3102
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2909
3103
|
"button",
|
|
2910
3104
|
{
|
|
2911
3105
|
type: "button",
|
|
@@ -2915,13 +3109,13 @@ function MatrxUuidCell({
|
|
|
2915
3109
|
"inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
|
|
2916
3110
|
copied && "text-primary"
|
|
2917
3111
|
),
|
|
2918
|
-
children: copied ? /* @__PURE__ */ (0,
|
|
3112
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Copy, { className: "h-3 w-3" })
|
|
2919
3113
|
}
|
|
2920
3114
|
) }),
|
|
2921
|
-
/* @__PURE__ */ (0,
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipContent, { side: "top", children: copied ? "Copied" : `Copy ${label ?? "id"}: ${value}` })
|
|
2922
3116
|
] }),
|
|
2923
|
-
canPeek ? /* @__PURE__ */ (0,
|
|
2924
|
-
/* @__PURE__ */ (0,
|
|
3117
|
+
canPeek ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Tooltip, { children: [
|
|
3118
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2925
3119
|
"button",
|
|
2926
3120
|
{
|
|
2927
3121
|
type: "button",
|
|
@@ -2931,16 +3125,16 @@ function MatrxUuidCell({
|
|
|
2931
3125
|
},
|
|
2932
3126
|
"aria-label": `Quick look at ${label ?? "record"}`,
|
|
2933
3127
|
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",
|
|
2934
|
-
children: /* @__PURE__ */ (0,
|
|
3128
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Lightbulb, { className: "h-3 w-3" })
|
|
2935
3129
|
}
|
|
2936
3130
|
) }),
|
|
2937
|
-
/* @__PURE__ */ (0,
|
|
3131
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(TooltipContent, { side: "top", children: [
|
|
2938
3132
|
"Quick look at ",
|
|
2939
3133
|
label ?? "record"
|
|
2940
3134
|
] })
|
|
2941
3135
|
] }) : null,
|
|
2942
|
-
onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0,
|
|
2943
|
-
/* @__PURE__ */ (0,
|
|
3136
|
+
onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(Tooltip, { children: [
|
|
3137
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2944
3138
|
"a",
|
|
2945
3139
|
{
|
|
2946
3140
|
href: resolvedHref,
|
|
@@ -2949,10 +3143,10 @@ function MatrxUuidCell({
|
|
|
2949
3143
|
onClick: stop,
|
|
2950
3144
|
"aria-label": `Open ${label ?? "record"} in a new tab`,
|
|
2951
3145
|
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",
|
|
2952
|
-
children: /* @__PURE__ */ (0,
|
|
3146
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ExternalLink, { className: "h-3 w-3" })
|
|
2953
3147
|
}
|
|
2954
3148
|
) }),
|
|
2955
|
-
/* @__PURE__ */ (0,
|
|
3149
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(TooltipContent, { side: "top", children: [
|
|
2956
3150
|
"Open ",
|
|
2957
3151
|
label ?? "record",
|
|
2958
3152
|
" in a new tab"
|
|
@@ -2960,7 +3154,7 @@ function MatrxUuidCell({
|
|
|
2960
3154
|
] }) : null,
|
|
2961
3155
|
trailing,
|
|
2962
3156
|
notice,
|
|
2963
|
-
canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0,
|
|
3157
|
+
canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
2964
3158
|
ResourcePeek,
|
|
2965
3159
|
{
|
|
2966
3160
|
kind: doors?.peekKind ?? token ?? "record",
|
|
@@ -2976,11 +3170,11 @@ function MatrxUuidCell({
|
|
|
2976
3170
|
|
|
2977
3171
|
// src/data-table/entity.ts
|
|
2978
3172
|
function isUuidValue(value) {
|
|
2979
|
-
return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[
|
|
3173
|
+
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);
|
|
2980
3174
|
}
|
|
2981
3175
|
|
|
2982
3176
|
// src/data-table/DataRowInspector.tsx
|
|
2983
|
-
var
|
|
3177
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
2984
3178
|
var noFieldToken = () => null;
|
|
2985
3179
|
function formatValue(value) {
|
|
2986
3180
|
if (value == null) return "\u2014";
|
|
@@ -3009,7 +3203,7 @@ function DataRowInspector({
|
|
|
3009
3203
|
tokenForField = noFieldToken
|
|
3010
3204
|
}) {
|
|
3011
3205
|
const entries = isPlainObject(row) ? Object.entries(row) : [["value", row]];
|
|
3012
|
-
const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ (0,
|
|
3206
|
+
const fieldButtons = (key, value) => fieldCopy ? /* @__PURE__ */ (0, import_jsx_runtime18.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_runtime18.jsx)(
|
|
3013
3207
|
CopyButtons,
|
|
3014
3208
|
{
|
|
3015
3209
|
size: "xs",
|
|
@@ -3024,21 +3218,21 @@ function DataRowInspector({
|
|
|
3024
3218
|
})
|
|
3025
3219
|
}
|
|
3026
3220
|
) }) : null;
|
|
3027
|
-
return /* @__PURE__ */ (0,
|
|
3221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3028
3222
|
"div",
|
|
3029
3223
|
{
|
|
3030
3224
|
className: cn("flex h-full min-h-0 flex-col overflow-hidden", className),
|
|
3031
3225
|
children: [
|
|
3032
|
-
title ? /* @__PURE__ */ (0,
|
|
3033
|
-
/* @__PURE__ */ (0,
|
|
3226
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "shrink-0 border-b border-border px-3 py-2 text-sm font-medium", children: title }) : null,
|
|
3227
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "min-h-0 flex-1 overflow-auto p-3", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("dl", { className: "space-y-2", children: entries.map(([key, value]) => {
|
|
3034
3228
|
if (isUuidValue(value)) {
|
|
3035
|
-
return /* @__PURE__ */ (0,
|
|
3229
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3036
3230
|
"div",
|
|
3037
3231
|
{
|
|
3038
3232
|
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",
|
|
3039
3233
|
children: [
|
|
3040
|
-
/* @__PURE__ */ (0,
|
|
3041
|
-
/* @__PURE__ */ (0,
|
|
3234
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("dd", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3042
3236
|
MatrxUuidCell,
|
|
3043
3237
|
{
|
|
3044
3238
|
value,
|
|
@@ -3053,13 +3247,13 @@ function DataRowInspector({
|
|
|
3053
3247
|
}
|
|
3054
3248
|
const formatted = formatValue(value);
|
|
3055
3249
|
const multiline = formatted.includes("\n") || formatted.length > 80;
|
|
3056
|
-
return /* @__PURE__ */ (0,
|
|
3250
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3057
3251
|
"div",
|
|
3058
3252
|
{
|
|
3059
3253
|
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",
|
|
3060
3254
|
children: [
|
|
3061
|
-
/* @__PURE__ */ (0,
|
|
3062
|
-
/* @__PURE__ */ (0,
|
|
3255
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("dt", { className: "truncate text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: key }),
|
|
3256
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3063
3257
|
"dd",
|
|
3064
3258
|
{
|
|
3065
3259
|
className: cn(
|
|
@@ -3081,7 +3275,7 @@ function DataRowInspector({
|
|
|
3081
3275
|
}
|
|
3082
3276
|
|
|
3083
3277
|
// src/data-table/DataRowWindow.tsx
|
|
3084
|
-
var
|
|
3278
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3085
3279
|
function DataRowWindow({
|
|
3086
3280
|
isOpen,
|
|
3087
3281
|
onClose,
|
|
@@ -3107,9 +3301,9 @@ function DataRowWindow({
|
|
|
3107
3301
|
setTab(defaultTab ?? (hasEdit ? "edit" : "view"));
|
|
3108
3302
|
}, [isOpen, windowId, hasEdit, defaultTab]);
|
|
3109
3303
|
if (!isOpen) return null;
|
|
3110
|
-
const viewBody = viewContent ?? /* @__PURE__ */ (0,
|
|
3111
|
-
const body = children ?? /* @__PURE__ */ (0,
|
|
3112
|
-
return /* @__PURE__ */ (0,
|
|
3304
|
+
const viewBody = viewContent ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DataRowInspector, { row });
|
|
3305
|
+
const body = children ?? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex h-full min-h-0 flex-1 flex-col overflow-hidden", children: hasTabs ? tab === "edit" ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: editContent }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: viewBody }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: viewBody }) });
|
|
3306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3113
3307
|
WindowPanel,
|
|
3114
3308
|
{
|
|
3115
3309
|
id: windowId,
|
|
@@ -3123,26 +3317,26 @@ function DataRowWindow({
|
|
|
3123
3317
|
bodyClassName: "flex min-h-0 flex-1 flex-col overflow-hidden p-0",
|
|
3124
3318
|
sidebarDefaultSize: 140,
|
|
3125
3319
|
sidebarMinSize: 110,
|
|
3126
|
-
sidebar: hasTabs ? /* @__PURE__ */ (0,
|
|
3320
|
+
sidebar: hasTabs ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3127
3321
|
"nav",
|
|
3128
3322
|
{
|
|
3129
3323
|
"aria-label": "Row window tabs",
|
|
3130
3324
|
className: "flex h-full flex-col gap-0.5 overflow-y-auto p-1.5",
|
|
3131
3325
|
children: [
|
|
3132
|
-
/* @__PURE__ */ (0,
|
|
3326
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3133
3327
|
TabButton,
|
|
3134
3328
|
{
|
|
3135
3329
|
active: tab === "view",
|
|
3136
|
-
icon: /* @__PURE__ */ (0,
|
|
3330
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Eye, { className: "h-4 w-4 shrink-0" }),
|
|
3137
3331
|
label: "View",
|
|
3138
3332
|
onClick: () => setTab("view")
|
|
3139
3333
|
}
|
|
3140
3334
|
),
|
|
3141
|
-
/* @__PURE__ */ (0,
|
|
3335
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3142
3336
|
TabButton,
|
|
3143
3337
|
{
|
|
3144
3338
|
active: tab === "edit",
|
|
3145
|
-
icon: /* @__PURE__ */ (0,
|
|
3339
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pencil, { className: "h-4 w-4 shrink-0" }),
|
|
3146
3340
|
label: "Edit",
|
|
3147
3341
|
onClick: () => setTab("edit")
|
|
3148
3342
|
}
|
|
@@ -3160,7 +3354,7 @@ function TabButton({
|
|
|
3160
3354
|
label,
|
|
3161
3355
|
onClick
|
|
3162
3356
|
}) {
|
|
3163
|
-
return /* @__PURE__ */ (0,
|
|
3357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3164
3358
|
"button",
|
|
3165
3359
|
{
|
|
3166
3360
|
type: "button",
|
|
@@ -3173,7 +3367,7 @@ function TabButton({
|
|
|
3173
3367
|
),
|
|
3174
3368
|
children: [
|
|
3175
3369
|
icon,
|
|
3176
|
-
/* @__PURE__ */ (0,
|
|
3370
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "min-w-0 flex-1 truncate", children: label })
|
|
3177
3371
|
]
|
|
3178
3372
|
}
|
|
3179
3373
|
);
|