实现侧边栏分组展开折叠状态持久化记忆
This commit is contained in:
@@ -170,8 +170,29 @@ function getInitialOpenKeys(sections: SidebarSection[], selectedKey: string) {
|
||||
.map((section) => section.key)
|
||||
}
|
||||
|
||||
const SIDEBAR_OPEN_KEYS_KEY = 'sidebar_open_keys'
|
||||
const SIDEBAR_COLLAPSED_KEY = 'sidebar_collapsed'
|
||||
|
||||
function loadStoredOpenKeys(sections: SidebarSection[], selectedKey: string): string[] {
|
||||
const initial = getInitialOpenKeys(sections, selectedKey)
|
||||
try {
|
||||
const raw = localStorage.getItem(SIDEBAR_OPEN_KEYS_KEY)
|
||||
if (raw) {
|
||||
const parsed = JSON.parse(raw)
|
||||
if (Array.isArray(parsed)) {
|
||||
return Array.from(new Set([...parsed, ...initial]))
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
return initial
|
||||
}
|
||||
|
||||
export default function MainLayout() {
|
||||
const [collapsed, setCollapsed] = useState(false)
|
||||
const [collapsed, setCollapsed] = useState<boolean>(() => {
|
||||
return localStorage.getItem(SIDEBAR_COLLAPSED_KEY) === 'true'
|
||||
})
|
||||
const { user, logout, isAdmin } = useAuth()
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
@@ -179,11 +200,15 @@ export default function MainLayout() {
|
||||
|
||||
const sections = useMemo(() => (isAdmin ? adminSections : merchantSections), [isAdmin])
|
||||
const selectedKey = getSelectedKey(location.pathname, location.search)
|
||||
const [openKeys, setOpenKeys] = useState<string[]>(() => getInitialOpenKeys(sections, selectedKey))
|
||||
const [openKeys, setOpenKeys] = useState<string[]>(() => loadStoredOpenKeys(sections, selectedKey))
|
||||
|
||||
useEffect(() => {
|
||||
const nextOpenKeys = getInitialOpenKeys(sections, selectedKey)
|
||||
setOpenKeys((current) => Array.from(new Set([...current, ...nextOpenKeys])))
|
||||
setOpenKeys((current) => {
|
||||
const merged = Array.from(new Set([...current, ...nextOpenKeys]))
|
||||
localStorage.setItem(SIDEBAR_OPEN_KEYS_KEY, JSON.stringify(merged))
|
||||
return merged
|
||||
})
|
||||
}, [sections, selectedKey])
|
||||
|
||||
const toggleSection = (section: SidebarSection) => {
|
||||
@@ -197,11 +222,18 @@ export default function MainLayout() {
|
||||
if (firstEnabledChild?.path) navigate(firstEnabledChild.path)
|
||||
return
|
||||
}
|
||||
setOpenKeys((current) =>
|
||||
current.includes(section.key)
|
||||
setOpenKeys((current) => {
|
||||
const next = current.includes(section.key)
|
||||
? current.filter((key) => key !== section.key)
|
||||
: [...current, section.key],
|
||||
)
|
||||
: [...current, section.key]
|
||||
localStorage.setItem(SIDEBAR_OPEN_KEYS_KEY, JSON.stringify(next))
|
||||
return next
|
||||
})
|
||||
}
|
||||
|
||||
const handleToggleCollapse = (next: boolean) => {
|
||||
setCollapsed(next)
|
||||
localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(next))
|
||||
}
|
||||
|
||||
const handleChildClick = (child: SidebarChild) => {
|
||||
@@ -300,7 +332,7 @@ export default function MainLayout() {
|
||||
<button
|
||||
className="app-header__collapse"
|
||||
type="button"
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
onClick={() => handleToggleCollapse(!collapsed)}
|
||||
aria-label={collapsed ? '展开侧边栏' : '收起侧边栏'}
|
||||
title={collapsed ? '展开侧边栏' : '收起侧边栏'}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user