refactor: convert to bun-workspaces monorepo (desktop/ + www/)
- Move the Tauri app (React frontend + Rust backend) into desktop/ via git mv — configs unchanged (relative paths: tauri.conf.json, vite.config.ts) - Root package.json becomes a private bun workspace container with orchestration scripts; desktop package renamed gridline-desktop - Scaffold www/ with Astro 7 + Tailwind v4 (hand-wired vite plugin, static output, ready for Dokploy) - Update release.yml for the new layout: projectPath: desktop, desktop/src-tauri resource paths, rust-cache workspace path - Update README + AGENTS.md structure trees and dev commands - Verified: vitest (1074), cargo test (354), desktop build, tauri dev (window launches), tauri build (dmg + app bundles), Astro build
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { useEffect } from "react";
|
||||
import { useConnectionStore } from "./stores/connectionStore";
|
||||
import { useSettingsStore } from "./stores/settingsStore";
|
||||
import { useUiStore } from "./stores/uiStore";
|
||||
import { useBackupStore } from "./stores/backupStore";
|
||||
import { HomeScreen } from "./components/layout/HomeScreen";
|
||||
import { SettingsPage } from "./components/settings/SettingsPage";
|
||||
import { NewConnectionScreen } from "./components/connections/NewConnectionScreen";
|
||||
import { ErrorBanner } from "./components/ui/ErrorBanner";
|
||||
import { ToastContainer } from "./components/ui/Toast";
|
||||
import { DbViewerScreen } from "./components/db-viewer/DbViewerScreen";
|
||||
import { useAppearance } from "./hooks/useAppearance";
|
||||
import { isMacOS } from "./lib/platform";
|
||||
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||
|
||||
const VIEW_TITLES: Record<string, string> = {
|
||||
home: "Gridline",
|
||||
settings: "Settings",
|
||||
"new-connection": "New Connection",
|
||||
"db-viewer": "",
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const activeView = useUiStore((s) => s.activeView);
|
||||
const setActiveView = useUiStore((s) => s.setActiveView);
|
||||
const settingsReturnView = useUiStore((s) => s.settingsReturnView);
|
||||
const openSettings = useUiStore((s) => s.openSettings);
|
||||
const loadConnections = useConnectionStore((s) => s.loadAll);
|
||||
const loadSettings = useSettingsStore((s) => s.load);
|
||||
const settings = useSettingsStore((s) => s.settings);
|
||||
const connectionError = useConnectionStore((s) => s.error);
|
||||
const activeFolderId = useUiStore((s) => s.activeFolderId);
|
||||
const folders = useConnectionStore((s) => s.folders);
|
||||
const tags = useConnectionStore((s) => s.tags);
|
||||
const prefilledConnectionString = useUiStore((s) => s.prefilledConnectionString);
|
||||
const clearPrefilledConnectionString = useUiStore((s) => s.clearPrefilledConnectionString);
|
||||
|
||||
useAppearance(settings?.theme ?? "system", settings?.font_size ?? "medium", settings?.accent_color ?? "#2563EB");
|
||||
|
||||
useEffect(() => {
|
||||
loadConnections();
|
||||
loadSettings();
|
||||
// Init backup event listener (noop outside Tauri)
|
||||
useBackupStore.getState().initListener().catch(() => {});
|
||||
}, [loadConnections, loadSettings]);
|
||||
|
||||
// If the user hasn't navigated anywhere yet, start in the configured default folder
|
||||
const setActiveFolderId = useUiStore((s) => s.setActiveFolderId);
|
||||
const defaultFolderId = settings?.default_folder_id;
|
||||
|
||||
useEffect(() => {
|
||||
if (defaultFolderId && useUiStore.getState().activeFolderId === null) {
|
||||
setActiveFolderId(defaultFolderId);
|
||||
}
|
||||
}, [defaultFolderId, setActiveFolderId]);
|
||||
|
||||
useEffect(() => {
|
||||
let title = VIEW_TITLES[activeView] ?? "Gridline";
|
||||
if (activeView === "db-viewer") {
|
||||
const conn = useConnectionStore.getState().connections.find(
|
||||
(c) => c.id === useUiStore.getState().activeConnectionId
|
||||
);
|
||||
if (conn) title = conn.name;
|
||||
}
|
||||
document.title = title;
|
||||
try {
|
||||
getCurrentWindow().setTitle(title).catch(() => {
|
||||
// Ignore environments where the Tauri API is unavailable (tests, browser)
|
||||
});
|
||||
} catch {
|
||||
// getCurrentWindow can throw outside of a Tauri runtime
|
||||
}
|
||||
}, [activeView]);
|
||||
|
||||
const keepDbViewerMounted =
|
||||
activeView === "db-viewer" ||
|
||||
(activeView === "settings" && settingsReturnView === "db-viewer");
|
||||
const dbViewerVisible = activeView === "db-viewer";
|
||||
|
||||
return (
|
||||
<div className="h-svh bg-canvas select-none flex flex-col overflow-hidden">
|
||||
{typeof window !== "undefined" &&
|
||||
"__TAURI_INTERNALS__" in window &&
|
||||
isMacOS() && (
|
||||
// macOS "Overlay" title bar: in-flow strip the window can be
|
||||
// dragged by; traffic lights float over it. Only in Tauri.
|
||||
<div
|
||||
data-tauri-drag-region
|
||||
aria-hidden
|
||||
className="h-7 shrink-0 bg-canvas select-none"
|
||||
/>
|
||||
)}
|
||||
<div className="flex-1 min-h-0">
|
||||
{connectionError && (
|
||||
<div className="px-6 pt-4">
|
||||
<ErrorBanner
|
||||
error={connectionError}
|
||||
onRetry={loadConnections}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{activeView === "settings" && <SettingsPage />}
|
||||
{activeView === "new-connection" && (
|
||||
<NewConnectionScreen
|
||||
defaultFolderId={activeFolderId}
|
||||
prefilledConnectionString={prefilledConnectionString ?? ""}
|
||||
folders={folders}
|
||||
tags={tags}
|
||||
onSaved={() => {
|
||||
clearPrefilledConnectionString();
|
||||
setActiveView("home");
|
||||
}}
|
||||
onCancel={() => {
|
||||
clearPrefilledConnectionString();
|
||||
setActiveView("home");
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{activeView === "home" && <HomeScreen />}
|
||||
{keepDbViewerMounted && (
|
||||
<div className={dbViewerVisible ? "contents" : "hidden"}>
|
||||
<DbViewerScreen
|
||||
connectionId={useUiStore.getState().activeConnectionId ?? ""}
|
||||
onHome={() => setActiveView("home")}
|
||||
onSettings={openSettings}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<ToastContainer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user