Skip to content

UX: Visualización de Task IDs en el Dashboard (#2641)#67

Merged
kelvinCB merged 12 commits intomainfrom
feat/visualize-task-ids-2641
Feb 14, 2026
Merged

UX: Visualización de Task IDs en el Dashboard (#2641)#67
kelvinCB merged 12 commits intomainfrom
feat/visualize-task-ids-2641

Conversation

@kelvinCB
Copy link
Owner

@kelvinCB kelvinCB commented Feb 14, 2026

🎯 Objetivo

Habilitar la visualización del ID numérico de las tareas en la interfaz de usuario de Kolium.com para facilitar la comunicación entre humanos y agentes IA.

🏁 Resultado Esperado

Los IDs de las tareas (#ID) ahora son visibles de forma consistente en:

  • Board View: En cada tarjeta de tarea.
  • Tree View: En cada fila de la lista de tareas.
  • Task Detail Modal: En el encabezado del modal de detalles.

🛠️ Cambios Realizados

  • Creado componente compartido TaskIdBadge para asegurar consistencia visual y accesibilidad.
  • Creado componente compartido TruncatedTaskTitle para unificar la lógica de truncamiento de títulos largos.
  • Refactorizados TaskBoard.tsx, TaskItem.tsx y TaskDetailModal.tsx para usar los nuevos componentes.
  • Corregidos problemas de contraste y soporte para emojis en el truncamiento.

✅ Verificación

  • Visualización correcta en modo claro y oscuro.
  • Tests unitarios actualizados y pasando.
  • Sin regresiones en el flujo de edición o movimiento de tareas.

Closes #2641

@vercel
Copy link

vercel bot commented Feb 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
task-manager-llwv Ready Ready Preview, Comment Feb 14, 2026 2:14pm

@github-actions
Copy link

Kimi K2.5 Co-Review

P2 TaskBoard.tsx, TaskItem.tsx, TaskDetailModal.tsx
Issue: Inconsistencia de diseño y posible valor undefined. Los tres archivos usan tamaños y opacidades diferentes para el ID (10px/60%, 11px/50%, text-lg/40%), lo que rompe la coherencia visual del sistema de diseño. Además, si task.id es undefined o null, renderizará "#undefined" sin fallback.
Recomendación: Extraer un componente TaskIdBadge compartido con estilos consistentes y agregar validación: {task.id && <span>#{task.id}</span>} o usar optional chaining.

P3 TaskBoard.tsx, TaskItem.tsx
Issue: Duplicación de lógica de truncamiento. La misma lógica condicional (maxLength, isLong, botón "..." y clases de tema) está duplicada en ambos archivos.
Recomendación: Extraer a un componente utilitario TruncatedTaskTitle o hook compartido para evitar divergencia futura.

P3 TaskDetailModal.tsx
Issue: Contraste de accesibilidad. Opacidad 40% (opacity-40) sobre fondo claro/oscuro puede no cumplir WCAG AA para texto pequeño.
Recomendación: Verificar ratio de contraste o aumentar a opacity-60 mínimo.


Nota de regresión: ✅ Sin regresiones funcionales detectadas. El comportamiento de truncate se preserva correctamente (solo aplica cuando el título no excede el límite).

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

P1 - Regresión visual en tareas completadas

  • Archivo: src/components/TaskItem.tsx y src/components/ui/TruncatedTaskTitle.tsx
  • Problema: TruncatedTaskTitle aplica colores de texto hardcodeados (text-gray-900/text-gray-100) en el <h3> interno, ignorando las clases de color pasadas vía className (como text-gray-500 para tareas Done). Esto provoca que las tareas completadas no se muestren en gris atenuado.
  • Recomendación: Modificar TruncatedTaskTitle para aceptar una prop titleClassName que se mergee con las clases internas del título, o usar clsx/tailwind-merge para combinar clases correctamente.

P2 - Accesibilidad y comportamiento del botón

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx
  • Problema: El botón "..." carece de type="button" (riesgo de submit accidental si se usa dentro de un formulario futuro) y no tiene aria-label (lectores de pantalla anuncian solo "button" sin contexto).
  • Recomendación: Añadir type="button" y aria-label="Ver título completo o editar tarea" al botón de expansión.

P2 - Inconsistencia de truncamiento

  • Archivo: src/components/TaskBoard.tsx vs src/components/TaskItem.tsx
  • Problema: El mismo componente usa maxLength={40} en un lugar y maxLength={60} en otro sin documentación. Esto genera UX inconsistente (el usuario ve "..." en el board pero el título completo en la lista para el mismo texto).
  • Recomendación: Estandarizar a un valor único o documentar via prop name (ej: compactView={true}) por qué difieren.

P3 - Defensiva contra datos nulos

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx
  • Problema: Si task.title es null/undefined (datos corruptos o API incompleta), task.title.length lanzará runtime error.
  • Recomendación: Usar task.title?.length ?? 0 o valores por defecto.

P3 - Layout shift en ID largos

  • Archivo: src/components/ui/TaskIdBadge.tsx
  • Problema: Si id es un UUID largo o string extenso, no hay truncamiento (truncate o max-width), pudiendo romper layouts en móviles.
  • Recomendación: Añadir truncate o max-w-[100px] al span del badge.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

P1 | src/components/ui/TruncatedTaskTitle.tsx
Regresión: Tema oscuro no aplicado al botón "..."
El código original en TaskItem usaba text-indigo-400 hover:text-indigo-300 para dark mode, pero el nuevo componente hardcodea text-indigo-600 sin consultar el tema.
Recomendación: Usar useTheme para aplicar clases condicionales al botón.

P1 | src/components/ui/TruncatedTaskTitle.tsx
Regresión: Cambio de jerarquía de headings
TaskBoard.tsx usaba <h4> para los títulos, pero TruncatedTaskTitle fuerza un <h3> hardcodeado, rompiendo la estructura semántica del documento.
Recomendación: Aceptar una prop as?: 'h2' | 'h3' | 'h4' o renderizar el título con <span> para no imponer jerarquía.

P2 | src/components/ui/TruncatedTaskTitle.tsx
Aplicación incorrecta de className
La prop className se aplica al div contenedor, no al elemento de texto (h3). Esto hace que font-bold y line-through pasados desde TaskItem no afecten visualmente al título (van al wrapper).
Recomendación: Separar en containerClassName y titleClassName, o aplicar className directamente al h3.

P2 | src/components/ui/TruncatedTaskTitle.tsx
UX misleading: Botón "..." siempre edita
El aria-label dice "Ver título completo o editar", pero el onClick siempre ejecuta onEdit(task). No existe la opción de solo ver el título completo sin entrar en modo edición.
Recomendación: Añadir un title nativo al botón con el texto completo, o implementar un tooltip/expansión inline antes de forzar la edición.

P3 | src/components/ui/TruncatedTaskTitle.tsx
Falta validación de maxLength
No se valida que maxLength sea positivo. Si se pasa 0 o un valor negativo, isLong será true y substring podría comportarse de forma inesperada.
Recomendación: Añadir const safeMaxLength = Math.max(1, maxLength);.

P3 | src/components/TaskDetailModal.tsx
Espaciado inconsistente del ID
TaskIdBadge tiene mr-1.5, pero al renderizarse inmediatamente antes de {task.title} dentro del <h2>, el espaciado puede ser insuficiente dependiendo del font-size. Además, el badge usa truncate max-w-[100px] dentro de un h2 con break-words, lo que puede causar comportamientos de layout impredecibles en viewports pequeños.
Recomendación: Añadir un espacio explícito ({' '}) o flex layout entre el badge y el título.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

P2 – TruncatedTaskTitle.tsx: IDs con valor 0 no se renderizan

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx:41
  • Problema: La condición {task.id && <TaskIdBadge ... />} evalúa 0 como falsy, ocultando el badge para tareas con ID cero (valor válido).
  • Recomendación: Usar task.id != null o Number.isFinite(task.id).

P2 – Regresión visual: pérdida de colores temáticos en títulos

  • Archivo: src/components/TaskItem.tsx:232-238, src/components/TaskBoard.tsx:192-198
  • Problema: El componente extraído aplica style={{ color: 'inherit' }} y titleClassName ya no incluye las clases ${theme === 'dark' ? 'text-gray-100' : 'text-gray-900'}. Si el contenedor padre no define el color explícitamente, el texto puede heredar colores incorrectos o defaults del navegador.
  • Recomendación: Inyectar las clases de color del tema dentro de TruncatedTaskTitle o pasarlas explícitamente en titleClassName en cada consumidor.

P2 – Accesibilidad: aria-label potencialmente masivo

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx:49
  • Problema: aria-label={Ver título completo: ${title}} usa el string completo sin truncar. Títulos extremadamente largos (1k+ chars) pueden saturar screen readers.
  • Recomendación: Truncar el aria-label a ~100 caracteres o usar aria-labelledby apuntando al tooltip nativo (title attribute).

P3 – Jerarquía de headings inconsistente (a11y)

  • Archivo: src/components/TaskItem.tsx:232
  • Problema: El diff cambia el elemento de h3 a h4 (as="h4"). Si no existe un h3 intermedio en la página, se rompe la secuencia lógica de headings para usuarios de lectores de pantalla.
  • Recomendación: Mantener as="h3" en TaskItem para preservar la jerarquía semántica original.

P3 – TaskIdBadge trunca IDs largos (UUIDs)

  • Archivo: src/components/ui/TaskIdBadge.tsx:25
  • Problema: max-w-[100px] puede cortar IDs tipo UUID (36 chars) en fuentes monoespaciadas grandes.
  • Recomendación: Hacer max-w configurable via prop o removerlo para IDs opacos.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

P2 | src/components/TaskItem.tsx
Regresión visual en tareas completadas: El título de tareas con status === 'Done' perdió la clase text-gray-500 que lo atenuaba. Anteriormente el texto completo se veía gris + tachado; ahora solo tiene tachado (line-through) pero mantiene el color de texto principal (negro/blanco según tema).
Recomendación: Incluir text-gray-500 (o equivalente según tema) en titleClassName cuando task.status === 'Done', o manejar el estado "completado" dentro de TruncatedTaskTitle.

P2 | src/components/ui/TruncatedTaskTitle.tsx
Lógica frágil de detección de color: La condición titleClassName.includes('text-') detecta cualquier clase utility de Tailwind que empiece con "text-" (ej: text-center, text-lg, text-base), no solo colores. Esto impide que se aplique el color por defecto del tema cuando se usan esas clases.
Recomendación: Usar una regex más específica (ej: /text-(gray|red|blue|indigo|green|yellow|white|black|transparent)-/ o verificar contra una lista de colores permitidos).

P2 | src/components/ui/TruncatedTaskTitle.tsx
Semántica HTML inválida: El <button> "..." está anidado dentro de un elemento heading (<h2>, <h3>, <h4>). HTML no permite contenido interactivo dentro de headings, lo que puede romper la navegación con screen readers o causar comportamientos inesperados en algunos browsers.
Recomendación: Mover el botón fuera del heading (hermano del mismo contenedor flex) o usar un <span role="button"> si es estrictamente necesario mantener la estructura, aunque lo ideal es separar la acción de edición del título semántico.

P3 | src/components/TaskDetailModal.tsx
Posible solapamiento de layout: El pr-8 (padding-right) existente en el <h2> asumía cierto ancho para botones de acción. Al añadir <TaskIdBadge> dentro del heading, el espacio disponible para el título se reduce, pudiendo causar truncamiento prematuro o solapamiento en viewports pequeños.
Recomendación: Verificar que el contenedor padre tenga min-width: 0 y considerar mover el TaskIdBadge fuera del flujo del heading (ej: como elemento flotante o en el header separado) si el espacio es crítico.

P3 | src/components/ui/TruncatedTaskTitle.tsx
Riesgo de hydration mismatch: El uso de useTheme() sin guarda contra SSR puede causar diferencias de hidratación si el servidor renderiza con un tema por defecto y el cliente con otro (basado en localStorage).
Recomendación: Añegir un efecto mounted o usar suppressHydrationWarning en el contenedor si la app usa SSR/SSG.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

P2 | TruncatedTaskTitle.tsx | Overflow risk on long truncated titles
The <span> containing the title only applies truncate when !isLong. When the title exceeds maxLength, the truncated text (60 chars) + the "..." button could overflow the flex container if the available width is narrow (e.g., mobile sidebar). The outer div has min-w-0, but the inner span lacks truncate or overflow-hidden for the long case.
Recommendation: Always apply truncate to the span, or wrap the text+button in a container with overflow-hidden.

P2 | TruncatedTaskTitle.tsx | Fragile color class detection
The regex /\btext-(?:[a-z]+(?:-[0-9]{2,3})?.../ fails for arbitrary Tailwind values like text-[#123456], text-[14px], or text-inherit. If such classes are passed via titleClassName, the component incorrectly injects the default text-gray-100/900, causing visual conflicts.
Recommendation: Replace regex with an explicit prop disableDefaultColor?: boolean or remove automatic color injection entirely when titleClassName is provided.

P2 | TruncatedTaskTitle.tsx | Poor button affordance
The "..." button to expand/edit lacks visual cues that it is clickable (no cursor-pointer, underline, or hover state beyond color). Users may mistake it for static truncation ellipsis.
Recommendation: Add cursor-pointer and hover:underline to the button.

P2 | TruncatedTaskTitle.tsx | Emoji split in aria-label
title.substring(0, 100) can slice surrogate pairs (emojis), producing invalid Unicode characters in the aria-label, potentially breaking screen readers.
Recommendation: Use Array.from(title).slice(0, 100).join('') or similar Unicode-safe truncation.

P2 | Consistency | Task ID semantic placement differs
In TaskDetailModal, the TaskIdBadge is rendered inside the <h2> (part of the heading), while in TruncatedTaskTitle it is rendered outside the heading element (sibling in a div). This creates inconsistent DOM structure for assistive technologies.
Recommendation: Unify placement—either always inside the heading text or always outside.

P3 | TaskIdBadge.tsx | Truncated ID lacks tooltip
The badge uses truncate max-w-[120px] but has no title attribute. Long IDs (UUIDs) are unreadable when clipped.
Recommendation: Add title={String(id)} to the span.

P3 | TaskIdBadge.tsx | Arbitrary Tailwind values
Uses text-[10px] and text-[11px] which fall outside standard design system scales.
Recommendation: Use text-xs (12px) or document these custom sizes in the theme config.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

P2 | src/components/ui/TruncatedTaskTitle.tsx
Issue: El truncamiento usa title.substring(0, safeMaxLength), que puede romper caracteres Unicode multibyte (emojis, símbolos CJK) generando "replacement characters" (�) si el corte cae en medio de un surrogate pair.
Recomendación: Usar el mismo enfoque que el aria-label:

const titleContent = isLong 
  ? Array.from(title).slice(0, safeMaxLength).join('') 
  : title;

P3 | src/components/ui/TruncatedTaskTitle.tsx
Issue: La regex hasColorClass no detecta clases de color sin número (text-current, text-transparent, text-inherit), causando que el color por defecto del tema sobrescriba el valor explícito proporcionado en titleClassName.
Recomendación: Añadir estos casos a la condición:

|| ['text-current', 'text-transparent', 'text-inherit'].some(c => titleClassName.includes(c))

P3 | src/components/TaskItem.tsx
Issue: Regresión visual: el color por defecto cambia de text-gray-800 (original) a text-gray-900 (vía el componente extracto) en tema claro para tareas no completadas.
Recomendación: Especificar explícitamente text-gray-800 en titleClassName cuando task.status !== 'Done' para mantener consistencia, o actualizar el theme del componente para coincidir con el diseño anterior.

P3 | src/components/TaskBoard.tsx
Issue: Cambio de comportamiento no documentado: maxLength pasó de 40 a 60 caracteres, lo que puede afectar layouts densos o móviles.
Recomendación: Confirmar si es intencional; de lo contrario, revertir a 40 o hacerlo configurable vía props.

Approved con observaciones menores: No se detectan issues de seguridad (XSS, injections) ni regresiones funcionales críticas. La lógica de stopPropagation es ahora consistente entre TaskBoard y TaskItem (ambos previenen la propagación al abrir el editor), lo cual corrige un potencial bug en el componente anterior.

@github-actions
Copy link

Kimi K2.5 Co-Review

P1 – UX/Accessibility: Acción confusa en botón de truncamiento

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx (líneas 56-64)
  • Problema: El aria-label dice "Ver título completo" pero el onClick ejecuta onEdit (abre edición), no muestra el título. Esto confunde a usuarios de lectores de pantalla.
  • Recomendación: Cambiar el label a algo como Editar tarea: ${title} o separar la acción de "ver más" de "editar". Si el botón abre el modal de edición, el label debe reflejarlo: aria-label="Editar tarea (título truncado)".

P2 – Regresión Visual: Cambio de color y peso de fuente no intencional

  • Archivo: src/components/TaskBoard.tsx (línea 192-198)
  • Problema: El código original usaba font-medium y text-gray-900 (light mode). El nuevo titleClassName usa font-bold y el componente aplica text-gray-800 por defecto, alterando el diseño visual incluso cuando la tarea no está completada (Done).
  • Recomendación: Mantener consistencia: usar font-medium y asegurar que el color por defecto en light mode sea text-gray-900, o documentar explícitamente el cambio de diseño en la descripción del PR.

P2 – Correctness: Falta de validación de callback

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx (línea 59)
  • Problema: No se verifica si onEdit está definido antes de llamarlo. Si el padre pasa undefined, el botón fallará silenciosamente o lanzará error al hacer click.
  • Recomendación: Hacer onEdit obligatoria en la interfaz o añadir guarda: if (onEdit) onEdit(task).

P2 – UX: ID dentro del heading semántico

  • Archivo: src/components/TaskDetailModal.tsx (línea 69-72)
  • Problema: El TaskIdBadge se renderiza dentro del <h2>, por lo que los lectores de pantalla anunciarán el ID como parte del título del documento (ej: "número 123 Mi Tarea"), dificultando la navegación por encabezados.
  • Recomendación: Mover el badge fuera del <h2> (ej: como un elemento previo) o usar aria-labelledby para excluirlo del nombre accesible del heading.

P2 – Correctness: Truncamiento inconsistente

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx (líneas 28-29)
  • Problema: Se trunca lógicamente a maxLength caracteres (usando Array.from para Unicode) pero el CSS truncate también corta visualmente. Si el contenedor es muy estrecho, el usuario verá "..." del CSS sin saber si hay más contenido real, o verá el botón "..." del código cuando aún hay espacio visual.
  • Recomendación: Eliminar la lógica de truncamiento por longitud de string y confiar solo en CSS truncate, o viceversa, pero no ambos. Si se mantiene la lógica de 40/60 caracteres, considerar usar line-clamp-1 en lugar de truncate para consistencia.

P3 – Seguridad: Sanitización en atributo ARIA

  • Archivo: src/components/ui/TruncatedTaskTitle.tsx (línea 31)
  • Problema: El safeAriaLabel concatena directamente el título. Aunque React escapa JSX, títulos con comillas dobles podrían romper el HTML generado en el atributo aria-label.
  • Recomendación: Usar una función de escape para atributos HTML o asegurar que el título no contenga caracteres de control antes de interpolar.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

P2 | src/components/ui/TruncatedTaskTitle.tsx
Inconsistencia de tipos en onEdit: La interfaz declara onEdit como requerido (onEdit: (task: Task) => void), pero el código lo trata como opcional (if (onEdit) onEdit(task)). Esto es incorrecto: si es requerido, el check es innecesario; si pretende ser opcional, debe marcarse como onEdit?: ... en la interfaz.

P3 | src/components/ui/TruncatedTaskTitle.tsx
Fragilidad en detección de clases de color: El regex hasColorClass no detecta variantes de estado (ej. hover:text-red-500, md:text-blue-400), por lo que podría inyectar clases de color del tema por defecto y sobrescribir intencionalmente estilos responsivos o de interacción.

P3 | src/components/ui/TaskIdBadge.tsx
Hardcoded max-width: El valor max-w-[140px] puede truncar agresivamente IDs largos (UUIDs). Considerar hacerlo configurable vía prop o usar max-w-full con contenedor padre flexible.

Nota UX: El refactor preserva el comportamiento donde el botón "..." para editar solo aparece en títulos truncados. Esto es inconsistente (el usuario no puede saber que debe hacer clic en "..." sin hover), pero mantiene paridad con el código original.

@kelvinCB
Copy link
Owner Author

He aplicado las correcciones para la ronda 3 del co-review:

  • TruncatedTaskTitle: ahora es opcional en la interfaz para coincidir con el uso interno.
  • TruncatedTaskTitle: Se mejoró el regex de colores para detectar variantes con prefijos (ej. , ).
  • TaskIdBadge: Se añadió la prop (default ) para permitir configurarlo o desactivarlo si es necesario.

Quedo a la espera de la validación de Kimi.

@kelvinCB
Copy link
Owner Author

He aplicado las correcciones de la ronda 3:

  • onEdit ahora es opcional en la interfaz.
  • Mejorado el regex de colores para detectar prefijos de Tailwind.
  • TaskIdBadge ahora acepta prop maxWidth.

@kelvinCB
Copy link
Owner Author

Kimi K2.5 Co-Review

Kimi review failed: request error/timeout.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

P1 - Test Incorrecto
src/test/components/ui/TaskIdBadge.test.tsx
El test espera la clase text-[10px] para el tamaño xs, pero el componente implementa text-xs scale-90 origin-left. Esto provocará un fallo en CI.
Recomendación: Actualizar el test para buscar text-xs (y opcionalmente verificar scale-90) en lugar de la clase arbitraria inexistente.

P2 - Inconsistencia de Localización
src/components/ui/TruncatedTaskTitle.tsx
El aria-label del botón de expansión usa español ("Editar tarea") mientras que toda la documentación, tests y componentes vecinos están en inglés.
Recomendación: Cambiar a "Edit task: ${title}" para mantener consistencia con el resto de la codebase.

P2 - Riesgo de Regresión Visual
src/components/ui/TruncatedTaskTitle.tsx
La refactorización envuelve el título en un div flex y modifica la estructura DOM (anteriormente el heading era el root). Esto puede alterar el espaciado, el flujo del layout o el comportamiento de truncamiento en contenedores padre con overflow específico (ej. Board vs Tree view).
Recomendación: Verificar manualmente en ambas vistas (Board y Tree) que el alineamiento vertical y el truncamiento se comportan igual que antes, especialmente con tareas marcadas como Done (line-through).

P3 - Defensa de Tipos
src/components/ui/TruncatedTaskTitle.tsx
Aunque TypeScript define task: Task, no hay validación runtime. Si por algún edge case se pasa null o undefined, el acceso a task.title lanzará excepción.
Recomendación: Añadir guard clause opcional: if (!task) return null;.

P3 - Uso de Coerción
src/components/TaskDetailModal.tsx
Se usa task.id != null (coerción) en lugar de !==. Aunque funciona para cubrir undefined y null, es menos explícito para otros mantenedores.
Recomendación: Considerar task.id !== undefined && task.id !== null o asegurar que el tipo sea string | number y usar truthy check si cero no es un ID válido.

@github-actions
Copy link

Kimi K2.5 Co-Review

Findings

  • P2 src/components/ui/TaskIdBadge.tsx
    Contraste & CSS: El badge aplica opacity-70/opacity-80 sobre colores grises (text-gray-400/500), lo que puede reducir la relación de contraste por debajo de 4.5:1 (WCAG AA). Además, truncate en un <span> inline por defecto no funciona fuera de un flex container; agregar inline-block o documentar que requiere contexto flex/block garantiza que no se rompa el layout en usos futuros.

  • P3 src/components/ui/TruncatedTaskTitle.tsx
    Mantenibilidad: La regex para detectar clases de color (/\b(?:[a-z0-9]+:)?text-.../) es frágil ante colores arbitrarios o plugins de Tailwind. Considerar usar clsx con prioridad de clases (última gana) en lugar de lógica condicional compleja, o documentar que titleClassName debe incluir el color explícito.

  • P3 src/components/ui/TaskIdBadge.tsx
    Acoplamiento: El mr-2 por defecto fuerza margen derecho en todos los usos. Aunque se puede sobrescribir vía className, considerar removerlo del componente base y dejar que el padre controle el espaciado (ej. con gap en flex).

@kelvinCB
Copy link
Owner Author

Approved by a human!! please merge this PR

@kelvinCB kelvinCB merged commit e6def7e into main Feb 14, 2026
3 checks passed
@kelvinCB kelvinCB deleted the feat/visualize-task-ids-2641 branch February 14, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments