fix: folder click shows overview doc, add same-name filter, move + to header
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useCallback } from 'react'
|
||||
import { X, Plus, AlertCircle } from 'lucide-react'
|
||||
import { useState, useCallback, useEffect } from 'react'
|
||||
import { X, AlertCircle } from 'lucide-react'
|
||||
import { DocTree } from './DocTree'
|
||||
import { DocContent } from './DocContent'
|
||||
import { buildFileTree } from '@/lib/parser'
|
||||
@@ -14,9 +14,11 @@ interface ExternalDoc {
|
||||
|
||||
interface ApiDocViewerProps {
|
||||
onDocsPathChange?: (path: string) => void;
|
||||
showAddModal?: boolean;
|
||||
onCloseAddModal?: () => void;
|
||||
}
|
||||
|
||||
export const ApiDocViewer = ({ onDocsPathChange }: ApiDocViewerProps) => {
|
||||
export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }: ApiDocViewerProps) => {
|
||||
const [fileTree, setFileTree] = useState<DocFile[]>([])
|
||||
const [selectedPath, setSelectedPath] = useState<string | undefined>()
|
||||
const [currentContent, setCurrentContent] = useState<string>('')
|
||||
@@ -26,6 +28,13 @@ export const ApiDocViewer = ({ onDocsPathChange }: ApiDocViewerProps) => {
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [errorMsg, setErrorMsg] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (showAddModal) {
|
||||
setShowModal(true)
|
||||
setErrorMsg(null)
|
||||
}
|
||||
}, [showAddModal])
|
||||
|
||||
const loadDocsFromPath = async (basePath: string): Promise<boolean> => {
|
||||
if (!basePath) {
|
||||
setErrorMsg('请输入文档路径')
|
||||
@@ -61,7 +70,17 @@ export const ApiDocViewer = ({ onDocsPathChange }: ApiDocViewerProps) => {
|
||||
}
|
||||
|
||||
setExternalDocs(docs)
|
||||
const fileList = docs.map(d => d.relativePath.replace(/^api\//, ''))
|
||||
|
||||
// 过滤掉与父文件夹同名的 md 文件,只用于目录树显示
|
||||
const filteredDocs = docs.filter(doc => {
|
||||
const parts = doc.relativePath.split('/')
|
||||
if (parts.length < 2) return true
|
||||
const filename = parts[parts.length - 1].replace(/\.md$/, '')
|
||||
const parentFolder = parts[parts.length - 2]
|
||||
return filename !== parentFolder
|
||||
})
|
||||
|
||||
const fileList = filteredDocs.map(d => d.relativePath.replace(/^api\//, ''))
|
||||
const tree = buildFileTree(fileList, '/')
|
||||
setFileTree(tree)
|
||||
|
||||
@@ -79,12 +98,20 @@ export const ApiDocViewer = ({ onDocsPathChange }: ApiDocViewerProps) => {
|
||||
}
|
||||
|
||||
const handleSelect = useCallback((file: DocFile) => {
|
||||
if (!file.isDir) {
|
||||
setSelectedPath(file.relativePath)
|
||||
const doc = externalDocs.find(d => d.relativePath === file.relativePath)
|
||||
if (doc) {
|
||||
setCurrentContent(doc.content)
|
||||
}
|
||||
setSelectedPath(file.relativePath)
|
||||
const doc = externalDocs.find(d => d.relativePath === file.relativePath)
|
||||
if (doc) {
|
||||
setCurrentContent(doc.content)
|
||||
}
|
||||
}, [externalDocs])
|
||||
|
||||
const handleFolderClick = useCallback((folderPath: string) => {
|
||||
const sameNamePath = `${folderPath}/${folderPath}.md`
|
||||
const sameNameDoc = externalDocs.find(d => d.relativePath === sameNamePath)
|
||||
|
||||
if (sameNameDoc) {
|
||||
setSelectedPath(sameNameDoc.relativePath.replace(/^api\//, ''))
|
||||
setCurrentContent(sameNameDoc.content)
|
||||
}
|
||||
}, [externalDocs])
|
||||
|
||||
@@ -93,6 +120,7 @@ export const ApiDocViewer = ({ onDocsPathChange }: ApiDocViewerProps) => {
|
||||
const success = await loadDocsFromPath(docsPath.trim())
|
||||
if (success) {
|
||||
setShowModal(false)
|
||||
onCloseAddModal?.()
|
||||
onDocsPathChange?.(docsPath.trim())
|
||||
}
|
||||
}
|
||||
@@ -112,24 +140,15 @@ export const ApiDocViewer = ({ onDocsPathChange }: ApiDocViewerProps) => {
|
||||
return (
|
||||
<div className="flex h-full bg-[#1e1e1e]">
|
||||
<aside className="w-64 bg-[#252526] border-r border-[#3c3c3c] flex flex-col">
|
||||
<div className="p-3 border-b border-[#3c3c3c] flex items-center justify-between">
|
||||
<div className="p-3 border-b border-[#3c3c3c]">
|
||||
<h2 className="text-sm font-semibold text-gray-200">文档目录</h2>
|
||||
<button
|
||||
onClick={() => {
|
||||
setShowModal(true)
|
||||
setErrorMsg(null)
|
||||
}}
|
||||
className="p-1 hover:bg-[#3c3c3c] rounded"
|
||||
title="添加文档路径"
|
||||
>
|
||||
<Plus size={16} className="text-gray-400" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<DocTree
|
||||
files={fileTree}
|
||||
selectedPath={selectedPath}
|
||||
onSelect={handleSelect}
|
||||
onFolderClick={handleFolderClick}
|
||||
/>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
Reference in New Issue
Block a user