Skip to content

[Task] Replace NotificationDialog with AlertDialog and Toast notifications to harmonise UI code #1487

Description

@sven1103

Context

The frontend currently uses two overlapping notification patterns that were introduced at different times:

  1. NotificationDialog (extends Vaadin ConfirmDialog) — a legacy blocking dialog used across ~12 call sites for warnings, errors, and confirmations.
  2. AlertDialog (built on AppDialog.small()) — the newer, intent-driven replacement that follows the design system pattern with danger/warning/error/info intents and IconFactory-based icons.

Additionally, AppDialog.small() was designed specifically for small notifications and sparse confirmations with user intervention (e.g., "Are you sure?"). Non-blocking informative or success messages should use the toast notification factory (MessageSourceNotificationFactory.toast()) instead of any blocking dialog.

AlertDialog is already used correctly in ConnectedDatasetsMain. The rest of the codebase still uses NotificationDialog.

Current NotificationDialog Usage

Subclasses (direct extensions of NotificationDialog) — all need migration

Class Current Role Target
AccessTokenDeletionConfirmationNotification Delete confirmation (cancelable, warning) AlertDialog.danger()
BatchDeletionConfirmationNotification Delete confirmation (cancelable, warning) AlertDialog.danger()
MeasurementDeletionConfirmationNotification Delete confirmation (cancelable, warning) AlertDialog.danger()
QCItemDeletionConfirmationNotification Delete confirmation (cancelable, warning) AlertDialog.danger()
PurchaseItemDeletionConfirmationNotification Delete confirmation (cancelable, warning) AlertDialog.danger()
ProjectUserRemovalConfirmationNotification Remove user (cancelable, warning) AlertDialog.danger()
ExistingGroupsPreventVariableEdit Error + redirect action (error) AlertDialog builder with error() intent
ExistingSamplesPreventVariableEdit Error, confirm-only (error) AlertDialog builder with error() intent
ExistingSamplesPreventSampleOriginEdit Error, confirm-only (error) AlertDialog builder with error() intent
ExistingSamplesPreventGroupEdit Error, confirm-only (error) AlertDialog builder with error() intent

Factory / infrastructure usage

Class Current Role Target
CancelConfirmationDialogFactory Returns NotificationDialog for discard-changes flows Return AlertDialog using AppDialog.small() pattern with danger intent
MessageSourceNotificationFactory.dialog() Returns NotificationDialog for i18n-driven blocking dialogs Needs evaluation — consider deprecating in favour of callers constructing AlertDialog directly, or adapt this factory
UiExceptionHandler.showErrorDialog() Opens NotificationDialog.errorDialog() for user-friendly errors Use AlertDialog with Intent.ERROR, or evaluate if a toast is sufficient for non-critical errors

Call-site usages

Location Current Role Target
AddProjectDialog (line ~150) Uses CancelConfirmationDialogFactory Migrated automatically once factory returns AlertDialog
ProjectSideNavigationComponent (line ~343) Uses CancelConfirmationDialogFactory Migrated automatically once factory returns AlertDialog

What Needs to Be Done

  1. Replace all NotificationDialog subclasses with AlertDialog (using .danger() shortcut for destructive confirmations, .alert(parent) builder for more complex cases).
  2. Update CancelConfirmationDialogFactory to produce AlertDialog-based dialogs backed by AppDialog.small() instead of NotificationDialog.
  3. Evaluate MessageSourceNotificationFactory.dialog() — determine if it should be adapted or if callers should construct AlertDialog directly.
  4. Update UiExceptionHandler to use AlertDialog or toast notifications for error reporting.
  5. Verify non-blocking notifications — any place that uses NotificationDialog only for informational display (no user action required) should be replaced with toast notifications from MessageSourceNotificationFactory.toast().
  6. Deprecate or remove NotificationDialog once all call sites are migrated.
  7. Update front-end-components.md to document the AlertDialog pattern and the decision tree:
    • Destructive/irreversible action confirmation → AlertDialog
    • Informational popup requiring acknowledgment → AlertDialog with Intent.INFO or Intent.ERROR
    • Transient success/info feedback → toast notification
    • Blocking informational dialog (rare) → AppDialog.small() with DialogBody.withoutUserInput()

Acceptance Criteria

  • No Java class extends or instantiates NotificationDialog (or it is explicitly marked @Deprecated)
  • All deletion and removal confirmations use AlertDialog.danger()
  • All "cannot proceed" error dialogs use AlertDialog with the appropriate intent
  • Cancel/discard-changes flows use AlertDialog via the updated CancelConfirmationDialogFactory
  • UiExceptionHandler uses the new pattern
  • front-end-components.md documents the notification component decision tree
  • Existing unit/integration tests are updated to match the new component types

Technical Notes

  • AlertDialog already exists at life.qbic.datamanager.views.general.dialog.AlertDialog
  • AppDialog.small() at life.qbic.datamanager.views.general.dialog.AppDialog provides the underlying small dialog
  • ConnectedDatasetsMain is the reference implementation showing correct AlertDialog usage
  • AlertDialog uses IconFactory.warningIcon() for WARNING/DANGER intents and VaadinIcon for ERROR/INFO
  • The .withDangerousConfirm() footer method provides the red confirm button styling
  • Vaadin's ConfirmDialog (which NotificationDialog extends) uses a fundamentally different API than AppDialog, so the migration requires adjusting how listeners and actions are wired

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions