import { Component, OnInit } from '@angular/core'; import { MatDialogRef, MatDialog } from '@angular/material/dialog'; import { ToastrService } from 'ngx-toastr'; import { DataService } from '../data.service'; import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component'; export interface AssetNode { name: string; type: 'folder' | 'file'; size: number | null; path: string; } @Component({ selector: 'app-asset-manager-modal', templateUrl: './asset-manager-modal.component.html', styleUrls: ['./asset-manager-modal.component.css'] }) export class AssetManagerModalComponent implements OnInit { currentPath: string = ''; assets: AssetNode[] = []; isLoading: boolean = false; isUploading: boolean = false; displayedColumns: string[] = ['icon', 'name', 'size', 'actions']; constructor( public dialogRef: MatDialogRef, private dialog: MatDialog, private dataService: DataService, private toastService: ToastrService ) { } ngOnInit(): void { this.loadAssets(); } loadAssets(): void { this.isLoading = true; this.dataService.getAssets(this.currentPath).subscribe({ next: (data) => { this.assets = data; this.isLoading = false; }, error: (err) => { this.isLoading = false; this.toastService.error('Error al cargar la ruta actual.'); console.error(err); // If we failed traversing down, fallback to root if (this.currentPath !== '') { this.currentPath = ''; this.loadAssets(); } } }); } enterFolder(folderName: string): void { if (this.currentPath === '') { this.currentPath = folderName; } else { this.currentPath = this.currentPath + '/' + folderName; } this.loadAssets(); } goUp(): void { if (this.currentPath === '') return; const parts = this.currentPath.split('/'); parts.pop(); this.currentPath = parts.join('/'); this.loadAssets(); } onFileSelected(event: any): void { const file = event.target.files[0]; if (file) { const isZip = file.name.toLowerCase().endsWith('.zip'); this.isUploading = true; this.dataService.uploadAssets(file, this.currentPath, isZip).subscribe({ next: (response) => { this.isUploading = false; this.toastService.success(response.message || 'Fichero subido correctamente.'); this.loadAssets(); // Refresh directory }, error: (error) => { this.isUploading = false; this.toastService.error(error?.error?.message || 'Error al subir el fichero.'); console.error(error); } }); } // Reset input so it triggers (change) next time even if it's the same file name event.target.value = ''; } deleteAsset(path: string): void { this.dialog.open(DeleteModalComponent, { width: '300px', data: { name: path } }).afterClosed().subscribe((result) => { if (result) { this.isLoading = true; this.dataService.deleteAsset(path).subscribe({ next: (res) => { this.toastService.success('Elemento eliminado correctamente.'); this.loadAssets(); }, error: (err) => { this.isLoading = false; this.toastService.error(err?.error?.message || 'No se pudo eliminar el elemento.'); } }); } }); } copyPath(path: string): void { // Generate an absolute-like path starting with /assets/ const fullUrl = `/assets/${path}`; navigator.clipboard.writeText(fullUrl).then(() => { this.toastService.info(`Enlace copiado: ${fullUrl}`); }).catch(err => { console.error('Error al copiar al portapapeles', err); }); } formatBytes(bytes: number | null): string { if (bytes === null || bytes === 0) return '0 Bytes'; const k = 1024; const dm = 2; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } close(): void { this.dialogRef.close(); } }