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é
configexige 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:
- Filas:
{ "items": [{ "label": "Lun", "value": 12 }] }o array directo. - 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.