80 lines
3.1 KiB
Vue
80 lines
3.1 KiB
Vue
<script setup lang="ts">
|
|
import { Link } from '@inertiajs/vue3';
|
|
import { ArrowLeft, Columns3, ListTree } from 'lucide-vue-next';
|
|
import TicketMetadata from '@/components/tickets/TicketMetadata.vue';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { Button } from '@/components/ui/button';
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import { index as backlogIndex } from '@/routes/projects/backlog';
|
|
import { index as boardIndex } from '@/routes/projects/board';
|
|
import { show } from '@/routes/projects';
|
|
import type { TicketDetailHeaderProps } from '@/types/ticket-detail';
|
|
defineProps<TicketDetailHeaderProps>();
|
|
const { t } = useLocalization();
|
|
const sections = [
|
|
'description',
|
|
'checklist',
|
|
'metadata',
|
|
'relationships',
|
|
'history',
|
|
'git',
|
|
] as const;
|
|
</script>
|
|
<template>
|
|
<header class="flex min-w-0 flex-col gap-5">
|
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
|
<Button as-child variant="ghost" class="max-w-full"
|
|
><Link :href="show(project.id)"
|
|
><ArrowLeft aria-hidden="true" />{{
|
|
t('ticketDetail.backToProject')
|
|
}}</Link
|
|
></Button
|
|
>
|
|
<div class="flex flex-wrap gap-2">
|
|
<Button as-child variant="outline"
|
|
><Link :href="backlogIndex(project.id)"
|
|
><ListTree aria-hidden="true" />{{
|
|
t('ticketDetail.openBacklog')
|
|
}}</Link
|
|
></Button
|
|
>
|
|
<Button as-child variant="outline"
|
|
><Link :href="boardIndex(project.id)"
|
|
><Columns3 aria-hidden="true" />{{
|
|
t('ticketDetail.openBoard')
|
|
}}</Link
|
|
></Button
|
|
>
|
|
</div>
|
|
</div>
|
|
<div class="flex min-w-0 flex-col gap-3">
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<span class="text-primary font-mono text-sm font-semibold">{{
|
|
ticket.ticket_key
|
|
}}</span
|
|
><Badge v-if="!canEditTicket" variant="outline">{{
|
|
t('ticketDetail.readOnly')
|
|
}}</Badge>
|
|
</div>
|
|
<h1
|
|
class="wrap-anywhere text-2xl font-semibold leading-tight tracking-tight sm:text-3xl"
|
|
>
|
|
{{ ticket.title }}
|
|
</h1>
|
|
<TicketMetadata :ticket="ticket" />
|
|
</div>
|
|
<nav
|
|
:aria-label="t('ticketDetail.sections')"
|
|
class="flex flex-wrap gap-1 border-b pb-3"
|
|
>
|
|
<a
|
|
v-for="section in sections"
|
|
:key="section"
|
|
:href="`#ticket-${section}`"
|
|
class="min-h-control text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring inline-flex items-center rounded-lg px-3 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2"
|
|
>{{ t(`ticketDetail.${section}`) }}</a
|
|
>
|
|
</nav>
|
|
</header>
|
|
</template>
|