Greenplum 7 (PG12-based) compatibility: - Auto-detect GP via version() string, store DbFlavor per connection - connect returns ConnectResult with version + flavor - Fix pg_total_relation_size to use c.oid (universal, safer on both PG/GP) - Branch is_identity column query for GP (lacks the column) - Branch list_sessions wait_event fields for GP - Exclude gp_toolkit schema in schema listing, completion, lookup, AI context - Smart StatusBar version display: GP shows "GP 7.0.0 (PG 12.4)" - Fix connection list spinner showing on all cards during connect AI SQL generation (Ollama): - Add AI settings, model selection, and generate_sql command - Frontend AI panel with prompt input and SQL output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { useEffect, useCallback } from "react";
|
|
import {
|
|
ResizableHandle,
|
|
ResizablePanel,
|
|
ResizablePanelGroup,
|
|
} from "@/components/ui/resizable";
|
|
import { Toolbar } from "@/components/layout/Toolbar";
|
|
import { Sidebar } from "@/components/layout/Sidebar";
|
|
import { TabBar } from "@/components/layout/TabBar";
|
|
import { TabContent } from "@/components/workspace/TabContent";
|
|
import { StatusBar } from "@/components/layout/StatusBar";
|
|
import { useAppStore } from "@/stores/app-store";
|
|
import type { Tab } from "@/types";
|
|
|
|
export default function App() {
|
|
const { activeConnectionId, currentDatabase, addTab } = useAppStore();
|
|
|
|
const handleNewQuery = useCallback(() => {
|
|
if (!activeConnectionId) return;
|
|
const tab: Tab = {
|
|
id: crypto.randomUUID(),
|
|
type: "query",
|
|
title: "New Query",
|
|
connectionId: activeConnectionId,
|
|
database: currentDatabase ?? undefined,
|
|
sql: "",
|
|
};
|
|
addTab(tab);
|
|
}, [activeConnectionId, currentDatabase, addTab]);
|
|
|
|
const handleCloseTab = useCallback(() => {
|
|
const { activeTabId, closeTab } = useAppStore.getState();
|
|
if (activeTabId) closeTab(activeTabId);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
if ((e.ctrlKey || e.metaKey) && e.key === "t") {
|
|
e.preventDefault();
|
|
handleNewQuery();
|
|
}
|
|
if ((e.ctrlKey || e.metaKey) && e.key === "w") {
|
|
e.preventDefault();
|
|
handleCloseTab();
|
|
}
|
|
};
|
|
window.addEventListener("keydown", handleKeyDown);
|
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
}, [handleNewQuery, handleCloseTab]);
|
|
|
|
return (
|
|
<div className="flex h-screen flex-col">
|
|
<Toolbar />
|
|
<div className="flex-1 overflow-hidden">
|
|
<ResizablePanelGroup orientation="horizontal">
|
|
<ResizablePanel id="sidebar" defaultSize="20%" minSize="180px" maxSize="40%">
|
|
<Sidebar />
|
|
</ResizablePanel>
|
|
<ResizableHandle />
|
|
<ResizablePanel id="main" defaultSize="80%">
|
|
<div className="flex h-full flex-col">
|
|
<TabBar />
|
|
<div className="flex-1 overflow-hidden">
|
|
<TabContent />
|
|
</div>
|
|
</div>
|
|
</ResizablePanel>
|
|
</ResizablePanelGroup>
|
|
</div>
|
|
<StatusBar />
|
|
</div>
|
|
);
|
|
}
|