Display already uploaded images name in edit pin popup + error handling

timeline
Alix JEUDI--LEMOINE 2 weeks ago
parent c5888c9d8e
commit d7d87732cb

@ -136,9 +136,10 @@
>Images</label >Images</label
> >
<app-drag-drop <app-drag-drop
[initialFiles]="form.get('files')?.value" [initialFiles]="getFileNames()"
(filesSelected)="onFilesReceived($event)" (filesSelected)="onFilesReceived($event)"
(fileRemoved)="removeFile($event)" (fileRemoved)="removeFile($event)"
[errorMessage]="uploadError"
></app-drag-drop> ></app-drag-drop>
</div> </div>

@ -5,6 +5,7 @@ import {
Input, Input,
OnDestroy, OnDestroy,
OnInit, OnInit,
ViewChild,
} from '@angular/core'; } from '@angular/core';
import { import {
FormBuilder, FormBuilder,
@ -41,12 +42,14 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
@Input() isHomePage: boolean = false; @Input() isHomePage: boolean = false;
@Input() pin!: Pin; @Input() pin!: Pin;
@ViewChild(DragDropComponent) dragDropComponent!: DragDropComponent;
form!: FormGroup; form!: FormGroup;
suggestions: any[] = []; suggestions: any[] = [];
inputFocused: boolean = false; inputFocused: boolean = false;
files: any[] = []; files: File[] = [];
isPinModalOpen: boolean = false; isPinModalOpen: boolean = false;
@Input() modalId!: string; @Input() modalId!: string;
uploadError: string = '';
private modalOpenSubscription!: Subscription; private modalOpenSubscription!: Subscription;
private routerSubscription!: Subscription; private routerSubscription!: Subscription;
@ -98,8 +101,11 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
: '', : '',
}); });
// Initialiser les fichiers existants this.pin.files.forEach((file) => {
this.files = this.pin?.files || []; this.imageService.getImageMetadata(file).subscribe((metadata) => {
this.files.push(new File([], metadata.metadata.original_filename + "|" + file.toString(), { type: metadata.metadata.content_type }));
});
});
// S'abonner aux changements d'état du modal // S'abonner aux changements d'état du modal
this.modalOpenSubscription = this.modalService this.modalOpenSubscription = this.modalService
@ -191,106 +197,92 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
async onFilesReceived(files: FileList): Promise<void> { async onFilesReceived(files: FileList): Promise<void> {
// Ajouter les nouveaux fichiers à la liste existante // Ajouter les nouveaux fichiers à la liste existante
this.files = [...this.files, ...Array.from(files)]; this.files = [...this.files, ...Array.from(files).map((file) => file)];
this.uploadError = ''; // Réinitialiser l'erreur
for (let i = 0; i < files.length; i++) { if (this.dragDropComponent) {
this.dragDropComponent.updateFileNamesFromFileList(files);
} else {
console.warn('EditPinPopupComponent - dragDropComponent not available');
}
// Ne traiter que la première photo pour les métadonnées EXIF
if (files.length > 0) {
try { try {
const data = await this.exifService.getLocation(files[i]); const data = await this.exifService.getLocation(files[0]);
if (data.latitude !== undefined && data.longitude !== undefined) { if (data.latitude !== undefined && data.longitude !== undefined) {
try { this.autocompleteService.getAddressFromCoordinates(data.latitude, data.longitude).subscribe((address) => {
const address = await this.autocompleteService
.getAddressFromCoordinates(data.latitude, data.longitude)
.pipe(take(1))
.toPromise();
if (address) { if (address) {
this.form.get('location')?.setValue(address.display_name); this.form.get('location')?.setValue(address.display_name);
this.form.get('complete_address')?.setValue(address.display_name); this.form.get('complete_address')?.setValue(address.display_name);
this.form.get('coordinates')?.setValue([data.latitude, data.longitude]); this.form.get('coordinates')?.setValue([data.latitude, data.longitude]);
break;
}
} catch (addressError) {
console.error("Erreur lors de la récupération de l'adresse:", addressError);
// Utiliser les coordonnées brutes en cas d'échec
this.form.get('location')?.setValue(`${data.latitude}, ${data.longitude}`);
this.form.get('complete_address')?.setValue(`${data.latitude}, ${data.longitude}`);
this.form.get('coordinates')?.setValue([data.latitude, data.longitude]);
} }
});
} }
} catch (error) { } catch (error) {
console.error('Erreur :', error); console.error(
'EditPinPopupComponent - Error processing EXIF data:',
error
);
} }
} }
} }
submitForm(): void { submitForm(): void {
// Marquer tous les champs comme touched pour afficher les erreurs
Object.keys(this.form.controls).forEach(key => {
const control = this.form.get(key);
control?.markAsTouched();
});
if (this.form.valid) { if (this.form.valid) {
const uploadObservables = this.files.map((file) => {
if(file.size === 0) {
if(file.name.includes("|")) {
return of({id: file.name.split("|")[1]});
} else {
this.uploadError = file.name + ' : ' + 'Image vide';
return of(null);
}
}
return this.imageService.postImage(file).pipe(
catchError(error => {
this.uploadError = file.name + ' : ' + error.error.detail || 'Erreur lors de l\'upload de l\'image';
if (this.dragDropComponent) {
this.dragDropComponent.errorMessage = this.uploadError;
}
return of(null);
})
)
});
forkJoin(uploadObservables).subscribe((responses) => {
console.log(responses);
// Vérifier si toutes les réponses sont valides
if (responses.some(response => response === null)) {
return; // Ne pas continuer si une erreur s'est produite
}
this.files = responses.map((res: any) => res.id);
const coordinates = this.form.get('coordinates')?.value; const coordinates = this.form.get('coordinates')?.value;
const pinData = { const pinData = {
...this.form.value, ...this.form.value,
files: this.files, files: this.files,
date: this.form.get('date')?.value || null, date: this.form.get('date')?.value || null,
location: coordinates || this.pin.location, // Utiliser les coordonnées pour location location: coordinates || [0, 0],
complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value, complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value,
}; };
// Supprimer le champ coordinates qui n'est pas dans le modèle Pin
delete pinData.coordinates; delete pinData.coordinates;
// Filtrer les fichiers qui sont déjà des IDs (images existantes)
const existingFiles = this.files.filter(
(file) => typeof file === 'string'
);
const newFiles = this.files.filter((file) => file instanceof File);
// Récupérer la date et la formater correctement
const dateValue = this.form.get('date')?.value;
const formattedDate = dateValue
? new Date(dateValue).toISOString()
: null;
if (newFiles.length > 0) {
// Upload des nouveaux fichiers
const uploadObservables = newFiles.map((file) =>
this.imageService.postImage(file)
);
forkJoin(uploadObservables).subscribe((responses) => {
// Combiner les IDs des nouvelles images avec les IDs existants
const allFileIds = [
...existingFiles,
...responses.map((res: any) => res.id),
];
const pinData = { this.pinService.updatePin(this.pin.id, pinData)?.subscribe(() => {
...this.form.getRawValue(),
files: allFileIds,
user_id: this.pin.user_id,
date: formattedDate,
location: coordinates || this.pin.location, // Utiliser les coordonnées pour location
complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value,
};
this.pinService.updatePin(this.pin.id, pinData).subscribe(() => {
this.mapReloadService.requestReload(); this.mapReloadService.requestReload();
this.closePinModal(); this.closePinModal();
}); });
}); });
} else { } else {
// Si pas de nouveaux fichiers, mettre à jour directement avec les fichiers existants console.error('Le formulaire est invalide');
const pinData = {
...this.form.getRawValue(),
files: existingFiles,
user_id: this.pin.user_id,
date: formattedDate,
location: coordinates || this.pin.location, // Utiliser les coordonnées pour location
complete_address: this.form.get('complete_address')?.value || this.form.get('location')?.value,
};
this.pinService.updatePin(this.pin.id, pinData).subscribe(() => {
this.mapReloadService.requestReload();
this.closePinModal();
});
}
} }
} }
@ -300,19 +292,34 @@ export class EditPinPopupComponent implements OnInit, AfterViewInit, OnDestroy {
closePinModal() { closePinModal() {
this.modalService.closeModal(this.modalId); this.modalService.closeModal(this.modalId);
this.form.reset();
this.files = [];
this.uploadError = '';
if (this.dragDropComponent) {
this.dragDropComponent.updateFileNamesFromFileList(new DataTransfer().files);
this.dragDropComponent.errorMessage = '';
} }
removeFile(fileName: string): void {
const index = this.files.findIndex((file) => {
if (typeof file === 'string') {
return file === fileName;
} }
return file.name === fileName;
});
removeFile(fileName: string): void {
const index = this.files.findIndex((file) => file.name === fileName);
if (index > -1) { if (index > -1) {
this.files.splice(index, 1); this.files.splice(index, 1);
this.form.patchValue({ files: this.files }); this.uploadError = ''; // Réinitialiser l'erreur lors de la suppression d'un fichier
if (this.dragDropComponent) {
this.dragDropComponent.errorMessage = '';
}
// Mettre à jour le form control
const dataTransfer = new DataTransfer();
this.files.forEach((file) => dataTransfer.items.add(file as File));
this.form.patchValue({ files: dataTransfer.files });
} }
} }
getFileNames(): string[] {
return this.files.map(file => {
return file.name.split("|")[0];
});
}
} }

Loading…
Cancel
Save