@ai-matrx/design-system 0.19.17 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/content-transfer/alchemy.svg +1 -1
- package/dist/content-transfer/icon.cjs +1 -1
- package/dist/content-transfer/icon.cjs.map +1 -1
- package/dist/content-transfer/icon.js +1 -1
- package/dist/content-transfer/icon.js.map +1 -1
- package/dist/content-transfer/portal.svg +1 -1
- package/dist/content-transfer.cjs +692 -407
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.css +15 -0
- package/dist/content-transfer.d.cts +19 -4
- package/dist/content-transfer.d.ts +19 -4
- package/dist/content-transfer.js +684 -396
- package/dist/content-transfer.js.map +1 -1
- package/dist/data-table/copy-helpers.d.cts +3 -1
- package/dist/data-table/copy-helpers.d.ts +3 -1
- package/dist/data-table/copy-types.cjs.map +1 -1
- package/dist/data-table/copy-types.d.cts +4 -0
- package/dist/data-table/copy-types.d.ts +4 -0
- package/dist/data-table/data-row-inspector.cjs +659 -465
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +662 -463
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +657 -463
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +663 -464
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/filter-engine.d.cts +3 -1
- package/dist/data-table/filter-engine.d.ts +3 -1
- package/dist/data-table/host.cjs.map +1 -1
- package/dist/data-table/host.d.cts +6 -1
- package/dist/data-table/host.d.ts +6 -1
- package/dist/data-table/host.js.map +1 -1
- package/dist/data-table/index.cjs +1211 -980
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +4 -2
- package/dist/data-table/index.d.ts +4 -2
- package/dist/data-table/index.js +1350 -1114
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +3 -1
- package/dist/data-table/infer-filter.d.ts +3 -1
- package/dist/data-table/layered-filters.d.cts +3 -1
- package/dist/data-table/layered-filters.d.ts +3 -1
- package/dist/data-table/pagination.cjs +2 -2
- package/dist/data-table/pagination.cjs.map +1 -1
- package/dist/data-table/pagination.js +2 -2
- package/dist/data-table/pagination.js.map +1 -1
- package/dist/data-table/query-control.d.cts +3 -1
- package/dist/data-table/query-control.d.ts +3 -1
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +3 -1
- package/dist/data-table/types.d.ts +3 -1
- package/dist/data-table/url-state.d.cts +3 -1
- package/dist/data-table/url-state.d.ts +3 -1
- package/dist/data-table/uuid-cell.cjs.map +1 -1
- package/dist/data-table/uuid-cell.js.map +1 -1
- package/dist/data-table/xlsx.d.cts +3 -1
- package/dist/data-table/xlsx.d.ts +3 -1
- package/dist/extensions-DCHtNwG3.d.cts +32 -0
- package/dist/extensions-DCHtNwG3.d.ts +32 -0
- package/dist/tap-target.css +2 -2
- package/dist/{types-DqlfNcC5.d.cts → types-C2yaTspG.d.cts} +6 -1
- package/dist/{types-lNw7TnTM.d.ts → types-DB30aCHu.d.ts} +6 -1
- package/package.json +1 -1
|
@@ -42,16 +42,18 @@ __export(content_transfer_exports, {
|
|
|
42
42
|
MatrxCopyMenu: () => MatrxCopyMenu,
|
|
43
43
|
applyGroomerPreset: () => applyGroomerPreset,
|
|
44
44
|
buildGroomerPresetPayload: () => buildGroomerPresetPayload,
|
|
45
|
+
createTransferEmailActions: () => createTransferEmailActions,
|
|
45
46
|
defaultGroomerSelections: () => defaultGroomerSelections,
|
|
46
47
|
groomerPresetVariants: () => groomerPresetVariants,
|
|
48
|
+
tableDataFormat: () => tableDataFormat,
|
|
49
|
+
tableSchemaFormat: () => tableSchemaFormat,
|
|
47
50
|
useContentTransferCapabilities: () => useContentTransferCapabilities,
|
|
48
51
|
useContentTransferSurface: () => useContentTransferSurface
|
|
49
52
|
});
|
|
50
53
|
module.exports = __toCommonJS(content_transfer_exports);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
var
|
|
54
|
-
var import_format2 = require("@ai-matrx/kit/format");
|
|
54
|
+
|
|
55
|
+
// src/content-transfer/email-review.tsx
|
|
56
|
+
var React6 = __toESM(require("react"), 1);
|
|
55
57
|
|
|
56
58
|
// src/button.tsx
|
|
57
59
|
var import_react_slot = require("@radix-ui/react-slot");
|
|
@@ -447,13 +449,133 @@ var DialogDescription = React5.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
447
449
|
));
|
|
448
450
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
449
451
|
|
|
452
|
+
// src/content-transfer/email-review.tsx
|
|
453
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
454
|
+
var cancelled = () => ({ status: "cancelled" });
|
|
455
|
+
var failed = (error) => ({
|
|
456
|
+
status: "error",
|
|
457
|
+
code: "email-failed",
|
|
458
|
+
message: error instanceof Error ? error.message : "Could not send email.",
|
|
459
|
+
retryable: true
|
|
460
|
+
});
|
|
461
|
+
function useReviewedTransferEmail(email) {
|
|
462
|
+
const [pending, setPending] = React6.useState(null);
|
|
463
|
+
const [sending, setSending] = React6.useState(false);
|
|
464
|
+
const pendingRef = React6.useRef(null);
|
|
465
|
+
const sendingRef = React6.useRef(false);
|
|
466
|
+
const settle = React6.useCallback((request, outcome, render = true) => {
|
|
467
|
+
if (pendingRef.current !== request) return;
|
|
468
|
+
pendingRef.current = null;
|
|
469
|
+
request.context.signal.removeEventListener("abort", request.onAbort);
|
|
470
|
+
request.resolve(outcome);
|
|
471
|
+
sendingRef.current = false;
|
|
472
|
+
if (render) {
|
|
473
|
+
setSending(false);
|
|
474
|
+
setPending(null);
|
|
475
|
+
}
|
|
476
|
+
}, []);
|
|
477
|
+
React6.useEffect(
|
|
478
|
+
() => () => {
|
|
479
|
+
const request = pendingRef.current;
|
|
480
|
+
if (!request) return;
|
|
481
|
+
pendingRef.current = null;
|
|
482
|
+
request.context.signal.removeEventListener("abort", request.onAbort);
|
|
483
|
+
request.resolve(cancelled());
|
|
484
|
+
sendingRef.current = false;
|
|
485
|
+
},
|
|
486
|
+
[]
|
|
487
|
+
);
|
|
488
|
+
const reviewed = React6.useMemo(() => {
|
|
489
|
+
if (!email) return void 0;
|
|
490
|
+
return {
|
|
491
|
+
send: (artifact, context) => {
|
|
492
|
+
if (context.signal.aborted) return Promise.resolve(cancelled());
|
|
493
|
+
if (pendingRef.current)
|
|
494
|
+
return Promise.resolve({
|
|
495
|
+
status: "error",
|
|
496
|
+
code: "email-review-active",
|
|
497
|
+
message: "Finish reviewing the current email before starting another.",
|
|
498
|
+
retryable: true
|
|
499
|
+
});
|
|
500
|
+
return new Promise((resolve2) => {
|
|
501
|
+
const request = {
|
|
502
|
+
artifact,
|
|
503
|
+
context,
|
|
504
|
+
resolve: resolve2,
|
|
505
|
+
onAbort: () => settle(request, cancelled())
|
|
506
|
+
};
|
|
507
|
+
pendingRef.current = request;
|
|
508
|
+
context.signal.addEventListener("abort", request.onAbort, { once: true });
|
|
509
|
+
setSending(false);
|
|
510
|
+
setPending(request);
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
}, [email, settle]);
|
|
515
|
+
const cancel = React6.useCallback(() => {
|
|
516
|
+
const request = pendingRef.current;
|
|
517
|
+
if (request && !sendingRef.current) settle(request, cancelled());
|
|
518
|
+
}, [settle]);
|
|
519
|
+
const confirm = React6.useCallback(() => {
|
|
520
|
+
const request = pendingRef.current;
|
|
521
|
+
if (!request || sendingRef.current || request.context.signal.aborted) return;
|
|
522
|
+
sendingRef.current = true;
|
|
523
|
+
setSending(true);
|
|
524
|
+
void email?.send(request.artifact, request.context).then(
|
|
525
|
+
(outcome) => settle(request, outcome),
|
|
526
|
+
(error) => settle(request, failed(error))
|
|
527
|
+
);
|
|
528
|
+
}, [email, settle]);
|
|
529
|
+
const review = pending ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { open: true, onOpenChange: (open) => {
|
|
530
|
+
if (!open) cancel();
|
|
531
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogContent, { className: "matrx-alchemy-workspace matrx-alchemy-email-review", "aria-busy": sending, children: [
|
|
532
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogHeader, { children: [
|
|
533
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogTitle, { children: "Review email attachment" }),
|
|
534
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogDescription, { children: [
|
|
535
|
+
"Email ",
|
|
536
|
+
pending.artifact.file?.filename ?? `${pending.artifact.format} output`,
|
|
537
|
+
" from ",
|
|
538
|
+
pending.context.label,
|
|
539
|
+
". Review this exact attachment before sending."
|
|
540
|
+
] })
|
|
541
|
+
] }),
|
|
542
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("textarea", { "aria-label": "Email attachment preview", readOnly: true, value: pending.artifact.plainText, className: "matrx-alchemy-preview" }),
|
|
543
|
+
pending.artifact.omissions.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "matrx-alchemy-email-adjustments", open: true, children: [
|
|
544
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("summary", { children: [
|
|
545
|
+
pending.artifact.omissions.length,
|
|
546
|
+
" omission",
|
|
547
|
+
pending.artifact.omissions.length === 1 ? "" : "s",
|
|
548
|
+
" or adjustment",
|
|
549
|
+
pending.artifact.omissions.length === 1 ? "" : "s"
|
|
550
|
+
] }),
|
|
551
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: pending.artifact.omissions.map((omission, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
|
|
552
|
+
omission.path || "/",
|
|
553
|
+
": ",
|
|
554
|
+
omission.reason,
|
|
555
|
+
omission.count == null ? "" : ` (${omission.count})`
|
|
556
|
+
] }, `${omission.path}-${omission.reason}-${index}`)) })
|
|
557
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "matrx-alchemy-meta", children: "No omissions or adjustments." }),
|
|
558
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogFooter, { children: [
|
|
559
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: sending, onClick: cancel, children: "Cancel" }),
|
|
560
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Button, { type: "button", className: "matrx-alchemy-workspace-primary", disabled: sending, onClick: confirm, children: sending ? "Sending email\u2026" : "Send email" })
|
|
561
|
+
] })
|
|
562
|
+
] }) }) : null;
|
|
563
|
+
return { email: reviewed, review };
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/content-transfer/index.tsx
|
|
567
|
+
var React10 = __toESM(require("react"), 1);
|
|
568
|
+
var import_react_dom = require("react-dom");
|
|
569
|
+
var import_content_transfer3 = require("@ai-matrx/kit/content-transfer");
|
|
570
|
+
var import_format2 = require("@ai-matrx/kit/format");
|
|
571
|
+
|
|
450
572
|
// src/popover.tsx
|
|
451
573
|
var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"), 1);
|
|
452
|
-
var
|
|
453
|
-
var
|
|
574
|
+
var React7 = __toESM(require("react"), 1);
|
|
575
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
454
576
|
var Popover = PopoverPrimitive.Root;
|
|
455
577
|
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
456
|
-
var PopoverContent =
|
|
578
|
+
var PopoverContent = React7.forwardRef(
|
|
457
579
|
({
|
|
458
580
|
className,
|
|
459
581
|
align = "center",
|
|
@@ -463,7 +585,7 @@ var PopoverContent = React6.forwardRef(
|
|
|
463
585
|
...props
|
|
464
586
|
}, ref) => {
|
|
465
587
|
const portalContainer = usePortalContainer(container);
|
|
466
|
-
return /* @__PURE__ */ (0,
|
|
588
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
467
589
|
PopoverPrimitive.Content,
|
|
468
590
|
{
|
|
469
591
|
ref,
|
|
@@ -492,13 +614,13 @@ var import_react = require("react");
|
|
|
492
614
|
|
|
493
615
|
// src/tooltip.tsx
|
|
494
616
|
var TooltipPrimitive = __toESM(require("@radix-ui/react-tooltip"), 1);
|
|
495
|
-
var
|
|
496
|
-
var
|
|
617
|
+
var React8 = __toESM(require("react"), 1);
|
|
618
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
497
619
|
var Tooltip = TooltipPrimitive.Root;
|
|
498
620
|
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
499
|
-
var TooltipContent =
|
|
621
|
+
var TooltipContent = React8.forwardRef(({ className, sideOffset = 4, container, animated = true, ...props }, ref) => {
|
|
500
622
|
const resolved = usePortalContainer(container);
|
|
501
|
-
return /* @__PURE__ */ (0,
|
|
623
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipPrimitive.Portal, { container: resolved ?? null, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
502
624
|
TooltipPrimitive.Content,
|
|
503
625
|
{
|
|
504
626
|
ref,
|
|
@@ -527,7 +649,7 @@ function getTapTargetLinkComponent() {
|
|
|
527
649
|
}
|
|
528
650
|
|
|
529
651
|
// src/tap-target/tap-target-button.tsx
|
|
530
|
-
var
|
|
652
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
531
653
|
var EXTERNAL_RE = /^(https?:|mailto:|tel:)/i;
|
|
532
654
|
var TAP_OUTER_CLASS = "matrx-tap-target group";
|
|
533
655
|
var TAP_GROUP_OUTER_CLASS = "matrx-tap-target matrx-tap-target-sm group";
|
|
@@ -543,9 +665,9 @@ function IconContent({
|
|
|
543
665
|
className: cn2(className, icon.props.className)
|
|
544
666
|
});
|
|
545
667
|
}
|
|
546
|
-
return /* @__PURE__ */ (0,
|
|
668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className, children: icon });
|
|
547
669
|
}
|
|
548
|
-
return /* @__PURE__ */ (0,
|
|
670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
549
671
|
"svg",
|
|
550
672
|
{
|
|
551
673
|
className,
|
|
@@ -582,7 +704,7 @@ function buildTapInner({
|
|
|
582
704
|
children,
|
|
583
705
|
strokeWidth = 2
|
|
584
706
|
}) {
|
|
585
|
-
const iconEl = /* @__PURE__ */ (0,
|
|
707
|
+
const iconEl = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
586
708
|
IconContent,
|
|
587
709
|
{
|
|
588
710
|
icon,
|
|
@@ -593,11 +715,11 @@ function buildTapInner({
|
|
|
593
715
|
);
|
|
594
716
|
const pillClasses = label ? `${pillClassName} ${inlineModifier}`.trim() : pillClassName;
|
|
595
717
|
if (!label) {
|
|
596
|
-
return /* @__PURE__ */ (0,
|
|
718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: pillClasses, children: iconEl });
|
|
597
719
|
}
|
|
598
|
-
return /* @__PURE__ */ (0,
|
|
720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: pillClasses, children: [
|
|
599
721
|
iconEl,
|
|
600
|
-
/* @__PURE__ */ (0,
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: labelClassName ?? "matrx-tap-label", children: label })
|
|
601
723
|
] });
|
|
602
724
|
}
|
|
603
725
|
function renderTapTarget({
|
|
@@ -685,7 +807,7 @@ function renderTrigger({
|
|
|
685
807
|
buttonRef
|
|
686
808
|
}) {
|
|
687
809
|
if (disabled && href) {
|
|
688
|
-
return /* @__PURE__ */ (0,
|
|
810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
689
811
|
"span",
|
|
690
812
|
{
|
|
691
813
|
"aria-disabled": "true",
|
|
@@ -698,7 +820,7 @@ function renderTrigger({
|
|
|
698
820
|
if (href) {
|
|
699
821
|
const isExternal = EXTERNAL_RE.test(href);
|
|
700
822
|
if (isExternal) {
|
|
701
|
-
return /* @__PURE__ */ (0,
|
|
823
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
702
824
|
"a",
|
|
703
825
|
{
|
|
704
826
|
href,
|
|
@@ -712,7 +834,7 @@ function renderTrigger({
|
|
|
712
834
|
}
|
|
713
835
|
const Link = linkComponent ?? getTapTargetLinkComponent();
|
|
714
836
|
if (Link) {
|
|
715
|
-
return /* @__PURE__ */ (0,
|
|
837
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
716
838
|
Link,
|
|
717
839
|
{
|
|
718
840
|
href,
|
|
@@ -725,7 +847,7 @@ function renderTrigger({
|
|
|
725
847
|
}
|
|
726
848
|
);
|
|
727
849
|
}
|
|
728
|
-
return /* @__PURE__ */ (0,
|
|
850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
729
851
|
"a",
|
|
730
852
|
{
|
|
731
853
|
href,
|
|
@@ -738,7 +860,7 @@ function renderTrigger({
|
|
|
738
860
|
);
|
|
739
861
|
}
|
|
740
862
|
if (as === "label") {
|
|
741
|
-
return /* @__PURE__ */ (0,
|
|
863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
742
864
|
"label",
|
|
743
865
|
{
|
|
744
866
|
htmlFor,
|
|
@@ -748,7 +870,7 @@ function renderTrigger({
|
|
|
748
870
|
}
|
|
749
871
|
);
|
|
750
872
|
}
|
|
751
|
-
return /* @__PURE__ */ (0,
|
|
873
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
752
874
|
"button",
|
|
753
875
|
{
|
|
754
876
|
ref: buttonRef,
|
|
@@ -772,14 +894,14 @@ function withTooltip(trigger, {
|
|
|
772
894
|
if (tooltip === false) return trigger;
|
|
773
895
|
const label = typeof tooltip === "string" && tooltip.length > 0 ? tooltip : ariaLabel;
|
|
774
896
|
if (!label) return trigger;
|
|
775
|
-
return /* @__PURE__ */ (0,
|
|
776
|
-
/* @__PURE__ */ (0,
|
|
897
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: disabled ? (
|
|
777
899
|
// Radix Tooltip triggers need a hoverable element; a disabled button
|
|
778
900
|
// does not dispatch pointer events, so we wrap in a span for the
|
|
779
901
|
// trigger target while keeping the disabled visual state.
|
|
780
|
-
/* @__PURE__ */ (0,
|
|
902
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "inline-flex", children: trigger })
|
|
781
903
|
) : trigger }),
|
|
782
|
-
/* @__PURE__ */ (0,
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side: tooltipSide, align: tooltipAlign, children: label })
|
|
783
905
|
] });
|
|
784
906
|
}
|
|
785
907
|
var TapTargetButton = (0, import_react.forwardRef)(function TapTargetButton2({
|
|
@@ -935,7 +1057,7 @@ var TapTargetButtonDestructive = (0, import_react.forwardRef)(function TapTarget
|
|
|
935
1057
|
hoverBgColor = "hover:bg-destructive/90",
|
|
936
1058
|
...rest
|
|
937
1059
|
}, ref) {
|
|
938
|
-
return /* @__PURE__ */ (0,
|
|
1060
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
939
1061
|
TapTargetButtonSolid,
|
|
940
1062
|
{
|
|
941
1063
|
ref,
|
|
@@ -999,7 +1121,7 @@ var TapTargetButtonForGroup = (0, import_react.forwardRef)(function TapTargetBut
|
|
|
999
1121
|
|
|
1000
1122
|
// src/content-transfer/icon.ts
|
|
1001
1123
|
var ALCHEMY_GLYPH_PATHS = {
|
|
1002
|
-
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-
|
|
1124
|
+
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"],
|
|
1003
1125
|
"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"]
|
|
1004
1126
|
};
|
|
1005
1127
|
var ALCHEMY_GLYPH_VIEWBOX = { portal: "0 0 24 24", "copy-transform": "0 0 24 24" };
|
|
@@ -1007,15 +1129,119 @@ var svg = (paths, viewBox) => `<svg xmlns="http://www.w3.org/2000/svg" width="18
|
|
|
1007
1129
|
var ALCHEMY_GLYPH_SVG = svg(ALCHEMY_GLYPH_PATHS.portal, ALCHEMY_GLYPH_VIEWBOX.portal);
|
|
1008
1130
|
var ALCHEMY_COPY_TRANSFORM_SVG = svg(ALCHEMY_GLYPH_PATHS["copy-transform"], ALCHEMY_GLYPH_VIEWBOX["copy-transform"]);
|
|
1009
1131
|
|
|
1010
|
-
// src/content-transfer/
|
|
1011
|
-
var React8 = __toESM(require("react"), 1);
|
|
1132
|
+
// src/content-transfer/extensions.ts
|
|
1012
1133
|
var import_content_transfer = require("@ai-matrx/kit/content-transfer");
|
|
1134
|
+
var exportableColumns = (payload) => payload.columns.filter(
|
|
1135
|
+
(column) => column.visible && column.exportable !== false && column.classification !== "secret" && column.classification !== "credential"
|
|
1136
|
+
);
|
|
1137
|
+
var tableSchemaFormat = {
|
|
1138
|
+
id: "table-schema",
|
|
1139
|
+
label: "Schema + rows",
|
|
1140
|
+
supports: (payload) => payload.kind === "rows",
|
|
1141
|
+
async build(draft, signal) {
|
|
1142
|
+
if (signal.aborted) throw new DOMException("Cancelled", "AbortError");
|
|
1143
|
+
if (draft.payload.kind !== "rows")
|
|
1144
|
+
throw new import_content_transfer.ContentTransferError(
|
|
1145
|
+
"unsupported-format",
|
|
1146
|
+
"Schema + rows requires tabular content; manually edited text cannot carry a table schema."
|
|
1147
|
+
);
|
|
1148
|
+
const rowColumns = exportableColumns(draft.payload);
|
|
1149
|
+
const columns = rowColumns.map((column) => ({
|
|
1150
|
+
id: column.id,
|
|
1151
|
+
label: column.label,
|
|
1152
|
+
path: column.path,
|
|
1153
|
+
...column.schema === void 0 ? {} : { schema: column.schema }
|
|
1154
|
+
}));
|
|
1155
|
+
const body = {
|
|
1156
|
+
sourceId: draft.sourceId,
|
|
1157
|
+
columns,
|
|
1158
|
+
rows: draft.payload.rows.map(
|
|
1159
|
+
(row) => Object.fromEntries(rowColumns.map((column) => [column.id, (0, import_content_transfer.readTransferCell)(row, column) ?? null]))
|
|
1160
|
+
)
|
|
1161
|
+
};
|
|
1162
|
+
const plainText = JSON.stringify(body, null, 2);
|
|
1163
|
+
return (0, import_content_transfer.sealTransferArtifact)({
|
|
1164
|
+
snapshotId: draft.snapshotId,
|
|
1165
|
+
draftRevision: draft.revision,
|
|
1166
|
+
format: "table-schema",
|
|
1167
|
+
plainText,
|
|
1168
|
+
file: {
|
|
1169
|
+
filename: "table-schema.json",
|
|
1170
|
+
mime: "application/json",
|
|
1171
|
+
bytes: new TextEncoder().encode(plainText)
|
|
1172
|
+
},
|
|
1173
|
+
omissions: [...draft.omissions]
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
function displayLabels(payload) {
|
|
1178
|
+
const columns = exportableColumns(payload);
|
|
1179
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1180
|
+
for (const column of columns) counts.set(column.label, (counts.get(column.label) ?? 0) + 1);
|
|
1181
|
+
const used = /* @__PURE__ */ new Set();
|
|
1182
|
+
return columns.map((column) => {
|
|
1183
|
+
const base = counts.get(column.label) === 1 ? column.label : `${column.label} [${column.id}]`;
|
|
1184
|
+
let label = base;
|
|
1185
|
+
for (let suffix = 2; used.has(label); suffix += 1) label = `${base} (${suffix})`;
|
|
1186
|
+
used.add(label);
|
|
1187
|
+
return [label, column];
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
var tableDataFormat = {
|
|
1191
|
+
id: "table-data",
|
|
1192
|
+
label: "JSON (display labels)",
|
|
1193
|
+
supports: (payload) => payload.kind === "rows",
|
|
1194
|
+
async build(draft, signal) {
|
|
1195
|
+
if (signal.aborted) throw new DOMException("Cancelled", "AbortError");
|
|
1196
|
+
if (draft.payload.kind !== "rows")
|
|
1197
|
+
throw new import_content_transfer.ContentTransferError("unsupported-format", "Display-label JSON requires tabular content.");
|
|
1198
|
+
const columns = displayLabels(draft.payload);
|
|
1199
|
+
const plainText = JSON.stringify(
|
|
1200
|
+
draft.payload.rows.map(
|
|
1201
|
+
(row) => Object.fromEntries(columns.map(([label, column]) => [label, (0, import_content_transfer.readTransferCell)(row, column) ?? null]))
|
|
1202
|
+
),
|
|
1203
|
+
null,
|
|
1204
|
+
2
|
|
1205
|
+
);
|
|
1206
|
+
return (0, import_content_transfer.sealTransferArtifact)({
|
|
1207
|
+
snapshotId: draft.snapshotId,
|
|
1208
|
+
draftRevision: draft.revision,
|
|
1209
|
+
format: "json",
|
|
1210
|
+
plainText,
|
|
1211
|
+
file: {
|
|
1212
|
+
filename: "data.json",
|
|
1213
|
+
mime: "application/json;charset=utf-8",
|
|
1214
|
+
bytes: new TextEncoder().encode(plainText)
|
|
1215
|
+
},
|
|
1216
|
+
omissions: [...draft.omissions]
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
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" }));
|
|
1221
|
+
function createTransferEmailActions(email, options = {}) {
|
|
1222
|
+
return ["csv", "json", "markdown"].map((format) => ({
|
|
1223
|
+
id: `email-${format}`,
|
|
1224
|
+
label: `Email ${format === "csv" ? "CSV" : format === "json" ? "JSON" : "Markdown"}`,
|
|
1225
|
+
prepared: true,
|
|
1226
|
+
group: "email",
|
|
1227
|
+
supports: (_snapshot, draft) => Boolean(draft) && (format !== "csv" || draft?.payload.kind === "rows"),
|
|
1228
|
+
async run({ draft, signal, snapshot }) {
|
|
1229
|
+
if (signal.aborted) return { status: "cancelled" };
|
|
1230
|
+
const artifact = await emailArtifact(draft, format, signal, options.jsonFormat);
|
|
1231
|
+
return email.send(artifact, { label: snapshot.label, signal });
|
|
1232
|
+
}
|
|
1233
|
+
}));
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// src/content-transfer/matrx-copy.tsx
|
|
1237
|
+
var React9 = __toESM(require("react"), 1);
|
|
1238
|
+
var import_content_transfer2 = require("@ai-matrx/kit/content-transfer");
|
|
1013
1239
|
var import_format = require("@ai-matrx/kit/format");
|
|
1014
|
-
var
|
|
1240
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1015
1241
|
var resolve = (value) => typeof value === "function" ? value() : value;
|
|
1016
1242
|
var asPayload = (value) => ({
|
|
1017
1243
|
kind: "markdown",
|
|
1018
|
-
text: typeof value === "string" ? value : (0,
|
|
1244
|
+
text: typeof value === "string" ? value : (0, import_content_transfer2.buildAgentPayload)(value)
|
|
1019
1245
|
});
|
|
1020
1246
|
var structuredPayload = (value) => {
|
|
1021
1247
|
if (typeof value === "string") return { kind: "markdown", text: value };
|
|
@@ -1024,7 +1250,7 @@ var structuredPayload = (value) => {
|
|
|
1024
1250
|
);
|
|
1025
1251
|
return {
|
|
1026
1252
|
kind: "json",
|
|
1027
|
-
value: (0,
|
|
1253
|
+
value: (0, import_content_transfer2.normalizeTransferJson)(
|
|
1028
1254
|
{
|
|
1029
1255
|
kind: value.kind,
|
|
1030
1256
|
location: value.location,
|
|
@@ -1052,12 +1278,12 @@ var sourceFor = (id, label, build) => ({
|
|
|
1052
1278
|
signal.throwIfAborted();
|
|
1053
1279
|
const payload = await build();
|
|
1054
1280
|
signal.throwIfAborted();
|
|
1055
|
-
return (0,
|
|
1281
|
+
return (0, import_content_transfer2.directSource)(payload, { sourceId: id, label });
|
|
1056
1282
|
}
|
|
1057
1283
|
});
|
|
1058
1284
|
function MatrxCopyMenu(props) {
|
|
1059
1285
|
const inherited = useContentTransferCapabilities();
|
|
1060
|
-
return /* @__PURE__ */ (0,
|
|
1286
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1061
1287
|
MatrxCopyMenuSession,
|
|
1062
1288
|
{
|
|
1063
1289
|
...props
|
|
@@ -1069,12 +1295,12 @@ function MatrxCopyMenu(props) {
|
|
|
1069
1295
|
);
|
|
1070
1296
|
}
|
|
1071
1297
|
function MatrxCopyMenuSession(props) {
|
|
1072
|
-
const instance =
|
|
1073
|
-
const controller =
|
|
1298
|
+
const instance = React9.useId();
|
|
1299
|
+
const controller = React9.useRef(null);
|
|
1074
1300
|
const capabilities = useContentTransferCapabilities();
|
|
1075
|
-
const transport = capabilities.transport ?? (0,
|
|
1076
|
-
const [modal, setModal] =
|
|
1077
|
-
const [configuration, setConfiguration] =
|
|
1301
|
+
const transport = capabilities.transport ?? (0, import_content_transfer2.createBrowserTransport)();
|
|
1302
|
+
const [modal, setModal] = React9.useState(null);
|
|
1303
|
+
const [configuration, setConfiguration] = React9.useState(null);
|
|
1078
1304
|
const copyVisible = !props.hide?.includes("copy");
|
|
1079
1305
|
const aiVisible = !props.hide?.includes("ai");
|
|
1080
1306
|
const exportVisible = !props.hide?.includes("export");
|
|
@@ -1090,14 +1316,14 @@ function MatrxCopyMenuSession(props) {
|
|
|
1090
1316
|
})) : void 0;
|
|
1091
1317
|
const json = aiVisible && props.json !== void 0 ? make("json", () => ({
|
|
1092
1318
|
kind: "json",
|
|
1093
|
-
value: (0,
|
|
1319
|
+
value: (0, import_content_transfer2.normalizeTransferJson)(resolve(props.json), {
|
|
1094
1320
|
omitUndefinedObjectProperties: true
|
|
1095
1321
|
})
|
|
1096
1322
|
})) : void 0;
|
|
1097
1323
|
const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
|
|
1098
1324
|
const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
|
|
1099
1325
|
const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
|
|
1100
|
-
const value = (0,
|
|
1326
|
+
const value = (0, import_content_transfer2.normalizeTransferJson)(props.export.sheetRows(), {
|
|
1101
1327
|
omitUndefinedObjectProperties: true
|
|
1102
1328
|
});
|
|
1103
1329
|
if (!Array.isArray(value) || value.some(
|
|
@@ -1234,7 +1460,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1234
1460
|
const bytes = new Uint8Array(value.bytes);
|
|
1235
1461
|
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"}`;
|
|
1236
1462
|
return transport.download(
|
|
1237
|
-
(0,
|
|
1463
|
+
(0, import_content_transfer2.sealTransferArtifact)({
|
|
1238
1464
|
snapshotId: snapshot.id,
|
|
1239
1465
|
draftRevision: draft.revision,
|
|
1240
1466
|
format: `export:${item.id}`,
|
|
@@ -1261,11 +1487,14 @@ function MatrxCopyMenuSession(props) {
|
|
|
1261
1487
|
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
1262
1488
|
if (!source && !actions.length) return null;
|
|
1263
1489
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
1264
|
-
return /* @__PURE__ */ (0,
|
|
1265
|
-
/* @__PURE__ */ (0,
|
|
1490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1491
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1266
1492
|
ContentTransferMenu,
|
|
1267
1493
|
{
|
|
1494
|
+
triggerSize: props.size === "xs" || props.size === "toolbar" ? "compact" : "default",
|
|
1268
1495
|
source: target,
|
|
1496
|
+
...props.references ? { references: props.references } : {},
|
|
1497
|
+
...props.referenceActions ? { referenceActions: props.referenceActions } : {},
|
|
1269
1498
|
...props.icon !== void 0 ? { icon: props.icon } : {},
|
|
1270
1499
|
...props.triggerVariant !== void 0 ? { triggerVariant: props.triggerVariant } : {},
|
|
1271
1500
|
controllerRef: controller,
|
|
@@ -1299,7 +1528,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1299
1528
|
if (!open) setModal(null);
|
|
1300
1529
|
}
|
|
1301
1530
|
}),
|
|
1302
|
-
configuration ? /* @__PURE__ */ (0,
|
|
1531
|
+
configuration ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1303
1532
|
SourceConfiguration,
|
|
1304
1533
|
{
|
|
1305
1534
|
restoreFocus: () => controller.current?.focusTrigger(),
|
|
@@ -1326,14 +1555,14 @@ function SourceConfiguration({
|
|
|
1326
1555
|
onPrepare
|
|
1327
1556
|
}) {
|
|
1328
1557
|
const custom = configuration.custom;
|
|
1329
|
-
const handingOff =
|
|
1558
|
+
const handingOff = React9.useRef(false);
|
|
1330
1559
|
const groomer = configuration.groomer;
|
|
1331
|
-
const [values, setValues] =
|
|
1560
|
+
const [values, setValues] = React9.useState(
|
|
1332
1561
|
() => Object.fromEntries(
|
|
1333
1562
|
custom?.options.map((option) => [option.key, option.default]) ?? []
|
|
1334
1563
|
)
|
|
1335
1564
|
);
|
|
1336
|
-
const [sections, setSections] =
|
|
1565
|
+
const [sections, setSections] = React9.useState(
|
|
1337
1566
|
() => Object.fromEntries(
|
|
1338
1567
|
groomer?.sections.map((section) => [
|
|
1339
1568
|
section.id,
|
|
@@ -1341,8 +1570,8 @@ function SourceConfiguration({
|
|
|
1341
1570
|
]) ?? []
|
|
1342
1571
|
)
|
|
1343
1572
|
);
|
|
1344
|
-
const [error, setError] =
|
|
1345
|
-
const [busy, setBusy] =
|
|
1573
|
+
const [error, setError] = React9.useState(null);
|
|
1574
|
+
const [busy, setBusy] = React9.useState(false);
|
|
1346
1575
|
const title = custom?.dialogTitle ?? groomer?.label ?? "Customize source";
|
|
1347
1576
|
let prepared = null;
|
|
1348
1577
|
let buildError = null;
|
|
@@ -1375,18 +1604,18 @@ function SourceConfiguration({
|
|
|
1375
1604
|
...groomer.context ? { context: groomer.context } : {}
|
|
1376
1605
|
};
|
|
1377
1606
|
}
|
|
1378
|
-
text = prepared ? (0,
|
|
1607
|
+
text = prepared ? (0, import_content_transfer2.buildAgentPayload)(prepared) : "";
|
|
1379
1608
|
} catch (cause) {
|
|
1380
1609
|
buildError = cause instanceof Error ? cause.message : "Could not prepare this source.";
|
|
1381
1610
|
}
|
|
1382
|
-
return /* @__PURE__ */ (0,
|
|
1611
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1383
1612
|
Dialog,
|
|
1384
1613
|
{
|
|
1385
1614
|
open: true,
|
|
1386
1615
|
onOpenChange: (open) => {
|
|
1387
1616
|
if (!open && !busy) onClose();
|
|
1388
1617
|
},
|
|
1389
|
-
children: /* @__PURE__ */ (0,
|
|
1618
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1390
1619
|
DialogContent,
|
|
1391
1620
|
{
|
|
1392
1621
|
onCloseAutoFocus: (event) => {
|
|
@@ -1395,23 +1624,23 @@ function SourceConfiguration({
|
|
|
1395
1624
|
},
|
|
1396
1625
|
className: "matrx-alchemy-workspace matrx-alchemy-configuration",
|
|
1397
1626
|
children: [
|
|
1398
|
-
/* @__PURE__ */ (0,
|
|
1399
|
-
/* @__PURE__ */ (0,
|
|
1400
|
-
/* @__PURE__ */ (0,
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogHeader, { children: [
|
|
1628
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogTitle, { children: title }),
|
|
1629
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogDescription, { children: custom?.dialogDescription ?? "Choose the source detail, then prepare, edit, summarize, copy or export it in Alchemy." })
|
|
1401
1630
|
] }),
|
|
1402
|
-
/* @__PURE__ */ (0,
|
|
1403
|
-
/* @__PURE__ */ (0,
|
|
1404
|
-
custom?.options.map((option) => /* @__PURE__ */ (0,
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
1632
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "matrx-alchemy-main matrx-alchemy-toolbar", children: [
|
|
1633
|
+
custom?.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
1405
1634
|
option.label,
|
|
1406
|
-
"hint" in option && option.hint ? /* @__PURE__ */ (0,
|
|
1407
|
-
option.kind === "toggle" ? /* @__PURE__ */ (0,
|
|
1635
|
+
"hint" in option && option.hint ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { children: option.hint }) : null,
|
|
1636
|
+
option.kind === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1408
1637
|
"input",
|
|
1409
1638
|
{
|
|
1410
1639
|
type: "checkbox",
|
|
1411
1640
|
checked: Boolean(values[option.key]),
|
|
1412
1641
|
onChange: (event) => setValues({ ...values, [option.key]: event.target.checked })
|
|
1413
1642
|
}
|
|
1414
|
-
) : option.kind === "preset" ? /* @__PURE__ */ (0,
|
|
1643
|
+
) : option.kind === "preset" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1415
1644
|
"select",
|
|
1416
1645
|
{
|
|
1417
1646
|
value: Number(values[option.key]),
|
|
@@ -1419,10 +1648,10 @@ function SourceConfiguration({
|
|
|
1419
1648
|
...values,
|
|
1420
1649
|
[option.key]: Number(event.target.value)
|
|
1421
1650
|
}),
|
|
1422
|
-
children: option.options.map((choice) => /* @__PURE__ */ (0,
|
|
1651
|
+
children: option.options.map((choice) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: choice.value, children: choice.label }, choice.value))
|
|
1423
1652
|
}
|
|
1424
|
-
) : option.kind === "slider" ? /* @__PURE__ */ (0,
|
|
1425
|
-
/* @__PURE__ */ (0,
|
|
1653
|
+
) : option.kind === "slider" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1426
1655
|
"input",
|
|
1427
1656
|
{
|
|
1428
1657
|
type: "range",
|
|
@@ -1436,9 +1665,9 @@ function SourceConfiguration({
|
|
|
1436
1665
|
})
|
|
1437
1666
|
}
|
|
1438
1667
|
),
|
|
1439
|
-
/* @__PURE__ */ (0,
|
|
1440
|
-
] }) : /* @__PURE__ */ (0,
|
|
1441
|
-
/* @__PURE__ */ (0,
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: option.formatValue(Number(values[option.key])) })
|
|
1669
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1670
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1442
1671
|
"input",
|
|
1443
1672
|
{
|
|
1444
1673
|
type: "number",
|
|
@@ -1451,7 +1680,7 @@ function SourceConfiguration({
|
|
|
1451
1680
|
})
|
|
1452
1681
|
}
|
|
1453
1682
|
),
|
|
1454
|
-
option.presets?.map((preset) => /* @__PURE__ */ (0,
|
|
1683
|
+
option.presets?.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1455
1684
|
Button,
|
|
1456
1685
|
{
|
|
1457
1686
|
type: "button",
|
|
@@ -1464,8 +1693,8 @@ function SourceConfiguration({
|
|
|
1464
1693
|
))
|
|
1465
1694
|
] })
|
|
1466
1695
|
] }, option.key)),
|
|
1467
|
-
groomer ? /* @__PURE__ */ (0,
|
|
1468
|
-
/* @__PURE__ */ (0,
|
|
1696
|
+
groomer ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
1697
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: ["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1469
1698
|
Button,
|
|
1470
1699
|
{
|
|
1471
1700
|
type: "button",
|
|
@@ -1483,9 +1712,9 @@ function SourceConfiguration({
|
|
|
1483
1712
|
},
|
|
1484
1713
|
level
|
|
1485
1714
|
)) }),
|
|
1486
|
-
groomer.sections.map((section) => /* @__PURE__ */ (0,
|
|
1715
|
+
groomer.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { children: [
|
|
1487
1716
|
section.title,
|
|
1488
|
-
/* @__PURE__ */ (0,
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
1489
1718
|
"select",
|
|
1490
1719
|
{
|
|
1491
1720
|
value: sections[section.id],
|
|
@@ -1494,26 +1723,26 @@ function SourceConfiguration({
|
|
|
1494
1723
|
[section.id]: event.target.value
|
|
1495
1724
|
}),
|
|
1496
1725
|
children: [
|
|
1497
|
-
["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0,
|
|
1498
|
-
section.cuttable ? /* @__PURE__ */ (0,
|
|
1726
|
+
["full", "compact", "brief"].map((level) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: level, children: section.levelLabels?.[level] ?? level }, level)),
|
|
1727
|
+
section.cuttable ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("option", { value: "off", children: "Exclude" }) : null
|
|
1499
1728
|
]
|
|
1500
1729
|
}
|
|
1501
1730
|
),
|
|
1502
|
-
section.description ? /* @__PURE__ */ (0,
|
|
1731
|
+
section.description ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: section.description }) : null
|
|
1503
1732
|
] }, section.id))
|
|
1504
1733
|
] }) : null
|
|
1505
1734
|
] }),
|
|
1506
|
-
/* @__PURE__ */ (0,
|
|
1735
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { children: [
|
|
1507
1736
|
(0, import_format.formatCount)(text.length),
|
|
1508
1737
|
" characters \xB7 approximately",
|
|
1509
1738
|
" ",
|
|
1510
1739
|
(0, import_format.formatCount)(Math.ceil(text.length / 4)),
|
|
1511
1740
|
" tokens"
|
|
1512
1741
|
] }),
|
|
1513
|
-
error || buildError ? /* @__PURE__ */ (0,
|
|
1742
|
+
error || buildError ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { role: "alert", children: error ?? buildError }) : null
|
|
1514
1743
|
] }),
|
|
1515
|
-
/* @__PURE__ */ (0,
|
|
1516
|
-
/* @__PURE__ */ (0,
|
|
1744
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(DialogFooter, { children: [
|
|
1745
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1517
1746
|
Button,
|
|
1518
1747
|
{
|
|
1519
1748
|
type: "button",
|
|
@@ -1524,7 +1753,7 @@ function SourceConfiguration({
|
|
|
1524
1753
|
children: "Cancel"
|
|
1525
1754
|
}
|
|
1526
1755
|
),
|
|
1527
|
-
/* @__PURE__ */ (0,
|
|
1756
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1528
1757
|
Button,
|
|
1529
1758
|
{
|
|
1530
1759
|
type: "button",
|
|
@@ -1615,26 +1844,26 @@ function groomerPresetVariants(getConfig) {
|
|
|
1615
1844
|
}
|
|
1616
1845
|
|
|
1617
1846
|
// src/content-transfer/index.tsx
|
|
1618
|
-
var
|
|
1847
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1619
1848
|
function AlchemyGlyph({ icon = "portal", ...props }) {
|
|
1620
|
-
return /* @__PURE__ */ (0,
|
|
1849
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsx)("path", { d }, d)) });
|
|
1621
1850
|
}
|
|
1622
|
-
var CapabilityContext =
|
|
1851
|
+
var CapabilityContext = React10.createContext({});
|
|
1623
1852
|
function ContentTransferCapabilitiesProvider({ value, children }) {
|
|
1624
|
-
return /* @__PURE__ */ (0,
|
|
1853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CapabilityContext.Provider, { value, children });
|
|
1625
1854
|
}
|
|
1626
|
-
var useContentTransferCapabilities = () =>
|
|
1627
|
-
var SurfaceContext =
|
|
1855
|
+
var useContentTransferCapabilities = () => React10.useContext(CapabilityContext);
|
|
1856
|
+
var SurfaceContext = React10.createContext(null);
|
|
1628
1857
|
function ContentTransferSurfaceProvider({ handle, children }) {
|
|
1629
|
-
return /* @__PURE__ */ (0,
|
|
1858
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SurfaceContext.Provider, { value: handle, children });
|
|
1630
1859
|
}
|
|
1631
|
-
var useContentTransferSurface = () =>
|
|
1860
|
+
var useContentTransferSurface = () => React10.useContext(SurfaceContext);
|
|
1632
1861
|
function MenuPresentation({ label, hint, icon: Icon }) {
|
|
1633
|
-
return /* @__PURE__ */ (0,
|
|
1634
|
-
Icon ? /* @__PURE__ */ (0,
|
|
1635
|
-
/* @__PURE__ */ (0,
|
|
1862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1863
|
+
Icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : null,
|
|
1864
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
1636
1865
|
label,
|
|
1637
|
-
hint ? /* @__PURE__ */ (0,
|
|
1866
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1638
1867
|
] })
|
|
1639
1868
|
] });
|
|
1640
1869
|
}
|
|
@@ -1652,71 +1881,71 @@ function DestinationPresentation({ action }) {
|
|
|
1652
1881
|
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"
|
|
1653
1882
|
};
|
|
1654
1883
|
const path = paths[action.id.replace(/^matrx:/, "")];
|
|
1655
|
-
return /* @__PURE__ */ (0,
|
|
1656
|
-
!action.icon ? path ? /* @__PURE__ */ (0,
|
|
1657
|
-
/* @__PURE__ */ (0,
|
|
1884
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1885
|
+
!action.icon ? path ? /* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsx)("path", { d: path }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { file: true }) : null,
|
|
1886
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MenuPresentation, { ...action })
|
|
1658
1887
|
] });
|
|
1659
1888
|
}
|
|
1660
1889
|
function ReceiptLink({ target }) {
|
|
1661
|
-
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0,
|
|
1890
|
+
return target?.href && /^(\/(?!\/)|https?:\/\/)/.test(target.href) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("a", { className: "matrx-alchemy-receipt-link", href: target.href, children: [
|
|
1662
1891
|
"Open ",
|
|
1663
1892
|
target.kind
|
|
1664
1893
|
] }) : null;
|
|
1665
1894
|
}
|
|
1666
1895
|
function PaletteGlyph({ format, ai = false, file = false, kind }) {
|
|
1667
|
-
if (kind === "ai-copy") return /* @__PURE__ */ (0,
|
|
1668
|
-
/* @__PURE__ */ (0,
|
|
1669
|
-
/* @__PURE__ */ (0,
|
|
1670
|
-
/* @__PURE__ */ (0,
|
|
1896
|
+
if (kind === "ai-copy") return /* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
1897
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "5", y: "5", width: "11", height: "14", rx: "2" }),
|
|
1898
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M9 3h6a2 2 0 0 1 2 2v10" }),
|
|
1899
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m18.5 3 .55 1.45L20.5 5l-1.45.55L18.5 7l-.55-1.45L16.5 5l1.45-.55z" })
|
|
1671
1900
|
] });
|
|
1672
|
-
if (kind === "sliders") return /* @__PURE__ */ (0,
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
1674
|
-
/* @__PURE__ */ (0,
|
|
1901
|
+
if (kind === "sliders") return /* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
1902
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 6h16M4 12h16M4 18h16" }),
|
|
1903
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M8 3v6M16 9v6M10 15v6" })
|
|
1675
1904
|
] });
|
|
1676
|
-
if (ai) return /* @__PURE__ */ (0,
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
1679
|
-
/* @__PURE__ */ (0,
|
|
1905
|
+
if (ai) return /* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M12 5v14M8 9h1M15 9h1M8 15h1M15 15h1" })
|
|
1680
1909
|
] });
|
|
1681
|
-
if (file) return /* @__PURE__ */ (0,
|
|
1682
|
-
/* @__PURE__ */ (0,
|
|
1683
|
-
/* @__PURE__ */ (0,
|
|
1910
|
+
if (file) return /* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
1911
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M6 3h8l4 4v14H6z" }),
|
|
1912
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 3v5h5M9 13h6M9 17h6" })
|
|
1684
1913
|
] });
|
|
1685
|
-
const path = format === "json" ? /* @__PURE__ */ (0,
|
|
1686
|
-
/* @__PURE__ */ (0,
|
|
1687
|
-
/* @__PURE__ */ (0,
|
|
1688
|
-
] }) : format === "compact-json" ? /* @__PURE__ */ (0,
|
|
1689
|
-
/* @__PURE__ */ (0,
|
|
1690
|
-
/* @__PURE__ */ (0,
|
|
1691
|
-
/* @__PURE__ */ (0,
|
|
1692
|
-
/* @__PURE__ */ (0,
|
|
1693
|
-
] }) : format === "csv" ? /* @__PURE__ */ (0,
|
|
1694
|
-
/* @__PURE__ */ (0,
|
|
1695
|
-
/* @__PURE__ */ (0,
|
|
1696
|
-
] }) : format === "tsv" ? /* @__PURE__ */ (0,
|
|
1697
|
-
/* @__PURE__ */ (0,
|
|
1698
|
-
/* @__PURE__ */ (0,
|
|
1699
|
-
] }) : format === "xlsx" ? /* @__PURE__ */ (0,
|
|
1700
|
-
/* @__PURE__ */ (0,
|
|
1701
|
-
/* @__PURE__ */ (0,
|
|
1702
|
-
] }) : format === "markdown" ? /* @__PURE__ */ (0,
|
|
1703
|
-
/* @__PURE__ */ (0,
|
|
1704
|
-
/* @__PURE__ */ (0,
|
|
1705
|
-
] }) : format === "html" ? /* @__PURE__ */ (0,
|
|
1706
|
-
return /* @__PURE__ */ (0,
|
|
1914
|
+
const path = format === "json" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M9 4C7 4 7 7 5 7v3c2 0 2 1 2 2s0 2-2 2v3c2 0 2 3 4 3" }),
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" })
|
|
1917
|
+
] }) : format === "compact-json" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1918
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m14 10 7-7" }),
|
|
1919
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M20 10h-6V4" }),
|
|
1920
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "m3 21 7-7" }),
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 14h6v6" })
|
|
1922
|
+
] }) : format === "csv" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1923
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", rx: "1" }),
|
|
1924
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 10h16M10 4v16" })
|
|
1925
|
+
] }) : format === "tsv" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1926
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1927
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2v6h6M8 13h2M14 13h2M8 17h2M14 17h2" })
|
|
1928
|
+
] }) : format === "xlsx" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1929
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
1930
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2v6h6M8 13h8M8 17h8M12 11v8" })
|
|
1931
|
+
] }) : format === "markdown" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1932
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
1933
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M14 2v6h6M10 13l-2 2 2 2M14 17l2-2-2-2" })
|
|
1934
|
+
] }) : format === "html" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M15 6h6M3 6h7M3 12h18M3 18h12" }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }) });
|
|
1935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.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 });
|
|
1707
1936
|
}
|
|
1708
1937
|
function PaletteRows({ title, items, onRun, extra, ai = false, glyphKind, fallbackHint }) {
|
|
1709
1938
|
if (!items.length && !extra) return null;
|
|
1710
|
-
return /* @__PURE__ */ (0,
|
|
1711
|
-
/* @__PURE__ */ (0,
|
|
1939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { children: title }),
|
|
1712
1941
|
items.map((item) => {
|
|
1713
1942
|
const label = item.copyLabel ?? item.label;
|
|
1714
1943
|
const hint = item.hint ?? fallbackHint;
|
|
1715
|
-
return /* @__PURE__ */ (0,
|
|
1716
|
-
item.icon ? /* @__PURE__ */ (0,
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
1944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.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: [
|
|
1945
|
+
item.icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(item.icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { ai, ...glyphKind ? { kind: glyphKind } : {} }),
|
|
1946
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
1718
1947
|
label,
|
|
1719
|
-
hint ? /* @__PURE__ */ (0,
|
|
1948
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: hint }) : null
|
|
1720
1949
|
] })
|
|
1721
1950
|
] }, item.id);
|
|
1722
1951
|
}),
|
|
@@ -1759,10 +1988,10 @@ function snapshotContent(snapshot) {
|
|
|
1759
1988
|
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
1760
1989
|
}
|
|
1761
1990
|
function useFence() {
|
|
1762
|
-
const mounted =
|
|
1763
|
-
const nextId =
|
|
1764
|
-
const active =
|
|
1765
|
-
|
|
1991
|
+
const mounted = React10.useRef(true);
|
|
1992
|
+
const nextId = React10.useRef(0);
|
|
1993
|
+
const active = React10.useRef(/* @__PURE__ */ new Set());
|
|
1994
|
+
React10.useEffect(() => {
|
|
1766
1995
|
mounted.current = true;
|
|
1767
1996
|
return () => {
|
|
1768
1997
|
mounted.current = false;
|
|
@@ -1771,14 +2000,14 @@ function useFence() {
|
|
|
1771
2000
|
active.current.clear();
|
|
1772
2001
|
};
|
|
1773
2002
|
}, []);
|
|
1774
|
-
const begin =
|
|
2003
|
+
const begin = React10.useCallback(() => {
|
|
1775
2004
|
const controller = new AbortController();
|
|
1776
2005
|
active.current.add(controller);
|
|
1777
2006
|
return { controller, id: ++nextId.current };
|
|
1778
2007
|
}, []);
|
|
1779
|
-
const finish =
|
|
1780
|
-
const valid =
|
|
1781
|
-
const abortAll =
|
|
2008
|
+
const finish = React10.useCallback((controller) => active.current.delete(controller), []);
|
|
2009
|
+
const valid = React10.useCallback((id, controller) => mounted.current && !controller.signal.aborted && nextId.current === id, []);
|
|
2010
|
+
const abortAll = React10.useCallback(() => {
|
|
1782
2011
|
nextId.current += 1;
|
|
1783
2012
|
active.current.forEach((c) => c.abort());
|
|
1784
2013
|
active.current.clear();
|
|
@@ -1790,73 +2019,79 @@ async function xlsxArtifact(draft, label) {
|
|
|
1790
2019
|
const XLSX = await import("xlsx");
|
|
1791
2020
|
const columns = draft.payload.columns.filter((c) => c.visible && c.exportable !== false && c.classification !== "secret" && c.classification !== "credential");
|
|
1792
2021
|
const cells = draft.payload.rows.map((row) => columns.map((column) => {
|
|
1793
|
-
const value = (0,
|
|
2022
|
+
const value = (0, import_content_transfer3.readTransferCell)(row, column);
|
|
1794
2023
|
return value === null || ["string", "number", "boolean"].includes(typeof value) ? value : value === void 0 ? "" : JSON.stringify(value);
|
|
1795
2024
|
}));
|
|
1796
2025
|
const sheet = XLSX.utils.aoa_to_sheet([columns.map((c) => c.label), ...cells]);
|
|
1797
2026
|
const book = XLSX.utils.book_new();
|
|
1798
2027
|
XLSX.utils.book_append_sheet(book, sheet, label.replace(/[\\/?*[\]:]/g, " ").trim().slice(0, 31) || "Data");
|
|
1799
2028
|
const written = XLSX.write(book, { type: "array", bookType: "xlsx", compression: true });
|
|
1800
|
-
return (0,
|
|
2029
|
+
return (0, import_content_transfer3.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "xlsx", plainText: (0, import_content_transfer3.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] });
|
|
1801
2030
|
}
|
|
1802
2031
|
async function buildArtifact(draft, format, label) {
|
|
1803
2032
|
if (!supportsBuiltIn(format, draft.payload)) throw new Error(`${LABEL[format]} is available for tabular content only.`);
|
|
1804
2033
|
if (format === "xlsx") return xlsxArtifact(draft, label);
|
|
1805
|
-
if (format === "html" && draft.payload.kind === "markdown") return (0,
|
|
2034
|
+
if (format === "html" && draft.payload.kind === "markdown") return (0, import_content_transfer3.serializeMarkdownRich)(draft, `${filenameFor(label)}.html`);
|
|
1806
2035
|
const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
|
|
1807
|
-
return (0,
|
|
2036
|
+
return (0, import_content_transfer3.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
1808
2037
|
}
|
|
1809
2038
|
function ContentTransferMenu(props) {
|
|
1810
|
-
const inherited =
|
|
2039
|
+
const inherited = React10.useContext(CapabilityContext);
|
|
1811
2040
|
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
1812
|
-
return /* @__PURE__ */ (0,
|
|
2041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
1813
2042
|
}
|
|
1814
|
-
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" }) {
|
|
1815
|
-
const triggerRef =
|
|
1816
|
-
const inherited =
|
|
1817
|
-
const nearestSurface =
|
|
2043
|
+
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" }) {
|
|
2044
|
+
const triggerRef = React10.useRef(null);
|
|
2045
|
+
const inherited = React10.useContext(CapabilityContext);
|
|
2046
|
+
const nearestSurface = React10.useContext(SurfaceContext);
|
|
1818
2047
|
const fence = useFence();
|
|
1819
|
-
const [menuCapture, setMenuCapture] =
|
|
1820
|
-
const [menuStatus, setMenuStatus] =
|
|
1821
|
-
const [workspaces, setWorkspaces] =
|
|
1822
|
-
const [workspaceKey, setWorkspaceKey] =
|
|
1823
|
-
const [workspaceOpen, setWorkspaceOpen] =
|
|
1824
|
-
const workspaceCaptures =
|
|
1825
|
-
const externalWorkspaceKeys =
|
|
1826
|
-
const [notice, setNotice] =
|
|
1827
|
-
const [receiptTarget, setReceiptTarget] =
|
|
1828
|
-
const [paletteOpen, setPaletteOpen] =
|
|
1829
|
-
const [mode, setMode] =
|
|
1830
|
-
const scopes =
|
|
1831
|
-
const
|
|
2048
|
+
const [menuCapture, setMenuCapture] = React10.useState(null);
|
|
2049
|
+
const [menuStatus, setMenuStatus] = React10.useState("idle");
|
|
2050
|
+
const [workspaces, setWorkspaces] = React10.useState({});
|
|
2051
|
+
const [workspaceKey, setWorkspaceKey] = React10.useState(null);
|
|
2052
|
+
const [workspaceOpen, setWorkspaceOpen] = React10.useState(false);
|
|
2053
|
+
const workspaceCaptures = React10.useRef(/* @__PURE__ */ new Map());
|
|
2054
|
+
const externalWorkspaceKeys = React10.useRef(/* @__PURE__ */ new Set());
|
|
2055
|
+
const [notice, setNotice] = React10.useState(null);
|
|
2056
|
+
const [receiptTarget, setReceiptTarget] = React10.useState();
|
|
2057
|
+
const [paletteOpen, setPaletteOpen] = React10.useState(false);
|
|
2058
|
+
const [mode, setMode] = React10.useState("copy");
|
|
2059
|
+
const scopes = React10.useMemo(() => table?.availableScopes ?? ["target"], [table]);
|
|
2060
|
+
const [requestedScope, setRequestedScope] = React10.useState(table?.initialScope ?? "target");
|
|
2061
|
+
const initialScope = scopes.includes(requestedScope) ? requestedScope : table?.initialScope ?? "target";
|
|
1832
2062
|
if (!scopes.includes(initialScope)) throw new Error("Alchemy initialScope must be included in availableScopes.");
|
|
1833
2063
|
const primary = surface ?? source ?? nearestSurface;
|
|
1834
2064
|
const sourceLabel = label ?? (surface?.surfaceName ?? (source && "label" in source ? source.label : nearestSurface?.surfaceName) ?? "content");
|
|
1835
|
-
const
|
|
2065
|
+
const primaryWorkspaceBase = `primary:${materialIdentity(primary)}`;
|
|
2066
|
+
const primaryWorkspaceKey = `${primaryWorkspaceBase}:${initialScope}`;
|
|
1836
2067
|
const nearestWorkspaceKey = source && !surface && nearestSurface ? `surface:${materialIdentity(nearestSurface)}` : null;
|
|
1837
|
-
const variantWorkspaceKeys =
|
|
1838
|
-
const transport = local?.transport ?? inherited.transport ?? (0,
|
|
2068
|
+
const variantWorkspaceKeys = React10.useMemo(() => new Map(variants.map((variant) => [variant.id, `variant:${variant.id}:${materialIdentity(variant.source)}`])), [variants]);
|
|
2069
|
+
const transport = local?.transport ?? inherited.transport ?? (0, import_content_transfer3.createBrowserTransport)();
|
|
1839
2070
|
const ai = local?.ai ?? inherited.ai;
|
|
1840
|
-
const
|
|
1841
|
-
const
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
const
|
|
2071
|
+
const referencePort = local?.reference ?? inherited.reference;
|
|
2072
|
+
const { email: emailPort, review: emailReview } = useReviewedTransferEmail(local?.email ?? inherited.email);
|
|
2073
|
+
const providerPreferences = React10.useMemo(() => (0, import_content_transfer3.resolveTransferPreferences)(inherited.preferences, local?.preferences), [inherited.preferences, local?.preferences]);
|
|
2074
|
+
const adapters = React10.useMemo(() => (0, import_content_transfer3.resolveTransferRegistry)(BUILT_INS, inherited.formats ?? [], local?.formats ?? []).filter((x) => "build" in x), [inherited.formats, local?.formats]);
|
|
2075
|
+
const emailJsonFormat = adapters.find((adapter) => adapter.id === "table-data");
|
|
2076
|
+
const emailActions = React10.useMemo(() => emailPort ? createTransferEmailActions(emailPort, emailJsonFormat ? { jsonFormat: emailJsonFormat } : {}) : [], [emailPort, emailJsonFormat]);
|
|
2077
|
+
const registeredActions = React10.useMemo(() => (0, import_content_transfer3.resolveTransferRegistry)(emailActions, inherited.actions ?? [], local?.actions ?? [], actions), [actions, emailActions, inherited.actions, local?.actions]);
|
|
2078
|
+
React10.useMemo(() => (0, import_content_transfer3.resolveTransferRegistry)(variants), [variants]);
|
|
2079
|
+
const report = React10.useCallback((result) => {
|
|
1845
2080
|
inherited.onOutcome?.(result);
|
|
1846
2081
|
local?.onOutcome?.(result);
|
|
1847
2082
|
setNotice(outcomeMessage(result));
|
|
1848
2083
|
setReceiptTarget("target" in result ? result.target : void 0);
|
|
1849
2084
|
}, [inherited, local]);
|
|
1850
|
-
|
|
1851
|
-
const valid = /* @__PURE__ */ new Set([
|
|
2085
|
+
React10.useEffect(() => {
|
|
2086
|
+
const valid = /* @__PURE__ */ new Set([...scopes.map((scope) => `${primaryWorkspaceBase}:${scope}`), ...nearestWorkspaceKey ? [nearestWorkspaceKey] : [], ...variantWorkspaceKeys.values(), ...externalWorkspaceKeys.current]);
|
|
1852
2087
|
setWorkspaces((current) => Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))));
|
|
1853
2088
|
for (const key of workspaceCaptures.current.keys()) if (!valid.has(key)) workspaceCaptures.current.delete(key);
|
|
1854
2089
|
if (workspaceKey && !valid.has(workspaceKey)) {
|
|
1855
2090
|
setWorkspaceKey(null);
|
|
1856
2091
|
setWorkspaceOpen(false);
|
|
1857
2092
|
}
|
|
1858
|
-
}, [nearestWorkspaceKey,
|
|
1859
|
-
const captureOne =
|
|
2093
|
+
}, [nearestWorkspaceKey, primaryWorkspaceBase, scopes, variantWorkspaceKeys, workspaceKey]);
|
|
2094
|
+
const captureOne = React10.useCallback(async (material, scope, signal, applyMenuProjection = false, collectPages = true) => {
|
|
1860
2095
|
if (!material) throw new Error("Alchemy needs a source or a mounted transfer surface.");
|
|
1861
2096
|
let sourceMaterial;
|
|
1862
2097
|
if ("instanceId" in material) {
|
|
@@ -1864,7 +2099,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1864
2099
|
const captured = await material.capture(signal);
|
|
1865
2100
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
1866
2101
|
} else if ("kind" in material) {
|
|
1867
|
-
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0,
|
|
2102
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => (0, import_content_transfer3.directSource)(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
1868
2103
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
1869
2104
|
sourceMaterial = {
|
|
1870
2105
|
id: material.id,
|
|
@@ -1882,27 +2117,27 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1882
2117
|
sourceMaterial = material;
|
|
1883
2118
|
}
|
|
1884
2119
|
const raw = await sourceMaterial.capture({ scope, signal });
|
|
1885
|
-
const constrained = (0,
|
|
1886
|
-
const result = await (0,
|
|
2120
|
+
const constrained = (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, raw.snapshot.limits);
|
|
2121
|
+
const result = await (0, import_content_transfer3.capture)({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
1887
2122
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
1888
2123
|
if (!result.allMatching) throw new Error("This source cannot provide a stable all-matching export.");
|
|
1889
|
-
const collected = await (0,
|
|
2124
|
+
const collected = await (0, import_content_transfer3.collectAllMatching)(result.allMatching, signal);
|
|
1890
2125
|
if (result.snapshot.payload.kind !== "rows") throw new Error("All-matching export requires tabular content.");
|
|
1891
|
-
return { snapshot: (0,
|
|
2126
|
+
return { snapshot: (0, import_content_transfer3.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 } : {} };
|
|
1892
2127
|
}, [preferences, projection, providerPreferences, sections, sourceLabel]);
|
|
1893
|
-
const capturePrimary =
|
|
2128
|
+
const capturePrimary = React10.useCallback((scope, signal) => captureOne(primary, scope, signal, true), [captureOne, primary]);
|
|
1894
2129
|
workspaceCaptures.current.set(primaryWorkspaceKey, capturePrimary);
|
|
1895
2130
|
if (nearestWorkspaceKey && nearestSurface) workspaceCaptures.current.set(nearestWorkspaceKey, (scope, signal) => captureOne(nearestSurface, scope, signal, true));
|
|
1896
2131
|
for (const variant of variants) {
|
|
1897
2132
|
const key = variantWorkspaceKeys.get(variant.id);
|
|
1898
2133
|
workspaceCaptures.current.set(key, (scope, signal) => captureOne(variant.source, scope, signal, true));
|
|
1899
2134
|
}
|
|
1900
|
-
const preflight =
|
|
2135
|
+
const preflight = React10.useCallback(async (scope = initialScope) => {
|
|
1901
2136
|
const { controller, id } = fence.begin();
|
|
1902
2137
|
setMenuCapture(null);
|
|
1903
2138
|
setMenuStatus("loading");
|
|
1904
2139
|
try {
|
|
1905
|
-
const result = await captureOne(primary,
|
|
2140
|
+
const result = await captureOne(primary, scope, controller.signal, true, false);
|
|
1906
2141
|
if (fence.valid(id, controller)) {
|
|
1907
2142
|
setMenuCapture(result);
|
|
1908
2143
|
setMenuStatus("idle");
|
|
@@ -1916,7 +2151,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1916
2151
|
fence.finish(controller);
|
|
1917
2152
|
}
|
|
1918
2153
|
}, [captureOne, fence, initialScope, primary]);
|
|
1919
|
-
const transfer =
|
|
2154
|
+
const transfer = React10.useCallback(async (format, download, alternate) => {
|
|
1920
2155
|
const { controller, id } = fence.begin();
|
|
1921
2156
|
try {
|
|
1922
2157
|
const explicit = alternate?.source ?? (typeof format === "string" && format !== "xlsx" ? formatSources?.[format] : void 0);
|
|
@@ -1926,8 +2161,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1926
2161
|
const reason = result.snapshot.coverage.reason ?? `${result.snapshot.omissions.length} omission${result.snapshot.omissions.length === 1 ? "" : "s"}`;
|
|
1927
2162
|
throw new Error(`Quick transfer is partial (${reason}). Open Prepare for AI to review it before delivery.`);
|
|
1928
2163
|
}
|
|
1929
|
-
const resolved = (0,
|
|
1930
|
-
const draft = (0,
|
|
2164
|
+
const resolved = (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, result.snapshot.limits);
|
|
2165
|
+
const draft = (0, import_content_transfer3.applyTransferLimits)((0, import_content_transfer3.createDraft)(result.snapshot), resolved.limits);
|
|
1931
2166
|
const revision = draft.revision;
|
|
1932
2167
|
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.");
|
|
1933
2168
|
const artifact = typeof format === "string" ? await buildArtifact(draft, format, result.snapshot.label) : await format.build(draft, controller.signal);
|
|
@@ -1941,12 +2176,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1941
2176
|
fence.finish(controller);
|
|
1942
2177
|
}
|
|
1943
2178
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
1944
|
-
const openWorkspace =
|
|
2179
|
+
const openWorkspace = React10.useCallback(
|
|
1945
2180
|
async (key = primaryWorkspaceKey, variant) => {
|
|
1946
2181
|
const variantMaterial = variant && "kind" in variant.source ? {
|
|
1947
2182
|
id: `variant:${key}`,
|
|
1948
2183
|
label: variant.label,
|
|
1949
|
-
capture: async () => (0,
|
|
2184
|
+
capture: async () => (0, import_content_transfer3.directSource)(variant.source, {
|
|
1950
2185
|
sourceId: `variant:${key}`,
|
|
1951
2186
|
label: variant.label
|
|
1952
2187
|
})
|
|
@@ -1957,15 +2192,16 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1957
2192
|
const { controller, id } = fence.begin();
|
|
1958
2193
|
if (existing) {
|
|
1959
2194
|
try {
|
|
1960
|
-
const
|
|
2195
|
+
const scopeChanged = existing.scope !== initialScope;
|
|
2196
|
+
const allMatching = initialScope === "all-matching";
|
|
1961
2197
|
const fresh = await captureWorkspace(
|
|
1962
|
-
|
|
2198
|
+
initialScope,
|
|
1963
2199
|
controller.signal,
|
|
1964
|
-
!allMatching
|
|
2200
|
+
scopeChanged || !allMatching
|
|
1965
2201
|
);
|
|
1966
2202
|
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
1967
2203
|
return;
|
|
1968
|
-
if (allMatching && (!
|
|
2204
|
+
if (allMatching && (!fresh.allMatching || !scopeChanged && !existing.allMatching))
|
|
1969
2205
|
throw new Error(
|
|
1970
2206
|
"This source can no longer provide an all-matching snapshot."
|
|
1971
2207
|
);
|
|
@@ -1975,7 +2211,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1975
2211
|
columns: value.columns,
|
|
1976
2212
|
limits: value.limits
|
|
1977
2213
|
};
|
|
1978
|
-
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
2214
|
+
const changed = scopeChanged || (allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot));
|
|
1979
2215
|
setWorkspaces((current) => {
|
|
1980
2216
|
const retained = current[key];
|
|
1981
2217
|
if (!retained) return current;
|
|
@@ -1984,7 +2220,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
1984
2220
|
[key]: {
|
|
1985
2221
|
...retained,
|
|
1986
2222
|
error: fresh.collectionError,
|
|
1987
|
-
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope:
|
|
2223
|
+
...allMatching && !scopeChanged ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: initialScope } } : { pending: void 0 }
|
|
1988
2224
|
}
|
|
1989
2225
|
};
|
|
1990
2226
|
});
|
|
@@ -2012,12 +2248,12 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
2012
2248
|
try {
|
|
2013
2249
|
const result = await captureWorkspace(initialScope, controller.signal);
|
|
2014
2250
|
if (!fence.valid(id, controller)) return;
|
|
2015
|
-
const resolved = (0,
|
|
2251
|
+
const resolved = (0, import_content_transfer3.resolveTransferPreferences)(
|
|
2016
2252
|
providerPreferences,
|
|
2017
2253
|
preferences,
|
|
2018
2254
|
result.snapshot.limits
|
|
2019
2255
|
);
|
|
2020
|
-
const original = (0,
|
|
2256
|
+
const original = (0, import_content_transfer3.createDraft)(result.snapshot);
|
|
2021
2257
|
const base = {
|
|
2022
2258
|
...result,
|
|
2023
2259
|
key,
|
|
@@ -2053,7 +2289,7 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
2053
2289
|
workspaces
|
|
2054
2290
|
]
|
|
2055
2291
|
);
|
|
2056
|
-
|
|
2292
|
+
React10.useImperativeHandle(controllerRef, () => ({
|
|
2057
2293
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
2058
2294
|
prepare: async (requestedSource, options) => {
|
|
2059
2295
|
const requestedLabel = options?.label ?? ("label" in requestedSource ? requestedSource.label : "content");
|
|
@@ -2062,13 +2298,13 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
2062
2298
|
await openWorkspace(requestedKey, { source: requestedSource, label: requestedLabel });
|
|
2063
2299
|
}
|
|
2064
2300
|
}), [openWorkspace]);
|
|
2065
|
-
const runAction =
|
|
2301
|
+
const runAction = React10.useCallback(async (action) => {
|
|
2066
2302
|
const { controller, id } = fence.begin();
|
|
2067
2303
|
try {
|
|
2068
2304
|
const actionSource = action.source;
|
|
2069
2305
|
const { snapshot } = actionSource ? await captureOne(actionSource, initialScope, controller.signal, true) : await capturePrimary(initialScope, controller.signal);
|
|
2070
|
-
const resolved = (0,
|
|
2071
|
-
const draft = (0,
|
|
2306
|
+
const resolved = (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, snapshot.limits);
|
|
2307
|
+
const draft = (0, import_content_transfer3.applyTransferLimits)((0, import_content_transfer3.createDraft)(snapshot), resolved.limits);
|
|
2072
2308
|
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.");
|
|
2073
2309
|
if (!action.supports(snapshot, draft)) throw new Error(`${action.label} is unavailable for this content.`);
|
|
2074
2310
|
const result = await action.run({ snapshot, draft, signal: controller.signal });
|
|
@@ -2079,13 +2315,38 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
2079
2315
|
fence.finish(controller);
|
|
2080
2316
|
}
|
|
2081
2317
|
}, [captureOne, capturePrimary, fence, initialScope, preferences, providerPreferences, report]);
|
|
2318
|
+
const copyReference = async (reference) => {
|
|
2319
|
+
const { controller, id } = fence.begin();
|
|
2320
|
+
closePalette();
|
|
2321
|
+
try {
|
|
2322
|
+
if (!referencePort?.supports(reference)) throw new Error("This reference is not registered or its identity is incomplete.");
|
|
2323
|
+
const text = await referencePort.build(reference);
|
|
2324
|
+
if (!text.trim()) throw new Error("The reference serializer returned no content.");
|
|
2325
|
+
const artifact = (0, import_content_transfer3.sealTransferArtifact)({ snapshotId: `reference:${reference.id}`, draftRevision: 0, format: "matrx-reference", plainText: text, omissions: [] });
|
|
2326
|
+
if (!fence.valid(id, controller)) return;
|
|
2327
|
+
const outcome = await transport.copy(artifact, controller.signal);
|
|
2328
|
+
if (fence.valid(id, controller)) report(outcome);
|
|
2329
|
+
} catch (error) {
|
|
2330
|
+
if (fence.valid(id, controller)) report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not copy reference"), retryable: true });
|
|
2331
|
+
} finally {
|
|
2332
|
+
fence.finish(controller);
|
|
2333
|
+
}
|
|
2334
|
+
};
|
|
2335
|
+
const openReference = async (action) => {
|
|
2336
|
+
closePalette();
|
|
2337
|
+
try {
|
|
2338
|
+
await action.run();
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
report({ status: "error", code: "reference-failed", message: errorMessage(error, "Could not open reference picker"), retryable: true });
|
|
2341
|
+
}
|
|
2342
|
+
};
|
|
2082
2343
|
if (!enabled) return null;
|
|
2083
2344
|
const payload = menuCapture?.snapshot.payload ?? (source && "kind" in source ? source : void 0);
|
|
2084
2345
|
const quickVariants = (section) => variants.filter((v) => v.copyLabel && (v.section ?? "ai") === section);
|
|
2085
2346
|
const visibleCopies = sourceFormats ? COPIES.filter((f) => Boolean(formatSources?.[f]) || !["csv", "tsv"].includes(f) || payload?.kind === "rows") : [];
|
|
2086
2347
|
const visibleDownloads = sourceFormats ? DOWNLOADS.filter((f) => f !== "xlsx" && Boolean(formatSources?.[f]) || !["csv", "tsv", "xlsx"].includes(f) || payload?.kind === "rows") : [];
|
|
2087
2348
|
const visibleAdapters = sourceFormats && menuCapture ? adapters.filter((a) => a.supports(menuCapture.snapshot.payload)) : [];
|
|
2088
|
-
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0,
|
|
2349
|
+
const visibleActions = menuCapture ? registeredActions.filter((a) => a.supports(menuCapture.snapshot, (0, import_content_transfer3.applyTransferLimits)((0, import_content_transfer3.createDraft)(menuCapture.snapshot), (0, import_content_transfer3.resolveTransferPreferences)(providerPreferences, preferences, menuCapture.snapshot.limits).limits))) : [];
|
|
2089
2350
|
const downloadActions = visibleActions.filter((action) => action.placement === "download");
|
|
2090
2351
|
const ordinaryActions = visibleActions.filter((action) => action.placement !== "download");
|
|
2091
2352
|
const preparedActions = registeredActions.filter((action) => action.prepared && !action.source);
|
|
@@ -2098,8 +2359,8 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
2098
2359
|
label: "AI context",
|
|
2099
2360
|
supports: () => true,
|
|
2100
2361
|
build: async (draft) => {
|
|
2101
|
-
const json = (0,
|
|
2102
|
-
return (0,
|
|
2362
|
+
const json = (0, import_content_transfer3.serialize)(draft, "json");
|
|
2363
|
+
return (0, import_content_transfer3.sealTransferArtifact)({ snapshotId: draft.snapshotId, draftRevision: draft.revision, format: "ai-context", plainText: (0, import_content_transfer3.buildAgentPayload)({ kind: "matrx_content", location: sourceLabel, description: "Captured content for an assistant", data: JSON.parse(json.plainText), attributes: { source: draft.sourceId } }), omissions: [...json.omissions] });
|
|
2103
2364
|
}
|
|
2104
2365
|
};
|
|
2105
2366
|
const closePalette = () => setPaletteOpen(false);
|
|
@@ -2107,106 +2368,123 @@ function ContentTransferMenuSession({ source, surface, label, projection, sectio
|
|
|
2107
2368
|
const presentation = options.action;
|
|
2108
2369
|
const Icon = presentation?.icon;
|
|
2109
2370
|
const fallbackLabel = options.file && !/^download\b/i.test(label2) ? `Download ${label2}` : label2;
|
|
2110
|
-
return /* @__PURE__ */ (0,
|
|
2371
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-tile", "aria-label": presentation?.ariaLabel ?? (presentation ? fallbackLabel : options.ariaLabel ?? `${resolvedMode === "copy" ? "Copy" : "Download"} ${label2}`), onClick: () => {
|
|
2111
2372
|
closePalette();
|
|
2112
2373
|
onClick();
|
|
2113
2374
|
}, children: [
|
|
2114
|
-
Icon ? /* @__PURE__ */ (0,
|
|
2115
|
-
/* @__PURE__ */ (0,
|
|
2375
|
+
Icon ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Icon, { className: "matrx-alchemy-menu-icon" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { ...!options.custom ? { format: id } : {}, ...options.ai ? { ai: true } : {}, ...options.file ? { file: true } : {} }),
|
|
2376
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
2116
2377
|
label2,
|
|
2117
|
-
presentation?.hint ? /* @__PURE__ */ (0,
|
|
2378
|
+
presentation?.hint ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: presentation.hint }) : null
|
|
2118
2379
|
] })
|
|
2119
2380
|
] }, id);
|
|
2120
2381
|
};
|
|
2121
|
-
return /* @__PURE__ */ (0,
|
|
2122
|
-
/* @__PURE__ */ (0,
|
|
2382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: cn("matrx-alchemy", className), onClick: stopPropagation ? (event) => event.stopPropagation() : void 0, children: [
|
|
2383
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Popover, { open: paletteOpen, onOpenChange: (open) => {
|
|
2123
2384
|
setPaletteOpen(open);
|
|
2124
2385
|
if (open) {
|
|
2125
2386
|
setMode("copy");
|
|
2126
2387
|
void preflight();
|
|
2127
2388
|
}
|
|
2128
2389
|
}, children: [
|
|
2129
|
-
/* @__PURE__ */ (0,
|
|
2130
|
-
/* @__PURE__ */ (0,
|
|
2131
|
-
menuStatus === "loading" ? /* @__PURE__ */ (0,
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2390
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverTrigger, { asChild: true, children: triggerVariant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsx)(AlchemyGlyph, { icon }) }) : triggerVariant === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TapTargetButton, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "glass", "data-alchemy-size": triggerSize, disabled }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TapTargetButtonTransparent, { ref: triggerRef, icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AlchemyGlyph, { icon }), tooltip: false, ariaLabel: `Copy, transform or export ${sourceLabel}`, "data-alchemy-trigger": "transparent", "data-alchemy-size": triggerSize, disabled }) }),
|
|
2391
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(PopoverContent, { align: "end", className: "matrx-alchemy-menu matrx-alchemy-palette", "aria-label": "Alchemy output options", onCloseAutoFocus: () => triggerRef.current?.focus(), children: [
|
|
2392
|
+
menuStatus === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-palette-status", children: "Inspecting content\u2026" }) : menuStatus !== "idle" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-error", children: menuStatus }) : null,
|
|
2393
|
+
table && scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "matrx-alchemy-scope", children: [
|
|
2394
|
+
"Content scope",
|
|
2395
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("select", { "aria-label": "Content scope", value: initialScope, onChange: (event) => {
|
|
2396
|
+
const next = scopes.find((scope) => scope === event.target.value);
|
|
2397
|
+
if (next) {
|
|
2398
|
+
setRequestedScope(next);
|
|
2399
|
+
void preflight(next);
|
|
2400
|
+
}
|
|
2401
|
+
}, children: scopes.map((scope) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: scope, children: table.scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
|
|
2402
|
+
] }) : null,
|
|
2403
|
+
copyAvailable || downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-output", children: [
|
|
2404
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { children: resolvedMode === "copy" ? "Copy as" : "Download as" }),
|
|
2405
|
+
copyAvailable && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-mode", "aria-label": "Output action", children: [
|
|
2406
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Copy mode", "aria-pressed": resolvedMode === "copy", onClick: () => setMode("copy"), children: "Copy" }),
|
|
2407
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Download mode", "aria-pressed": resolvedMode === "download", onClick: () => setMode("download"), children: "Download" })
|
|
2137
2408
|
] }) : null,
|
|
2138
|
-
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0,
|
|
2139
|
-
/* @__PURE__ */ (0,
|
|
2409
|
+
resolvedMode === "copy" && copyAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2410
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
2140
2411
|
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]}` })),
|
|
2141
2412
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, false), { custom: true }))
|
|
2142
2413
|
] }),
|
|
2143
|
-
quickVariants("copy").length ? /* @__PURE__ */ (0,
|
|
2414
|
+
quickVariants("copy").length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Quick copy", items: quickVariants("copy"), onRun: (variant) => {
|
|
2144
2415
|
closePalette();
|
|
2145
2416
|
void transfer("markdown", false, variant);
|
|
2146
2417
|
} }) : null
|
|
2147
2418
|
] }) : null,
|
|
2148
|
-
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0,
|
|
2419
|
+
resolvedMode === "download" && downloadAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-palette-grid", children: [
|
|
2149
2420
|
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]}` })),
|
|
2150
2421
|
visibleAdapters.map((adapter) => tile(adapter.id, adapter.label, () => void transfer(adapter, true), { custom: true })),
|
|
2151
2422
|
downloadActions.map((action) => tile(action.id, action.label, () => void runAction(action), { custom: true, action, file: true }))
|
|
2152
2423
|
] }) }) : null
|
|
2153
2424
|
] }) : null,
|
|
2154
|
-
prepareAvailable ? /* @__PURE__ */ (0,
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
2425
|
+
prepareAvailable ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2426
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Copy for AI", ai: true, glyphKind: "ai-copy", fallbackHint: "Copies immediately", extra: sourceFormats ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
2156
2427
|
closePalette();
|
|
2157
2428
|
void transfer(nativeAiFormat, false);
|
|
2158
2429
|
}, children: [
|
|
2159
|
-
/* @__PURE__ */ (0,
|
|
2160
|
-
/* @__PURE__ */ (0,
|
|
2430
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { kind: "ai-copy" }),
|
|
2431
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
2161
2432
|
"Copy with AI context",
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2433
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Content, source and capture details" })
|
|
2163
2434
|
] })
|
|
2164
2435
|
] }) : null, items: quickVariants("ai"), onRun: (variant) => {
|
|
2165
2436
|
closePalette();
|
|
2166
2437
|
void transfer("markdown", false, variant);
|
|
2167
2438
|
} }),
|
|
2168
|
-
/* @__PURE__ */ (0,
|
|
2439
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Edit and prepare", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": "Prepare for AI", onClick: () => {
|
|
2169
2440
|
closePalette();
|
|
2170
2441
|
void openWorkspace();
|
|
2171
2442
|
}, children: [
|
|
2172
|
-
/* @__PURE__ */ (0,
|
|
2173
|
-
/* @__PURE__ */ (0,
|
|
2443
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteGlyph, { kind: "sliders" }),
|
|
2444
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
2174
2445
|
"Prepare for AI",
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
2446
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { className: "matrx-alchemy-menu-hint", children: "Review and edit before copying" })
|
|
2176
2447
|
] })
|
|
2177
2448
|
] }) })
|
|
2178
2449
|
] }) : null,
|
|
2179
|
-
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0,
|
|
2180
|
-
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0,
|
|
2450
|
+
prepareAvailable && (nearestWorkspaceKey || variants.length) ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PaletteRows, { title: "Other sources", items: [], extra: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2451
|
+
nearestWorkspaceKey && nearestSurface ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => {
|
|
2181
2452
|
closePalette();
|
|
2182
2453
|
void openWorkspace(nearestWorkspaceKey, { source: nearestSurface, label: nearestSurface.surfaceName });
|
|
2183
|
-
}, children: /* @__PURE__ */ (0,
|
|
2184
|
-
variants.map((variant) => /* @__PURE__ */ (0,
|
|
2454
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: "Prepare this surface" }) }) : null,
|
|
2455
|
+
variants.map((variant) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": variant.ariaLabel, onClick: () => {
|
|
2185
2456
|
closePalette();
|
|
2186
2457
|
void openWorkspace(variantWorkspaceKeys.get(variant.id), variant);
|
|
2187
|
-
}, children: /* @__PURE__ */ (0,
|
|
2458
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MenuPresentation, { ...variant, label: `Prepare ${variant.label}` }) }, variant.id))
|
|
2188
2459
|
] }) }) : null,
|
|
2189
|
-
|
|
2460
|
+
references.length || referenceActions.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-palette-section", children: [
|
|
2461
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { children: "Live references" }),
|
|
2462
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "matrx-alchemy-menu-hint", children: "Pointers to saved data, independent of filters and edits." }),
|
|
2463
|
+
references.map((reference) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void copyReference(reference), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: reference.label }) }, reference.id)),
|
|
2464
|
+
referenceActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", onClick: () => void openReference(action), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: action.label }) }, action.id))
|
|
2465
|
+
] }) : null,
|
|
2466
|
+
["save", "chat", "email", "other"].map((group) => {
|
|
2190
2467
|
const entries = ordinaryActions.filter((action) => (action.group ?? "other") === group);
|
|
2191
|
-
return entries.length ? /* @__PURE__ */ (0,
|
|
2192
|
-
/* @__PURE__ */ (0,
|
|
2193
|
-
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : "Actions",
|
|
2194
|
-
/* @__PURE__ */ (0,
|
|
2468
|
+
return entries.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-palette-destinations", children: [
|
|
2469
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2470
|
+
group === "save" ? "Save to Matrx" : group === "chat" ? "Continue with AI" : group === "email" ? "Email to me" : "Actions",
|
|
2471
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: entries.length })
|
|
2195
2472
|
] }),
|
|
2196
|
-
/* @__PURE__ */ (0,
|
|
2473
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { children: entries.map((action) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "matrx-alchemy-palette-row", "aria-label": action.ariaLabel, onClick: () => {
|
|
2197
2474
|
closePalette();
|
|
2198
2475
|
void runAction(action);
|
|
2199
|
-
}, children: /* @__PURE__ */ (0,
|
|
2476
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DestinationPresentation, { action }) }, action.id)) })
|
|
2200
2477
|
] }, group) : null;
|
|
2201
2478
|
})
|
|
2202
2479
|
] })
|
|
2203
2480
|
] }),
|
|
2204
|
-
notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0,
|
|
2205
|
-
/* @__PURE__ */ (0,
|
|
2206
|
-
/* @__PURE__ */ (0,
|
|
2207
|
-
/* @__PURE__ */ (0,
|
|
2481
|
+
notice && triggerRef.current ? (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-feedback", children: [
|
|
2482
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { role: "status", children: notice }),
|
|
2483
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ReceiptLink, { target: receiptTarget }),
|
|
2484
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Dismiss Alchemy feedback", onClick: () => setNotice(null), children: "\xD7" })
|
|
2208
2485
|
] }), triggerRef.current.ownerDocument.body) : null,
|
|
2209
|
-
Object.values(workspaces).map((saved) => /* @__PURE__ */ (0,
|
|
2486
|
+
Object.values(workspaces).map((saved) => /* @__PURE__ */ (0, import_jsx_runtime11.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)),
|
|
2487
|
+
emailReview
|
|
2210
2488
|
] });
|
|
2211
2489
|
}
|
|
2212
2490
|
function initialControls(state) {
|
|
@@ -2234,9 +2512,9 @@ function presetLimits(preset, controls, preferences) {
|
|
|
2234
2512
|
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) };
|
|
2235
2513
|
}
|
|
2236
2514
|
function rebuild(state, controls) {
|
|
2237
|
-
let draft = (0,
|
|
2238
|
-
if (state.snapshot.sections.length) draft = (0,
|
|
2239
|
-
if (draft.payload.kind === "rows") draft = (0,
|
|
2515
|
+
let draft = (0, import_content_transfer3.resetDraft)(state.snapshot);
|
|
2516
|
+
if (state.snapshot.sections.length) draft = (0, import_content_transfer3.applySectionSelection)(draft, state.snapshot, controls.sections);
|
|
2517
|
+
if (draft.payload.kind === "rows") draft = (0, import_content_transfer3.transformRows)(draft, {
|
|
2240
2518
|
search: controls.search,
|
|
2241
2519
|
filters: controls.filters,
|
|
2242
2520
|
...controls.sort ? { sort: { column: controls.sort, direction: controls.direction } } : {},
|
|
@@ -2247,45 +2525,45 @@ function rebuild(state, controls) {
|
|
|
2247
2525
|
});
|
|
2248
2526
|
const limits = presetLimits(controls.preset, controls, state.preferences);
|
|
2249
2527
|
if (draft.payload.kind === "json" || draft.payload.kind === "registered") {
|
|
2250
|
-
draft = (0,
|
|
2528
|
+
draft = (0, import_content_transfer3.reduceJson)(draft, { maxDepth: limits.maxDepth, maxStringChars: limits.maxStringChars, maxArrayItems: limits.maxArrayItems ?? null });
|
|
2251
2529
|
}
|
|
2252
|
-
return (0,
|
|
2530
|
+
return (0, import_content_transfer3.applyTransferLimits)(draft, limits);
|
|
2253
2531
|
}
|
|
2254
2532
|
function isBuiltInFormat(format) {
|
|
2255
2533
|
return format in LABEL;
|
|
2256
2534
|
}
|
|
2257
2535
|
function preview(draft, format) {
|
|
2258
2536
|
const resolved = isBuiltInFormat(format) ? format : "plain";
|
|
2259
|
-
return (0,
|
|
2537
|
+
return (0, import_content_transfer3.serialize)(draft, resolved === "xlsx" ? "tsv" : resolved, { spreadsheetSafe: resolved === "csv" || resolved === "tsv" || resolved === "xlsx" }).plainText;
|
|
2260
2538
|
}
|
|
2261
|
-
function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
2539
|
+
function PreparationWorkspace({ restoreFocus, open, state, scopes, scopeLabels, onClose, onChange, transport, ai, adapters, actions, onOutcome, captureScope }) {
|
|
2262
2540
|
const fence = useFence();
|
|
2263
|
-
const latest =
|
|
2541
|
+
const latest = React10.useRef(state);
|
|
2264
2542
|
latest.current = state;
|
|
2265
|
-
const aiSession =
|
|
2543
|
+
const aiSession = React10.useRef(void 0);
|
|
2266
2544
|
if (!aiSession.current && ai) aiSession.current = ai.fork?.() ?? ai;
|
|
2267
|
-
const [controls, setControls] =
|
|
2268
|
-
const [controlsHistory, setControlsHistory] =
|
|
2269
|
-
const [pendingControls, setPendingControls] =
|
|
2545
|
+
const [controls, setControls] = React10.useState(() => initialControls(state));
|
|
2546
|
+
const [controlsHistory, setControlsHistory] = React10.useState([]);
|
|
2547
|
+
const [pendingControls, setPendingControls] = React10.useState(null);
|
|
2270
2548
|
const requestedFormat = state.preferences.initialFormat;
|
|
2271
|
-
const [format, setFormat] =
|
|
2272
|
-
const [buffer, setBuffer] =
|
|
2273
|
-
const [bufferError, setBufferError] =
|
|
2274
|
-
const [formatError, setFormatError] =
|
|
2275
|
-
const [preparedArtifact, setPreparedArtifact] =
|
|
2276
|
-
const [instruction, setInstruction] =
|
|
2277
|
-
const [busy, setBusy] =
|
|
2278
|
-
const [aiFailed, setAiFailed] =
|
|
2279
|
-
|
|
2549
|
+
const [format, setFormat] = React10.useState(() => isBuiltInFormat(requestedFormat) ? supportsBuiltIn(requestedFormat, state.draft.payload) ? requestedFormat : "plain" : adapters.some((adapter) => adapter.id === requestedFormat && adapter.supports(state.draft.payload)) ? requestedFormat : "plain");
|
|
2550
|
+
const [buffer, setBuffer] = React10.useState(() => isBuiltInFormat(format) ? preview(state.draft, format) : "Preparing format preview\u2026");
|
|
2551
|
+
const [bufferError, setBufferError] = React10.useState(null);
|
|
2552
|
+
const [formatError, setFormatError] = React10.useState(null);
|
|
2553
|
+
const [preparedArtifact, setPreparedArtifact] = React10.useState(null);
|
|
2554
|
+
const [instruction, setInstruction] = React10.useState("");
|
|
2555
|
+
const [busy, setBusy] = React10.useState(null);
|
|
2556
|
+
const [aiFailed, setAiFailed] = React10.useState(false);
|
|
2557
|
+
React10.useEffect(() => {
|
|
2280
2558
|
setAiFailed(false);
|
|
2281
2559
|
}, [state.snapshot.id, state.draft.revision]);
|
|
2282
|
-
const handingOff =
|
|
2283
|
-
|
|
2560
|
+
const handingOff = React10.useRef(false);
|
|
2561
|
+
React10.useEffect(() => {
|
|
2284
2562
|
if (open) handingOff.current = false;
|
|
2285
2563
|
}, [open]);
|
|
2286
|
-
const activeAi =
|
|
2287
|
-
const activeCapture =
|
|
2288
|
-
|
|
2564
|
+
const activeAi = React10.useRef(null);
|
|
2565
|
+
const activeCapture = React10.useRef(null);
|
|
2566
|
+
React10.useEffect(() => {
|
|
2289
2567
|
if (bufferError) return;
|
|
2290
2568
|
const adapter = adapters.find((candidate) => candidate.id === format);
|
|
2291
2569
|
const controller = new AbortController();
|
|
@@ -2305,7 +2583,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2305
2583
|
});
|
|
2306
2584
|
return () => controller.abort();
|
|
2307
2585
|
}, [adapters, bufferError, format, state.draft, state.snapshot.id]);
|
|
2308
|
-
const close =
|
|
2586
|
+
const close = React10.useCallback(() => {
|
|
2309
2587
|
activeAi.current?.abort();
|
|
2310
2588
|
activeCapture.current?.abort();
|
|
2311
2589
|
activeAi.current = null;
|
|
@@ -2341,7 +2619,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2341
2619
|
const value = JSON.parse(text);
|
|
2342
2620
|
const next = payload.kind === "json" ? { kind: "json", value } : { kind: "registered", format: payload.format, value };
|
|
2343
2621
|
setBufferError(null);
|
|
2344
|
-
onChange({ ...state, draft: (0,
|
|
2622
|
+
onChange({ ...state, draft: (0, import_content_transfer3.editDraft)(state.draft, next), error: void 0 });
|
|
2345
2623
|
} catch {
|
|
2346
2624
|
setBufferError("JSON is incomplete or invalid. Fix it before copying or downloading.");
|
|
2347
2625
|
}
|
|
@@ -2350,7 +2628,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2350
2628
|
setBufferError(null);
|
|
2351
2629
|
const kind = payload.kind === "markdown" || format === "markdown" ? "markdown" : "text";
|
|
2352
2630
|
if (payload.kind === "rows" || !isBuiltInFormat(format)) setFormat("plain");
|
|
2353
|
-
onChange({ ...state, draft: (0,
|
|
2631
|
+
onChange({ ...state, draft: (0, import_content_transfer3.editDraft)(state.draft, { kind, text }), error: void 0 });
|
|
2354
2632
|
};
|
|
2355
2633
|
const requestCapture = async (scope) => {
|
|
2356
2634
|
activeCapture.current?.abort();
|
|
@@ -2377,8 +2655,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2377
2655
|
return;
|
|
2378
2656
|
}
|
|
2379
2657
|
const pending = state.pending;
|
|
2380
|
-
const preferences = (0,
|
|
2381
|
-
const base = { ...pending, key: state.key, original: (0,
|
|
2658
|
+
const preferences = (0, import_content_transfer3.resolveTransferPreferences)({}, state.preferences, pending.snapshot.limits);
|
|
2659
|
+
const base = { ...pending, key: state.key, original: (0, import_content_transfer3.createDraft)(pending.snapshot), draft: (0, import_content_transfer3.createDraft)(pending.snapshot), scope: pending.scope, preferences, ...pending.collectionError ? { error: pending.collectionError } : {} };
|
|
2382
2660
|
const nextControls = initialControls(base);
|
|
2383
2661
|
setControls(nextControls);
|
|
2384
2662
|
setControlsHistory([]);
|
|
@@ -2401,7 +2679,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2401
2679
|
const current = latest.current;
|
|
2402
2680
|
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;
|
|
2403
2681
|
try {
|
|
2404
|
-
(0,
|
|
2682
|
+
(0, import_content_transfer3.serialize)(next, "plain");
|
|
2405
2683
|
} catch {
|
|
2406
2684
|
onChange({ ...current, error: "AI returned an invalid transfer draft." });
|
|
2407
2685
|
setAiFailed(true);
|
|
@@ -2434,8 +2712,8 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2434
2712
|
if (fence.valid(id, controller)) setBusy(null);
|
|
2435
2713
|
}
|
|
2436
2714
|
};
|
|
2437
|
-
const [deliveryNotice, setDeliveryNotice] =
|
|
2438
|
-
|
|
2715
|
+
const [deliveryNotice, setDeliveryNotice] = React10.useState(null);
|
|
2716
|
+
React10.useEffect(() => {
|
|
2439
2717
|
setDeliveryNotice(null);
|
|
2440
2718
|
}, [state.draft.revision]);
|
|
2441
2719
|
const reportDelivery = (outcome) => {
|
|
@@ -2486,49 +2764,49 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2486
2764
|
const workspaceAdapters = adapters.filter((adapter) => adapter.supports(state.draft.payload));
|
|
2487
2765
|
const displayedOmissions = preparedArtifact?.omissions ?? state.draft.omissions;
|
|
2488
2766
|
const limitText = Object.entries(state.preferences.limits).filter(([, value]) => value != null).map(([key, value]) => `${key.replace(/^max/, "max ")} ${(0, import_format2.formatCount)(Number(value))}`).join(" \xB7 ");
|
|
2489
|
-
return /* @__PURE__ */ (0,
|
|
2767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Dialog, { open, onOpenChange: (next) => {
|
|
2490
2768
|
if (!next) close();
|
|
2491
|
-
}, children: /* @__PURE__ */ (0,
|
|
2769
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogContent, { onCloseAutoFocus: (event) => {
|
|
2492
2770
|
event.preventDefault();
|
|
2493
2771
|
if (!handingOff.current) restoreFocus();
|
|
2494
2772
|
}, className: "matrx-alchemy-workspace max-w-5xl", "aria-busy": busy !== null, children: [
|
|
2495
|
-
/* @__PURE__ */ (0,
|
|
2496
|
-
/* @__PURE__ */ (0,
|
|
2773
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogHeader, { children: [
|
|
2774
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogTitle, { children: [
|
|
2497
2775
|
"Prepare ",
|
|
2498
2776
|
state.snapshot.label
|
|
2499
2777
|
] }),
|
|
2500
|
-
/* @__PURE__ */ (0,
|
|
2778
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogDescription, { children: [
|
|
2501
2779
|
state.snapshot.unsavedChanges ? "Includes your unsaved changes. " : "",
|
|
2502
2780
|
"Review and edit this copy. Your original stays unchanged."
|
|
2503
2781
|
] })
|
|
2504
2782
|
] }),
|
|
2505
|
-
/* @__PURE__ */ (0,
|
|
2506
|
-
/* @__PURE__ */ (0,
|
|
2507
|
-
/* @__PURE__ */ (0,
|
|
2508
|
-
/* @__PURE__ */ (0,
|
|
2509
|
-
scopes.length > 1 ? /* @__PURE__ */ (0,
|
|
2783
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-workspace-body", children: [
|
|
2784
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-workspace-grid", children: [
|
|
2785
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("section", { className: "matrx-alchemy-main", children: [
|
|
2786
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2787
|
+
scopes.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2510
2788
|
"Scope",
|
|
2511
|
-
/* @__PURE__ */ (0,
|
|
2789
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsx)("option", { value: scope, children: scopeLabels?.[scope] ?? SCOPE_LABEL[scope] }, scope)) })
|
|
2512
2790
|
] }) : null,
|
|
2513
|
-
/* @__PURE__ */ (0,
|
|
2791
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2514
2792
|
"Detail",
|
|
2515
|
-
/* @__PURE__ */ (0,
|
|
2516
|
-
/* @__PURE__ */ (0,
|
|
2517
|
-
/* @__PURE__ */ (0,
|
|
2518
|
-
/* @__PURE__ */ (0,
|
|
2519
|
-
/* @__PURE__ */ (0,
|
|
2793
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { "aria-label": "Detail preset", value: controls.preset, onChange: (e) => changeControls({ ...controls, preset: e.target.value }), children: [
|
|
2794
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "full", children: "Full" }),
|
|
2795
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "compact", children: "Compact" }),
|
|
2796
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "brief", children: "Brief" }),
|
|
2797
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "custom", children: "Custom" })
|
|
2520
2798
|
] })
|
|
2521
2799
|
] }),
|
|
2522
|
-
/* @__PURE__ */ (0,
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: !state.draft.history?.length && !controlsHistory.length || busy !== null, onClick: () => {
|
|
2523
2801
|
setBufferError(null);
|
|
2524
2802
|
if (controlsHistory.length) {
|
|
2525
2803
|
const next = controlsHistory[controlsHistory.length - 1];
|
|
2526
2804
|
setControls(next);
|
|
2527
2805
|
setControlsHistory((history) => history.slice(0, -1));
|
|
2528
2806
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
2529
|
-
} else onChange({ ...state, draft: (0,
|
|
2807
|
+
} else onChange({ ...state, draft: (0, import_content_transfer3.undoDraft)(state.draft), error: void 0 });
|
|
2530
2808
|
}, children: "Undo" }),
|
|
2531
|
-
/* @__PURE__ */ (0,
|
|
2809
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => {
|
|
2532
2810
|
const next = initialControls(state);
|
|
2533
2811
|
setControls(next);
|
|
2534
2812
|
setControlsHistory([]);
|
|
@@ -2536,64 +2814,64 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2536
2814
|
setBufferError(null);
|
|
2537
2815
|
onChange({ ...state, draft: rebuild(state, next), error: void 0 });
|
|
2538
2816
|
}, children: "Reset" }),
|
|
2539
|
-
/* @__PURE__ */ (0,
|
|
2817
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", size: "sm", variant: "outline", className: "matrx-alchemy-workspace-secondary", disabled: busy !== null, onClick: () => void requestCapture(state.scope), children: "Refresh source" })
|
|
2540
2818
|
] }),
|
|
2541
|
-
controls.preset === "custom" ? /* @__PURE__ */ (0,
|
|
2542
|
-
/* @__PURE__ */ (0,
|
|
2543
|
-
[["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,
|
|
2819
|
+
controls.preset === "custom" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("fieldset", { className: "matrx-alchemy-options", children: [
|
|
2820
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("legend", { children: state.draft.payload.kind === "json" || state.draft.payload.kind === "registered" ? "JSON limits" : "Content limits" }),
|
|
2821
|
+
[["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_runtime11.jsxs)("label", { children: [
|
|
2544
2822
|
text,
|
|
2545
|
-
/* @__PURE__ */ (0,
|
|
2823
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", min: "0", value: controls[key] ?? "", onChange: (e) => changeControls({ ...controls, [key]: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
2546
2824
|
] }, key))
|
|
2547
2825
|
] }) : null,
|
|
2548
|
-
rows ? /* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2826
|
+
rows ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-data-controls", children: [
|
|
2827
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2550
2828
|
"Data selection \xB7 ",
|
|
2551
2829
|
controls.visibleColumns.length,
|
|
2552
2830
|
" columns",
|
|
2553
2831
|
controls.search || controls.sort || controls.top != null || controls.selectedOnly || Object.values(controls.filters).some(Boolean) ? " \xB7 customized" : " \xB7 all rows"
|
|
2554
2832
|
] }),
|
|
2555
|
-
/* @__PURE__ */ (0,
|
|
2833
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "matrx-alchemy-data-controls-body", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(RowControls, { rows, controls, change: changeControls }) })
|
|
2556
2834
|
] }) : null,
|
|
2557
|
-
state.snapshot.sections.length ? /* @__PURE__ */ (0,
|
|
2558
|
-
/* @__PURE__ */ (0,
|
|
2835
|
+
state.snapshot.sections.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2836
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2559
2837
|
"Sections \xB7 ",
|
|
2560
2838
|
controls.sections.length,
|
|
2561
2839
|
" included"
|
|
2562
2840
|
] }),
|
|
2563
|
-
/* @__PURE__ */ (0,
|
|
2564
|
-
/* @__PURE__ */ (0,
|
|
2841
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("fieldset", { "aria-label": "Included sections", children: state.snapshot.sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2842
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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) }) }),
|
|
2565
2843
|
" ",
|
|
2566
2844
|
section.label
|
|
2567
2845
|
] }, section.id)) })
|
|
2568
2846
|
] }) : null,
|
|
2569
|
-
/* @__PURE__ */ (0,
|
|
2847
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { className: "matrx-alchemy-preview-label", children: [
|
|
2570
2848
|
"Output format",
|
|
2571
|
-
/* @__PURE__ */ (0,
|
|
2572
|
-
formats.map((f) => /* @__PURE__ */ (0,
|
|
2573
|
-
state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0,
|
|
2574
|
-
workspaceAdapters.map((adapter) => /* @__PURE__ */ (0,
|
|
2849
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { "aria-label": "Output format", value: format, onChange: (e) => setFormat(e.target.value), children: [
|
|
2850
|
+
formats.map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: f, children: LABEL[f] }, f)),
|
|
2851
|
+
state.draft.payload.kind === "rows" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "xlsx", children: "Excel workbook" }) : null,
|
|
2852
|
+
workspaceAdapters.map((adapter) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: adapter.id, children: adapter.label }, adapter.id))
|
|
2575
2853
|
] })
|
|
2576
2854
|
] }),
|
|
2577
|
-
/* @__PURE__ */ (0,
|
|
2578
|
-
/* @__PURE__ */ (0,
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2855
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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) }),
|
|
2856
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-coverage", children: [
|
|
2857
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
2580
2858
|
state.snapshot.coverage.included.toLocaleString(),
|
|
2581
2859
|
" included",
|
|
2582
2860
|
state.snapshot.coverage.total == null ? "" : ` of ${state.snapshot.coverage.total.toLocaleString()}`,
|
|
2583
2861
|
" \xB7 ",
|
|
2584
2862
|
state.snapshot.coverage.status
|
|
2585
2863
|
] }),
|
|
2586
|
-
state.snapshot.coverage.reason ? /* @__PURE__ */ (0,
|
|
2587
|
-
limitText ? /* @__PURE__ */ (0,
|
|
2864
|
+
state.snapshot.coverage.reason ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: state.snapshot.coverage.reason }) : null,
|
|
2865
|
+
limitText ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
|
|
2588
2866
|
"Limits: ",
|
|
2589
2867
|
limitText
|
|
2590
2868
|
] }) : null,
|
|
2591
|
-
displayedOmissions.length ? /* @__PURE__ */ (0,
|
|
2592
|
-
/* @__PURE__ */ (0,
|
|
2869
|
+
displayedOmissions.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { children: [
|
|
2870
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2593
2871
|
displayedOmissions.length,
|
|
2594
2872
|
" omissions or adjustments"
|
|
2595
2873
|
] }),
|
|
2596
|
-
/* @__PURE__ */ (0,
|
|
2874
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { children: displayedOmissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("li", { children: [
|
|
2597
2875
|
o.path || "/",
|
|
2598
2876
|
": ",
|
|
2599
2877
|
o.reason,
|
|
@@ -2601,79 +2879,86 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
2601
2879
|
] }, `${o.path}-${o.reason}-${i}`)) })
|
|
2602
2880
|
] }) : null
|
|
2603
2881
|
] }),
|
|
2604
|
-
bufferError ? /* @__PURE__ */ (0,
|
|
2605
|
-
formatError ? /* @__PURE__ */ (0,
|
|
2606
|
-
bufferError ? /* @__PURE__ */ (0,
|
|
2607
|
-
const fallback = (0,
|
|
2882
|
+
bufferError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { id: "alchemy-buffer-error", role: "alert", className: "matrx-alchemy-error", children: bufferError }) : null,
|
|
2883
|
+
formatError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: formatError }) : null,
|
|
2884
|
+
bufferError ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", disabled: busy !== null, onClick: () => {
|
|
2885
|
+
const fallback = (0, import_content_transfer3.editDraft)(state.draft, { kind: "text", text: buffer });
|
|
2608
2886
|
setBufferError(null);
|
|
2609
2887
|
onChange({ ...state, draft: fallback, error: void 0 });
|
|
2610
2888
|
setFormat("plain");
|
|
2611
2889
|
}, children: "Use invalid JSON as plain text" }) : null
|
|
2612
2890
|
] }),
|
|
2613
|
-
ai || busy === "capture" || state.error ? /* @__PURE__ */ (0,
|
|
2614
|
-
ai ? /* @__PURE__ */ (0,
|
|
2615
|
-
/* @__PURE__ */ (0,
|
|
2891
|
+
ai || busy === "capture" || state.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("aside", { children: [
|
|
2892
|
+
ai ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2893
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2616
2894
|
"Start with",
|
|
2617
|
-
/* @__PURE__ */ (0,
|
|
2895
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { "aria-label": "AI preparation recipe", defaultValue: "", onChange: (event) => {
|
|
2618
2896
|
if (event.target.value) setInstruction(event.target.value);
|
|
2619
2897
|
}, children: [
|
|
2620
|
-
/* @__PURE__ */ (0,
|
|
2621
|
-
/* @__PURE__ */ (0,
|
|
2622
|
-
/* @__PURE__ */ (0,
|
|
2623
|
-
/* @__PURE__ */ (0,
|
|
2624
|
-
/* @__PURE__ */ (0,
|
|
2625
|
-
/* @__PURE__ */ (0,
|
|
2626
|
-
/* @__PURE__ */ (0,
|
|
2898
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "", children: "Choose an instruction" }),
|
|
2899
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Summarize this content concisely. Preserve important facts, names, decisions, and source references.", children: "Summarize" }),
|
|
2900
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Extract decisions, action items, owners, and due dates. Mark missing details as unspecified.", children: "Extract action items" }),
|
|
2901
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Prepare a complete handoff for another assistant. Include the objective, relevant facts, constraints, decisions, and unresolved questions.", children: "Assistant handoff" }),
|
|
2902
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Condense this content by removing repetition and formatting noise. Preserve every unique fact and all identifiers.", children: "Condense without losing facts" }),
|
|
2903
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Turn this content into a clear structured outline. Keep the original meaning and explicitly flag uncertainty.", children: "Create an outline" }),
|
|
2904
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "Analyze this data. Identify patterns, anomalies, and useful comparisons. Distinguish observations from inferences.", children: "Analyze the data" })
|
|
2627
2905
|
] })
|
|
2628
2906
|
] }),
|
|
2629
|
-
/* @__PURE__ */ (0,
|
|
2907
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2630
2908
|
"AI instruction",
|
|
2631
|
-
/* @__PURE__ */ (0,
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("textarea", { value: instruction, onChange: (e) => setInstruction(e.target.value), placeholder: "Tell AI how to prepare this content" })
|
|
2632
2910
|
] }),
|
|
2633
|
-
/* @__PURE__ */ (0,
|
|
2634
|
-
busy === "ai" ? /* @__PURE__ */ (0,
|
|
2911
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
2912
|
+
busy === "ai" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => void cancelAi(), children: aiSession.current?.cancel ? "Cancel AI" : "Stop waiting" }) : null
|
|
2635
2913
|
] }) : null,
|
|
2636
|
-
busy === "capture" ? /* @__PURE__ */ (0,
|
|
2914
|
+
busy === "capture" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => {
|
|
2637
2915
|
activeCapture.current?.abort();
|
|
2638
2916
|
activeCapture.current = null;
|
|
2639
2917
|
setBusy(null);
|
|
2640
2918
|
}, children: "Stop loading rows" }) : null,
|
|
2641
|
-
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0,
|
|
2642
|
-
ai ? /* @__PURE__ */ (0,
|
|
2643
|
-
state.error ? /* @__PURE__ */ (0,
|
|
2919
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime11.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,
|
|
2920
|
+
ai ? /* @__PURE__ */ (0, import_jsx_runtime11.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,
|
|
2921
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
2644
2922
|
] }) : null
|
|
2645
2923
|
] }),
|
|
2646
|
-
pendingControls ? /* @__PURE__ */ (0,
|
|
2647
|
-
/* @__PURE__ */ (0,
|
|
2648
|
-
/* @__PURE__ */ (0,
|
|
2649
|
-
/* @__PURE__ */ (0,
|
|
2924
|
+
pendingControls ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2925
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: "This control would replace your manual edit." }),
|
|
2926
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
2927
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
2650
2928
|
] }) : null,
|
|
2651
|
-
state.sourceStale ? /* @__PURE__ */ (0,
|
|
2652
|
-
state.pending ? /* @__PURE__ */ (0,
|
|
2653
|
-
/* @__PURE__ */ (0,
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2655
|
-
|
|
2929
|
+
state.sourceStale ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
2930
|
+
state.pending ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
2931
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: "A fresh source snapshot is ready." }),
|
|
2932
|
+
state.pending.scope !== state.scope ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { children: [
|
|
2933
|
+
"Switch from ",
|
|
2934
|
+
scopeLabels?.[state.scope] ?? SCOPE_LABEL[state.scope],
|
|
2935
|
+
" to ",
|
|
2936
|
+
scopeLabels?.[state.pending.scope] ?? SCOPE_LABEL[state.pending.scope],
|
|
2937
|
+
" by regenerating. Your current draft is retained until you choose."
|
|
2938
|
+
] }) : null,
|
|
2939
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-secondary", type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
2940
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { className: "matrx-alchemy-workspace-primary", type: "button", onClick: () => resolveCapture("regenerate"), children: "Regenerate from fresh source" })
|
|
2656
2941
|
] }) : null,
|
|
2657
|
-
eligibleActions.length ? /* @__PURE__ */ (0,
|
|
2658
|
-
/* @__PURE__ */ (0,
|
|
2942
|
+
eligibleActions.length ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options matrx-alchemy-destinations", children: [
|
|
2943
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2659
2944
|
"Use prepared content \xB7 ",
|
|
2660
2945
|
eligibleActions.length,
|
|
2661
2946
|
" destinations"
|
|
2662
2947
|
] }),
|
|
2663
|
-
/* @__PURE__ */ (0,
|
|
2948
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "matrx-alchemy-destination-grid", children: eligibleActions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime11.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_runtime11.jsx)(DestinationPresentation, { action }) }, action.id)) })
|
|
2664
2949
|
] }) : null,
|
|
2665
|
-
deliveryNotice ? /* @__PURE__ */ (0,
|
|
2950
|
+
deliveryNotice ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { role: "status", className: "matrx-alchemy-meta", children: deliveryNotice }) : null
|
|
2666
2951
|
] }),
|
|
2667
|
-
/* @__PURE__ */ (0,
|
|
2668
|
-
/* @__PURE__ */ (0,
|
|
2952
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(DialogFooter, { children: [
|
|
2953
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "matrx-alchemy-meta", children: [
|
|
2669
2954
|
buffer.length.toLocaleString(),
|
|
2670
2955
|
" characters \xB7 ~",
|
|
2671
2956
|
estimateTokens(buffer).toLocaleString(),
|
|
2672
2957
|
" tokens"
|
|
2673
2958
|
] }),
|
|
2674
|
-
/* @__PURE__ */ (0,
|
|
2675
|
-
/* @__PURE__ */ (0,
|
|
2676
|
-
/* @__PURE__ */ (0,
|
|
2959
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { type: "button", variant: "outline", className: "matrx-alchemy-workspace-secondary", onClick: close, children: "Close" }),
|
|
2960
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" }),
|
|
2961
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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" })
|
|
2677
2962
|
] })
|
|
2678
2963
|
] }) });
|
|
2679
2964
|
}
|
|
@@ -2681,59 +2966,59 @@ function RowControls({ rows, controls, change }) {
|
|
|
2681
2966
|
const filterCount = Object.values(controls.filters).filter(Boolean).length;
|
|
2682
2967
|
const selectionSummary = controls.selectedOnly ? `${controls.selectedIndices.length} selected row${controls.selectedIndices.length === 1 ? "" : "s"}` : "All rows";
|
|
2683
2968
|
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 ");
|
|
2684
|
-
return /* @__PURE__ */ (0,
|
|
2685
|
-
/* @__PURE__ */ (0,
|
|
2686
|
-
/* @__PURE__ */ (0,
|
|
2969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
2970
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-toolbar", children: [
|
|
2971
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2687
2972
|
"Search",
|
|
2688
|
-
/* @__PURE__ */ (0,
|
|
2973
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { value: controls.search, onChange: (e) => change({ ...controls, search: e.target.value }) })
|
|
2689
2974
|
] }),
|
|
2690
|
-
/* @__PURE__ */ (0,
|
|
2975
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2691
2976
|
"Sort",
|
|
2692
|
-
/* @__PURE__ */ (0,
|
|
2693
|
-
/* @__PURE__ */ (0,
|
|
2694
|
-
rows.columns.map((column) => /* @__PURE__ */ (0,
|
|
2977
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { value: controls.sort, onChange: (e) => change({ ...controls, sort: e.target.value }), children: [
|
|
2978
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "", children: "None" }),
|
|
2979
|
+
rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: column.id, children: column.label }, column.id))
|
|
2695
2980
|
] })
|
|
2696
2981
|
] }),
|
|
2697
|
-
/* @__PURE__ */ (0,
|
|
2982
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2698
2983
|
"Direction",
|
|
2699
|
-
/* @__PURE__ */ (0,
|
|
2700
|
-
/* @__PURE__ */ (0,
|
|
2701
|
-
/* @__PURE__ */ (0,
|
|
2984
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("select", { value: controls.direction, disabled: !controls.sort, onChange: (e) => change({ ...controls, direction: e.target.value }), children: [
|
|
2985
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "asc", children: "Ascending" }),
|
|
2986
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("option", { value: "desc", children: "Descending" })
|
|
2702
2987
|
] })
|
|
2703
2988
|
] }),
|
|
2704
|
-
/* @__PURE__ */ (0,
|
|
2989
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
2705
2990
|
"Top rows",
|
|
2706
|
-
/* @__PURE__ */ (0,
|
|
2991
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "number", min: "0", value: controls.top ?? "", onChange: (e) => change({ ...controls, top: Number.isNaN(e.target.valueAsNumber) ? null : e.target.valueAsNumber }) })
|
|
2707
2992
|
] })
|
|
2708
2993
|
] }),
|
|
2709
|
-
/* @__PURE__ */ (0,
|
|
2710
|
-
/* @__PURE__ */ (0,
|
|
2994
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
2995
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2711
2996
|
"Columns and filters",
|
|
2712
2997
|
dataSummary ? ` \u2014 ${dataSummary}` : ""
|
|
2713
2998
|
] }),
|
|
2714
|
-
/* @__PURE__ */ (0,
|
|
2715
|
-
/* @__PURE__ */ (0,
|
|
2716
|
-
/* @__PURE__ */ (0,
|
|
2999
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("fieldset", { "aria-label": "Columns and filters", children: rows.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "matrx-alchemy-column", children: [
|
|
3000
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
3001
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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) }) }),
|
|
2717
3002
|
" ",
|
|
2718
3003
|
column.label
|
|
2719
3004
|
] }),
|
|
2720
|
-
/* @__PURE__ */ (0,
|
|
3005
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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 } }) })
|
|
2721
3006
|
] }, column.id)) })
|
|
2722
3007
|
] }),
|
|
2723
|
-
/* @__PURE__ */ (0,
|
|
2724
|
-
/* @__PURE__ */ (0,
|
|
3008
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("details", { className: "matrx-alchemy-options", children: [
|
|
3009
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { children: [
|
|
2725
3010
|
"Rows \u2014 ",
|
|
2726
3011
|
selectionSummary
|
|
2727
3012
|
] }),
|
|
2728
|
-
/* @__PURE__ */ (0,
|
|
2729
|
-
/* @__PURE__ */ (0,
|
|
2730
|
-
/* @__PURE__ */ (0,
|
|
3013
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("fieldset", { "aria-label": "Row selection", children: [
|
|
3014
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
3015
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "checkbox", checked: controls.selectedOnly, onChange: (e) => change({ ...controls, selectedOnly: e.target.checked }) }),
|
|
2731
3016
|
" Only selected rows"
|
|
2732
3017
|
] }),
|
|
2733
|
-
/* @__PURE__ */ (0,
|
|
2734
|
-
const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0,
|
|
2735
|
-
return /* @__PURE__ */ (0,
|
|
2736
|
-
/* @__PURE__ */ (0,
|
|
3018
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "matrx-alchemy-row-list", children: rows.rows.map((row, index) => {
|
|
3019
|
+
const summary = rows.columns.filter((column) => column.visible).slice(0, 2).map((column) => String((0, import_content_transfer3.readTransferCell)(row, column) ?? "")).filter(Boolean).join(" \xB7 ");
|
|
3020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("label", { children: [
|
|
3021
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.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) }) }),
|
|
2737
3022
|
" Row ",
|
|
2738
3023
|
index + 1,
|
|
2739
3024
|
summary ? ` \u2014 ${summary}` : ""
|