@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
|
@@ -701,6 +701,10 @@ function materialIdentity(material) {
|
|
|
701
701
|
}
|
|
702
702
|
return `payload:${id}`;
|
|
703
703
|
}
|
|
704
|
+
function snapshotContent(snapshot) {
|
|
705
|
+
const { sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits } = snapshot;
|
|
706
|
+
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
707
|
+
}
|
|
704
708
|
function useFence() {
|
|
705
709
|
const mounted = React7.useRef(true);
|
|
706
710
|
const nextId = React7.useRef(0);
|
|
@@ -749,7 +753,12 @@ async function buildArtifact(draft, format, label) {
|
|
|
749
753
|
const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
|
|
750
754
|
return serialize(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
751
755
|
}
|
|
752
|
-
function ContentTransferMenu(
|
|
756
|
+
function ContentTransferMenu(props) {
|
|
757
|
+
const inherited = React7.useContext(CapabilityContext);
|
|
758
|
+
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
759
|
+
return /* @__PURE__ */ jsx10(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
760
|
+
}
|
|
761
|
+
function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
|
|
753
762
|
const triggerRef = React7.useRef(null);
|
|
754
763
|
const inherited = React7.useContext(CapabilityContext);
|
|
755
764
|
const nearestSurface = React7.useContext(SurfaceContext);
|
|
@@ -798,7 +807,7 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
798
807
|
const captured = await material.capture(signal);
|
|
799
808
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
800
809
|
} else if ("kind" in material) {
|
|
801
|
-
sourceMaterial =
|
|
810
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => directSource(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
802
811
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
803
812
|
sourceMaterial = {
|
|
804
813
|
id: material.id,
|
|
@@ -815,7 +824,7 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
815
824
|
} else {
|
|
816
825
|
sourceMaterial = material;
|
|
817
826
|
}
|
|
818
|
-
const raw =
|
|
827
|
+
const raw = await sourceMaterial.capture({ scope, signal });
|
|
819
828
|
const constrained = resolveTransferPreferences(providerPreferences, preferences, raw.snapshot.limits);
|
|
820
829
|
const result = await capture({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
821
830
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
@@ -875,31 +884,117 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
875
884
|
fence.finish(controller);
|
|
876
885
|
}
|
|
877
886
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
878
|
-
const openWorkspace = React7.useCallback(
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
887
|
+
const openWorkspace = React7.useCallback(
|
|
888
|
+
async (key = primaryWorkspaceKey, variant) => {
|
|
889
|
+
const variantMaterial = variant && "kind" in variant.source ? {
|
|
890
|
+
id: `variant:${key}`,
|
|
891
|
+
label: variant.label,
|
|
892
|
+
capture: async () => directSource(variant.source, {
|
|
893
|
+
sourceId: `variant:${key}`,
|
|
894
|
+
label: variant.label
|
|
895
|
+
})
|
|
896
|
+
} : variant?.source;
|
|
897
|
+
const captureWorkspace = (scope, signal, collectPages = true) => captureOne(variantMaterial ?? primary, scope, signal, true, collectPages);
|
|
898
|
+
workspaceCaptures.current.set(key, captureWorkspace);
|
|
899
|
+
const existing = workspaces[key];
|
|
900
|
+
const { controller, id } = fence.begin();
|
|
901
|
+
if (existing) {
|
|
902
|
+
try {
|
|
903
|
+
const allMatching = existing.scope === "all-matching";
|
|
904
|
+
const fresh = await captureWorkspace(
|
|
905
|
+
existing.scope,
|
|
906
|
+
controller.signal,
|
|
907
|
+
!allMatching
|
|
908
|
+
);
|
|
909
|
+
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
910
|
+
return;
|
|
911
|
+
if (allMatching && (!existing.allMatching || !fresh.allMatching))
|
|
912
|
+
throw new Error(
|
|
913
|
+
"This source can no longer provide an all-matching snapshot."
|
|
914
|
+
);
|
|
915
|
+
const collectionIdentity = (value) => value && {
|
|
916
|
+
query: value.source.query,
|
|
917
|
+
projection: value.projection,
|
|
918
|
+
columns: value.columns,
|
|
919
|
+
limits: value.limits
|
|
920
|
+
};
|
|
921
|
+
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
922
|
+
setWorkspaces((current) => {
|
|
923
|
+
const retained = current[key];
|
|
924
|
+
if (!retained) return current;
|
|
925
|
+
return {
|
|
926
|
+
...current,
|
|
927
|
+
[key]: {
|
|
928
|
+
...retained,
|
|
929
|
+
error: fresh.collectionError,
|
|
930
|
+
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: retained.scope } } : { pending: void 0 }
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
});
|
|
934
|
+
setWorkspaceKey(key);
|
|
935
|
+
setWorkspaceOpen(true);
|
|
936
|
+
} catch (error) {
|
|
937
|
+
if (fence.valid(id, controller) && workspaceCaptures.current.has(key)) {
|
|
938
|
+
setWorkspaces(
|
|
939
|
+
(current) => current[key] ? {
|
|
940
|
+
...current,
|
|
941
|
+
[key]: {
|
|
942
|
+
...current[key],
|
|
943
|
+
error: errorMessage(error, "Could not refresh source")
|
|
944
|
+
}
|
|
945
|
+
} : current
|
|
946
|
+
);
|
|
947
|
+
setWorkspaceKey(key);
|
|
948
|
+
setWorkspaceOpen(true);
|
|
949
|
+
}
|
|
950
|
+
} finally {
|
|
951
|
+
fence.finish(controller);
|
|
952
|
+
}
|
|
953
|
+
return;
|
|
954
|
+
}
|
|
955
|
+
try {
|
|
956
|
+
const result = await captureWorkspace(initialScope, controller.signal);
|
|
957
|
+
if (!fence.valid(id, controller)) return;
|
|
958
|
+
const resolved = resolveTransferPreferences(
|
|
959
|
+
providerPreferences,
|
|
960
|
+
preferences,
|
|
961
|
+
result.snapshot.limits
|
|
962
|
+
);
|
|
963
|
+
const original = createDraft(result.snapshot);
|
|
964
|
+
const base = {
|
|
965
|
+
...result,
|
|
966
|
+
key,
|
|
967
|
+
original,
|
|
968
|
+
draft: original,
|
|
969
|
+
scope: initialScope,
|
|
970
|
+
preferences: resolved,
|
|
971
|
+
...result.collectionError ? { error: result.collectionError } : {}
|
|
972
|
+
};
|
|
973
|
+
setWorkspaces((current) => ({
|
|
974
|
+
...current,
|
|
975
|
+
[key]: { ...base, draft: rebuild(base, initialControls(base)) }
|
|
976
|
+
}));
|
|
977
|
+
setWorkspaceKey(key);
|
|
978
|
+
setWorkspaceOpen(true);
|
|
979
|
+
} catch (error) {
|
|
980
|
+
if (fence.valid(id, controller))
|
|
981
|
+
setNotice(errorMessage(error, "Could not capture content"));
|
|
982
|
+
} finally {
|
|
983
|
+
fence.finish(controller);
|
|
984
|
+
}
|
|
985
|
+
},
|
|
986
|
+
[
|
|
987
|
+
captureOne,
|
|
988
|
+
capturePrimary,
|
|
989
|
+
fence,
|
|
990
|
+
initialScope,
|
|
991
|
+
preferences,
|
|
992
|
+
primaryWorkspaceKey,
|
|
993
|
+
primary,
|
|
994
|
+
providerPreferences,
|
|
995
|
+
workspaces
|
|
996
|
+
]
|
|
997
|
+
);
|
|
903
998
|
React7.useImperativeHandle(controllerRef, () => ({
|
|
904
999
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
905
1000
|
prepare: async (requestedSource, options) => {
|
|
@@ -1042,6 +1137,9 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1042
1137
|
const [instruction, setInstruction] = React7.useState("");
|
|
1043
1138
|
const [busy, setBusy] = React7.useState(null);
|
|
1044
1139
|
const [aiFailed, setAiFailed] = React7.useState(false);
|
|
1140
|
+
React7.useEffect(() => {
|
|
1141
|
+
setAiFailed(false);
|
|
1142
|
+
}, [state.snapshot.id, state.draft.revision]);
|
|
1045
1143
|
const activeAi = React7.useRef(null);
|
|
1046
1144
|
const activeCapture = React7.useRef(null);
|
|
1047
1145
|
React7.useEffect(() => {
|
|
@@ -1119,7 +1217,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1119
1217
|
setBusy("capture");
|
|
1120
1218
|
try {
|
|
1121
1219
|
const result = await captureScope(scope, controller.signal);
|
|
1122
|
-
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, error: result.collectionError });
|
|
1220
|
+
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, sourceStale: false, error: result.collectionError });
|
|
1123
1221
|
} catch (error) {
|
|
1124
1222
|
if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "Refresh failed") });
|
|
1125
1223
|
} finally {
|
|
@@ -1352,7 +1450,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1352
1450
|
activeCapture.current = null;
|
|
1353
1451
|
setBusy(null);
|
|
1354
1452
|
}, children: "Stop loading rows" }) : null,
|
|
1355
|
-
ai && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx10(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
1453
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx10(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
1356
1454
|
ai ? /* @__PURE__ */ jsx10("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
|
|
1357
1455
|
state.error ? /* @__PURE__ */ jsx10("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
1358
1456
|
] }) : null
|
|
@@ -1362,6 +1460,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1362
1460
|
/* @__PURE__ */ jsx10(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
1363
1461
|
/* @__PURE__ */ jsx10(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
1364
1462
|
] }) : null,
|
|
1463
|
+
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,
|
|
1365
1464
|
state.pending ? /* @__PURE__ */ jsxs6("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
1366
1465
|
/* @__PURE__ */ jsx10("p", { children: "A fresh source snapshot is ready." }),
|
|
1367
1466
|
/* @__PURE__ */ jsx10(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|
|
@@ -1479,7 +1578,17 @@ var sourceFor = (id, label, build) => ({
|
|
|
1479
1578
|
}
|
|
1480
1579
|
});
|
|
1481
1580
|
function MatrxCopyMenu(props) {
|
|
1482
|
-
|
|
1581
|
+
const inherited = useContentTransferCapabilities();
|
|
1582
|
+
return /* @__PURE__ */ jsx11(
|
|
1583
|
+
MatrxCopyMenuSession,
|
|
1584
|
+
{
|
|
1585
|
+
...props
|
|
1586
|
+
},
|
|
1587
|
+
JSON.stringify([
|
|
1588
|
+
inherited.identityKey ?? null,
|
|
1589
|
+
props.sourceId ?? props.label
|
|
1590
|
+
])
|
|
1591
|
+
);
|
|
1483
1592
|
}
|
|
1484
1593
|
function MatrxCopyMenuSession(props) {
|
|
1485
1594
|
const instance = React8.useId();
|
|
@@ -1507,7 +1616,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1507
1616
|
})) : void 0;
|
|
1508
1617
|
const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
|
|
1509
1618
|
const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
|
|
1510
|
-
const table = exportVisible && props.export?.sheetRows ? make("rows", () => {
|
|
1619
|
+
const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
|
|
1511
1620
|
const value = normalizeTransferJson(props.export.sheetRows());
|
|
1512
1621
|
if (!Array.isArray(value) || value.some(
|
|
1513
1622
|
(row) => row === null || typeof row !== "object" || Array.isArray(row)
|
|
@@ -1654,7 +1763,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1654
1763
|
return props.sendToSheet(draft.payload.rows, props.label);
|
|
1655
1764
|
}
|
|
1656
1765
|
});
|
|
1657
|
-
const source = json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
1766
|
+
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
1658
1767
|
if (!source && !actions.length) return null;
|
|
1659
1768
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
1660
1769
|
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
@@ -1674,7 +1783,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
1674
1783
|
formatSources: {
|
|
1675
1784
|
...human ? { plain: human, markdown: humanMarkdown, html: humanMarkdown } : {},
|
|
1676
1785
|
...json ? { json, "compact-json": json } : {},
|
|
1677
|
-
...table ? { csv: table, tsv: table } : {}
|
|
1786
|
+
...table && exportVisible ? { csv: table, tsv: table } : {}
|
|
1678
1787
|
},
|
|
1679
1788
|
...props.disabled !== void 0 ? { disabled: props.disabled } : {},
|
|
1680
1789
|
className: cn(
|
|
@@ -1947,8 +2056,9 @@ function SourceConfiguration({
|
|
|
1947
2056
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1948
2057
|
function CopyButtons(props) {
|
|
1949
2058
|
const { CopyControls } = useMatrxDataTableHost();
|
|
1950
|
-
|
|
1951
|
-
return /* @__PURE__ */ jsx12(
|
|
2059
|
+
const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
|
|
2060
|
+
if (CopyControls) return /* @__PURE__ */ jsx12(CopyControls, { ...copyProps });
|
|
2061
|
+
return /* @__PURE__ */ jsx12(MatrxCopyMenu, { ...copyProps });
|
|
1952
2062
|
}
|
|
1953
2063
|
|
|
1954
2064
|
// src/data-table/MatrxUuidCell.tsx
|