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