From 698f0106d1acc5e615d8a0190d7742c966c36c7a Mon Sep 17 00:00:00 2001 From: ContextMatrix Runner Date: Mon, 11 May 2026 18:40:14 +0000 Subject: [PATCH] fix(web): show mobile doc selector when no KB doc is selected - Add MobileDocTrigger component reused by viewer/editor - Render trigger in KnowledgeBase fallback branches so mobile users can reach the sheet from "Select a doc" and "No KB yet" states - Refactor KnowledgeDocViewer/Editor to consume the shared component - Update web/CLAUDE.md Mobile Knowledge Base architecture --- web/CLAUDE.md | 13 +++-- .../KnowledgeBase/KnowledgeBase.tsx | 37 +++++++------ .../KnowledgeBase/KnowledgeDocEditor.tsx | 26 +-------- .../KnowledgeBase/KnowledgeDocViewer.tsx | 20 +------ .../KnowledgeBase/MobileDocTrigger.tsx | 53 +++++++++++++++++++ 5 files changed, 87 insertions(+), 62 deletions(-) create mode 100644 web/src/components/KnowledgeBase/MobileDocTrigger.tsx diff --git a/web/CLAUDE.md b/web/CLAUDE.md index cce24f8..9b6be2c 100644 --- a/web/CLAUDE.md +++ b/web/CLAUDE.md @@ -518,9 +518,10 @@ the doc-title row. Desktop layout is unchanged. | File | Role | |---|---| | `web/src/components/KnowledgeBase/MobileDocSheet.tsx` | Backdrop overlay + right-side slide-in panel (reuses `card-panel` and `animate-panel-slide-in` CSS classes). Renders `KnowledgeBaseSidebar` inside. Accepts all sidebar props plus `onClose: () => void`. Calls `onClose` after a doc is selected (intercepts `onSelect`). | -| `web/src/components/KnowledgeBase/KnowledgeBase.tsx` | Owns `isSheetOpen: boolean` state. Applies `hidden md:flex` to the sidebar wrapper. Renders `` when `isSheetOpen` is true. Passes `onOpenSelector={() => setIsSheetOpen(true)}` to `KnowledgeDocViewer`. | -| `web/src/components/KnowledgeBase/KnowledgeDocViewer.tsx` | Accepts `onOpenSelector?: () => void`. Renders a `md:hidden` trigger button at the top of the component showing the current doc name + chevron. Clicking it calls `onOpenSelector?.()`. Also forwards `onOpenSelector` to `KnowledgeDocEditor` when editing. | -| `web/src/components/KnowledgeBase/KnowledgeDocEditor.tsx` | Accepts `onOpenSelector?: () => void`. Renders the same `md:hidden` trigger button at the top. When no doc is provided, shows "Choose a document ›" as the prompt. | +| `web/src/components/KnowledgeBase/MobileDocTrigger.tsx` | Shared `md:hidden` trigger row: open-book icon + doc name (or "Choose a document" in `--grey1` when undefined) + chevron-right. Props: `docName?: string; onClick: () => void`. Used by `KnowledgeBase.tsx` fallback branches and by `KnowledgeDocViewer`/`KnowledgeDocEditor`. | +| `web/src/components/KnowledgeBase/KnowledgeBase.tsx` | Owns `isSheetOpen: boolean` state. Applies `hidden md:flex` to the sidebar wrapper. Renders `` when `isSheetOpen` is true. Passes `onOpenSelector={() => setIsSheetOpen(true)}` to `KnowledgeDocViewer`. Also renders `` in the "No KB docs yet" and "Select a doc." fallback branches so mobile users always have a way to open the sheet. | +| `web/src/components/KnowledgeBase/KnowledgeDocViewer.tsx` | Accepts `onOpenSelector?: () => void`. Renders `` at the top when `onOpenSelector` is set. Forwards `onOpenSelector` to `KnowledgeDocEditor` when editing. | +| `web/src/components/KnowledgeBase/KnowledgeDocEditor.tsx` | Accepts `onOpenSelector?: () => void`. Renders `` at the top when `onOpenSelector` is set. | ### Behaviour @@ -528,8 +529,10 @@ the doc-title row. Desktop layout is unchanged. left (`w-72`). Trigger row hidden (`md:hidden`). - **Mobile (< `md`):** Viewer/editor takes full width. Sidebar hidden (`hidden md:flex`). Trigger row visible at the top showing current doc name + - chevron, or "Choose a document ›" when no doc is selected. Tapping the trigger - sets `isSheetOpen = true`. + chevron, or "Choose a document" when no doc is selected. Tapping the trigger + sets `isSheetOpen = true`. The trigger is also rendered in the "No KB docs + yet" and "Select a doc." fallback branches, so mobile users always have a way + to open the sheet regardless of selection state. ### Closing the sheet diff --git a/web/src/components/KnowledgeBase/KnowledgeBase.tsx b/web/src/components/KnowledgeBase/KnowledgeBase.tsx index b951af0..392c58a 100644 --- a/web/src/components/KnowledgeBase/KnowledgeBase.tsx +++ b/web/src/components/KnowledgeBase/KnowledgeBase.tsx @@ -4,6 +4,7 @@ import { api, errorMessage } from '../../api/client'; import { KnowledgeBaseSidebar } from './KnowledgeBaseSidebar'; import { KnowledgeDocViewer } from './KnowledgeDocViewer'; import { MobileDocSheet } from './MobileDocSheet'; +import { MobileDocTrigger } from './MobileDocTrigger'; import { useUnsavedGuard } from './useUnsavedGuard'; import { useKnowledgeBaseData } from './useKnowledgeBaseData'; import { useKnowledgeRefreshStatus } from './useKnowledgeRefreshStatus'; @@ -198,23 +199,29 @@ export function KnowledgeBase({ project }: { project: string }) { } /> ) : summary.repos.every((r) => r.docs.length === 0) ? ( -
-

No knowledge base docs yet for this project.

-

- Click the Refresh button next to a repo on the left to build the KB. Alternatively - run{' '} - - /contextmatrix:refresh-knowledge --project {project} - {' '} - in your Claude Code session. -

+
+ setIsSheetOpen(true)} /> +
+

No knowledge base docs yet for this project.

+

+ Click the Refresh button next to a repo on the left to build the KB. Alternatively + run{' '} + + /contextmatrix:refresh-knowledge --project {project} + {' '} + in your Claude Code session. +

+
) : ( -
- Select a doc. +
+ setIsSheetOpen(true)} /> +
+ Select a doc. +
)}
diff --git a/web/src/components/KnowledgeBase/KnowledgeDocEditor.tsx b/web/src/components/KnowledgeBase/KnowledgeDocEditor.tsx index 1807788..802d3a4 100644 --- a/web/src/components/KnowledgeBase/KnowledgeDocEditor.tsx +++ b/web/src/components/KnowledgeBase/KnowledgeDocEditor.tsx @@ -1,6 +1,7 @@ import { lazy, Suspense, useEffect, useRef, useState } from 'react'; import { errorMessage } from '../../api/client'; import { useTheme } from '../../hooks/useTheme'; +import { MobileDocTrigger } from './MobileDocTrigger'; const MDEditor = lazy(() => import('@uiw/react-md-editor')); @@ -79,30 +80,7 @@ export function KnowledgeDocEditor({ initialContent, doc, onCancel, onSave, onDi return (
- {onOpenSelector && ( - - )} + {onOpenSelector && }
import('@uiw/react-markdown-preview')); @@ -102,24 +103,7 @@ export function KnowledgeDocViewer({ return (
- {onOpenSelector && ( - - )} + {onOpenSelector && }
void; +} + +export function MobileDocTrigger({ docName, onClick }: MobileDocTriggerProps) { + return ( + + ); +}