fix(grid): refresh copied insert after row edits

This commit is contained in:
t8y2 2026-07-01 02:10:21 +08:00
parent e83f41c63c
commit c2bae3b957
2 changed files with 63 additions and 2 deletions

View File

@ -178,7 +178,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
}
function updateCopyKey(): string {
const rows = updateEligibleRows().map((item) => item.id);
const rows = copyStatementRowsKey(updateEligibleRows());
return JSON.stringify({
databaseType: databaseType.value ?? null,
schema: tableMeta.value?.schema ?? null,
@ -191,7 +191,7 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
}
function insertCopyKey(excludePrimaryKeys: boolean): string {
const rows = insertEligibleRows().map((item) => item.id);
const rows = copyStatementRowsKey(insertEligibleRows());
return JSON.stringify({
databaseType: databaseType.value ?? null,
schema: tableMeta.value?.schema ?? null,
@ -204,6 +204,11 @@ export function useDataGridExport(options: UseDataGridExportOptions) {
});
}
function copyStatementRowsKey(rows: RowItem[]): Array<{ id: number; data: CellValue[] }> {
// Prepared copy SQL depends on current cell values; edited rows keep the same id while their data changes.
return rows.map((item) => ({ id: item.id, data: item.data }));
}
function insertCopyCache(excludePrimaryKeys: boolean): CopyStatementCache {
return excludePrimaryKeys ? copyRowInsertWithoutPrimaryKeysCache.value : copyRowInsertCache.value;
}

View File

@ -379,6 +379,62 @@ test("copy MongoDB rows as INSERT excludes _id for insert without primary keys",
assert.equal(clipboardMock.copyToClipboard.mock.calls[0][0], 'db.getCollection("accounting_reconciliations").insertMany([{"status":"done"},{"status":"draft"}]);');
});
test("copy row as INSERT refreshes prepared SQL after row data changes", async () => {
const contextCell = ref({ rowId: 1, rowIndex: 0, col: 0 });
const row = {
id: 1,
data: [1, "before"],
isNew: false,
isDeleted: false,
isDirtyCol: [false, false],
status: "",
};
apiMock.buildDataGridCopyInsertStatement
.mockResolvedValueOnce("INSERT INTO users (id, name) VALUES (1, 'before');")
.mockResolvedValueOnce("INSERT INTO users (id, name) VALUES (1, 'after');");
const composable = useDataGridExport({
columns: computed(() => ["id", "name"]),
displayItems: computed(() => [row]),
sql: computed(() => undefined),
tableMeta: computed(() => ({
tableName: "users",
primaryKeys: ["id"],
})),
databaseType: computed(() => "mysql"),
connectionId: computed(() => "conn-1"),
database: computed(() => "db"),
context: computed(() => "table-data"),
sourceColumns: computed(() => undefined),
columnTypes: computed(() => undefined),
whereInput: computed(() => undefined),
orderBy: computed(() => undefined),
exportBatchSize: computed(() => 1000),
hasCellSelection: computed(() => false),
selectedCells: computed(() => ({ columns: [], rows: [] })),
selectedRange: computed(() => null),
contextCell,
getRowItem: () => row,
selectedRowIds: ref(new Set<number>()),
hasRowSelection: computed(() => false),
});
await composable.prefetchRowAsInsertStatement(false);
await composable.copyRowAsInsert();
row.data = [1, "after"];
await composable.prefetchRowAsInsertStatement(false);
await composable.copyRowAsInsert();
assert.equal(apiMock.buildDataGridCopyInsertStatement.mock.calls.length, 2);
assert.deepEqual(apiMock.buildDataGridCopyInsertStatement.mock.calls.map((call) => call[0].rows), [
[[1, "before"]],
[[1, "after"]],
]);
assert.deepEqual(clipboardMock.copyToClipboard.mock.calls.map((call) => call[0]), [
"INSERT INTO users (id, name) VALUES (1, 'before');",
"INSERT INTO users (id, name) VALUES (1, 'after');",
]);
});
test("default data grid export file names use sanitized base names and compact local timestamps", () => {
vi.useFakeTimers();
try {