Public: anyone can read this; the crew can change it.

A card moved under a filter lands where the hidden cards are: a visible index passed as an absolute one #33

shipped production is serving it opened this has it
opened this

src/tty.test.ts records this as today's behaviour because #22 forbade fixing it in that change. It is a bug, and without an issue behind it the characterization test reads as a contract in six months.

db.moveCard(boardId, cardId, columnId, index) takes an index among every card in the target column, ordered by position. The terminal passes state.cardCursor, which is an index into the filtered list — visibleCards drops what the filter hides. With no filter the two agree, which is why nothing has noticed.

With a filter on they do not. src/keys.ts:

  • J passes state.cardCursor + 1 and K passes state.cardCursor - 1.
  • H and L pass Math.min(state.cardCursor, visibleCards(target).length) — a visible count used as an absolute position in the target column.

The test at src/tty.test.ts:258 is the smallest case: a column holding x-one, hidden, x-two with the filter x-, cursor on x-one, J pressed. The card lands at absolute index 1, behind hidden, and the visible order does not change — the person pressed a key and the board did not move.

The web page does not have this bug: src/routes.ts posts the index the drag computed, over the full column, and its filter is a query that re-renders rather than a cursor.

Done looks like

  • [ ] Moving a card with J/K/H/L while a filter is on puts it where the person saw it go: after the card that was visibly above it, before the one that was visibly below.
  • [ ] The fix is a translation at the boundary between the cursor and db.moveCard — visible index to absolute index, in src/keys.ts — and not a change to db.moveCard, which the web page and src/mcp.ts call with an absolute index already.
  • [ ] J at the bottom and K at the top of the visible list still do nothing, and H/L at the edges still do nothing.
  • [ ] A card hidden by the filter does not move.
  • [ ] src/tty.test.ts:258 is rewritten to assert the new behaviour, and the comment calling it today's-behaviour-recorded goes with it. Every other test in that file passes unchanged — that is what says the fix was narrow.

Files I expect to change

  • src/keys.ts — the four move branches.
  • src/tty.test.ts — the recorded case becomes the asserted one, plus K and H/L under a filter.

Risks

  • The translation needs the filtered list of the target column, not the current one, for H/L.
  • An empty filtered target column and a filter that hides everything in the source are the two ends to hold: the cursor must stay inside the board, as src/tty.test.ts already checks.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs