From 326c4f54954eb379042823810fea23107c7fdf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E4=B8=AB=E8=AE=B2=E6=A2=B5?= Date: Tue, 7 Jul 2026 16:39:38 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(dataGrid):=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=A4=8D=E5=88=B6=E9=80=90=E8=A1=8C=E6=8F=92=E5=85=A5?= =?UTF-8?q?=E8=AF=AD=E5=8F=A5=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/src/components/grid/DataGrid.vue | 40 ++++++++-- .../src/components/ui/CustomContextMenu.vue | 8 +- .../src/composables/useDataGridExport.ts | 79 +++++++++++++------ apps/desktop/src/i18n/locales/en.ts | 4 + apps/desktop/src/i18n/locales/es.ts | 4 + apps/desktop/src/i18n/locales/it.ts | 4 + apps/desktop/src/i18n/locales/ja.ts | 4 + apps/desktop/src/i18n/locales/pt-BR.ts | 4 + apps/desktop/src/i18n/locales/zh-CN.ts | 4 + apps/desktop/src/i18n/locales/zh-TW.ts | 4 + apps/desktop/src/lib/dataGrid/dataGridSql.ts | 3 + crates/dbx-core/src/data_grid_sql.rs | 42 +++++++++- .../dbx-core/tests/live_postgres_tsvector.rs | 4 +- 13 files changed, 166 insertions(+), 38 deletions(-) diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index 8e5fb89069..f353a425fb 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -7335,8 +7335,14 @@ function onRowContext(rowId: number, rowIndex: number) { async function prefetchCopyStatements() { await prefetchRowAsInsertStatement(false); + if (isMultiRow.value) { + await prefetchRowAsInsertStatement(false, "row-by-row"); + } if (canCopyRowAsInsertWithoutPrimaryKeys.value) { await prefetchRowAsInsertStatement(true); + if (isMultiRow.value) { + await prefetchRowAsInsertStatement(true, "row-by-row"); + } } if (canCopyRowAsUpdate.value) { await prefetchRowAsUpdateStatement(); @@ -7945,7 +7951,11 @@ function copyRowLabels() { return { row: isMultiRow.value ? t("grid.copyRows", { count }) : t("grid.copyRow"), insert: isMultiRow.value ? t("grid.copyRowsInsert", { count }) : t("grid.copyRowInsert"), + insertMerged: t("grid.copyRowsInsertMerged", { count }), + insertRowByRow: t("grid.copyRowsInsertRowByRow", { count }), insertNoPk: isMultiRow.value ? t("grid.copyRowsInsertWithoutPrimaryKeys", { count }) : t("grid.copyRowInsertWithoutPrimaryKeys"), + insertNoPkMerged: t("grid.copyRowsInsertWithoutPrimaryKeysMerged", { count }), + insertNoPkRowByRow: t("grid.copyRowsInsertWithoutPrimaryKeysRowByRow", { count }), update: isMultiRow.value ? t("grid.copyRowsUpdate", { count }) : t("grid.copyRowUpdate"), }; } @@ -7977,13 +7987,31 @@ function copySubmenu(): ContextMenuItem { items.push({ label: t("grid.copyCell"), action: copyCell }); } items.push({ label: labels.row, action: copyRow }); - items.push({ label: labels.insert, action: copyRowAsInsert, disabled: !canCopyPreparedInsert(false) }); + if (isMultiRow.value) { + items.push({ label: labels.insertMerged, action: () => copyRowAsInsert("merged"), disabled: !canCopyPreparedInsert(false, "merged") }); + items.push({ label: labels.insertRowByRow, action: () => copyRowAsInsert("row-by-row"), disabled: !canCopyPreparedInsert(false, "row-by-row") }); + } else { + items.push({ label: labels.insert, action: () => copyRowAsInsert(), disabled: !canCopyPreparedInsert(false) }); + } if (canCopyRowAsInsertWithoutPrimaryKeys.value) { - items.push({ - label: labels.insertNoPk, - action: copyRowAsInsertWithoutPrimaryKeys, - disabled: !canCopyPreparedInsert(true), - }); + if (isMultiRow.value) { + items.push({ + label: labels.insertNoPkMerged, + action: () => copyRowAsInsertWithoutPrimaryKeys("merged"), + disabled: !canCopyPreparedInsert(true, "merged"), + }); + items.push({ + label: labels.insertNoPkRowByRow, + action: () => copyRowAsInsertWithoutPrimaryKeys("row-by-row"), + disabled: !canCopyPreparedInsert(true, "row-by-row"), + }); + } else { + items.push({ + label: labels.insertNoPk, + action: () => copyRowAsInsertWithoutPrimaryKeys(), + disabled: !canCopyPreparedInsert(true), + }); + } } if (canCopyRowAsUpdate.value) { items.push({ label: labels.update, action: copyRowAsUpdate, disabled: !canCopyPreparedUpdate() }); diff --git a/apps/desktop/src/components/ui/CustomContextMenu.vue b/apps/desktop/src/components/ui/CustomContextMenu.vue index 9c2672d661..aaa7c84765 100644 --- a/apps/desktop/src/components/ui/CustomContextMenu.vue +++ b/apps/desktop/src/components/ui/CustomContextMenu.vue @@ -258,7 +258,7 @@ onBeforeUnmount(() => { -
+