diff --git a/app/Livewire/Inspections/TemplateManager.php b/app/Livewire/Inspections/TemplateManager.php
index 4975159..ffa256b 100644
--- a/app/Livewire/Inspections/TemplateManager.php
+++ b/app/Livewire/Inspections/TemplateManager.php
@@ -25,6 +25,7 @@ class TemplateManager extends Component
'name' => '',
'description' => '',
'phase_id' => null,
+ 'is_global' => false,
'fields' => [],
];
@@ -67,8 +68,12 @@ class TemplateManager extends Component
public function loadTemplates()
{
- $this->templates = InspectionTemplate::where('project_id', $this->project->id)
+ // Plantillas del proyecto + globales (project_id null)
+ $this->templates = InspectionTemplate::where(function ($q) {
+ $q->where('project_id', $this->project->id)->orWhereNull('project_id');
+ })
->with('phase')
+ ->orderBy('name')
->get();
}
@@ -87,6 +92,7 @@ class TemplateManager extends Component
'name' => $template->name,
'description' => $template->description ?? '',
'phase_id' => $template->phase_id,
+ 'is_global' => is_null($template->project_id),
'fields' => $template->fields ?? [],
];
$this->editingTemplate = $id;
@@ -105,6 +111,7 @@ class TemplateManager extends Component
'name' => '',
'description' => '',
'phase_id' => null,
+ 'is_global' => false,
'fields' => [],
];
$this->editingTemplate = null;
@@ -113,14 +120,17 @@ class TemplateManager extends Component
public function addField()
{
$this->form['fields'][] = [
+ 'group' => '',
'name' => '',
'label' => '',
+ 'question' => '',
'type' => 'text',
'options' => '',
'required' => false,
'min' => null,
'max' => null,
'step' => null,
+ 'help' => '',
];
}
@@ -141,8 +151,8 @@ class TemplateManager extends Component
$data = [
'name' => $this->form['name'],
'description' => $this->form['description'],
- 'project_id' => $this->project->id,
- 'phase_id' => $this->form['phase_id'] ?: null,
+ 'project_id' => ($this->form['is_global'] ?? false) ? null : $this->project->id,
+ 'phase_id' => ($this->form['is_global'] ?? false) ? null : ($this->form['phase_id'] ?: null),
'fields' => array_values($this->form['fields']),
];
diff --git a/resources/views/livewire/inspections/template-manager.blade.php b/resources/views/livewire/inspections/template-manager.blade.php
index b0905cd..73a5b3c 100644
--- a/resources/views/livewire/inspections/template-manager.blade.php
+++ b/resources/views/livewire/inspections/template-manager.blade.php
@@ -54,7 +54,7 @@
{{ __('Associated phase (optional)') }}
- |
+
+ {{-- Plantilla global (disponible en todos los proyectos) --}}
+
+ | {{ __('Global template') }} |
+
+
+ |
+
@@ -72,6 +83,11 @@
{{ __('Form fields') }}
@foreach($form['fields'] as $index => $field)
+ {{-- Fila: grupo / sección --}}
+
+
{{ __('Group / section') }}
+
+
{{-- Fila: nombre interno --}}
{{ __('Internal name') }}
@@ -82,6 +98,11 @@
{{ __('Visible label') }}
+ {{-- Fila: pregunta / revisar (texto corto) --}}
+
+
{{ __('Question / check') }}
+
+
{{-- Fila: tipo --}}
{{ __('Field type') }}
@@ -118,6 +139,12 @@
@endif
+
+ {{-- Fila: comentarios / ayuda (texto largo) --}}
+
+
{{ __('Comments / help') }}
+
+
@endforeach
@@ -145,7 +172,12 @@
@forelse($templates as $template)
- | {{ $template->name }} |
+
+ {{ $template->name }}
+ @if(is_null($template->project_id))
+ {{ __('Global') }}
+ @endif
+ |
{{ $template->description ?? '-' }} |
{{ $template->phase ? $template->phase->name : __('Global project') }} |
{{ count($template->fields) }} |
diff --git a/tests/Feature/TemplateCreationTest.php b/tests/Feature/TemplateCreationTest.php
index 8e83890..accd6e6 100644
--- a/tests/Feature/TemplateCreationTest.php
+++ b/tests/Feature/TemplateCreationTest.php
@@ -56,4 +56,55 @@ class TemplateCreationTest extends TestCase
'name' => 'Recepción de hormigón',
]);
}
+
+ public function test_field_keeps_group_question_and_help(): void
+ {
+ [$user, $project] = $this->setup_();
+
+ Livewire::actingAs($user)
+ ->test(TemplateManager::class, ['project' => $project])
+ ->call('newTemplate')
+ ->set('form.name', 'Con grupos')
+ ->call('addField')
+ ->set('form.fields.0.group', 'Geometría')
+ ->set('form.fields.0.name', 'altura')
+ ->set('form.fields.0.label', 'Altura (m)')
+ ->set('form.fields.0.question', '¿Cumple la cota?')
+ ->set('form.fields.0.help', 'Medir con láser')
+ ->call('saveTemplate')
+ ->assertHasNoErrors();
+
+ $tpl = \App\Models\InspectionTemplate::where('name', 'Con grupos')->first();
+ $this->assertSame('Geometría', $tpl->fields[0]['group']);
+ $this->assertSame('¿Cumple la cota?', $tpl->fields[0]['question']);
+ $this->assertSame('Medir con láser', $tpl->fields[0]['help']);
+ }
+
+ public function test_global_template_has_no_project_and_shows_in_other_projects(): void
+ {
+ [$user, $project] = $this->setup_();
+
+ Livewire::actingAs($user)
+ ->test(TemplateManager::class, ['project' => $project])
+ ->call('newTemplate')
+ ->set('form.name', 'Plantilla global')
+ ->set('form.is_global', true)
+ ->call('saveTemplate')
+ ->assertHasNoErrors();
+
+ $this->assertDatabaseHas('inspection_templates', [
+ 'name' => 'Plantilla global', 'project_id' => null,
+ ]);
+
+ // Otro proyecto del mismo usuario ve la plantilla global en su listado
+ $other = \App\Models\Project::create([
+ 'reference' => 'OTH', 'name' => 'Otro', 'address' => 'x', 'lat' => 40, 'lng' => -3,
+ 'start_date' => now()->toDateString(), 'end_date_estimated' => now()->addMonth()->toDateString(),
+ 'status' => 'in_progress', 'created_by' => $user->id,
+ ]);
+
+ Livewire::actingAs($user)
+ ->test(TemplateManager::class, ['project' => $other])
+ ->assertSee('Plantilla global');
+ }
}