feat(ideContainer): 添加菜单树展开/折叠全部功能

master
钟良源 2 months ago
parent dde9083fd5
commit 72b8a0f671

@ -20,7 +20,9 @@ import {
IconEye,
IconSearch,
IconPlus,
IconEyeInvisible
IconEyeInvisible,
IconExpand,
IconShrink
} from '@arco-design/web-react/icon';
import { menuData1, menuData2 } from './config/menuData';
import { Selected } from '@/pages/ideContainer/types';
@ -210,6 +212,8 @@ const SideBar: React.FC<SideBarProps> = ({
const [hiddenNodes, setHiddenNodes] = useState<Set<string>>(new Set());
// 用于控制展开的节点
const [expandedKeys, setExpandedKeys] = useState<string[]>(['0']);
// 用于标记是否全部展开
const [isAllExpanded, setIsAllExpanded] = useState(false);
const resizeBoxRef = useRef<HTMLDivElement>(null); // 引用第一个 ResizeBox 容器
const contextMenuRef = useRef<HTMLDivElement>(null); // 右键菜单引用
const { menuData, info, canvasDataMap } = useSelector(state => state.ideContainer);
@ -284,31 +288,70 @@ const SideBar: React.FC<SideBarProps> = ({
// 切换子菜单区域的收起/展开状态
const toggleSubMenu = () => {
setIsSubMenuCollapsed(!isSubMenuCollapsed);
const width = isSubMenuCollapsed ? 300 : 0;
resizeBoxRef.current.style.width = `${width}px`;
setIsSubMenuCollapsed(prev => !prev);
};
// 监听子菜单收起/展开状态变化,更新宽度
useEffect(() => {
if (resizeBoxRef.current) {
const width = isSubMenuCollapsed ? 0 : 300;
resizeBoxRef.current.style.width = `${width}px`;
}
}, [isSubMenuCollapsed]);
// 获取所有可展开节点的 keys
const getAllExpandableKeys = useCallback((menuItems?: MenuItemType[], parentKey = '0'): string[] => {
const keys: string[] = [];
if (!menuItems || menuItems.length === 0) return keys;
menuItems.forEach((item, index) => {
const key = `${parentKey}-${index}`;
// 只有有子节点的才需要添加到展开列表
if (item.children && item.children.length > 0) {
keys.push(key);
// 递归获取子节点的 keys
keys.push(...getAllExpandableKeys(item.children, key));
}
});
return keys;
}, []);
// 切换展开/折叠全部
const toggleExpandAll = useCallback(() => {
if (isAllExpanded) {
// 折叠全部
setExpandedKeys([]);
setIsAllExpanded(false);
}
else {
// 展开全部
const allKeys = getAllExpandableKeys(filteredMenu[activeKey]?.children);
setExpandedKeys(allKeys);
setIsAllExpanded(true);
}
}, [isAllExpanded, activeKey, getAllExpandableKeys]);
// 处理菜单项点击事件
const handleMenuItemClick = (item: MenuItemType, index: number) => {
setActiveKey(index);
if (showSubMenu) {
// 如果点击的是当前已激活的菜单项,则切换子菜单的展开/收起状态
if (selected.key === `${item.key}`) {
if ((selected?.parentKey || selected.key) === `${item.key}`) {
toggleSubMenu();
}
else {
// 如果点击的是其他菜单项,则展开子菜单(如果已收起)
if (isSubMenuCollapsed) {
setIsSubMenuCollapsed(false);
resizeBoxRef.current.style.width = `300px`;
}
}
}
// 调用外部传入的菜单选择处理函数
onMenuSelect?.({ ...item });
// 单独针对这个title过滤
if (item.title !== '应用列表') onMenuSelect?.({ ...item });
};
// 监听 selected 状态变化,更新 activeKey
@ -327,11 +370,10 @@ const SideBar: React.FC<SideBarProps> = ({
if (selected?.key && menuData[identity]) {
// 确保子菜单区域根据selected状态正确展开或收起
if (['appList', 'appFlow'].includes(selected.parentKey)) {
// 如果应该显示子菜单但当前是收起状态,则展开
if (isSubMenuCollapsed) {
setIsSubMenuCollapsed(false);
resizeBoxRef.current.style.width = `300px`;
}
// // 如果应该显示子菜单但当前是收起状态,则展开
// if (isSubMenuCollapsed) {
// setIsSubMenuCollapsed(false);
// }
}
// 强制更新filteredMenu以确保显示正确的子菜单
@ -787,10 +829,17 @@ const SideBar: React.FC<SideBarProps> = ({
<Input
prefix={<IconSearch />}
placeholder={'搜索'}
style={{ width: '90%' }}
style={{ flex: 1 }}
value={searchValue}
onChange={handleSearchChange}
/>
<Button
type="secondary"
icon={isAllExpanded ? <IconShrink /> : <IconExpand />}
style={{ marginLeft: 5 }}
onClick={toggleExpandAll}
title={isAllExpanded ? '折叠全部' : '展开全部'}
/>
<Button
type="primary"
icon={<IconPlus />}
@ -806,7 +855,12 @@ const SideBar: React.FC<SideBarProps> = ({
<div onContextMenu={handleContextMenu}>
<Tree
expandedKeys={expandedKeys}
onExpand={(keys) => setExpandedKeys(keys as string[])}
onExpand={(keys) => {
setExpandedKeys(keys as string[]);
// 检查是否全部展开,更新 isAllExpanded 状态
const allKeys = getAllExpandableKeys(filteredMenu[activeKey]?.children);
setIsAllExpanded(keys.length >= allKeys.length && allKeys.length > 0);
}}
selectedKeys={[]} // 移除选中样式
onMouseDown={handleMouseDown}
onSelect={async (_selectedKeys, info) => {

Loading…
Cancel
Save