Skip to content

Directorio — miembros y gestión

La ruta /directory lista miembros de la organización (GET /identity/directory/members vía directoryService). El esquema DirectoryMemberResponseDto incluye roles (por defecto [] si el JSON no trae el campo). El repositorio actual del API devuelve roles: [] hasta que exista agregación por miembro; la UI usa member.roles ?? [] como respaldo. Cada fila muestra nombre, correo, avatar, insignias cuando hay roles, y antigüedad relativa (createdAt).

Diálogo de miembro

Layout inspirado en el diseño de ficha de contacto, sin datos ficticios:

  • Cierre: sin botón (X) en la esquina; el diálogo se cierra con clic en el fondo o tecla Escape (showCloseButton={false} en DialogContent).
  • Cabecera: avatar, nombre, insignias de roles cuando member.roles tiene entradas, fila tipo Directorio · <orgName> cuando orgName viene en el DTO, y acciones: teléfono y mensajes deshabilitados (sin API en directorio), correo como enlace mailto real.
  • Pestañas principales: todas son pestañas reales (TabsList variante línea: indicador bajo el título, color primario en activo). Al cambiar de pestaña, el disparador activo hace scroll suave dentro de la fila y se centra en horizontal (scrollIntoView con inline: 'center') cuando hay desbordamiento. Resumen y Tareas tienen contenido conectado al API; Suscripciones, Deals, Tickets y Notas muestran un estado vacío explícito hasta que existan endpoints.
  • Cuerpo (~34 % / ~66 %) en Resumen:
    • Columna izquierda (MemberDialogMetadataAside): correo real (etiqueta “Principal”) según el DTO del directorio; sin bloques de teléfono ni dirección hasta que el API los exponga.
    • Columna derecha: segunda fila de pestañas en variante línea (mismo estilo que las principales, scroll horizontal sin barra visible, mismo centrado al seleccionar): Seguridad primero (roles, excepciones de políticas, zona de riesgo); luego Información comercial, Interés comercial, Acceso y dispositivos, Preferencias y Resumen financiero (vacías hasta API).
      • Roles / Políticas pre-toggled: al abrir el diálogo, useMemberAccess(userId) hace GET /identity/organization/members/:userId/access y devuelve { roles, policies } reales del usuario en la org activa. Esa respuesta inicializa los switches, así que los roles y políticas ya asignados aparecen activados. Al guardar, se invalida memberAccessQueryKey(userId) para reflejar los cambios sin recargar.
  • Pestaña Tareas (misma proporción aproximada que Resumen): columna izquierda con cabecera “Tareas del miembro”, lista paginada vía GET /operations/tasks/search con creatorId, sort=-createdAt, page y limit, y controles de paginación cuando hay más de una página; columna derecha con el formulario de edición embebido (TaskDialog en modo embedded + useTaskDialog con uiMode: 'inline'). useTasksModule({ moduleEnabled, fetchTasks: false }) no descarga el tablero (listAllTasks). Los catálogos de estado/proyecto/etiqueta (fetchEditorCatalog) solo se piden cuando el usuario abre una tarea (selectores del editor); el nombre de estado en cada fila de la lista viene de ITaskResponse.status.

No se muestra información de 2FA ni dispositivos de otros usuarios: esos endpoints son de perfil propio.

Pestaña Tareas (datos reales)

El listado usa SearchTasksQuery / useDirectoryMemberTasks (creatorId = usuario del miembro, orden por createdAt descendente). Tras guardar en el editor embebido se invalida la query de búsqueda del directorio para refrescar la página actual; las mutaciones siguen actualizando la caché del tablero (listAllTasks) por si el usuario abre /tasks después.

Al guardar desde el editor embebido, la tarea se actualiza con las mismas mutaciones que el tablero; en modo inline el diálogo modal no se abre y el formulario se reinicializa con la respuesta del API y el checklist recargado.

Extensión futura

  • Campos extra del directorio (p. ej. teléfono) solo deben mostrarse cuando existan en el contrato del API.