fix(grid): preserve null clipboard metadata

This commit is contained in:
zipg authored and GitHub committed 2026-07-21 11:13:21 +08:00
1 parent 8632a0f261
commit c4052074b8
5 files changed
+138 -19

No files matched your search

@@ -7,6 +7,7 @@ import { useToast } from "@/composables/useToast";
import { displayCellValue, type CellValue } from "@/lib/dataGrid/cellValue";
import { tryStartExclusiveActivation, type ActionActivationGuard } from "@/lib/connection/actionActivation";
import { copyToClipboard } from "@/lib/common/clipboard";
import { clearDataGridClipboardCopy, rememberDataGridClipboardCopy } from "@/lib/dataGrid/dataGridClipboard";
import { buildDataGridCopyInsertStatement, buildDataGridCopyUpdateStatements, type DataGridCopyInsertMode, type DataGridTableMeta } from "@/lib/dataGrid/dataGridSql";
import { formatSqlInsert, formatTsv } from "@/lib/export/exportFormats";
import { uuid } from "@/lib/common/utils";
@@ -210,9 +211,12 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
} = options;
const selectedCellMatrix = selectedCellMatrixOption ?? computed<CellSelectionMatrix | null>(() => null);
async function copyText(text: string) {
async function copyText(text: string, gridCopy?: { rows: readonly (readonly unknown[])[]; includeHeader?: boolean }) {
const copiedRows = gridCopy?.rows.map((row) => [...row]);
clearDataGridClipboardCopy();
try {
await copyToClipboard(text);
if (copiedRows) rememberDataGridClipboardCopy(text, copiedRows, gridCopy?.includeHeader);
toast(t("grid.copied"));
} catch (e: any) {
toast(t("grid.copyFailed", { message: e?.message || String(e) }), 5000);
@@ -684,12 +688,14 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
// --- Selection copy functions ---
async function copySelectionTsv() {
if (!hasCellSelection.value) return;
await copyText(formatSelectionAsTsv(selectedCells.value));
const selection = selectedCells.value;
await copyText(formatSelectionAsTsv(selection), { rows: selection.rows });
}
async function copySelectionTsvWithHeaders() {
if (!hasCellSelection.value) return;
await copyText(formatSelectionAsTsv(selectedCells.value, true));
const selection = selectedCells.value;
await copyText(formatSelectionAsTsv(selection, true), { rows: selection.rows, includeHeader: true });
}
async function copySelectionCsv() {
@@ -711,14 +717,14 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
if (!hasRowSelection.value || selectedRowIds.value.size === 0) return;
const rows = displayItems.value.filter((item) => selectedRowIds.value.has(item.id) && !item.isDraft).map((item) => item.data);
if (rows.length === 0) return;
await copyText(formatSelectionAsTsv({ columns: columns.value, rows }));
await copyText(formatSelectionAsTsv({ columns: columns.value, rows }), { rows });
}
async function copySelectedRowsTsvWithHeaders() {
if (!hasRowSelection.value || selectedRowIds.value.size === 0) return;
const rows = displayItems.value.filter((item) => selectedRowIds.value.has(item.id) && !item.isDraft).map((item) => item.data);
if (rows.length === 0) return;
await copyText(formatSelectionAsTsv({ columns: columns.value, rows }, true));
await copyText(formatSelectionAsTsv({ columns: columns.value, rows }, true), { rows, includeHeader: true });
}
async function copyColumnNames() {
@@ -753,7 +759,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
const item = getRowItem(contextCell.value.rowId);
if (!item || item.isDraft) return;
const val = item?.data[contextCell.value.col] ?? null;
await copyText(displayCellValue(val));
await copyText(displayCellValue(val), { rows: [[val]] });
}
async function copyRow() {
@@ -823,11 +829,9 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
async function copyAll() {
const header = columns.value.join("\t");
const body = displayItems.value
.filter((item) => !item.isDraft)
.map((item) => item.data.map((c) => displayCellValue(c)).join("\t"))
.join("\n");
await copyText(`${header}\n${body}`);
const rows = displayItems.value.filter((item) => !item.isDraft).map((item) => item.data);
const body = rows.map((row) => row.map((cell) => displayCellValue(cell)).join("\t")).join("\n");
await copyText(`${header}\n${body}`, { rows, includeHeader: true });
}
// --- Export functions ---