made more ticket components
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
<script setup lang="ts">
|
||||
import { Form, Link } from '@inertiajs/vue3';
|
||||
import ProjectTicketLinkController from '@/actions/App/Http/Controllers/ProjectTicketLinkController';
|
||||
import InputError from '@/components/InputError.vue';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/components/ui/card';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { frostedAsideCardClass, nativeSelectClass } from '@/lib/ticket-styles';
|
||||
import { show as showTicket } from '@/routes/projects/tickets';
|
||||
import type { TicketLinkModel } from '@/types/models/ticket-link-model';
|
||||
import type { TicketLinkTypeModel } from '@/types/models/ticket-link-type-model';
|
||||
import type { TicketReferenceModel } from '@/types/models/ticket-reference-model';
|
||||
|
||||
defineProps<{
|
||||
canEditTicket: boolean;
|
||||
linkedTickets: TicketLinkModel[];
|
||||
projectId: number;
|
||||
ticketId: number;
|
||||
ticketLinkOptions: TicketReferenceModel[];
|
||||
ticketLinkTypes: TicketLinkTypeModel[];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Card :class="frostedAsideCardClass">
|
||||
<CardHeader>
|
||||
<CardTitle>Linked tickets</CardTitle>
|
||||
<CardDescription>
|
||||
Track cross-ticket relationships with project-defined link
|
||||
labels.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent class="space-y-4">
|
||||
<Form
|
||||
v-if="
|
||||
canEditTicket &&
|
||||
ticketLinkTypes.length > 0 &&
|
||||
ticketLinkOptions.length > 0
|
||||
"
|
||||
:action="
|
||||
ProjectTicketLinkController.store.url({
|
||||
project: projectId,
|
||||
ticket: ticketId,
|
||||
})
|
||||
"
|
||||
class="border-border grid gap-4 rounded-xl border border-dashed p-4"
|
||||
method="post"
|
||||
v-slot="{ errors, processing }"
|
||||
>
|
||||
<div class="grid gap-2">
|
||||
<Label for="ticket_link_type_id">Link type</Label>
|
||||
<select
|
||||
id="ticket_link_type_id"
|
||||
name="ticket_link_type_id"
|
||||
:class="nativeSelectClass"
|
||||
>
|
||||
<option
|
||||
v-for="ticketLinkType in ticketLinkTypes"
|
||||
:key="ticketLinkType.id"
|
||||
:value="ticketLinkType.id"
|
||||
>
|
||||
{{ ticketLinkType.label }}
|
||||
</option>
|
||||
</select>
|
||||
<InputError :message="errors.ticket_link_type_id" />
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<Label for="linked_ticket_id">Linked ticket</Label>
|
||||
<select
|
||||
id="linked_ticket_id"
|
||||
name="linked_ticket_id"
|
||||
:class="nativeSelectClass"
|
||||
>
|
||||
<option
|
||||
v-for="ticketLinkOption in ticketLinkOptions"
|
||||
:key="ticketLinkOption.id"
|
||||
:value="ticketLinkOption.id"
|
||||
>
|
||||
{{
|
||||
`${ticketLinkOption.ticket_key} - ${ticketLinkOption.title}`
|
||||
}}
|
||||
</option>
|
||||
</select>
|
||||
<InputError :message="errors.linked_ticket_id" />
|
||||
</div>
|
||||
|
||||
<Button type="submit" :disabled="processing">Save link</Button>
|
||||
</Form>
|
||||
|
||||
<div
|
||||
v-if="linkedTickets.length === 0"
|
||||
class="border-border text-muted-foreground rounded-xl border border-dashed px-4 py-6 text-sm"
|
||||
>
|
||||
No ticket links are configured for this ticket yet.
|
||||
</div>
|
||||
|
||||
<div v-else class="space-y-3">
|
||||
<div
|
||||
v-for="linkedTicket in linkedTickets"
|
||||
:key="linkedTicket.id"
|
||||
class="border-border rounded-xl border px-4 py-4"
|
||||
>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<Badge variant="secondary">
|
||||
{{ linkedTicket.ticket_link_type.label }}
|
||||
</Badge>
|
||||
<Link
|
||||
:href="
|
||||
showTicket({
|
||||
project: projectId,
|
||||
ticket: linkedTicket.linked_ticket.id,
|
||||
})
|
||||
"
|
||||
class="text-foreground hover:text-primary font-medium transition"
|
||||
>
|
||||
{{ linkedTicket.linked_ticket.ticket_key }}
|
||||
</Link>
|
||||
</div>
|
||||
<p class="text-muted-foreground mt-2 text-sm">
|
||||
{{ linkedTicket.linked_ticket.title }}
|
||||
</p>
|
||||
|
||||
<Form
|
||||
v-if="canEditTicket"
|
||||
:action="
|
||||
ProjectTicketLinkController.destroy.url({
|
||||
project: projectId,
|
||||
ticket: ticketId,
|
||||
ticketLink: linkedTicket.id,
|
||||
})
|
||||
"
|
||||
class="mt-3 flex justify-end"
|
||||
method="delete"
|
||||
v-slot="{ processing: deleting }"
|
||||
>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
:disabled="deleting"
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</template>
|
||||
Reference in New Issue
Block a user