// ============================================
// Quarantine — Flagged Images Management
// ============================================
const Quarantine = {
items: [],
selectedItems: new Set(),
init() {
this.items = Helpers.deepClone(MockData.quarantineItems);
this.renderTable();
this.bindEvents();
},
bindEvents() {
// Search
Helpers.$('#quarantine-search').addEventListener('input', Helpers.debounce((e) => {
this.filterTable(e.target.value, Helpers.$('#quarantine-reason-filter').value);
}));
// Reason filter
Helpers.$('#quarantine-reason-filter').addEventListener('change', (e) => {
this.filterTable(Helpers.$('#quarantine-search').value, e.target.value);
});
// Select all
Helpers.$('#quarantine-select-all').addEventListener('change', (e) => {
this.toggleSelectAll(e.target.checked);
});
// Bulk actions
Helpers.$('#btn-release-bulk')?.addEventListener('click', () => this.releaseSelected());
Helpers.$('#btn-delete-bulk')?.addEventListener('click', () => this.deleteSelected());
},
renderTable(items = null) {
const tbody = Helpers.$('#quarantine-tbody');
if (!tbody) return;
const data = items || this.items;
if (data.length === 0) {
tbody.innerHTML = `
|
No quarantined items
|
`;
return;
}
tbody.innerHTML = data.map(item => `
|
${item.filename}
${item.size}
|
${item.camera} |
${item.category} |
${Helpers.getReasonBadge(item.reason)} |
${Helpers.formatDate(item.date)} |
|
`).join('');
},
filterTable(searchTerm, reasonFilter) {
const term = (searchTerm || '').toLowerCase();
let filtered = this.items;
if (term) {
filtered = filtered.filter(item => item.filename.toLowerCase().includes(term));
}
if (reasonFilter) {
filtered = filtered.filter(item => item.reason === reasonFilter);
}
this.renderTable(filtered);
},
toggleSelectAll(checked) {
Helpers.$$('.quarantine-item-checkbox').forEach(cb => {
cb.checked = checked;
const id = cb.dataset.id;
if (checked) this.selectedItems.add(id);
else this.selectedItems.delete(id);
});
},
viewDetail(id) {
const item = this.items.find(i => i.id === id);
if (!item) return;
const svgUrl = Helpers.generatePlaceholderSVG({
filename: item.filename,
category: 'unsorted',
isGood: null,
hasMask: false
});
const bodyHtml = `
File Information
Filename
${item.filename}
Size
${item.size}
Date
${Helpers.formatDate(item.date)}
Camera
${item.camera}
Quarantine Details
Reason
${Helpers.getReasonBadge(item.reason)}
Status
Quarantined
`;
App.openDetailPanel('Quarantine Detail', bodyHtml);
},
releaseItem(id) {
this.items = this.items.filter(i => i.id !== id);
this.selectedItems.delete(id);
this.renderTable();
Toast.show('Item released back to dataset', 'success');
},
deleteItem(id) {
if (!confirm('Are you sure you want to delete this item?')) return;
this.items = this.items.filter(i => i.id !== id);
this.selectedItems.delete(id);
this.renderTable();
Toast.show('Item deleted', 'warning');
},
releaseSelected() {
this.selectedItems.forEach(id => this.releaseItem(id));
Toast.show(`${this.selectedItems.size} items released`, 'success');
},
deleteSelected() {
if (!confirm(`Delete ${this.selectedItems.size} items?`)) return;
this.selectedItems.forEach(id => this.deleteItem(id));
Toast.show(`${this.selectedItems.size} items deleted`, 'warning');
}
};