71 lines
2.6 KiB
Vue
71 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
} from '@/components/ui/card';
|
|
|
|
import { Badge } from '@/components/ui/badge';
|
|
import type { TicketDetailHistoryProps } from '@/types/ticket-detail';
|
|
defineProps<TicketDetailHistoryProps>();
|
|
const { t, date } = useLocalization();
|
|
const formatDateTime = (value: string): string =>
|
|
date(new Date(value), { dateStyle: 'medium', timeStyle: 'short' });
|
|
</script>
|
|
|
|
<template>
|
|
<section
|
|
id="ticket-history"
|
|
aria-labelledby="ticket-history-title"
|
|
class="wrap-anywhere min-w-0 scroll-mt-6"
|
|
>
|
|
<Card class="h-fit">
|
|
<CardHeader>
|
|
<h2 id="ticket-history-title" class="text-lg font-semibold">
|
|
{{ t('ticketDetail.history') }}
|
|
</h2>
|
|
<CardDescription>{{
|
|
t('ticketDetail.historyDescription')
|
|
}}</CardDescription>
|
|
</CardHeader>
|
|
|
|
<CardContent class="space-y-4">
|
|
<div
|
|
v-if="(ticket.worklog_entries?.length ?? 0) === 0"
|
|
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
|
>
|
|
{{ t('ticketDetail.noHistory') }}
|
|
</div>
|
|
|
|
<div v-else class="flex flex-col gap-4">
|
|
<div
|
|
v-for="worklogEntry in ticket.worklog_entries"
|
|
:key="worklogEntry.id"
|
|
class="border-border rounded-xl border px-4 py-4"
|
|
>
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<Badge variant="outline">
|
|
{{ worklogEntry.entry_type }}
|
|
</Badge>
|
|
<span class="text-foreground text-sm font-medium">
|
|
{{
|
|
worklogEntry.actor?.name ??
|
|
t('ticketDetail.system')
|
|
}}
|
|
</span>
|
|
</div>
|
|
<p class="text-foreground mt-3 text-sm">
|
|
{{ worklogEntry.summary }}
|
|
</p>
|
|
<p class="text-muted-foreground mt-2 text-xs">
|
|
{{ formatDateTime(worklogEntry.created_at) }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</section>
|
|
</template>
|