user(); return Inertia::render('projects/Index', [ 'projects' => ProjectResource::collection($this->listVisibleProjects->handle($user))->resolve(), 'status' => session('status'), ]); } public function create(Request $request): Response { abort_unless( $this->permissionService->allows($request->user(), Permission::ProjectCreate), 403, ); $sourceTemplates = ProjectTemplate::query() ->published() ->with('sourceProject') ->orderBy('name') ->get(); $selectedTemplateId = $request->integer('template'); return Inertia::render('projects/Create', [ 'copyAreaOptions' => DuplicateProjectConfiguration::copyAreaOptions(), 'sourceProjects' => ProjectResource::collection( $this->listVisibleProjects->handle($request->user()), )->resolve(), 'sourceTemplates' => ProjectTemplateResource::collection($sourceTemplates)->resolve(), 'selectedSourceTemplateId' => $sourceTemplates->contains('id', $selectedTemplateId) ? $selectedTemplateId : null, ]); } public function store(StoreProjectRequest $request): RedirectResponse { $project = $this->createProject->handle($request->validated(), $request->user()); return to_route('projects.show', $project); } public function show(Request $request, Project $project): Response { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectRead, $project), 403, ); return Inertia::render('projects/Show', [ 'canManageAccess' => $this->permissionService->allows($user, Permission::ProjectAdmin, $project), 'project' => ProjectResource::make($project)->resolve(), 'templateState' => $this->resolveProjectTemplateState->handle($project), ]); } public function backlog(Request $request, Project $project): Response { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectRead, $project), 403, ); return Inertia::render( 'projects/Backlog', $this->buildProjectBacklogPayload->handle($project, $user, session('status')), ); } public function general(Request $request, Project $project): Response { return Inertia::render('projects/settings/General', [ 'project' => ProjectResource::make($project)->resolve(), 'sourceTemplates' => ProjectTemplateResource::collection( ProjectTemplate::query() ->published() ->with('sourceProject') ->orderBy('name') ->get(), )->resolve(), 'status' => session('status'), 'templateState' => $this->resolveProjectTemplateState->handle($project), ]); } public function switchTemplate(SwitchProjectTemplateRequest $request, Project $project): RedirectResponse { $template = ProjectTemplate::query() ->published() ->findOrFail($request->integer('source_template_id')); $this->updateProjectTemplateLink->switch($project, $template); return to_route('projects.settings.general', $project) ->with('status', "{$project->name} now uses the {$template->name} template."); } public function resetTemplate(ResetProjectTemplateRequest $request, Project $project): RedirectResponse { $request->validated(); $template = $project->projectTemplate; abort_if($template === null, 422, 'This project has no linked template to reset.'); $this->updateProjectTemplateLink->reset($project->load('projectTemplate')); return to_route('projects.settings.general', $project) ->with('status', "{$project->name} was reset to the {$template->name} template baseline."); } public function access(Request $request, Project $project): Response { $user = $request->user(); abort_unless( $this->permissionService->allows($user, Permission::ProjectAdmin, $project), 403, ); return Inertia::render('projects/Access', [ 'directPermissions' => $this->permissionService->assignmentMap(User::class, $project), 'permissionOptions' => PermissionOptionResource::collection( $this->permissionService->permissionOptions(User::class, Project::class), )->resolve(), 'project' => ProjectResource::make($project)->resolve(), 'status' => session('status'), 'teamPermissions' => $this->permissionService->assignmentMap(Team::class, $project), 'teams' => TeamResource::collection( Team::query() ->with('users') ->orderBy('name') ->get(), )->resolve(), 'users' => UserResource::collection( User::query() ->orderBy('name') ->get(), )->resolve(), ]); } public function updateUserPermissions( SyncProjectPermissionsRequest $request, Project $project, User $user, ): RedirectResponse { abort_unless( $this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project), 403, ); $validated = $request->validated(); $permissions = Arr::get($validated, 'permissions', []); $this->permissionService->sync($user, $project, $permissions); return to_route('projects.access', $project) ->with('status', "{$user->name} permissions were updated."); } public function updateTeamPermissions( SyncProjectPermissionsRequest $request, Project $project, Team $team, ): RedirectResponse { abort_unless( $this->permissionService->allows($request->user(), Permission::ProjectAdmin, $project), 403, ); $validated = $request->validated(); $permissions = Arr::get($validated, 'permissions', []); $this->permissionService->sync($team, $project, $permissions); return to_route('projects.access', $project) ->with('status', "{$team->name} permissions were updated."); } public function destroy(DeleteProjectRequest $request, Project $project): RedirectResponse { $request->validated(); $projectName = $this->deleteProject->handle($project); return to_route('projects.index') ->with('status', "Project {$projectName} was deleted."); } }