fix(ui): replace native confirm()/alert() with shared dialogs and toasts

New app-confirm-dialog (wraps existing app-dialog + app-button) replaces
every native confirm() across media library bulk-delete, static pages
editor (delete/bulk-delete), builder save-bar (publish/reset-draft),
project-editor-page (reset-section), homepage/languages/widgets sections
(remove block/language/widget), and cart (clear-cart).

Cart's native alert() calls (delivery/terms validation, email send
success/failure) now route through the existing UserNotificationService
toast pipeline instead.

No native confirm()/alert()/prompt() remain in production UI.
This commit is contained in:
sdarbinyan
2026-07-26 00:08:00 +04:00
parent a670ca994f
commit 6c6fa00ccf
23 changed files with 251 additions and 41 deletions

View File

@@ -127,4 +127,17 @@
<app-button variant="danger" (click)="proceedDelete()">{{ 'mediaLibrary.confirm' | translate }}</app-button>
</div>
</app-dialog>
<app-dialog
[open]="bulkDeleteConfirmOpen()"
[titleText]="'mediaLibrary.deleteConfirmTitle' | translate"
size="sm"
(closed)="bulkDeleteConfirmOpen.set(false)"
>
<p>{{ 'mediaLibrary.bulkDeleteConfirm' | translate }}</p>
<div class="media-page__dialog-actions">
<app-button variant="secondary" (click)="bulkDeleteConfirmOpen.set(false)">{{ 'mediaLibrary.cancel' | translate }}</app-button>
<app-button variant="danger" (click)="proceedBulkDelete()">{{ 'mediaLibrary.confirm' | translate }}</app-button>
</div>
</app-dialog>
</section>

View File

@@ -49,6 +49,7 @@ export class MediaLibraryPageComponent implements OnInit {
@ViewChild('fileInput') private fileInput?: ElementRef<HTMLInputElement>;
protected readonly pendingDelete = signal<MediaAsset | null>(null);
protected readonly bulkDeleteConfirmOpen = signal(false);
protected readonly detailsAsset = signal<MediaAsset | null>(null);
protected readonly dragActive = signal(false);
protected readonly totalPages = () => Math.max(1, Math.ceil(this.facade.total() / PAGE_SIZE));
@@ -212,10 +213,15 @@ export class MediaLibraryPageComponent implements OnInit {
return this.facade.items().filter(a => this.facade.isSelected(a.id));
}
protected async bulkDelete(): Promise<void> {
protected bulkDelete(): void {
if (this.selectedAssets().length === 0) return;
this.bulkDeleteConfirmOpen.set(true);
}
protected async proceedBulkDelete(): Promise<void> {
const ids = this.selectedAssets().map(a => a.id);
this.bulkDeleteConfirmOpen.set(false);
if (ids.length === 0) return;
if (!confirm(this.translate.t('mediaLibrary.bulkDeleteConfirm'))) return;
await this.facade.bulkDelete(ids);
}