92 lines
2.6 KiB
Vue
92 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
import { CircleUserRound, OctagonAlert } from 'lucide-vue-next';
|
|
import { computed } from 'vue';
|
|
import { Badge } from '@/components/ui/badge';
|
|
import { UserAvatar } from '@/components/ui/avatar';
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import { ticketStatusLabel } from '@/lib/tickets';
|
|
import type { TicketModel } from '@/types/models/ticket-model';
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
showStatus?: boolean;
|
|
ticket: TicketModel;
|
|
}>(),
|
|
{
|
|
showStatus: true,
|
|
},
|
|
);
|
|
|
|
const { t } = useLocalization();
|
|
const statusLabel = computed(() =>
|
|
ticketStatusLabel(props.ticket.ticket_status, t('tickets.noStatus')),
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<div class="gap-stack flex min-w-0 flex-wrap items-center">
|
|
<Badge
|
|
v-if="ticket.is_blocked"
|
|
variant="warning"
|
|
:aria-label="t('tickets.blocked')"
|
|
>
|
|
<OctagonAlert aria-hidden="true" />
|
|
{{ t('tickets.blocked') }}
|
|
</Badge>
|
|
|
|
<Badge
|
|
variant="secondary"
|
|
:aria-label="
|
|
t('tickets.typeLabel', { name: ticket.ticket_type.name })
|
|
"
|
|
:data-ticket-type-id="ticket.ticket_type.id"
|
|
>
|
|
{{ ticket.ticket_type.name }}
|
|
</Badge>
|
|
|
|
<Badge
|
|
variant="outline"
|
|
:aria-label="
|
|
t('tickets.priorityLabel', {
|
|
name: ticket.ticket_priority.name,
|
|
})
|
|
"
|
|
:data-ticket-priority-id="ticket.ticket_priority.id"
|
|
>
|
|
{{ ticket.ticket_priority.name }}
|
|
</Badge>
|
|
|
|
<Badge
|
|
v-if="showStatus"
|
|
variant="outline"
|
|
:aria-label="t('tickets.statusLabel', { name: statusLabel })"
|
|
:data-ticket-status-id="ticket.ticket_status?.id"
|
|
>
|
|
{{ statusLabel }}
|
|
</Badge>
|
|
|
|
<span
|
|
v-if="ticket.assignee"
|
|
class="text-caption text-muted-foreground flex min-w-0 items-center gap-1.5"
|
|
:aria-label="
|
|
t('tickets.assignedTo', { name: ticket.assignee.name })
|
|
"
|
|
>
|
|
<UserAvatar
|
|
:user="ticket.assignee"
|
|
size="sm"
|
|
:label="ticket.assignee.name"
|
|
/>
|
|
<span class="max-w-40 truncate">{{ ticket.assignee.name }}</span>
|
|
</span>
|
|
|
|
<span
|
|
v-else
|
|
class="text-caption text-muted-foreground flex items-center gap-1.5"
|
|
>
|
|
<CircleUserRound class="size-4" aria-hidden="true" />
|
|
{{ t('tickets.unassigned') }}
|
|
</span>
|
|
</div>
|
|
</template>
|