131 lines
4.3 KiB
TypeScript
131 lines
4.3 KiB
TypeScript
import { ChangeDetectionStrategy, Component, HostListener, Inject, TemplateRef } from '@angular/core';
|
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|
import { TranslateService } from '@ngx-translate/core';
|
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
|
|
|
|
export type TitleColor = 'default' | 'warn';
|
|
|
|
export enum TitleColors {
|
|
DEFAULT = 'default',
|
|
WARN = 'warn',
|
|
}
|
|
|
|
export enum ConfirmOptions {
|
|
CONFIRM = 1,
|
|
SECOND_CONFIRM = 2,
|
|
DISCARD_CHANGES = 3,
|
|
}
|
|
|
|
interface CheckBox {
|
|
value: boolean;
|
|
label: string;
|
|
extraContent?: TemplateRef<unknown>;
|
|
extraContentData?: Record<string, unknown>;
|
|
}
|
|
|
|
export class ConfirmationDialogInput {
|
|
title?: string;
|
|
titleColor?: TitleColor;
|
|
question?: string;
|
|
details?: string;
|
|
confirmationText?: string;
|
|
alternativeConfirmationText?: string;
|
|
discardChangesText?: string;
|
|
requireInput?: boolean;
|
|
disableConfirm?: boolean;
|
|
denyText?: string;
|
|
translateParams?: Record<string, unknown>;
|
|
checkboxes?: CheckBox[];
|
|
toastMessage?: string;
|
|
|
|
constructor(options?: ConfirmationDialogInput) {
|
|
this.title = options?.title || _('common.confirmation-dialog.title');
|
|
this.titleColor = options?.titleColor || TitleColors.DEFAULT;
|
|
this.question = options?.question || _('common.confirmation-dialog.description');
|
|
this.details = options?.details || '';
|
|
this.confirmationText = options?.confirmationText || _('common.confirmation-dialog.confirm');
|
|
this.alternativeConfirmationText = options?.alternativeConfirmationText;
|
|
this.discardChangesText = options?.discardChangesText;
|
|
this.requireInput = options?.requireInput || false;
|
|
this.disableConfirm = options?.disableConfirm || false;
|
|
this.denyText = options?.denyText || _('common.confirmation-dialog.deny');
|
|
this.translateParams = options?.translateParams || {};
|
|
this.checkboxes = options?.checkboxes || [];
|
|
this.toastMessage = options?.toastMessage;
|
|
}
|
|
}
|
|
|
|
@Component({
|
|
templateUrl: './confirmation-dialog.component.html',
|
|
styleUrls: ['./confirmation-dialog.component.scss'],
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
})
|
|
export class ConfirmationDialogComponent {
|
|
config: ConfirmationDialogInput;
|
|
inputValue = '';
|
|
showToast = false;
|
|
readonly inputLabel: string;
|
|
readonly ConfirmOptions = ConfirmOptions;
|
|
|
|
constructor(
|
|
private readonly _dialogRef: MatDialogRef<ConfirmationDialogComponent>,
|
|
private readonly _translateService: TranslateService,
|
|
@Inject(MAT_DIALOG_DATA) private readonly _confirmationDialogInput: ConfirmationDialogInput,
|
|
) {
|
|
this.config = _confirmationDialogInput ?? new ConfirmationDialogInput();
|
|
this.translate(this.config);
|
|
this.inputLabel = `${this._translateService.instant('confirmation-dialog.input-label')} '${this.config.confirmationText || ''}'`;
|
|
}
|
|
|
|
get uncheckedBoxes(): boolean {
|
|
return !!this.config.checkboxes?.some(c => !c.value);
|
|
}
|
|
|
|
get isDeleteAction(): boolean {
|
|
return this.config?.titleColor === TitleColors.WARN;
|
|
}
|
|
|
|
@HostListener('window:keyup.enter')
|
|
onKeyupEnter(): void {
|
|
if (this.config.requireInput && !this.confirmationDoesNotMatch()) {
|
|
this.confirm(1);
|
|
}
|
|
}
|
|
|
|
confirmationDoesNotMatch(): boolean {
|
|
return this.inputValue.toLowerCase() !== this.config.confirmationText?.toLowerCase();
|
|
}
|
|
|
|
deny(): void {
|
|
this._dialogRef.close();
|
|
}
|
|
|
|
confirm(option: ConfirmOptions): void {
|
|
if (this.uncheckedBoxes) {
|
|
this.showToast = true;
|
|
} else {
|
|
this._dialogRef.close(option);
|
|
}
|
|
}
|
|
|
|
translate(obj: ConfirmationDialogInput): void {
|
|
const translateKeys: (keyof typeof obj)[] = [
|
|
'title',
|
|
'question',
|
|
'details',
|
|
'confirmationText',
|
|
'alternativeConfirmationText',
|
|
'discardChangesText',
|
|
'denyText',
|
|
];
|
|
|
|
translateKeys
|
|
.filter(key => !!obj[key])
|
|
.forEach(key => {
|
|
Object.assign(obj, {
|
|
[key]: this._translateService.instant(obj[key] as string, this.config.translateParams) as string,
|
|
});
|
|
});
|
|
}
|
|
}
|