mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2025-04-19 13:32:24 +00:00
chore: transforming a common sidebar into a separate component
- also added saving collapsed state
This commit is contained in:
parent
40ebf2902e
commit
3ea05d30c1
6 changed files with 109 additions and 63 deletions
|
@ -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
web/html/xui/component/aSidebar.html
Normal file
101
web/html/xui/component/aSidebar.html
Normal file
|
@ -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}}
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue