admin-vben5/packages/effects/layouts/src/basic/tabbar/use-tabs.ts

246 lines
6.4 KiB
TypeScript
Raw Normal View History

2024-05-19 21:20:42 +08:00
import type { IContextMenuItem } from '@vben-core/tabs-ui';
import type { TabDefinition } from '@vben-core/typings';
2024-06-08 19:49:06 +08:00
import type {
RouteLocationNormalized,
RouteLocationNormalizedGeneric,
2024-06-08 19:49:06 +08:00
} from 'vue-router';
2024-05-19 21:20:42 +08:00
import { computed, ref, watch } from 'vue';
2024-06-08 19:49:06 +08:00
import { useRoute, useRouter } from 'vue-router';
2024-05-19 21:20:42 +08:00
import {
ArrowLeftToLine,
ArrowRightLeft,
ArrowRightToLine,
ExternalLink,
FoldHorizontal,
Fullscreen,
2024-05-19 21:20:42 +08:00
MdiPin,
MdiPinOff,
Minimize2,
RotateCw,
X,
} from '@vben-core/icons';
import { $t, useI18n } from '@vben-core/locales';
import { updatePreferences, usePreferences } from '@vben-core/preferences';
import {
storeToRefs,
useCoreAccessStore,
useCoreTabbarStore,
} from '@vben-core/stores';
import { filterTree, openWindow } from '@vben-core/toolkit';
function updateContentScreen(screen: boolean) {
updatePreferences({
header: {
hidden: !!screen,
},
sidebar: {
hidden: !!screen,
},
});
}
2024-05-19 21:20:42 +08:00
function useTabs() {
const router = useRouter();
const route = useRoute();
const accessStore = useCoreAccessStore();
const { contentIsMaximize } = usePreferences();
2024-07-10 00:50:41 +08:00
const coreTabbarStore = useCoreTabbarStore();
2024-05-19 21:20:42 +08:00
const { accessMenus } = storeToRefs(accessStore);
const currentActive = computed(() => {
return route.path;
});
const { locale } = useI18n();
const currentTabs = ref<RouteLocationNormalizedGeneric[]>();
2024-07-10 00:50:41 +08:00
watch([() => coreTabbarStore.getTabs, () => locale.value], ([tabs, _]) => {
currentTabs.value = tabs.map((item) => wrapperTabLocale(item));
2024-05-19 21:20:42 +08:00
});
/**
*
*/
const initAffixTabs = () => {
const affixTabs = filterTree(router.getRoutes(), (route) => {
return !!route.meta?.affixTab;
});
2024-07-10 00:50:41 +08:00
coreTabbarStore.setAffixTabs(affixTabs);
2024-05-19 21:20:42 +08:00
};
// 点击tab,跳转路由
const handleClick = (key: string) => {
router.push(key);
};
// 关闭tab
const handleClose = async (key: string) => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.closeTabByKey(key, router);
2024-05-19 21:20:42 +08:00
};
function wrapperTabLocale(tab: RouteLocationNormalizedGeneric) {
return {
...tab,
meta: {
...tab?.meta,
title: $t(tab?.meta?.title as string),
},
};
}
2024-05-19 21:20:42 +08:00
watch(
() => accessMenus.value,
() => {
initAffixTabs();
},
{ immediate: true },
);
watch(
() => route.path,
() => {
2024-07-10 00:50:41 +08:00
coreTabbarStore.addTab(route as RouteLocationNormalized);
2024-05-19 21:20:42 +08:00
},
{ immediate: true },
);
const createContextMenus = (tab: TabDefinition) => {
2024-07-10 00:50:41 +08:00
const tabs = coreTabbarStore.getTabs;
const affixTabs = coreTabbarStore.affixTabs;
2024-05-19 21:20:42 +08:00
const index = tabs.findIndex((item) => item.path === tab.path);
const disabled = tabs.length <= 1;
const { meta } = tab;
const affixTab = meta?.affixTab ?? false;
const isCurrentTab = route.path === tab.path;
// 当前处于最左侧或者减去固定标签页的数量等于0
const closeLeftDisabled =
index === 0 || index - affixTabs.length <= 0 || !isCurrentTab;
const closeRightDisabled = !isCurrentTab || index === tabs.length - 1;
const closeOtherDisabled =
disabled || !isCurrentTab || tabs.length - affixTabs.length <= 1;
const menus: IContextMenuItem[] = [
{
disabled: !!affixTab || disabled,
handler: async () => {
await coreTabbarStore.closeTab(tab, router);
},
icon: X,
key: 'close',
text: $t('preferences.tabbar.contextMenu.close'),
},
{
handler: async () => {
await (affixTab
? coreTabbarStore.unpinTab(tab)
: coreTabbarStore.pinTab(tab));
},
icon: affixTab ? MdiPinOff : MdiPin,
key: 'affix',
text: affixTab
? $t('preferences.tabbar.contextMenu.unpin')
: $t('preferences.tabbar.contextMenu.pin'),
},
{
handler: async () => {
if (!contentIsMaximize.value) {
await router.push(tab.fullPath);
}
updateContentScreen(!contentIsMaximize.value);
},
icon: contentIsMaximize.value ? Minimize2 : Fullscreen,
key: contentIsMaximize.value ? 'restore-maximize' : 'maximize',
text: contentIsMaximize.value
? $t('preferences.tabbar.contextMenu.restoreMaximize')
: $t('preferences.tabbar.contextMenu.maximize'),
},
2024-05-19 21:20:42 +08:00
{
disabled: !isCurrentTab,
handler: async () => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.refresh(router);
2024-05-19 21:20:42 +08:00
},
icon: RotateCw,
2024-05-19 21:20:42 +08:00
key: 'reload',
text: $t('preferences.tabbar.contextMenu.reload'),
2024-05-19 21:20:42 +08:00
},
{
handler: async () => {
const { hash, origin } = location;
const path = tab.fullPath;
const fullPath = path.startsWith('/') ? path : `/${path}`;
const url = `${origin}${hash ? '/#' : ''}${fullPath}`;
openWindow(url, { target: '_blank' });
},
icon: ExternalLink,
key: 'open-in-new-window',
separator: true,
text: $t('preferences.tabbar.contextMenu.openInNewWindow'),
},
2024-05-19 21:20:42 +08:00
{
disabled: closeLeftDisabled,
handler: async () => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.closeLeftTabs(tab);
2024-05-19 21:20:42 +08:00
},
icon: ArrowLeftToLine,
2024-05-19 21:20:42 +08:00
key: 'close-left',
text: $t('preferences.tabbar.contextMenu.closeLeft'),
2024-05-19 21:20:42 +08:00
},
{
disabled: closeRightDisabled,
handler: async () => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.closeRightTabs(tab);
2024-05-19 21:20:42 +08:00
},
icon: ArrowRightToLine,
2024-05-19 21:20:42 +08:00
key: 'close-right',
separator: true,
text: $t('preferences.tabbar.contextMenu.closeRight'),
2024-05-19 21:20:42 +08:00
},
{
disabled: closeOtherDisabled,
handler: async () => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.closeOtherTabs(tab);
2024-05-19 21:20:42 +08:00
},
icon: FoldHorizontal,
2024-05-19 21:20:42 +08:00
key: 'close-other',
text: $t('preferences.tabbar.contextMenu.closeOther'),
2024-05-19 21:20:42 +08:00
},
{
disabled,
handler: async () => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.closeAllTabs(router);
2024-05-19 21:20:42 +08:00
},
icon: ArrowRightLeft,
2024-05-19 21:20:42 +08:00
key: 'close-all',
text: $t('preferences.tabbar.contextMenu.closeAll'),
2024-05-19 21:20:42 +08:00
},
];
return menus;
};
/**
*
*/
const handleUnpinTab = async (tab: TabDefinition) => {
2024-07-10 00:50:41 +08:00
await coreTabbarStore.unpinTab(tab);
2024-05-19 21:20:42 +08:00
};
return {
createContextMenus,
currentActive,
currentTabs,
handleClick,
handleClose,
2024-07-10 00:50:41 +08:00
handleUnpinTab,
2024-05-19 21:20:42 +08:00
};
}
export { updateContentScreen, useTabs };