@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
|
@@ -103,6 +103,8 @@ interface MatrxCopyMenuProps {
|
|
|
103
103
|
label: string;
|
|
104
104
|
/** Stable record identity when this mounted control can switch between records. */
|
|
105
105
|
sourceId?: string;
|
|
106
|
+
/** Prepare the tabular view while keeping raw JSON and human copy formats. */
|
|
107
|
+
primarySource?: "table";
|
|
106
108
|
human?: Resolvable<string>;
|
|
107
109
|
json?: Resolvable<unknown>;
|
|
108
110
|
agent?: Resolvable<AgentPayloadInput | string>;
|
|
@@ -141,6 +143,8 @@ declare function groomerPresetVariants(getConfig: () => AlchemyGroomerConfig): A
|
|
|
141
143
|
|
|
142
144
|
declare function AlchemyGlyph(props: React.SVGAttributes<SVGSVGElement>): React.JSX.Element;
|
|
143
145
|
type ContentTransferCapabilities = TransferCapabilities & {
|
|
146
|
+
/** Opaque host session boundary. It is used only to reset local menu state. */
|
|
147
|
+
identityKey?: string;
|
|
144
148
|
transport?: Transport;
|
|
145
149
|
actions?: PageAction[];
|
|
146
150
|
preferences?: TransferPreferenceOverrides;
|
|
@@ -203,6 +207,6 @@ interface ContentTransferController {
|
|
|
203
207
|
label?: string;
|
|
204
208
|
}): Promise<void>;
|
|
205
209
|
}
|
|
206
|
-
declare function ContentTransferMenu(
|
|
210
|
+
declare function ContentTransferMenu(props: ContentTransferMenuProps): React.JSX.Element;
|
|
207
211
|
|
|
208
212
|
export { type AlchemyCopyVariant, type AlchemyCustomSource, type AlchemyDetail, type AlchemyExportItem, AlchemyGlyph, type AlchemyGroomerConfig, type AlchemyGroomerPreset, type AlchemyGroomerSection, type AlchemyOptionValues, type AlchemySourceOption, type ContentTransferCapabilities, ContentTransferCapabilitiesProvider, type ContentTransferController, ContentTransferMenu, type ContentTransferMenuProps, ContentTransferSurfaceProvider, GROOMER_LEVELS, MatrxCopyMenu, type MatrxCopyMenuProps, type SerializableFormat, type TransferMenuPresentation, type TransferMenuVariant, applyGroomerPreset, buildGroomerPresetPayload, defaultGroomerSelections, groomerPresetVariants, useContentTransferCapabilities, useContentTransferSurface };
|
|
@@ -103,6 +103,8 @@ interface MatrxCopyMenuProps {
|
|
|
103
103
|
label: string;
|
|
104
104
|
/** Stable record identity when this mounted control can switch between records. */
|
|
105
105
|
sourceId?: string;
|
|
106
|
+
/** Prepare the tabular view while keeping raw JSON and human copy formats. */
|
|
107
|
+
primarySource?: "table";
|
|
106
108
|
human?: Resolvable<string>;
|
|
107
109
|
json?: Resolvable<unknown>;
|
|
108
110
|
agent?: Resolvable<AgentPayloadInput | string>;
|
|
@@ -141,6 +143,8 @@ declare function groomerPresetVariants(getConfig: () => AlchemyGroomerConfig): A
|
|
|
141
143
|
|
|
142
144
|
declare function AlchemyGlyph(props: React.SVGAttributes<SVGSVGElement>): React.JSX.Element;
|
|
143
145
|
type ContentTransferCapabilities = TransferCapabilities & {
|
|
146
|
+
/** Opaque host session boundary. It is used only to reset local menu state. */
|
|
147
|
+
identityKey?: string;
|
|
144
148
|
transport?: Transport;
|
|
145
149
|
actions?: PageAction[];
|
|
146
150
|
preferences?: TransferPreferenceOverrides;
|
|
@@ -203,6 +207,6 @@ interface ContentTransferController {
|
|
|
203
207
|
label?: string;
|
|
204
208
|
}): Promise<void>;
|
|
205
209
|
}
|
|
206
|
-
declare function ContentTransferMenu(
|
|
210
|
+
declare function ContentTransferMenu(props: ContentTransferMenuProps): React.JSX.Element;
|
|
207
211
|
|
|
208
212
|
export { type AlchemyCopyVariant, type AlchemyCustomSource, type AlchemyDetail, type AlchemyExportItem, AlchemyGlyph, type AlchemyGroomerConfig, type AlchemyGroomerPreset, type AlchemyGroomerSection, type AlchemyOptionValues, type AlchemySourceOption, type ContentTransferCapabilities, ContentTransferCapabilitiesProvider, type ContentTransferController, ContentTransferMenu, type ContentTransferMenuProps, ContentTransferSurfaceProvider, GROOMER_LEVELS, MatrxCopyMenu, type MatrxCopyMenuProps, type SerializableFormat, type TransferMenuPresentation, type TransferMenuVariant, applyGroomerPreset, buildGroomerPresetPayload, defaultGroomerSelections, groomerPresetVariants, useContentTransferCapabilities, useContentTransferSurface };
|
package/dist/content-transfer.js
CHANGED
|
@@ -641,7 +641,17 @@ var sourceFor = (id, label, build) => ({
|
|
|
641
641
|
}
|
|
642
642
|
});
|
|
643
643
|
function MatrxCopyMenu(props) {
|
|
644
|
-
|
|
644
|
+
const inherited = useContentTransferCapabilities();
|
|
645
|
+
return /* @__PURE__ */ jsx7(
|
|
646
|
+
MatrxCopyMenuSession,
|
|
647
|
+
{
|
|
648
|
+
...props
|
|
649
|
+
},
|
|
650
|
+
JSON.stringify([
|
|
651
|
+
inherited.identityKey ?? null,
|
|
652
|
+
props.sourceId ?? props.label
|
|
653
|
+
])
|
|
654
|
+
);
|
|
645
655
|
}
|
|
646
656
|
function MatrxCopyMenuSession(props) {
|
|
647
657
|
const instance = React7.useId();
|
|
@@ -669,7 +679,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
669
679
|
})) : void 0;
|
|
670
680
|
const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
|
|
671
681
|
const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
|
|
672
|
-
const table = exportVisible && props.export?.sheetRows ? make("rows", () => {
|
|
682
|
+
const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
|
|
673
683
|
const value = normalizeTransferJson(props.export.sheetRows());
|
|
674
684
|
if (!Array.isArray(value) || value.some(
|
|
675
685
|
(row) => row === null || typeof row !== "object" || Array.isArray(row)
|
|
@@ -816,7 +826,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
816
826
|
return props.sendToSheet(draft.payload.rows, props.label);
|
|
817
827
|
}
|
|
818
828
|
});
|
|
819
|
-
const source = json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
829
|
+
const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
|
|
820
830
|
if (!source && !actions.length) return null;
|
|
821
831
|
const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
|
|
822
832
|
return /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
@@ -836,7 +846,7 @@ function MatrxCopyMenuSession(props) {
|
|
|
836
846
|
formatSources: {
|
|
837
847
|
...human ? { plain: human, markdown: humanMarkdown, html: humanMarkdown } : {},
|
|
838
848
|
...json ? { json, "compact-json": json } : {},
|
|
839
|
-
...table ? { csv: table, tsv: table } : {}
|
|
849
|
+
...table && exportVisible ? { csv: table, tsv: table } : {}
|
|
840
850
|
},
|
|
841
851
|
...props.disabled !== void 0 ? { disabled: props.disabled } : {},
|
|
842
852
|
className: cn(
|
|
@@ -1221,6 +1231,10 @@ function materialIdentity(material) {
|
|
|
1221
1231
|
}
|
|
1222
1232
|
return `payload:${id}`;
|
|
1223
1233
|
}
|
|
1234
|
+
function snapshotContent(snapshot) {
|
|
1235
|
+
const { sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits } = snapshot;
|
|
1236
|
+
return JSON.stringify({ sourceId, label, payload, coverage, unsavedChanges, omissions, sections, limits });
|
|
1237
|
+
}
|
|
1224
1238
|
function useFence() {
|
|
1225
1239
|
const mounted = React8.useRef(true);
|
|
1226
1240
|
const nextId = React8.useRef(0);
|
|
@@ -1269,7 +1283,12 @@ async function buildArtifact(draft, format, label) {
|
|
|
1269
1283
|
const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
|
|
1270
1284
|
return serialize(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
|
|
1271
1285
|
}
|
|
1272
|
-
function ContentTransferMenu(
|
|
1286
|
+
function ContentTransferMenu(props) {
|
|
1287
|
+
const inherited = React8.useContext(CapabilityContext);
|
|
1288
|
+
const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
|
|
1289
|
+
return /* @__PURE__ */ jsx8(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
|
|
1290
|
+
}
|
|
1291
|
+
function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
|
|
1273
1292
|
const triggerRef = React8.useRef(null);
|
|
1274
1293
|
const inherited = React8.useContext(CapabilityContext);
|
|
1275
1294
|
const nearestSurface = React8.useContext(SurfaceContext);
|
|
@@ -1318,7 +1337,7 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
1318
1337
|
const captured = await material.capture(signal);
|
|
1319
1338
|
sourceMaterial = { id: captured.snapshot.sourceId, label: captured.snapshot.label, capture: async () => captured };
|
|
1320
1339
|
} else if ("kind" in material) {
|
|
1321
|
-
sourceMaterial =
|
|
1340
|
+
sourceMaterial = { id: materialIdentity(material), label: sourceLabel, capture: async () => directSource2(material, { sourceId: materialIdentity(material), label: sourceLabel, ...applyMenuProjection && projection ? { projection } : {}, ...applyMenuProjection && sections ? { sections } : {} }) };
|
|
1322
1341
|
} else if (applyMenuProjection && (projection || sections)) {
|
|
1323
1342
|
sourceMaterial = {
|
|
1324
1343
|
id: material.id,
|
|
@@ -1335,7 +1354,7 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
1335
1354
|
} else {
|
|
1336
1355
|
sourceMaterial = material;
|
|
1337
1356
|
}
|
|
1338
|
-
const raw =
|
|
1357
|
+
const raw = await sourceMaterial.capture({ scope, signal });
|
|
1339
1358
|
const constrained = resolveTransferPreferences(providerPreferences, preferences, raw.snapshot.limits);
|
|
1340
1359
|
const result = await capture({ id: raw.snapshot.sourceId, label: raw.snapshot.label, capture: async () => ({ ...raw, snapshot: { ...raw.snapshot, limits: constrained.limits } }) }, signal, scope);
|
|
1341
1360
|
if (scope !== "all-matching" || !collectPages) return result;
|
|
@@ -1395,31 +1414,117 @@ function ContentTransferMenu({ source, surface, label, projection, sections, pre
|
|
|
1395
1414
|
fence.finish(controller);
|
|
1396
1415
|
}
|
|
1397
1416
|
}, [captureOne, capturePrimary, fence, formatSources, initialScope, preferences, providerPreferences, report, transport]);
|
|
1398
|
-
const openWorkspace = React8.useCallback(
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1417
|
+
const openWorkspace = React8.useCallback(
|
|
1418
|
+
async (key = primaryWorkspaceKey, variant) => {
|
|
1419
|
+
const variantMaterial = variant && "kind" in variant.source ? {
|
|
1420
|
+
id: `variant:${key}`,
|
|
1421
|
+
label: variant.label,
|
|
1422
|
+
capture: async () => directSource2(variant.source, {
|
|
1423
|
+
sourceId: `variant:${key}`,
|
|
1424
|
+
label: variant.label
|
|
1425
|
+
})
|
|
1426
|
+
} : variant?.source;
|
|
1427
|
+
const captureWorkspace = (scope, signal, collectPages = true) => captureOne(variantMaterial ?? primary, scope, signal, true, collectPages);
|
|
1428
|
+
workspaceCaptures.current.set(key, captureWorkspace);
|
|
1429
|
+
const existing = workspaces[key];
|
|
1430
|
+
const { controller, id } = fence.begin();
|
|
1431
|
+
if (existing) {
|
|
1432
|
+
try {
|
|
1433
|
+
const allMatching = existing.scope === "all-matching";
|
|
1434
|
+
const fresh = await captureWorkspace(
|
|
1435
|
+
existing.scope,
|
|
1436
|
+
controller.signal,
|
|
1437
|
+
!allMatching
|
|
1438
|
+
);
|
|
1439
|
+
if (!fence.valid(id, controller) || !workspaceCaptures.current.has(key))
|
|
1440
|
+
return;
|
|
1441
|
+
if (allMatching && (!existing.allMatching || !fresh.allMatching))
|
|
1442
|
+
throw new Error(
|
|
1443
|
+
"This source can no longer provide an all-matching snapshot."
|
|
1444
|
+
);
|
|
1445
|
+
const collectionIdentity = (value) => value && {
|
|
1446
|
+
query: value.source.query,
|
|
1447
|
+
projection: value.projection,
|
|
1448
|
+
columns: value.columns,
|
|
1449
|
+
limits: value.limits
|
|
1450
|
+
};
|
|
1451
|
+
const changed = allMatching ? JSON.stringify(collectionIdentity(existing.allMatching)) !== JSON.stringify(collectionIdentity(fresh.allMatching)) : snapshotContent(existing.snapshot) !== snapshotContent(fresh.snapshot);
|
|
1452
|
+
setWorkspaces((current) => {
|
|
1453
|
+
const retained = current[key];
|
|
1454
|
+
if (!retained) return current;
|
|
1455
|
+
return {
|
|
1456
|
+
...current,
|
|
1457
|
+
[key]: {
|
|
1458
|
+
...retained,
|
|
1459
|
+
error: fresh.collectionError,
|
|
1460
|
+
...allMatching ? { sourceStale: changed } : changed ? { pending: { ...fresh, scope: retained.scope } } : { pending: void 0 }
|
|
1461
|
+
}
|
|
1462
|
+
};
|
|
1463
|
+
});
|
|
1464
|
+
setWorkspaceKey(key);
|
|
1465
|
+
setWorkspaceOpen(true);
|
|
1466
|
+
} catch (error) {
|
|
1467
|
+
if (fence.valid(id, controller) && workspaceCaptures.current.has(key)) {
|
|
1468
|
+
setWorkspaces(
|
|
1469
|
+
(current) => current[key] ? {
|
|
1470
|
+
...current,
|
|
1471
|
+
[key]: {
|
|
1472
|
+
...current[key],
|
|
1473
|
+
error: errorMessage(error, "Could not refresh source")
|
|
1474
|
+
}
|
|
1475
|
+
} : current
|
|
1476
|
+
);
|
|
1477
|
+
setWorkspaceKey(key);
|
|
1478
|
+
setWorkspaceOpen(true);
|
|
1479
|
+
}
|
|
1480
|
+
} finally {
|
|
1481
|
+
fence.finish(controller);
|
|
1482
|
+
}
|
|
1483
|
+
return;
|
|
1484
|
+
}
|
|
1485
|
+
try {
|
|
1486
|
+
const result = await captureWorkspace(initialScope, controller.signal);
|
|
1487
|
+
if (!fence.valid(id, controller)) return;
|
|
1488
|
+
const resolved = resolveTransferPreferences(
|
|
1489
|
+
providerPreferences,
|
|
1490
|
+
preferences,
|
|
1491
|
+
result.snapshot.limits
|
|
1492
|
+
);
|
|
1493
|
+
const original = createDraft(result.snapshot);
|
|
1494
|
+
const base = {
|
|
1495
|
+
...result,
|
|
1496
|
+
key,
|
|
1497
|
+
original,
|
|
1498
|
+
draft: original,
|
|
1499
|
+
scope: initialScope,
|
|
1500
|
+
preferences: resolved,
|
|
1501
|
+
...result.collectionError ? { error: result.collectionError } : {}
|
|
1502
|
+
};
|
|
1503
|
+
setWorkspaces((current) => ({
|
|
1504
|
+
...current,
|
|
1505
|
+
[key]: { ...base, draft: rebuild(base, initialControls(base)) }
|
|
1506
|
+
}));
|
|
1507
|
+
setWorkspaceKey(key);
|
|
1508
|
+
setWorkspaceOpen(true);
|
|
1509
|
+
} catch (error) {
|
|
1510
|
+
if (fence.valid(id, controller))
|
|
1511
|
+
setNotice(errorMessage(error, "Could not capture content"));
|
|
1512
|
+
} finally {
|
|
1513
|
+
fence.finish(controller);
|
|
1514
|
+
}
|
|
1515
|
+
},
|
|
1516
|
+
[
|
|
1517
|
+
captureOne,
|
|
1518
|
+
capturePrimary,
|
|
1519
|
+
fence,
|
|
1520
|
+
initialScope,
|
|
1521
|
+
preferences,
|
|
1522
|
+
primaryWorkspaceKey,
|
|
1523
|
+
primary,
|
|
1524
|
+
providerPreferences,
|
|
1525
|
+
workspaces
|
|
1526
|
+
]
|
|
1527
|
+
);
|
|
1423
1528
|
React8.useImperativeHandle(controllerRef, () => ({
|
|
1424
1529
|
focusTrigger: () => triggerRef.current?.focus(),
|
|
1425
1530
|
prepare: async (requestedSource, options) => {
|
|
@@ -1562,6 +1667,9 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1562
1667
|
const [instruction, setInstruction] = React8.useState("");
|
|
1563
1668
|
const [busy, setBusy] = React8.useState(null);
|
|
1564
1669
|
const [aiFailed, setAiFailed] = React8.useState(false);
|
|
1670
|
+
React8.useEffect(() => {
|
|
1671
|
+
setAiFailed(false);
|
|
1672
|
+
}, [state.snapshot.id, state.draft.revision]);
|
|
1565
1673
|
const activeAi = React8.useRef(null);
|
|
1566
1674
|
const activeCapture = React8.useRef(null);
|
|
1567
1675
|
React8.useEffect(() => {
|
|
@@ -1639,7 +1747,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1639
1747
|
setBusy("capture");
|
|
1640
1748
|
try {
|
|
1641
1749
|
const result = await captureScope(scope, controller.signal);
|
|
1642
|
-
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, error: result.collectionError });
|
|
1750
|
+
if (fence.valid(id, controller) && latest.current.draft.revision === revision) onChange({ ...latest.current, pending: { ...result, scope }, sourceStale: false, error: result.collectionError });
|
|
1643
1751
|
} catch (error) {
|
|
1644
1752
|
if (fence.valid(id, controller)) onChange({ ...latest.current, error: errorMessage(error, "Refresh failed") });
|
|
1645
1753
|
} finally {
|
|
@@ -1872,7 +1980,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1872
1980
|
activeCapture.current = null;
|
|
1873
1981
|
setBusy(null);
|
|
1874
1982
|
}, children: "Stop loading rows" }) : null,
|
|
1875
|
-
ai && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
1983
|
+
ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
|
|
1876
1984
|
ai ? /* @__PURE__ */ jsx8("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
|
|
1877
1985
|
state.error ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
|
|
1878
1986
|
] }) : null
|
|
@@ -1882,6 +1990,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
|
|
|
1882
1990
|
/* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => setPendingControls(null), children: "Keep edited draft" }),
|
|
1883
1991
|
/* @__PURE__ */ jsx8(Button, { type: "button", onClick: applyPendingControls, children: "Rebuild from source" })
|
|
1884
1992
|
] }) : null,
|
|
1993
|
+
state.sourceStale ? /* @__PURE__ */ jsx8("p", { role: "alert", className: "matrx-alchemy-decision", children: "The source changed since this draft. Use Refresh source to review the latest data." }) : null,
|
|
1885
1994
|
state.pending ? /* @__PURE__ */ jsxs5("div", { className: "matrx-alchemy-decision", role: "alert", children: [
|
|
1886
1995
|
/* @__PURE__ */ jsx8("p", { children: "A fresh source snapshot is ready." }),
|
|
1887
1996
|
/* @__PURE__ */ jsx8(Button, { type: "button", variant: "outline", onClick: () => resolveCapture("keep"), children: "Keep current snapshot and draft" }),
|