Files
fn_registry/dev/issues/0091-kanban-sidebar-drag-zones.md

4.7 KiB

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
id title status type domain scope priority depends blocks related created updated tags
0091 kanban: drag-aware dropzones para abrir/cerrar sidebar pendiente feature
kanban
multi-app media
2026-05-17 2026-05-17

Problema

Mover una card desde el board a una columna que vive en el sidebar (location="sidebar") obliga a:

  1. Soltar la card en el board.
  2. Hacer click en el toggle del navbar (icono "menu") para abrir el sidebar.
  3. Volver a coger la card y arrastrarla a la columna sidebar.

Tres pasos manuales para una operacion que conceptualmente es una sola. Es friccion innecesaria — el sidebar deberia abrirse solo si el usuario claramente intenta llegar a el durante un drag.

Solucion

Anadir una banda invisible de 32px en el borde izquierdo del viewport (entre el header y el bottom). Mientras hay un drag activo, si el puntero entra en esa banda y se queda mas de 400ms sin moverse fuera, el sidebar se abre solo (setNavOpen(true)).

Comportamiento

  • Auto-open: si navOpen=false y hay drag activo y el puntero entra en la banda → timer 400ms → abrir sidebar.
  • Auto-close: fuera de scope en este issue. La friccion principal es abrir. Cerrar el sidebar a mano tras el drop es un click; mantenerlo abierto despues del drop es ademas lo que el usuario suele querer (suelta en sidebar, mira lo que tiene parqueado, decide). Se documenta como followup si surge.
  • Feedback visual: mientras el drag esta activo y el puntero esta dentro de la banda, render de un borde/glow inset 4px 0 0 var(--mantine-color-blue-4) con pulso suave.

Detalles tecnicos

  • La banda es un <div> position: fixed, left: 0, top: 50px (alto del header), bottom: 0, width: 32px, z-index: 200 (encima del main, debajo de modals que son z-index: 1000+).
  • pointer-events: none para no interferir con el drop target real (board). Detectamos mouseover/out mediante document.addEventListener('mousemove') solo cuando hay drag activo, y comprobamos clientX < 32. Esto evita problemas de event-routing con dnd-kit que ya tiene capturado el pointer.
  • Timer cancelado en cuanto el puntero sale, en cuanto el drag termina, o si el sidebar ya esta abierto.

Frontend

  1. apps/kanban/frontend/src/App.tsx

    • Reusar el state activeCard/activeType ya existente para saber si hay drag activo (isDragging = activeCard !== null || activeColumnId !== null).
    • Anadir useEffect que, mientras isDragging, escuche mousemove global y dispare timers de hover.
    • Render del overlay debajo del AppShell o dentro pero antes de AppShell.Main.
  2. apps/kanban/frontend/src/styles/dropzone.css (nuevo)

    • Animacion @keyframes simple para el pulso del borde.
    • Class .kanban-drag-edge con la animacion + transition de opacity.
  3. apps/kanban/frontend/src/main.tsx

    • Import del CSS nuevo.
  4. apps/kanban/frontend/src/components/KanbanColumn.tsx

    • Anadir data-column-id={column.id} al Paper raiz para selectores estables en e2e.

Tests

  • Playwright e2e: apps/kanban/frontend/e2e/sidebar-dropzone.spec.ts usando funciones del registry (pw_kanban_login, pw_drag_drop, pw_wait_predicate).
    • Setup: garantizar via API (page.request) que existe al menos una columna sidebar y una card en una columna board.
    • Login → board cargado → assert sidebar collapsed (width 0 o el slot oculto).
    • Drag de la card hacia x=10 (banda izquierda) con hoverMs: 600 para que el timer 400ms se cumpla.
    • Assert que el sidebar se abrio (AppShell.Navbar ahora visible con ancho > 0).
    • Drop directamente en la columna sidebar visible.
    • Assert via /api/board que la card cambio de column_id a la columna sidebar.

Criterios de aceptacion

  • Aparece una banda de 32px en el borde izquierdo cuando hay drag activo (con feedback visual sutil al hover).
  • Hover en la banda durante >=400ms con drag activo y sidebar cerrado → sidebar se abre.
  • Cancelar el hover (mover puntero fuera antes de 400ms) → sidebar sigue cerrado.
  • Terminar drag mientras el sidebar esta abierto por la banda → sidebar sigue abierto (no auto-close).
  • Drag card de board a columna sidebar funciona end-to-end en Playwright.
  • Vitest existentes siguen pasando.

Ramas / commits

  • Rama: issue/0091-kanban-sidebar-drag-zones
  • Merge --no-ff a master.

Followups potenciales

  • Auto-close: simetria total — cuando se drage desde una columna sidebar hacia el board, hover en la zona central-derecha cierra el sidebar tras 400ms. Cuesta diseñar bien la "zona de cierre" sin colisionar con la columna sidebar misma; postpuesto.
  • Persistir preferencia de "abrir-on-drag" en localStorage por si algun usuario no la quiere.