mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 08:12:17 +01:00
add reporting submenus to navbar
This commit is contained in:
committed by
Constantin Graf
parent
2560619c15
commit
9c82efdf07
@@ -1,35 +1,109 @@
|
||||
<script setup lang="ts">
|
||||
import type { Component } from 'vue';
|
||||
import { Link } from '@inertiajs/vue3';
|
||||
import { type Component } from 'vue';
|
||||
import NavigationSidebarLink from '@/Components/NavigationSidebarLink.vue';
|
||||
import {
|
||||
CollapsibleContent,
|
||||
CollapsibleRoot,
|
||||
CollapsibleTrigger,
|
||||
} from 'radix-vue';
|
||||
import { useSessionStorage } from '@vueuse/core';
|
||||
import { ChevronRightIcon } from '@heroicons/vue/20/solid';
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
icon: Component;
|
||||
icon?: Component;
|
||||
current?: boolean;
|
||||
href: string;
|
||||
subItems?: { title: string; route: string }[];
|
||||
}>();
|
||||
|
||||
const open = useSessionStorage('nav-collapse-state-' + props.title, true);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li>
|
||||
<Link
|
||||
:href="href"
|
||||
:class="[
|
||||
current
|
||||
? 'bg-menu-active text-white'
|
||||
: 'text-muted hover:text-white hover:bg-menu-active ',
|
||||
'group flex gap-x-2 rounded-md px-2 py-1.5 transition leading-6 font-semibold text-sm items-center',
|
||||
]">
|
||||
<component
|
||||
:is="icon"
|
||||
:class="[
|
||||
current
|
||||
? 'text-icon-active'
|
||||
: 'text-icon-default group-hover:text-icon-active',
|
||||
'transition h-5 w-5 shrink-0',
|
||||
]"
|
||||
aria-hidden="true" />
|
||||
{{ title }}
|
||||
</Link>
|
||||
<li class="relative">
|
||||
<NavigationSidebarLink
|
||||
v-if="!subItems"
|
||||
class="py-0.5"
|
||||
:title
|
||||
:icon
|
||||
:current
|
||||
:href></NavigationSidebarLink>
|
||||
<CollapsibleRoot v-model:open="open" v-else
|
||||
><CollapsibleTrigger class="w-full group py-0.5">
|
||||
<div
|
||||
class="text-muted group-hover:text-white group-hover:bg-menu-active group flex gap-x-2 rounded-md transition leading-6 py-1 px-2 font-medium text-sm items-center justify-between">
|
||||
<div class="flex items-center gap-x-2">
|
||||
<component
|
||||
v-if="icon"
|
||||
:is="icon"
|
||||
:class="[
|
||||
current
|
||||
? 'text-icon-active'
|
||||
: 'text-icon-default group-hover:text-icon-active',
|
||||
'transition h-5 w-5 shrink-0',
|
||||
]"
|
||||
aria-hidden="true" />
|
||||
<span>
|
||||
{{ title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<ChevronRightIcon
|
||||
:class="[
|
||||
'w-5 text-text-secondary',
|
||||
{ 'transform rotate-90': open },
|
||||
]"></ChevronRightIcon>
|
||||
</div>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent class="CollapsibleContent">
|
||||
<div class="px-3.5">
|
||||
<ul
|
||||
class="flex min-w-0 flex-col border-l border-border-secondary px-3 w-full my-0.5"
|
||||
v-if="subItems">
|
||||
<li
|
||||
v-for="subItem in subItems"
|
||||
:key="subItem.title"
|
||||
class="w-full relative">
|
||||
<NavigationSidebarLink
|
||||
:title="subItem.title"
|
||||
:current="route().current(subItem.route)"
|
||||
:href="
|
||||
route(subItem.route)
|
||||
"></NavigationSidebarLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</CollapsibleContent>
|
||||
</CollapsibleRoot>
|
||||
</li>
|
||||
</template>
|
||||
<style scoped>
|
||||
.CollapsibleContent {
|
||||
overflow: hidden;
|
||||
}
|
||||
.CollapsibleContent[data-state='open'] {
|
||||
animation: slideDown 300ms ease-out;
|
||||
}
|
||||
.CollapsibleContent[data-state='closed'] {
|
||||
animation: slideUp 300ms ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
height: var(--radix-collapsible-content-height);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
height: var(--radix-collapsible-content-height);
|
||||
}
|
||||
to {
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
36
resources/js/Components/NavigationSidebarLink.vue
Normal file
36
resources/js/Components/NavigationSidebarLink.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { Link } from '@inertiajs/vue3';
|
||||
import type { Component } from 'vue';
|
||||
defineProps<{
|
||||
title: string;
|
||||
icon?: Component;
|
||||
current?: boolean;
|
||||
href: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Link :href="href" class="block group">
|
||||
<div
|
||||
:class="[
|
||||
current
|
||||
? 'bg-menu-active text-white'
|
||||
: 'text-muted group-hover:text-white group-hover:bg-menu-active ',
|
||||
'group flex gap-x-2 rounded-md transition leading-6 py-1 px-2 font-medium text-sm items-center',
|
||||
]">
|
||||
<component
|
||||
v-if="icon"
|
||||
:is="icon"
|
||||
:class="[
|
||||
current
|
||||
? 'text-icon-active'
|
||||
: 'text-icon-default group-hover:text-icon-active',
|
||||
'transition h-5 w-5 shrink-0',
|
||||
]"
|
||||
aria-hidden="true" />
|
||||
{{ title }}
|
||||
</div>
|
||||
</Link>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -114,13 +114,27 @@ const page = usePage<{
|
||||
<NavigationSidebarItem
|
||||
title="Reporting"
|
||||
:icon="ChartBarIcon"
|
||||
:sub-items="[
|
||||
{
|
||||
title: 'Overview',
|
||||
route: 'reporting',
|
||||
},
|
||||
{
|
||||
title: 'Detailed',
|
||||
route: 'reporting.detailed',
|
||||
},
|
||||
{
|
||||
title: 'Shared',
|
||||
route: 'reporting.shared',
|
||||
},
|
||||
]"
|
||||
:current="
|
||||
route().current('reporting') ||
|
||||
route().current('reporting.detailed')
|
||||
route().current('reporting.detailed') ||
|
||||
route().current('reporting.shared')
|
||||
"
|
||||
:href="
|
||||
route('reporting')
|
||||
"></NavigationSidebarItem>
|
||||
:href="route('reporting')">
|
||||
</NavigationSidebarItem>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ import {
|
||||
import { type GroupingOption, useReportingStore } from '@/utils/useReporting';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import TagDropdown from '@/packages/ui/src/Tag/TagDropdown.vue';
|
||||
import { type AggregatedTimeEntriesQueryParams, api } from '@/packages/api/src';
|
||||
import type {
|
||||
AggregatedTimeEntriesQueryParams,
|
||||
CreateReportBodyProperties,
|
||||
import {
|
||||
type AggregatedTimeEntriesQueryParams,
|
||||
type CreateReportBodyProperties,
|
||||
api,
|
||||
} from '@/packages/api/src';
|
||||
import ReportingFilterBadge from '@/Components/Common/Reporting/ReportingFilterBadge.vue';
|
||||
import ProjectMultiselectDropdown from '@/Components/Common/Project/ProjectMultiselectDropdown.vue';
|
||||
|
||||
Reference in New Issue
Block a user