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