fix(KB): blank-screen on panel open + tooltips on bulk-action buttons

The Stored Knowledge Base Files render crashed on first open in v1.32.0-rc.5
with `ReferenceError: sourceToDisplayName is not defined`. The table column's
render() called `sourceToDisplayName(record.source)` but the function was
extracted to `lib/kb_file_grouping.ts` in PR #892 and never imported in
KnowledgeBaseModal.tsx. The unhandled error unmounts the entire React tree,
so users see a blank screen ~20s after opening the panel.

Root cause: PR #895 (conditional warnings) rewrote the render() and used
`sourceToDisplayName(record.source)` instead of `record.displayName`, which
KbFileGroup already carries from groupAndSortKbFiles(). PR #895's review
follow-up (cbae48a) compounded this by narrowing the StyledTable generic
from `KbFileGroup` to `{source: string}`, hiding the type drift from tsc.

This restores the post-#892 pattern:
- StyledTable generic back to `KbFileGroup`
- Render uses `record.displayName` (works for both per-file rows and the
  collapsed admin-docs row; calling sourceToDisplayName on the synthetic
  `__admin_docs_group__` would have rendered that literal as the row name).

Also folds in tooltip copy on the three bulk-action buttons (Reset & Rebuild,
Re-embed All, Sync Storage) so the difference in destructiveness is visible
on hover. Uses native `title` attribute via StyledButton's prop pass-through;
no new component dependency.

Inertia tsconfig catches this regression cleanly (TS2304 + TS2339); the
pre-push hook only runs the backend tsconfig which excludes inertia/**, so
the bug shipped. Tracking the typecheck-coverage gap as a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Sherwood 2026-05-17 11:10:16 -07:00 committed by Jake Turner
parent 2150189121
commit 633a3c3500
1 changed files with 5 additions and 2 deletions

View File

@ -420,6 +420,7 @@ export default function KnowledgeBaseModal({ aiAssistantName = "AI Assistant", o
onClick={() => { setResetTyped(''); setBulkMode('reset') }}
disabled={isUploading || qdrantOffline || bulkBusy}
loading={resetMutation.isPending}
title="Drop the entire embeddings collection and re-embed everything from scratch. Permanently removes vectors for files no longer on disk. Destructive: requires typing RESET to confirm."
>
Reset & Rebuild
</StyledButton>
@ -430,6 +431,7 @@ export default function KnowledgeBaseModal({ aiAssistantName = "AI Assistant", o
onClick={() => setBulkMode('reembed')}
disabled={isUploading || qdrantOffline || bulkBusy || storedFiles.length === 0}
loading={reembedMutation.isPending}
title="Re-embed every file on disk, replacing existing vectors file-by-file. Vectors for files no longer on disk are preserved. Use this if the chunker or embedding model has changed."
>
Re-embed All
</StyledButton>
@ -440,6 +442,7 @@ export default function KnowledgeBaseModal({ aiAssistantName = "AI Assistant", o
onClick={handleConfirmSync}
disabled={syncMutation.isPending || isUploading || qdrantOffline || bulkBusy}
loading={syncMutation.isPending || isUploading}
title="Scan storage for new files and queue any that haven't been embedded yet. Safe to run anytime; won't touch already-embedded content."
>
Sync Storage
</StyledButton>
@ -454,7 +457,7 @@ export default function KnowledgeBaseModal({ aiAssistantName = "AI Assistant", o
</span>
</div>
)}
<StyledTable<{ source: string }>
<StyledTable<KbFileGroup>
className="font-semibold"
rowLines={true}
columns={[
@ -466,7 +469,7 @@ export default function KnowledgeBaseModal({ aiAssistantName = "AI Assistant", o
return (
<div className="flex flex-col gap-1">
<span className="text-text-primary">
{sourceToDisplayName(record.source)}
{record.displayName}
</span>
{warnings.map((w, i) => (
<span