fix: persist docs config to localStorage

- Save docsPath, externalDocs, and selectedPath to localStorage
- Restore state when component mounts
- Fix data loss when switching pages
This commit is contained in:
2026-03-19 12:46:46 +08:00
parent 58a83f445a
commit 7c7b9ea1c6

View File

@@ -18,13 +18,32 @@ interface ApiDocViewerProps {
onCloseAddModal?: () => void; onCloseAddModal?: () => void;
} }
const STORAGE_KEY = 'xc-docs-config';
function loadStoredConfig() {
try {
const stored = localStorage.getItem(STORAGE_KEY);
if (stored) {
return JSON.parse(stored);
}
} catch {}
return { docsPath: '', externalDocs: [] as ExternalDoc[], selectedPath: undefined };
}
function saveStoredConfig(docsPath: string, externalDocs: ExternalDoc[], selectedPath?: string) {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify({ docsPath, externalDocs, selectedPath }));
} catch {}
}
export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }: ApiDocViewerProps) => { export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }: ApiDocViewerProps) => {
const stored = loadStoredConfig();
const [fileTree, setFileTree] = useState<DocFile[]>([]) const [fileTree, setFileTree] = useState<DocFile[]>([])
const [selectedPath, setSelectedPath] = useState<string | undefined>() const [selectedPath, setSelectedPath] = useState<string | undefined>(stored.selectedPath)
const [currentContent, setCurrentContent] = useState<string>('') const [currentContent, setCurrentContent] = useState<string>('')
const [showModal, setShowModal] = useState(false) const [showModal, setShowModal] = useState(false)
const [docsPath, setDocsPath] = useState('') const [docsPath, setDocsPath] = useState(stored.docsPath)
const [externalDocs, setExternalDocs] = useState<ExternalDoc[]>([]) const [externalDocs, setExternalDocs] = useState<ExternalDoc[]>(stored.externalDocs)
const [isLoading, setIsLoading] = useState(false) const [isLoading, setIsLoading] = useState(false)
const [errorMsg, setErrorMsg] = useState<string | null>(null) const [errorMsg, setErrorMsg] = useState<string | null>(null)
@@ -35,6 +54,35 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }
} }
}, [showAddModal]) }, [showAddModal])
useEffect(() => {
if (externalDocs.length > 0 && fileTree.length > 0 && !selectedPath) {
const fileList = externalDocs
.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
})
.map(d => d.relativePath)
const targetPath = stored.selectedPath && externalDocs.find(d => d.relativePath === stored.selectedPath)
? stored.selectedPath
: fileList[0]
if (targetPath) {
setSelectedPath(targetPath)
setCurrentContent(externalDocs.find(d => d.relativePath === targetPath)?.content || '')
}
}
}, [externalDocs, fileTree, selectedPath])
useEffect(() => {
if (docsPath && externalDocs.length > 0) {
saveStoredConfig(docsPath, externalDocs, selectedPath)
}
}, [docsPath, externalDocs, selectedPath])
const loadDocsFromPath = async (basePath: string): Promise<boolean> => { const loadDocsFromPath = async (basePath: string): Promise<boolean> => {
if (!basePath) { if (!basePath) {
setErrorMsg('请输入文档路径') setErrorMsg('请输入文档路径')
@@ -70,6 +118,7 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }
} }
setExternalDocs(docs) setExternalDocs(docs)
saveStoredConfig(basePath, docs)
const fileList = docs const fileList = docs
.filter(doc => { .filter(doc => {
@@ -86,6 +135,9 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }
if (fileList.length > 0) { if (fileList.length > 0) {
setSelectedPath(fileList[0]) setSelectedPath(fileList[0])
setCurrentContent(docs[0].content) setCurrentContent(docs[0].content)
saveStoredConfig(basePath, docs, fileList[0])
} else {
saveStoredConfig(basePath, docs, undefined)
} }
return true return true
} catch (err) { } catch (err) {