mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-23 09:23:26 +00:00
feat(tabs): add duplicate tab feature in context menu
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { computed, ref, watch, nextTick } from "vue";
|
||||
import type { CSSProperties } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { X, Pin, ChevronDown, Table2, Code2, TableProperties, PencilRuler, KeyRound, Pencil, Package, Check, Lock } from "@lucide/vue";
|
||||
import { X, Pin, ChevronDown, Table2, Code2, TableProperties, PencilRuler, KeyRound, Pencil, Package, Check, Lock, Copy } from "@lucide/vue";
|
||||
import CustomContextMenu, { type ContextMenuItem } from "@/components/ui/CustomContextMenu.vue";
|
||||
import LightDropdown from "@/components/ui/LightDropdown.vue";
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
|
||||
@@ -83,6 +83,12 @@ function getTabMenuItems(tab: QueryTab): ContextMenuItem[] {
|
||||
icon: Pencil,
|
||||
visible: canRenameTab(tab),
|
||||
},
|
||||
{
|
||||
label: t("contextMenu.duplicateTab"),
|
||||
action: () => queryStore.duplicateTab(tab.id),
|
||||
icon: Copy,
|
||||
visible: canRenameTab(tab),
|
||||
},
|
||||
{ label: "", separator: true },
|
||||
{
|
||||
label: tab.pinned ? t("contextMenu.unpin") : t("contextMenu.pin"),
|
||||
|
||||
@@ -1010,6 +1010,7 @@
|
||||
unpin: "Unpin",
|
||||
refreshTab: "Refresh Data",
|
||||
renameTab: "Rename Tab",
|
||||
duplicateTab: "Duplicate Tab",
|
||||
compactTabTitle: "Shorten Tab Titles",
|
||||
closeTab: "Close Tab",
|
||||
closeOtherTabs: "Close Other Tabs",
|
||||
|
||||
@@ -873,6 +873,7 @@
|
||||
unpin: "Desfijar",
|
||||
refreshTab: "Actualizar datos",
|
||||
renameTab: "Renombrar pestaña",
|
||||
duplicateTab: "Duplicar pestaña",
|
||||
closeTab: "Cerrar pestaña",
|
||||
closeOtherTabs: "Cerrar otras pestañas",
|
||||
closeAllTabs: "Cerrar todas las pestañas",
|
||||
|
||||
@@ -974,6 +974,7 @@
|
||||
unpin: "Sblocca",
|
||||
refreshTab: "Aggiorna Dati",
|
||||
renameTab: "Rinomina Scheda",
|
||||
duplicateTab: "Duplica Scheda",
|
||||
compactTabTitle: "Accorcia Titoli Schede",
|
||||
closeTab: "Chiudi Scheda",
|
||||
closeOtherTabs: "Chiudi Altre Schede",
|
||||
|
||||
@@ -974,6 +974,7 @@
|
||||
unpin: "Desafixar",
|
||||
refreshTab: "Atualizar Dados",
|
||||
renameTab: "Renomear Aba",
|
||||
duplicateTab: "Duplicar Aba",
|
||||
compactTabTitle: "Encurtar Títulos das Abas",
|
||||
closeTab: "Fechar Aba",
|
||||
closeOtherTabs: "Fechar Outras Abas",
|
||||
|
||||
@@ -1009,6 +1009,7 @@
|
||||
unpin: "取消置顶",
|
||||
refreshTab: "刷新数据",
|
||||
renameTab: "重命名标签页",
|
||||
duplicateTab: "复制标签页",
|
||||
compactTabTitle: "缩短标签标题",
|
||||
closeTab: "关闭标签页",
|
||||
closeOtherTabs: "关闭其他标签页",
|
||||
|
||||
@@ -953,6 +953,7 @@
|
||||
unpin: "取消置頂",
|
||||
refreshTab: "重新整理資料",
|
||||
renameTab: "重新命名分頁",
|
||||
duplicateTab: "複製分頁",
|
||||
compactTabTitle: "縮短標籤標題",
|
||||
closeTab: "關閉分頁",
|
||||
closeOtherTabs: "關閉其他分頁",
|
||||
|
||||
@@ -397,6 +397,69 @@ export const useQueryStore = defineStore("query", () => {
|
||||
activeTabId.value = next.activeTabId;
|
||||
}
|
||||
|
||||
function duplicateTab(id: string) {
|
||||
const idx = tabs.value.findIndex((t) => t.id === id);
|
||||
if (idx < 0) return;
|
||||
const original = tabs.value[idx];
|
||||
const newId = uuid();
|
||||
const newTab: QueryTab = {
|
||||
id: newId,
|
||||
title: original.title,
|
||||
customTitle: original.customTitle,
|
||||
connectionId: original.connectionId,
|
||||
database: original.database,
|
||||
schema: original.schema,
|
||||
sql: original.sql,
|
||||
savedSqlId: original.savedSqlId,
|
||||
lastExecutedSql: undefined,
|
||||
resultBaseSql: original.resultBaseSql,
|
||||
resultSortedSql: undefined,
|
||||
resultSortColumn: undefined,
|
||||
resultSortColumnIndex: undefined,
|
||||
resultSortDirection: undefined,
|
||||
orderByInput: undefined,
|
||||
resultPageSql: undefined,
|
||||
resultPageLimit: undefined,
|
||||
resultPageOffset: undefined,
|
||||
resultCountSql: undefined,
|
||||
resultTotalRowCount: undefined,
|
||||
resultTotalRowCountLoading: undefined,
|
||||
resultSessionId: undefined,
|
||||
resultAccessedAt: undefined,
|
||||
resultCacheKey: undefined,
|
||||
resultCacheState: undefined,
|
||||
pinned: false,
|
||||
result: undefined,
|
||||
results: undefined,
|
||||
activeResultIndex: undefined,
|
||||
explainPlan: undefined,
|
||||
explainError: undefined,
|
||||
explainSql: undefined,
|
||||
lastExplainedSql: undefined,
|
||||
isExecuting: false,
|
||||
isCancelling: false,
|
||||
queryExecutionStartedAt: undefined,
|
||||
editorViewport: undefined,
|
||||
editorSelection: undefined,
|
||||
executionId: undefined,
|
||||
isExplaining: false,
|
||||
explainExecutionId: undefined,
|
||||
mode: original.mode,
|
||||
structureTableName: original.structureTableName,
|
||||
objectBrowser: original.objectBrowser ? { ...original.objectBrowser } : undefined,
|
||||
objectSource: original.objectSource ? { ...original.objectSource } : undefined,
|
||||
tableMeta: original.tableMeta ? { ...original.tableMeta, columns: [...original.tableMeta.columns], primaryKeys: [...original.tableMeta.primaryKeys] } : undefined,
|
||||
queryAnalysis: original.queryAnalysis ? { ...original.queryAnalysis, columns: original.queryAnalysis.columns.map((c) => ({ ...c })) } : undefined,
|
||||
querySourceColumns: original.querySourceColumns ? [...original.querySourceColumns] : undefined,
|
||||
queryEditabilityReason: original.queryEditabilityReason,
|
||||
resultEvicted: undefined,
|
||||
whereInput: original.whereInput,
|
||||
previewSql: original.previewSql,
|
||||
};
|
||||
tabs.value.splice(idx + 1, 0, newTab);
|
||||
activeTabId.value = newId;
|
||||
}
|
||||
|
||||
function closeTabsWhere(predicate: (tab: QueryTab) => boolean) {
|
||||
const closingIds = new Set(tabs.value.filter((tab) => predicate(tab)).map((tab) => tab.id));
|
||||
if (closingIds.size === 0) return;
|
||||
@@ -1535,6 +1598,7 @@ export const useQueryStore = defineStore("query", () => {
|
||||
closeTab,
|
||||
closeOtherTabs,
|
||||
closeAllTabs,
|
||||
duplicateTab,
|
||||
closeConnectionTabs,
|
||||
closeDatabaseTabs,
|
||||
releaseConnectionTabs,
|
||||
|
||||
Reference in New Issue
Block a user