kanban-dev-webapp/src
Dave 02adcb43ac fix(board): keep optimistic state authoritative so a single drop always lands
The previous handler called router.refresh() after every successful move
and the Board effect then adopted the new initialCards prop. Because
router.refresh() schedules the server re-render asynchronously, the new
initialCards could land AFTER setSaving(false) had already cleared busy.
The effect then ran with !busy and setCards(initialCards) reverted the
optimistic move — the card visibly snapped back to its origin column
on every single drag, even though the database had the move. The user
had to drag the card a second time to land it in the destination.

Trust the optimistic state for the lifetime of the Board instance.
The first mount still adopts the server snapshot via the useState
initializer. Concurrent moves from other clients appear on the next
page visit, which is acceptable for an owner-only kanban.

The useRefreshOnFocus hook still keeps a focus listener registered
while not busy, so a real cross-tab refresh still fires.
2026-09-17 12:15:34 +02:00
..
app fix(theme): no <script> in RSC, OS preference via CSS media query 2026-09-17 12:06:25 +02:00
components fix(board): keep optimistic state authoritative so a single drop always lands 2026-09-17 12:15:34 +02:00
lib feat(nav): sidebar Kanban flyout, grouped by client 2026-09-17 10:42:50 +02:00
middleware.ts feat(roadmap): planning page with bands, timeline and stats 2026-09-17 07:19:00 +02:00