src/app/core/common-components/confirmation-dialog/confirmation-dialog/confirmation-dialog.component.ts

Description

A configurable confirmation dialog box used by the ConfirmationDialogService.

Example

Metadata

Relationships

Used by

No results matching.

Depends on

  • DialogCloseComponent
  • MatDialogModule
  • MatButtonModule
  • MatFormFieldModule
  • MatInputModule
  • MarkdownComponent

Index

Properties
Methods

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 :
Name Type Optional
button ConfirmationDialogButton No
Returns : boolean

Properties

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

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""