feat: persist sider menu group collapse state across refresh

This commit is contained in:
gitlawr
2026-06-10 20:24:53 +08:00
committed by jialin
parent ab75685955
commit 55d16c5681
2 changed files with 28 additions and 11 deletions
+7
View File
@@ -55,3 +55,10 @@ export const userSettingsHelperAtom = atom(
} }
); );
export const hideModalTemporarilyAtom = atom<boolean>(false); export const hideModalTemporarilyAtom = atom<boolean>(false);
export const collapsedMenuGroupsAtom = atomWithStorage<string[]>(
'collapsedMenuGroups',
[],
undefined,
{ getOnInit: true }
);
+21 -11
View File
@@ -1,9 +1,11 @@
import { collapsedMenuGroupsAtom } from '@/atoms/settings';
import { CaretDownOutlined } from '@ant-design/icons'; import { CaretDownOutlined } from '@ant-design/icons';
import { IconFont, OverlayScroller } from '@gpustack/core-ui'; import { IconFont, OverlayScroller } from '@gpustack/core-ui';
import { Link, useLocation } from '@umijs/max'; import { Link, useLocation } from '@umijs/max';
import { Tooltip } from 'antd'; import { Tooltip } from 'antd';
import { createStyles, type FullToken } from 'antd-style'; import { createStyles, type FullToken } from 'antd-style';
import React, { useMemo, useState } from 'react'; import { useAtom } from 'jotai';
import React, { useMemo } from 'react';
interface MenuItem { interface MenuItem {
icon?: string; icon?: string;
@@ -144,8 +146,19 @@ const SiderMenu: React.FC<SiderMenuProps> = (props) => {
const { menuData, collapsed } = props; const { menuData, collapsed } = props;
const { styles, cx } = useStyles(); const { styles, cx } = useStyles();
const location = useLocation(); const location = useLocation();
const [collapseKeys, setCollapseKeys] = useState<Set<string>>(new Set()); const [storedCollapsedGroups, setCollapsedGroups] = useAtom(
console.log('SiderMenu', location.pathname); collapsedMenuGroupsAtom
);
// atomWithStorage falls back to the initial value on JSON parse
// errors, but not when the stored value is valid JSON of another
// shape — normalize so array methods below can't throw.
const collapsedGroups = Array.isArray(storedCollapsedGroups)
? storedCollapsedGroups
: [];
const collapseKeys = useMemo(
() => new Set(collapsedGroups),
[collapsedGroups]
);
const dividerStyles = useMemo(() => { const dividerStyles = useMemo(() => {
if (collapsed) { if (collapsed) {
@@ -164,14 +177,11 @@ const SiderMenu: React.FC<SiderMenuProps> = (props) => {
const handleToggleGroup = (e: any, menuGroup: any) => { const handleToggleGroup = (e: any, menuGroup: any) => {
e.stopPropagation(); e.stopPropagation();
console.log('handleToggleGroup', menuGroup.key); setCollapsedGroups(
collapsedGroups.includes(menuGroup.key)
if (collapseKeys.has(menuGroup.key)) { ? collapsedGroups.filter((key) => key !== menuGroup.key)
collapseKeys.delete(menuGroup.key); : [...collapsedGroups, menuGroup.key]
} else { );
collapseKeys.add(menuGroup.key);
}
setCollapseKeys(new Set(collapseKeys));
}; };
const menuItemRender = (menuItem: MenuItem, key: string) => { const menuItemRender = (menuItem: MenuItem, key: string) => {