Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: customize sidebar navi #1336

Merged
merged 12 commits into from
May 6, 2023
8 changes: 8 additions & 0 deletions src/components/TheSettingsMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import SettingsDashboardTab from '@/components/settings/SettingsDashboardTab.vue
import SettingsGCodeViewerTab from '@/components/settings/SettingsGCodeViewerTab.vue'
import SettingsEditorTab from '@/components/settings/SettingsEditorTab.vue'
import SettingsTimelapseTab from '@/components/settings/SettingsTimelapseTab.vue'
import SettingsNavigationTab from '@/components/settings/SettingsNavigationTab.vue'

import Panel from '@/components/ui/Panel.vue'
import {
Expand All @@ -98,6 +99,7 @@ import {
mdiVideo3d,
mdiWebcam,
mdiDipSwitch,
mdiMenu,
} from '@mdi/js'
import SettingsMiscellaneousTab from '@/components/settings/SettingsMiscellaneousTab.vue'
@Component({
Expand All @@ -116,6 +118,7 @@ import SettingsMiscellaneousTab from '@/components/settings/SettingsMiscellaneou
SettingsEditorTab,
SettingsTimelapseTab,
SettingsMiscellaneousTab,
SettingsNavigationTab,
},
})
export default class TheSettingsMenu extends Mixins(BaseMixin) {
Expand Down Expand Up @@ -194,6 +197,11 @@ export default class TheSettingsMenu extends Mixins(BaseMixin) {
name: 'miscellaneous',
title: this.$t('Settings.MiscellaneousTab.Miscellaneous'),
},
{
icon: mdiMenu,
name: 'navigation',
title: this.$t('Settings.NavigationTab.Navigation'),
},
]

if (this.moonrakerComponents.includes('timelapse')) {
Expand Down
194 changes: 44 additions & 150 deletions src/components/TheSidebar.vue
Original file line number Diff line number Diff line change
@@ -1,46 +1,3 @@
<style>
.nav-logo {
height: 32px;
}

.small-list-item {
height: var(--sidebar-menu-item-height);
}

.no-text-decoration {
text-decoration: none;
background-color: transparent;
}

.no-background:before {
background-color: rgba(255, 255, 255, 0) !important;
}

.no-border {
border: 0 !important;
}
</style>
<style scoped>
.active-nav-item {
border-right: 4px solid var(--v-primary-base);
}

.menu-item-icon {
opacity: 0.85;
}

.menu-item-title {
line-height: 30px;
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
opacity: 0.85;
}

.nav-scrollbar {
height: 100%;
}
</style>
<template>
<v-navigation-drawer
:key="navigationStyle"
Expand All @@ -59,78 +16,27 @@
v-if="isMobile"
router
to="/"
:class="
'sidebar-logo no-text-decoration no-background no-border ' +
(navigationStyle === 'iconsOnly' ? 'pa-0 justify-center' : '')
"
:class="mobileLogoClass"
:style="'height: ' + topbarHeight + 'px'"
:ripple="false">
<template v-if="sidebarLogo">
<img :src="sidebarLogo" :style="logoCssVars" class="nav-logo" alt="Logo" />
</template>
<template v-else>
<mainsail-logo
:color="logoColor"
:style="logoCssVars"
class="nav-logo"
:ripple="false"></mainsail-logo>
<mainsail-logo :color="logoColor" :style="logoCssVars" class="nav-logo" :ripple="false" />
</template>
<template v-if="navigationStyle !== 'iconsOnly'">
<span class="text-h6 font-weight-regular text-truncate">{{ printerName }}</span>
</template>
</v-list-item>
<template v-if="countPrinters">
<v-tooltip right :open-delay="500" :disabled="navigationStyle !== 'iconsOnly'">
<template #activator="{ on, attrs }">
<v-list-item
router
to="/allPrinters"
class="small-list-item mt-1"
v-bind="attrs"
v-on="on">
<v-list-item-icon class="my-3 mr-3 menu-item-icon">
<v-icon>{{ mdiViewDashboardOutline }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title tile class="menu-item-title">
{{ $t('App.Printers') }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<span>{{ $t('App.Printers') }}</span>
</v-tooltip>
<v-divider class="my-1"></v-divider>
</template>
<div v-for="(category, index) in naviPoints" :key="index">
<v-tooltip right :open-delay="500" :disabled="navigationStyle !== 'iconsOnly'">
<template #activator="{ on, attrs }">
<v-list-item
router
:to="category.path"
class="small-list-item"
v-bind="attrs"
v-on="on">
<v-list-item-icon class="my-3 mr-3 menu-item-icon">
<v-icon>{{ category.icon }}</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title tile class="menu-item-title">
{{ $t(`Router.${category.title}`) }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
<span>{{ $t(`Router.${category.title}`) }}</span>
</v-tooltip>
</div>
<sidebar-item v-for="(category, index) in visibleNaviPoints" :key="index" :item="category" />
</v-list-item-group>
</v-list>
</overlay-scrollbars>
<template #append>
<v-list-item class="small-list-item mb-2">
<v-list-item-icon class="menu-item-icon">
<about-dialog></about-dialog>
<about-dialog />
</v-list-item-icon>
</v-list-item>
</template>
Expand All @@ -139,32 +45,27 @@

<script lang="ts">
import Component from 'vue-class-component'
import routes, { AppRoute } from '@/routes'
import { Mixins } from 'vue-property-decorator'
import BaseMixin from '@/components/mixins/base'
import { PrinterStateKlipperConfig } from '@/store/printer/types'
import TheSelectPrinterDialog from '@/components/TheSelectPrinterDialog.vue'
import AboutDialog from '@/components/dialogs/AboutDialog.vue'
import { navigationWidth, topbarHeight } from '@/store/variables'
import MainsailLogo from '@/components/ui/MainsailLogo.vue'
import { mdiViewDashboardOutline } from '@mdi/js'
import SidebarItem from '@/components/ui/SidebarItem.vue'
import NavigationMixin from '@/components/mixins/navigation'

@Component({
components: {
SidebarItem,
TheSelectPrinterDialog,
AboutDialog,
MainsailLogo,
},
})
export default class TheSidebar extends Mixins(BaseMixin) {
export default class TheSidebar extends Mixins(NavigationMixin, BaseMixin) {
navigationWidth = navigationWidth
topbarHeight = topbarHeight

/**
* Icons
*/
mdiViewDashboardOutline = mdiViewDashboardOutline

get naviDrawer(): boolean {
return this.$store.state.naviDrawer
}
Expand All @@ -181,45 +82,12 @@ export default class TheSidebar extends Mixins(BaseMixin) {
return this.$store.getters['files/getSidebarBackground']
}

get naviPoints(): AppRoute[] {
return routes.filter((element) => {
return element.showInNavi && this.showInNavi(element)
})
}

get klippy_state(): string {
return this.$store.state.server.klippy_state
}

get boolNaviWebcam(): boolean {
return this.$store.state.gui.uiSettings.boolWebcamNavi
}

get moonrakerComponents(): string[] {
return this.$store.state.server.components
}

get registeredDirectories(): string[] {
return this.$store.state.server.registered_directories
}

get klipperConfigfileSettings(): PrinterStateKlipperConfig[] {
return this.$store.state.printer.configfile?.settings ?? {}
}

get currentPage(): string {
return this.$route.fullPath
}

get countPrinters() {
return this.$store.getters['farm/countPrinters']
}

get boolNaviTemp(): boolean {
if (!this.isMobile && this.$vuetify.breakpoint.mdAndDown) {
return true
}
return false
return !this.isMobile && this.$vuetify.breakpoint.mdAndDown
}

get sidebarCssVars(): any {
Expand Down Expand Up @@ -255,20 +123,46 @@ export default class TheSidebar extends Mixins(BaseMixin) {
return {}
}

showInNavi(route: AppRoute): boolean {
if (['shutdown', 'error', 'disconnected'].includes(this.klippy_state) && !route.alwaysShow) return false
else if (route.title === 'Webcam' && !this.boolNaviWebcam) return false
else if (route.moonrakerComponent && !this.moonrakerComponents.includes(route.moonrakerComponent)) return false
else if (route.registeredDirectory && !this.registeredDirectories.includes(route.registeredDirectory))
return false
else if (route.klipperComponent && !(route.klipperComponent in this.klipperConfigfileSettings)) return false
else if (route.klipperIsConnected && !this.klippyIsConnected) return false
get mobileLogoClass() {
const output = ['sidebar-logo', 'no-text-decoration', 'no-background', 'no-border']

return true
if (this.navigationStyle === 'iconsOnly') {
output.push('pa-0')
output.push('justify-center')
}

return output
}

mounted() {
this.naviDrawer = this.$vuetify.breakpoint.lgAndUp
}
}
</script>

<style scoped>
.no-text-decoration {
text-decoration: none;
background-color: transparent;
}

.no-background:before {
background-color: rgba(255, 255, 255, 0) !important;
}

.no-border {
border: 0 !important;
}

.nav-logo {
height: 32px;
}

.menu-item-icon {
opacity: 0.85;
}

.nav-scrollbar {
height: 100%;
}
</style>
Loading