15 KiB
Rapid Dashboards — Guia de uso
Dashboard builder declarativo: defines un YAML, obtienes un dashboard desktop con datos en vivo.
Inicio rapido
cd apps/rapid_dashboards
# Desarrollo — usa symlink dashboard.yaml (ver "Cambiar entre dashboards")
wails dev
# Desarrollo — build produccion
CGO_ENABLED=1 wails build -tags fts5
./build/bin/rapid-dashboards --dashboard examples/fn_registry_overview.yaml
Compilar un dashboard especifico
Desarrollo (wails dev)
wails dev no pasa argumentos CLI al binario. El binario busca el dashboard en este orden:
- Flag
--dashboard <path>(solo funciona conwails build, no conwails dev) - Variable de entorno
DASHBOARD(no se propaga al binario enwails dev) - Archivo
dashboard.yamlen el cwd (metodo recomendado para desarrollo)
Para desarrollo, usar un symlink:
# Apuntar al dashboard deseado
ln -sf examples/fn_registry_overview.yaml dashboard.yaml
# Lanzar — el binario encuentra dashboard.yaml automaticamente
wails dev
Produccion (wails build)
# Compilar
CGO_ENABLED=1 wails build -tags fts5
# Ejecutar con un YAML especifico
./build/bin/rapid-dashboards --dashboard examples/fn_registry_overview.yaml
./build/bin/rapid-dashboards --dashboard /ruta/absoluta/mi_dashboard.yaml
El binario compilado acepta el flag --dashboard directamente.
Cambiar entre dashboards
En vivo (dropdown en la app)
Si hay mas de un archivo .yaml en el directorio del dashboard actual, aparece un dropdown junto al titulo. Al seleccionar otro dashboard:
- Se cargan las nuevas conexiones, queries y widgets
- Se cierran las conexiones anteriores
- El tema se aplica automaticamente
Los dashboards disponibles se escanean del directorio donde esta el YAML actual (por defecto examples/).
Cambiando el symlink (para desarrollo)
# Ver dashboards disponibles
ls examples/*.yaml
# Cambiar al dashboard de apps
ln -sf examples/fn_registry_apps.yaml dashboard.yaml
# Cambiar al overview de funciones
ln -sf examples/fn_registry_overview.yaml dashboard.yaml
# Reiniciar wails dev para que tome el cambio
Por CLI (produccion)
# Dashboard de funciones
./build/bin/rapid-dashboards --dashboard examples/fn_registry_overview.yaml
# Dashboard de apps
./build/bin/rapid-dashboards --dashboard examples/fn_registry_apps.yaml
Temas
El campo theme del YAML controla toda la estetica del dashboard. Cada tema cambia colores de fondo, texto, cards, bordes, acentos y la paleta de colores de los graficos.
Temas disponibles
| Tema | Descripcion | Uso recomendado |
|---|---|---|
dark |
Azul-gris profundo, acentos azules | Default, dashboards tecnicos |
emerald |
Verde esmeralda oscuro, acentos dorados | Dashboards financieros, naturaleza |
amber |
Calido ambar/naranja sobre fondo oscuro | Dashboards de alertas, operaciones |
rose |
Rosa/magenta sobre fondo oscuro | Dashboards de marketing, analytics |
light |
Fondo claro con sombras sutiles | Presentaciones, pantallas con luz |
Ejemplo de uso
# Dashboard con tema esmeralda
theme: "emerald"
# Dashboard con tema claro
theme: "light"
Que cambia cada tema
- Background y foreground: tonos base del fondo y texto
- Card: color de fondo de widgets, sin bordes en temas oscuros, con sombra en light
- Primary/accent: color de acento para interacciones y highlights
- Border: tonos de separadores y bordes
- Chart palette: cada tema tiene su propia secuencia de colores para graficos (
--chart-1a--chart-5)
Anadir un tema nuevo
Anadir un bloque [data-theme="nombre"] en frontend/src/app.css con todas las variables CSS. El tema se activa automaticamente al usar theme: "nombre" en el YAML.
Estructura del YAML
Un dashboard se define con 5 bloques:
settings: # titulo, dimensiones, refresh global, columnas
theme: # tema visual
connections: # bases de datos
queries: # SQL + refresh + params
filters: # controles de filtro
sections: # secciones con widgets
1. settings
settings:
title: "Mi Dashboard" # titulo de la ventana
refresh: 30s # refresh global por defecto
width: 1280 # ancho ventana (px)
height: 800 # alto ventana (px)
columns: 12 # columnas del grid CSS
refreshacepta duraciones Go:200ms,1s,5s,1m,30mcolumnsdefine el grid base. Cada widget usaspanpara ocupar N columnas.
2. connections
Cada conexion tiene un nombre y un driver. Secrets via variables de entorno ${VAR}.
SQLite
connections:
local:
driver: sqlite
path: ./data.db
PostgreSQL
connections:
main_db:
driver: postgres
host: localhost
port: 5432
user: analytics
password: "${PG_PASSWORD}"
database: myapp
sslmode: disable
DuckDB
connections:
warehouse:
driver: duckdb
path: ./warehouse.duckdb
ClickHouse
connections:
events:
driver: clickhouse
host: localhost
port: 9000
user: default
password: ""
database: events
Paths relativos: se resuelven desde el cwd del binario, NO desde la ubicacion del YAML. En desarrollo el cwd es apps/rapid_dashboards/, asi que ../../registry.db apunta a la raiz del repo.
3. queries
queries:
revenue_total:
connection: main_db
sql: "SELECT SUM(amount) as value FROM orders"
refresh: 10s
stale_time: 5s
revenue_by_date:
connection: main_db
sql: |
SELECT date, SUM(amount) as revenue
FROM orders
WHERE date >= :date_from AND date <= :date_to
ORDER BY date
params:
date_from: "$filter.date_range.from"
date_to: "$filter.date_range.to"
Parametros
:nombreen el SQL se reemplaza por el valor del param.$filter.xxxreferencia el valor actual de un filtro.$filter.date_range.fromaccede al subcampofrom.- Placeholders se convierten al formato del driver (
$1para Postgres,?para SQLite/DuckDB/ClickHouse).
Fechas relativas
| Valor | Resultado |
|---|---|
now |
timestamp actual |
now-7d |
hace 7 dias |
now-24h |
hace 24 horas |
now-30m |
hace 30 minutos |
4. filters
Select
filters:
category:
type: select
label: "Categoria"
default: "all"
options:
- { label: "Todas", value: "all" }
- { label: "Electronics", value: "electronics" }
Date Range
filters:
date_range:
type: date_range
label: "Periodo"
default: { from: "now-7d", to: "now" }
presets:
- { label: "7 dias", from: "now-7d", to: "now" }
- { label: "30 dias", from: "now-30d", to: "now" }
Text
filters:
search:
type: text
label: "Buscar"
placeholder: "Buscar por nombre..."
debounce: 300
5. sections y widgets
sections:
- id: kpis
title: "Metricas"
columns: 4 # override de columnas
widgets:
- id: total_users
type: kpi
title: "Usuarios"
query: count_users
mapping: { value: "value" }
span: 1
- id: charts
title: "Graficos"
collapsible: true
columns: 2
widgets:
- id: revenue_line
type: line_chart
title: "Revenue"
query: revenue_by_date
mapping:
x: "date"
series:
- { key: "revenue", name: "Revenue", color: "#3b82f6" }
options:
zoomable: true
span: 1
Tipos de widget
kpi
- type: kpi
mapping:
value: "campo_sql"
format: "$,.2f" # opcional
line_chart
- type: line_chart
mapping:
x: "date"
series:
- { key: "revenue", name: "Revenue", color: "#3b82f6" }
options:
curve: monotone # linear | monotone | step
show_grid: true
show_legend: true
zoomable: true
height: 400
bar_chart
- type: bar_chart
mapping:
x: "category"
y: "count"
# O multi-series con series: [...]
options:
horizontal: true # barras horizontales
show_grid: true
show_legend: true
height: 300
pie_chart
- type: pie_chart
mapping:
name: "domain" # campo para nombres de segmentos
value: "cantidad" # campo numerico
options:
donut: true # hueco central
show_legend: true # default: true
height: 300
area_chart
- type: area_chart
mapping:
x: "date"
series:
- { key: "users", name: "Usuarios" }
options:
stacked: true
height: 300
sparkline
- type: sparkline
mapping:
value: "metric"
options:
variant: area # line | area | bar
width: 200
height: 40
table
- type: table
mapping:
columns:
- { key: "name", label: "Nombre" }
- { key: "amount", label: "Monto", format: "$,.2f" }
- { key: "created_at", label: "Fecha", format: "datetime" }
options:
heatmap_columns: ["go", "python", "bash"] # colorea celdas por intensidad
Si no defines columns, se auto-detectan del resultado SQL.
Heatmap: options.heatmap_columns acepta un array de nombres de columna. Las celdas se colorean de azul oscuro (valor minimo) a azul brillante (valor maximo), calculado por columna.
Formatos de valor
| Formato | Ejemplo | Resultado |
|---|---|---|
$,.2f |
1234.5 | $1,234.50 |
,.2f |
1234.5 | 1,234.50 |
.2f |
1234.5 | 1234.50 |
, |
1234 | 1,234 |
datetime |
ISO string | locale datetime |
Variables de entorno
Cualquier campo del YAML soporta ${VARIABLE}:
DB_HOST=prod.example.com DB_PASSWORD=secret \
./rapid-dashboards --dashboard prod.yaml
Puntos clave (aprendizajes)
Wails dev no pasa CLI args al binario
wails dev -- --flag value no funciona: Wails compila y ejecuta el binario como proceso hijo sin pasar los args despues de --. Tampoco propaga variables de entorno al binario. La solucion es usar un archivo dashboard.yaml en el cwd que el binario detecta automaticamente.
Wails genera bindings ejecutando el binario sin args
Durante wails dev, el primer paso es generar bindings TypeScript. Para esto Wails ejecuta el binario sin argumentos. Si el binario requiere flags obligatorios y hace os.Exit(1), la generacion falla. Solucion: detectar cuando no hay args y usar un config dummy con slices vacios (no nil) para que los tipos se generen correctamente.
Slices nil de Go se serializan como null en JSON
[]SectionDef(nil) se serializa como null, no como []. Si el frontend hace .map() sobre null, crash. Inicializar siempre con []SectionDef{} para el config dummy, y usar (config.sections ?? []) en el frontend.
Tipos de Wails vs tipos manuales de TypeScript
Wails genera models.ts con tipos string genericos. Si el frontend tiene tipos mas estrictos (union types como "select" | "date_range"), hay incompatibilidad. Solucion: castear los imports con as unknown as typeof X.
Paths relativos se resuelven desde el cwd, no desde el YAML
SQLiteOpen(path) resuelve paths relativos al cwd del proceso. Si el YAML esta en examples/ y el binario corre desde apps/rapid_dashboards/, un path ../../registry.db es correcto pero ../../../registry.db (relativo al YAML) no. Siempre pensar los paths desde el cwd del binario.
Recharts Pie necesita valores numericos
SQLite puede devolver numeros como strings en algunos contextos. Recharts Pie no renderiza nada si dataKey apunta a un string. Solucion: coercer a Number() antes de pasar a Pie.
Recharts PieLabelRenderProps es estricto
El tipo label de <Pie> no acepta callbacks con tipos genericos como Record<string, unknown>. Hay que importar PieLabelRenderProps de recharts y usar una funcion con nombre tipada, no un lambda inline.
Animaciones de Recharts
Las animaciones por defecto de Recharts Pie son lentas en dashboards que refrescan frecuentemente. Usar isAnimationActive={false} para render instantaneo.
Scripts de lanzamiento
Cada dashboard YAML debe tener forma de lanzarse rapido desde scripts/. La carpeta scripts/ contiene dos scripts genericos que reciben el nombre del dashboard como argumento:
# Listar dashboards disponibles
./scripts/dev.sh
# Desarrollo — crea symlink + wails dev
./scripts/dev.sh fn_registry_overview
# Produccion — compila si es necesario + ejecuta
./scripts/prod.sh fn_registry_apps
# Produccion con variables de entorno
DB_PASSWORD=secret ./scripts/prod.sh mi_dashboard
Convencion
Al crear un nuevo YAML en examples/, no hace falta crear scripts adicionales — dev.sh y prod.sh descubren automaticamente los .yaml de examples/. Solo ejecutar con el nombre (sin extension):
# Nuevo dashboard
vim examples/mi_nuevo_dashboard.yaml
# Lanzar inmediatamente
./scripts/dev.sh mi_nuevo_dashboard
dev.sh crea el symlink dashboard.yaml y lanza wails dev. prod.sh compila con CGO_ENABLED=1 wails build -tags fts5 si el binario no existe o el YAML es mas reciente, y ejecuta con --dashboard.
Compilacion multiplataforma
Linux (default)
CGO_ENABLED=1 wails build -tags fts5
Genera build/bin/rapid-dashboards con soporte para SQLite, PostgreSQL, DuckDB y ClickHouse.
Windows (cross-compile desde Linux)
CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64 \
wails build -tags "fts5 noduckdb noclickhouse" -platform windows/amd64 -skipbindings
Genera build/bin/rapid-dashboards.exe. Requiere mingw-w64 instalado (apt install gcc-mingw-w64-x86-64).
Limitacion: DuckDB y ClickHouse se excluyen con los tags noduckdb y noclickhouse porque go-duckdb depende de libstdc++ y no cross-compila bien desde Linux. El .exe solo soporta SQLite y PostgreSQL. Si un YAML usa esos drivers, dara error: "duckdb support not compiled".
Windows nativo (con DuckDB y ClickHouse)
Para compilar con todos los drivers, compilar directamente en Windows con Go y MinGW/MSYS2 instalados:
# En Windows con Go + MinGW (MSYS2)
$env:CGO_ENABLED=1
wails build -tags fts5
Esto genera un .exe con soporte completo: SQLite, PostgreSQL, DuckDB y ClickHouse.
Resumen de soporte por plataforma
| Driver | Linux | Windows (cross-compile) | Windows (nativo) |
|---|---|---|---|
| SQLite | si | si | si |
| PostgreSQL | si | si | si |
| DuckDB | si | no | si |
| ClickHouse | si | no | si |
Rutas en Windows
Las rutas no se rompen entre plataformas. El codigo usa filepath.Join y filepath.IsAbs de Go, que adaptan los separadores automaticamente (/ en Linux, \ en Windows). Los paths relativos en el YAML (ej: ../../registry.db) funcionan igual en ambos OS.
Extensibilidad
Para anadir un tipo de widget nuevo:
- Crear
frontend/src/components/widgets/MiWidget.tsximplementandoWidgetProps - Registrar en
frontend/src/components/widgets/register.ts:registerWidget('mi_tipo', MiWidget) - Usar en YAML:
type: mi_tipo