ADR 018: Routing de pantallas y jerarquía de títulos del panel¶
Estado¶
Aceptado — 2026-07
Relacionado con ADR 003 y ADR 012.
Contexto¶
El shell shadcn mostraba títulos duplicados (header del panel, ModuleScreen, DashboardRenderer, cards de widgets) y rutas ambiguas: una URL como /panel/resources/create podía resolverse contra path: ":id" con id=create, mostrando un infolist vacío en lugar de un formulario.
Los manifests manuales y el orden de screens[] no bastaban para garantizar el comportamiento correcto.
Decisión¶
1. Resolución de pantallas por especificidad¶
En @cortex/panel-core:
scoreScreenPath(path)— prioriza segmentos literales sobre parámetros (:id).matchModuleScreen(manifest, relativePath)— elige la pantalla coincidente con mayor score.relativeModulePath(pathname, moduleUrl)— obtiene el segmento relativo bajo un módulo.
ModuleScreen y PanelShell deben usar estos helpers; no reimplementar matching por orden de array.
2. Jerarquía de títulos¶
| Capa | Regla |
|---|---|
PanelShell | Un h1 por pantalla = screens[].title resuelto |
ModuleScreen | h2 solo si theme.shellOwnsPageTitle === false |
DashboardRenderer | h3 solo si layout.hideTitle === false |
| Widgets | CardTitle solo si config.title está definido |
3. Flags de tema (PanelTheme)¶
| Flag | Default en shadcn | Descripción |
|---|---|---|
shellOwnsPageTitle | true | El shell muestra el título de pantalla |
showPanelSubtitle | true | Muestra panel.title como subtítulo del header |
4. Defaults en ResourceBuilder¶
Los dashboards generados para list/create/edit/view usan emit_dashboard(..., hide_title=True).
Si TableBuilder no define título, se propaga el título del recurso al widget data-table.
El manifest emitido ordena pantallas: list → create → edit → view.
Consecuencias¶
- Manifests manuales con acción CREATE deben declarar
path: "create"explícitamente. - Plugins que migran a
ResourceBuilderobtienen routing y títulos correctos sin cambios en React. - Skins distintos de shadcn pueden dejar
shellOwnsPageTitleenfalsepara comportamiento legacy. - Tests unitarios en
routingParams.test.tsytest_ui_form_builder.pyfijan el contrato.
Referencias¶
- Cortex Panel — runtime
- Recursos (plugins)
packages/cortex-panel-core/src/routingParams.tspackages/cortex-panel-shadcn/src/shell/PanelShell.tsx