|
|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
import React, { useEffect, useRef, useState } from 'react';
|
|
|
|
|
import React, { useEffect, useRef, useState, useMemo } from 'react';
|
|
|
|
|
import styles from './style/sideBar.module.less';
|
|
|
|
|
import {
|
|
|
|
|
ResizeBox,
|
|
|
|
|
@ -168,6 +168,7 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
|
onDeleteApp
|
|
|
|
|
}) => {
|
|
|
|
|
const [menu, setMenu] = useState<MenuItemType[]>([]);
|
|
|
|
|
const [searchValue, setSearchValue] = useState(''); // 添加搜索状态
|
|
|
|
|
const [subMenuWidth, setSubMenuWidth] = useState(300); // 子菜单宽度状态
|
|
|
|
|
const [isSubMenuCollapsed, setIsSubMenuCollapsed] = useState(false); // 子菜单收起状态
|
|
|
|
|
const [activeKey, setActiveKey] = useState(0);
|
|
|
|
|
@ -260,6 +261,40 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
|
onMenuSelect?.({ ...item });
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 根据搜索值过滤菜单数据
|
|
|
|
|
const filteredMenu = useMemo(() => {
|
|
|
|
|
if (!searchValue || activeKey === undefined || !menu[activeKey]?.children) {
|
|
|
|
|
return menu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 深拷贝菜单数据以避免修改原始数据
|
|
|
|
|
const menuCopy = _.cloneDeep(menu);
|
|
|
|
|
|
|
|
|
|
// 只对当前激活的菜单项进行过滤
|
|
|
|
|
if (menuCopy[activeKey]?.children) {
|
|
|
|
|
menuCopy[activeKey].children = menuCopy[activeKey].children.filter((item: MenuItemType) => {
|
|
|
|
|
// 检查当前项是否匹配搜索条件
|
|
|
|
|
const title = item.title || '';
|
|
|
|
|
const isMatch = title.toLowerCase().includes(searchValue.toLowerCase());
|
|
|
|
|
|
|
|
|
|
// 如果当前项不匹配,检查其子项是否匹配
|
|
|
|
|
if (!isMatch && item.children && item.children.length > 0) {
|
|
|
|
|
item.children = item.children.filter(child => {
|
|
|
|
|
const childTitle = child.title || '';
|
|
|
|
|
return childTitle.toLowerCase().includes(searchValue.toLowerCase());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 如果有匹配的子项,或者当前项匹配,则保留该项
|
|
|
|
|
return item.children.length > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return isMatch;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return menuCopy;
|
|
|
|
|
}, [menu, searchValue, activeKey]);
|
|
|
|
|
|
|
|
|
|
const getProjectEnvData = async (data) => {
|
|
|
|
|
if (!data.path || !data.key) return;
|
|
|
|
|
const parentKey = menu[activeKey]?.key;
|
|
|
|
|
@ -359,6 +394,10 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
|
else if (identity === 'componentDevelopment') setMenu(getMenuData());
|
|
|
|
|
}, [subMenuData, identity]);
|
|
|
|
|
|
|
|
|
|
// 处理搜索输入变化
|
|
|
|
|
const handleSearchChange = (value: string) => {
|
|
|
|
|
setSearchValue(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 渲染节点的额外操作按钮
|
|
|
|
|
const renderNodeExtra = (node) => {
|
|
|
|
|
@ -472,6 +511,8 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
|
prefix={<IconSearch />}
|
|
|
|
|
placeholder={'搜索'}
|
|
|
|
|
style={{ width: '90%' }}
|
|
|
|
|
value={searchValue}
|
|
|
|
|
onChange={handleSearchChange}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
type="primary"
|
|
|
|
|
@ -501,7 +542,7 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
|
style={{ background: 'transparent' }} // 移除背景色
|
|
|
|
|
renderExtra={selected?.parentKey === 'appList' ? renderNodeExtra : null}
|
|
|
|
|
>
|
|
|
|
|
{renderMenuItems(menu[activeKey]?.children)}
|
|
|
|
|
{renderMenuItems(filteredMenu[activeKey]?.children)}
|
|
|
|
|
</Tree>
|
|
|
|
|
</div>
|
|
|
|
|
</ResizeBox>}
|
|
|
|
|
|