3f240e5277
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>
53 lines
2.4 KiB
PHP
53 lines
2.4 KiB
PHP
<div>
|
|
{{-- ================================================================
|
|
HEADER
|
|
================================================================ --}}
|
|
<div class="flex flex-wrap items-center justify-between gap-3 mb-5">
|
|
<div>
|
|
<h2 class="text-xl font-bold">Incidencias del proyecto</h2>
|
|
<p class="text-sm text-base-content/60">Gestión de incidencias y problemas</p>
|
|
</div>
|
|
@can('create issues')
|
|
<a
|
|
href="{{ route('projects.issues.create', $project) }}"
|
|
wire:navigate
|
|
class="btn btn-primary btn-sm gap-2"
|
|
>
|
|
<x-heroicon-o-plus class="w-4 h-4" />
|
|
Nueva incidencia
|
|
</a>
|
|
@endcan
|
|
</div>
|
|
|
|
{{-- ================================================================
|
|
STATS BAR
|
|
================================================================ --}}
|
|
<div class="flex flex-wrap gap-2 mb-5">
|
|
<div class="stat bg-base-200 rounded-box py-2 px-4 flex-1 min-w-[120px]">
|
|
<div class="stat-title text-xs">Abiertos</div>
|
|
<div class="stat-value text-error text-2xl">{{ $countOpen }}</div>
|
|
</div>
|
|
<div class="stat bg-base-200 rounded-box py-2 px-4 flex-1 min-w-[120px]">
|
|
<div class="stat-title text-xs">En revisión</div>
|
|
<div class="stat-value text-warning text-2xl">{{ $countInReview }}</div>
|
|
</div>
|
|
<div class="stat bg-base-200 rounded-box py-2 px-4 flex-1 min-w-[120px]">
|
|
<div class="stat-title text-xs">Resueltos</div>
|
|
<div class="stat-value text-success text-2xl">{{ $countResolved }}</div>
|
|
</div>
|
|
<div class="stat bg-base-200 rounded-box py-2 px-4 flex-1 min-w-[120px]">
|
|
<div class="stat-title text-xs">Cerrados</div>
|
|
<div class="stat-value text-base-content/50 text-2xl">{{ $countClosed }}</div>
|
|
</div>
|
|
<div class="stat bg-base-200 rounded-box py-2 px-4 flex-1 min-w-[120px]">
|
|
<div class="stat-title text-xs">Total</div>
|
|
<div class="stat-value text-2xl">{{ $countTotal }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- ================================================================
|
|
ISSUES TABLE (Rappasoft)
|
|
================================================================ --}}
|
|
<livewire:issue-table :project-id="$project->id" :key="'issue-table-'.$project->id" />
|
|
</div>
|