+60
-10
@@ -272,6 +272,10 @@ async function loadEvents() {
|
||||
}
|
||||
|
||||
let allTags = [];
|
||||
const PAGE_SIZE = 25;
|
||||
let renderedCount = 0;
|
||||
let filteredEvents = [];
|
||||
let isLoadingMore = false;
|
||||
|
||||
async function loadAllTags() {
|
||||
try {
|
||||
@@ -290,24 +294,36 @@ function renderTimeline() {
|
||||
const tagFilter = document.getElementById('tagFilter').value;
|
||||
const search = document.getElementById('searchEvents').value.toLowerCase();
|
||||
|
||||
let filtered = events;
|
||||
if (teamFilter) filtered = filtered.filter(e => e.team_id == teamFilter);
|
||||
if (tagFilter) filtered = filtered.filter(e => e.tags && e.tags.includes(tagFilter));
|
||||
if (search) filtered = filtered.filter(e =>
|
||||
filteredEvents = events;
|
||||
if (teamFilter) filteredEvents = filteredEvents.filter(e => e.team_id == teamFilter);
|
||||
if (tagFilter) filteredEvents = filteredEvents.filter(e => e.tags && e.tags.includes(tagFilter));
|
||||
if (search) filteredEvents = filteredEvents.filter(e =>
|
||||
e.title.toLowerCase().includes(search) ||
|
||||
(e.description && e.description.toLowerCase().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>';
|
||||
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();
|
||||
return `
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-item" data-event-id="${e.id}">
|
||||
<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-body py-1 px-3">
|
||||
@@ -341,10 +357,44 @@ function renderTimeline() {
|
||||
</div>`;
|
||||
}).join('');
|
||||
|
||||
filtered.forEach(e => {
|
||||
const container = document.getElementById('attachments-' + e.id);
|
||||
if (container) renderAttachments(e.id, container);
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = html;
|
||||
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user