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:
@@ -18,13 +18,32 @@ interface ApiDocViewerProps {
|
||||
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) => {
|
||||
const stored = loadStoredConfig();
|
||||
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 [showModal, setShowModal] = useState(false)
|
||||
const [docsPath, setDocsPath] = useState('')
|
||||
const [externalDocs, setExternalDocs] = useState<ExternalDoc[]>([])
|
||||
const [docsPath, setDocsPath] = useState(stored.docsPath)
|
||||
const [externalDocs, setExternalDocs] = useState<ExternalDoc[]>(stored.externalDocs)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [errorMsg, setErrorMsg] = useState<string | null>(null)
|
||||
|
||||
@@ -35,6 +54,35 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }
|
||||
}
|
||||
}, [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> => {
|
||||
if (!basePath) {
|
||||
setErrorMsg('请输入文档路径')
|
||||
@@ -70,6 +118,7 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }
|
||||
}
|
||||
|
||||
setExternalDocs(docs)
|
||||
saveStoredConfig(basePath, docs)
|
||||
|
||||
const fileList = docs
|
||||
.filter(doc => {
|
||||
@@ -86,6 +135,9 @@ export const ApiDocViewer = ({ onDocsPathChange, showAddModal, onCloseAddModal }
|
||||
if (fileList.length > 0) {
|
||||
setSelectedPath(fileList[0])
|
||||
setCurrentContent(docs[0].content)
|
||||
saveStoredConfig(basePath, docs, fileList[0])
|
||||
} else {
|
||||
saveStoredConfig(basePath, docs, undefined)
|
||||
}
|
||||
return true
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user