Add editable project template flow
This commit is contained in:
@@ -4,7 +4,9 @@ namespace App\Http\Controllers;
|
||||
|
||||
use App\Actions\Projects\CreateProjectTemplate;
|
||||
use App\Actions\Projects\DuplicateProjectConfiguration;
|
||||
use App\Actions\Projects\UpdateProjectTemplate;
|
||||
use App\Http\Requests\StoreProjectTemplateRequest;
|
||||
use App\Http\Requests\UpdateProjectTemplateRequest;
|
||||
use App\Http\Resources\ProjectResource;
|
||||
use App\Http\Resources\ProjectTemplateResource;
|
||||
use App\Models\Project;
|
||||
@@ -18,6 +20,7 @@ class ProjectTemplateController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly CreateProjectTemplate $createProjectTemplate,
|
||||
private readonly UpdateProjectTemplate $updateProjectTemplate,
|
||||
) {}
|
||||
|
||||
public function index(Request $request): Response
|
||||
@@ -28,12 +31,25 @@ class ProjectTemplateController extends Controller
|
||||
ProjectTemplate::query()
|
||||
->published()
|
||||
->with('sourceProject')
|
||||
->withCount('linkedProjects')
|
||||
->orderBy('name')
|
||||
->get(),
|
||||
)->resolve(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(ProjectTemplate $projectTemplate): Response
|
||||
{
|
||||
abort_if(! $projectTemplate->is_published, 404);
|
||||
|
||||
$projectTemplate->load('sourceProject')->loadCount('linkedProjects');
|
||||
|
||||
return Inertia::render('project-templates/Edit', [
|
||||
'copyAreaOptions' => DuplicateProjectConfiguration::copyAreaOptions(),
|
||||
'template' => ProjectTemplateResource::make($projectTemplate)->resolve(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(Project $project): Response
|
||||
{
|
||||
return Inertia::render('project-templates/Create', [
|
||||
@@ -50,6 +66,16 @@ class ProjectTemplateController extends Controller
|
||||
->with('status', "Template {$template->name} was created.");
|
||||
}
|
||||
|
||||
public function update(UpdateProjectTemplateRequest $request, ProjectTemplate $projectTemplate): RedirectResponse
|
||||
{
|
||||
abort_if(! $projectTemplate->is_published, 404);
|
||||
|
||||
$template = $this->updateProjectTemplate->handle($projectTemplate, $request->validated());
|
||||
|
||||
return to_route('project-templates.index')
|
||||
->with('status', "Template {$template->name} was updated.");
|
||||
}
|
||||
|
||||
public function destroy(ProjectTemplate $projectTemplate): RedirectResponse
|
||||
{
|
||||
abort_if(! $projectTemplate->is_published, 404);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Actions\Projects\DuplicateProjectConfiguration;
|
||||
use App\Models\ProjectTemplate;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateProjectTemplateRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user()?->can('create-project') ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var ProjectTemplate|null $projectTemplate */
|
||||
$projectTemplate = $this->route('projectTemplate');
|
||||
$requiresImpactConfirmation = $projectTemplate?->linkedProjects()->exists() ?? false;
|
||||
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'copy_areas' => ['required', 'array', 'min:1'],
|
||||
'copy_areas.*' => ['string', Rule::in(DuplicateProjectConfiguration::copyableAreas())],
|
||||
'confirm_linked_projects_update' => [
|
||||
Rule::requiredIf($requiresImpactConfirmation),
|
||||
'accepted',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'confirm_linked_projects_update.accepted' => 'Acknowledge the linked project warning before saving template changes.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ class ProjectTemplateResource extends JsonResource
|
||||
'is_published' => $this->is_published,
|
||||
'copy_areas' => $this->copy_areas ?? [],
|
||||
'configuration_snapshot' => $this->configuration_snapshot ?? [],
|
||||
'linked_project_count' => $this->whenCounted('linkedProjects'),
|
||||
'created_at' => $this->created_at?->toISOString(),
|
||||
'updated_at' => $this->updated_at?->toISOString(),
|
||||
];
|
||||
@@ -44,6 +45,7 @@ class ProjectTemplateResource extends JsonResource
|
||||
'is_published' => Arr::get($this->resource, 'is_published', true),
|
||||
'copy_areas' => Arr::get($this->resource, 'copy_areas', []),
|
||||
'configuration_snapshot' => Arr::get($this->resource, 'configuration_snapshot', []),
|
||||
'linked_project_count' => Arr::get($this->resource, 'linked_project_count'),
|
||||
'created_at' => Arr::get($this->resource, 'created_at'),
|
||||
'updated_at' => Arr::get($this->resource, 'updated_at'),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user