From 534d9f8eabf130b42e899d88bc03f82dd256784b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Bra=C3=B1a?= Date: Tue, 4 Aug 2026 13:58:56 +0200 Subject: [PATCH] Fix Livewire BindingResolutionException: replace @this calls in pushed scripts with #[On] + Livewire.emit - Add #[On] attributes to 5 Livewire component methods: - LayerManager::saveManualGeojson - ProjectForm::setLocation - ProjectMap::selectFeature (already had #[On]) - TaskForm::closeModal - TaskKanban::updateTaskStatus - Replace @this.method() in @push('scripts') with Livewire.emit() calls - Fix DataTable event payloads from objects {id: X} to scalars X for: - FeatureTable::map-select-feature - InspectionTable::map-view-inspection, edit-inspection, delete-inspection --- app/Livewire/Layers/LayerManager.php | 2 + app/Livewire/Projects/FeatureTable.php | 18 +- app/Livewire/Projects/InspectionTable.php | 20 +- app/Livewire/Projects/ProjectForm.php | 3 + app/Livewire/Tasks/TaskForm.php | 2 + app/Livewire/Tasks/TaskKanban.php | 1 + .../livewire/layers/layer-manager.blade.php | 2 +- .../projects/feature-manager.blade.php | 188 ++++++++++++------ .../livewire/projects/project-form.blade.php | 4 +- .../livewire/projects/project-map.blade.php | 2 +- .../views/livewire/tasks/task-form.blade.php | 2 +- .../livewire/tasks/task-kanban.blade.php | 2 +- 12 files changed, 164 insertions(+), 82 deletions(-) diff --git a/app/Livewire/Layers/LayerManager.php b/app/Livewire/Layers/LayerManager.php index 1ff59c2..29920f0 100644 --- a/app/Livewire/Layers/LayerManager.php +++ b/app/Livewire/Layers/LayerManager.php @@ -5,6 +5,7 @@ namespace App\Livewire\Layers; use Livewire\Component; use Livewire\WithFileUploads; use Livewire\Attributes\Layout; +use Livewire\Attributes\On; use App\Models\Project; use App\Models\Phase; use App\Models\Layer; @@ -251,6 +252,7 @@ class LayerManager extends Component // ── Save drawn GeoJSON ──────────────────────────────────────────────────── + #[On('save-manual-geojson')] public function saveManualGeojson($geojsonString) { if (!$this->selectedLayer) { diff --git a/app/Livewire/Projects/FeatureTable.php b/app/Livewire/Projects/FeatureTable.php index 0577598..dee1d76 100644 --- a/app/Livewire/Projects/FeatureTable.php +++ b/app/Livewire/Projects/FeatureTable.php @@ -69,15 +69,15 @@ class FeatureTable extends DataTableComponent ->html(), Column::make('Acciones') - ->label(fn ($row) => - '
- -
') - ->html(), + ->label(fn ($row) => + '
' + . '' + . '
') + ->html(), ]; } diff --git a/app/Livewire/Projects/InspectionTable.php b/app/Livewire/Projects/InspectionTable.php index d872045..84cf183 100644 --- a/app/Livewire/Projects/InspectionTable.php +++ b/app/Livewire/Projects/InspectionTable.php @@ -85,21 +85,21 @@ class InspectionTable extends DataTableComponent Column::make('Acciones') ->label(fn ($row) => '
' - . '' . '@can("edit inspections")' - . '' . '@endcan' . '@can("delete inspections")' - . '' . '@endcan' . '
') @@ -111,15 +111,15 @@ class InspectionTable extends DataTableComponent { $images = $row->media->where('category', 'image')->values(); $count = $images->count(); - + if ($count === 0) { return ''; } - $thumbnails = $images->take(3)->map(fn ($m) => - ' - ' . e($m->name) . ' - ' + $thumbnails = $images->take(3)->map(fn ($m) => + '' + . '' . e($m->name) . '' + . '' )->implode(''); $more = $count > 3 ? '+' . ($count - 3) . '' : ''; @@ -154,4 +154,4 @@ class InspectionTable extends DataTableComponent ->filter(fn (Builder $query, string $value) => $query->where('inspections.user_id', $value)), ]; } -} +} \ No newline at end of file diff --git a/app/Livewire/Projects/ProjectForm.php b/app/Livewire/Projects/ProjectForm.php index c1fe282..5214f9a 100644 --- a/app/Livewire/Projects/ProjectForm.php +++ b/app/Livewire/Projects/ProjectForm.php @@ -4,6 +4,7 @@ namespace App\Livewire\Projects; use Livewire\Component; use Livewire\Attributes\Layout; +use Livewire\Attributes\On; use App\Models\Project; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Gate; @@ -49,6 +50,8 @@ class ProjectForm extends Component } // Called from JS after map click / marker drag + reverse geocode + + #[On('set-location')] public function setLocation(string $lat, string $lng, string $address = '', string $country = ''): void { $this->lat = $lat; diff --git a/app/Livewire/Tasks/TaskForm.php b/app/Livewire/Tasks/TaskForm.php index 45c43de..aee3ddd 100644 --- a/app/Livewire/Tasks/TaskForm.php +++ b/app/Livewire/Tasks/TaskForm.php @@ -8,6 +8,7 @@ use App\Models\User; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Str; use Livewire\Attributes\Layout; +use Livewire\Attributes\On; use Livewire\Attributes\Validate; use Livewire\Component; use Livewire\WithFileUploads; @@ -171,6 +172,7 @@ class TaskForm extends Component $this->closeModal(); } + #[On('close-modal')] public function closeModal(): void { $this->showModal = false; diff --git a/app/Livewire/Tasks/TaskKanban.php b/app/Livewire/Tasks/TaskKanban.php index 3642ec6..80976f9 100644 --- a/app/Livewire/Tasks/TaskKanban.php +++ b/app/Livewire/Tasks/TaskKanban.php @@ -63,6 +63,7 @@ class TaskKanban extends Component // Trigger re-render } + #[On('update-task-status')] public function updateTaskStatus(Task $task, string $status): void { abort_unless(Auth::user()->can('update', $task), 403); diff --git a/resources/views/livewire/layers/layer-manager.blade.php b/resources/views/livewire/layers/layer-manager.blade.php index 8462c3a..4f6ae6d 100644 --- a/resources/views/livewire/layers/layer-manager.blade.php +++ b/resources/views/livewire/layers/layer-manager.blade.php @@ -199,7 +199,7 @@ features: features, style: { color: allLayersData[currentEditableLayerId]?.color || '#3b82f6' } }; - @this.saveManualGeojson(JSON.stringify(finalGeojson)); + Livewire.emit('save-manual-geojson', JSON.stringify(finalGeojson)); } // Eventos Livewire diff --git a/resources/views/livewire/projects/feature-manager.blade.php b/resources/views/livewire/projects/feature-manager.blade.php index 122d55e..2589dd0 100644 --- a/resources/views/livewire/projects/feature-manager.blade.php +++ b/resources/views/livewire/projects/feature-manager.blade.php @@ -1,61 +1,135 @@ -
- - Volver - -
-
-

Elementos del proyecto

-

{{ $project->name }} · editar nombre, tipo, activar/desactivar o eliminar

-
- - Tipos de elemento - -
- - - - {{-- Modal editar elemento --}} - @if($showForm) -
-
-
-
-

Editar elemento

- -
-
-
- - - @error('name'){{ $message }}@enderror -
-
- - - @if($featureTypes->isEmpty()) - No hay tipos. - Crear tipos - - @endif -
-
- -
-
- - -
-
+ +
+ {{-- Izquierda: avatar + datos --}} +
+ {{-- Avatar --}} +
+

{{ $project->name }}

+ @if($project->description) +

{{ Str::limit($project->description, 80) }}

+ @endif
- @endif + + {{-- Derecha: estado + botones --}} +
+
+ + Volver + + {{-- Estado --}} + @php + $statusCfg = match($project->status) { + 'in_progress' => ['badge-primary', 'En progreso'], + 'completed' => ['badge-success', 'Completado'], + 'paused' => ['badge-warning', 'Pausado'], + 'planning' => ['badge-ghost', 'Planificación'], + default => ['badge-ghost', ucfirst(str_replace('_',' ',$project->status))], + }; + @endphp + {{ $statusCfg[1] }} +
+ {{-- Botones --}} +
+ + + Mapa + + @can('edit layers') + + + Elementos + + @endcan + @can('edit projects') + + + Plantillas + + @endcan + + + Gantt + + + + Issues + + @can('view tasks') + + + Tareas + + @endcan +
+
+
+
+ +
+
+ + Volver + + +
+
+

Elementos del proyecto

+

{{ $project->name }} · editar nombre, tipo, activar/desactivar o eliminar

+
+ + Tipos de elemento + +
+ +
+ +
+
+ +{{-- Modal editar elemento --}} +@if($showForm) +
+
+
+
+

Editar elemento

+ +
+
+
+ + + @error('name'){{ $message }}@enderror +
+
+ + + @if($featureTypes->isEmpty()) + No hay tipos. + Crear tipos + + @endif +
+
+ +
+
+ + +
+
+
+
+@endif + diff --git a/resources/views/livewire/projects/project-form.blade.php b/resources/views/livewire/projects/project-form.blade.php index 7bba82b..f770711 100644 --- a/resources/views/livewire/projects/project-form.blade.php +++ b/resources/views/livewire/projects/project-form.blade.php @@ -70,7 +70,7 @@ country = (d.address && d.address.country_code) ? d.address.country_code : ''; } } catch (e) { /* geocoding optional */ } - @this.setLocation(String(lat), String(lng), address, country); + Livewire.emit('set-location', String(lat), String(lng), address, country); setStatus(''); } @@ -86,7 +86,7 @@ placeMarker(lat, lng); const address = arr[0].display_name || ''; const country = (arr[0].address && arr[0].address.country_code) ? arr[0].address.country_code : ''; - @this.setLocation(String(lat), String(lng), address, country); + Livewire.emit('set-location', String(lat), String(lng), address, country); setStatus(''); } else { setStatus('{{ __('No results') }}'); diff --git a/resources/views/livewire/projects/project-map.blade.php b/resources/views/livewire/projects/project-map.blade.php index 2777955..5bd25cc 100644 --- a/resources/views/livewire/projects/project-map.blade.php +++ b/resources/views/livewire/projects/project-map.blade.php @@ -725,7 +725,7 @@ } function selectFeature(featureId) { - @this.selectFeature(featureId); + Livewire.emit('map-select-feature', featureId); } function getUserLocation() { diff --git a/resources/views/livewire/tasks/task-form.blade.php b/resources/views/livewire/tasks/task-form.blade.php index 5fa93bb..3d6adcf 100644 --- a/resources/views/livewire/tasks/task-form.blade.php +++ b/resources/views/livewire/tasks/task-form.blade.php @@ -170,7 +170,7 @@ // Close modal on Escape key document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { - @this.call('closeModal'); + Livewire.emit('close-modal'); } }); diff --git a/resources/views/livewire/tasks/task-kanban.blade.php b/resources/views/livewire/tasks/task-kanban.blade.php index 4276745..37bed12 100644 --- a/resources/views/livewire/tasks/task-kanban.blade.php +++ b/resources/views/livewire/tasks/task-kanban.blade.php @@ -234,7 +234,7 @@ if (taskId && this.draggedFromStatus !== targetStatus) { // Call Livewire to update status - @this.call('updateTaskStatus', taskId, targetStatus); + Livewire.emit('update-task-status', taskId, targetStatus); } }, };