Saltar a contenido

Widgets

Catálogo de tipos CUS que el shell renderiza. Declaras type + config en dashboards o dejas que los builders los emitan.

Cuándo consultar

  • Eliges widget para un dashboard JSON manual.
  • Necesitas saber qué config exige cada tipo.
  • Extiendes el registry en TypeScript (caso avanzado).

Tipos registrados (shadcn)

type Alias Componente Origen típico
data-table api-table DataTableWidget TableBuilder
form json-form FormWidget FormBuilder / recurso
infolist InfolistWidget InfolistBuilder
stat-card StatCardWidget StatCardBuilder
stats-overview StatsOverviewWidget StatsOverviewBuilder
calendar CalendarWidget CalendarBuilder
actions-bar ActionsBarWidget ActionBuilder / recurso
section SectionWidget Layout / anidación
relation RelationManagerWidget RelationBuilder
settings SettingsWidget panel host / settings API
wizard reservation-wizard WizardWidget booking, custom
reservation-flow ReservationFlowWidget booking (orquestador)
client-picker ClientPickerWidget wizard reserva
payment-checkout PaymentCheckoutWidget wizard reserva
booking-slot-picker BookingSlotPickerWidget wizard reserva
schema SchemaRenderer SchemaBuilder
chart ChartWidget (Recharts) emit_chart_widget / JSON
report ReportWidget ReportBuilder
api-card ApiCardWidget JSON manual
plugin-list PluginListWidget control

Registry: packages/cortex-panel-shadcn/src/defaultRegistry.ts.

Tipos TypeScript: packages/cortex-panel-core/src/uiTypes.ts.

Wizard de reserva (composición)

El flujo reservation-flow orquesta pasos con widgets de dominio (booking-slot-picker, client-picker, payment-checkout). Cada widget puede reutilizarse en otros dashboards; booking solo referencia el tipo CUS en el manifest. Ver ADR 019.

booking-slot-picker

Calendario FullCalendar (timeGridWeek / timeGridDay) sobre GET /api/v1/booking/slots. Los slots disponibles se muestran como eventos; al seleccionar uno aparece un overlay con fecha, horario, recurso y tarifa (no un panel lateral). El slot elegido se comparte vía ReservationDraftContext para habilitar el paso siguiente del wizard.

Estructura de dashboard

{
  "dashboardId": "clients-list",
  "title": "Clientes",
  "layout": { "type": "grid", "columns": 12, "hideTitle": true },
  "widgets": {
    "table": {
      "type": "data-table",
      "config": {
        "path": "/api/v1/clients/clients",
        "columns": [{ "name": "name", "label": "Nombre" }]
      },
      "grid": { "xs": 12 }
    }
  }
}

Validación en bootstrap: framework/cortex_framework/panel/validate.py.

Títulos en widgets

Los widgets data-table, form e infolist no muestran cabecera de card si config.title está ausente. Evita fallbacks como "Tabla" o "Detalle". El título de pantalla lo muestra el shell cuando shellOwnsPageTitle está activo (ver Cortex Panel — jerarquía de títulos).

Aliases legacy

api-table y json-form siguen soportados. En plugins nuevos prefiere data-table y form.

Widget stats-overview

Bloque de KPIs con un solo fetch (equivalente a Filament StatsOverviewWidget). Ideal para pantallas home o cabeceras de módulo con varias métricas del mismo endpoint.

{
  "type": "stats-overview",
  "config": {
    "path": "/api/v1/resources/resources/summary",
    "columns": 3,
    "grid": { "xs": 12 },
    "stats": [
      { "key": "total_resources", "title": "Total recursos", "color": "slate" },
      { "key": "available", "title": "Disponibles", "color": "orange" }
    ]
  }
}

Cada key lee del payload un escalar (bookings_today: 23) o un objeto { "value": 115, "label": "64% del total" }. Colores: orange, green, blue, slate. Formato opcional: currency, number, text.

Builder Python:

from cortex_framework.ui import StatsOverviewBuilder

StatsOverviewBuilder()
    .path("/api/v1/demo/summary")
    .columns(3)
    .stat("total", "Total", color="slate")
    .stat("revenue", "Ingresos", color="green", format="currency")
    .to_widget()

Widget chart

Gráficos interactivos con Recharts (React nativo). El plugin expone datos REST; el shell renderiza.

Formatos de API soportados:

  1. Filas: { "items": [{ "label": "Lun", "value": 12 }] } o array directo.
  2. Multi-serie (estilo Chart.js): { "labels": [...], "datasets": [{ "label": "...", "data": [...] }] }.
{
  "type": "chart",
  "config": {
    "title": "Reservas de la semana",
    "description": "Comparativo semanal",
    "path": "/api/v1/operations/charts/bookings-trend",
    "chartType": "bar",
    "valueFormat": "number",
    "height": 300,
    "showLegend": true,
    "grid": { "xs": 12, "lg": 8 }
  }
}

chartType: bar (default), line, area, pie. valueFormat: currency, number, percent (tooltips y ejes).

Widget section

Agrupa hijos en el grid:

{
  "type": "section",
  "config": { "title": "Resumen" },
  "children": {
    "kpi": { "type": "stat-card", "config": { ... } }
  }
}

Extensión (avanzado)

En una app custom puedes registrar tipos adicionales en WidgetRegistry antes de montar PanelProvider. El plugin no importa React; solo declara JSON válido.

Siguiente paso

Layouts para composición y merge entre plugins.

Ver Cortex Panel (runtime) para el flujo de render.