Files
docupulse/static/js/events.js
2025-05-29 14:27:15 +02:00

272 lines
9.5 KiB
JavaScript

/**
* @fileoverview Manages the events page functionality.
* This file handles event filtering, pagination, and modal interactions.
*/
document.addEventListener('DOMContentLoaded', function() {
// Elements
const eventTypeFilter = document.getElementById('eventTypeFilter');
const dateRangeFilter = document.getElementById('dateRangeFilter');
const userFilter = document.getElementById('userFilter');
const applyFiltersBtn = document.getElementById('applyFilters');
const eventsTableBody = document.getElementById('eventsTableBody');
const prevPageBtn = document.getElementById('prevPage');
const nextPageBtn = document.getElementById('nextPage');
const currentPageSpan = document.getElementById('currentPage');
const totalPagesSpan = document.getElementById('totalPages');
const eventDetailsModal = document.getElementById('eventDetailsModal');
const eventDetailsContent = document.getElementById('eventDetailsContent');
// State
let currentPage = 1;
let totalPages = 1;
let currentFilters = {
eventType: '',
dateRange: '24h',
userId: ''
};
/**
* Loads events based on current filters and page
*/
async function loadEvents() {
try {
const response = await fetch(`/api/events?page=${currentPage}&${new URLSearchParams(currentFilters)}`);
const data = await response.json();
if (data.success) {
renderEvents(data.events);
updatePagination(data.total_pages);
} else {
console.error('Failed to load events:', data.error);
}
} catch (error) {
console.error('Error loading events:', error);
}
}
/**
* Renders events in the table
*/
function renderEvents(events) {
if (!Array.isArray(events)) {
console.error('Invalid events data received:', events);
return;
}
const eventRows = events.map(event => {
if (!event || typeof event !== 'object') {
console.error('Invalid event data:', event);
return '';
}
// Determine badge color and text based on event type
let badgeClass = 'bg-secondary';
let eventText = event.event_type || 'Unknown Event';
switch(event.event_type) {
case 'user_login':
badgeClass = 'bg-success';
eventText = 'User Login';
break;
case 'user_logout':
badgeClass = 'bg-secondary';
eventText = 'User Logout';
break;
case 'user_register':
badgeClass = 'bg-info';
eventText = 'User Registration';
break;
case 'user_update':
badgeClass = 'bg-primary';
eventText = 'User Update';
break;
case 'file_upload':
badgeClass = 'bg-success';
eventText = 'File Upload';
break;
case 'file_delete':
badgeClass = 'bg-danger';
eventText = 'File Delete';
break;
case 'file_download':
badgeClass = 'bg-info';
eventText = 'File Download';
break;
case 'file_restore':
badgeClass = 'bg-warning';
eventText = 'File Restore';
break;
case 'file_move':
badgeClass = 'bg-primary';
eventText = 'File Move';
break;
case 'file_rename':
badgeClass = 'bg-info';
eventText = 'File Rename';
break;
case 'file_star':
badgeClass = 'bg-warning';
eventText = 'File Star';
break;
case 'file_unstar':
badgeClass = 'bg-secondary';
eventText = 'File Unstar';
break;
case 'room_create':
badgeClass = 'bg-success';
eventText = 'Room Create';
break;
case 'room_delete':
badgeClass = 'bg-danger';
eventText = 'Room Delete';
break;
case 'room_update':
badgeClass = 'bg-primary';
eventText = 'Room Update';
break;
case 'room_join':
badgeClass = 'bg-info';
eventText = 'Room Join';
break;
case 'room_leave':
badgeClass = 'bg-secondary';
eventText = 'Room Leave';
break;
case 'conversation_create':
badgeClass = 'bg-success';
eventText = 'Conversation Create';
break;
case 'conversation_delete':
badgeClass = 'bg-danger';
eventText = 'Conversation Delete';
break;
case 'message_sent':
badgeClass = 'bg-primary';
eventText = 'Message Sent';
break;
case 'attachment_download':
badgeClass = 'bg-info';
eventText = 'Attachment Download';
break;
}
const timestamp = event.timestamp ? new Date(event.timestamp).toLocaleString() : '-';
const username = event.user?.username || 'Unknown User';
const lastName = event.user?.last_name || '';
const eventId = event.id || '';
const ipAddress = event.ip_address || '-';
return `
<tr>
<td>${timestamp}</td>
<td><span class="badge ${badgeClass}">${eventText}</span></td>
<td>${username} ${lastName}</td>
<td>
<button class="btn btn-sm btn-outline-secondary"
data-bs-toggle="modal"
data-bs-target="#eventDetailsModal"
data-event-id="${eventId}">
<i class="fas fa-info-circle"></i> View Details
</button>
</td>
<td>${ipAddress}</td>
</tr>
`;
}).join('');
eventsTableBody.innerHTML = eventRows;
// Add event listeners to detail buttons
document.querySelectorAll('[data-event-id]').forEach(button => {
button.addEventListener('click', () => {
const eventId = button.dataset.eventId;
if (eventId) {
showEventDetails(eventId);
}
});
});
}
/**
* Updates pagination controls
*/
function updatePagination(total) {
totalPages = total;
currentPageSpan.textContent = currentPage;
totalPagesSpan.textContent = totalPages;
prevPageBtn.classList.toggle('disabled', currentPage === 1);
nextPageBtn.classList.toggle('disabled', currentPage === totalPages);
}
/**
* Shows event details in modal
*/
async function showEventDetails(eventId) {
try {
const response = await fetch(`/api/events/${eventId}`);
const data = await response.json();
if (data.success) {
const event = data.event;
eventDetailsContent.textContent = JSON.stringify(event.details, null, 2);
} else {
console.error('Failed to load event details:', data.error);
}
} catch (error) {
console.error('Error loading event details:', error);
}
}
/**
* Loads users for the user filter
*/
async function loadUsers() {
try {
const response = await fetch('/api/users');
const data = await response.json();
const userFilter = document.getElementById('userFilter');
userFilter.innerHTML = '<option value="">All Users</option>';
data.users.forEach(user => {
const option = document.createElement('option');
option.value = user.id;
option.textContent = `${user.username} ${user.last_name || ''}`.trim();
userFilter.appendChild(option);
});
} catch (error) {
console.error('Error loading users:', error);
}
}
// Event Listeners
applyFiltersBtn.addEventListener('click', () => {
currentFilters = {
eventType: eventTypeFilter.value,
dateRange: dateRangeFilter.value,
userId: userFilter.value
};
currentPage = 1;
loadEvents();
});
prevPageBtn.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
loadEvents();
}
});
nextPageBtn.addEventListener('click', () => {
if (currentPage < totalPages) {
currentPage++;
loadEvents();
}
});
// Initialize
loadUsers();
loadEvents();
});