feat(KAN-30): rebuild responsive ticket detail view
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user