Appearance
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}enDialogContent). - Cabecera: avatar, nombre, insignias de roles cuando
member.rolestiene entradas, fila tipo Directorio · <orgName> cuandoorgNameviene en el DTO, y acciones: teléfono y mensajes deshabilitados (sin API en directorio), correo como enlacemailtoreal. - Pestañas principales: todas son pestañas reales (
TabsListvariante 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 (scrollIntoViewconinline: '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)haceGET /identity/organization/members/:userId/accessy 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 invalidamemberAccessQueryKey(userId)para reflejar los cambios sin recargar.
- Roles / Políticas pre-toggled: al abrir el diálogo,
- Columna izquierda (
- Pestaña Tareas (misma proporción aproximada que Resumen): columna izquierda con cabecera “Tareas del miembro”, lista paginada vía
GET /operations/tasks/searchconcreatorId,sort=-createdAt,pageylimit, y controles de paginación cuando hay más de una página; columna derecha con el formulario de edición embebido (TaskDialogen modoembedded+useTaskDialogconuiMode: '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 deITaskResponse.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.