phase 3
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<x-app-layout>
|
||||
@php($currentProject = $project)
|
||||
|
||||
<x-slot name="header">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">{{ $project->name }} — Issues</h2>
|
||||
</div>
|
||||
</x-slot>
|
||||
|
||||
<div class="py-8" x-data="{ selected: [], selectAll: false }">
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-4">
|
||||
|
||||
@if(session('status'))
|
||||
<div class="bg-green-50 border border-green-200 text-green-700 px-4 py-3 rounded-md text-sm">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- Filters --}}
|
||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg p-4">
|
||||
<form method="GET" action="{{ route('projects.issues.index', $project) }}" class="flex flex-wrap items-end gap-4">
|
||||
<div class="flex-1 min-w-[200px]">
|
||||
<x-input-label for="search" value="Search" />
|
||||
<x-text-input id="search" name="search" type="text" class="mt-1 block w-full" :value="$search" placeholder="Search issues..." />
|
||||
</div>
|
||||
<div>
|
||||
<x-input-label for="status" value="Status" />
|
||||
<select id="status" name="status" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm text-sm">
|
||||
<option value="">All</option>
|
||||
@foreach(['unresolved', 'resolved', 'ignored', 'muted'] as $s)
|
||||
<option value="{{ $s }}" {{ $currentStatus === $s ? 'selected' : '' }}>{{ ucfirst($s) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<x-input-label for="level" value="Level" />
|
||||
<select id="level" name="level" class="mt-1 block w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm text-sm">
|
||||
<option value="">All</option>
|
||||
@foreach(['fatal', 'error', 'warning', 'info', 'debug'] as $l)
|
||||
<option value="{{ $l }}" {{ $currentLevel === $l ? 'selected' : '' }}>{{ ucfirst($l) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<x-primary-button>Filter</x-primary-button>
|
||||
@if($search || $currentLevel || $currentStatus !== 'unresolved')
|
||||
<a href="{{ route('projects.issues.index', $project) }}" class="text-sm text-gray-500 hover:text-gray-700">Reset</a>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- Bulk Actions --}}
|
||||
<div x-show="selected.length > 0" x-cloak class="bg-indigo-50 border border-indigo-200 rounded-md p-3 flex items-center gap-4">
|
||||
<span class="text-sm font-medium text-indigo-800" x-text="selected.length + ' selected'"></span>
|
||||
<form method="POST" action="{{ route('projects.issues.bulk', $project) }}" class="flex gap-2">
|
||||
@csrf
|
||||
<template x-for="id in selected" :key="id">
|
||||
<input type="hidden" name="issues[]" :value="id">
|
||||
</template>
|
||||
<button type="submit" name="action" value="resolve" class="px-3 py-1 text-xs font-medium rounded-md bg-green-100 text-green-800 hover:bg-green-200 transition">Resolve</button>
|
||||
<button type="submit" name="action" value="ignore" class="px-3 py-1 text-xs font-medium rounded-md bg-yellow-100 text-yellow-800 hover:bg-yellow-200 transition">Ignore</button>
|
||||
<button type="submit" name="action" value="mute" class="px-3 py-1 text-xs font-medium rounded-md bg-gray-100 text-gray-800 hover:bg-gray-200 transition">Mute</button>
|
||||
<button type="submit" name="action" value="delete" class="px-3 py-1 text-xs font-medium rounded-md bg-red-100 text-red-800 hover:bg-red-200 transition"
|
||||
onclick="return confirm('Delete selected issues permanently?')">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- Issues Table --}}
|
||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||
@if($issues->isEmpty())
|
||||
<div class="p-12 text-center text-gray-500">
|
||||
No issues found.
|
||||
</div>
|
||||
@else
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-4 py-3 w-10">
|
||||
<input type="checkbox" x-model="selectAll"
|
||||
@change="selectAll ? selected = {{ json_encode($issues->pluck('id')) }} : selected = []"
|
||||
class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500">
|
||||
</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase w-20">Status</th>
|
||||
<th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase">Issue</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-24">Events</th>
|
||||
<th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase w-40">Last Seen</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
@foreach($issues as $issue)
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3">
|
||||
<input type="checkbox" :value="'{{ $issue->id }}'" x-model="selected"
|
||||
class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500">
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
@php
|
||||
$statusColors = [
|
||||
'unresolved' => 'bg-red-100 text-red-800',
|
||||
'resolved' => 'bg-green-100 text-green-800',
|
||||
'ignored' => 'bg-yellow-100 text-yellow-800',
|
||||
'muted' => 'bg-gray-100 text-gray-600',
|
||||
];
|
||||
$levelColors = [
|
||||
'fatal' => 'bg-red-600',
|
||||
'error' => 'bg-red-400',
|
||||
'warning' => 'bg-yellow-400',
|
||||
'info' => 'bg-blue-400',
|
||||
'debug' => 'bg-gray-400',
|
||||
];
|
||||
@endphp
|
||||
<span class="inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-xs font-medium {{ $statusColors[$issue->status] ?? 'bg-gray-100 text-gray-600' }}">
|
||||
<span class="w-1.5 h-1.5 rounded-full {{ $levelColors[$issue->level] ?? 'bg-gray-400' }}"></span>
|
||||
{{ ucfirst($issue->status) }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-4 py-3">
|
||||
<a href="{{ route('projects.issues.show', [$project, $issue]) }}" class="block">
|
||||
<div class="text-sm font-medium text-gray-900 truncate max-w-lg">{{ $issue->title }}</div>
|
||||
@if($issue->culprit)
|
||||
<div class="text-xs text-gray-500 truncate max-w-lg mt-0.5">{{ $issue->culprit }}</div>
|
||||
@endif
|
||||
</a>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right text-sm text-gray-700 font-mono">
|
||||
{{ number_format($issue->times_seen) }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-right text-sm text-gray-500" title="{{ $issue->last_seen_at }}">
|
||||
{{ $issue->last_seen_at->diffForHumans() }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="px-4 py-3 border-t border-gray-200">
|
||||
{{ $issues->links() }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
Reference in New Issue
Block a user