user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectRead, $project), 403, ); $canManageTickets = $this->permissionService->allows($user, Permission::ProjectWrite, $project); return Inertia::render('projects/Board', [ 'boardColumns' => BoardColumnResource::collection( $project->boardColumns() ->with([ 'ticketStatuses', 'tickets' => fn ($query) => $query ->with([ 'ticketPriority', 'ticketStatus.allowedTargetStatuses.boardColumn', 'ticketStatus.boardColumn', 'ticketType', ]), ]) ->get(), )->resolve(), 'canCreateTickets' => $canManageTickets, 'canEditTickets' => $canManageTickets, 'project' => ProjectResource::make($project)->resolve(), 'status' => session('status'), ]); } public function move( MoveProjectTicketRequest $request, Project $project, Ticket $ticket, ): RedirectResponse { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectWrite, $project), 403, ); $validated = $request->validated(); $ticketStatusId = (int) Arr::get($validated, 'ticket_status_id'); $redirectRoute = Arr::get($validated, 'redirect_to') === 'backlog' ? 'projects.backlog.index' : 'projects.board.index'; $destinationStatus = $project->ticketStatuses() ->with('boardColumn') ->findOrFail($ticketStatusId); $ticket->loadMissing('ticketStatus.boardColumn'); $originStatusId = $ticket->ticket_status_id; $originLabel = $this->statusLabel($ticket->ticketStatus); $destinationLabel = $this->statusLabel($destinationStatus); if ($ticket->ticket_status_id === $ticketStatusId) { return to_route($redirectRoute, $project) ->with('status', "{$ticket->ticket_key} already belongs to {$destinationLabel}."); } $ticket->update([ 'ticket_status_id' => $destinationStatus->id, ]); $this->createTicketWorklogEntry->handle( $ticket->fresh(), $user, TicketWorklogEntryType::StatusChanged, "Moved from {$originLabel} to {$destinationLabel}.", [ 'from' => [ 'label' => $originLabel, 'ticket_status_id' => $originStatusId, ], 'to' => [ 'label' => $destinationLabel, 'ticket_status_id' => $destinationStatus->id, ], ], ); return to_route($redirectRoute, $project) ->with('status', "{$ticket->ticket_key} moved to {$destinationLabel}."); } private function statusLabel(?TicketStatus $ticketStatus): string { if ($ticketStatus === null) { return 'Unknown status'; } if ($ticketStatus->boardColumn === null) { return $ticketStatus->name; } if ($ticketStatus->boardColumn->name === $ticketStatus->name) { return $ticketStatus->name; } return "{$ticketStatus->boardColumn->name} / {$ticketStatus->name}"; } }