Personalizar el panel de administración
El panel de administración está construido a partir de partes que puedes usar tú mismo. Para personalizarlo, escribes un componente ordinario de React y lo colocas en una ubicación. Ese es todo el modelo:
- Bloques de construcción que renderizas: la tabla de una colección, el formulario de un registro, el kit de UI.
- Hooks para datos, el usuario autenticado, notificaciones toast y navegación.
- Ubicaciones donde colocar un componente: una página, un modo de vista de colección, un botón de barra de herramientas, una pestaña de registro, un campo, un slot junto a una parte integrada o un reemplazo que sustituye a una.
Si un bloque de construcción no hace lo que necesitas, copia su código fuente en tu proyecto y modifícalo. Nada aquí requiere que exista previamente una opción de configuración. Consulta Copiar una parte integrada.
Recetas
Sección titulada «Recetas»Se incluyen ejemplos funcionales y probados dentro de @rebasepro/cms, por lo que los que están en node_modules/@rebasepro/cms/recipes siempre coinciden con tu versión instalada. Solo importan paquetes públicos: copia uno en tu proyecto tal cual.
| Receta | Lo que muestra |
|---|---|
site-settings.tsx |
Un singleton: un único registro de configuración en su propia página, creado en el primer guardado. |
my-preferences.tsx |
Configuración por usuario: cada usuario edita el registro identificado por su uid. |
bulk-set-status.tsx |
Un botón de barra de herramientas que actualiza cada fila seleccionada. |
calendar-view.tsx |
Un nuevo modo de vista: las filas de una colección en una cuadrícula mensual. |
orders-dashboard.tsx |
Una página que lee datos, dibuja un gráfico y enlaza al panel de administración. |
custom-login.tsx |
Reemplazo de la pantalla de inicio de sesión. |
El archivo README.md junto a ellos es la referencia completa de bloques de construcción, hooks y ubicaciones.
Ejemplo: un singleton
Sección titulada «Ejemplo: un singleton»Un singleton no es un tipo de colección especial. Es una tabla ordinaria cuya página siempre abre la misma fila. Al proporcionarle un id a EntityFormPanel, este edita ese registro y lo crea bajo ese id la primera vez, por lo que no es necesario inicializar datos (seeding).
import React from "react";import { defineCollection } from "@rebasepro/cms-types";import type { AppView } from "@rebasepro/cms-types";import { EntityFormPanel } from "@rebasepro/cms";import { Container, Typography } from "@rebasepro/ui";
// config/collections/site_settings.ts — `rebase db push` creates the table.export const siteSettingsCollection = defineCollection({ name: "Site settings", slug: "site_settings", table: "site_settings", properties: { id: { name: "ID", type: "string", isId: true }, siteName: { name: "Site name", type: "string", validation: { required: true } }, maintenanceMode: { name: "Maintenance mode", type: "boolean" } }, admin: { hideFromNavigation: true, hideIdFromForm: true }});
// Add to <RebaseCMS views={[siteSettingsView]}>.export const siteSettingsView: AppView = { slug: "settings/site", name: "Site settings", icon: "Settings", view: ( <Container maxWidth={"3xl"} className={"py-8"}> <Typography variant={"h4"} gutterBottom>Site settings</Typography> <EntityFormPanel collection={siteSettingsCollection} entityId={"site"}/> </Container> )};La misma estructura con entityId={user.uid} (de useAuthController()) es una página de configuración por usuario.
Ubicaciones
Sección titulada «Ubicaciones»| Para agregar… | Coloca un componente en |
|---|---|
| Una página | <RebaseCMS views={[{ slug, name, icon, view }]}> |
| Un modo de vista para una colección | collectionViews={[{ key, name, Builder }]} y admin.customViews: ["key"] — consulta Modos de vista |
| Un botón en la barra de herramientas de una colección | admin.Actions: [Component] |
| Un botón en un registro | admin.entityActions — consulta Acciones de entidad |
| Una pestaña en un registro | admin.entityViews — consulta Vistas de entidad |
| Cómo se edita o muestra un campo | admin.Field / admin.Preview — consulta Campos personalizados |
| Algo junto a una parte integrada | <Rebase slots> — consulta Slots |
| Un reemplazo para una parte integrada | <Rebase components> — consulta Reemplazos de componentes |
Qué recibe tu componente en cada ubicación
Sección titulada «Qué recibe tu componente en cada ubicación»| Ubicación | Tu componente recibe |
|---|---|
Una página (views) |
Nada: lee lo que necesites con los hooks. Se renderiza dentro del router del panel, así que useUrlController().navigate(…) (o react-router) funciona. |
Un Builder de modo de vista |
CollectionCustomViewParams: collection, path, tableController (su data son las filas que seleccionan la búsqueda y los filtros de la barra de herramientas, dataLoading, …), onEntityClick(entity) para abrir una fila como la colección abre las filas, selectionController, emptyComponent. |
admin.Actions |
CollectionActionsProps: path, collection, selectionController (hasSelection, selection, clearSelection()), tableController, openNewDocument(defaults?). Convierte selection en filas con resolveSelection({ selection, accessor: useData().collection(path) }): puede representar “todas las filas que coinciden con el filtro”, no solo las marcadas. |
Builder de admin.entityViews |
EntityCustomViewParams: collection, el registro (entity, ausente mientras se crea), sus valores sin guardar (modifiedValues) y el formulario (formContext). |
"Auth.LoginView" |
{ authController }. Inicia sesión con authController.emailPasswordLogin?.(email, password) (opcional: presente cuando el inicio de sesión por correo está activado); un fallo lanza una excepción y también queda en authController.authProviderError. En cuanto authController.user tiene valor, el panel sustituye tu pantalla por sí solo. |
| Cualquier otro reemplazo | Las props de la parte que sustituye; con wrap: true, esas más OriginalComponent. |
| Hook | Paquete | Te proporciona |
|---|---|---|
useData |
@rebasepro/app |
useData().collection("orders").find / findById / create / update / delete, a través del servidor, por lo que se aplican callbacks y reglas de seguridad. |
useCollection / useFetch |
@rebasepro/app |
Una lista en tiempo real de filas / un registro individual en tiempo real. |
useAuthController |
@rebasepro/app |
El user autenticado (uid, roles), inicio de sesión y cierre de sesión. |
useSnackbarController |
@rebasepro/app |
open({ type, message }) para una notificación toast. |
useSidePanel |
@rebasepro/cms |
Abre cualquier registro en el panel lateral. |
useUrlController |
@rebasepro/cms |
URLs y navegación del panel de administración. |
resolveSelection |
@rebasepro/cms |
Una selección de tabla (filas marcadas o “todas las coincidentes”) como filas. |
Copiar una parte integrada
Sección titulada «Copiar una parte integrada»Cuando una parte integrada se acerca a lo que quieres, copia su código fuente del repositorio de @rebasepro/cms (o @rebasepro/app) en tu proyecto, apunta sus imports relativos a los paquetes, modifícala y regístrala con su nombre en <Rebase components>. Todo lo que importa una parte es una exportación pública, así que la copia compila, en todas las partes salvo tres, y esas tres son deliberadas:
Collection.Viewes la composición de todos los modos de vista (lista, tabla, tarjetas, tablero, dividida) con edición en línea, el editor de campos emergente, el diálogo de borrado y el estado del modo de vista en la URL. Lo que importa son los detalles internos de esos modos. Sustituye en su lugar una de sus partes (Collection.Table,Collection.Card,Collection.Actions,Collection.EmptyState, que se pueden copiar), añade un modo de vista propio o envuélvela conwrap: true.DetailViewes la composición de la vista de un registro: barra de identidad, pestañas, inspector y los botones de la lista dividida, en torno a identificadores de pestaña que son valores de la URL. Personaliza un registro con vistas de entidad, acciones de entidad, los slotsform.*o los reemplazosEntity.FormyEditView.FormActions, que se pueden copiar.HomePagese puede copiar salvo por la reordenación de tarjetas y grupos con arrastrar y soltar, que no tiene una API propia que exportar. Una página de inicio propia componeNavigationGroup,NavigationCardBindingyFavouritesViewsobreuseNavigationStateController().topLevelNavigation; para añadir algo a la página estándar, usa el slothome.cards.