Files
KanbanGit/app/Http/Controllers/ProjectBoardSettingsController.php
Twyco 8b25421e7c
linter / quality (pull_request) Successful in 1m18s
tests / ci (8.4) (pull_request) Successful in 1m28s
Add application API and OpenAPI docs
2026-04-20 13:22:56 +02:00

165 lines
5.9 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Actions\Permissions\PermissionService;
use App\Actions\ProjectBoard\DeleteBoardColumn;
use App\Actions\ProjectBoard\DeleteTicketStatus;
use App\Actions\ProjectBoard\StoreBoardColumn;
use App\Actions\ProjectBoard\StoreTicketStatus;
use App\Actions\ProjectBoard\UpdateBoardColumn;
use App\Actions\ProjectBoard\UpdateTicketStatus;
use App\Actions\ProjectBoard\UpdateTicketStatusTransitions;
use App\Actions\Projects\BuildProjectBoardSettingsPayload;
use App\Enums\Permission;
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;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
class ProjectBoardSettingsController extends Controller
{
public function __construct(
private readonly BuildProjectBoardSettingsPayload $buildProjectBoardSettingsPayload,
private readonly DeleteBoardColumn $deleteBoardColumn,
private readonly DeleteTicketStatus $deleteTicketStatus,
private readonly PermissionService $permissionService,
private readonly StoreBoardColumn $storeBoardColumn,
private readonly StoreTicketStatus $storeTicketStatus,
private readonly UpdateBoardColumn $updateBoardColumn,
private readonly UpdateTicketStatus $updateTicketStatus,
private readonly UpdateTicketStatusTransitions $updateTicketStatusTransitions,
) {}
public function show(Request $request, Project $project): Response
{
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
return Inertia::render(
'projects/settings/Board',
$this->buildProjectBoardSettingsPayload->handle($project, session('status')),
);
}
public function store(
StoreBoardColumnRequest $request,
Project $project,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$boardColumn = $this->storeBoardColumn->handle($project, $request->validated());
return to_route('projects.settings.board', $project)
->with('status', "{$boardColumn->name} was added to the board workflow.");
}
public function update(
UpdateBoardColumnRequest $request,
Project $project,
BoardColumn $boardColumn,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$boardColumn = $this->updateBoardColumn->handle($project, $boardColumn, $request->validated());
return to_route('projects.settings.board', $project)
->with('status', "{$boardColumn->fresh()->name} was updated.");
}
public function destroy(
Request $request,
Project $project,
BoardColumn $boardColumn,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$deletedName = $this->deleteBoardColumn->handle($project, $boardColumn);
return to_route('projects.settings.board', $project)
->with('status', "{$deletedName} was removed from the board workflow.");
}
public function storeStatus(
StoreTicketStatusRequest $request,
Project $project,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$ticketStatus = $this->storeTicketStatus->handle($project, $request->validated());
return to_route('projects.settings.board', $project)
->with('status', "{$ticketStatus->name} was added to {$this->statusContextLabel($ticketStatus)}.");
}
public function updateStatus(
UpdateTicketStatusRequest $request,
Project $project,
TicketStatus $ticketStatus,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$ticketStatus = $this->updateTicketStatus->handle($ticketStatus, $request->validated());
return to_route('projects.settings.board', $project)
->with('status', "{$ticketStatus->fresh()->name} was updated.");
}
public function destroyStatus(
Request $request,
Project $project,
TicketStatus $ticketStatus,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$result = $this->deleteTicketStatus->handle($project, $ticketStatus);
return to_route('projects.settings.board', $project)
->with('status', "{$result['deleted_name']} was removed from {$result['context_label']}.");
}
public function updateStatusTransitions(
UpdateTicketStatusTransitionsRequest $request,
Project $project,
TicketStatus $ticketStatus,
): RedirectResponse {
abort_unless(
$this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project),
403,
);
$this->updateTicketStatusTransitions->handle($ticketStatus, $request->validated());
return to_route('projects.settings.board', $project)
->with('status', "{$ticketStatus->name} move targets were updated.");
}
private function statusContextLabel(TicketStatus $ticketStatus): string
{
return $ticketStatus->boardColumn?->name ?? 'Backlog';
}
}