canvasSlice.tsfix(pipeline,inbox): filters that survive a refresh, and a lost deal that leaves the board
Three reported bugs, two of them the same mechanism seen from different ends.
A rejected viewConfig save was invisible. Every filter control fires
`void saveCanvasViewConfig(id)`, so a rejection had no observer at all: no toast,
no retry, and a local config the user believed was stored. `dirtyCanvasIds` kept
the edit on screen — but that Set was never persisted while `canvasesById` was,
so a reload came back with the change still in localStorage and nothing marking
it unsaved. The server's pre-save row then won rehydration, which is why this
read as "my pipeline filters don't survive a refresh" rather than as a write that
failed. The save now reports failure and resolves false instead of rejecting, so
all ~20 `void` call sites are covered without touching them; the dirty set
persists, so the guard already in upsertCanvas holds across the reload it was
being thrown away by; and CanvasHeader stops flashing "Saved" over a failure.
Saves are also chained per canvas. Working through a filter popover fired several
updateCanvas mutations at one row concurrently, so the last RESPONSE to land, not
the last edit made, decided what the server kept.
Closed Lost deals stayed in the pipeline because status is filtered SERVER-side:
a page's membership is fixed when it is fetched, and marking a deal Closed Lost
writes to the store, never to that page. The status/priority change now
invalidates listConversations — it was the only successful-update path that never
did — and the fetched rows are re-checked against the optimistic value, so the row
leaves in the same frame as the click and the refetch merely agrees. That check is
one shared predicate now; the kanban had its own copy, which is why two views of
one pipeline disagreed about what a stage filter admits.
Escape clears the inbox filters, in a second stage. Selection first, filters only
once nothing is selected — a single stage would throw a filter set away on every
ordinary deselect.
Co-Authored-By: Claude Opus 5 (1M context) <<email>>Aug 29, 2026, 4:06 PM