Confirmation dialog
This commit is contained in:
parent
5eda852e94
commit
01dff98820
@ -5,7 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { SortByPipe } from './sorting';
|
||||
import { HumanizePipe } from './utils';
|
||||
import { StatusBarComponent } from './misc';
|
||||
import { ConfirmationDialogComponent, HiddenActionComponent, LogoComponent, StatusBarComponent } from './misc';
|
||||
import { FullPageLoadingIndicatorComponent } from './loading';
|
||||
import { FullPageErrorComponent } from './error';
|
||||
import { IqserListingModule } from './listing';
|
||||
@ -17,10 +17,10 @@ import { IqserButtonsModule } from './buttons';
|
||||
import { IqserScrollbarModule } from './scrollbar';
|
||||
import { IqserEmptyStatesModule } from './empty-states';
|
||||
import { LogPipe } from './utils/pipes/log.pipe';
|
||||
import { LogoComponent } from './misc/logo/logo.component';
|
||||
import { HiddenActionComponent } from './misc/hidden-action/hidden-action.component';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
|
||||
const matModules = [MatIconModule, MatProgressSpinnerModule];
|
||||
const matModules = [MatIconModule, MatProgressSpinnerModule, MatButtonModule];
|
||||
const modules = [
|
||||
TranslateModule,
|
||||
IqserIconsModule,
|
||||
@ -32,12 +32,19 @@ const modules = [
|
||||
IqserScrollbarModule,
|
||||
IqserEmptyStatesModule
|
||||
];
|
||||
const components = [StatusBarComponent, FullPageLoadingIndicatorComponent, FullPageErrorComponent, LogoComponent, HiddenActionComponent];
|
||||
const components = [
|
||||
StatusBarComponent,
|
||||
FullPageLoadingIndicatorComponent,
|
||||
FullPageErrorComponent,
|
||||
LogoComponent,
|
||||
HiddenActionComponent,
|
||||
ConfirmationDialogComponent
|
||||
];
|
||||
const pipes = [SortByPipe, HumanizePipe];
|
||||
|
||||
@NgModule({
|
||||
declarations: [...components, ...pipes, LogPipe],
|
||||
imports: [CommonModule, ...matModules, ...modules],
|
||||
imports: [CommonModule, ...matModules, ...modules, FormsModule, ReactiveFormsModule],
|
||||
exports: [...components, ...pipes, ...modules, LogPipe]
|
||||
})
|
||||
export class CommonUiModule {}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
<section class="dialog">
|
||||
<div [class.primary]="isDeleteAction" class="dialog-header heading-l">
|
||||
{{ config.title }}
|
||||
</div>
|
||||
|
||||
<div class="dialog-content">
|
||||
<p [class.heading]="isDeleteAction" [innerHTML]="config.question" class="mt-0 mb-8"></p>
|
||||
<p *ngIf="config.details" [innerHTML]="config.details" class="mt-0"></p>
|
||||
|
||||
<div *ngIf="config.requireInput" class="iqser-input-group required w-300 mt-24">
|
||||
<label>{{ inputLabel }}</label>
|
||||
<input [(ngModel)]="inputValue" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dialog-actions">
|
||||
<button (click)="confirm(1)" [disabled]="config.requireInput && confirmationDoesNotMatch()" color="primary" mat-flat-button>
|
||||
{{ config.confirmationText }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
(click)="confirm(2)"
|
||||
[disabled]="config.requireInput && confirmationDoesNotMatch()"
|
||||
color="primary"
|
||||
mat-flat-button
|
||||
*ngIf="config.alternativeConfirmationText"
|
||||
>
|
||||
{{ config.alternativeConfirmationText }}
|
||||
</button>
|
||||
|
||||
<div (click)="deny()" class="all-caps-label cancel">
|
||||
{{ config.denyText }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<iqser-circle-button class="dialog-close" icon="iqser:close" mat-dialog-close></iqser-circle-button>
|
||||
</section>
|
||||
@ -0,0 +1,98 @@
|
||||
import { ChangeDetectionStrategy, Component, HostListener, Inject } 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' | 'primary';
|
||||
|
||||
export enum TitleColors {
|
||||
DEFAULT = 'default',
|
||||
PRIMARY = 'primary'
|
||||
}
|
||||
|
||||
export class ConfirmationDialogInput {
|
||||
title?: string;
|
||||
titleColor?: TitleColor;
|
||||
question?: string;
|
||||
details?: string;
|
||||
confirmationText?: string;
|
||||
alternativeConfirmationText?: string;
|
||||
requireInput?: boolean;
|
||||
denyText?: string;
|
||||
translateParams?: Record<string, unknown>;
|
||||
|
||||
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.requireInput = options?.requireInput || false;
|
||||
this.denyText = options?.denyText || _('common.confirmation-dialog.deny');
|
||||
this.translateParams = options?.translateParams || {};
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: './confirmation-dialog.component.html',
|
||||
styleUrls: ['./confirmation-dialog.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ConfirmationDialogComponent {
|
||||
config: ConfirmationDialogInput;
|
||||
inputValue = '';
|
||||
readonly inputLabel: string;
|
||||
|
||||
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') as string} '${
|
||||
this.config.confirmationText as string
|
||||
}'`;
|
||||
}
|
||||
|
||||
get isDeleteAction(): boolean {
|
||||
return this.config?.titleColor === TitleColors.PRIMARY;
|
||||
}
|
||||
|
||||
@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: number): void {
|
||||
this._dialogRef.close(option);
|
||||
}
|
||||
|
||||
translate(obj: ConfirmationDialogInput): void {
|
||||
const translateKeys: (keyof typeof obj)[] = [
|
||||
'title',
|
||||
'question',
|
||||
'details',
|
||||
'confirmationText',
|
||||
'alternativeConfirmationText',
|
||||
'denyText'
|
||||
];
|
||||
|
||||
translateKeys
|
||||
.filter(key => !!obj[key])
|
||||
.forEach(key => {
|
||||
Object.assign(obj, { [key]: this._translateService.instant(obj[key] as string, this.config.translateParams) as string });
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,5 @@
|
||||
export * from './status-bar/status-bar.component';
|
||||
export * from './status-bar/status-bar-config.model';
|
||||
export * from './logo/logo.component';
|
||||
export * from './confirmation-dialog/confirmation-dialog.component';
|
||||
export * from './hidden-action/hidden-action.component';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user