@datarecce/ui 0.1.40 → 0.1.41
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/dist/api.d.mts +1 -1
- package/dist/{components-DTLQ2djq.js → components-DfXnN1Hx.js} +592 -13
- package/dist/components-DfXnN1Hx.js.map +1 -0
- package/dist/{components-B6oaPB5f.mjs → components-jh6r4tQn.mjs} +593 -14
- package/dist/components-jh6r4tQn.mjs.map +1 -0
- package/dist/components.d.mts +1 -1
- package/dist/components.js +1 -1
- package/dist/components.mjs +1 -1
- package/dist/hooks.d.mts +1 -1
- package/dist/{index-CbF0x3kW.d.mts → index-B5bpmv0i.d.mts} +70 -70
- package/dist/{index-CbF0x3kW.d.mts.map → index-B5bpmv0i.d.mts.map} +1 -1
- package/dist/index-B9lSPJTi.d.ts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/theme.d.mts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +1 -1
- package/recce-source/docs/plans/2024-12-31-csv-download-design.md +121 -0
- package/recce-source/docs/plans/2024-12-31-csv-download-implementation.md +930 -0
- package/recce-source/js/src/components/run/RunResultPane.tsx +138 -14
- package/recce-source/js/src/lib/csv/extractors.test.ts +456 -0
- package/recce-source/js/src/lib/csv/extractors.ts +468 -0
- package/recce-source/js/src/lib/csv/format.test.ts +211 -0
- package/recce-source/js/src/lib/csv/format.ts +44 -0
- package/recce-source/js/src/lib/csv/index.test.ts +155 -0
- package/recce-source/js/src/lib/csv/index.ts +109 -0
- package/recce-source/js/src/lib/hooks/useCSVExport.ts +136 -0
- package/recce-source/recce/mcp_server.py +54 -30
- package/recce-source/recce/models/check.py +10 -2
- package/dist/components-B6oaPB5f.mjs.map +0 -1
- package/dist/components-DTLQ2djq.js.map +0 -1
package/dist/api.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { $i as getLineageDiff, $r as ValueDiffDetailViewOptions, A as connectToCloud, Ai as getRun, B as submitQueryBase, Bi as getCll, C as SchemaDiffViewParams, Ci as TopKResult, D as markOnboardingCompleted, Di as SubmitRunTrackProps, E as getServerFlag, Ei as SubmitOptions, F as QueryPreviewChangeParams, Fi as waitRun, Gi as LineageDiffResult, Hi as LineageData, I as QueryResult, Ii as CllInput, Ji as NodeColumnData, Ki as ManifestMetadata, L as QueryRunParams, Li as CllNodeData, M as QueryDiffResult, Mi as searchRuns, N as QueryDiffViewOptions, Ni as submitRun, O as markRelaunchHintCompleted, Oi as aggregateRuns, P as QueryParams, Pi as submitRunFromCheck, Qi as getLineage, Qr as ValueDiffDetailResult, R as QueryViewOptions, Ri as ColumnLineageData, S as select, Si as TopKDiffResult, T as RecceServerFlags, Ti as RunsAggregated, Ui as LineageDataFromMetadata, V as submitQueryDiff, Vi as CatalogMetadata, Wi as LineageDiffData, Xi as SQLMeshInfo, Yi as NodeData, Zi as ServerInfoResult, Zr as ValueDiffDetailParams, _ as saveAs, _i as HistogramResult, _r as reorderChecks, a as User, aa as stateMetadata, ai as RowCountDiffResult, b as SelectInput, bi as ProfileDiffViewOptions, c as ImportedState, ci as submitRowCountDiff, cr as createLineageDiffCheck, d as SyncStateInput, di as RowCountDiff, dr as createCheckByRun, ea as getLineageWithError, ei as ValueDiffParams, f as SyncStateResponse, fi as fetchModelRowCount, fr as createSimpleCheck, g as rename, ga as reactQueryClient, gi as HistogramDiffResult, gr as markAsPresetCheck, h as isStateSyncing, ha as axiosClient, hi as HistogramDiffParams, hr as listChecks, i as useVersionNumber, ia as pullRequestInfo, ii as RowCountDiffParams, j as QueryDiffParams, ji as listRuns, k as ConnectToCloud, ki as cancelRun, l as SaveAsInput, li as QueryRowCountResult, lr as Check, m as importState, mi as queryRowCount, mr as getCheck, n as localStorageKeys, na as getServerInfo, ni as submitValueDiff, o as fetchGitHubAvatar, oi as RowCountParams, p as exportState, pi as queryModelRowCount, pr as deleteCheck, qi as ModelInfoResult, r as getVersion, ra as gitInfo, ri as submitValueDiffDetail, s as fetchUser, si as RowCountResult, sr as LineageDiffViewOptions, t as sessionStorageKeys, ta as getModelInfo, ti as ValueDiffResult, u as ShareStateResponse, ui as RowCount, ur as CreateCheckBody, v as shareState, vi as ProfileDiffParams, vr as updateCheck, w as createSchemaDiffCheck, wi as submitProfileDiff, x as SelectOutput, xi as TopKDiffParams, y as syncState, yi as ProfileDiffResult, yr as useChecks, z as submitQuery, zi as ImpactRadiusParams } from "./index-
|
|
2
|
+
import { $i as getLineageDiff, $r as ValueDiffDetailViewOptions, A as connectToCloud, Ai as getRun, B as submitQueryBase, Bi as getCll, C as SchemaDiffViewParams, Ci as TopKResult, D as markOnboardingCompleted, Di as SubmitRunTrackProps, E as getServerFlag, Ei as SubmitOptions, F as QueryPreviewChangeParams, Fi as waitRun, Gi as LineageDiffResult, Hi as LineageData, I as QueryResult, Ii as CllInput, Ji as NodeColumnData, Ki as ManifestMetadata, L as QueryRunParams, Li as CllNodeData, M as QueryDiffResult, Mi as searchRuns, N as QueryDiffViewOptions, Ni as submitRun, O as markRelaunchHintCompleted, Oi as aggregateRuns, P as QueryParams, Pi as submitRunFromCheck, Qi as getLineage, Qr as ValueDiffDetailResult, R as QueryViewOptions, Ri as ColumnLineageData, S as select, Si as TopKDiffResult, T as RecceServerFlags, Ti as RunsAggregated, Ui as LineageDataFromMetadata, V as submitQueryDiff, Vi as CatalogMetadata, Wi as LineageDiffData, Xi as SQLMeshInfo, Yi as NodeData, Zi as ServerInfoResult, Zr as ValueDiffDetailParams, _ as saveAs, _i as HistogramResult, _r as reorderChecks, a as User, aa as stateMetadata, ai as RowCountDiffResult, b as SelectInput, bi as ProfileDiffViewOptions, c as ImportedState, ci as submitRowCountDiff, cr as createLineageDiffCheck, d as SyncStateInput, di as RowCountDiff, dr as createCheckByRun, ea as getLineageWithError, ei as ValueDiffParams, f as SyncStateResponse, fi as fetchModelRowCount, fr as createSimpleCheck, g as rename, ga as reactQueryClient, gi as HistogramDiffResult, gr as markAsPresetCheck, h as isStateSyncing, ha as axiosClient, hi as HistogramDiffParams, hr as listChecks, i as useVersionNumber, ia as pullRequestInfo, ii as RowCountDiffParams, j as QueryDiffParams, ji as listRuns, k as ConnectToCloud, ki as cancelRun, l as SaveAsInput, li as QueryRowCountResult, lr as Check, m as importState, mi as queryRowCount, mr as getCheck, n as localStorageKeys, na as getServerInfo, ni as submitValueDiff, o as fetchGitHubAvatar, oi as RowCountParams, p as exportState, pi as queryModelRowCount, pr as deleteCheck, qi as ModelInfoResult, r as getVersion, ra as gitInfo, ri as submitValueDiffDetail, s as fetchUser, si as RowCountResult, sr as LineageDiffViewOptions, t as sessionStorageKeys, ta as getModelInfo, ti as ValueDiffResult, u as ShareStateResponse, ui as RowCount, ur as CreateCheckBody, v as shareState, vi as ProfileDiffParams, vr as updateCheck, w as createSchemaDiffCheck, wi as submitProfileDiff, x as SelectOutput, xi as TopKDiffParams, y as syncState, yi as ProfileDiffResult, yr as useChecks, z as submitQuery, zi as ImpactRadiusParams } from "./index-B5bpmv0i.mjs";
|
|
3
3
|
export { CatalogMetadata, Check, CllInput, CllNodeData, ColumnLineageData, ConnectToCloud, CreateCheckBody, HistogramDiffParams, HistogramDiffResult, HistogramResult, ImpactRadiusParams, ImportedState, LineageData, LineageDataFromMetadata, LineageDiffData, LineageDiffResult, LineageDiffViewOptions, ManifestMetadata, ModelInfoResult, NodeColumnData, NodeData, ProfileDiffParams, ProfileDiffResult, ProfileDiffViewOptions, QueryDiffParams, QueryDiffResult, QueryDiffViewOptions, QueryParams, QueryPreviewChangeParams, QueryResult, QueryRowCountResult, QueryRunParams, QueryViewOptions, RecceServerFlags, RowCount, RowCountDiff, RowCountDiffParams, RowCountDiffResult, RowCountParams, RowCountResult, RunsAggregated, SQLMeshInfo, SaveAsInput, SchemaDiffViewParams, SelectInput, SelectOutput, ServerInfoResult, ShareStateResponse, SubmitOptions, SubmitRunTrackProps, SyncStateInput, SyncStateResponse, TopKDiffParams, TopKDiffResult, TopKResult, User, ValueDiffDetailParams, ValueDiffDetailResult, ValueDiffDetailViewOptions, ValueDiffParams, ValueDiffResult, aggregateRuns, axiosClient, cancelRun, connectToCloud, createCheckByRun, createLineageDiffCheck, createSchemaDiffCheck, createSimpleCheck, deleteCheck, exportState, fetchGitHubAvatar, fetchModelRowCount, fetchUser, getCheck, getCll, getLineage, getLineageDiff, getLineageWithError, getModelInfo, getRun, getServerFlag, getServerInfo, getVersion, gitInfo, importState, isStateSyncing, listChecks, listRuns, localStorageKeys, markAsPresetCheck, markOnboardingCompleted, markRelaunchHintCompleted, pullRequestInfo, queryModelRowCount, queryRowCount, reactQueryClient, rename, reorderChecks, saveAs, searchRuns, select, sessionStorageKeys, shareState, stateMetadata, submitProfileDiff, submitQuery, submitQueryBase, submitQueryDiff, submitRowCountDiff, submitRun, submitRunFromCheck, submitValueDiff, submitValueDiffDetail, syncState, updateCheck, useChecks, useVersionNumber, waitRun };
|
|
@@ -6496,6 +6496,512 @@ function AuthModal({ handleParentClose, parentOpen = false, ignoreCookie = false
|
|
|
6496
6496
|
});
|
|
6497
6497
|
}
|
|
6498
6498
|
|
|
6499
|
+
//#endregion
|
|
6500
|
+
//#region recce-source/js/src/lib/csv/format.ts
|
|
6501
|
+
/**
|
|
6502
|
+
* CSV formatting utilities with Excel-friendly output
|
|
6503
|
+
*/
|
|
6504
|
+
/**
|
|
6505
|
+
* Escape a value for CSV format
|
|
6506
|
+
* - Wrap in quotes if contains comma, quote, or newline
|
|
6507
|
+
* - Escape quotes by doubling them
|
|
6508
|
+
*/
|
|
6509
|
+
function escapeCSVValue(value) {
|
|
6510
|
+
if (value === null || value === void 0) return "";
|
|
6511
|
+
const stringValue = typeof value === "object" ? JSON.stringify(value) : String(value);
|
|
6512
|
+
if (stringValue.includes(",") || stringValue.includes("\"") || stringValue.includes("\n") || stringValue.includes("\r")) return `"${stringValue.replace(/"/g, "\"\"")}"`;
|
|
6513
|
+
return stringValue;
|
|
6514
|
+
}
|
|
6515
|
+
/**
|
|
6516
|
+
* Convert tabular data to CSV string
|
|
6517
|
+
* @param columns - Column headers
|
|
6518
|
+
* @param rows - Row data (array of arrays)
|
|
6519
|
+
* @returns CSV string with UTF-8 BOM for Excel compatibility
|
|
6520
|
+
*/
|
|
6521
|
+
function toCSV(columns, rows) {
|
|
6522
|
+
return "" + [columns.map(escapeCSVValue).join(","), ...rows.map((row) => row.map(escapeCSVValue).join(","))].join("\r\n");
|
|
6523
|
+
}
|
|
6524
|
+
|
|
6525
|
+
//#endregion
|
|
6526
|
+
//#region recce-source/js/src/lib/csv/extractors.ts
|
|
6527
|
+
/**
|
|
6528
|
+
* Format a cell value for inline diff mode
|
|
6529
|
+
* If base and current are the same, return the value
|
|
6530
|
+
* If different, return "(base_value) (current_value)"
|
|
6531
|
+
*/
|
|
6532
|
+
function formatInlineDiffCell(baseValue, currentValue) {
|
|
6533
|
+
if ((baseValue == null ? "" : String(baseValue)) === (currentValue == null ? "" : String(currentValue))) return baseValue;
|
|
6534
|
+
return `${baseValue == null ? "" : `(${baseValue})`} ${currentValue == null ? "" : `(${currentValue})`}`.trim();
|
|
6535
|
+
}
|
|
6536
|
+
/**
|
|
6537
|
+
* Extract columns and rows from a DataFrame
|
|
6538
|
+
*/
|
|
6539
|
+
function extractDataFrame(df) {
|
|
6540
|
+
if (!df || !df.columns || !df.data) return null;
|
|
6541
|
+
return {
|
|
6542
|
+
columns: df.columns.map((col) => col.name),
|
|
6543
|
+
rows: df.data.map((row) => [...row])
|
|
6544
|
+
};
|
|
6545
|
+
}
|
|
6546
|
+
/**
|
|
6547
|
+
* Extract CSV data from query result (single environment)
|
|
6548
|
+
*/
|
|
6549
|
+
function extractQuery(result) {
|
|
6550
|
+
return extractDataFrame(result);
|
|
6551
|
+
}
|
|
6552
|
+
/**
|
|
6553
|
+
* Extract CSV data from query_base result
|
|
6554
|
+
*/
|
|
6555
|
+
function extractQueryBase(result) {
|
|
6556
|
+
return extractDataFrame(result);
|
|
6557
|
+
}
|
|
6558
|
+
/**
|
|
6559
|
+
* Extract CSV data from query_diff result
|
|
6560
|
+
* Supports two result shapes:
|
|
6561
|
+
* 1. { diff: DataFrame } - joined diff result (QueryDiffJoinResultView)
|
|
6562
|
+
* 2. { base: DataFrame, current: DataFrame } - separate base/current (QueryDiffResultView)
|
|
6563
|
+
*
|
|
6564
|
+
* Display modes:
|
|
6565
|
+
* - "inline": Merged rows where same values shown as-is, differing values shown as "(base) (current)"
|
|
6566
|
+
* - "side_by_side": Single row per record with base__col, current__col columns
|
|
6567
|
+
*
|
|
6568
|
+
* Note: When base and current have different row counts (e.g., added/removed rows),
|
|
6569
|
+
* the merge is done positionally. Extra rows will show null for the missing environment.
|
|
6570
|
+
*/
|
|
6571
|
+
function extractQueryDiff(result, options) {
|
|
6572
|
+
const typed = result;
|
|
6573
|
+
const displayMode = options?.displayMode ?? "inline";
|
|
6574
|
+
const primaryKeys = options?.primaryKeys ?? [];
|
|
6575
|
+
if (typed?.diff) return extractQueryDiffJoined(typed.diff, displayMode, primaryKeys);
|
|
6576
|
+
return extractQueryDiffSeparate(typed, displayMode);
|
|
6577
|
+
}
|
|
6578
|
+
/**
|
|
6579
|
+
* Extract CSV from joined diff DataFrame (QueryDiffJoinResultView)
|
|
6580
|
+
* The diff DataFrame has columns like: pk, col1, col2, in_a, in_b
|
|
6581
|
+
* where in_a/in_b indicate presence in base/current
|
|
6582
|
+
*
|
|
6583
|
+
* The DataFrame may have separate rows for base (in_a=true) and current (in_b=true)
|
|
6584
|
+
* records. This function groups them by primary key and merges into single output rows.
|
|
6585
|
+
*
|
|
6586
|
+
* Produces same layout as extractQueryDiffSeparate for consistency.
|
|
6587
|
+
*/
|
|
6588
|
+
function extractQueryDiffJoined(diff, displayMode, primaryKeys) {
|
|
6589
|
+
if (!diff?.columns || !diff?.data) return null;
|
|
6590
|
+
const inAIndex = diff.columns.findIndex((col) => col.key.toLowerCase() === "in_a");
|
|
6591
|
+
const inBIndex = diff.columns.findIndex((col) => col.key.toLowerCase() === "in_b");
|
|
6592
|
+
const dataColumns = diff.columns.filter((col) => col.key.toLowerCase() !== "in_a" && col.key.toLowerCase() !== "in_b");
|
|
6593
|
+
const dataColumnNames = dataColumns.map((col) => col.name);
|
|
6594
|
+
const dataColumnIndices = dataColumns.map((col) => diff.columns.findIndex((c) => c.key === col.key));
|
|
6595
|
+
const pkIndices = primaryKeys.map((pk) => diff.columns.findIndex((col) => col.key === pk)).filter((idx) => idx >= 0);
|
|
6596
|
+
const extractRowValues = (rowData) => {
|
|
6597
|
+
return dataColumnIndices.map((colIndex) => rowData[colIndex]);
|
|
6598
|
+
};
|
|
6599
|
+
const getPrimaryKeyValue = (rowData) => {
|
|
6600
|
+
if (pkIndices.length === 0) return "";
|
|
6601
|
+
return pkIndices.map((idx) => String(rowData[idx] ?? "")).join("|||");
|
|
6602
|
+
};
|
|
6603
|
+
const groupedRows = /* @__PURE__ */ new Map();
|
|
6604
|
+
const rowOrder = [];
|
|
6605
|
+
diff.data.forEach((rowData, index) => {
|
|
6606
|
+
const inA = inAIndex >= 0 ? rowData[inAIndex] : true;
|
|
6607
|
+
const inB = inBIndex >= 0 ? rowData[inBIndex] : true;
|
|
6608
|
+
let pkValue = getPrimaryKeyValue(rowData);
|
|
6609
|
+
if (pkValue === "") pkValue = String(index);
|
|
6610
|
+
if (!groupedRows.has(pkValue)) {
|
|
6611
|
+
groupedRows.set(pkValue, {
|
|
6612
|
+
base: null,
|
|
6613
|
+
current: null
|
|
6614
|
+
});
|
|
6615
|
+
rowOrder.push(pkValue);
|
|
6616
|
+
}
|
|
6617
|
+
const group = groupedRows.get(pkValue);
|
|
6618
|
+
if (!group) return;
|
|
6619
|
+
const values = extractRowValues(rowData);
|
|
6620
|
+
if (inA) group.base = values;
|
|
6621
|
+
if (inB) group.current = values;
|
|
6622
|
+
});
|
|
6623
|
+
if (displayMode === "side_by_side") {
|
|
6624
|
+
const columns$1 = [];
|
|
6625
|
+
dataColumnNames.forEach((name) => {
|
|
6626
|
+
columns$1.push(`base__${name}`, `current__${name}`);
|
|
6627
|
+
});
|
|
6628
|
+
const rows$1 = [];
|
|
6629
|
+
for (const pkValue of rowOrder) {
|
|
6630
|
+
const group = groupedRows.get(pkValue);
|
|
6631
|
+
if (!group) continue;
|
|
6632
|
+
const baseValues = group.base;
|
|
6633
|
+
const currentValues = group.current;
|
|
6634
|
+
const row = [];
|
|
6635
|
+
dataColumnNames.forEach((_$1, colIndex) => {
|
|
6636
|
+
row.push(baseValues ? baseValues[colIndex] : null);
|
|
6637
|
+
row.push(currentValues ? currentValues[colIndex] : null);
|
|
6638
|
+
});
|
|
6639
|
+
rows$1.push(row);
|
|
6640
|
+
}
|
|
6641
|
+
return {
|
|
6642
|
+
columns: columns$1,
|
|
6643
|
+
rows: rows$1
|
|
6644
|
+
};
|
|
6645
|
+
}
|
|
6646
|
+
const columns = [...dataColumnNames];
|
|
6647
|
+
const rows = [];
|
|
6648
|
+
for (const pkValue of rowOrder) {
|
|
6649
|
+
const group = groupedRows.get(pkValue);
|
|
6650
|
+
if (!group) continue;
|
|
6651
|
+
const baseValues = group.base;
|
|
6652
|
+
const currentValues = group.current;
|
|
6653
|
+
const row = [];
|
|
6654
|
+
dataColumnNames.forEach((_$1, colIndex) => {
|
|
6655
|
+
const baseVal = baseValues ? baseValues[colIndex] : null;
|
|
6656
|
+
const currentVal = currentValues ? currentValues[colIndex] : null;
|
|
6657
|
+
row.push(formatInlineDiffCell(baseVal, currentVal));
|
|
6658
|
+
});
|
|
6659
|
+
rows.push(row);
|
|
6660
|
+
}
|
|
6661
|
+
return {
|
|
6662
|
+
columns,
|
|
6663
|
+
rows
|
|
6664
|
+
};
|
|
6665
|
+
}
|
|
6666
|
+
/**
|
|
6667
|
+
* Extract CSV from separate base/current DataFrames (QueryDiffResultView)
|
|
6668
|
+
*/
|
|
6669
|
+
function extractQueryDiffSeparate(typed, displayMode) {
|
|
6670
|
+
const df = typed?.current || typed?.base;
|
|
6671
|
+
if (!df) return null;
|
|
6672
|
+
if (!typed?.base || !typed?.current) return extractDataFrame(df);
|
|
6673
|
+
const columnNames = typed.current.columns.map((c) => c.name);
|
|
6674
|
+
if (displayMode === "side_by_side") {
|
|
6675
|
+
const columns$1 = [];
|
|
6676
|
+
columnNames.forEach((name) => {
|
|
6677
|
+
columns$1.push(`base__${name}`, `current__${name}`);
|
|
6678
|
+
});
|
|
6679
|
+
const rows$1 = [];
|
|
6680
|
+
const maxRows$1 = Math.max(typed.base.data.length, typed.current.data.length);
|
|
6681
|
+
for (let i = 0; i < maxRows$1; i++) {
|
|
6682
|
+
const row = [];
|
|
6683
|
+
const baseRow = i < typed.base.data.length ? typed.base.data[i] : null;
|
|
6684
|
+
const currentRow = i < typed.current.data.length ? typed.current.data[i] : null;
|
|
6685
|
+
columnNames.forEach((_$1, colIndex) => {
|
|
6686
|
+
row.push(baseRow ? baseRow[colIndex] : null);
|
|
6687
|
+
row.push(currentRow ? currentRow[colIndex] : null);
|
|
6688
|
+
});
|
|
6689
|
+
rows$1.push(row);
|
|
6690
|
+
}
|
|
6691
|
+
return {
|
|
6692
|
+
columns: columns$1,
|
|
6693
|
+
rows: rows$1
|
|
6694
|
+
};
|
|
6695
|
+
}
|
|
6696
|
+
const columns = [...columnNames];
|
|
6697
|
+
const rows = [];
|
|
6698
|
+
const maxRows = Math.max(typed.base.data.length, typed.current.data.length);
|
|
6699
|
+
for (let i = 0; i < maxRows; i++) {
|
|
6700
|
+
const baseRow = i < typed.base.data.length ? typed.base.data[i] : null;
|
|
6701
|
+
const currentRow = i < typed.current.data.length ? typed.current.data[i] : null;
|
|
6702
|
+
const row = [];
|
|
6703
|
+
columnNames.forEach((_$1, colIndex) => {
|
|
6704
|
+
const baseVal = baseRow ? baseRow[colIndex] : null;
|
|
6705
|
+
const currentVal = currentRow ? currentRow[colIndex] : null;
|
|
6706
|
+
row.push(formatInlineDiffCell(baseVal, currentVal));
|
|
6707
|
+
});
|
|
6708
|
+
rows.push(row);
|
|
6709
|
+
}
|
|
6710
|
+
return {
|
|
6711
|
+
columns,
|
|
6712
|
+
rows
|
|
6713
|
+
};
|
|
6714
|
+
}
|
|
6715
|
+
/**
|
|
6716
|
+
* Extract CSV data from profile_diff result
|
|
6717
|
+
*/
|
|
6718
|
+
function extractProfileDiff(result) {
|
|
6719
|
+
const typed = result;
|
|
6720
|
+
const df = typed?.current || typed?.base;
|
|
6721
|
+
if (!df) return null;
|
|
6722
|
+
if (typed?.base && typed?.current) {
|
|
6723
|
+
const columns = ["_source", ...typed.current.columns.map((c) => c.name)];
|
|
6724
|
+
const rows = [];
|
|
6725
|
+
typed.base.data.forEach((row) => {
|
|
6726
|
+
rows.push(["base", ...row]);
|
|
6727
|
+
});
|
|
6728
|
+
typed.current.data.forEach((row) => {
|
|
6729
|
+
rows.push(["current", ...row]);
|
|
6730
|
+
});
|
|
6731
|
+
return {
|
|
6732
|
+
columns,
|
|
6733
|
+
rows
|
|
6734
|
+
};
|
|
6735
|
+
}
|
|
6736
|
+
return extractDataFrame(df);
|
|
6737
|
+
}
|
|
6738
|
+
/**
|
|
6739
|
+
* Extract CSV data from row_count_diff result
|
|
6740
|
+
*/
|
|
6741
|
+
function extractRowCountDiff(result) {
|
|
6742
|
+
const typed = result;
|
|
6743
|
+
if (!typed || typeof typed !== "object") return null;
|
|
6744
|
+
const columns = [
|
|
6745
|
+
"node",
|
|
6746
|
+
"base_count",
|
|
6747
|
+
"current_count",
|
|
6748
|
+
"diff",
|
|
6749
|
+
"diff_percent"
|
|
6750
|
+
];
|
|
6751
|
+
const rows = [];
|
|
6752
|
+
for (const [nodeName, counts] of Object.entries(typed)) if (counts && typeof counts === "object") {
|
|
6753
|
+
const base = counts.base;
|
|
6754
|
+
const current = counts.curr;
|
|
6755
|
+
const diff = base != null && current != null ? current - base : null;
|
|
6756
|
+
const diffPercent = base && diff !== null ? (diff / base * 100).toFixed(2) + "%" : null;
|
|
6757
|
+
rows.push([
|
|
6758
|
+
nodeName,
|
|
6759
|
+
base,
|
|
6760
|
+
current,
|
|
6761
|
+
diff,
|
|
6762
|
+
diffPercent
|
|
6763
|
+
]);
|
|
6764
|
+
}
|
|
6765
|
+
return {
|
|
6766
|
+
columns,
|
|
6767
|
+
rows
|
|
6768
|
+
};
|
|
6769
|
+
}
|
|
6770
|
+
/**
|
|
6771
|
+
* Extract CSV data from value_diff result
|
|
6772
|
+
*/
|
|
6773
|
+
function extractValueDiff(result) {
|
|
6774
|
+
const typed = result;
|
|
6775
|
+
if (!typed?.data) return null;
|
|
6776
|
+
return extractDataFrame(typed.data);
|
|
6777
|
+
}
|
|
6778
|
+
/**
|
|
6779
|
+
* Extract CSV data from value_diff_detail result
|
|
6780
|
+
*/
|
|
6781
|
+
function extractValueDiffDetail(result) {
|
|
6782
|
+
return extractDataFrame(result);
|
|
6783
|
+
}
|
|
6784
|
+
/**
|
|
6785
|
+
* Extract CSV data from top_k_diff result
|
|
6786
|
+
*/
|
|
6787
|
+
function extractTopKDiff(result) {
|
|
6788
|
+
const typed = result;
|
|
6789
|
+
const hasBaseValues = !!typed?.base?.values;
|
|
6790
|
+
const hasCurrentValues = !!typed?.current?.values;
|
|
6791
|
+
if (!hasBaseValues && !hasCurrentValues) return null;
|
|
6792
|
+
const columns = [
|
|
6793
|
+
"_source",
|
|
6794
|
+
"value",
|
|
6795
|
+
"count"
|
|
6796
|
+
];
|
|
6797
|
+
const rows = [];
|
|
6798
|
+
if (typed?.base?.values) typed.base.values.forEach((value, index) => {
|
|
6799
|
+
rows.push([
|
|
6800
|
+
"base",
|
|
6801
|
+
value,
|
|
6802
|
+
typed.base.counts[index]
|
|
6803
|
+
]);
|
|
6804
|
+
});
|
|
6805
|
+
if (typed?.current?.values) typed.current.values.forEach((value, index) => {
|
|
6806
|
+
rows.push([
|
|
6807
|
+
"current",
|
|
6808
|
+
value,
|
|
6809
|
+
typed.current.counts[index]
|
|
6810
|
+
]);
|
|
6811
|
+
});
|
|
6812
|
+
return {
|
|
6813
|
+
columns,
|
|
6814
|
+
rows
|
|
6815
|
+
};
|
|
6816
|
+
}
|
|
6817
|
+
/**
|
|
6818
|
+
* Map of run types to their extractor functions
|
|
6819
|
+
* Some extractors accept options (like query_diff for displayMode)
|
|
6820
|
+
*/
|
|
6821
|
+
const extractors = {
|
|
6822
|
+
query: extractQuery,
|
|
6823
|
+
query_base: extractQueryBase,
|
|
6824
|
+
query_diff: extractQueryDiff,
|
|
6825
|
+
profile: extractProfileDiff,
|
|
6826
|
+
profile_diff: extractProfileDiff,
|
|
6827
|
+
row_count: extractRowCountDiff,
|
|
6828
|
+
row_count_diff: extractRowCountDiff,
|
|
6829
|
+
value_diff: extractValueDiff,
|
|
6830
|
+
value_diff_detail: extractValueDiffDetail,
|
|
6831
|
+
top_k_diff: extractTopKDiff
|
|
6832
|
+
};
|
|
6833
|
+
/**
|
|
6834
|
+
* Extract CSV data from a run result
|
|
6835
|
+
* @param runType - The type of run (query, query_diff, etc.)
|
|
6836
|
+
* @param result - The run result data
|
|
6837
|
+
* @param options - Optional export options (e.g., displayMode for query_diff)
|
|
6838
|
+
* @returns CSVData or null if the run type doesn't support CSV export
|
|
6839
|
+
*/
|
|
6840
|
+
function extractCSVData(runType, result, options) {
|
|
6841
|
+
const extractor = extractors[runType];
|
|
6842
|
+
if (!extractor) return null;
|
|
6843
|
+
try {
|
|
6844
|
+
return extractor(result, options);
|
|
6845
|
+
} catch (error) {
|
|
6846
|
+
console.error(`Failed to extract CSV data for run type "${runType}":`, error);
|
|
6847
|
+
return null;
|
|
6848
|
+
}
|
|
6849
|
+
}
|
|
6850
|
+
/**
|
|
6851
|
+
* Check if a run type supports CSV export
|
|
6852
|
+
*/
|
|
6853
|
+
function supportsCSVExport(runType) {
|
|
6854
|
+
return runType in extractors;
|
|
6855
|
+
}
|
|
6856
|
+
|
|
6857
|
+
//#endregion
|
|
6858
|
+
//#region recce-source/js/src/lib/csv/index.ts
|
|
6859
|
+
/**
|
|
6860
|
+
* CSV export utilities
|
|
6861
|
+
*/
|
|
6862
|
+
/**
|
|
6863
|
+
* Trigger browser download of CSV file
|
|
6864
|
+
*/
|
|
6865
|
+
function downloadCSV(content, filename) {
|
|
6866
|
+
(0, file_saver.default)(new Blob([content], { type: "text/csv;charset=utf-8" }), filename);
|
|
6867
|
+
}
|
|
6868
|
+
/**
|
|
6869
|
+
* Copy CSV content to clipboard
|
|
6870
|
+
* Uses modern Clipboard API with fallback for older browsers
|
|
6871
|
+
*/
|
|
6872
|
+
async function copyCSVToClipboard(content) {
|
|
6873
|
+
if (typeof navigator !== "undefined" && navigator.clipboard && typeof navigator.clipboard.writeText === "function") {
|
|
6874
|
+
await navigator.clipboard.writeText(content);
|
|
6875
|
+
return;
|
|
6876
|
+
}
|
|
6877
|
+
if (typeof document === "undefined") throw new Error("Clipboard API not available in this environment");
|
|
6878
|
+
const textarea = document.createElement("textarea");
|
|
6879
|
+
textarea.value = content;
|
|
6880
|
+
textarea.style.position = "fixed";
|
|
6881
|
+
textarea.style.opacity = "0";
|
|
6882
|
+
textarea.setAttribute("readonly", "");
|
|
6883
|
+
document.body.appendChild(textarea);
|
|
6884
|
+
textarea.focus();
|
|
6885
|
+
textarea.select();
|
|
6886
|
+
try {
|
|
6887
|
+
if (!document.execCommand("copy")) throw new Error("execCommand('copy') failed");
|
|
6888
|
+
} finally {
|
|
6889
|
+
document.body.removeChild(textarea);
|
|
6890
|
+
}
|
|
6891
|
+
}
|
|
6892
|
+
/**
|
|
6893
|
+
* Generate timestamp string for filenames
|
|
6894
|
+
* Format: YYYYMMDD-HHmmss
|
|
6895
|
+
*/
|
|
6896
|
+
function generateTimestamp() {
|
|
6897
|
+
const now = /* @__PURE__ */ new Date();
|
|
6898
|
+
return `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")}-${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}${String(now.getSeconds()).padStart(2, "0")}`;
|
|
6899
|
+
}
|
|
6900
|
+
/**
|
|
6901
|
+
* Generate context-aware CSV filename
|
|
6902
|
+
*/
|
|
6903
|
+
function generateCSVFilename(runType, params) {
|
|
6904
|
+
const timestamp = generateTimestamp();
|
|
6905
|
+
const type = runType.replace(/_/g, "-");
|
|
6906
|
+
let nodeName;
|
|
6907
|
+
if (params?.node_names && Array.isArray(params.node_names) && params.node_names.length === 1) nodeName = String(params.node_names[0]);
|
|
6908
|
+
else if (params?.model && typeof params.model === "string") nodeName = params.model;
|
|
6909
|
+
if (nodeName) {
|
|
6910
|
+
nodeName = nodeName.replace(/[^a-zA-Z0-9_.-]/g, "-").toLowerCase();
|
|
6911
|
+
return `${type}-${nodeName}-${timestamp}.csv`;
|
|
6912
|
+
}
|
|
6913
|
+
return `${type}-result-${timestamp}.csv`;
|
|
6914
|
+
}
|
|
6915
|
+
|
|
6916
|
+
//#endregion
|
|
6917
|
+
//#region recce-source/js/src/lib/hooks/useCSVExport.ts
|
|
6918
|
+
/**
|
|
6919
|
+
* Hook for CSV export functionality
|
|
6920
|
+
*/
|
|
6921
|
+
function useCSVExport({ run, viewOptions }) {
|
|
6922
|
+
const canExportCSV = (0, react.useMemo)(() => {
|
|
6923
|
+
if (!run?.type || !run?.result) return false;
|
|
6924
|
+
return supportsCSVExport(run.type);
|
|
6925
|
+
}, [run?.type, run?.result]);
|
|
6926
|
+
const getCSVContent = (0, react.useCallback)(() => {
|
|
6927
|
+
if (!run?.type || !run?.result) return null;
|
|
6928
|
+
const exportOptions = {
|
|
6929
|
+
displayMode: viewOptions?.display_mode,
|
|
6930
|
+
primaryKeys: (run?.params)?.primary_keys
|
|
6931
|
+
};
|
|
6932
|
+
const csvData = extractCSVData(run.type, run.result, exportOptions);
|
|
6933
|
+
if (!csvData) return null;
|
|
6934
|
+
return toCSV(csvData.columns, csvData.rows);
|
|
6935
|
+
}, [
|
|
6936
|
+
run?.type,
|
|
6937
|
+
run?.result,
|
|
6938
|
+
run?.params,
|
|
6939
|
+
viewOptions
|
|
6940
|
+
]);
|
|
6941
|
+
return {
|
|
6942
|
+
canExportCSV,
|
|
6943
|
+
copyAsCSV: (0, react.useCallback)(async () => {
|
|
6944
|
+
const content = getCSVContent();
|
|
6945
|
+
if (!content) {
|
|
6946
|
+
require_RecceCheckContext.toaster.create({
|
|
6947
|
+
title: "Export failed",
|
|
6948
|
+
description: "Unable to extract data for CSV export",
|
|
6949
|
+
type: "error",
|
|
6950
|
+
duration: 3e3
|
|
6951
|
+
});
|
|
6952
|
+
return;
|
|
6953
|
+
}
|
|
6954
|
+
try {
|
|
6955
|
+
await copyCSVToClipboard(content);
|
|
6956
|
+
require_RecceCheckContext.toaster.create({
|
|
6957
|
+
title: "Copied to clipboard",
|
|
6958
|
+
description: "CSV data copied successfully",
|
|
6959
|
+
type: "success",
|
|
6960
|
+
duration: 2e3
|
|
6961
|
+
});
|
|
6962
|
+
} catch (error) {
|
|
6963
|
+
console.error("Failed to copy CSV to clipboard:", error);
|
|
6964
|
+
require_RecceCheckContext.toaster.create({
|
|
6965
|
+
title: "Copy failed",
|
|
6966
|
+
description: "Failed to copy to clipboard",
|
|
6967
|
+
type: "error",
|
|
6968
|
+
duration: 3e3
|
|
6969
|
+
});
|
|
6970
|
+
}
|
|
6971
|
+
}, [getCSVContent]),
|
|
6972
|
+
downloadAsCSV: (0, react.useCallback)(() => {
|
|
6973
|
+
const content = getCSVContent();
|
|
6974
|
+
if (!content) {
|
|
6975
|
+
require_RecceCheckContext.toaster.create({
|
|
6976
|
+
title: "Export failed",
|
|
6977
|
+
description: "Unable to extract data for CSV export",
|
|
6978
|
+
type: "error",
|
|
6979
|
+
duration: 3e3
|
|
6980
|
+
});
|
|
6981
|
+
return;
|
|
6982
|
+
}
|
|
6983
|
+
try {
|
|
6984
|
+
const filename = generateCSVFilename(run?.type ?? "", run?.params);
|
|
6985
|
+
downloadCSV(content, filename);
|
|
6986
|
+
require_RecceCheckContext.toaster.create({
|
|
6987
|
+
title: "Downloaded",
|
|
6988
|
+
description: filename,
|
|
6989
|
+
type: "success",
|
|
6990
|
+
duration: 3e3
|
|
6991
|
+
});
|
|
6992
|
+
} catch (error) {
|
|
6993
|
+
console.error("Failed to download CSV file:", error);
|
|
6994
|
+
require_RecceCheckContext.toaster.create({
|
|
6995
|
+
title: "Download failed",
|
|
6996
|
+
description: "Failed to download CSV file",
|
|
6997
|
+
type: "error",
|
|
6998
|
+
duration: 3e3
|
|
6999
|
+
});
|
|
7000
|
+
}
|
|
7001
|
+
}, [getCSVContent, run])
|
|
7002
|
+
};
|
|
7003
|
+
}
|
|
7004
|
+
|
|
6499
7005
|
//#endregion
|
|
6500
7006
|
//#region recce-source/js/src/components/query/SqlEditor.tsx
|
|
6501
7007
|
function SqlEditor({ value, onChange, onRun, onRunBase, onRunDiff, label, CustomEditor, options = {}, manifestData, schemas, ...props }) {
|
|
@@ -6890,12 +7396,71 @@ const SingleEnvironmentSetupNotification = ({ runType }) => {
|
|
|
6890
7396
|
default: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
6891
7397
|
}
|
|
6892
7398
|
};
|
|
6893
|
-
const
|
|
7399
|
+
const RunResultExportMenu = ({ run, viewOptions, disableExport, onCopyAsImage, onMouseEnter, onMouseLeave }) => {
|
|
7400
|
+
const [anchorEl, setAnchorEl] = (0, react.useState)(null);
|
|
7401
|
+
const open = Boolean(anchorEl);
|
|
7402
|
+
const { canExportCSV, copyAsCSV, downloadAsCSV } = useCSVExport({
|
|
7403
|
+
run,
|
|
7404
|
+
viewOptions
|
|
7405
|
+
});
|
|
7406
|
+
const handleClick = (event) => {
|
|
7407
|
+
setAnchorEl(event.currentTarget);
|
|
7408
|
+
};
|
|
7409
|
+
const handleClose = () => {
|
|
7410
|
+
setAnchorEl(null);
|
|
7411
|
+
};
|
|
7412
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Button.default, {
|
|
7413
|
+
size: "small",
|
|
7414
|
+
variant: "outlined",
|
|
7415
|
+
color: "neutral",
|
|
7416
|
+
onClick: handleClick,
|
|
7417
|
+
endIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiCaretDown, {}),
|
|
7418
|
+
sx: { textTransform: "none" },
|
|
7419
|
+
children: "Export"
|
|
7420
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_Menu.default, {
|
|
7421
|
+
anchorEl,
|
|
7422
|
+
open,
|
|
7423
|
+
onClose: handleClose,
|
|
7424
|
+
children: [
|
|
7425
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
7426
|
+
onClick: async () => {
|
|
7427
|
+
await onCopyAsImage();
|
|
7428
|
+
handleClose();
|
|
7429
|
+
},
|
|
7430
|
+
onMouseEnter,
|
|
7431
|
+
onMouseLeave,
|
|
7432
|
+
disabled: disableExport,
|
|
7433
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiImage, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Copy as Image" })]
|
|
7434
|
+
}),
|
|
7435
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
7436
|
+
onClick: async () => {
|
|
7437
|
+
await copyAsCSV();
|
|
7438
|
+
handleClose();
|
|
7439
|
+
},
|
|
7440
|
+
disabled: disableExport || !canExportCSV,
|
|
7441
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiTable, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Copy as CSV" })]
|
|
7442
|
+
}),
|
|
7443
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
7444
|
+
onClick: () => {
|
|
7445
|
+
downloadAsCSV();
|
|
7446
|
+
handleClose();
|
|
7447
|
+
},
|
|
7448
|
+
disabled: disableExport || !canExportCSV,
|
|
7449
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiDownloadSimple, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Download as CSV" })]
|
|
7450
|
+
})
|
|
7451
|
+
]
|
|
7452
|
+
})] });
|
|
7453
|
+
};
|
|
7454
|
+
const RunResultShareMenu = ({ run, viewOptions, disableCopyToClipboard, onCopyToClipboard, onMouseEnter, onMouseLeave }) => {
|
|
6894
7455
|
const { authed } = require_RecceCheckContext.useRecceInstanceContext();
|
|
6895
7456
|
const { handleShareClick } = require_RecceCheckContext.useRecceShareStateContext();
|
|
6896
7457
|
const [showModal, setShowModal] = (0, react.useState)(false);
|
|
6897
7458
|
const [anchorEl, setAnchorEl] = (0, react.useState)(null);
|
|
6898
7459
|
const open = Boolean(anchorEl);
|
|
7460
|
+
const { canExportCSV, copyAsCSV, downloadAsCSV } = useCSVExport({
|
|
7461
|
+
run,
|
|
7462
|
+
viewOptions
|
|
7463
|
+
});
|
|
6899
7464
|
const handleClick = (event) => {
|
|
6900
7465
|
setAnchorEl(event.currentTarget);
|
|
6901
7466
|
};
|
|
@@ -6925,7 +7490,23 @@ const RunResultShareMenu = ({ disableCopyToClipboard, onCopyToClipboard, onMouse
|
|
|
6925
7490
|
onMouseEnter,
|
|
6926
7491
|
onMouseLeave,
|
|
6927
7492
|
disabled: disableCopyToClipboard,
|
|
6928
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.
|
|
7493
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiImage, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Copy as Image" })]
|
|
7494
|
+
}),
|
|
7495
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
7496
|
+
onClick: async () => {
|
|
7497
|
+
await copyAsCSV();
|
|
7498
|
+
handleClose();
|
|
7499
|
+
},
|
|
7500
|
+
disabled: disableCopyToClipboard || !canExportCSV,
|
|
7501
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiTable, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Copy as CSV" })]
|
|
7502
|
+
}),
|
|
7503
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
7504
|
+
onClick: () => {
|
|
7505
|
+
downloadAsCSV();
|
|
7506
|
+
handleClose();
|
|
7507
|
+
},
|
|
7508
|
+
disabled: disableCopyToClipboard || !canExportCSV,
|
|
7509
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemIcon.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiDownloadSimple, {}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_ListItemText.default, { children: "Download as CSV" })]
|
|
6929
7510
|
}),
|
|
6930
7511
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material_Divider.default, {}),
|
|
6931
7512
|
authed ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material_MenuItem.default, {
|
|
@@ -7023,18 +7604,16 @@ const PrivateLoadableRunView = ({ runId, onClose, isSingleEnvironment }) => {
|
|
|
7023
7604
|
sx: { textTransform: "none" },
|
|
7024
7605
|
children: "Rerun"
|
|
7025
7606
|
}),
|
|
7026
|
-
featureToggles.disableShare ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
7027
|
-
|
|
7028
|
-
|
|
7029
|
-
|
|
7607
|
+
featureToggles.disableShare ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RunResultExportMenu, {
|
|
7608
|
+
run,
|
|
7609
|
+
viewOptions,
|
|
7610
|
+
disableExport: !runId || !run?.result || !!error || tabValue !== "result",
|
|
7611
|
+
onCopyAsImage: onCopyToClipboard,
|
|
7030
7612
|
onMouseEnter,
|
|
7031
|
-
onMouseLeave
|
|
7032
|
-
size: "small",
|
|
7033
|
-
onClick: onCopyToClipboard,
|
|
7034
|
-
startIcon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiCopy, {}),
|
|
7035
|
-
sx: { textTransform: "none" },
|
|
7036
|
-
children: "Copy to Clipboard"
|
|
7613
|
+
onMouseLeave
|
|
7037
7614
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RunResultShareMenu, {
|
|
7615
|
+
run,
|
|
7616
|
+
viewOptions,
|
|
7038
7617
|
disableCopyToClipboard,
|
|
7039
7618
|
onCopyToClipboard: async () => {
|
|
7040
7619
|
await onCopyToClipboard();
|
|
@@ -14107,4 +14686,4 @@ Object.defineProperty(exports, 'mui_provider_default', {
|
|
|
14107
14686
|
return mui_provider_default;
|
|
14108
14687
|
}
|
|
14109
14688
|
});
|
|
14110
|
-
//# sourceMappingURL=components-
|
|
14689
|
+
//# sourceMappingURL=components-DfXnN1Hx.js.map
|