add performance
Deploy / deploy (push) Successful in 39s

This commit is contained in:
2026-05-12 10:02:38 +02:00
parent 9814443218
commit 06775b3bee
+60 -10
View File
@@ -272,6 +272,10 @@ async function loadEvents() {
} }
let allTags = []; let allTags = [];
const PAGE_SIZE = 25;
let renderedCount = 0;
let filteredEvents = [];
let isLoadingMore = false;
async function loadAllTags() { async function loadAllTags() {
try { try {
@@ -290,24 +294,36 @@ function renderTimeline() {
const tagFilter = document.getElementById('tagFilter').value; const tagFilter = document.getElementById('tagFilter').value;
const search = document.getElementById('searchEvents').value.toLowerCase(); const search = document.getElementById('searchEvents').value.toLowerCase();
let filtered = events; filteredEvents = events;
if (teamFilter) filtered = filtered.filter(e => e.team_id == teamFilter); if (teamFilter) filteredEvents = filteredEvents.filter(e => e.team_id == teamFilter);
if (tagFilter) filtered = filtered.filter(e => e.tags && e.tags.includes(tagFilter)); if (tagFilter) filteredEvents = filteredEvents.filter(e => e.tags && e.tags.includes(tagFilter));
if (search) filtered = filtered.filter(e => if (search) filteredEvents = filteredEvents.filter(e =>
e.title.toLowerCase().includes(search) || e.title.toLowerCase().includes(search) ||
(e.description && e.description.toLowerCase().includes(search)) || (e.description && e.description.toLowerCase().includes(search)) ||
(e.tags && e.tags.some(t => t.includes(search))) (e.tags && e.tags.some(t => t.includes(search)))
); );
if (!filtered.length) { renderedCount = 0;
container.innerHTML = '';
container.removeAttribute('style');
renderMoreEvents();
}
function renderMoreEvents() {
const container = document.getElementById('timelineContainer');
if (!filteredEvents.length) {
container.innerHTML = '<div class="text-center text-secondary py-5"><i class="fas fa-book-open fs-1 mb-2"></i><p>No events yet. Create your first incident entry!</p></div>'; container.innerHTML = '<div class="text-center text-secondary py-5"><i class="fas fa-book-open fs-1 mb-2"></i><p>No events yet. Create your first incident entry!</p></div>';
return; return;
} }
container.innerHTML = filtered.map(e => { const next = Math.min(renderedCount + PAGE_SIZE, filteredEvents.length);
const batch = filteredEvents.slice(renderedCount, next);
const html = batch.map(e => {
const date = new Date(e.occurred_at).toLocaleString(); const date = new Date(e.occurred_at).toLocaleString();
return ` return `
<div class="timeline-item"> <div class="timeline-item" data-event-id="${e.id}">
<div class="timeline-dot severity-${e.severity}"></div> <div class="timeline-dot severity-${e.severity}"></div>
<div class="card timeline-card bg-dark border-secondary" style="border-left-color: ${e.team_color}"> <div class="card timeline-card bg-dark border-secondary" style="border-left-color: ${e.team_color}">
<div class="card-body py-1 px-3"> <div class="card-body py-1 px-3">
@@ -341,10 +357,44 @@ function renderTimeline() {
</div>`; </div>`;
}).join(''); }).join('');
filtered.forEach(e => { const wrapper = document.createElement('div');
const container = document.getElementById('attachments-' + e.id); wrapper.innerHTML = html;
if (container) renderAttachments(e.id, container);
const fragment = document.createDocumentFragment();
while (wrapper.firstChild) fragment.appendChild(wrapper.firstChild);
container.appendChild(fragment);
renderedCount = next;
batch.forEach(e => {
const el = document.querySelector(`.timeline-item[data-event-id="${e.id}"] .attachments-list`);
if (el) renderAttachments(e.id, el);
}); });
if (renderedCount < filteredEvents.length) {
const sentinel = document.createElement('div');
sentinel.id = 'timeline-sentinel';
sentinel.className = 'text-center py-3';
sentinel.innerHTML = '<button class="btn btn-outline-primary btn-sm" onclick="renderMoreEvents()"><i class="fas fa-chevron-down me-1"></i>Load more (' + (filteredEvents.length - renderedCount) + ' remaining)</button>';
container.appendChild(sentinel);
observeSentinel();
}
}
let sentinelObserver = null;
function observeSentinel() {
if (sentinelObserver) sentinelObserver.disconnect();
const sentinel = document.getElementById('timeline-sentinel');
if (!sentinel) return;
sentinelObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && !isLoadingMore) {
isLoadingMore = true;
renderMoreEvents();
isLoadingMore = false;
}
}, { rootMargin: '200px' });
sentinelObserver.observe(sentinel);
} }
function renderDocLinks(text) { function renderDocLinks(text) {