Context
The frontend currently uses two overlapping notification patterns that were introduced at different times:
NotificationDialog (extends Vaadin ConfirmDialog) — a legacy blocking dialog used across ~12 call sites for warnings, errors, and confirmations.
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
- Replace all
NotificationDialog subclasses with AlertDialog (using .danger() shortcut for destructive confirmations, .alert(parent) builder for more complex cases).
- Update
CancelConfirmationDialogFactory to produce AlertDialog-based dialogs backed by AppDialog.small() instead of NotificationDialog.
- Evaluate
MessageSourceNotificationFactory.dialog() — determine if it should be adapted or if callers should construct AlertDialog directly.
- Update
UiExceptionHandler to use AlertDialog or toast notifications for error reporting.
- 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().
- Deprecate or remove
NotificationDialog once all call sites are migrated.
- 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
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
Context
The frontend currently uses two overlapping notification patterns that were introduced at different times:
NotificationDialog(extends VaadinConfirmDialog) — a legacy blocking dialog used across ~12 call sites for warnings, errors, and confirmations.AlertDialog(built onAppDialog.small()) — the newer, intent-driven replacement that follows the design system pattern with danger/warning/error/info intents andIconFactory-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.AlertDialogis already used correctly inConnectedDatasetsMain. The rest of the codebase still usesNotificationDialog.Current
NotificationDialogUsageSubclasses (direct extensions of
NotificationDialog) — all need migrationAccessTokenDeletionConfirmationNotificationAlertDialog.danger()BatchDeletionConfirmationNotificationAlertDialog.danger()MeasurementDeletionConfirmationNotificationAlertDialog.danger()QCItemDeletionConfirmationNotificationAlertDialog.danger()PurchaseItemDeletionConfirmationNotificationAlertDialog.danger()ProjectUserRemovalConfirmationNotificationAlertDialog.danger()ExistingGroupsPreventVariableEditAlertDialogbuilder witherror()intentExistingSamplesPreventVariableEditAlertDialogbuilder witherror()intentExistingSamplesPreventSampleOriginEditAlertDialogbuilder witherror()intentExistingSamplesPreventGroupEditAlertDialogbuilder witherror()intentFactory / infrastructure usage
CancelConfirmationDialogFactoryNotificationDialogfor discard-changes flowsAlertDialogusingAppDialog.small()pattern with danger intentMessageSourceNotificationFactory.dialog()NotificationDialogfor i18n-driven blocking dialogsAlertDialogdirectly, or adapt this factoryUiExceptionHandler.showErrorDialog()NotificationDialog.errorDialog()for user-friendly errorsAlertDialogwithIntent.ERROR, or evaluate if a toast is sufficient for non-critical errorsCall-site usages
AddProjectDialog(line ~150)CancelConfirmationDialogFactoryAlertDialogProjectSideNavigationComponent(line ~343)CancelConfirmationDialogFactoryAlertDialogWhat Needs to Be Done
NotificationDialogsubclasses withAlertDialog(using.danger()shortcut for destructive confirmations,.alert(parent)builder for more complex cases).CancelConfirmationDialogFactoryto produceAlertDialog-based dialogs backed byAppDialog.small()instead ofNotificationDialog.MessageSourceNotificationFactory.dialog()— determine if it should be adapted or if callers should constructAlertDialogdirectly.UiExceptionHandlerto useAlertDialogor toast notifications for error reporting.NotificationDialogonly for informational display (no user action required) should be replaced with toast notifications fromMessageSourceNotificationFactory.toast().NotificationDialogonce all call sites are migrated.front-end-components.mdto document theAlertDialogpattern and the decision tree:AlertDialogAlertDialogwithIntent.INFOorIntent.ERRORAppDialog.small()withDialogBody.withoutUserInput()Acceptance Criteria
NotificationDialog(or it is explicitly marked@Deprecated)AlertDialog.danger()AlertDialogwith the appropriate intentAlertDialogvia the updatedCancelConfirmationDialogFactoryUiExceptionHandleruses the new patternfront-end-components.mddocuments the notification component decision treeTechnical Notes
AlertDialogalready exists atlife.qbic.datamanager.views.general.dialog.AlertDialogAppDialog.small()atlife.qbic.datamanager.views.general.dialog.AppDialogprovides the underlying small dialogConnectedDatasetsMainis the reference implementation showing correctAlertDialogusageAlertDialogusesIconFactory.warningIcon()for WARNING/DANGER intents andVaadinIconfor ERROR/INFO.withDangerousConfirm()footer method provides the red confirm button stylingConfirmDialog(whichNotificationDialogextends) uses a fundamentally different API thanAppDialog, so the migration requires adjusting how listeners and actions are wired