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>
|
<body>
|
||||||
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
||||||
{{ template "commonSider" . }}
|
<a-sidebar></a-sidebar>
|
||||||
<a-layout id="content-layout">
|
<a-layout id="content-layout">
|
||||||
<a-layout-content>
|
<a-layout-content>
|
||||||
<a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
<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/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/inbound.js?{{ .cur_ver }}"></script>
|
||||||
<script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/model/dbinbound.js?{{ .cur_ver }}"></script>
|
||||||
|
{{template "component/aSidebar" .}}
|
||||||
{{template "component/aThemeSwitch" .}}
|
{{template "component/aThemeSwitch" .}}
|
||||||
{{template "component/aCustomStatistic" .}}
|
{{template "component/aCustomStatistic" .}}
|
||||||
{{template "component/aPersianDatepicker" .}}
|
{{template "component/aPersianDatepicker" .}}
|
||||||
|
@ -678,7 +679,6 @@
|
||||||
delimiters: ['[[', ']]'],
|
delimiters: ['[[', ']]'],
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
siderDrawer,
|
|
||||||
themeSwitcher,
|
themeSwitcher,
|
||||||
persianDatepicker,
|
persianDatepicker,
|
||||||
spinning: false,
|
spinning: false,
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
||||||
{{ template "commonSider" . }}
|
<a-sidebar></a-sidebar>
|
||||||
<a-layout id="content-layout">
|
<a-layout id="content-layout">
|
||||||
<a-layout-content>
|
<a-layout-content>
|
||||||
<a-spin :spinning="spinning" :delay="200" :tip="loadingTip">
|
<a-spin :spinning="spinning" :delay="200" :tip="loadingTip">
|
||||||
|
@ -417,6 +417,7 @@
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
{{template "js" .}}
|
{{template "js" .}}
|
||||||
|
{{template "component/aSidebar" .}}
|
||||||
{{template "component/aThemeSwitch" .}}
|
{{template "component/aThemeSwitch" .}}
|
||||||
{{template "component/aCustomStatistic" .}}
|
{{template "component/aCustomStatistic" .}}
|
||||||
{{template "modals/textModal"}}
|
{{template "modals/textModal"}}
|
||||||
|
@ -591,7 +592,6 @@
|
||||||
delimiters: ['[[', ']]'],
|
delimiters: ['[[', ']]'],
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
siderDrawer,
|
|
||||||
themeSwitcher,
|
themeSwitcher,
|
||||||
status: new Status(),
|
status: new Status(),
|
||||||
versionModal,
|
versionModal,
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
||||||
{{ template "commonSider" . }}
|
<a-sidebar></a-sidebar>
|
||||||
<a-layout id="content-layout">
|
<a-layout id="content-layout">
|
||||||
<a-layout-content>
|
<a-layout-content>
|
||||||
<a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
<a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
||||||
|
@ -131,6 +131,7 @@
|
||||||
</a-layout>
|
</a-layout>
|
||||||
{{template "js" .}}
|
{{template "js" .}}
|
||||||
<script src="{{ .base_path }}assets/js/model/setting.js?{{ .cur_ver }}"></script>
|
<script src="{{ .base_path }}assets/js/model/setting.js?{{ .cur_ver }}"></script>
|
||||||
|
{{template "component/aSidebar" .}}
|
||||||
{{template "component/aThemeSwitch" .}}
|
{{template "component/aThemeSwitch" .}}
|
||||||
{{template "component/aPasswordInput" .}}
|
{{template "component/aPasswordInput" .}}
|
||||||
{{template "component/aSettingListItem" .}}
|
{{template "component/aSettingListItem" .}}
|
||||||
|
@ -139,7 +140,6 @@
|
||||||
delimiters: ['[[', ']]'],
|
delimiters: ['[[', ']]'],
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
siderDrawer,
|
|
||||||
themeSwitcher,
|
themeSwitcher,
|
||||||
spinning: false,
|
spinning: false,
|
||||||
changeSecret: false,
|
changeSecret: false,
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
<a-layout id="app" v-cloak :class="themeSwitcher.currentTheme">
|
||||||
{{ template "commonSider" . }}
|
<a-sidebar></a-sidebar>
|
||||||
<a-layout id="content-layout">
|
<a-layout id="content-layout">
|
||||||
<a-layout-content>
|
<a-layout-content>
|
||||||
<a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
<a-spin :spinning="spinning" :delay="500" tip='{{ i18n "loading"}}'>
|
||||||
|
@ -130,6 +130,7 @@
|
||||||
</a-layout>
|
</a-layout>
|
||||||
</a-layout>
|
</a-layout>
|
||||||
{{template "js" .}}
|
{{template "js" .}}
|
||||||
|
{{template "component/aSidebar" .}}
|
||||||
{{template "component/aThemeSwitch" .}}
|
{{template "component/aThemeSwitch" .}}
|
||||||
{{template "component/aTableSortable" .}}
|
{{template "component/aTableSortable" .}}
|
||||||
{{template "component/aSettingListItem" .}}
|
{{template "component/aSettingListItem" .}}
|
||||||
|
@ -207,7 +208,6 @@
|
||||||
delimiters: ['[[', ']]'],
|
delimiters: ['[[', ']]'],
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
siderDrawer,
|
|
||||||
themeSwitcher,
|
themeSwitcher,
|
||||||
isDarkTheme: themeSwitcher.isDarkTheme,
|
isDarkTheme: themeSwitcher.isDarkTheme,
|
||||||
spinning: false,
|
spinning: false,
|
||||||
|
|
Loading…
Reference in a new issue