feat: add schema browser sidebar and app layout

Add SchemaTree with database/schema/category hierarchy, Sidebar with
search, Toolbar, TabBar, StatusBar, and full app layout with
resizable panels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 19:06:42 +03:00
parent 734b84b525
commit d333732346
5 changed files with 596 additions and 0 deletions

View File

@@ -0,0 +1,86 @@
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { ConnectionSelector } from "@/components/connections/ConnectionSelector";
import { ConnectionList } from "@/components/connections/ConnectionList";
import { ConnectionDialog } from "@/components/connections/ConnectionDialog";
import { useAppStore } from "@/stores/app-store";
import { Database, Plus } from "lucide-react";
import type { ConnectionConfig, Tab } from "@/types";
export function Toolbar() {
const [listOpen, setListOpen] = useState(false);
const [dialogOpen, setDialogOpen] = useState(false);
const [editingConn, setEditingConn] = useState<ConnectionConfig | null>(null);
const { activeConnectionId, addTab } = useAppStore();
const handleNewQuery = () => {
if (!activeConnectionId) return;
const tab: Tab = {
id: crypto.randomUUID(),
type: "query",
title: "New Query",
connectionId: activeConnectionId,
sql: "",
};
addTab(tab);
};
return (
<>
<div className="flex h-10 items-center gap-2 border-b px-3 bg-card">
<Button
variant="ghost"
size="sm"
className="h-7 gap-1.5"
onClick={() => setListOpen(true)}
>
<Database className="h-3.5 w-3.5" />
Connections
</Button>
<Separator orientation="vertical" className="h-5" />
<ConnectionSelector />
<Separator orientation="vertical" className="h-5" />
<Button
variant="ghost"
size="sm"
className="h-7 gap-1.5"
onClick={handleNewQuery}
disabled={!activeConnectionId}
>
<Plus className="h-3.5 w-3.5" />
New Query
</Button>
<div className="flex-1" />
<span className="text-xs font-semibold text-muted-foreground tracking-wide">
TUSK
</span>
</div>
<ConnectionList
open={listOpen}
onOpenChange={setListOpen}
onEdit={(conn) => {
setEditingConn(conn);
setDialogOpen(true);
}}
onNew={() => {
setEditingConn(null);
setDialogOpen(true);
}}
/>
<ConnectionDialog
open={dialogOpen}
onOpenChange={setDialogOpen}
connection={editingConn}
/>
</>
);
}