diff --git a/resources/js/components/tickets/detail/TicketDetailContent.vue b/resources/js/components/tickets/detail/TicketDetailContent.vue index 17681e7..b488033 100644 --- a/resources/js/components/tickets/detail/TicketDetailContent.vue +++ b/resources/js/components/tickets/detail/TicketDetailContent.vue @@ -3,7 +3,7 @@ import { useLocalization } from '@/composables/useLocalization'; import { Card, CardContent, CardHeader } from '@/components/ui/card'; import { useForm, useRemember } from '@inertiajs/vue3'; -import { computed, ref, toRef, unref } from 'vue'; +import { computed, ref, toRef, unref, useTemplateRef, nextTick } from 'vue'; import ProjectTicketController from '@/actions/App/Http/Controllers/ProjectTicketController'; import InputError from '@/components/InputError.vue'; import AcceptanceCriteriaChecklist from '@/components/tickets/AcceptanceCriteriaChecklist.vue'; @@ -20,6 +20,18 @@ import { import type { TicketDetailContentProps } from '@/types/ticket-detail'; const props = defineProps(); const { t } = useLocalization(); +const editor = useTemplateRef('editor'); +async function editParent(): Promise { + if (!props.canEditTicket || !editor.value) { + return; + } + editor.value.open = true; + await nextTick(); + editor.value + ?.querySelector('#parent_ticket_id') + ?.focus(); +} +defineExpose({ editParent }); const canEditAuthor = computed( () => props.canEditTicket && props.canManageProject, ); @@ -279,6 +291,7 @@ const submit = (): void => {
-import { useLocalization } from '@/composables/useLocalization'; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from '@/components/ui/card'; - -import { Form, Link } from '@inertiajs/vue3'; -import { computed } from 'vue'; -import ProjectTicketLinkController from '@/actions/App/Http/Controllers/ProjectTicketLinkController'; -import InputError from '@/components/InputError.vue'; +import { Link, useForm } from '@inertiajs/vue3'; +import { ArrowRight, GitFork, Link2, Plus } from 'lucide-vue-next'; +import { computed, nextTick, useTemplateRef } from 'vue'; +import { store } from '@/actions/App/Http/Controllers/ProjectTicketLinkController'; +import FormFeedback from '@/components/FormFeedback.vue'; import TicketTreeList from '@/components/TicketTreeList.vue'; +import TicketFormField from '@/components/tickets/TicketFormField.vue'; +import TicketRelationshipLink from '@/components/tickets/detail/TicketRelationshipLink.vue'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; -import { Label } from '@/components/ui/label'; +import { Card, CardContent, CardHeader } from '@/components/ui/card'; +import { useFormProtection } from '@/composables/useFormProtection'; +import { useLocalization } from '@/composables/useLocalization'; import { show as showTicket } from '@/routes/projects/tickets'; import type { TicketDetailRelationshipsProps } from '@/types/ticket-detail'; + const props = defineProps(); +defineEmits<{ editParent: [] }>(); const { t } = useLocalization(); +const linksHeading = useTemplateRef('linksHeading'); const currentParentTicket = computed( () => props.ticket.parent_ticket ?? props.parentTicketOptions.find( - (parentTicket) => parentTicket.id === props.ticket.parent_ticket_id, + (parent) => parent.id === props.ticket.parent_ticket_id, ) ?? null, ); +const canAddLink = computed( + () => + props.canEditTicket && + props.ticketLinkTypes.length > 0 && + props.ticketLinkOptions.length > 0, +); +const form = useForm({ + ticket_link_type_id: props.ticketLinkTypes[0]?.id ?? '', + linked_ticket_id: '', +}); +const protection = useFormProtection(form, { + isDirty: () => props.canEditTicket && form.isDirty, +}); +const selectedType = computed(() => + props.ticketLinkTypes.find( + (type) => String(type.id) === String(form.ticket_link_type_id), + ), +); +const selectedTicket = computed(() => + props.ticketLinkOptions.find( + (ticket) => String(ticket.id) === String(form.linked_ticket_id), + ), +); + +async function focusLinks(): Promise { + await nextTick(); + linksHeading.value?.focus(); +} +function submit(): void { + if (!canAddLink.value) { + return; + } + protection.submit( + store({ project: props.project.id, ticket: props.ticket.id }), + { + preserveScroll: true, + onSuccess: () => { + form.linked_ticket_id = ''; + form.clearErrors(); + void focusLinks(); + }, + }, + ); +}