4ec62f5ed6
- Migra el frontend a Mantine v9 siguiendo la regla de theming del registry (@fn_library, sin Tailwind/cn/CVA). - Reescribe DashboardShell, FilterBar, Section, WidgetRenderer y todos los widgets (Area/Bar/Line/Pie/KPI/Sparkline/Table) con componentes y props de Mantine. - Ajusta vite.config, main.tsx, App.tsx, app.css y env.d.ts. - Añade postcss.config.cjs requerido por Mantine. - Actualiza package.json y pnpm-lock. - Ajusta config.go, main.go y los ejemplos (fn_registry_apps/overview) para el nuevo esquema de tipos en frontend/src/types.ts.
158 lines
4.4 KiB
Go
158 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
"database/sql"
|
|
"embed"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/wailsapp/wails/v2"
|
|
"github.com/wailsapp/wails/v2/pkg/options"
|
|
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
|
|
)
|
|
|
|
//go:embed all:frontend/dist
|
|
var assets embed.FS
|
|
|
|
// examplesDir returns the path to the examples/ directory.
|
|
// Checks cwd first (wails dev), then next to the executable (production).
|
|
func examplesDir() string {
|
|
// 1. examples/ in cwd (wails dev runs from project root)
|
|
if info, err := os.Stat("examples"); err == nil && info.IsDir() {
|
|
return "examples"
|
|
}
|
|
|
|
// 2. examples/ next to the executable (production binary)
|
|
if exePath, err := os.Executable(); err == nil {
|
|
dir := filepath.Join(filepath.Dir(exePath), "examples")
|
|
if info, err := os.Stat(dir); err == nil && info.IsDir() {
|
|
return dir
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func firstYAML(dir string) string {
|
|
entries, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
for _, e := range entries {
|
|
if !e.IsDir() && (filepath.Ext(e.Name()) == ".yaml" || filepath.Ext(e.Name()) == ".yml") {
|
|
return filepath.Join(dir, e.Name())
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func main() {
|
|
// File logger for debugging
|
|
logFile, err := os.OpenFile("rapid_dashboards.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
|
if err == nil {
|
|
log.SetOutput(logFile)
|
|
defer logFile.Close()
|
|
}
|
|
|
|
log.Printf("=== rapid_dashboards starting ===")
|
|
log.Printf("os.Args: %v", os.Args)
|
|
log.Printf("DASHBOARD env: %q", os.Getenv("DASHBOARD"))
|
|
log.Printf("cwd: %s", func() string { d, _ := os.Getwd(); return d }())
|
|
|
|
dashboardPath := flag.String("dashboard", "", "path to dashboard YAML file")
|
|
flag.Parse()
|
|
|
|
log.Printf("flag --dashboard: %q", *dashboardPath)
|
|
|
|
// Resolve examples directory — always used for listing/switching dashboards.
|
|
dashDir := examplesDir()
|
|
log.Printf("examples dir: %q", dashDir)
|
|
|
|
// Fallback: CLI flag → env var → first YAML in examples/
|
|
if *dashboardPath == "" {
|
|
if envPath := os.Getenv("DASHBOARD"); envPath != "" {
|
|
*dashboardPath = envPath
|
|
log.Printf("using DASHBOARD env var: %q", envPath)
|
|
} else if dashDir != "" {
|
|
if first := firstYAML(dashDir); first != "" {
|
|
*dashboardPath = first
|
|
log.Printf("auto-discovered dashboard: %q", first)
|
|
}
|
|
}
|
|
}
|
|
|
|
var cfg *DashboardConfig
|
|
var pool map[string]*sql.DB
|
|
|
|
if *dashboardPath == "" {
|
|
log.Printf("NO dashboard path — using dummy config (bindings mode)")
|
|
cfg = &DashboardConfig{
|
|
Settings: Settings{Title: "rapid-dashboards", Width: 1280, Height: 800, Columns: 12},
|
|
Queries: map[string]QueryDef{},
|
|
Filters: map[string]FilterDef{},
|
|
Sections: []SectionDef{},
|
|
Connections: map[string]ConnConfig{},
|
|
}
|
|
} else {
|
|
log.Printf("loading dashboard from: %q", *dashboardPath)
|
|
var loadErr error
|
|
cfg, loadErr = LoadDashboard(*dashboardPath)
|
|
if loadErr != nil {
|
|
log.Printf("ERROR loading dashboard: %v", loadErr)
|
|
fmt.Fprintf(os.Stderr, "error loading dashboard: %v\n", loadErr)
|
|
os.Exit(1)
|
|
}
|
|
log.Printf("dashboard loaded OK — title=%q sections=%d queries=%d",
|
|
cfg.Settings.Title, len(cfg.Sections), len(cfg.Queries))
|
|
|
|
yamlDir := filepath.Dir(*dashboardPath)
|
|
pool, loadErr = OpenConnections(cfg.Connections, yamlDir)
|
|
if loadErr != nil {
|
|
log.Printf("ERROR opening connections: %v", loadErr)
|
|
fmt.Fprintf(os.Stderr, "error opening connections: %v\n", loadErr)
|
|
os.Exit(1)
|
|
}
|
|
defer CloseConnections(pool)
|
|
log.Printf("connections opened: %d", len(pool))
|
|
}
|
|
|
|
engine := NewQueryEngine(cfg, pool)
|
|
app := NewApp(cfg, engine, pool, dashDir, *dashboardPath)
|
|
|
|
log.Printf("starting wails — title=%q width=%d height=%d layout=%q dashDir=%q", cfg.Settings.Title, cfg.Settings.Width, cfg.Settings.Height, cfg.Settings.Layout, dashDir)
|
|
|
|
wailsOpts := &options.App{
|
|
Title: cfg.Settings.Title,
|
|
Width: cfg.Settings.Width,
|
|
Height: cfg.Settings.Height,
|
|
AssetServer: &assetserver.Options{
|
|
Assets: assets,
|
|
},
|
|
BackgroundColour: &options.RGBA{R: 10, G: 10, B: 15, A: 1},
|
|
OnStartup: app.startup,
|
|
Bind: []interface{}{
|
|
app,
|
|
},
|
|
}
|
|
|
|
if cfg.Settings.Layout == "single_view" {
|
|
wailsOpts.MaxWidth = cfg.Settings.Width
|
|
wailsOpts.MaxHeight = cfg.Settings.Height
|
|
wailsOpts.MinWidth = cfg.Settings.Width
|
|
wailsOpts.MinHeight = cfg.Settings.Height
|
|
wailsOpts.DisableResize = true
|
|
}
|
|
|
|
runErr := wails.Run(wailsOpts)
|
|
|
|
if runErr != nil {
|
|
log.Printf("ERROR wails.Run: %v", runErr)
|
|
fmt.Fprintf(os.Stderr, "error: %v\n", runErr)
|
|
os.Exit(1)
|
|
}
|
|
log.Printf("=== rapid_dashboards exited cleanly ===")
|
|
}
|