|
|
import React, { useEffect, useState, useRef } from 'react';
|
|
|
import { getUrlParams } from '@/utils/common';
|
|
|
import styles from './style/index.module.less';
|
|
|
import SideBar from './sideBar';
|
|
|
import LogBar from './logBar';
|
|
|
import RightSideBar from './rightSideBar';
|
|
|
import NavBar, { NavBarRef } from './navBar';
|
|
|
import { Selected } from '@/pages/ideContainer/types';
|
|
|
import { updateInfo } from '@/store/ideContainer';
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
import { getAppListBySceneId } from '@/api/apps';
|
|
|
|
|
|
import ProjectContainer from '@/pages/orchestration/project';
|
|
|
import ApplicationContainer from '@/pages/orchestration/application';
|
|
|
import EventContainer from '@/pages/orchestration/event';
|
|
|
import GlobalVarContainer from '@/pages/orchestration/globalVar';
|
|
|
|
|
|
type UrlParamsOptions = {
|
|
|
identity?: string;
|
|
|
[key: string]: string
|
|
|
};
|
|
|
|
|
|
const CompListComponent = () => <div style={{ height: '100%', width: '100%' }}>组件列表</div>;
|
|
|
const AppInstanceComponent = () => <div style={{ height: '100%', width: '100%' }}>应用实例</div>;
|
|
|
const AppCompComponent = () => <div style={{ height: '100%', width: '100%' }}>组件</div>;
|
|
|
const MyComponents = () => <div style={{ height: '100%', width: '100%' }}>我的组件</div>;
|
|
|
const MatchingComponents = () => <div style={{ height: '100%', width: '100%' }}>协同组件</div>;
|
|
|
const ComponentReview = () => <div style={{ height: '100%', width: '100%' }}>组件审核</div>;
|
|
|
const ComponentCoding = () => <div style={{ height: '100%', width: '100%' }}>组件编码</div>;
|
|
|
const ComponentDeployment = () => <div style={{ height: '100%', width: '100%' }}>组件部署</div>;
|
|
|
const ComponentTest = () => <div style={{ height: '100%', width: '100%' }}>组件测试</div>;
|
|
|
|
|
|
// 所有可显示的组件路径列表
|
|
|
const ALL_PATHS = [
|
|
|
'compFlow', 'appFlow', 'compList', 'appInstance', 'event', 'globalVar', 'appCompList',
|
|
|
'myComponents', 'matchingComponents', 'componentReview',
|
|
|
'componentCoding', 'componentDeployment', 'componentTest'
|
|
|
];
|
|
|
|
|
|
function IDEContainer() {
|
|
|
const [selected, setSelected] = useState<Selected>({});
|
|
|
const [urlParams, setUrlParams] = useState<UrlParamsOptions>({});
|
|
|
const [subMenuWidth, setSubMenuWidth] = useState(200); // 子菜单宽度状态
|
|
|
// 用于跟踪已打开的tab,保持组件状态
|
|
|
const [openedTabs, setOpenedTabs] = useState<Set<string>>(new Set());
|
|
|
const [subMenuData, setSubMenuData] = useState<any>({});
|
|
|
const { menuData } = useSelector((state) => state.ideContainer);
|
|
|
const dispatch = useDispatch();
|
|
|
const navBarRef = useRef<NavBarRef>(null);
|
|
|
|
|
|
const getAppList = async () => {
|
|
|
const res: any = await getAppListBySceneId({
|
|
|
pageSize: 999,
|
|
|
currPage: 1,
|
|
|
sceneId: urlParams.id
|
|
|
});
|
|
|
if (res.code === 200) setSubMenuData({ 'appList': res.data.list.reverse() });
|
|
|
};
|
|
|
|
|
|
useEffect(() => {
|
|
|
setUrlParams(getUrlParams(window.location.href) as UrlParamsOptions);
|
|
|
dispatch(updateInfo(getUrlParams(window.location.href) as UrlParamsOptions));
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (urlParams.id) getAppList();
|
|
|
}, [urlParams.id]);
|
|
|
|
|
|
// 当selected.path变化时,添加到已打开的tab集合中
|
|
|
useEffect(() => {
|
|
|
console.log('selected:', selected);
|
|
|
if (selected.key) {
|
|
|
setOpenedTabs(prev => new Set(prev).add(selected.key!));
|
|
|
}
|
|
|
}, [selected.key]);
|
|
|
|
|
|
// 根据选中的菜单项渲染对应组件
|
|
|
const renderContent = () => {
|
|
|
return (
|
|
|
<div style={{ height: '100%', position: 'relative' }}>
|
|
|
{ALL_PATHS.map((path, i) => {
|
|
|
// 检查该路径的组件是否已打开
|
|
|
const isOpened = openedTabs.has(selected.key);
|
|
|
// 检查是否是当前选中的路径
|
|
|
const isSelected = selected.path === path;
|
|
|
|
|
|
// 只有已打开的组件才渲染,通过CSS控制显示/隐藏
|
|
|
return isOpened ? (
|
|
|
<div
|
|
|
key={`${selected.key}-${i}`}
|
|
|
style={{
|
|
|
display: isSelected ? 'block' : 'none',
|
|
|
height: '100%'
|
|
|
}}
|
|
|
>
|
|
|
{getContentByPath(path)}
|
|
|
</div>
|
|
|
) : null;
|
|
|
})}
|
|
|
|
|
|
{/* 默认内容,当没有选中任何tab时显示 */}
|
|
|
{!selected.path && (
|
|
|
<div style={{
|
|
|
width: '100%',
|
|
|
height: '100%',
|
|
|
display: 'flex',
|
|
|
justifyContent: 'center',
|
|
|
alignItems: 'center',
|
|
|
flexDirection: 'column',
|
|
|
backgroundColor: '#ffffff'
|
|
|
}}>
|
|
|
<img
|
|
|
src={'/ideContainer/background/empty.png'}
|
|
|
/>
|
|
|
<span style={{
|
|
|
fontSize: '20px',
|
|
|
color: 'rgba(141, 141, 153, 1)'
|
|
|
}}>
|
|
|
请选择应用,预览配置信息
|
|
|
</span>
|
|
|
</div>
|
|
|
)}
|
|
|
</div>
|
|
|
);
|
|
|
};
|
|
|
|
|
|
// 根据路径获取对应的组件
|
|
|
const getContentByPath = (path: string) => {
|
|
|
switch (path) {
|
|
|
case 'compFlow':
|
|
|
return <ProjectContainer selected={selected} />;
|
|
|
case 'appFlow':
|
|
|
return <ApplicationContainer />;
|
|
|
case 'compList':
|
|
|
return <CompListComponent />;
|
|
|
case 'appInstance':
|
|
|
return <AppInstanceComponent />;
|
|
|
case 'event':
|
|
|
return <EventContainer />;
|
|
|
case 'globalVar':
|
|
|
return <GlobalVarContainer />;
|
|
|
case 'appCompList':
|
|
|
return <AppCompComponent />;
|
|
|
case 'myComponents':
|
|
|
return <MyComponents />;
|
|
|
case 'matchingComponents':
|
|
|
return <MatchingComponents />;
|
|
|
case 'componentReview':
|
|
|
return <ComponentReview />;
|
|
|
case 'componentCoding':
|
|
|
return <ComponentCoding />;
|
|
|
case 'componentDeployment':
|
|
|
return <ComponentDeployment />;
|
|
|
case 'componentTest':
|
|
|
return <ComponentTest />;
|
|
|
default:
|
|
|
return <div>未知页面</div>;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 处理子菜单区域的拖拽调整大小
|
|
|
const handleSubMenuResize = (e: MouseEvent, { width }: { width: number }) => {
|
|
|
setSubMenuWidth(width);
|
|
|
};
|
|
|
|
|
|
// 处理tab切换
|
|
|
const handleTabChange = (key: string) => {
|
|
|
if (key) {
|
|
|
const findMenuItem = (menuItems: any[], key: string): any => {
|
|
|
for (const item of menuItems) {
|
|
|
if (item.key === key) {
|
|
|
return item;
|
|
|
}
|
|
|
if (item.children) {
|
|
|
const found = findMenuItem(item.children, key);
|
|
|
if (found) return found;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
};
|
|
|
|
|
|
const menuItems = menuData[urlParams.identity];
|
|
|
const menuItem = findMenuItem(menuItems, key);
|
|
|
|
|
|
if (menuItem) {
|
|
|
setSelected({
|
|
|
...menuItem,
|
|
|
key: menuItem.key,
|
|
|
parentKey: menuItem.parentKey
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
else {
|
|
|
// 没有激活的tab,重置selected状态
|
|
|
setSelected({});
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 处理tab关闭
|
|
|
const handleTabClose = (key: string) => {
|
|
|
// 从已打开的tab集合中移除
|
|
|
const newOpenedTabs = new Set(openedTabs);
|
|
|
newOpenedTabs.delete(key);
|
|
|
setOpenedTabs(newOpenedTabs);
|
|
|
|
|
|
// 如果关闭的是当前激活的tab,则重置selected状态
|
|
|
// if (path === selected.path) {
|
|
|
// setSelected({});
|
|
|
// }
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
<>
|
|
|
<div className={styles.IDEContainer}>
|
|
|
<SideBar
|
|
|
selected={selected}
|
|
|
identity={urlParams.identity}
|
|
|
subMenuData={subMenuData}
|
|
|
showSubMenu={!['event', 'globalVar', 'appCompList'].includes(selected.key)}
|
|
|
onMenuSelect={(select) => setSelected(select)}
|
|
|
onRefresh={() => getAppList()}
|
|
|
onDeleteApp={(appId) => {
|
|
|
// 从已打开的tab集合中移除被删除的应用
|
|
|
const newOpenedTabs = new Set(openedTabs);
|
|
|
// 查找并删除与该应用相关的tab
|
|
|
const tabsToDelete = Array.from(newOpenedTabs).filter(key => key?.includes(appId));
|
|
|
tabsToDelete.forEach(tabKey => newOpenedTabs.delete(tabKey));
|
|
|
setOpenedTabs(newOpenedTabs);
|
|
|
|
|
|
// 如果当前选中的tab与被删除的应用相关,则重置selected状态
|
|
|
if (selected.key && selected.key.includes(appId)) {
|
|
|
setSelected({});
|
|
|
}
|
|
|
|
|
|
// 通知NavBar删除对应的tab
|
|
|
navBarRef.current?.deleteTabByKey(`compFlow-${appId}`);
|
|
|
}}
|
|
|
/>
|
|
|
<div className={styles.content}>
|
|
|
<div className={styles.mainContent}>
|
|
|
{/*顶部导航栏*/}
|
|
|
<NavBar
|
|
|
ref={navBarRef}
|
|
|
selected={selected}
|
|
|
menuData={menuData[urlParams.identity]}
|
|
|
onTabChange={handleTabChange}
|
|
|
onTabClose={handleTabClose}
|
|
|
></NavBar>
|
|
|
{/*页面渲染*/}
|
|
|
{renderContent()}
|
|
|
{/*底部日志栏*/}
|
|
|
{urlParams.identity !== 'componentDevelopment' && !['event', 'globalVar', 'appCompList'].includes(selected.key) &&
|
|
|
<LogBar></LogBar>}
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
{!['event', 'globalVar', 'appCompList'].includes(selected.key) && <RightSideBar></RightSideBar>}
|
|
|
</div>
|
|
|
</>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
export default IDEContainer; |