{ const logsContainer = document.getElementById('logsContainer'); if (logsContainer) { this.isScrolling = true; logsContainer.scrollTop = logsContainer.scrollHeight; setTimeout(() => { this.isScrolling = false; }, 50); } }, 100); } else { clearInterval(this.intervalId); this.intervalId = null; } }, handleScroll(event) { if (!this.alwaysScroll || this.isScrolling) return; const el = event.target; // Check if user scrolled away from the bottom const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight; if (distanceFromBottom > 50) { this.alwaysScroll = false; clearInterval(this.intervalId); this.intervalId = null; } }, matchesSearch(line) { if (!this.searchQuery.trim()) return true; return line.toLowerCase().includes(this.searchQuery.toLowerCase()); }, decodeHtml(text) { const doc = new DOMParser().parseFromString(text, 'text/html'); return doc.documentElement.textContent; }, highlightMatch(text) { const decoded = this.decodeHtml(text); if (!this.searchQuery.trim()) return this.styleTimestamp(decoded); const escaped = this.searchQuery.replace(/[.*+?^${}()|[\]\\]/g, String.fromCharCode(92) + '$&'); const regex = new RegExp('(' + escaped + ')', 'gi'); const highlighted = decoded.replace(regex, '$1'); return this.styleTimestamp(highlighted); }, styleTimestamp(text) { return text.replace(/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)/g, '$1'); }, getMatchCount() { if (!this.searchQuery.trim()) return 0; const logs = document.getElementById('logs'); if (!logs) return 0; const lines = logs.querySelectorAll('[data-log-line]'); let count = 0; lines.forEach(line => { if (line.textContent.toLowerCase().includes(this.searchQuery.toLowerCase())) { count++; } }); return count; }, downloadLogs() { const logs = document.getElementById('logs'); if (!logs) return; const visibleLines = logs.querySelectorAll('[data-log-line]:not(.hidden)'); let content = ''; visibleLines.forEach(line => { const text = line.textContent.replace(/\s+/g, ' ').trim(); if (text) { content += text + String.fromCharCode(10); } }); const blob = new Blob([content], { type: 'text/plain' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; const timestamp = new Date().toISOString().slice(0,19).replace(/[T:]/g, '-'); a.download = this.containerName + '-logs-' + timestamp + '.txt'; a.click(); URL.revokeObjectURL(url); } }" x-init="if (expanded) { $wire.getLogs(); }">
@if ($displayName)

{{ $displayName }}

@elseif ($resource?->type() === 'application' || str($resource?->type())->startsWith('standalone'))

{{ $container }}

@else

{{ str($container)->beforeLast('-')->headline() }}

@endif @if ($pull_request)
({{ $pull_request }})
@endif @if ($streamLogs) @endif
@if ($outputs)
No matches found.
@foreach (explode("\n", $outputs) as $line) @php // Skip empty lines if (trim($line) === '') { continue; } // Escape HTML for safety $escapedLine = htmlspecialchars($line); @endphp
{!! preg_replace( '/(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)/', '$1', $escapedLine, ) !!}
@endforeach
@else
Refresh to get the logs...
@endif