Files
KanbanGit/app/Http/Controllers/ProjectBoardSettingsController.php
T
Twyco ff796aa10a
linter / quality (pull_request) Successful in 1m28s
tests / ci (8.4) (pull_request) Successful in 1m47s
feat: overhaul project workspace navigation
2026-07-18 17:52:25 +02:00

157 lines
5.6 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\Enums\Permission;
use App\Enums\ProjectSettingsSection;
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;
class ProjectBoardSettingsController extends Controller
{
public function __construct(
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 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 $this->settingsRedirect($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 $this->settingsRedirect($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 $this->settingsRedirect($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 $this->settingsRedirect($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 $this->settingsRedirect($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 $this->settingsRedirect($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 $this->settingsRedirect($project)
->with('status', "{$ticketStatus->name} move targets were updated.");
}
private function statusContextLabel(TicketStatus $ticketStatus): string
{
return $ticketStatus->boardColumn?->name ?? 'Backlog';
}
private function settingsRedirect(Project $project): RedirectResponse
{
return to_route('projects.settings.index', [
'project' => $project,
'section' => ProjectSettingsSection::Board->value,
]);
}
}