feat(ideContainer): 实现应用删除时自动关闭相关标签页

- 引入 useRef 和 useImperativeHandle 支持父子组件通信
- 添加 NavBarRef 类型定义及 deleteTabByKey 方法
-通过 ref 调用 NavBar 的删除 tab 方法
- 在 SideBar 中新增 onDeleteApp 回调处理应用删除逻辑- 更新 tab 关闭逻辑以支持根据 key 删除
- 表单提交后调整 onRefresh 和 onClose 执行顺序- 删除应用时同步清理已打开的标签页状态
master
钟良源 4 months ago
parent c52ee5f5ca
commit 95a132c061

@ -1,10 +1,10 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState, useRef } from 'react';
import { getUrlParams } from '@/utils/common'; import { getUrlParams } from '@/utils/common';
import styles from './style/index.module.less'; import styles from './style/index.module.less';
import SideBar from './sideBar'; import SideBar from './sideBar';
import LogBar from './logBar'; import LogBar from './logBar';
import RightSideBar from './rightSideBar'; import RightSideBar from './rightSideBar';
import NavBar from './navBar'; import NavBar, { NavBarRef } from './navBar';
import ProjectContainer from '@/pages/orchestration/project'; import ProjectContainer from '@/pages/orchestration/project';
import ApplicationContainer from '@/pages/orchestration/application'; import ApplicationContainer from '@/pages/orchestration/application';
import { Selected } from '@/pages/ideContainer/types'; import { Selected } from '@/pages/ideContainer/types';
@ -45,7 +45,8 @@ function IDEContainer() {
const [subMenuData, setSubMenuData] = useState<any>({}); const [subMenuData, setSubMenuData] = useState<any>({});
const { menuData } = useSelector((state) => state.ideContainer); const { menuData } = useSelector((state) => state.ideContainer);
const dispatch = useDispatch(); const dispatch = useDispatch();
const navBarRef = useRef<NavBarRef>(null);
const getAppList = async () => { const getAppList = async () => {
const res: any = await getAppListBySceneId({ const res: any = await getAppListBySceneId({
pageSize: 999, pageSize: 999,
@ -195,10 +196,10 @@ function IDEContainer() {
}; };
// 处理tab关闭 // 处理tab关闭
const handleTabClose = (path: string) => { const handleTabClose = (key: string) => {
// 从已打开的tab集合中移除 // 从已打开的tab集合中移除
const newOpenedTabs = new Set(openedTabs); const newOpenedTabs = new Set(openedTabs);
newOpenedTabs.delete(path); newOpenedTabs.delete(key);
setOpenedTabs(newOpenedTabs); setOpenedTabs(newOpenedTabs);
// 如果关闭的是当前激活的tab则重置selected状态 // 如果关闭的是当前激活的tab则重置selected状态
@ -216,11 +217,28 @@ function IDEContainer() {
subMenuData={subMenuData} subMenuData={subMenuData}
onMenuSelect={(select) => setSelected(select)} onMenuSelect={(select) => setSelected(select)}
onRefresh={() => getAppList()} 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.content}>
<div className={styles.mainContent}> <div className={styles.mainContent}>
{/*顶部导航栏*/} {/*顶部导航栏*/}
<NavBar <NavBar
ref={navBarRef}
selected={selected} selected={selected}
menuData={menuData[urlParams.identity]} menuData={menuData[urlParams.identity]}
onTabChange={handleTabChange} onTabChange={handleTabChange}

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect, useImperativeHandle } from 'react';
import { Tabs } from '@arco-design/web-react'; import { Tabs } from '@arco-design/web-react';
import styles from './style/navbar.module.less'; import styles from './style/navbar.module.less';
import { Selected } from '@/pages/ideContainer/types'; import { Selected } from '@/pages/ideContainer/types';
@ -12,7 +12,17 @@ interface NavBarProps {
onTabClose?: (path: string) => void; onTabClose?: (path: string) => void;
} }
const NavBar: React.FC<NavBarProps> = ({ selected, menuData, onTabChange, onTabClose }) => { // 添加ref类型定义
export type NavBarRef = {
deleteTabByKey: (key: string) => void;
};
const NavBar: React.ForwardRefRenderFunction<NavBarRef, NavBarProps> = ({
selected,
menuData,
onTabChange,
onTabClose
}, ref) => {
const [tabs, setTabs] = useState<any[]>([]); const [tabs, setTabs] = useState<any[]>([]);
const [activeTab, setActiveTab] = useState<string>(''); const [activeTab, setActiveTab] = useState<string>('');
@ -84,6 +94,16 @@ const NavBar: React.FC<NavBarProps> = ({ selected, menuData, onTabChange, onTabC
onTabClose?.(key); onTabClose?.(key);
}; };
// 提供给父组件调用的删除tab方法
const deleteTabByKey = (key: string) => {
handleDeleteTab(key);
};
// 暴露方法给父组件使用
useImperativeHandle(ref, () => ({
deleteTabByKey
}));
const handleTabChange = (key: string) => { const handleTabChange = (key: string) => {
setActiveTab(key); setActiveTab(key);
// 查找对应的tab并通知父组件 // 查找对应的tab并通知父组件
@ -121,4 +141,4 @@ const NavBar: React.FC<NavBarProps> = ({ selected, menuData, onTabChange, onTabC
); );
}; };
export default NavBar; export default React.forwardRef(NavBar);

@ -42,6 +42,7 @@ interface SideBarProps {
identity?: string; identity?: string;
onMenuSelect?: (selected: Selected) => void; onMenuSelect?: (selected: Selected) => void;
onRefresh: () => void; onRefresh: () => void;
onDeleteApp?: (appId: string) => void; // 添加删除应用的回调函数
} }
const compTypeMap = { const compTypeMap = {
@ -54,21 +55,11 @@ const AppHandleModal = ({ appInfo, visible, type, onChangeVisible, onClose, onRe
const { info } = useSelector(state => state.ideContainer); const { info } = useSelector(state => state.ideContainer);
const [form] = Form.useForm(); const [form] = Form.useForm();
if (appInfo) {
form.setFieldsValue({
id: appInfo?.id,
name: appInfo?.name,
description: appInfo?.description,
published: appInfo?.published === 1,
logo: 'scene04.png', // 先写死
sceneId: info.id
});
}
const onOk = async () => { const onOk = async () => {
await form.validate(); await form.validate();
const formData = form.getFields(); const formData = form.getFields();
// 新增
if (type === 'ADD') { if (type === 'ADD') {
// 新增应用的入参 // 新增应用的入参
const params = { const params = {
@ -82,7 +73,18 @@ const AppHandleModal = ({ appInfo, visible, type, onChangeVisible, onClose, onRe
if (res.code === 200) Message.success('创建成功'); if (res.code === 200) Message.success('创建成功');
else Message.error(res.message); else Message.error(res.message);
} }
// 编辑
else { else {
if (appInfo) {
form.setFieldsValue({
id: appInfo?.id,
name: appInfo?.name,
description: appInfo?.description,
published: appInfo?.published === 1,
logo: 'scene04.png', // 先写死
sceneId: info.id
});
}
const res: any = await editApp(formData); const res: any = await editApp(formData);
if (res.code === 200) Message.success('编辑成功'); if (res.code === 200) Message.success('编辑成功');
else Message.error(res.message); else Message.error(res.message);
@ -90,8 +92,8 @@ const AppHandleModal = ({ appInfo, visible, type, onChangeVisible, onClose, onRe
// 清空表单数据和其他变量数据 // 清空表单数据和其他变量数据
form.resetFields(); form.resetFields();
onClose();
onRefresh(); onRefresh();
onClose();
}; };
@ -153,7 +155,7 @@ const AppHandleModal = ({ appInfo, visible, type, onChangeVisible, onClose, onRe
); );
}; };
const SideBar: React.FC<SideBarProps> = ({ selected, identity, subMenuData, onMenuSelect, onRefresh }) => { const SideBar: React.FC<SideBarProps> = ({ selected, identity, subMenuData, onMenuSelect, onRefresh, onDeleteApp }) => {
const [menu, setMenu] = useState<MenuItemType[]>([]); const [menu, setMenu] = useState<MenuItemType[]>([]);
const [subMenuWidth, setSubMenuWidth] = useState(300); // 子菜单宽度状态 const [subMenuWidth, setSubMenuWidth] = useState(300); // 子菜单宽度状态
const [isSubMenuCollapsed, setIsSubMenuCollapsed] = useState(false); // 子菜单收起状态 const [isSubMenuCollapsed, setIsSubMenuCollapsed] = useState(false); // 子菜单收起状态
@ -330,6 +332,8 @@ const SideBar: React.FC<SideBarProps> = ({ selected, identity, subMenuData, onMe
closable: false, closable: false,
onOk: async () => { onOk: async () => {
await deleteApp(node.dataRef.id); await deleteApp(node.dataRef.id);
// 通知父组件应用已被删除
onDeleteApp?.(node.dataRef.id);
onRefresh(); onRefresh();
} }
}); });

Loading…
Cancel
Save