elevate folder navigation to app view state

This commit is contained in:
Arjun 2026-05-28 00:41:42 +05:30 committed by arkml
parent 373d1ee92b
commit 78c5ad2e6f
2 changed files with 22 additions and 9 deletions

View file

@ -587,7 +587,7 @@ type ViewState =
| { type: 'live-notes' }
| { type: 'email' }
| { type: 'workspace'; path?: string }
| { type: 'knowledge-view' }
| { type: 'knowledge-view'; folderPath?: string }
| { type: 'chat-history' }
| { type: 'home' }
@ -597,6 +597,7 @@ function viewStatesEqual(a: ViewState, b: ViewState): boolean {
if (a.type === 'file' && b.type === 'file') return a.path === b.path
if (a.type === 'task' && b.type === 'task') return a.name === b.name
if (a.type === 'workspace' && b.type === 'workspace') return (a.path ?? '') === (b.path ?? '')
if (a.type === 'knowledge-view' && b.type === 'knowledge-view') return (a.folderPath ?? '') === (b.folderPath ?? '')
return true // both graph
}
@ -644,8 +645,10 @@ function parseDeepLink(input: string): ViewState | null {
const path = params.get('path')
return { type: 'workspace', path: path ?? undefined }
}
case 'knowledge-view':
return { type: 'knowledge-view' }
case 'knowledge-view': {
const folderPath = params.get('folderPath')
return { type: 'knowledge-view', folderPath: folderPath ?? undefined }
}
case 'chat-history':
return { type: 'chat-history' }
case 'home':
@ -762,6 +765,9 @@ function App() {
const [isWorkspaceOpen, setIsWorkspaceOpen] = useState(false)
const [workspaceInitialPath, setWorkspaceInitialPath] = useState<string | null>(null)
const [isKnowledgeViewOpen, setIsKnowledgeViewOpen] = useState(false)
// Folder being browsed inside the knowledge view (null = root overview).
// Lives in ViewState so folder drill-down participates in back/forward history.
const [knowledgeViewFolderPath, setKnowledgeViewFolderPath] = useState<string | null>(null)
const [isChatHistoryOpen, setIsChatHistoryOpen] = useState(false)
// Default landing view: Home in the middle with the chat docked on the right.
const [isHomeOpen, setIsHomeOpen] = useState(true)
@ -3463,13 +3469,13 @@ function App() {
if (isLiveNotesOpen) return { type: 'live-notes' }
if (isSuggestedTopicsOpen) return { type: 'suggested-topics' }
if (isWorkspaceOpen) return { type: 'workspace', path: workspaceInitialPath ?? undefined }
if (isKnowledgeViewOpen) return { type: 'knowledge-view' }
if (isKnowledgeViewOpen) return { type: 'knowledge-view', folderPath: knowledgeViewFolderPath ?? undefined }
if (isChatHistoryOpen) return { type: 'chat-history' }
if (isHomeOpen) return { type: 'home' }
if (selectedPath) return { type: 'file', path: selectedPath }
if (isGraphOpen) return { type: 'graph' }
return { type: 'chat', runId }
}, [selectedBackgroundTask, isEmailOpen, isMeetingsOpen, isLiveNotesOpen, isBgTasksOpen, isSuggestedTopicsOpen, selectedPath, isGraphOpen, isWorkspaceOpen, isKnowledgeViewOpen, isChatHistoryOpen, isHomeOpen, workspaceInitialPath, runId])
}, [selectedBackgroundTask, isEmailOpen, isMeetingsOpen, isLiveNotesOpen, isBgTasksOpen, isSuggestedTopicsOpen, selectedPath, isGraphOpen, isWorkspaceOpen, isKnowledgeViewOpen, knowledgeViewFolderPath, isChatHistoryOpen, isHomeOpen, workspaceInitialPath, runId])
const appendUnique = useCallback((stack: ViewState[], entry: ViewState) => {
const last = stack[stack.length - 1]
@ -3809,6 +3815,7 @@ function App() {
setIsEmailOpen(false)
setIsWorkspaceOpen(false)
setIsKnowledgeViewOpen(true)
setKnowledgeViewFolderPath(view.folderPath ?? null)
setIsChatHistoryOpen(false)
setIsHomeOpen(false)
ensureKnowledgeViewFileTab()
@ -5553,6 +5560,8 @@ function App() {
revealInFileManager: knowledgeActions.revealInFileManager,
onOpenInNewTab: knowledgeActions.onOpenInNewTab,
}}
folderPath={knowledgeViewFolderPath}
onNavigateFolder={(path) => { void navigateToView({ type: 'knowledge-view', folderPath: path ?? undefined }) }}
onOpenNote={(path) => navigateToFile(path)}
onOpenGraph={() => knowledgeActions.openGraph()}
onOpenSearch={() => { setSearchDefaultScope('knowledge'); setIsSearchOpen(true) }}

View file

@ -49,6 +49,10 @@ export type KnowledgeViewActions = {
type KnowledgeViewProps = {
tree: TreeNode[]
actions: KnowledgeViewActions
// Folder currently being browsed (null = root overview). Controlled by the
// app so drill-down participates in the global back/forward history.
folderPath: string | null
onNavigateFolder: (path: string | null) => void
onOpenNote: (path: string) => void
onOpenGraph: () => void
onOpenSearch: () => void
@ -141,14 +145,14 @@ function displayName(node: TreeNode): string {
export function KnowledgeView({
tree,
actions,
folderPath,
onNavigateFolder,
onOpenNote,
onOpenGraph,
onOpenSearch,
onOpenBases,
onVoiceNoteCreated,
}: KnowledgeViewProps) {
// null = root (folder overview); otherwise the path of the folder being browsed.
const [folderPath, setFolderPath] = useState<string | null>(null)
const [renameTarget, setRenameTarget] = useState<string | null>(null)
const topLevel = useMemo(
@ -170,7 +174,7 @@ export function KnowledgeView({
[topLevel],
)
const openFolder = useCallback((path: string) => setFolderPath(path), [])
const openFolder = useCallback((path: string) => onNavigateFolder(path), [onNavigateFolder])
// When the open folder no longer exists (deleted/renamed externally), fall
// back to the root overview rather than holding a dangling drill-down.
@ -210,7 +214,7 @@ export function KnowledgeView({
renameTarget={renameTarget}
onRequestRename={setRenameTarget}
onClearRename={() => setRenameTarget(null)}
onNavigate={setFolderPath}
onNavigate={onNavigateFolder}
onOpenFolder={openFolder}
onOpenNote={onOpenNote}
/>