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.

139 lines
3.5 KiB
TypeScript

1 year ago
import { Dropdown, Tabs } from 'antd';
import { useCallback, useMemo } from 'react';
import { history } from '@umijs/max';
import { KeepAliveTab, useKeepAliveTabs } from './useKeepAliveTabs';
import type { ItemType, MenuInfo } from 'rc-menu/lib/interface';
import { KeepAliveTabContext } from './context';
enum OperationType {
REFRESH = 'refresh',
CLOSE = 'close',
CLOSEOTHER = 'close-other',
}
type MenuItemType = ItemType & { key: OperationType } | null;
const KeepAliveLayout = () => {
const {
keepAliveTabs,
activeTabRoutePath,
closeTab,
refreshTab,
closeOtherTab,
onHidden,
onShow,
} = useKeepAliveTabs();
const menuItems: MenuItemType[] = useMemo(() => [
{
label: '刷新',
key: OperationType.REFRESH,
},
keepAliveTabs.length <= 1 ? null : {
label: '关闭',
key: OperationType.CLOSE,
},
keepAliveTabs.length <= 1 ? null : {
label: '关闭其他',
key: OperationType.CLOSEOTHER,
},
].filter(o => o), [keepAliveTabs]);
const menuClick = useCallback(({ key, domEvent }: MenuInfo, tab: KeepAliveTab) => {
domEvent.stopPropagation();
if (key === OperationType.REFRESH) {
refreshTab(tab.routePath);
} else if (key === OperationType.CLOSE) {
closeTab(tab.routePath);
} else if (key === OperationType.CLOSEOTHER) {
closeOtherTab(tab.routePath);
}
}, [closeOtherTab, closeTab, refreshTab]);
const renderTabTitle = useCallback((tab: KeepAliveTab) => {
return (
<Dropdown
menu={{ items: menuItems, onClick: (e) => menuClick(e, tab) }}
trigger={['contextMenu']}
>
<div style={{ margin: '-12px 0', padding: '12px 0' }}>
{/*{tab.icon}*/}
{tab.title}
</div>
</Dropdown>
)
}, [menuItems]);
const tabItems = useMemo(() => {
let finalKeepAliveTabs = keepAliveTabs
// .filter(item => !item?.isHideTab)
return finalKeepAliveTabs.map(tab => {
console.log(tab,'tabItems')
// TODO 未找到合适办法只去除tab标题栏位保留页面内容
return {
key: tab.routePath,
label: renderTabTitle(tab),
children: (
<div
key={tab.key}
style={{ height: 'calc(100vh - 232px)', overflow: 'auto' }}
>
{tab.children}
</div>
),
// style: {display: 'none'},
closable: keepAliveTabs.length > 1,
forceRender: true
}
})
}, [keepAliveTabs]);
const onTabsChange = useCallback((tabRoutePath: string) => {
const curTab = keepAliveTabs.find(o => o.routePath === tabRoutePath);
if (curTab) {
history.push(curTab?.pathname);
}
}, [keepAliveTabs]);
const onTabEdit = (
targetKey: React.MouseEvent | React.KeyboardEvent | string,
action: 'add' | 'remove',
) => {
if (action === 'remove') {
closeTab(targetKey as string);
}
};
const keepAliveContextValue = useMemo(
() => ({
closeTab,
closeOtherTab,
refreshTab,
onHidden,
onShow,
}),
[closeTab, closeOtherTab, refreshTab, onHidden, onShow]
);
return (
<KeepAliveTabContext.Provider value={keepAliveContextValue}>
<Tabs
type="editable-card"
items={tabItems}
activeKey={activeTabRoutePath}
onChange={onTabsChange}
className='keep-alive-tabs'
hideAdd
animated={false}
onEdit={onTabEdit}
/>
</KeepAliveTabContext.Provider>
)
}
export default KeepAliveLayout;