|
|
|
@ -177,68 +177,80 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
const [showModal, setShowModal] = useState(false);
|
|
|
|
const [showModal, setShowModal] = useState(false);
|
|
|
|
const [modalType, setModalType] = useState<'ADD' | 'EDIT'>('ADD');
|
|
|
|
const [modalType, setModalType] = useState<'ADD' | 'EDIT'>('ADD');
|
|
|
|
const [currentApp, setCurrentApp] = useState<any>(null);
|
|
|
|
const [currentApp, setCurrentApp] = useState<any>(null);
|
|
|
|
|
|
|
|
const [contextMenu, setContextMenu] = useState<{
|
|
|
|
|
|
|
|
visible: boolean;
|
|
|
|
|
|
|
|
x: number;
|
|
|
|
|
|
|
|
y: number;
|
|
|
|
|
|
|
|
nodeData: any;
|
|
|
|
|
|
|
|
}>({
|
|
|
|
|
|
|
|
visible: false,
|
|
|
|
|
|
|
|
x: 0,
|
|
|
|
|
|
|
|
y: 0,
|
|
|
|
|
|
|
|
nodeData: null
|
|
|
|
|
|
|
|
}); // 添加右键菜单状态
|
|
|
|
const resizeBoxRef = useRef<HTMLDivElement>(null); // 引用第一个 ResizeBox 容器
|
|
|
|
const resizeBoxRef = useRef<HTMLDivElement>(null); // 引用第一个 ResizeBox 容器
|
|
|
|
|
|
|
|
const contextMenuRef = useRef<HTMLDivElement>(null); // 右键菜单引用
|
|
|
|
const { menuData } = useSelector(state => state.ideContainer);
|
|
|
|
const { menuData } = useSelector(state => state.ideContainer);
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
|
|
|
|
|
|
|
function getMenuData(): MenuItemType[] {
|
|
|
|
function getMenuData(): MenuItemType[] {
|
|
|
|
switch (identity) {
|
|
|
|
switch (identity) {
|
|
|
|
case 'scene':
|
|
|
|
case 'scene':
|
|
|
|
const menuData = _.cloneDeep(menuData1);
|
|
|
|
const menuData = _.cloneDeep(menuData1);
|
|
|
|
const newSubMenuData = _.cloneDeep(subMenuData);
|
|
|
|
const newSubMenuData = _.cloneDeep(subMenuData);
|
|
|
|
|
|
|
|
|
|
|
|
// 遍历所有 subMenuKey 来构建子菜单数据结构
|
|
|
|
// 遍历所有 subMenuKey 来构建子菜单数据结构
|
|
|
|
Object.keys(newSubMenuData).forEach(subMenuKey => {
|
|
|
|
Object.keys(newSubMenuData).forEach(subMenuKey => {
|
|
|
|
const subMenuValue: any = _.cloneDeep(newSubMenuData[subMenuKey]);
|
|
|
|
const subMenuValue: any = _.cloneDeep(newSubMenuData[subMenuKey]);
|
|
|
|
const menuIndex = menuData.findIndex(v => v.key === subMenuKey);
|
|
|
|
const menuIndex = menuData.findIndex(v => v.key === subMenuKey);
|
|
|
|
|
|
|
|
|
|
|
|
if (menuIndex !== -1) {
|
|
|
|
if (menuIndex !== -1) {
|
|
|
|
// 构建数据结构,这是目录默认需要的数据结构
|
|
|
|
// 构建数据结构,这是目录默认需要的数据结构
|
|
|
|
subMenuValue.forEach(v => {
|
|
|
|
subMenuValue.forEach(v => {
|
|
|
|
v.title = v.name;
|
|
|
|
v.title = v.name;
|
|
|
|
v.key = `compFlow-${v.id}`;
|
|
|
|
v.key = `compFlow-${v.id}`;
|
|
|
|
v.path = 'compFlow';
|
|
|
|
v.path = 'compFlow';
|
|
|
|
v.parentKey = subMenuKey;
|
|
|
|
v.parentKey = subMenuKey;
|
|
|
|
v.icon = '/ideContainer/icon/app.png';
|
|
|
|
v.icon = '/ideContainer/icon/app.png';
|
|
|
|
if (subMenuKey !== 'appFlow') {
|
|
|
|
if (subMenuKey !== 'appFlow') {
|
|
|
|
v.children = [
|
|
|
|
v.children = [
|
|
|
|
{
|
|
|
|
{
|
|
|
|
title: '事件',
|
|
|
|
title: '事件',
|
|
|
|
children: null,
|
|
|
|
children: null,
|
|
|
|
icon: '/ideContainer/icon/list.png'
|
|
|
|
icon: '/ideContainer/icon/list.png'
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{
|
|
|
|
title: '组件列表',
|
|
|
|
title: '组件列表',
|
|
|
|
children: null,
|
|
|
|
children: null,
|
|
|
|
icon: '/ideContainer/icon/list.png'
|
|
|
|
icon: '/ideContainer/icon/list.png'
|
|
|
|
}
|
|
|
|
}
|
|
|
|
];
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
menuData[menuIndex]['children'] = subMenuValue;
|
|
|
|
menuData[menuIndex]['children'] = subMenuValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
dispatch(updateMenuData({ 'scene': menuData }));
|
|
|
|
dispatch(updateMenuData({ 'scene': menuData }));
|
|
|
|
return menuData;
|
|
|
|
return menuData;
|
|
|
|
case 'componentDevelopment' :
|
|
|
|
case 'componentDevelopment' :
|
|
|
|
dispatch(updateMenuData({ 'componentDevelopment': menuData2 }));
|
|
|
|
dispatch(updateMenuData({ 'componentDevelopment': menuData2 }));
|
|
|
|
return menuData2;
|
|
|
|
return menuData2;
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return menuData1;
|
|
|
|
return menuData1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理子菜单区域的拖拽调整大小
|
|
|
|
// 处理子菜单区域的拖拽调整大小
|
|
|
|
const handleSubMenuResize = (e: MouseEvent, { width }: { width: number }) => {
|
|
|
|
const handleSubMenuResize = (e: MouseEvent, { width }: { width: number }) => {
|
|
|
|
resizeBoxRef.current.style.width = `${width}px`;
|
|
|
|
resizeBoxRef.current.style.width = `${width}px`;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 切换子菜单区域的收起/展开状态
|
|
|
|
// 切换子菜单区域的收起/展开状态
|
|
|
|
const toggleSubMenu = () => {
|
|
|
|
const toggleSubMenu = () => {
|
|
|
|
setIsSubMenuCollapsed(!isSubMenuCollapsed);
|
|
|
|
setIsSubMenuCollapsed(!isSubMenuCollapsed);
|
|
|
|
const width = isSubMenuCollapsed ? 300 : 0;
|
|
|
|
const width = isSubMenuCollapsed ? 300 : 0;
|
|
|
|
resizeBoxRef.current.style.width = `${width}px`;
|
|
|
|
resizeBoxRef.current.style.width = `${width}px`;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理菜单项点击事件
|
|
|
|
// 处理菜单项点击事件
|
|
|
|
@ -254,7 +266,7 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
// 如果点击的是其他菜单项,则展开子菜单(如果已收起)
|
|
|
|
// 如果点击的是其他菜单项,则展开子菜单(如果已收起)
|
|
|
|
if (isSubMenuCollapsed) {
|
|
|
|
if (isSubMenuCollapsed) {
|
|
|
|
setIsSubMenuCollapsed(false);
|
|
|
|
setIsSubMenuCollapsed(false);
|
|
|
|
resizeBoxRef.current.style.width = `300px`;
|
|
|
|
resizeBoxRef.current.style.width = `300px`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -303,6 +315,7 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
const currentMenu = _.cloneDeep(menuData[identity]);
|
|
|
|
const currentMenu = _.cloneDeep(menuData[identity]);
|
|
|
|
const index = currentMenu.findIndex(v => v.key === parentKey);
|
|
|
|
const index = currentMenu.findIndex(v => v.key === parentKey);
|
|
|
|
const res: any = await getAppInfoNew(data.id);
|
|
|
|
const res: any = await getAppInfoNew(data.id);
|
|
|
|
|
|
|
|
console.log('res.data:', res.data.subs);
|
|
|
|
if (res.code === 200) {
|
|
|
|
if (res.code === 200) {
|
|
|
|
const children = currentMenu[index].children.find(v => v.id === data.id);
|
|
|
|
const children = currentMenu[index].children.find(v => v.id === data.id);
|
|
|
|
children.children[0].children = res.data.events.map(item => {
|
|
|
|
children.children[0].children = res.data.events.map(item => {
|
|
|
|
@ -316,12 +329,19 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
title: compTypeMap[item],
|
|
|
|
title: compTypeMap[item],
|
|
|
|
icon: item === 'appComponent' ? '/ideContainer/icon/app1.png' : '/ideContainer/icon/complexApp.png',
|
|
|
|
icon: item === 'appComponent' ? '/ideContainer/icon/app1.png' : '/ideContainer/icon/complexApp.png',
|
|
|
|
children: res.data.compList[item].map(item => {
|
|
|
|
children: item === 'appComponent' ? res.data.compList[item].map(title => {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
title: item,
|
|
|
|
title: title,
|
|
|
|
children: null,
|
|
|
|
children: null,
|
|
|
|
icon: '/ideContainer/icon/tool.png'
|
|
|
|
icon: '/ideContainer/icon/tool.png'
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
}) : res.data.subs.map(info => {
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
title: info.flowName,
|
|
|
|
|
|
|
|
children: null,
|
|
|
|
|
|
|
|
icon: '/ideContainer/icon/tool.png',
|
|
|
|
|
|
|
|
compData: info
|
|
|
|
|
|
|
|
};
|
|
|
|
})
|
|
|
|
})
|
|
|
|
};
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@ -401,6 +421,59 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
setSearchValue(value);
|
|
|
|
setSearchValue(value);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理鼠标按下事件
|
|
|
|
|
|
|
|
const handleMouseDown = (e: React.MouseEvent) => {
|
|
|
|
|
|
|
|
// 明确检查右键点击
|
|
|
|
|
|
|
|
if (e.button === 2) {
|
|
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取点击的目标元素及其数据
|
|
|
|
|
|
|
|
const target = e.target as HTMLElement;
|
|
|
|
|
|
|
|
const treeNode = target.closest('.arco-tree-node');
|
|
|
|
|
|
|
|
if (treeNode) {
|
|
|
|
|
|
|
|
// 在实际应用中,你可能需要通过 tree-node 获取对应的数据
|
|
|
|
|
|
|
|
// 这里我们简单地显示右键菜单
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置右键菜单的位置和显示
|
|
|
|
|
|
|
|
setContextMenu({
|
|
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
|
|
x: e.clientX,
|
|
|
|
|
|
|
|
y: e.clientY,
|
|
|
|
|
|
|
|
nodeData: null
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 劫持右键
|
|
|
|
|
|
|
|
const handleContextMenu = (e: React.MouseEvent) => {
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置右键菜单的位置和显示
|
|
|
|
|
|
|
|
setContextMenu({
|
|
|
|
|
|
|
|
visible: true,
|
|
|
|
|
|
|
|
x: e.clientX,
|
|
|
|
|
|
|
|
y: e.clientY,
|
|
|
|
|
|
|
|
nodeData: null
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 点击其他地方隐藏右键菜单
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
const handleClickOutside = (e: MouseEvent) => {
|
|
|
|
|
|
|
|
if (contextMenuRef.current && !contextMenuRef.current.contains(e.target as Node)) {
|
|
|
|
|
|
|
|
setContextMenu(prev => ({ ...prev, visible: false }));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
// 渲染节点的额外操作按钮
|
|
|
|
// 渲染节点的额外操作按钮
|
|
|
|
const renderNodeExtra = (node) => {
|
|
|
|
const renderNodeExtra = (node) => {
|
|
|
|
// 只有当 node.dataRef.id 存在时才渲染操作按钮
|
|
|
|
// 只有当 node.dataRef.id 存在时才渲染操作按钮
|
|
|
|
@ -416,6 +489,7 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
setCurrentApp(node.dataRef);
|
|
|
|
setCurrentApp(node.dataRef);
|
|
|
|
setModalType('EDIT');
|
|
|
|
setModalType('EDIT');
|
|
|
|
setShowModal(true);
|
|
|
|
setShowModal(true);
|
|
|
|
|
|
|
|
setContextMenu(prev => ({ ...prev, visible: false })); // 隐藏右键菜单
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<span style={{ color: 'rgba(161, 165, 194, 1)' }}>
|
|
|
|
<span style={{ color: 'rgba(161, 165, 194, 1)' }}>
|
|
|
|
@ -439,6 +513,7 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
// 通知父组件应用已被删除
|
|
|
|
// 通知父组件应用已被删除
|
|
|
|
onDeleteApp?.(node.dataRef.id);
|
|
|
|
onDeleteApp?.(node.dataRef.id);
|
|
|
|
onRefresh();
|
|
|
|
onRefresh();
|
|
|
|
|
|
|
|
setContextMenu(prev => ({ ...prev, visible: false })); // 隐藏右键菜单
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
@ -462,6 +537,9 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
top: 10,
|
|
|
|
top: 10,
|
|
|
|
color: '#000000'
|
|
|
|
color: '#000000'
|
|
|
|
}}
|
|
|
|
}}
|
|
|
|
|
|
|
|
onClick={(e) => {
|
|
|
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</Dropdown>
|
|
|
|
</Dropdown>
|
|
|
|
);
|
|
|
|
);
|
|
|
|
@ -528,27 +606,64 @@ const SideBar: React.FC<SideBarProps> = ({
|
|
|
|
</div>}
|
|
|
|
</div>}
|
|
|
|
|
|
|
|
|
|
|
|
{/* 子菜单 */}
|
|
|
|
{/* 子菜单 */}
|
|
|
|
<Tree
|
|
|
|
<div onContextMenu={handleContextMenu}>
|
|
|
|
defaultExpandedKeys={['0-0']}
|
|
|
|
<Tree
|
|
|
|
selectedKeys={[]} // 移除选中样式
|
|
|
|
defaultExpandedKeys={['0']} // 整个属性去掉就会展开全部
|
|
|
|
onSelect={async (_selectedKeys, info) => {
|
|
|
|
selectedKeys={[]} // 移除选中样式
|
|
|
|
const selectedNode = info.node;
|
|
|
|
onMouseDown={handleMouseDown}
|
|
|
|
const originalData = selectedNode.props.dataRef;
|
|
|
|
onSelect={async (_selectedKeys, info) => {
|
|
|
|
if (selected?.parentKey === 'appList') {
|
|
|
|
const selectedNode = info.node;
|
|
|
|
await getProjectEnvData(originalData);
|
|
|
|
const originalData = selectedNode.props.dataRef;
|
|
|
|
|
|
|
|
console.log(originalData);
|
|
|
|
// 调用外部传入的菜单选择处理函数
|
|
|
|
if (selected?.parentKey === 'appList') {
|
|
|
|
originalData.key && onMenuSelect?.({ ...originalData } as Selected);
|
|
|
|
await getProjectEnvData(originalData);
|
|
|
|
}
|
|
|
|
|
|
|
|
}}
|
|
|
|
// 调用外部传入的菜单选择处理函数
|
|
|
|
style={{ background: 'transparent' }} // 移除背景色
|
|
|
|
originalData.key && onMenuSelect?.({ ...originalData } as Selected);
|
|
|
|
renderExtra={selected?.parentKey === 'appList' ? renderNodeExtra : null}
|
|
|
|
}
|
|
|
|
>
|
|
|
|
}}
|
|
|
|
{renderMenuItems(filteredMenu[activeKey]?.children)}
|
|
|
|
style={{ background: 'transparent' }} // 移除背景色
|
|
|
|
</Tree>
|
|
|
|
renderExtra={selected?.parentKey === 'appList' ? renderNodeExtra : null}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{renderMenuItems(filteredMenu[activeKey]?.children)}
|
|
|
|
|
|
|
|
</Tree>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</ResizeBox>}
|
|
|
|
</ResizeBox>}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* 右键菜单 */}
|
|
|
|
|
|
|
|
{/*{contextMenu.visible && (*/}
|
|
|
|
|
|
|
|
{/* <div*/}
|
|
|
|
|
|
|
|
{/* ref={contextMenuRef}*/}
|
|
|
|
|
|
|
|
{/* className={styles['context-menu']}*/}
|
|
|
|
|
|
|
|
{/* style={{*/}
|
|
|
|
|
|
|
|
{/* position: 'fixed',*/}
|
|
|
|
|
|
|
|
{/* top: contextMenu.y,*/}
|
|
|
|
|
|
|
|
{/* left: contextMenu.x,*/}
|
|
|
|
|
|
|
|
{/* zIndex: 1000*/}
|
|
|
|
|
|
|
|
{/* }}*/}
|
|
|
|
|
|
|
|
{/* >*/}
|
|
|
|
|
|
|
|
{/* <Menu*/}
|
|
|
|
|
|
|
|
{/* className={styles['context-menu-dropdown']}*/}
|
|
|
|
|
|
|
|
{/* style={{*/}
|
|
|
|
|
|
|
|
{/* borderRadius: 4,*/}
|
|
|
|
|
|
|
|
{/* boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)'*/}
|
|
|
|
|
|
|
|
{/* }}*/}
|
|
|
|
|
|
|
|
{/* >*/}
|
|
|
|
|
|
|
|
{/* <MenuItem*/}
|
|
|
|
|
|
|
|
{/* key="refresh"*/}
|
|
|
|
|
|
|
|
{/* onClick={() => {*/}
|
|
|
|
|
|
|
|
{/* console.log('点击');*/}
|
|
|
|
|
|
|
|
{/* // onRefresh();*/}
|
|
|
|
|
|
|
|
{/* // setContextMenu(prev => ({ ...prev, visible: false }));*/}
|
|
|
|
|
|
|
|
{/* }}*/}
|
|
|
|
|
|
|
|
{/* >*/}
|
|
|
|
|
|
|
|
{/* <span>编辑复合组件</span>*/}
|
|
|
|
|
|
|
|
{/* </MenuItem>*/}
|
|
|
|
|
|
|
|
{/* </Menu>*/}
|
|
|
|
|
|
|
|
{/* </div>*/}
|
|
|
|
|
|
|
|
{/*)}*/}
|
|
|
|
|
|
|
|
|
|
|
|
{/* 新增/编辑应用 */}
|
|
|
|
{/* 新增/编辑应用 */}
|
|
|
|
{showModal && (
|
|
|
|
{showModal && (
|
|
|
|
<AppHandleModal
|
|
|
|
<AppHandleModal
|
|
|
|
|