added status restriction

This commit is contained in:
2026-04-14 19:07:15 +02:00
parent 9927a91327
commit fb10ecd535
12 changed files with 570 additions and 69 deletions
@@ -8,6 +8,7 @@ use App\Http\Requests\StoreBoardColumnRequest;
use App\Http\Requests\StoreTicketStatusRequest;
use App\Http\Requests\UpdateBoardColumnRequest;
use App\Http\Requests\UpdateTicketStatusRequest;
use App\Http\Requests\UpdateTicketStatusTransitionsRequest;
use App\Models\BoardColumn;
use App\Models\Project;
use App\Models\TicketStatus;
@@ -42,6 +43,9 @@ class ProjectBoardSettingsController extends Controller
->get(),
'project' => $project,
'status' => session('status'),
'ticketStatuses' => $project->ticketStatuses()
->with(['allowedTargetStatuses.boardColumn', 'boardColumn'])
->get(),
]);
}
@@ -217,6 +221,28 @@ class ProjectBoardSettingsController extends Controller
->with('status', "{$deletedName} was removed from {$contextLabel}.");
}
public function updateStatusTransitions(
UpdateTicketStatusTransitionsRequest $request,
Project $project,
TicketStatus $ticketStatus,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$validated = $request->validated();
$allowedTicketStatusIds = collect(Arr::get($validated, 'allowed_ticket_status_ids', []))
->map(fn (int|string $ticketStatusId): int => (int) $ticketStatusId)
->unique()
->values()
->all();
$ticketStatus->allowedTargetStatuses()->sync($allowedTicketStatusIds);
return to_route('projects.settings.board', $project)
->with('status', "{$ticketStatus->name} move targets were updated.");
}
private function normalizeColumnPositions(Project $project): void
{
$this->persistOrderedColumns(
@@ -0,0 +1,68 @@
<?php
namespace App\Http\Requests;
use App\Models\Project;
use App\Models\TicketStatus;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Arr;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Validator;
class UpdateTicketStatusTransitionsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return $this->user() !== null;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
/** @var Project $project */
$project = $this->route('project');
return [
'allowed_ticket_status_ids' => ['nullable', 'array'],
'allowed_ticket_status_ids.*' => [
'integer',
Rule::exists('ticket_statuses', 'id')->where('project_id', $project->id),
],
];
}
/**
* @return array<int, callable(Validator): void>
*/
public function after(): array
{
return [
function (Validator $validator): void {
if ($validator->errors()->isNotEmpty()) {
return;
}
/** @var TicketStatus $ticketStatus */
$ticketStatus = $this->route('ticketStatus');
$validated = $validator->validated();
$allowedTicketStatusIds = collect(Arr::get($validated, 'allowed_ticket_status_ids', []))
->map(fn (int|string $ticketStatusId): int => (int) $ticketStatusId);
if ($allowedTicketStatusIds->contains($ticketStatus->id)) {
$validator->errors()->add(
'allowed_ticket_status_ids',
'A status cannot allow moves to itself.',
);
}
},
];
}
}