111 lines
4.0 KiB
Vue
111 lines
4.0 KiB
Vue
<script setup lang="ts">
|
|
import { Link, router } from '@inertiajs/vue3';
|
|
import { Settings2, X } from 'lucide-vue-next';
|
|
import { computed, onMounted, onUnmounted } from 'vue';
|
|
import AppLogo from '@/components/AppLogo.vue';
|
|
import NavMain from '@/components/NavMain.vue';
|
|
import { Button } from '@/components/ui/button';
|
|
import {
|
|
Sidebar,
|
|
SidebarContent,
|
|
SidebarFooter,
|
|
SidebarHeader,
|
|
SidebarMenu,
|
|
SidebarMenuButton,
|
|
SidebarMenuItem,
|
|
useSidebar,
|
|
} from '@/components/ui/sidebar';
|
|
import { useAppNavigation } from '@/composables/useAppNavigation';
|
|
import { useCurrentUrl } from '@/composables/useCurrentUrl';
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import { dashboard } from '@/routes';
|
|
import { edit as profile } from '@/routes/profile';
|
|
import { show } from '@/routes/projects';
|
|
|
|
const { t } = useLocalization();
|
|
const { currentUrl } = useCurrentUrl();
|
|
const { project, workspaceItems, projectItems, projectSettingsItems } =
|
|
useAppNavigation();
|
|
const { isMobile, setOpenMobile } = useSidebar();
|
|
const accountItems = computed(() => [
|
|
{
|
|
title: t('navigation.settings'),
|
|
href: profile(),
|
|
icon: Settings2,
|
|
isActive: currentUrl.value.startsWith('/settings/'),
|
|
},
|
|
]);
|
|
let removeNavigationListener: (() => void) | undefined;
|
|
onMounted(() => {
|
|
removeNavigationListener = router.on('navigate', () =>
|
|
setOpenMobile(false),
|
|
);
|
|
});
|
|
onUnmounted(() => removeNavigationListener?.());
|
|
</script>
|
|
|
|
<template>
|
|
<Sidebar id="app-navigation" collapsible="icon" variant="sidebar">
|
|
<SidebarHeader class="border-sidebar-border gap-4 border-b p-3">
|
|
<div class="flex items-center gap-2">
|
|
<SidebarMenu class="min-w-0">
|
|
<SidebarMenuItem>
|
|
<SidebarMenuButton
|
|
size="lg"
|
|
as-child
|
|
tooltip="KanbanGit"
|
|
>
|
|
<Link :href="dashboard()" aria-label="KanbanGit"
|
|
><AppLogo
|
|
/></Link>
|
|
</SidebarMenuButton>
|
|
</SidebarMenuItem>
|
|
</SidebarMenu>
|
|
<Button
|
|
v-if="isMobile"
|
|
variant="ghost"
|
|
size="icon"
|
|
:aria-label="t('navigation.close')"
|
|
@click="setOpenMobile(false)"
|
|
>
|
|
<X aria-hidden="true" />
|
|
</Button>
|
|
</div>
|
|
<Link
|
|
v-if="project"
|
|
:href="show(project.id)"
|
|
class="bg-sidebar-accent flex min-w-0 items-center gap-3 rounded-md p-3 group-data-[collapsible=icon]:hidden"
|
|
>
|
|
<span
|
|
class="text-label bg-brand/15 text-primary shrink-0 rounded-md px-2 py-1"
|
|
>{{ project.key }}</span
|
|
>
|
|
<span class="truncate font-semibold" :title="project.name">{{
|
|
project.name
|
|
}}</span>
|
|
</Link>
|
|
</SidebarHeader>
|
|
<SidebarContent>
|
|
<nav :aria-label="t('navigation.main')">
|
|
<NavMain
|
|
:items="workspaceItems"
|
|
:label="t('navigation.workspace')"
|
|
/>
|
|
<NavMain
|
|
v-if="projectItems.length"
|
|
:items="projectItems"
|
|
:label="t('navigation.project')"
|
|
/>
|
|
<NavMain
|
|
v-if="projectSettingsItems.length"
|
|
:items="projectSettingsItems"
|
|
:label="t('navigation.projectSettings')"
|
|
/>
|
|
</nav>
|
|
</SidebarContent>
|
|
<SidebarFooter class="border-sidebar-border border-t p-0">
|
|
<NavMain :items="accountItems" :label="t('navigation.account')" />
|
|
</SidebarFooter>
|
|
</Sidebar>
|
|
</template>
|