Files
warren/frontend/components/AppBreadcrumbs.vue
2025-07-20 13:14:31 +02:00

129 lines
3.7 KiB
Vue

<script setup lang="ts">
import {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbPage,
BreadcrumbSeparator,
} from '@/components/ui/breadcrumb';
import type { BreadcrumbData } from '#shared/types';
const route = useRoute();
const store = useWarrenStore();
const routeCrumbs = computed<BreadcrumbData[]>(() => {
if (route.path === '/') {
return [{ name: '/', href: '/' }];
}
const rawCrumbs = route.path.split('/');
const crumbs: BreadcrumbData[] = [];
crumbs[0] = {
name: '/',
href: '/',
};
for (let i = 1; i < rawCrumbs.length; i++) {
crumbs.push({
name: rawCrumbs[i],
href: rawCrumbs.slice(0, i + 1).join('/'),
});
}
return crumbs;
});
type WarrenBreadcrumbData = {
name: string;
action: () => void;
};
const warrenCrumbs = computed<WarrenBreadcrumbData[]>(() => {
if (store.current == null) {
return [];
}
const warren = store.warrens[store.current.warrenId];
const rawCrumbs = store.current.path.split('/').filter((c) => c.length > 0);
const crumbs: WarrenBreadcrumbData[] = [
{
name: '/',
action: async () => {
await navigateTo({
path: '/',
});
store.clearCurrentWarren();
},
},
{
name: 'warrens',
action: async () => {
await navigateTo({
path: '/warrens',
});
store.clearCurrentWarren();
},
},
{
name: warren.name,
action: () => store.setCurrentWarren(warren.id, '/'),
},
];
for (let i = 0; i < rawCrumbs.length; i++) {
const path = rawCrumbs.slice(0, i + 1).join('/');
crumbs.push({
name: rawCrumbs[i],
action: () => store.setCurrentWarrenPath(path),
});
}
return crumbs;
});
</script>
<template>
<Breadcrumb>
<BreadcrumbList>
<template v-if="store.current == null">
<template v-for="(crumb, i) in routeCrumbs" :key="i">
<BreadcrumbItem>
<NuxtLink
v-if="i < routeCrumbs.length - 1"
:to="crumb.href"
as-child
>
<BreadcrumbLink>
{{ crumb.name }}
</BreadcrumbLink>
</NuxtLink>
<BreadcrumbPage v-else>{{ crumb.name }}</BreadcrumbPage>
</BreadcrumbItem>
<BreadcrumbSeparator
v-if="i < routeCrumbs.length - 1"
class="hidden md:block"
/>
</template>
</template>
<template
v-for="(crumb, i) in warrenCrumbs"
v-else-if="route.path.startsWith('/warrens')"
:key="i"
>
<BreadcrumbItem
v-if="i < warrenCrumbs.length - 1"
class="cursor-pointer"
@click="crumb.action"
>
<BreadcrumbLink>
{{ crumb.name }}
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbPage v-else>{{ crumb.name }}</BreadcrumbPage>
<BreadcrumbSeparator
v-if="i < warrenCrumbs.length - 1"
class="hidden md:block"
/>
</template>
</BreadcrumbList>
</Breadcrumb>
</template>