- FeatureTable: dispatch { featureId } object instead of raw ID
- ProjectMap: selectFeature listener accepts both formats (direct ID or { featureId })
- project-map.blade.php: move selectFeature inside livewire:init handler so Livewire.emit is available
- Added logging for debugging
Fixes: 'Livewire.emit is not a function' on map click and 'Only arrays and Traversables can be unpacked' on table button
- Move Route::model to register() in AppServiceProvider so it persists in route cache
- Re-register in boot() for runtime
- Fix navigation spacing for language/notification/user menu
All 101 tests pass
El importador de plantillas solo parseaba name/label/type/required/options/
min/max/step, dejando fuera group (sección), question (pregunta corta) y help
(ayuda) que el builder manual sí soporta.
- Nuevo orden de columnas: group,name,label,question,type,required,options,min,max,step,help
- parseRows() rellena las 11 claves (coincide con addField()).
- readFileRows() ya no descarta filas por la 1ª columna (ahora es `group`, que
puede ir vacía); filtra por "fila con algún contenido" y parseRows descarta
las que no tengan `name`.
- CSV de ejemplo actualizado (con BOM UTF-8) y con filas que muestran group/
question/help/select.
- Modal de importación: texto de columnas y tabla de preview muestran Grupo y
Pregunta.
Tests: nuevo test csv_import_parses_group_question_and_help. Suite 95 passing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
El sw.js experimental (mayo) tenía tres problemas graves:
1. Estrategia cache-first para TODO: una vez cacheada una página o asset, el
navegador servía la versión vieja indefinidamente, incluso tras deploys
("los cambios no se ven"). También cacheaba HTML con tokens CSRF caducados.
2. cache.put() sobre peticiones POST (no soportado, TypeError) → interceptaba
y podía romper peticiones Livewire de forma intermitente.
3. Su precache incluía /css/app.css y /js/app.js, inexistentes con Vite →
"Failed to execute 'addAll' on 'Cache': Request failed" en cada instalación.
Se sustituye por un SW de auto-limpieza (kill switch): al actualizarse en el
navegador borra todos los caches, se desregistra y recarga las pestañas.
Los layouts siguen registrándolo para que los clientes con la PWA vieja se
limpien solos; más adelante podrá retirarse el registro por completo.
Suite 94 passing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1) global-template-manager.blade.php: los botones "Nuevo" e "Importar CSV/Excel"
estaban dentro de <x-slot name="header">, que Blade renderiza FUERA del
componente Livewire (lo pinta el layout), por lo que sus wire:click no se
ataban. Movidos al cuerpo del componente; el slot solo lleva el título.
2) config/livewire.php: creado para sobrescribir temporary_file_upload.rules.
Por defecto Livewire aplica "file|mimes:png,jpeg,...|max:12288" al fichero
temporal, lo que hace que .kml/.kmz/.shp/.dwg/.zip rebote con
"The uploadFile failed to upload". Ahora el paso temporal solo exige file y
max 50 MB; los componentes ya validan mime/tamaño reales antes de guardar.
Nota: en el servidor hay que `php artisan config:clear && php artisan config:cache`
para que el nuevo config/livewire.php se aplique.
Suite 91 passing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Nueva InspectionTemplatesTable (DataTableComponent): columnas Plantilla,
Descripción, Campos, Proyectos (uso) y Acciones; filtros en cabecera por nombre,
descripción y uso (en uso / sin uso). Gateada por manage templates.
- GlobalTemplateManager: el listado HTML se sustituye por la tabla embebida.
Acciones Editar/Borrar viajan por eventos (template-edit/template-delete);
el manager emite templates-changed al guardar/borrar/importar para que la tabla
se refresque (#[On('templates-changed')]).
Tests: GlobalTemplatesTest amplía con tabla (render + permiso, evento edit). Suite 91 passing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Migración: tabla pivot inspection_template_project; drop de phase_id (asociación
a fase descartada); project_id se mantiene en inspection_templates por compat.
Migra automáticamente las plantillas existentes (project_id → pivot).
- Modelos: Project::inspectionTemplates() ↔ InspectionTemplate::projects() (BTM);
retirada la relación phase() de InspectionTemplate.
- GlobalTemplateManager (nuevo, ruta /inspection-templates, permiso manage templates):
catálogo único global, CRUD + import CSV; sin asociación a fase ni a proyecto.
- ProjectTemplatesPicker (nuevo, ruta projects.templates, permiso edit projects):
lista global con checkbox para asignar/desasignar plantillas al proyecto.
- ProjectMap: el selector de plantillas del mapa lee SOLO las asignadas al proyecto
vía pivot. API móvil (bundle + /templates) adaptado al pivot.
- Eliminado el viejo TemplateManager por-proyecto, su vista wrapper y la tabla
ImportTemplatesTable (ya no aplica: todas son globales).
- Acceso "Plantillas" añadido al menú principal (gate manage templates).
Tests: GlobalTemplatesTest (4). Suite 89 passing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sustituye el modal (proyecto + checkboxes) por una tabla Rappasoft:
- ImportTemplatesTable lista todas las plantillas de proyectos accesibles (excluye el
destino), con filtros en cabecera (nombre, proyecto) y checkbox de selección (bulk).
- Acción masiva "Importar seleccionadas" copia al proyecto destino (dedupe por nombre)
y avisa a TemplateManager por evento (templates-imported) para refrescar/cerrar.
- TemplateManager: eliminada la lógica vieja (importProjectId/importableTemplates/
selectedImportTemplateIds/importFromProject); el modal embebe la tabla.
Tests: TemplateImportTest adaptado (selección+import, excluye destino). Suite 92 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parte 2 del bloque de plantillas/inspecciones:
- Formulario de inspección (mapa): campos agrupados por sección, muestra la
"pregunta" del campo (con la etiqueta como subtexto) y la ayuda; al final,
apartado de Comentarios (notes) y subida de Fotos (media en la inspección).
- ProjectMap: WithFileUploads + inspectionPhotos; saveInspection adjunta las fotos
como media; Inspection gana relación media().
- Visor de inspección: datos agrupados por sección con pregunta/valor, comentarios
y galería de fotos.
Tests: InspectionFormTest (registra inspección con comentarios + foto). Suite 91 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Builder de plantillas (parte 1 del bloque):
- Cada campo admite "Grupo / sección" (título), "Pregunta / revisar" (texto corto,
tras la etiqueta) y "Comentarios / ayuda" (texto largo, al final).
- Plantillas híbridas: toggle "Global" → project_id null; el listado de un proyecto
muestra sus plantillas + las globales (badge "Global").
Tests: TemplateCreationTest (grupo/pregunta/ayuda persisten; global sin proyecto y
visible en otros proyectos). Suite 90 passing.
Pendiente (parte 2): adaptar el formulario de inspección (grupos, comentarios, fotos)
y el visor de inspección.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Migración: tabla feature_types + columnas feature_type_id (FK) e is_active en features.
Modelo FeatureType; Feature gana featureType() + casts is_active.
- Catálogo de tipos (FeatureTypeManager, ruta /feature-types): CRUD con modal
(nombre, descripción, color), contador de usos; gateado por edit layers.
- Editor de elementos del proyecto (FeatureManager, ruta projects.features):
tabla Rappasoft ProjectFeaturesTable (filtros nombre/capa/tipo en cabecera),
toggle activo/inactivo y borrado individual; modal para editar nombre/tipo/activo.
- Acceso: botón "Elementos" en el dashboard del proyecto (edit layers) y enlace a
"Tipos de elemento" desde el editor.
Tests: FeatureManagementTest (6). Suite 87 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El TemplateManager ya implementaba ambos flujos pero la vista no los exponía.
Añadidos a la cabecera los botones "Importar de proyecto" e "Importar CSV/Excel" y
sus modales:
- CSV/Excel: nombre + fichero, vista previa de campos detectados, crear; con enlace
para descargar CSV de ejemplo.
- Otro proyecto: selección de proyecto accesible + checklist de plantillas a importar.
Tests: TemplateImportTest (importar de proyecto y desde CSV). Suite 81 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
resources/views/projects/templates.blade.php usaba `<livewire/template-manager>`
(sintaxis inválida; tras la reorganización el alias es `inspections.template-manager`)
y un botón suelto con `$emit` (Livewire 2, fuera de componente) que no hacía nada.
Ahora embebe correctamente <livewire:inspections.template-manager> (que ya trae su
botón "Nuevo" + formulario funcional) y se elimina el botón roto.
Tests: TemplateCreationTest (la página embebe el componente; crear plantilla funciona).
Suite 79 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
No había forma de llegar a projects.templates. Añadidos dos accesos, gateados con
@can('edit projects') (mismo permiso que protege la ruta):
- Dashboard del proyecto: botón "Plantillas" junto a "Mapa".
- Mapa: enlace "Gestionar plantillas" junto al selector de plantilla.
Test: TemplatesAccessTest (403 sin permiso, 200 con edit projects). Suite 77 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- FeatureTable e InspectionTable (DataTableComponent) sustituyen las tablas HTML
de las pestañas "Elementos" e "Inspecciones" del mapa: búsqueda, orden, filtro
(progreso) y acciones.
- Selección de elemento e "ver inspección" se comunican al ProjectMap por eventos
(map-select-feature / map-view-inspection, vía #[On]); seleccionar abre el panel
de edición y centra el mapa igual que antes.
- Las relaciones requieren sus FKs en additionalSelects (layer_id / feature_id,
template_id, user_id) porque Rappasoft no selecciona '*'.
Tests: MapTablesTest (3). Suite 74 passing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cambios de trabajo confirmados como funcionales:
- project-dashboard.blade.php: cabecera reorganizada (estado + accesos a mapa/gantt/incidencias).
- docs/Manual.docx: documento del manual generado.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Sustituye el panel saturado de estadísticas por una vista "Home" centrada en lo
del usuario: mis proyectos (compacto), mis tareas pendientes, incidencias asignadas
y notificaciones recientes. Sin inundar de detalle (mejor con muchos proyectos).
- Etiqueta "Dashboard" -> "Home" en el menú y la cabecera.
- Elimina el orderByRaw FIELD() (solo MySQL) del antiguo dashboard.
- ExampleTest: ahora valida la conducta real (la raíz redirige a login).
Suite: 71 passing (0 fallos; resueltas las 2 pre-existentes de SQLite).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- app/Livewire: 34 componentes agrupados en Issues/, Projects/, Phases/,
Companies/, Users/, Admin/, Inspections/, Layers/, Media/, Common/
(Client/, Reports/, Forms/, Actions/ ya estaban). Namespaces actualizados.
- resources/views/livewire: vistas sueltas movidas a subcarpetas espejo
(companies/, users/, phases/, roles/, inspections/, media/, common/);
render() actualizado.
- Referencias actualizadas sin romper nada: rutas (FQN, nombres de ruta intactos),
tags <livewire:...>/@livewire() a alias con punto, y use de los tests.
- No tocado: Volt de Breeze (auth/profile/navigation), y el portal cliente
(user-nav/client-projects) que ya tenía referencias inconsistentes.
Verificado: 69 rutas OK, vistas compilan, suite 69 passing (solo 2 pre-existentes
sqlite). autoload regenerado con --ignore-platform-reqs (PHP 8.2).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Permiso 'assign companies' propio (antes empresas reutilizaba 'assign users');
concedido a los roles que ya tenían 'assign users'.
- ProjectUsersTable y ProjectCompaniesTable (Rappasoft): búsqueda, filtro por rol,
cambio de rol en línea y quitar; gateadas por assign users / assign companies.
- ProjectUsers/ProjectCompanies quedan como contenedor (form de asignación) que
embebe la tabla y refresca el desplegable vía eventos.
- Unificadas confirmaciones (wire:confirm) y notificaciones (dispatch notify).
Tests: ProjectAssignmentsTest (4). Suite 69 passing (solo 2 pre-existentes sqlite).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- PhaseList pasa a contenedor: botón "Agregar fase" + modal crear/editar con todos
los parámetros (nombre, descripción, orden, color, progreso, fechas previstas y
reales) y validación. Antes "Agregar fase" creaba directamente 'Nueva fase'.
- PhaseTable (Rappasoft): orden, nombre+descripción, barra de progreso, fechas,
color y acciones (editar abre el modal vía evento, actualizar progreso, eliminar);
búsqueda y ordenación. Gateado por 'manage phases' + acceso al proyecto.
Tests: PhaseManagementTest (4). Suite 65 passing (solo 2 pre-existentes sqlite).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Issue::TYPES + typeLabels() (ES) + accessors type_label/type_color; columna type
(string, default 'other') + fillable.
- IssueForm: select "Tipo de incidencia" con validación/carga/guardado.
- IssueTable: columna Tipo (badge) + SelectFilter por tipo.
- IssueDetail: badge de tipo en la cabecera.
- Sync offline: issue.create/update aceptan type; bundle (mapIssue) lo incluye.
Tests: IssuesEnhancementsTest (create muestra el campo vía HTTP, edición persiste) +
MobileApiTest (create con type). Suite 61 passing (solo 2 pre-existentes sqlite).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Campo "Idioma por defecto" al crear/editar usuario (columna locale ya existente),
como desplegable Alpine con banderas SVG reales (no emoji, que en Windows se ven
como "ES"/"GB") servidas localmente: public/images/flags/{es,gb}.svg.
- User: locale añadido a fillable. UserForm: propiedad/validación/guardado de locale.
- LanguageSwitcher de la cabecera usa las mismas banderas SVG.
- Regla CSS [x-cloak] en el layout para evitar parpadeo de desplegables Alpine.
Tests: UserLocaleTest (2) — crear/editar persisten el idioma.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Notificaciones (DB): asignación de incidencia (IssueAssigned), asignación de tarea
(IssueTaskAssigned), comentario (IssueCommented) y cambio de estado
(IssueStatusChanged) a reporter+asignado excluyendo al actor.
- Plantillas de checklist: tabla issue_checklist_templates + modelo, gestor CRUD
(IssueChecklistManager, ruta projects.issues.checklists) y "Aplicar plantilla" en
el detalle (alta masiva de tareas).
- Alertas de vencimiento: columna overdue_notified_at + scope overdue, comando
issues:notify-overdue (programado a diario) que avisa al asignado una sola vez;
badge "vencidas" en la tabla y resaltado por tarea en el detalle.
- Reporte desde el mapa: botón "Incidencia" en el panel del feature seleccionado →
formulario con feature pre-vinculado (IssueForm lee ?feature=).
Tests: IssuesEnhancementsTest (7). Suite 57 passing (solo 2 pre-existentes sqlite).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Web:
- IssueTask + IssueComment (modelos, migraciones, soft-deletes, campos de sync).
Issue gana tasks()/comments() y accessor de % de avance derivado de tareas.
- IssueDetail (página): checklist con asignado/fecha límite/progreso, hilo de
comentarios con foto por comentario, galería de fotos de la incidencia y flujo
de verificación open→in_review→resolved/closed (+reabrir) con notas.
- Creación/edición en páginas propias (IssueForm), sin modal; al guardar redirige
al detalle. Rutas projects.issues.create/edit/show.
- Listado con tabla Rappasoft (IssueTable): filtros por estado/prioridad, búsqueda,
barra de progreso y acciones por fila gateadas por permisos; IssueManager queda
como contenedor (cabecera + stats) que embebe la tabla.
- Seguridad: pertenencia al proyecto + permisos por acción (view/create/edit/delete
issues, upload/delete media) en todos los componentes.
API móvil (offline):
- /sync: issue_task.create/update y issue_comment.create (idempotente, LWW).
- /media: parent_entity issue_task / issue_comment.
- bundle + tombstones incluyen issue_tasks / issue_comments.
- openapi.yaml + MOBILE_SYNC_PROTOCOL.md actualizados.
Tests: MobileApiTest 23 passing (+5); IssuesTablePageTest (3) smoke de la tabla.
Branding: logo RTE International — MAI Group (public/images/logo-rte.png) en login
y navegación; application-logo pasa de SVG por defecto a <img>.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Finishes Phase 2: the /admin route group no longer requires 'manage all'
globally. Each route is gated by its specific permission so a non-super-admin
role can be granted partial admin access:
- /admin/users (+show) -> can:view users; create -> can:create users;
edit -> can:edit users
- /admin/roles, roles/*, permissions -> can:manage roles
- Aligned the role screens' mount checks (RoleForm/RoleView/RolePermissionManager)
from 'manage all' to 'manage roles'.
- Nav 'Administrator' link now shows on can('view users').
Admins keep full access via Gate::before (manage all). Closure routes
(users/roles lists) are now protected at the route level.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New 'Ficha' tab (first, default) on the user view: basic info card
(name/username/email/phone/address/member since) plus the 'Validez de acceso'
card and the Empresa card, moved here from the Permissions tab. The Permissions
tab now focuses on roles + the direct-permissions form.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1. Role view (Details tab): a small form to add users to the role (select of
users not yet in the role + Add) and a per-row remove button. Uses
assignRole/removeRole.
2. User view (Permissions tab): the same grouped, collapsible permissions form
with switches — operating on the user's DIRECT permissions
(givePermissionTo/revokePermissionTo). Permissions inherited from a role show
as checked+disabled with a 'from role' tag; per-group All/None too.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Permissions tab in the role view:
1. Each section is now a collapsible card (Alpine, chevron rotates).
2. Section header has 'All' / 'None' buttons (setGroup grants/revokes every
permission of that group for the role; Admin keeps 'manage all').
3. Permissions render in a single column: name+description on the left, control
on the right.
4. Controls are DaisyUI toggle switches.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Migration: add 'group' and 'description' columns to the permissions table.
- PermissionCatalogSeeder (idempotent updateOrCreate): full catalogue across 11
sections — Proyectos, Fases y progreso, Capas y elementos, Inspecciones,
Incidencias, Empresas, Usuarios, Roles, Informes, Archivos, General. Sets
group + description on existing and creates the new ones; does NOT touch role
assignments. Registered in DatabaseSeeder.
- RoleView: group permission toggles by the 'group' column in a defined section
order and show each permission's description.
DB updated locally (migrate + seed run).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1. Roles list now uses a Rappasoft table (RoleTable): search/sort, per-row
view/edit/delete, and built-in bulk selection + 'Delete selected'. The
/admin/roles page is a plain view embedding <livewire:role-table />.
RoleForm create/edit now only has Name + Description (permissions removed).
2. New RoleView page (/admin/roles/{role}) with two tabs:
- 'Details': header with role name + Back button; description with Edit/Delete
buttons; table of users holding the role (avatar+name | last name | status).
- 'Permissions': all permissions grouped by section (by resource), each with a
toggle switch to grant/revoke for this role (Admin keeps 'manage all').
Removed the old RoleManager component/view (superseded).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per feedback, 'New role' (and Edit) now open a dedicated page instead of a
modal:
- New RoleForm full-page component + view at /admin/roles/create and
/admin/roles/{role}/edit (name, description, permission checkboxes; saves
and redirects back to the list).
- RoleManager trimmed: the create/edit modal and its logic removed; 'New role'
and the per-row/view-modal Edit are now links to the new pages.
- Kept the read-only View modal, single + bulk delete, and protections.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per request:
- Migration: add nullable 'description' to the roles table.
- RoleManager Livewire component + view at /admin/roles:
* Roles list table with per-row checkboxes for bulk selection (+ select-all)
and a 'Delete selected' bulk action (protected roles skipped).
* 'New role' opens a modal form with just Name + Description (and permission
checkboxes to assign).
* Per-row View / Edit / Delete buttons (View modal shows description,
counts and assigned permissions).
- Admin role stays protected (no rename/delete/lose 'manage all').
- /admin/users links to the new Roles screen; the phase-1 permission matrix
stays available via a 'Matrix view' link.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 1 (additive, doesn't touch existing checks):
- Gate::before grants everything to holders of 'manage all' (the Admin role),
robustly (returns true/null, never false; swallows missing-permission).
- New RolePermissionManager Livewire component + view at /admin/permissions:
editable Roles x Permissions matrix (toggle saves instantly), create/delete
roles, create/delete permissions. Admin role and 'manage all' are protected.
- Link to the screen from /admin/users header.
Roles are editable from the UI as chosen.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Login authenticated fine but the landing page crashed (so it looked like
'login doesn't work'):
- bootstrap/app.php didn't register Spatie's middleware aliases -> any route
with role:/permission: threw 'Target class [role] does not exist'.
Registered role / permission / role_or_permission.
- config/livewire.php absent -> default layout is the non-existent
components.layouts.app. ProjectList, PhaseProgress and ReportsDashboard
lacked #[Layout('layouts.app')] -> MissingLayoutException. Added it (the
other 10 routed components already had it).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
User's manual changes: header slots with New-user/New-company actions, wider
max-w-7xl containers on /admin/users and /companies, plus tweaks to
user-view and projects index views. All views compile.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuilt IssueManager to match the 403-line draft view that had no companion
component:
- Modal create/edit form (title, description, priority, status, assignee,
resolution notes shown when resolved/closed)
- Stats bar (open/in_review/resolved/closed/total) and a styled table
- New methods: openForm/closeForm, resolve, close (+ existing save/delete),
projectUsers for the assignee dropdown, resolved_at kept in sync with status
- render() now points to livewire.issues.issue-manager; deleted the old
89-line stub livewire/issue-manager.blade.php
The Issue model already had everything (resolution_notes, resolved_at,
priority_color/status_color accessors, reporter/feature/assignee relations).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deleted (all superseded, recoverable in git history):
- resources/views/projects/edit.blade.php + ProjectController@edit()
- resources/views/projects/create.blade.php + ProjectController@create()
(projects.create/edit routes point to the Livewire ProjectForm; these
controller methods were excluded from the resource and never invoked)
- app/Livewire/ProjectEditTabs.php + project-edit-tabs.blade.php
(old tabbed editor, functionality recovered inside ProjectForm)
- app/Livewire/LayerUpload.php + layer-upload.blade.php (superseded by LayerManager)
Kept resources/views/livewire/issues/issue-manager.blade.php as a reference
for the future rich Issues screen (its companion component was never built).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Point 2 (migrate to Rappasoft tables):
- /admin/users now renders <livewire:user-table /> (+ a New user button)
instead of the custom admin-users component
- /companies now renders <livewire:company-table /> (+ New company button)
instead of the hand-rolled card list
Point 3 (delete): removed resources/views/welcome.blade.php (unused — '/'
redirects to dashboard).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The edit/create project page used a stripped-down inline form. Rewired it
to the existing-but-orphaned pieces:
- Project Data uses the rich partial project-data-form (labels-left/field-right
layout, sections Identification/Location/Planning, address search + Leaflet
map with draggable marker + reverse/forward geocoding, country dropdown)
- When editing, tabs added for Phases / Users / Companies (nested Livewire
components phase-list / project-users / project-companies)
- ProjectForm now provides $countryList (the partial's country dropdown needs it)
- Added the map JS the partial was missing: inits #project-location-map, search
box, and calls $this->setLocation(lat,lng,address,country) so the wire:model
fields update
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
project-form.blade.php referenced $projectId, but the ProjectForm component
exposes $project (the model, null when creating). Caused 'Undefined variable
$projectId' on /projects/{id}/edit. Switched both usages to $project.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1. Editor tabs restyled as spaced DaisyUI buttons (btn-primary when active,
btn-ghost otherwise) — fixes cramped labels and missing active indicator.
2. Layer visibility now works at two levels:
- Phase toggle calls togglePhase() and shows/hides ALL its layers
(checked only when every layer of the phase is active)
- Each layer has its own independent toggle calling toggleLayer()
Map JS regrouped to build one Leaflet group per LAYER (keyed by layer id)
instead of per phase, so activeLayers (layer ids) drives visibility
correctly per layer.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>