Último artículo de esta serie sobre los 25 nuevos componentes de sgcHTML. Cerramos con los tres que todo panel de administración acaba necesitando: quién está conectado ahora mismo, quién puede hacer qué, y la tabla donde realmente gestionas las cuentas. Los tres envían actualizaciones en vivo por el mismo canal WebSocket que ya usan tus pantallas de chat y de progreso de tareas, así que este bloque encaja directamente junto a los componentes de los artículos anteriores.
Presence — una lista en vivo de usuarios conectados
TsgcHTMLComponent_Presence renderiza una pila de avatares superpuestos o una lista de nombre y estado, limitada por MaxVisible con una chip de desbordamiento "+N". AddUser inserta o actualiza una entrada de la lista, SetUserStatus actualiza solo el punto de estado, y GetUserFragmentHTML envía ese único cambio a todos los clientes conectados.
uses
sgcHTML_Component_Presence;
var
oPresence: TsgcHTMLComponent_Presence;
begin
oPresence := TsgcHTMLComponent_Presence.Create(nil);
try
oPresence.PresenceID := 'roster';
oPresence.Layout := plAvatars;
oPresence.MaxVisible := 5;
oPresence.Title := 'Online';
oPresence.AddUser('u1', 'Ana Torres', psOnline);
oPresence.AddUser('u2', 'Marc Bell', psAway, '', 'Back at 3pm');
oPresence.AddUser('u3', 'Kenji Ito', psBusy);
WebModule.Response := oPresence.HTML; // avatar stack + scoped CSS
finally
oPresence.Free;
end;
end;
// Push a status change to every connected client, no full re-render:
oPresence.SetUserStatus('u2', psOnline);
TsgcHTMX_Engine_Server.BroadcastFragment(oPresence.GetUserFragmentHTML('u2'));
RolesPermissions — una matriz de asignación, no un formulario lleno de casillas
TsgcHTMLComponent_RolesPermissions organiza los roles en columnas y los permisos en filas (agrupados por categoría), con una casilla en cada intersección. AddRole y AddPermission construyen los dos ejes, SetGrant marca las casillas iniciales, y cada cambio realizado en el cliente llega al servidor como un payload JSON que tu manejador debe autorizar antes de aplicarlo con ProcessGrantChanged.
uses
sgcHTML_Enums, sgcHTML_Component_RolesPermissions;
var
oMatrix: TsgcHTMLComponent_RolesPermissions;
begin
oMatrix := TsgcHTMLComponent_RolesPermissions.Create(nil);
try
oMatrix.MatrixID := 'acl';
oMatrix.StickyHeader := True;
oMatrix.AddRole('admin', 'Administrator').Color := hcDanger;
oMatrix.AddRole('editor', 'Editor');
oMatrix.AddRole('viewer', 'Viewer');
oMatrix.AddPermission('users.edit', 'Edit users', 'Users');
oMatrix.AddPermission('users.delete', 'Delete users', 'Users');
oMatrix.AddPermission('billing.view', 'View invoices', 'Billing');
oMatrix.SetGrant('admin', 'users.edit', True);
oMatrix.SetGrant('admin', 'users.delete', True);
oMatrix.SetGrant('editor', 'users.edit', True);
WebModule.Response := oMatrix.HTML; // matrix table + inline script
finally
oMatrix.Free;
end;
end;
// Server-side handler for a checkbox toggle received over WebSockets.
// ALWAYS verify the acting user is authorized before applying the change:
oMatrix.ProcessGrantChanged('editor', 'users.delete', True);
UserManagement — la propia tabla de cuentas
TsgcHTMLComponent_UserManagement es la tabla donde se asignan esos roles: avatar, badge de estado, badges de roles, último inicio de sesión, cuadro de búsqueda, y un desplegable de acciones por fila (editar, deshabilitar/habilitar, restablecer contraseña y, si lo activas, suplantar y eliminar). AddUser añade una fila y devuelve un TsgcHTMLUser para rellenar; ProcessUserAction gestiona lo que envíe el desplegable de cada fila, de nuevo solo después de tu propia comprobación de autorización.
uses
sgcHTML_Component_UserManagement;
var
oUsers: TsgcHTMLComponent_UserManagement;
oUser: TsgcHTMLUser;
begin
oUsers := TsgcHTMLComponent_UserManagement.Create(nil);
try
oUsers.TableID := 'users';
oUsers.AllowImpersonate := True;
oUsers.AllowDelete := True;
oUser := oUsers.AddUser('u1', 'ana.torres', 'ana@example.com');
oUser.DisplayName := 'Ana Torres';
oUser.Roles := 'admin,editor';
oUser.Status := usActive;
oUser.LastLogin := '2026-07-15 09:12';
oUsers.AddUser('u2', 'marc.bell', 'marc@example.com').Status := usInvited;
WebModule.Response := oUsers.HTML; // toolbar + table + inline script
finally
oUsers.Free;
end;
end;
// Server-side handler for an action received over WebSockets.
// ALWAYS verify the acting user is authorized before applying it:
oUsers.ProcessUserAction('userDisable', 'u2');
Fíjate en el patrón que se repite tanto en RolesPermissions como en UserManagement: el componente solo renderiza la interfaz y emite un evento. Nada cambia de estado hasta que tu propio código de servidor decide que el usuario que actúa tiene permiso para hacer ese cambio, y entonces llama explícitamente a ProcessGrantChanged o ProcessUserAction. El componente nunca autoriza nada por ti, por diseño.
Fin de la serie
Veinticinco componentes repartidos en cinco artículos: datos estructurados (TreeGrid, PivotTable, ActivityFeed, Splitter), gráficos y códigos (Heatmap, Sparkline, CandlestickChart, TreeMap, QRCode, Barcode), campos de formulario (MultiSelect, ColorPicker, Slider, TimePicker, SignaturePad, Transfer), feedback y maquetación (Badge, PDFViewer, ContextMenu, ProgressBar, JobProgress, LogViewer), y los tres componentes de administración de hoy. La matriz completa de funcionalidades ahora incluye 83 componentes repartidos en nueve familias, y cada uno de ellos está documentado con una guía rápida en Delphi, C++Builder y .NET en su propia página, incluidos Presence, RolesPermissions y UserManagement.
¿Preguntas, comentarios o ayuda con la migración? Ponte en contacto — recibirás respuesta de las personas que escribieron el código.
