Use pankow SideBar component
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
<script setup>
|
||||
|
||||
import { onMounted, ref, useTemplateRef } from 'vue';
|
||||
import { Notification, fetcher } from 'pankow';
|
||||
import { Notification, fetcher, SideBar } from 'pankow';
|
||||
import { API_ORIGIN, TOKEN_TYPES } from './constants.js';
|
||||
import ProfileModel from './models/ProfileModel.js';
|
||||
import DashboardModel from './models/DashboardModel.js';
|
||||
import Sidebar from './components/Sidebar.vue';
|
||||
import Headerbar from './components/Headerbar.vue';
|
||||
import OfflineOverlay from './components/OfflineOverlay.vue';
|
||||
import AppsView from './views/AppsView.vue';
|
||||
@@ -88,6 +87,7 @@ fetcher.globalOptions.errorHook = (error) => {
|
||||
const dashboardModel = DashboardModel.create();
|
||||
const profileModel = ProfileModel.create();
|
||||
|
||||
const sidebar = useTemplateRef('sidebar');
|
||||
const ready = ref(false);
|
||||
const view = ref('');
|
||||
const profile = ref({});
|
||||
@@ -96,9 +96,24 @@ const subscription = ref({
|
||||
});
|
||||
const config = ref({});
|
||||
|
||||
function onSidebarClose() {
|
||||
sidebar.value.close();
|
||||
}
|
||||
|
||||
const activeSidebarItem = ref('');
|
||||
const activeSidebarGroup = ref('');
|
||||
function onToggleGroup(group) {
|
||||
activeSidebarGroup.value = activeSidebarGroup.value === group ? '' : group;
|
||||
}
|
||||
|
||||
function onHashChange() {
|
||||
const v = location.hash.slice(2);
|
||||
|
||||
activeSidebarItem.value = v;
|
||||
|
||||
if (activeSidebarItem.value.indexOf('email') === 0) activeSidebarGroup.value = 'email';
|
||||
else activeSidebarGroup.value = '';
|
||||
|
||||
if (v === VIEWS.APPS) {
|
||||
view.value = VIEWS.APPS;
|
||||
} else if (v.indexOf(VIEWS.APPSTORE) === 0) {
|
||||
@@ -184,7 +199,35 @@ onMounted(async () => {
|
||||
<Transition name="pankow-animation-pop-up">
|
||||
<div v-if="ready" style="display: flex; flex-direction: row; overflow: hidden; height: 100%;">
|
||||
|
||||
<Sidebar v-if="profile.isAtLeastUserManager" :profile="profile" :config="config"/>
|
||||
<!-- <Sidebar :profile="profile" :config="config"/> -->
|
||||
<SideBar v-if="profile.isAtLeastUserManager" ref="sidebar">
|
||||
<a href="#/" class="sidebar-logo" @click="onSidebarClose()">
|
||||
<img :src="`https://${config.adminFqdn}/api/v1/cloudron/avatar`" width="40" height="40"/> {{ config.cloudronName || 'Cloudron' }}
|
||||
</a>
|
||||
<div class="sidebar-list">
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'apps' }" href="#/apps" @click="onSidebarClose()"><i class="fa fa-grip fa-fw"></i> {{ $t('apps.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'appstore' }" v-show="profile.isAtLeastAdmin" href="#/appstore" @click="onSidebarClose()"><i class="fa fa-cloud-download-alt fa-fw"></i> {{ $t('appstore.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'users' }" v-show="profile.isAtLeastUserManager" href="#/users" @click="onSidebarClose()"><i class="fa fa-users fa-fw"></i> {{ $t('main.navbar.users') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'backups' }" v-show="profile.isAtLeastAdmin" href="#/backups" @click="onSidebarClose()"><i class="fa fa-archive fa-fw"></i> {{ $t('backups.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'branding' }" v-show="profile.isAtLeastAdmin" href="#/branding" @click="onSidebarClose()"><i class="fa fa-passport fa-fw"></i> {{ $t('branding.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'domains' }" v-show="profile.isAtLeastAdmin" href="#/domains" @click="onSidebarClose()"><i class="fa fa-globe fa-fw"></i> {{ $t('domains.title') }}</a>
|
||||
<div class="sidebar-item actionable" v-show="profile.isAtLeastMailManager" @click="onToggleGroup('email')"><i class="fa fa-envelope fa-fw"></i> {{ $t('emails.title') }}</div>
|
||||
<Transition name="sidebar-item-group-animation">
|
||||
<div class="sidebar-item-group" v-if="activeSidebarGroup === 'email'">
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'emails-mailboxes' }" href="#/emails-mailboxes" @click="onSidebarClose()"><i class="fa fa-inbox fa-fw"></i> {{ $t('email.incoming.mailboxes.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'emails-mailinglists' }" href="#/emails-mailinglists" @click="onSidebarClose()"><i class="fa-solid fa-envelopes-bulk fa-fw"></i> {{ $t('email.incoming.mailinglists.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'email' }" href="#/email" @click="onSidebarClose()"><i class="fa fa-cog fa-fw"></i> {{ $t('emails.title') }} {{ $t('settings.title') }}</a>
|
||||
</div>
|
||||
</Transition>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'eventlog' }" v-show="profile.isAtLeastAdmin" href="#/eventlog" @click="onSidebarClose()"><i class="fa fa-list-alt fa-fw"></i> {{ $t('eventlog.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'network' }" v-show="profile.isAtLeastAdmin" href="#/network" @click="onSidebarClose()"><i class="fas fa-network-wired fa-fw"></i> {{ $t('network.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'services' }" v-show="profile.isAtLeastAdmin" href="#/services" @click="onSidebarClose()"><i class="fa fa-cogs fa-fw"></i> {{ $t('services.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'settings' }" v-show="profile.isAtLeastAdmin" href="#/settings" @click="onSidebarClose()"><i class="fa fa-wrench fa-fw"></i> {{ $t('settings.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'user-directory' }" v-show="profile.isAtLeastAdmin" href="#/user-directory" @click="onSidebarClose()"><i class="fa fa-users-gear fa-fw"></i> {{ $t('users.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'volumes' }" v-show="profile.isAtLeastAdmin" href="#/volumes" @click="onSidebarClose()"><i class="fa fa-hdd fa-fw"></i> {{ $t('volumes.title') }}</a>
|
||||
<a class="sidebar-item" :class="{ active: activeSidebarItem === 'system' }" v-show="profile.isAtLeastAdmin" href="#/system" @click="onSidebarClose()"><i class="fa fa-chart-area fa-fw"></i> {{ $t('system.title') }}</a>
|
||||
</div>
|
||||
</SideBar>
|
||||
|
||||
<div style="flex-grow: 1; display: flex; flex-direction: column; overflow: hidden; height: 100%;">
|
||||
<Headerbar :config="config" :subscription="subscription" :profile="profile"/>
|
||||
@@ -218,3 +261,93 @@ onMounted(async () => {
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.pankow-sidebar {
|
||||
background-color: var(--navbar-background);
|
||||
border-right: 1px solid var(--pankow-color-background-hover);
|
||||
padding: 22px 10px 10px 10px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.sidebar-logo img {
|
||||
margin-right: 10px;
|
||||
border-radius: var(--pankow-border-radius);
|
||||
}
|
||||
|
||||
.sidebar-logo,
|
||||
.sidebar-logo:hover {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--pankow-text-color);
|
||||
text-decoration: none;
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.sidebar-list {
|
||||
overflow: auto;
|
||||
padding-top: 20px;
|
||||
scrollbar-color: transparent transparent;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
.sidebar-list:hover {
|
||||
scrollbar-color: var(--color-neutral-border) transparent;
|
||||
}
|
||||
|
||||
.sidebar-item {
|
||||
display: block;
|
||||
color: var(--pankow-text-color);
|
||||
border-radius: 3px;
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.sidebar-item i {
|
||||
opacity: 0.5;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.sidebar-item.active {
|
||||
color: var(--pankow-color-primary);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sidebar-item:hover {
|
||||
background-color: #e9ecef;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.sidebar-item:hover {
|
||||
background-color: var(--card-background);
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-item.active i ,
|
||||
.sidebar-item:hover i {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar-item-group {
|
||||
padding-left: 20px;
|
||||
height: auto;
|
||||
overflow: hidden;
|
||||
/* we need height to auto so we animate max-height. needs to be bigger than we need */
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.sidebar-item-group-animation-enter-active,
|
||||
.sidebar-item-group-animation-leave-active {
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
.sidebar-item-group-animation-leave-to,
|
||||
.sidebar-item-group-animation-enter-from {
|
||||
transform: translateX(-100px);
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user