瀏覽代碼

chore: transforming a common sidebar into a separate component
- also added saving collapsed state

Shishkevich D. 1 周之前
父節點
當前提交
3ea05d30c1

+ 0 - 55
web/html/xui/common_sider.html

@@ -1,55 +0,0 @@
-{{define "menuItems"}}
-<a-menu-item key="{{ .base_path }}panel/">
-  <a-icon type="dashboard"></a-icon>
-  <span>{{ i18n "menu.dashboard"}}</span>
-</a-menu-item>
-<a-menu-item key="{{ .base_path }}panel/inbounds">
-  <a-icon type="user"></a-icon>
-  <span>{{ i18n "menu.inbounds"}}</span>
-</a-menu-item>
-<a-menu-item key="{{ .base_path }}panel/settings">
-  <a-icon type="setting"></a-icon>
-  <span>{{ i18n "menu.settings"}}</span>
-</a-menu-item>
-<a-menu-item key="{{ .base_path }}panel/xray">
-  <a-icon type="tool"></a-icon>
-  <span>{{ i18n "menu.xray"}}</span>
-</a-menu-item>
-<a-menu-item key="{{ .base_path }}logout">
-  <a-icon type="logout"></a-icon>
-  <span>{{ i18n "menu.logout"}}</span>
-</a-menu-item>
-{{end}}
-
-
-{{define "commonSider"}}
-<a-layout-sider :theme="themeSwitcher.currentTheme" id="sider" collapsible breakpoint="md">
-  <a-theme-switch></a-theme-switch>
-  <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key">
-    {{template "menuItems" .}}
-  </a-menu>
-</a-layout-sider>
-<a-drawer id="sider-drawer" placement="left" :closable="false" @close="siderDrawer.close()" :visible="siderDrawer.visible" :wrap-class-name="themeSwitcher.currentTheme" :wrap-style="{ padding: 0 }">
-  <div class="drawer-handle" @click="siderDrawer.change()" slot="handle">
-    <a-icon :type="siderDrawer.visible ? 'close' : 'menu-fold'"></a-icon>
-  </div>
-  <a-theme-switch></a-theme-switch>
-  <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="['{{ .request_uri }}']" @click="({key}) => key.startsWith('http') ? window.open(key) : location.href = key">
-    {{template "menuItems" .}}
-  </a-menu>
-</a-drawer>
-<script>
-  const siderDrawer = {
-    visible: false,
-    show() {
-      this.visible = true;
-    },
-    close() {
-      this.visible = false;
-    },
-    change() {
-      this.visible = !this.visible;
-    },
-  };
-</script>
-{{end}}

+ 101 - 0
web/html/xui/component/aSidebar.html

@@ -0,0 +1,101 @@
+{{define "component/sidebar/content"}}
+<template>
+    <div class="ant-sidebar">
+        <a-layout-sider :theme="themeSwitcher.currentTheme" collapsible :collapsed="collapsed"
+            @collapse="(isCollapsed, type) => collapseHandle(isCollapsed, type)" breakpoint="md">
+            <a-theme-switch></a-theme-switch>
+            <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="activeTab"
+                @click="({key}) => openLink(key)">
+                <a-menu-item v-for="tab in tabs" :key="tab.key">
+                    <a-icon :type="tab.icon"></a-icon>
+                    <span v-text="tab.title"></span>
+                </a-menu-item>
+            </a-menu>
+        </a-layout-sider>
+        <a-drawer placement="left" :closable="false" @close="closeDrawer" :visible="visible"
+            :wrap-class-name="themeSwitcher.currentTheme" :wrap-style="{ padding: 0 }" :style="{ height: '100%' }">
+            <div class="drawer-handle" @click="toggleDrawer" slot="handle">
+                <a-icon :type="visible ? 'close' : 'menu-fold'"></a-icon>
+            </div>
+            <a-theme-switch></a-theme-switch>
+            <a-menu :theme="themeSwitcher.currentTheme" mode="inline" :selected-keys="activeTab"
+                @click="({key}) => openLink(key)">
+                <a-menu-item v-for="tab in tabs" :key="tab.key">
+                    <a-icon :type="tab.icon"></a-icon>
+                    <span v-text="tab.title"></span>
+                </a-menu-item>
+            </a-menu>
+        </a-drawer>
+    </div>
+</template>
+{{end}}
+
+{{define "component/aSidebar"}}
+<style>
+    .ant-sidebar>.ant-layout-sider {
+        height: 100%;
+    }
+</style>
+
+<script>
+    const SIDEBAR_COLLAPSED_KEY = "isSidebarCollapsed"
+
+    Vue.component('a-sidebar', {
+        data() {
+            return {
+                tabs: [
+                    {
+                        key: '/panel/',
+                        icon: 'dashboard',
+                        title: '{{ i18n "menu.dashboard"}}'
+                    },
+                    {
+                        key: '/panel/inbounds',
+                        icon: 'user',
+                        title: '{{ i18n "menu.inbounds"}}'
+                    },
+                    {
+                        key: '/panel/settings',
+                        icon: 'setting',
+                        title: '{{ i18n "menu.settings"}}'
+                    },
+                    {
+                        key: '/panel/xray',
+                        icon: 'tool',
+                        title: '{{ i18n "menu.xray"}}'
+                    },
+                    {
+                        key: '/logout/',
+                        icon: 'logout',
+                        title: '{{ i18n "menu.logout"}}'
+                    },
+                ],
+                activeTab: [
+                    '{{ .request_uri }}'
+                ],
+                visible: false,
+                collapsed: JSON.parse(localStorage.getItem(SIDEBAR_COLLAPSED_KEY)),
+            }
+        },
+        methods: {
+            openLink(key) {
+                return key.startsWith('http') ? window.open(key) : location.href = key
+            },
+            closeDrawer() {
+                this.visible = false;
+            },
+            toggleDrawer() {
+                this.visible = !this.visible;
+            },
+            collapseHandle(collapsed, type) {
+                if (type === "clickTrigger") {
+                    localStorage.setItem(SIDEBAR_COLLAPSED_KEY, collapsed);
+
+                    this.collapsed = JSON.parse(localStorage.getItem(SIDEBAR_COLLAPSED_KEY));
+                }
+            }
+        },
+        template: `{{template "component/sidebar/content"}}`,
+    });
+</script>
+{{end}}

+ 2 - 2
web/html/xui/inbounds.html

@@ -133,7 +133,7 @@
 
 <body>
 <a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
-  {{ template "commonSider" . }}
+  <a-sidebar></a-sidebar>
   <a-layout id="content-layout">
     <a-layout-content>
       <a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
@@ -584,6 +584,7 @@
 <script src="{{ .base_path }}assets/uri/URI.min.js?{{ .cur_ver }}"></script>
 <script src="{{ .base_path }}assets/js/model/inbound.js?{{ .cur_ver }}"></script>
 <script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
+{{template "component/aSidebar" .}}
 {{template "component/aThemeSwitch" .}}
 {{template "component/aCustomStatistic" .}}
 {{template "component/aPersianDatepicker" .}}
@@ -678,7 +679,6 @@
         delimiters: ['[[', ']]'],
         el: '#app',
         data: {
-            siderDrawer,
             themeSwitcher,
             persianDatepicker,
             spinning: false,

+ 2 - 2
web/html/xui/index.html

@@ -74,7 +74,7 @@
 
 <body>
   <a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
-    {{ template "commonSider" . }}
+    <a-sidebar></a-sidebar>
     <a-layout id="content-layout">
       <a-layout-content>
         <a-spin :spinning="spinning" :delay="200" :tip="loadingTip">
@@ -417,6 +417,7 @@
     </a-modal>
   </a-layout>
 {{template "js" .}}
+{{template "component/aSidebar" .}}
 {{template "component/aThemeSwitch" .}}
 {{template "component/aCustomStatistic" .}}
 {{template "modals/textModal"}}
@@ -591,7 +592,6 @@
         delimiters: ['[[', ']]'],
         el: '#app',
         data: {
-            siderDrawer,
             themeSwitcher,
             status: new Status(),
             versionModal,

+ 2 - 2
web/html/xui/settings.html

@@ -70,7 +70,7 @@
 </style>
 <body>
   <a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
-    {{ template "commonSider" . }}
+    <a-sidebar></a-sidebar>
     <a-layout id="content-layout">
       <a-layout-content>
         <a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
@@ -131,6 +131,7 @@
   </a-layout>
 {{template "js" .}}
 <script src="{{ .base_path }}assets/js/model/setting.js?{{ .cur_ver }}"></script>
+{{template "component/aSidebar" .}}
 {{template "component/aThemeSwitch" .}}
 {{template "component/aPasswordInput" .}}
 {{template "component/aSettingListItem" .}}
@@ -139,7 +140,6 @@
     delimiters: ['[[', ']]'],
     el: '#app',
     data: {
-      siderDrawer,
       themeSwitcher,
       spinning: false,
       changeSecret: false,

+ 2 - 2
web/html/xui/xray.html

@@ -59,7 +59,7 @@
 </style>
 <body>
   <a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
-    {{ template "commonSider" . }}
+    <a-sidebar></a-sidebar>
     <a-layout id="content-layout">
       <a-layout-content>
         <a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
@@ -130,6 +130,7 @@
     </a-layout>
   </a-layout>
 {{template "js" .}}
+{{template "component/aSidebar" .}}
 {{template "component/aThemeSwitch" .}}
 {{template "component/aTableSortable" .}}
 {{template "component/aSettingListItem" .}}
@@ -207,7 +208,6 @@
         delimiters: ['[[', ']]'],
         el: '#app',
         data: {
-            siderDrawer,
             themeSwitcher,
             isDarkTheme: themeSwitcher.isDarkTheme,
             spinning: false,