RED-9578: added support for custom component and reversing buttons.

This commit is contained in:
Nicoleta Panaghiu 2024-09-19 14:52:04 +03:00
parent c644eaeba2
commit c71a4995a6
3 changed files with 76 additions and 26 deletions

View File

@ -16,6 +16,10 @@
<p [innerHTML]="config.details" class="mt-0"></p>
}
@if (config.component) {
<ng-container #detailsComponent></ng-container>
}
@if (config.requireInput) {
<div class="iqser-input-group required w-300 mt-24">
<label>{{ inputLabel }}</label>
@ -35,14 +39,20 @@
}
</div>
<div class="dialog-actions">
<iqser-icon-button
(action)="confirm(confirmOption)"
[disabled]="(config.requireInput && confirmationDoesNotMatch()) || config.disableConfirm"
[label]="config.confirmationText"
[type]="iconButtonTypes.primary"
buttonId="confirm"
></iqser-icon-button>
<div class="dialog-actions" [class.reverse]="config.cancelButtonPrimary">
@if (!config.cancelButtonPrimary) {
<iqser-icon-button
(action)="confirm(confirmOption)"
[disabled]="(config.requireInput && confirmationDoesNotMatch()) || config.disableConfirm"
[label]="config.confirmationText"
[type]="iconButtonTypes.primary"
buttonId="confirm"
></iqser-icon-button>
} @else {
<div (click)="confirm(confirmOption)" class="all-caps-label cancel no-uppercase" id="confirm">
{{ config.confirmationText }}
</div>
}
@if (config.alternativeConfirmationText) {
<iqser-icon-button
@ -60,9 +70,13 @@
}
@if (!config.discardChangesText) {
<div (click)="deny()" class="all-caps-label cancel">
{{ config.denyText }}
</div>
@if (config.cancelButtonPrimary) {
<iqser-icon-button (click)="deny()" [label]="config.denyText" [type]="iconButtonTypes.primary"></iqser-icon-button>
} @else {
<div (click)="deny()" class="all-caps-label cancel">
{{ config.denyText }}
</div>
}
}
</div>

View File

@ -6,3 +6,12 @@
display: flex;
flex-direction: column;
}
.reverse {
flex-direction: row-reverse;
justify-content: flex-end;
}
.no-uppercase {
text-transform: unset;
}

View File

@ -1,15 +1,24 @@
import { NgTemplateOutlet } from '@angular/common';
import { ChangeDetectionStrategy, Component, HostListener, inject, TemplateRef } from '@angular/core';
import { NgClass, NgTemplateOutlet } from '@angular/common';
import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
HostListener,
inject,
TemplateRef,
Type,
viewChild,
ViewContainerRef,
} from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { CircleButtonComponent } from '../../buttons/circle-button/circle-button.component';
import { IconButtonComponent } from '../../buttons/icon-button/icon-button.component';
import { IconButtonTypes } from '../../buttons/types/icon-button.type';
import { ValuesOf } from '../../utils/types/utility-types';
import { CircleButtonComponent, IconButtonTypes } from '../../buttons';
import { IconButtonComponent } from '../../buttons';
import { ValuesOf } from '../../utils';
export const TitleColors = {
DEFAULT: 'default',
@ -48,6 +57,9 @@ interface InternalConfirmationDialogData {
readonly checkboxes: CheckBox[];
readonly checkboxesValidation: boolean;
readonly toastMessage?: string;
readonly component?: Type<unknown>;
readonly componentInputs?: { [key: string]: unknown };
readonly cancelButtonPrimary?: boolean;
}
export type IConfirmationDialogData = Partial<InternalConfirmationDialogData>;
@ -65,6 +77,9 @@ function getConfig(options?: IConfirmationDialogData): InternalConfirmationDialo
denyText: options?.denyText ?? _('common.confirmation-dialog.deny'),
checkboxes: options?.checkboxes ?? [],
checkboxesValidation: typeof options?.checkboxesValidation === 'boolean' ? options.checkboxesValidation : true,
component: options?.component,
componentInputs: options?.componentInputs,
cancelButtonPrimary: options?.cancelButtonPrimary ?? false,
};
}
@ -82,15 +97,17 @@ function getConfig(options?: IConfirmationDialogData): InternalConfirmationDialo
IconButtonComponent,
CircleButtonComponent,
MatDialogModule,
NgClass,
],
})
export class ConfirmationDialogComponent {
export class ConfirmationDialogComponent implements AfterViewInit {
readonly config = getConfig(inject(MAT_DIALOG_DATA));
inputValue = '';
showToast = false;
readonly inputLabel: string;
readonly confirmOptions = ConfirmOptions;
readonly iconButtonTypes = IconButtonTypes;
readonly detailsComponentRef = viewChild.required('detailsComponent', { read: ViewContainerRef });
constructor(
private readonly _dialogRef: MatDialogRef<ConfirmationDialogComponent, ConfirmOption>,
@ -115,13 +132,19 @@ export class ConfirmationDialogComponent {
return ConfirmOptions.CONFIRM;
}
@HostListener('window:keyup.enter')
onKeyupEnter(): void {
if (this.config.requireInput && !this.confirmationDoesNotMatch()) {
this.confirm(ConfirmOptions.CONFIRM);
@HostListener('window:keyup.enter', ['$event'])
onKeyupEnter(event: KeyboardEvent): void {
event?.stopImmediatePropagation();
if (!this.config.requireInput || !this.confirmationDoesNotMatch()) {
if (!this.config.cancelButtonPrimary) this.confirm(ConfirmOptions.CONFIRM);
else this.deny();
}
}
ngAfterViewInit() {
this.#initializeDetailsComponent();
}
confirmationDoesNotMatch(): boolean {
return this.inputValue.toLowerCase() !== this.config.confirmationText.toLowerCase();
}
@ -156,9 +179,13 @@ export class ConfirmationDialogComponent {
});
}
@HostListener('window:keydown.Enter', ['$event'])
onEnter(event: KeyboardEvent): void {
event?.stopImmediatePropagation();
this.confirm(ConfirmOptions.CONFIRM);
#initializeDetailsComponent() {
if (!this.config.component) return;
const component = this.detailsComponentRef().createComponent(this.config.component);
if (this.config.componentInputs) {
for (const [key, value] of Object.entries(this.config.componentInputs)) {
(component.instance as any)[key] = value;
}
}
}
}