You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
7.4 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import React, { useEffect, useState } 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 from './navBar';
import ProjectContainer from '@/pages/orchestration/project';
import ApplicationContainer from '@/pages/orchestration/application';
import { Selected } from '@/pages/ideContainer/types';
import { updateInfo } from '@/store/ideContainer';
import { useDispatch, useSelector } from 'react-redux';
import { getAppListBySceneId } from '@/api/apps';
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 EventComponent = () => <div style={{ height: '100%', width: '100%' }}></div>;
const GlobalVarComponent = () => <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 getAppList = async () => {
const res: any = await getAppListBySceneId({
pageSize: 999,
currPage: 1,
sceneId: urlParams.id
});
if (res.code === 200) setSubMenuData({ 'appList': res.data.list });
};
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(() => {
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></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 <EventComponent />;
case 'globalVar':
return <GlobalVarComponent />;
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 = (path: string) => {
// 从已打开的tab集合中移除
const newOpenedTabs = new Set(openedTabs);
newOpenedTabs.delete(path);
setOpenedTabs(newOpenedTabs);
// 如果关闭的是当前激活的tab则重置selected状态
// if (path === selected.path) {
// setSelected({});
// }
};
return (
<>
<div className={styles.IDEContainer}>
<SideBar
selected={selected}
identity={urlParams.identity}
subMenuData={subMenuData}
onMenuSelect={(select) => setSelected(select)}
/>
<div className={styles.content}>
<div className={styles.mainContent}>
{/*顶部导航栏*/}
<NavBar
selected={selected}
menuData={menuData[urlParams.identity]}
onTabChange={handleTabChange}
onTabClose={handleTabClose}
></NavBar>
{/*页面渲染*/}
{renderContent()}
{/*底部日志栏*/}
{urlParams.identity !== 'componentDevelopment' && <LogBar></LogBar>}
</div>
</div>
<RightSideBar></RightSideBar>
</div>
</>
);
}
export default IDEContainer;