68 lines
2.2 KiB
Vue
68 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import { Badge } from '@/components/ui/badge';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from '@/components/ui/card';
|
|
import { frostedAsideCardClass } from '@/lib/ticket-styles';
|
|
import type { TicketWorklogEntryModel } from '@/types/models/ticket-worklog-entry-model';
|
|
|
|
defineProps<{
|
|
worklogEntries: TicketWorklogEntryModel[];
|
|
}>();
|
|
|
|
const formatDateTime = (value: string): string => {
|
|
return new Intl.DateTimeFormat(undefined, {
|
|
dateStyle: 'medium',
|
|
timeStyle: 'short',
|
|
}).format(new Date(value));
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<Card :class="frostedAsideCardClass">
|
|
<CardHeader>
|
|
<CardTitle>Worklog</CardTitle>
|
|
<CardDescription>
|
|
Every tracked ticket change is recorded with actor and
|
|
timestamp.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
|
|
<CardContent class="space-y-4">
|
|
<div
|
|
v-if="worklogEntries.length === 0"
|
|
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
|
>
|
|
No worklog entries exist for this ticket yet.
|
|
</div>
|
|
|
|
<div v-else class="flex flex-col gap-4">
|
|
<div
|
|
v-for="worklogEntry in worklogEntries"
|
|
: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 ?? '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>
|
|
</template>
|