fix(wiki): stop config tab from auto-switching back to sources

Two compounding causes made the management view jump from the config
tab back to 'raw' a few seconds after the user selected it:

1. The tab-snap watcher used a single getter returning a new array
   (`() => [currentKB?.id, workspaceMode]`). Vue compares the returned
   value with Object.is, so a fresh array reference reports a change on
   every re-evaluation — including background refreshCurrentKB() calls
   that reassign the KB object with the same id. That re-ran the snap and
   forced activeTab back to 'raw'. Switch to an array of getters so each
   source is compared individually and the callback fires only on a real
   id/mode change.

2. RawMaterialPanel's onBeforeUnmount cleared the SSE stream and the 60s
   fallback timer but not the per-raw jobPoller setTimeout chain. While a
   raw was still processing, leaving the sources tab left that 3s poller
   running, calling refreshCurrentKB() indefinitely. Clear jobPoller on
   unmount as well.
This commit is contained in:
倪程伟 2026-06-27 00:08:17 +08:00
parent 8522aa7591
commit 1bce1fc1b9
2 changed files with 16 additions and 1 deletions

View File

@ -439,6 +439,14 @@ onBeforeUnmount(() => {
clearInterval(fallbackTimer)
fallbackTimer = null
}
// Stop the per-raw job poller too. Without this the setTimeout chain keeps
// running after the panel unmounts (e.g. switching to the config tab while a
// raw is still processing), calling refreshCurrentKB() every 3s and snapping
// the user back to this tab.
if (jobPoller != null) {
clearTimeout(jobPoller)
jobPoller = null
}
})
// RFC-033: Job polling per raw material

View File

@ -157,8 +157,15 @@ const tabs = computed<{ key: WikiTab; label: string }[]>(() => {
// Snap to each view's default tab whenever the KB or the view mode changes, so
// the user never lands on a stale tab (or one that doesn't exist in this mode).
// Use an array of getters (not a single getter returning an array): the latter
// returns a fresh array reference on every evaluation, so Vue's Object.is check
// always reports a change and the callback fires on *any* currentKB
// reassignment including background refreshes (refreshCurrentKB) that keep the
// same id. That would yank the user off the config tab back to 'raw' every time
// a poll/SSE refresh reassigned the KB object. The array-of-getters form
// compares each source individually, so it fires only on a real id/mode change.
watch(
() => [store.currentKB?.id, store.workspaceMode],
[() => store.currentKB?.id, () => store.workspaceMode],
() => { activeTab.value = store.workspaceMode === 'manage' ? 'raw' : 'pages' },
{ immediate: true },
)