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;
|
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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user