@@ -1331,9 +1466,13 @@
let filteredFindings = [];
let currentFilters = {
dimension: 'all',
- severity: null,
+ severities: new Set(), // ✨ NEW: Multiple severity selection
search: ''
};
+ let sortConfig = {
+ field: 'severity',
+ order: 'desc' // ✨ NEW: 'asc' or 'desc'
+ };
let pollingInterval = null;
let reviewState = null;
@@ -1357,17 +1496,96 @@
}
function selectAll() {
+ allFindings.forEach(finding => {
+ selectedFindings.add(finding.id);
+ });
+ updateSelectionUI();
+ }
+
+ // ✨ NEW: Select only currently visible findings
+ function selectAllVisible() {
filteredFindings.forEach(finding => {
selectedFindings.add(finding.id);
});
updateSelectionUI();
}
+ // ✨ NEW: Select findings by severity
+ function selectBySeverity(severity) {
+ allFindings.forEach(finding => {
+ if (finding.severity.toLowerCase() === severity) {
+ selectedFindings.add(finding.id);
+ }
+ });
+ updateSelectionUI();
+ }
+
function deselectAll() {
selectedFindings.clear();
updateSelectionUI();
}
+ // ✨ NEW: Toggle severity filter
+ function toggleSeverityFilter(severity) {
+ if (currentFilters.severities.has(severity)) {
+ currentFilters.severities.delete(severity);
+ document.getElementById(`filter-${severity}`).classList.remove('active');
+ } else {
+ currentFilters.severities.add(severity);
+ document.getElementById(`filter-${severity}`).classList.add('active');
+ }
+ applyFilters();
+ }
+
+ // ✨ NEW: Toggle sort order
+ function toggleSortOrder() {
+ sortConfig.order = sortConfig.order === 'asc' ? 'desc' : 'asc';
+
+ // Update UI
+ const icon = document.getElementById('sortOrderIcon');
+ const text = document.getElementById('sortOrderText');
+
+ if (sortConfig.order === 'asc') {
+ icon.textContent = '↑';
+ text.textContent = 'Ascending';
+ } else {
+ icon.textContent = '↓';
+ text.textContent = 'Descending';
+ }
+
+ sortFindings();
+ }
+
+ // ✨ NEW: Reset all filters
+ function resetFilters() {
+ // Reset severity filters
+ currentFilters.severities.clear();
+ document.querySelectorAll('.filter-checkbox-item').forEach(item => {
+ item.classList.remove('active');
+ const checkbox = item.querySelector('input[type="checkbox"]');
+ if (checkbox) checkbox.checked = false;
+ });
+
+ // Reset dimension filter
+ currentFilters.dimension = 'all';
+ document.querySelectorAll('.tab').forEach(tab => {
+ tab.classList.toggle('active', tab.dataset.dimension === 'all');
+ });
+
+ // Reset search
+ currentFilters.search = '';
+ document.getElementById('searchInput').value = '';
+
+ // Reset sort
+ sortConfig.field = 'severity';
+ sortConfig.order = 'desc';
+ document.getElementById('sortSelect').value = 'severity';
+ document.getElementById('sortOrderIcon').textContent = '↓';
+ document.getElementById('sortOrderText').textContent = 'Descending';
+
+ applyFilters();
+ }
+
function updateSelectionUI() {
// Update counter
const counter = document.getElementById('selectionCounter');
@@ -2264,11 +2482,6 @@
applyFilters();
}
- function filterBySeverity(severity) {
- currentFilters.severity = currentFilters.severity === severity ? null : severity;
- applyFilters();
- }
-
function setupSearch() {
const searchInput = document.getElementById('searchInput');
searchInput.addEventListener('input', (e) => {
@@ -2284,14 +2497,16 @@
return false;
}
- // Severity filter
- if (currentFilters.severity && finding.severity !== currentFilters.severity) {
- return false;
+ // ✨ NEW: Multi-select severity filter
+ if (currentFilters.severities.size > 0) {
+ if (!currentFilters.severities.has(finding.severity.toLowerCase())) {
+ return false;
+ }
}
// Search filter
if (currentFilters.search) {
- const searchText = `${finding.title} ${finding.description} ${finding.file}`.toLowerCase();
+ const searchText = `${finding.title} ${finding.description} ${finding.file} ${finding.category || ''}`.toLowerCase();
if (!searchText.includes(currentFilters.search)) {
return false;
}
@@ -2300,24 +2515,32 @@
return true;
});
- renderFindings();
+ // Auto-sort after filtering
+ sortFindings();
}
- // Sort findings
+ // ✨ UPDATED: Sort findings with order support
function sortFindings() {
const sortBy = document.getElementById('sortSelect').value;
+ sortConfig.field = sortBy;
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
filteredFindings.sort((a, b) => {
+ let comparison = 0;
+
if (sortBy === 'severity') {
- return severityOrder[a.severity] - severityOrder[b.severity];
+ comparison = severityOrder[a.severity.toLowerCase()] - severityOrder[b.severity.toLowerCase()];
} else if (sortBy === 'dimension') {
- return a.dimension.localeCompare(b.dimension);
+ comparison = a.dimension.localeCompare(b.dimension);
} else if (sortBy === 'file') {
- return a.file.localeCompare(b.file);
+ comparison = a.file.localeCompare(b.file);
+ } else if (sortBy === 'title') {
+ comparison = a.title.localeCompare(b.title);
}
- return 0;
+
+ // ✨ NEW: Apply sort order (asc/desc)
+ return sortConfig.order === 'asc' ? comparison : -comparison;
});
renderFindings();