mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-14 04:02:26 +00:00
fix(kanban): make dashboard board pin authoritative over server current file (#21230)
When the user created a new board via the dashboard with "switch" checked, the server-side `current` file was flipped to the new board. Clicking the original board's tab then showed no cards even though the count badge read correctly — the REST fetch dropped `?board=` when the selection was "default" and the backend fell through to `current` (= the new board), returning a different board's data than the tab the user clicked. Fix: - `withBoard()` always appends `?board=<slug>` when a board is selected, including "default". The dashboard's tab selection becomes authoritative instead of silently deferring to the server's `current` file. - `writeSelectedBoard()` persists every selection (including "default") to localStorage. Previously "default" was stripped, which meant the next page load had nothing to pin to and fell through to `current`. - Same change applied to the WebSocket query builder in `openWs()`. Contract verified live: current_board = "proj2" GET /board → proj2's tasks (bug shape: falls through to current) GET /board?board=default → default's tasks (fix: explicit pin wins) GET /board?board=proj2 → proj2's tasks Closes #20879.
This commit is contained in:
parent
647f95b422
commit
b9f1ac8c10
1 changed files with 24 additions and 9 deletions
33
plugins/kanban/dashboard/dist/index.js
vendored
33
plugins/kanban/dashboard/dist/index.js
vendored
|
|
@ -112,17 +112,30 @@
|
||||||
|
|
||||||
function writeSelectedBoard(slug) {
|
function writeSelectedBoard(slug) {
|
||||||
try {
|
try {
|
||||||
if (slug && slug !== "default") window.localStorage.setItem(LS_BOARD_KEY, slug);
|
// Persist the user's dashboard-side board pin even for "default".
|
||||||
|
// Previously this stripped "default" to keep localStorage empty,
|
||||||
|
// but the fetch layer read that absence as "no opinion" and fell
|
||||||
|
// through to the server-side ``current`` file — which the board
|
||||||
|
// switcher also writes. Result: selecting the default tab after
|
||||||
|
// creating a new board with "switch" checked showed the new
|
||||||
|
// board's (wrong) data because the URL omitted ``?board=`` and
|
||||||
|
// the backend happily returned whichever board was "current".
|
||||||
|
// Persisting every selection keeps the dashboard's board opinion
|
||||||
|
// independent of the CLI's active board, which was the original
|
||||||
|
// design intent. Regression: #20879.
|
||||||
|
if (slug) window.localStorage.setItem(LS_BOARD_KEY, slug);
|
||||||
else window.localStorage.removeItem(LS_BOARD_KEY);
|
else window.localStorage.removeItem(LS_BOARD_KEY);
|
||||||
} catch (_e) { /* ignore quota / private mode */ }
|
} catch (_e) { /* ignore quota / private mode */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
function withBoard(url, board) {
|
function withBoard(url, board) {
|
||||||
// Append ?board=<slug> when a non-default board is active. Omitted
|
// Always append ?board=<slug> when we have one picked — including
|
||||||
// for default so the URL stays clean and the backend falls through
|
// "default". Omitting the param would fall through to the backend's
|
||||||
// to its own resolution chain (env var → ``current`` file →
|
// resolution chain (env var → ``current`` file → default), which
|
||||||
// default) which is already correct.
|
// means the dashboard's tab selection gets silently overridden by
|
||||||
if (!board || board === "default") return url;
|
// whatever board the CLI or "switch" checkbox last activated.
|
||||||
|
// Regression: #20879.
|
||||||
|
if (!board) return url;
|
||||||
const sep = url.indexOf("?") >= 0 ? "&" : "?";
|
const sep = url.indexOf("?") >= 0 ? "&" : "?";
|
||||||
return `${url}${sep}board=${encodeURIComponent(board)}`;
|
return `${url}${sep}board=${encodeURIComponent(board)}`;
|
||||||
}
|
}
|
||||||
|
|
@ -447,9 +460,11 @@
|
||||||
token: token,
|
token: token,
|
||||||
};
|
};
|
||||||
// Pin the WS stream to the currently-selected board so events
|
// Pin the WS stream to the currently-selected board so events
|
||||||
// from other boards don't bleed in. Only set for non-default so
|
// from other boards don't bleed in. Includes "default" so the
|
||||||
// single-board installs keep the cleaner URL.
|
// dashboard's own board pin always wins over the server-side
|
||||||
if (board && board !== "default") qsParams.board = board;
|
// ``current`` file — same rationale as ``withBoard()`` above.
|
||||||
|
// Regression: #20879.
|
||||||
|
if (board) qsParams.board = board;
|
||||||
const qs = new URLSearchParams(qsParams);
|
const qs = new URLSearchParams(qsParams);
|
||||||
const url = `${proto}//${window.location.host}${API}/events?${qs}`;
|
const url = `${proto}//${window.location.host}${API}/events?${qs}`;
|
||||||
let ws;
|
let ws;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue