From c461d9bd5f378bc5f0ac730fe7665b2c48896049 Mon Sep 17 00:00:00 2001 From: sdarbinyan Date: Thu, 13 Aug 2026 08:34:18 +0400 Subject: [PATCH] fix: kill remaining native confirm() in admin, standardize on themed dialog Order cancel/refund and user suspend used window.confirm(). Migrated all three to app-confirm-dialog, matching products/categories/orders delete gates from earlier in this phase. Remaining window.confirm() usages are the three canDeactivate dirty guards (categories/products/project-editor) - left as-is, since CanDeactivate needs a synchronous or Observable/Promise return and browser navigation guards conventionally use the native dialog there; converting those is a separate, larger refactor. Co-Authored-By: Claude Sonnet 5 --- .../admin-order-detail-page.component.html | 14 +++++++++++++ .../admin-order-detail-page.component.ts | 21 ++++++++++++++++--- .../pages/admin-users-page.component.html | 8 +++++++ .../users/pages/admin-users-page.component.ts | 15 +++++++++++-- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/app/features/admin/orders/pages/admin-order-detail-page.component.html b/src/app/features/admin/orders/pages/admin-order-detail-page.component.html index 6afaa2e..50e0c11 100644 --- a/src/app/features/admin/orders/pages/admin-order-detail-page.component.html +++ b/src/app/features/admin/orders/pages/admin-order-detail-page.component.html @@ -88,6 +88,20 @@ {{ 'adminOrders.addNote' | translate }} + + } @else {

{{ 'common.loading' | translate }}

diff --git a/src/app/features/admin/orders/pages/admin-order-detail-page.component.ts b/src/app/features/admin/orders/pages/admin-order-detail-page.component.ts index 27d78b7..db4050b 100644 --- a/src/app/features/admin/orders/pages/admin-order-detail-page.component.ts +++ b/src/app/features/admin/orders/pages/admin-order-detail-page.component.ts @@ -10,6 +10,7 @@ import { LanguageService } from '../../../../services/language.service'; import { ButtonComponent } from '../../../../shared/ui/button/button.component'; import { BadgeComponent } from '../../../../shared/ui/badge/badge.component'; import { OrderTimelineComponent, OrderTimelineEntry } from '../components/order-timeline/order-timeline.component'; +import { ConfirmDialogComponent } from '../../../../shared/ui/confirm-dialog/confirm-dialog.component'; const WORKFLOW_STEPS: AdminOrderStatus[] = ['pending', 'processing', 'shipped', 'delivered']; const TERMINAL_STATUSES: AdminOrderStatus[] = ['cancelled', 'refunded']; @@ -17,7 +18,7 @@ const TERMINAL_STATUSES: AdminOrderStatus[] = ['cancelled', 'refunded']; @Component({ selector: 'app-admin-order-detail-page', standalone: true, - imports: [CommonModule, FormsModule, TranslatePipe, ButtonComponent, BadgeComponent, OrderTimelineComponent], + imports: [CommonModule, FormsModule, TranslatePipe, ButtonComponent, BadgeComponent, OrderTimelineComponent, ConfirmDialogComponent], templateUrl: './admin-order-detail-page.component.html', styleUrls: ['./admin-order-detail-page.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -34,6 +35,8 @@ export class AdminOrderDetailPageComponent { readonly selectableStatuses: AdminOrderStatus[] = this.statuses.filter(status => !TERMINAL_STATUSES.includes(status)); readonly workflowSteps = WORKFLOW_STEPS; readonly noteDraft = signal(''); + readonly pendingCancelId = signal(null); + readonly pendingRefundId = signal(null); readonly internalNoteDraft = signal(''); readonly isTerminal = computed(() => { @@ -85,15 +88,27 @@ export class AdminOrderDetailPageComponent { } cancel(id: string): void { - if (window.confirm(this.translate.t('adminOrders.confirmCancel'))) { + this.pendingCancelId.set(id); + } + + confirmCancel(): void { + const id = this.pendingCancelId(); + if (id) { this.facade.cancelOrder(id); } + this.pendingCancelId.set(null); } requestRefund(id: string): void { - if (window.confirm(this.translate.t('adminOrders.confirmRefund'))) { + this.pendingRefundId.set(id); + } + + confirmRefund(): void { + const id = this.pendingRefundId(); + if (id) { this.facade.requestRefund(id); } + this.pendingRefundId.set(null); } submitNote(id: string): void { diff --git a/src/app/features/admin/users/pages/admin-users-page.component.html b/src/app/features/admin/users/pages/admin-users-page.component.html index 0840a66..0672c20 100644 --- a/src/app/features/admin/users/pages/admin-users-page.component.html +++ b/src/app/features/admin/users/pages/admin-users-page.component.html @@ -120,4 +120,12 @@

{{ entry.timestamp | date:'short' }} — {{ ('adminUsers.actor.' + entry.actor) | translate }} — {{ auditText(entry) }}

} + + diff --git a/src/app/features/admin/users/pages/admin-users-page.component.ts b/src/app/features/admin/users/pages/admin-users-page.component.ts index 931cc78..733920e 100644 --- a/src/app/features/admin/users/pages/admin-users-page.component.ts +++ b/src/app/features/admin/users/pages/admin-users-page.component.ts @@ -12,11 +12,12 @@ import { TableComponent } from '../../../../shared/ui/table/table.component'; import { DialogComponent } from '../../../../shared/ui/dialog/dialog.component'; import { SkeletonComponent } from '../../../../shared/ui/skeleton/skeleton.component'; import { EmptyStateComponent } from '../../../../shared/ui/empty-state/empty-state.component'; +import { ConfirmDialogComponent } from '../../../../shared/ui/confirm-dialog/confirm-dialog.component'; @Component({ selector: 'app-admin-users-page', standalone: true, - imports: [CommonModule, FormsModule, TranslatePipe, ButtonComponent, InputComponent, BadgeComponent, TableComponent, DialogComponent, SkeletonComponent, EmptyStateComponent], + imports: [CommonModule, FormsModule, TranslatePipe, ButtonComponent, InputComponent, BadgeComponent, TableComponent, DialogComponent, SkeletonComponent, EmptyStateComponent, ConfirmDialogComponent], templateUrl: './admin-users-page.component.html', styleUrls: ['./admin-users-page.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush @@ -28,6 +29,7 @@ export class AdminUsersPageComponent { readonly inviteEmail = signal(''); readonly inviteRoleId = signal('viewer'); readonly inviteScope = signal('office'); + readonly pendingSuspendUserId = signal(null); constructor() { this.facade.loadAll(); @@ -40,12 +42,21 @@ export class AdminUsersPageComponent { toggleStatus(userId: string, current: AdminUserStatus): void { const next: AdminUserStatus = current === 'suspended' ? 'active' : 'suspended'; - if (next === 'suspended' && !window.confirm(this.translate.t('adminUsers.confirmSuspend'))) { + if (next === 'suspended') { + this.pendingSuspendUserId.set(userId); return; } this.facade.setStatus(userId, next); } + confirmSuspend(): void { + const userId = this.pendingSuspendUserId(); + if (userId) { + this.facade.setStatus(userId, 'suspended'); + } + this.pendingSuspendUserId.set(null); + } + private static readonly PERMISSION_KEYS: Record = { '*': 'all', 'products.manage': 'productsManage',