import { matchesModifierOnlyShortcut, type ShortcutLikeEvent } from "@/lib/editor/keyboardShortcuts"; import type { QueryTab, TreeNodeType } from "@/types/database"; export type DataTabOpenMode = "default" | "new-tab"; type DataTabLike = Pick; export interface DataTabTarget { connectionId: string; database: string; schema?: string; catalog?: string; tableName: string; } export type ExistingDataTabCandidate = { tab: T; match: "same-table" | "database"; }; const dataNodeTypes = new Set(["table", "view", "materialized_view"]); export function isDataTreeNodeType(type: TreeNodeType): boolean { return dataNodeTypes.has(type); } export function dataTabOpenModeFromTreeClick(type: TreeNodeType, event: Omit, shortcut: string): DataTabOpenMode { if (!isDataTreeNodeType(type)) return "default"; return matchesModifierOnlyShortcut(event, shortcut) ? "new-tab" : "default"; } function isSameDatabase(tab: DataTabLike, target: Pick): boolean { return tab.mode === "data" && tab.connectionId === target.connectionId && tab.database === target.database; } function isSameTable(tab: DataTabLike, target: DataTabTarget): boolean { return isSameDatabase(tab, target) && (tab.tableMeta?.catalog || "") === (target.catalog || "") && (tab.schema || "") === (target.schema || "") && (tab.tableMeta?.tableName || tab.title) === target.tableName; } export function canApplyDataTabMetadata(tab: DataTabLike | undefined, target: DataTabTarget, signal?: AbortSignal): boolean { return signal?.aborted !== true && tab !== undefined && isSameTable(tab, target); } export function findExistingDataTabCandidate(tabs: T[], target: DataTabTarget, options: { openMode: DataTabOpenMode; reuseDataTab: boolean }): ExistingDataTabCandidate | undefined { if (options.openMode === "new-tab") return undefined; const sameTable = tabs.find((tab) => isSameTable(tab, target)); if (sameTable) return { tab: sameTable, match: "same-table" }; if (!options.reuseDataTab) return undefined; const sameDatabase = tabs.find((tab) => isSameDatabase(tab, target)); return sameDatabase ? { tab: sameDatabase, match: "database" } : undefined; }