Add loading indicators to product CRUD and dialog components
This commit is contained in:
@@ -15,11 +15,12 @@ import {
|
||||
} from '@angular/material/dialog';
|
||||
import {MatIcon} from '@angular/material/icon';
|
||||
|
||||
import {catchError, forkJoin, of, Observable} from 'rxjs';
|
||||
import {catchError, forkJoin, of, Observable, finalize} from 'rxjs';
|
||||
|
||||
import {PsItem} from '../../interfaces/ps-item';
|
||||
import {ProductListItem} from '../../interfaces/product-list-item';
|
||||
import {PrestashopService} from '../../services/prestashop.serivce';
|
||||
import {MatProgressSpinner} from '@angular/material/progress-spinner';
|
||||
|
||||
export type ProductDialogData = {
|
||||
mode: 'create' | 'edit';
|
||||
@@ -38,7 +39,7 @@ type CarouselItem = { src: string; isPlaceholder: boolean };
|
||||
CommonModule, ReactiveFormsModule,
|
||||
MatFormField, MatLabel, MatInput, MatSelectModule, MatCheckbox,
|
||||
MatButton, MatDialogActions, MatDialogContent, MatDialogTitle,
|
||||
MatIcon, MatIconButton
|
||||
MatIcon, MatIconButton, MatProgressSpinner
|
||||
]
|
||||
})
|
||||
export class PsProductDialogComponent implements OnInit, OnDestroy {
|
||||
@@ -51,6 +52,8 @@ export class PsProductDialogComponent implements OnInit, OnDestroy {
|
||||
) {
|
||||
}
|
||||
|
||||
isSaving = false;
|
||||
|
||||
mode!: 'create' | 'edit';
|
||||
categories: PsItem[] = [];
|
||||
manufacturers: PsItem[] = [];
|
||||
@@ -265,7 +268,10 @@ export class PsProductDialogComponent implements OnInit, OnDestroy {
|
||||
// -------- Save / close --------
|
||||
|
||||
save() {
|
||||
if (this.form.invalid) return;
|
||||
if (this.form.invalid || this.isSaving) return;
|
||||
|
||||
this.isSaving = true;
|
||||
this.dialogRef.disableClose = true;
|
||||
|
||||
const v = this.form.getRawValue();
|
||||
const effectiveDescription = (v.description ?? '').trim() || this.lastLoadedDescription;
|
||||
@@ -276,7 +282,7 @@ export class PsProductDialogComponent implements OnInit, OnDestroy {
|
||||
categoryId: +v.categoryId!,
|
||||
manufacturerId: +v.manufacturerId!,
|
||||
supplierId: +v.supplierId!,
|
||||
images: this.images, // toujours les fichiers sélectionnés
|
||||
images: this.images,
|
||||
complete: !!v.complete,
|
||||
hasManual: !!v.hasManual,
|
||||
conditionLabel: v.conditionLabel || undefined,
|
||||
@@ -292,10 +298,19 @@ export class PsProductDialogComponent implements OnInit, OnDestroy {
|
||||
op$ = this.ps.updateProduct(this.productRow.id, dto) as Observable<unknown>;
|
||||
}
|
||||
|
||||
op$.subscribe({
|
||||
next: () => this.dialogRef.close(true),
|
||||
error: (e: unknown) => alert('Erreur: ' + (e instanceof Error ? e.message : String(e)))
|
||||
});
|
||||
op$
|
||||
.pipe(
|
||||
finalize(() => {
|
||||
// si la boîte de dialogue est encore ouverte, on réactive tout
|
||||
this.isSaving = false;
|
||||
this.dialogRef.disableClose = false;
|
||||
})
|
||||
)
|
||||
.subscribe({
|
||||
next: () => this.dialogRef.close(true),
|
||||
error: (e: unknown) =>
|
||||
alert('Erreur: ' + (e instanceof Error ? e.message : String(e)))
|
||||
});
|
||||
}
|
||||
|
||||
/** Extrait l'id_image depuis une URL FO Presta (.../img/p/.../<id>.jpg) */
|
||||
@@ -375,6 +390,7 @@ export class PsProductDialogComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
close() {
|
||||
if (this.isSaving) return;
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user