@ai-matrx/design-system 0.18.1 → 0.18.3
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 +25 -0
- package/dist/content-transfer.cjs +143 -34
- package/dist/content-transfer.cjs.map +1 -1
- package/dist/content-transfer.d.cts +5 -1
- package/dist/content-transfer.d.ts +5 -1
- package/dist/content-transfer.js +143 -34
- package/dist/content-transfer.js.map +1 -1
- package/dist/data-table/copy-types.cjs.map +1 -1
- package/dist/data-table/copy-types.d.cts +2 -0
- package/dist/data-table/copy-types.d.ts +2 -0
- package/dist/data-table/data-row-inspector.cjs +146 -36
- package/dist/data-table/data-row-inspector.cjs.map +1 -1
- package/dist/data-table/data-row-inspector.js +146 -36
- package/dist/data-table/data-row-inspector.js.map +1 -1
- package/dist/data-table/data-row-window.cjs +146 -36
- package/dist/data-table/data-row-window.cjs.map +1 -1
- package/dist/data-table/data-row-window.js +146 -36
- package/dist/data-table/data-row-window.js.map +1 -1
- package/dist/data-table/index.cjs +146 -36
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.js +146 -36
- package/dist/data-table/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -648,6 +648,10 @@ function materialIdentity(material) {
|
|
|
648
648
|
}
|
|
649
649
|
return `payload:${id}`;
|
|
650
650
|
}
|
|
651
|
+
function snapshotContent(snapshot) {
|
|
652
|
+
const { sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits } = snapshot;
|
|
653
|
+
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
654
|
+
}
|
|
651
655
|
function useFence() {
|
|
652
656
|
const mounted = React7.useRef(true);
|
|
653
657
|
const nextId = React7.useRef(0);
|
|
@@ -696,7 +700,12 @@ async function buildArtifact(draft, format, label) {
|
|
|
696
700
|
const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
|
|
697
701
|
return serialize(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
698
702
|
}
|
|
699
|
-
function ContentTransferMenu(
|
|
703
|
+
function ContentTransferMenu(props) {
|
|
704
|
+
const inherited = React7.useContext(CapabilityContext);
|
|
705
|
+
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
706
|
+
return /* @__PURE__ */ jsx7(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
707
|
+
}
|
|
708
|
+
function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
|
|
700
709
|
const triggerRef = React7.useRef(null);
|
|
701
710
|
const inherited = React7.useContext(CapabilityContext);
|
|
702
711
|
const nearestSurface = React7.useContext(SurfaceContext);
|
|
@@ -745,7 +754,7 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
745
754
|
const captured = await material.capture(signal);
|
|
746
755
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
747
756
|
} else if ("kind" in material) {
|
|
748
|
-
sourceMaterial =
|
|
757
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => directSource(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
749
758
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
750
759
|
sourceMaterial = {
|
|
751
760
|
id: material.id,
|
|
@@ -762,7 +771,7 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
762
771
|
} else {
|
|
763
772
|
sourceMaterial = material;
|
|
764
773
|
}
|
|
765
|
-
const raw =
|
|
774
|
+
const raw = await sourceMaterial.capture({ scope, signal });
|
|
766
775
|
const constrained = resolveTransferPreferences(providerPreferences, preferences, raw.snapshot.limits);
|
|
767
776
|
const result = await capture({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
768
777
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
@@ -822,31 +831,117 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
822
831
|
fence.finish(controller);
|
|
823
832
|
}
|
|
824
833
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
825
|
-
const openWorkspace = React7.useCallback(
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
const
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
834
|
+
const openWorkspace = React7.useCallback(
|
|
835
|
+
async (key = primaryWorkspaceKey, variant) => {
|
|
836
|
+
const variantMaterial = variant && "kind" in variant.source ? {
|
|
837
|
+
id: `variant:${key}`,
|
|
838
|
+
label: variant.label,
|
|
839
|
+
capture: async () => directSource(variant.source, {
|
|
840
|
+
sourceId: `variant:${key}`,
|
|
841
|
+
label: variant.label
|
|
842
|
+
})
|
|
843
|
+
} : variant?.source;
|
|
844
|
+
const captureWorkspace = (scope, signal, collectPages = true) => captureOne(variantMaterial ?? primary, scope, signal, true, collectPages);
|
|
845
|
+
workspaceCaptures.current.set(key, captureWorkspace);
|
|
846
|
+
const existing = workspaces[key];
|
|
847
|
+
const { controller, id } = fence.begin();
|
|
848
|
+
if (existing) {
|
|
849
|
+
try {
|
|
850
|
+
const allMatching = existing.scope === "all-matching";
|
|
851
|
+
const fresh = await captureWorkspace(
|
|
852
|
+
existing.scope,
|
|
853
|
+
controller.signal,
|
|
854
|
+
!allMatching
|
|
855
|
+
);
|
|
856
|
+
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
857
|
+
return;
|
|
858
|
+
if (allMatching && (!existing.allMatching || !fresh.allMatching))
|
|
859
|
+
throw new Error(
|
|
860
|
+
"This source can no longer provide an all-matching snapshot."
|
|
861
|
+
);
|
|
862
|
+
const collectionIdentity = (value) => value && {
|
|
863
|
+
query: value.source.query,
|
|
864
|
+
projection: value.projection,
|
|
865
|
+
columns: value.columns,
|
|
866
|
+
limits: value.limits
|
|
867
|
+
};
|
|
868
|
+
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
869
|
+
setWorkspaces((current) => {
|
|
870
|
+
const retained = current[key];
|
|
871
|
+
if (!retained) return current;
|
|
872
|
+
return {
|
|
873
|
+
...current,
|
|
874
|
+
[key]: {
|
|
875
|
+
...retained,
|
|
876
|
+
error: fresh.collectionError,
|
|
877
|
+
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: retained.scope } } : { pending: void 0 }
|
|
878
|
+
}
|
|
879
|
+
};
|
|
880
|
+
});
|
|
881
|
+
setWorkspaceKey(key);
|
|
882
|
+
setWorkspaceOpen(true);
|
|
883
|
+
} catch (error) {
|
|
884
|
+
if (fence.valid(id, controller) && workspaceCaptures.current.has(key)) {
|
|
885
|
+
setWorkspaces(
|
|
886
|
+
(current) => current[key] ? {
|
|
887
|
+
...current,
|
|
888
|
+
[key]: {
|
|
889
|
+
...current[key],
|
|
890
|
+
error: errorMessage(error, "Could not refresh source")
|
|
891
|
+
}
|
|
892
|
+
} : current
|
|
893
|
+
);
|
|
894
|
+
setWorkspaceKey(key);
|
|
895
|
+
setWorkspaceOpen(true);
|
|
896
|
+
}
|
|
897
|
+
} finally {
|
|
898
|
+
fence.finish(controller);
|
|
899
|
+
}
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
try {
|
|
903
|
+
const result = await captureWorkspace(initialScope, controller.signal);
|
|
904
|
+
if (!fence.valid(id, controller)) return;
|
|
905
|
+
const resolved = resolveTransferPreferences(
|
|
906
|
+
providerPreferences,
|
|
907
|
+
preferences,
|
|
908
|
+
result.snapshot.limits
|
|
909
|
+
);
|
|
910
|
+
const original = createDraft(result.snapshot);
|
|
911
|
+
const base = {
|
|
912
|
+
...result,
|
|
913
|
+
key,
|
|
914
|
+
original,
|
|
915
|
+
draft: original,
|
|
916
|
+
scope: initialScope,
|
|
917
|
+
preferences: resolved,
|
|
918
|
+
...result.collectionError ? { error: result.collectionError } : {}
|
|
919
|
+
};
|
|
920
|
+
setWorkspaces((current) => ({
|
|
921
|
+
...current,
|
|
922
|
+
[key]: { ...base, draft: rebuild(base, initialControls(base)) }
|
|
923
|
+
}));
|
|
924
|
+
setWorkspaceKey(key);
|
|
925
|
+
setWorkspaceOpen(true);
|
|
926
|
+
} catch (error) {
|
|
927
|
+
if (fence.valid(id, controller))
|
|
928
|
+
setNotice(errorMessage(error, "Could not capture content"));
|
|
929
|
+
} finally {
|
|
930
|
+
fence.finish(controller);
|
|
931
|
+
}
|
|
932
|
+
},
|
|
933
|
+
[
|
|
934
|
+
captureOne,
|
|
935
|
+
capturePrimary,
|
|
936
|
+
fence,
|
|
937
|
+
initialScope,
|
|
938
|
+
preferences,
|
|
939
|
+
primaryWorkspaceKey,
|
|
940
|
+
primary,
|
|
941
|
+
providerPreferences,
|
|
942
|
+
workspaces
|
|
943
|
+
]
|
|
944
|
+
);
|
|
850
945
|
React7.useImperativeHandle(controllerRef, () => ({
|
|
851
946
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
852
947
|
prepare: async (requestedSource, options) => {
|
|
@@ -989,6 +1084,9 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
989
1084
|
const [instruction, setInstruction] = React7.useState("");
|
|
990
1085
|
const [busy, setBusy] = React7.useState(null);
|
|
991
1086
|
const [aiFailed, setAiFailed] = React7.useState(false);
|
|
1087
|
+
React7.useEffect(() => {
|
|
1088
|
+
setAiFailed(false);
|
|
1089
|
+
}, [state.snapshot.id, state.draft.revision]);
|
|
992
1090
|
const activeAi = React7.useRef(null);
|
|
993
1091
|
const activeCapture = React7.useRef(null);
|
|
994
1092
|
React7.useEffect(() => {
|
|
@@ -1066,7 +1164,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1066
1164
|
setBusy("capture");
|
|
1067
1165
|
try {
|
|
1068
1166
|
const result = await captureScope(scope, controller.signal);
|
|
1069
|
-
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, error: result.collectionError });
|
|
1167
|
+
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, sourceStale: false, error: result.collectionError });
|
|
1070
1168
|
} catch (error) {
|
|
1071
1169
|
if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "Refresh failed") });
|
|
1072
1170
|
} finally {
|
|
@@ -1299,7 +1397,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1299
1397
|
activeCapture.current = null;
|
|
1300
1398
|
setBusy(null);
|
|
1301
1399
|
}, children: "Stop loading rows" }) : null,
|
|
1302
|
-
ai && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
1400
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
1303
1401
|
ai ? /* @__PURE__ */ jsx7("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
|
|
1304
1402
|
state.error ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
1305
1403
|
] }) : null
|
|
@@ -1309,6 +1407,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1309
1407
|
/* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
1310
1408
|
/* @__PURE__ */ jsx7(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
1311
1409
|
] }) : null,
|
|
1410
|
+
state.sourceStale ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
1312
1411
|
state.pending ? /* @__PURE__ */ jsxs4("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
1313
1412
|
/* @__PURE__ */ jsx7("p", { children: "A fresh source snapshot is ready." }),
|
|
1314
1413
|
/* @__PURE__ */ jsx7(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
@@ -1426,7 +1525,17 @@ var sourceFor = (id, label, build) => ({
|
|
|
1426
1525
|
}
|
|
1427
1526
|
});
|
|
1428
1527
|
function MatrxCopyMenu(props) {
|
|
1429
|
-
|
|
1528
|
+
const inherited = useContentTransferCapabilities();
|
|
1529
|
+
return /* @__PURE__ */ jsx8(
|
|
1530
|
+
MatrxCopyMenuSession,
|
|
1531
|
+
{
|
|
1532
|
+
...props
|
|
1533
|
+
},
|
|
1534
|
+
JSON.stringify([
|
|
1535
|
+
inherited.identityKey ?? null,
|
|
1536
|
+
props.sourceId ?? props.label
|
|
1537
|
+
])
|
|
1538
|
+
);
|
|
1430
1539
|
}
|
|
1431
1540
|
function MatrxCopyMenuSession(props) {
|
|
1432
1541
|
const instance = React8.useId();
|
|
@@ -1454,7 +1563,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1454
1563
|
})) : void 0;
|
|
1455
1564
|
const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
|
|
1456
1565
|
const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
|
|
1457
|
-
const table = exportVisible && props.export?.sheetRows ? make("rows", () => {
|
|
1566
|
+
const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
|
|
1458
1567
|
const value = normalizeTransferJson(props.export.sheetRows());
|
|
1459
1568
|
if (!Array.isArray(value) || value.some(
|
|
1460
1569
|
(row) => row === null || typeof row !== "object" || Array.isArray(row)
|
|
@@ -1601,7 +1710,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1601
1710
|
return props.sendToSheet(draft.payload.rows, props.label);
|
|
1602
1711
|
}
|
|
1603
1712
|
});
|
|
1604
|
-
const source = json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
1713
|
+
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
1605
1714
|
if (!source && !actions.length) return null;
|
|
1606
1715
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
1607
1716
|
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
@@ -1621,7 +1730,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1621
1730
|
formatSources: {
|
|
1622
1731
|
...human ? { plain: human, markdown: humanMarkdown, html: humanMarkdown } : {},
|
|
1623
1732
|
...json ? { json, "compact-json": json } : {},
|
|
1624
|
-
...table ? { csv: table, tsv: table } : {}
|
|
1733
|
+
...table && exportVisible ? { csv: table, tsv: table } : {}
|
|
1625
1734
|
},
|
|
1626
1735
|
...props.disabled !== void 0 ? { disabled: props.disabled } : {},
|
|
1627
1736
|
className: cn(
|
|
@@ -1904,8 +2013,9 @@ function useMatrxDataTableHost() {
|
|
|
1904
2013
|
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1905
2014
|
function CopyButtons(props) {
|
|
1906
2015
|
const { CopyControls } = useMatrxDataTableHost();
|
|
1907
|
-
|
|
1908
|
-
return /* @__PURE__ */ jsx10(
|
|
2016
|
+
const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
|
|
2017
|
+
if (CopyControls) return /* @__PURE__ */ jsx10(CopyControls, { ...copyProps });
|
|
2018
|
+
return /* @__PURE__ */ jsx10(MatrxCopyMenu, { ...copyProps });
|
|
1909
2019
|
}
|
|
1910
2020
|
|
|
1911
2021
|
// src/data-table/MatrxUuidCell.tsx
|