Browse Source

feat: tabs adds new window opening and maximizing/restore capabilities

vince 8 months ago
parent
commit
59a8ce9500

+ 12 - 0
packages/@core/forward/preferences/src/use-preferences.ts

@@ -138,10 +138,22 @@ function usePreferences() {
     return enable && globalPreferences;
   });
 
+  /**
+   * @zh_CN 内容是否已经最大化
+   * 排除 full-content模式
+   */
+  const contentIsMaximize = computed(() => {
+    const headerIsHidden = preferences.header.hidden;
+    const sidebarIsHidden = preferences.sidebar.hidden;
+
+    return headerIsHidden && sidebarIsHidden && !isFullContent.value;
+  });
+
   return {
     authPanelCenter,
     authPanelLeft,
     authPanelRight,
+    contentIsMaximize,
     diffPreference,
     globalLockScreenShortcutKey,
     globalLogoutShortcutKey,

+ 4 - 1
packages/@core/locales/src/langs/en-US.json

@@ -184,7 +184,10 @@
         "closeLeft": "Close Left Tabs",
         "closeRight": "Close Right Tabs",
         "closeOther": "Close Other Tabs",
-        "closeAll": "Close All Tabs"
+        "closeAll": "Close All Tabs",
+        "openInNewWindow": "Open in New Window",
+        "maximize": "Maximize",
+        "restoreMaximize": "Restore"
       }
     },
     "navigationMenu": {

+ 4 - 1
packages/@core/locales/src/langs/zh-CN.json

@@ -184,7 +184,10 @@
         "closeLeft": "关闭左侧标签页",
         "closeRight": "关闭右侧标签页",
         "closeOther": "关闭其它标签页",
-        "closeAll": "关闭全部标签页"
+        "closeAll": "关闭全部标签页",
+        "openInNewWindow": "在新窗口打开",
+        "maximize": "最大化",
+        "restoreMaximize": "还原"
       }
     },
     "navigationMenu": {

+ 2 - 0
packages/@core/shared/iconify/src/material.ts

@@ -79,6 +79,8 @@ export const IcRoundArrowBackIosNew = createIconifyIcon(
 
 export const IcRoundMultipleStop = createIconifyIcon('ic:round-multiple-stop');
 
+export const IcRoundTableView = createIconifyIcon('ic:round-table-view');
+
 export const IcRoundRefresh = createIconifyIcon('ic:round-refresh');
 
 export const IcRoundCreditScore = createIconifyIcon('ic:round-credit-score');

+ 4 - 15
packages/business/layouts/src/basic/tabbar/tabbar-tools.vue

@@ -2,10 +2,10 @@
 import { computed } from 'vue';
 import { useRoute } from 'vue-router';
 
-import { preferences, updatePreferences } from '@vben-core/preferences';
+import { preferences } from '@vben-core/preferences';
 import { TabsToolMore, TabsToolScreen } from '@vben-core/tabs-ui';
 
-import { useTabs } from './use-tabs';
+import { updateContentScreen, useTabs } from './use-tabs';
 
 const route = useRoute();
 
@@ -14,17 +14,6 @@ const { createContextMenus } = useTabs();
 const menus = computed(() => {
   return createContextMenus(route);
 });
-
-function handleScreenChange(screen: boolean) {
-  updatePreferences({
-    header: {
-      hidden: !!screen,
-    },
-    sidebar: {
-      hidden: !!screen,
-    },
-  });
-}
 </script>
 
 <template>
@@ -32,8 +21,8 @@ function handleScreenChange(screen: boolean) {
     <TabsToolMore :menus="menus" />
     <TabsToolScreen
       :screen="preferences.sidebar.hidden"
-      @change="handleScreenChange"
-      @update:screen="handleScreenChange"
+      @change="updateContentScreen"
+      @update:screen="updateContentScreen"
     />
   </div>
 </template>

+ 44 - 8
packages/business/layouts/src/basic/tabbar/use-tabs.ts

@@ -10,8 +10,11 @@ import { useRoute, useRouter } from 'vue-router';
 
 import {
   IcRoundClose,
+  IcRoundFitScreen,
   IcRoundMultipleStop,
   IcRoundRefresh,
+  IcRoundTableView,
+  IcTwotoneFitScreen,
   MdiArrowExpandHorizontal,
   MdiFormatHorizontalAlignLeft,
   MdiFormatHorizontalAlignRight,
@@ -19,17 +22,30 @@ import {
   MdiPinOff,
 } from '@vben-core/iconify';
 import { $t, useI18n } from '@vben-core/locales';
+import { updatePreferences, usePreferences } from '@vben-core/preferences';
 import {
   storeToRefs,
   useCoreAccessStore,
   useCoreTabbarStore,
 } from '@vben-core/stores';
-import { filterTree } from '@vben-core/toolkit';
+import { filterTree, openWindow } from '@vben-core/toolkit';
+
+function updateContentScreen(screen: boolean) {
+  updatePreferences({
+    header: {
+      hidden: !!screen,
+    },
+    sidebar: {
+      hidden: !!screen,
+    },
+  });
+}
 
 function useTabs() {
   const router = useRouter();
   const route = useRoute();
   const accessStore = useCoreAccessStore();
+  const { contentIsMaximize } = usePreferences();
   const coreTabbarStore = useCoreTabbarStore();
   const { accessMenus } = storeToRefs(accessStore);
 
@@ -136,11 +152,36 @@ function useTabs() {
         },
         icon: affixTab ? MdiPinOff : MdiPin,
         key: 'affix',
-        separator: true,
         text: affixTab
           ? $t('preferences.tabbar.contextMenu.unpin')
           : $t('preferences.tabbar.contextMenu.pin'),
       },
+      {
+        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: IcRoundTableView,
+        key: 'open-in-new-window',
+        text: $t('preferences.tabbar.contextMenu.openInNewWindow'),
+      },
+      {
+        handler: async () => {
+          if (!contentIsMaximize.value) {
+            await router.push(tab.fullPath);
+          }
+          updateContentScreen(!contentIsMaximize.value);
+        },
+        icon: contentIsMaximize.value ? IcRoundFitScreen : IcTwotoneFitScreen,
+        key: contentIsMaximize.value ? 'restore-maximize' : 'maximize',
+        separator: true,
+        text: contentIsMaximize.value
+          ? $t('preferences.tabbar.contextMenu.restoreMaximize')
+          : $t('preferences.tabbar.contextMenu.maximize'),
+      },
       {
         disabled: closeLeftDisabled,
         handler: async () => {
@@ -178,11 +219,6 @@ function useTabs() {
         key: 'close-all',
         text: $t('preferences.tabbar.contextMenu.closeAll'),
       },
-      // {
-      //   icon: 'icon-[material-symbols--back-to-tab-sharp]',
-      //   key: 'close-all',
-      //   text: '新窗口打开',
-      // },
     ];
     return menus;
   };
@@ -204,4 +240,4 @@ function useTabs() {
   };
 }
 
-export { useTabs };
+export { updateContentScreen, useTabs };