CreaRack-SL

Feature s77: Gestor transversal de comentarios, badge cyan y deep-links de tareas

Resumen

PR#57 (2026-05-20, @Esquembri) agrupa 5 mejoras del menú Tareas encadenadas, todas bajo la referencia interna s77. El objetivo central es hacer el módulo de tareas más navegable: los comentarios son visibles desde las tarjetas, existe una vista dedicada para gestionarlos, y los deep-links desde el widget del escritorio funcionan de forma fiable.

Mejoras incluidas

Problema: al hacer click en una tarjeta del widget KanbanMini (que navega a /tasks?task=N), el modal no se abría. El useEffect que sincronizaba modalTask → URL borraba el parámetro ?task=N antes de que el effect lector pudiera ejecutarse (las tasks todavía estaban loading=true al montar).

Solución (TaskManager.tsx):

// Guard añadido en el useEffect de sincronización modalTask → URL
if (loading && modalTask === null) return;

Además, loading se añadió como dependencia del efecto ([modalTask, loading]) para que se re-evalúe cuando la carga termine.

2. Badge “comentarios” en tarjetas (tinte cyan)

  • functions/api/tasks/index.ts: subquery añadida al SELECT principal:
    (SELECT COUNT(*) FROM task_comments WHERE task_id = tasks.id) AS comment_count
  • src/lib/types.ts y TaskModal.tsx: campo comment_count?: number añadido a la interfaz Task.
  • TaskKanban.tsx y KanbanMini.tsx: chip task-link-badge task-link-badge-comment mostrado cuando comment_count > 0.
  • CSS (globals.css): clase .task-link-badge-comment con tinte cyan (var(--accent-2) al 14%) para distinguirlo visualmente de los badges de emails/eventos Zoho.
.task-link-badge-comment {
  background: color-mix(in srgb, var(--accent-2) 14%, transparent);
  color: var(--accent-2);
}

3. Gestor transversal de comentarios

Nueva vista en /tasks?view=comments que muestra todos los comentarios del workspace con filtros avanzados.

Componente: src/components/tasks/TaskCommentsView.tsx (333 LOC).

Filtros disponibles en la filter bar:

FiltroTipoAPI param
Buscar en cuerpotext inputq
Autorselect (TEAM_FILTER)author
Destinatarioselect (TEAM_FILTER)target_user
Título de tareatext inputtask_title
Desdedate inputstart_date
Hastadate inputend_date

Paginación: PAGE_SIZE = 50, botón “Cargar más” (offset acumulativo). El total visible se muestra como N/total comentarios.

Cards clickables: cada article.task-comment-card abre el TaskModal de la tarea origen mediante onOpenTask(associatedTask). Si la tarea ya no está en memoria, navega directamente a /tasks?task=<id>.

Integración en TaskManager:

  • Nueva opción en el type View: 'board' | 'list' | 'calendar' | 'comments'.
  • Tab { key: 'comments', label: 'Comentarios' } en la barra de pestañas.
  • URL persistida: ?view=comments mediante replaceState. Al montar, se lee el param ?view= para restaurar la vista activa.

4. Botón “Nueva” del widget abre modal de creación

DesktopA.tsx: el botón “Nueva” del widget Tareas cambia de href="/tasks" a href="/tasks?task=new". TaskManager ya leía ese parámetro para abrir el modal en modo CREAR. Texto actualizado a + Nueva.

5. Enlace nota → modal tarea

TaskModal.createAndLinkNote: al crear una nota desde el modal de edición de una tarea existente (cuando task?.id existe), se inyecta al inicio del contenido de la nota:

[Nota asociada a tarea #N](/tasks?task=N)

En la vista preview del cuaderno (modo markdown), el link es clickable y navega a /tasks?task=N, abriendo el modal de edición de esa tarea.

Archivos modificados

ArchivoTipo de cambio
functions/api/tasks/comments.tsNuevo — endpoint CF Pages Function
functions/api/tasks/index.tsModificado — añade subquery comment_count
src/components/tasks/TaskCommentsView.tsxNuevo — componente React (333 LOC)
src/components/tasks/TaskKanban.tsxModificado — chip badge comentarios
src/components/tasks/TaskManager.tsxModificado — tab comments, view URL, fix race condition
src/components/tasks/TaskModal.tsxModificado — comment_count en interfaz + inject link nota
src/components/variants/desktop/DesktopA.tsxModificado — botón ?task=new
src/components/widgets/KanbanMini.tsxModificado — chip badge comentarios
src/lib/types.tsModificado — campo comment_count en Task
src/styles/globals.cssModificado — .task-link-badge-comment, .task-comment-card

Estilos CSS introducidos

/* Badge comentarios (tinte cyan) */
.task-link-badge-comment { … }

/* Card gestor transversal — clickable */
.task-comment-card { … }
.task-comment-card:hover { … }

Decisiones de diseño destacadas

  • Race condition guard: la solución es mínima y localizada; se prefirió un guard de una línea sobre refactorizar el flujo de efectos completo.
  • Separación de endpoint: se creó functions/api/tasks/comments.ts separado del index principal para mantener cohesión y facilitar caching/permisos futuros por ruta.
  • Pattern { results, total }: reutiliza el shape de /api/activity para minimizar código nuevo en el frontend de paginación.
  • target_user_ids LIKE con comillas: previene falsos positivos en nombres cortos (e.g. “Ed” en “Edu”) sin necesitar JSON functions de SQLite.

Véase también

  • [[entity—tasks—endpoint—api-tasks-comments]]
  • [[entity—tasks—endpoint—api-tasks-index]]