src/app/core/common-components/confirmation-dialog/confirmation-dialog/confirmation-dialog.component.ts
A configurable confirmation dialog box used by the ConfirmationDialogService.
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | app-confirmation-dialog |
| standalone | true |
| imports |
MatDialogModule
MatButtonModule
MatFormFieldModule
MatInputModule
MarkdownComponent
|
| styleUrls | ./confirmation-dialog.component.scss |
| templateUrl | ./confirmation-dialog.component.html |
| styleUrl | ./confirmation-dialog.component.scss |
No results matching.
DialogCloseComponent
MatDialogModule
MatButtonModule
MatFormFieldModule
MatInputModule
MarkdownComponent
Properties |
Methods |
| isBlocked | ||||||
isBlocked(button: ConfirmationDialogButton)
|
||||||
|
Confirming buttons stay disabled until the required keyword has been typed, while buttons that abort the action (e.g. "Cancel") remain available.
Parameters :
Returns :
boolean
|
| data |
Type : unknown
|
Default value : inject<ConfirmationDialogConfig>(MAT_DIALOG_DATA)
|
| dialogRef |
Type : unknown
|
Default value : inject<MatDialogRef<ConfirmationDialogComponent>>(MatDialogRef)
|
| typedConfirmation |
Type : unknown
|
Default value : signal("")
|
|
what the user has typed into the confirmation input (if a keyword is required) |
import {
Component,
inject,
ChangeDetectionStrategy,
signal,
computed,
} from "@angular/core";
import {
MAT_DIALOG_DATA,
MatDialogModule,
MatDialogRef,
} from "@angular/material/dialog";
import { DialogCloseComponent } from "../../dialog-close/dialog-close.component";
import { MatButtonModule } from "@angular/material/button";
import { MatFormFieldModule } from "@angular/material/form-field";
import { MatInputModule } from "@angular/material/input";
import { MarkdownComponent } from "ngx-markdown";
/**
* A configurable confirmation dialog box
* used by the {@link ConfirmationDialogService}.
*/
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "app-confirmation-dialog",
templateUrl: "./confirmation-dialog.component.html",
styleUrl: "./confirmation-dialog.component.scss",
imports: [
DialogCloseComponent,
MatDialogModule,
MatButtonModule,
MatFormFieldModule,
MatInputModule,
MarkdownComponent,
],
})
export class ConfirmationDialogComponent {
dialogRef = inject<MatDialogRef<ConfirmationDialogComponent>>(MatDialogRef);
data = inject<ConfirmationDialogConfig>(MAT_DIALOG_DATA);
/** what the user has typed into the confirmation input (if a keyword is required) */
typedConfirmation = signal("");
/** whether the required keyword has been entered correctly */
private readonly keywordEntered = computed(() => {
const keyword = this.data.confirmationKeyword;
return (
!keyword ||
this.typedConfirmation().trim().toLowerCase() === keyword.toLowerCase()
);
});
/**
* Confirming buttons stay disabled until the required keyword has been typed,
* while buttons that abort the action (e.g. "Cancel") remain available.
*/
isBlocked(button: ConfirmationDialogButton): boolean {
return !!button.dialogResult && !this.keywordEntered();
}
}
/**
* Options to configure the {@link ConfirmationDialogComponent}.
*/
export interface ConfirmationDialogConfig {
/** title of the dialog box */
title: string;
/** description text in the dialog box */
text: string;
/** The buttons that should be displayed */
buttons: ConfirmationDialogButton[];
/** Whether or not to specify a 'close' icon-button.
* This button is on the top-right of the dialog and closes it with no result
*/
closeButton?: boolean;
/**
* If set, the user has to type this keyword into an input field
* before the confirming buttons become available.
*
* Use this as an additional safeguard for critical, irreversible actions.
*/
confirmationKeyword?: string;
}
/**
* The keyword a user has to type to confirm an action that deletes data irreversibly.
*/
export const DELETE_CONFIRMATION_KEYWORD = $localize`:Keyword to be typed by the user to confirm deleting data:delete`;
export interface ConfirmationDialogButton {
text: string;
dialogResult?: boolean | string | undefined;
click();
}
export const OkButton: ConfirmationDialogButton[] = [
{
text: $localize`:Confirmation dialog OK:OK`,
click() {
// Intentionally blank
// To react to emissions from this button, use the `MatDialogRef.beforeClosed()` hook
},
dialogResult: true,
},
];
export const YesNoButtons: ConfirmationDialogButton[] = [
{
text: $localize`:Confirmation dialog Yes:Yes`,
click() {
// Intentionally blank
// To react to emissions from this button, use the `MatDialogRef.beforeClosed()` hook
},
dialogResult: true,
},
{
text: $localize`:Confirmation dialog No:No`,
click() {
// Intentionally blank
// To react to emissions from this button, use the `MatDialogRef.beforeClosed()` hook
},
dialogResult: false,
},
];
export const YesNoCancelButtons: ConfirmationDialogButton[] = [
{
text: $localize`:Confirmation dialog Yes:Yes`,
click() {
// Intentionally blank
// To react to emissions from this button, use the `MatDialogRef.beforeClosed()` hook
},
dialogResult: true,
},
{
text: $localize`:Confirmation dialog No:No`,
click() {
// Intentionally blank
// To react to emissions from this button, use the `MatDialogRef.beforeClosed()` hook
},
dialogResult: false,
},
{
text: $localize`:Confirmation dialog Cancel:Cancel`,
click() {
// Intentionally blank
// To react to emissions from this button, use the `MatDialogRef.beforeClosed()` hook
},
dialogResult: undefined,
},
];
export function CustomYesNoButtons(
yesLabel: string,
noLabel: string,
): ConfirmationDialogButton[] {
return [
{ text: yesLabel, dialogResult: true, click() {} },
{ text: noLabel, dialogResult: false, click() {} },
];
}
<h1 mat-dialog-title>
{{ data.title }}
@if (data.closeButton) {
<app-dialog-close mat-dialog-close></app-dialog-close>
}
</h1>
<div mat-dialog-content>
<markdown>{{ data.text }}</markdown>
@if (data.confirmationKeyword) {
<mat-form-field class="full-width">
<mat-label i18n="Label of the input to confirm a critical action"
>Type "{{ data.confirmationKeyword }}" to confirm</mat-label
>
<input
#confirmationInput
matInput
cdkFocusInitial
autocomplete="off"
[value]="typedConfirmation()"
(input)="typedConfirmation.set(confirmationInput.value)"
/>
</mat-form-field>
}
</div>
<div mat-dialog-actions>
@for (button of data.buttons; track button.text) {
<button
mat-stroked-button
[disabled]="isBlocked(button)"
(click)="button.click()"
[mat-dialog-close]="button.dialogResult"
>
{{ button.text }}
</button>
}
</div>
./confirmation-dialog.component.scss