This commit is contained in:
+118
-2
@@ -504,10 +504,21 @@ function showEpisodesModal(data) {
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<button id="bulk-select-all" class="btn btn-sm btn-secondary" onclick="toggleSelectAll()">
|
||||
<i class="fas fa-check-square"></i> Select All
|
||||
</button>
|
||||
<button id="bulk-delete-selected" class="btn btn-sm btn-danger" onclick="bulkDeleteSelected()" style="margin-left: 10px;" disabled>
|
||||
<i class="fas fa-trash"></i> Delete Selected (<span id="selected-count">0</span>)
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-container">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="40px">
|
||||
<input type="checkbox" id="select-all-checkbox" onchange="toggleSelectAll()">
|
||||
</th>
|
||||
<th>Episode</th>
|
||||
<th>Aired</th>
|
||||
<th>Date Added</th>
|
||||
@@ -530,7 +541,10 @@ function showEpisodesModal(data) {
|
||||
`<td>${dateadded}</td>`;
|
||||
|
||||
return `
|
||||
<tr class="${rowClass}" data-has-date="${!missingDate}">
|
||||
<tr class="${rowClass}" data-has-date="${!missingDate}" data-imdb="${data.series.imdb_id}" data-season="${episode.season}" data-episode="${episode.episode}">
|
||||
<td>
|
||||
<input type="checkbox" class="episode-checkbox" onchange="updateBulkDeleteButton()">
|
||||
</td>
|
||||
<td>S${episode.season.toString().padStart(2, '0')}E${episode.episode.toString().padStart(2, '0')}</td>
|
||||
<td>${episode.aired || '-'}</td>
|
||||
${dateCell}
|
||||
@@ -1625,4 +1639,106 @@ async function logout() {
|
||||
console.error('Logout failed:', error);
|
||||
showToast('❌ Logout error', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bulk delete functions for TV episodes
|
||||
function toggleSelectAll() {
|
||||
const selectAllCheckbox = document.getElementById('select-all-checkbox');
|
||||
const episodeCheckboxes = document.querySelectorAll('.episode-checkbox');
|
||||
|
||||
if (selectAllCheckbox && episodeCheckboxes.length > 0) {
|
||||
const shouldCheck = selectAllCheckbox.checked;
|
||||
episodeCheckboxes.forEach(checkbox => {
|
||||
checkbox.checked = shouldCheck;
|
||||
});
|
||||
updateBulkDeleteButton();
|
||||
}
|
||||
}
|
||||
|
||||
function updateBulkDeleteButton() {
|
||||
const selectedCheckboxes = document.querySelectorAll('.episode-checkbox:checked');
|
||||
const selectedCount = selectedCheckboxes.length;
|
||||
const bulkDeleteButton = document.getElementById('bulk-delete-selected');
|
||||
const selectedCountSpan = document.getElementById('selected-count');
|
||||
|
||||
if (selectedCountSpan) {
|
||||
selectedCountSpan.textContent = selectedCount;
|
||||
}
|
||||
|
||||
if (bulkDeleteButton) {
|
||||
bulkDeleteButton.disabled = selectedCount === 0;
|
||||
}
|
||||
|
||||
// Update select all checkbox state
|
||||
const selectAllCheckbox = document.getElementById('select-all-checkbox');
|
||||
const allCheckboxes = document.querySelectorAll('.episode-checkbox');
|
||||
if (selectAllCheckbox && allCheckboxes.length > 0) {
|
||||
selectAllCheckbox.checked = selectedCount === allCheckboxes.length;
|
||||
selectAllCheckbox.indeterminate = selectedCount > 0 && selectedCount < allCheckboxes.length;
|
||||
}
|
||||
}
|
||||
|
||||
async function bulkDeleteSelected() {
|
||||
const selectedCheckboxes = document.querySelectorAll('.episode-checkbox:checked');
|
||||
const selectedCount = selectedCheckboxes.length;
|
||||
|
||||
if (selectedCount === 0) {
|
||||
showToast('❌ No episodes selected', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm(`Are you sure you want to delete ${selectedCount} episode(s)? This action cannot be undone.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bulkDeleteButton = document.getElementById('bulk-delete-selected');
|
||||
const originalText = bulkDeleteButton.innerHTML;
|
||||
bulkDeleteButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Deleting...';
|
||||
bulkDeleteButton.disabled = true;
|
||||
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
// Process deletions
|
||||
for (const checkbox of selectedCheckboxes) {
|
||||
const row = checkbox.closest('tr');
|
||||
const imdbId = row.getAttribute('data-imdb');
|
||||
const season = parseInt(row.getAttribute('data-season'));
|
||||
const episode = parseInt(row.getAttribute('data-episode'));
|
||||
|
||||
try {
|
||||
const response = await apiCall(`/api/tv/${imdbId}/${season}/${episode}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
|
||||
if (response.success) {
|
||||
// Remove the row from the table
|
||||
row.remove();
|
||||
successCount++;
|
||||
} else {
|
||||
failCount++;
|
||||
console.error(`Failed to delete S${season.toString().padStart(2, '0')}E${episode.toString().padStart(2, '0')}:`, response.message);
|
||||
}
|
||||
} catch (error) {
|
||||
failCount++;
|
||||
console.error(`Error deleting S${season.toString().padStart(2, '0')}E${episode.toString().padStart(2, '0')}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
// Update UI
|
||||
updateEpisodeModalCounts();
|
||||
updateBulkDeleteButton();
|
||||
|
||||
// Reset button
|
||||
bulkDeleteButton.innerHTML = originalText;
|
||||
bulkDeleteButton.disabled = true;
|
||||
|
||||
// Show results
|
||||
if (successCount > 0 && failCount === 0) {
|
||||
showToast(`✅ Successfully deleted ${successCount} episode(s)`, 'success');
|
||||
} else if (successCount > 0 && failCount > 0) {
|
||||
showToast(`⚠️ Deleted ${successCount} episode(s), ${failCount} failed`, 'warning');
|
||||
} else {
|
||||
showToast(`❌ Failed to delete ${failCount} episode(s)`, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user