155 lines
5.9 KiB
JavaScript
Raw Normal View History

2025-11-10 01:58:41 +01:00
import { api } from '../api.js';
2025-11-10 15:46:40 +01:00
import { BaseFileList } from './base-file-list.js';
2025-11-10 01:58:41 +01:00
2025-11-10 15:46:40 +01:00
export class DeletedFiles extends BaseFileList {
2025-11-10 01:58:41 +01:00
constructor() {
super();
}
async connectedCallback() {
2025-11-10 15:46:40 +01:00
super.connectedCallback();
2025-11-10 01:58:41 +01:00
await this.loadDeletedFiles();
}
async loadDeletedFiles() {
try {
2025-11-10 15:46:40 +01:00
this.files = await api.listDeletedFiles();
this.folders = [];
this.selectedFiles.clear();
this.selectedFolders.clear();
2025-11-10 01:58:41 +01:00
this.render();
} catch (error) {
console.error('Failed to load deleted files:', error);
this.innerHTML = '<p class="error-message">Failed to load deleted files.</p>';
}
}
render() {
2025-11-10 15:46:40 +01:00
const hasSelected = this.selectedFiles.size > 0;
const totalSelected = this.selectedFiles.size;
const allSelected = this.files.length > 0 && this.selectedFiles.size === this.files.length;
const someSelected = hasSelected && !allSelected;
if (this.files.length === 0) {
2025-11-10 01:58:41 +01:00
this.innerHTML = `
2025-11-10 15:46:40 +01:00
<div class="file-list-container">
<div class="file-list-header">
<h2>Deleted Files</h2>
</div>
2025-11-10 01:58:41 +01:00
<p class="empty-state">No deleted files found.</p>
</div>
`;
return;
}
this.innerHTML = `
2025-11-10 15:46:40 +01:00
<div class="file-list-container">
<div class="file-list-header">
<div class="header-left">
<h2>Deleted Files</h2>
${this.files.length > 0 ? `
<div class="selection-controls">
<input type="checkbox" id="select-all" ${allSelected ? 'checked' : ''} ${someSelected ? 'data-indeterminate="true"' : ''}>
<label for="select-all">
${hasSelected ? `${totalSelected} selected` : 'Select all'}
</label>
</div>
` : ''}
</div>
</div>
${hasSelected ? `
<div class="batch-actions">
<button class="button button-small button-primary" id="batch-restore-btn">Restore Selected</button>
<button class="button button-small" id="clear-selection-btn">Clear Selection</button>
</div>
` : ''}
2025-11-10 01:58:41 +01:00
<div class="file-grid">
2025-11-10 15:46:40 +01:00
${this.files.map(file => this.renderDeletedFile(file)).join('')}
2025-11-10 01:58:41 +01:00
</div>
</div>
`;
this.attachListeners();
2025-11-10 15:46:40 +01:00
this.updateIndeterminateState();
2025-11-10 01:58:41 +01:00
}
renderDeletedFile(file) {
2025-11-10 15:46:40 +01:00
const isSelected = this.selectedFiles.has(file.id);
2025-11-10 01:58:41 +01:00
const icon = this.getFileIcon(file.mime_type);
const size = this.formatFileSize(file.size);
2025-11-10 15:46:40 +01:00
const deletedAt = file.deleted_at ? new Date(file.deleted_at).toLocaleString() : 'N/A';
2025-11-10 01:58:41 +01:00
return `
2025-11-10 15:46:40 +01:00
<div class="file-item ${isSelected ? 'selected' : ''}" data-file-id="${file.id}">
<input type="checkbox" class="select-item" data-type="file" data-id="${file.id}" ${isSelected ? 'checked' : ''}>
2025-11-10 01:58:41 +01:00
<div class="file-icon">${icon}</div>
<div class="file-name">${file.name}</div>
<div class="file-size">${size}</div>
2025-11-10 15:46:40 +01:00
<div class="file-deleted-at">Deleted: ${deletedAt}</div>
2025-11-10 01:58:41 +01:00
<div class="file-actions-menu">
2025-11-10 15:46:40 +01:00
<button class="action-btn" data-action="restore" data-id="${file.id}">Restore</button>
2025-11-10 01:58:41 +01:00
</div>
</div>
`;
}
2025-11-10 15:46:40 +01:00
createBatchActionsBar() {
const container = this.querySelector('.file-list-container');
const header = container.querySelector('.file-list-header');
const batchBar = document.createElement('div');
batchBar.className = 'batch-actions';
batchBar.innerHTML = `
<button class="button button-small button-primary" id="batch-restore-btn">Restore Selected</button>
<button class="button button-small" id="clear-selection-btn">Clear Selection</button>
`;
header.insertAdjacentElement('afterend', batchBar);
2025-11-10 01:58:41 +01:00
}
attachListeners() {
2025-11-10 15:46:40 +01:00
const batchRestoreBtn = this.querySelector('#batch-restore-btn');
if (batchRestoreBtn) {
batchRestoreBtn.addEventListener('click', () => this.handleBatchRestore());
}
2025-11-10 01:58:41 +01:00
}
2025-11-10 15:46:40 +01:00
async handleBatchRestore() {
const totalSelected = this.selectedFiles.size;
if (totalSelected === 0) return;
if (!confirm(`Restore ${totalSelected} files?`)) return;
try {
for (const fileId of this.selectedFiles) {
2025-11-10 01:58:41 +01:00
await api.restoreFile(fileId);
2025-11-10 15:46:40 +01:00
}
document.dispatchEvent(new CustomEvent('show-toast', {
detail: { message: 'Files restored successfully!', type: 'success' }
}));
await this.loadDeletedFiles();
} catch (error) {
document.dispatchEvent(new CustomEvent('show-toast', {
detail: { message: 'Failed to restore files: ' + error.message, type: 'error' }
}));
}
}
async handleAction(action, id) {
try {
if (action === 'restore') {
await api.restoreFile(id);
2025-11-10 01:58:41 +01:00
document.dispatchEvent(new CustomEvent('show-toast', {
detail: { message: 'File restored successfully!', type: 'success' }
}));
2025-11-10 15:46:40 +01:00
await this.loadDeletedFiles();
2025-11-10 01:58:41 +01:00
}
2025-11-10 15:46:40 +01:00
} catch (error) {
document.dispatchEvent(new CustomEvent('show-toast', {
detail: { message: 'Action failed: ' + error.message, type: 'error' }
}));
2025-11-10 01:58:41 +01:00
}
}
}
customElements.define('deleted-files', DeletedFiles);