118 lines
2.3 KiB
Vue
118 lines
2.3 KiB
Vue
<template>
|
|
<div class="default-layout">
|
|
<NavigationSidebar>
|
|
<template #logo>
|
|
<NavigationLogo />
|
|
</template>
|
|
|
|
<template #default>
|
|
<NavigationItem
|
|
v-for="item in navItems"
|
|
:key="item.to"
|
|
:to="item.to"
|
|
:icon="item.icon"
|
|
:title="item.title"
|
|
:matcher="item.matcher ?? defaultMatcher(item.to)"
|
|
/>
|
|
</template>
|
|
|
|
<template #bottom>
|
|
<NavigationItem
|
|
icon="info"
|
|
title="Help"
|
|
to="/_"
|
|
:matcher="() => ['/help'].includes(route.fullPath)"
|
|
/>
|
|
</template>
|
|
</NavigationSidebar>
|
|
|
|
<main
|
|
class="default-layout__main"
|
|
:class="{
|
|
center: shouldCenterContent,
|
|
narrow: isAnySidebarOpened,
|
|
}"
|
|
>
|
|
<div class="container">
|
|
<slot />
|
|
</div>
|
|
</main>
|
|
|
|
<ModalsContainer />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ModalsContainer, useVfm } from 'vue-final-modal'
|
|
|
|
const { t } = useI18n()
|
|
const route = useRoute()
|
|
const { openedModals } = useVfm()
|
|
|
|
const defaultMatcher = link => () => route.fullPath === link
|
|
|
|
const navItems = computed(() => [
|
|
{
|
|
icon: 'merchant',
|
|
title: t('projects'),
|
|
to: '/projects',
|
|
matcher: () =>
|
|
route.fullPath === '/projects'
|
|
|| route.fullPath.startsWith('/projects')
|
|
|| route.meta.alias?.startsWith('/projects'),
|
|
},
|
|
])
|
|
|
|
const shouldCenterContent = computed(() => route.meta.centerContent)
|
|
const isAnySidebarOpened = computed(() => openedModals.some(modal => modal.value.modalId.startsWith('sidebar') && modal.value.overlayVisible.value))
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.default-layout {
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
display: grid;
|
|
grid-template-columns: 120px 1fr;
|
|
|
|
grid-area: sidebar;
|
|
overflow-y: hidden;
|
|
z-index: 1;
|
|
|
|
&__main {
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow-y: auto;
|
|
min-height: 100%;
|
|
padding: 0 35px 32px;
|
|
transition: padding-right .2s ease-in-out;
|
|
|
|
&.center {
|
|
padding-top: 32px;
|
|
|
|
> .container {
|
|
margin-block: auto;
|
|
}
|
|
}
|
|
|
|
&.narrow {
|
|
padding-right: calc(353px + 35px);
|
|
}
|
|
|
|
&:not(.center) {
|
|
> .container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
> .container {
|
|
width: 100%;
|
|
max-width: 1250px;
|
|
margin: 0 auto;
|
|
}
|
|
}
|
|
}
|
|
</style>
|