diff --git a/src/App.vue b/src/App.vue
index ad2acc34bd..3272c71401 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -411,7 +411,11 @@ function onAiRequestAutoExecuteSql(sql: string) {
function handleKeydown(e: KeyboardEvent) {
if (isCloseTabShortcut(e)) {
e.preventDefault();
- if (queryStore.activeTabId) queryStore.closeTab(queryStore.activeTabId);
+ if (showDriverStore.value) {
+ showDriverStore.value = false;
+ } else if (queryStore.activeTabId) {
+ queryStore.closeTab(queryStore.activeTabId);
+ }
return;
}
if (
diff --git a/src/components/grid/DataGrid.vue b/src/components/grid/DataGrid.vue
index 813d85d194..9e436f97e8 100644
--- a/src/components/grid/DataGrid.vue
+++ b/src/components/grid/DataGrid.vue
@@ -1091,6 +1091,26 @@ const selectionSummary = computed(() => {
return t("grid.selectedCells", { count: selectedCellCount.value });
});
+const multiRowCount = computed(() => {
+ if (hasRowSelection.value) return selectedRowCount.value;
+ const range = selectedRange.value;
+ if (range && range.startRow !== range.endRow) return range.endRow - range.startRow + 1;
+ return 1;
+});
+
+const isMultiRow = computed(() => multiRowCount.value > 1);
+
+function affectedRowIds(): number[] {
+ if (hasRowSelection.value && selectedRowCount.value > 0) {
+ return [...selectedRowIds.value];
+ }
+ const range = selectedRange.value;
+ if (range && range.startRow !== range.endRow) {
+ return displayItems.value.slice(range.startRow, range.endRow + 1).map((item) => item.id);
+ }
+ return [];
+}
+
function isRowActive(index: number): boolean {
const item = displayItems.value[index];
if (item && isRowSelected(item.id)) return true;
@@ -2570,18 +2590,10 @@ defineExpose({
{{ t("grid.copyCell") }}
- {{
- hasRowSelection && selectedRowCount > 1
- ? t("grid.copyRows", { count: selectedRowCount })
- : t("grid.copyRow")
- }}
+ {{ isMultiRow ? t("grid.copyRows", { count: multiRowCount }) : t("grid.copyRow") }}
- {{
- hasRowSelection && selectedRowCount > 1
- ? t("grid.copyRowsInsert", { count: selectedRowCount })
- : t("grid.copyRowInsert")
- }}
+ {{ isMultiRow ? t("grid.copyRowsInsert", { count: multiRowCount }) : t("grid.copyRowInsert") }}
{{ t("grid.copyAll") }}
@@ -2604,17 +2616,9 @@ defineExpose({
- 1 ? cloneRows([...selectedRowIds]) : cloneRow(contextRowItem.id)
- "
- >
+
- {{
- hasRowSelection && selectedRowCount > 1
- ? t("grid.cloneRows", { count: selectedRowCount })
- : t("grid.cloneRow")
- }}
+ {{ isMultiRow ? t("grid.cloneRows", { count: multiRowCount }) : t("grid.cloneRow") }}
{{ t("grid.restoreRow") }}
@@ -2622,18 +2626,10 @@ defineExpose({
1
- ? requestDeleteRows([...selectedRowIds])
- : requestDeleteRow(contextRowItem.id)
- "
+ @click="isMultiRow ? requestDeleteRows(affectedRowIds()) : requestDeleteRow(contextRowItem.id)"
>
- {{
- hasRowSelection && selectedRowCount > 1
- ? t("grid.deleteRows", { count: selectedRowCount })
- : t("grid.deleteRow")
- }}
+ {{ isMultiRow ? t("grid.deleteRows", { count: multiRowCount }) : t("grid.deleteRow") }}
diff --git a/src/components/layout/AppTabBar.vue b/src/components/layout/AppTabBar.vue
index 8d4b9468c9..393e93f80b 100644
--- a/src/components/layout/AppTabBar.vue
+++ b/src/components/layout/AppTabBar.vue
@@ -17,7 +17,7 @@ import { connectionColor, tabDisplayTitle, tabTooltipLines } from "@/lib/tabPres
import { hexToRgba } from "@/lib/color";
import type { QueryTab } from "@/types/database";
-defineProps<{
+const props = defineProps<{
showDriverStore?: boolean;
}>();
@@ -55,9 +55,25 @@ watch(
},
);
+watch(
+ () => props.showDriverStore,
+ (show) => {
+ if (!show) return;
+ nextTick(() => {
+ const container = tabsContainerRef.value;
+ if (!container) return;
+ const el = container.querySelector("[data-driver-store-tab]");
+ if (el) {
+ el.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" });
+ }
+ updateScrollButtons();
+ });
+ },
+);
+
function tabColorStyle(tab: QueryTab) {
const color = connectionColor(tab.connectionId);
- const isActive = tab.id === queryStore.activeTabId;
+ const isActive = tab.id === queryStore.activeTabId && !props.showDriverStore;
const isClassic = settingsStore.editorSettings.appLayout === "classic";
if (!color) {
if (isClassic) {
@@ -124,19 +140,19 @@ function tabIconClass(tab: QueryTab) {
settingsStore.editorSettings.appLayout === 'classic'
? [
'h-full border-r border-border/50',
- tab.id === queryStore.activeTabId
+ tab.id === queryStore.activeTabId && !showDriverStore
? 'bg-background text-foreground font-medium'
: 'text-foreground/70 hover:text-foreground/90',
]
: [
'h-7 rounded-md border',
- tab.id === queryStore.activeTabId
+ tab.id === queryStore.activeTabId && !showDriverStore
? 'text-foreground font-medium'
: 'border-border/60 text-foreground/70 hover:border-border hover:text-foreground/90',
]
"
:style="tabColorStyle(tab)"
- :data-active-tab="tab.id === queryStore.activeTabId"
+ :data-active-tab="tab.id === queryStore.activeTabId && !showDriverStore"
@click="
queryStore.activeTabId = tab.id;
emit('close-driver-store');
@@ -202,6 +218,7 @@ function tabIconClass(tab: QueryTab) {