144 lines
4.2 KiB
TypeScript
144 lines
4.2 KiB
TypeScript
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<AssetManagerModalComponent>,
|
|
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();
|
|
}
|
|
}
|