user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectWrite, $project), 403, ); $source = Arr::get($request->query(), 'source') === 'board' ? 'board' : 'backlog'; $defaultTicketStatus = $source === 'board' ? $project->ticketStatuses()->whereNotNull('board_column_id')->first() : $project->ticketStatuses()->whereNull('board_column_id')->first(); $defaultTicketStatus ??= $project->ticketStatuses()->first(); return Inertia::render('projects/TicketCreate', [ 'defaultTicketStatusId' => $defaultTicketStatus?->id, 'project' => ProjectResource::make($project)->resolve(), 'source' => $source, 'status' => session('status'), 'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(), 'ticketStatusOptions' => TicketStatusResource::collection( $project->ticketStatuses() ->with('boardColumn') ->get(), )->resolve(), 'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->get())->resolve(), 'users' => UserResource::collection( User::query() ->orderBy('name') ->get(), )->resolve(), ]); } public function store(StoreProjectTicketRequest $request, Project $project): RedirectResponse { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectWrite, $project), 403, ); $ticket = $this->createProjectTicket->handle( $project, $request->validated(), $user, ); return to_route('projects.tickets.show', [$project, $ticket]) ->with('status', "{$ticket->ticket_key} was created."); } public function show(Request $request, Project $project, Ticket $ticket): Response { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectRead, $project), 403, ); $canEditTicket = $this->permissionService->allows($user, Permission::ProjectWrite, $project); $canManageProject = $this->permissionService->allows($user, Permission::ProjectAdmin, $project); $displayTicket = $ticket->load([ 'assignee', 'author', 'fieldValues.ticketFieldDefinition', 'fieldValues.userValue', 'parentTicket', 'ticketPriority', 'ticketStatus.boardColumn', 'ticketType', 'worklogEntries.actor', ]); if (! $project->show_author && ! $canManageProject) { $displayTicket->setRelation('author', null); $displayTicket->author_user_id = null; } return Inertia::render('projects/Ticket', [ 'canEditTicket' => $canEditTicket, 'canManageProject' => $canManageProject, 'childTicketTree' => TicketTreeNodeResource::collection( $ticket->childTickets() ->with('ticketType') ->get(), )->resolve(), 'linkedTickets' => TicketLinkResource::collection( TicketLink::query() ->with(['sourceTicket', 'targetTicket', 'ticketLinkType']) ->where(function ($query) use ($ticket): void { $query ->where('source_ticket_id', $ticket->id) ->orWhere('target_ticket_id', $ticket->id); }) ->orderBy('id') ->get() ->each(fn (TicketLink $ticketLink) => $ticketLink->setAttribute('current_ticket_id', $ticket->id)), )->resolve(), 'parentTicketOptions' => TicketReferenceResource::collection( Ticket::query() ->where('project_id', $project->id) ->whereKeyNot($ticket->id) ->whereHas('ticketType', fn ($query) => $query->where('is_parent', true)) ->orderByDesc('sequence_number') ->get(), )->resolve(), 'project' => ProjectResource::make($project)->resolve(), 'repositoryBranches' => TicketRepositoryBranchResource::collection( $this->resolveTicketBranchMatches->handle( $user, $project, $ticket, ), )->resolve(), 'repositoryPullRequests' => TicketRepositoryPullRequestResource::collection( $this->resolveTicketPullRequestMatches->handle( $user, $project, $ticket, ), )->resolve(), 'status' => session('status'), 'suggestedBranchName' => $this->buildSuggestedTicketBranchName->handle($ticket), 'ticket' => TicketResource::make($displayTicket)->resolve(), 'ticketFieldDefinitions' => TicketFieldDefinitionResource::collection($project->ticketFieldDefinitions()->get())->resolve(), 'ticketLinkOptions' => TicketReferenceResource::collection( Ticket::query() ->where('project_id', $project->id) ->whereKeyNot($ticket->id) ->orderByDesc('sequence_number') ->get(), )->resolve(), 'ticketLinkTypes' => TicketLinkTypeResource::collection($project->ticketLinkTypes()->get())->resolve(), 'ticketPriorities' => TicketPriorityResource::collection($project->ticketPriorities()->get())->resolve(), 'ticketTypes' => TicketTypeResource::collection($project->ticketTypes()->get())->resolve(), 'users' => UserResource::collection( User::query() ->orderBy('name') ->get(), )->resolve(), ]); } public function update( UpdateProjectTicketRequest $request, Project $project, Ticket $ticket, ): RedirectResponse { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectWrite, $project), 403, ); $validated = $request->validated(); $wasUpdated = $this->updateProjectTicket->handle( $ticket, $user, $validated, ); $statusMessage = $wasUpdated ? "{$ticket->ticket_key} was updated." : 'No ticket changes were detected.'; return to_route('projects.tickets.show', [$project, $ticket]) ->with('status', $statusMessage); } }