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 { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||||
import { SortByPipe } from './sorting';
|
import { SortByPipe } from './sorting';
|
||||||
import { HumanizePipe } from './utils';
|
import { HumanizePipe } from './utils';
|
||||||
import { StatusBarComponent } from './misc';
|
import { ConfirmationDialogComponent, HiddenActionComponent, LogoComponent, StatusBarComponent } from './misc';
|
||||||
import { FullPageLoadingIndicatorComponent } from './loading';
|
import { FullPageLoadingIndicatorComponent } from './loading';
|
||||||
import { FullPageErrorComponent } from './error';
|
import { FullPageErrorComponent } from './error';
|
||||||
import { IqserListingModule } from './listing';
|
import { IqserListingModule } from './listing';
|
||||||
@ -17,10 +17,10 @@ import { IqserButtonsModule } from './buttons';
|
|||||||
import { IqserScrollbarModule } from './scrollbar';
|
import { IqserScrollbarModule } from './scrollbar';
|
||||||
import { IqserEmptyStatesModule } from './empty-states';
|
import { IqserEmptyStatesModule } from './empty-states';
|
||||||
import { LogPipe } from './utils/pipes/log.pipe';
|
import { LogPipe } from './utils/pipes/log.pipe';
|
||||||
import { LogoComponent } from './misc/logo/logo.component';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { HiddenActionComponent } from './misc/hidden-action/hidden-action.component';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
|
||||||
const matModules = [MatIconModule, MatProgressSpinnerModule];
|
const matModules = [MatIconModule, MatProgressSpinnerModule, MatButtonModule];
|
||||||
const modules = [
|
const modules = [
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
IqserIconsModule,
|
IqserIconsModule,
|
||||||
@ -32,12 +32,19 @@ const modules = [
|
|||||||
IqserScrollbarModule,
|
IqserScrollbarModule,
|
||||||
IqserEmptyStatesModule
|
IqserEmptyStatesModule
|
||||||
];
|
];
|
||||||
const components = [StatusBarComponent, FullPageLoadingIndicatorComponent, FullPageErrorComponent, LogoComponent, HiddenActionComponent];
|
const components = [
|
||||||
|
StatusBarComponent,
|
||||||
|
FullPageLoadingIndicatorComponent,
|
||||||
|
FullPageErrorComponent,
|
||||||
|
LogoComponent,
|
||||||
|
HiddenActionComponent,
|
||||||
|
ConfirmationDialogComponent
|
||||||
|
];
|
||||||
const pipes = [SortByPipe, HumanizePipe];
|
const pipes = [SortByPipe, HumanizePipe];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [...components, ...pipes, LogPipe],
|
declarations: [...components, ...pipes, LogPipe],
|
||||||
imports: [CommonModule, ...matModules, ...modules],
|
imports: [CommonModule, ...matModules, ...modules, FormsModule, ReactiveFormsModule],
|
||||||
exports: [...components, ...pipes, ...modules, LogPipe]
|
exports: [...components, ...pipes, ...modules, LogPipe]
|
||||||
})
|
})
|
||||||
export class CommonUiModule {}
|
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.component';
|
||||||
export * from './status-bar/status-bar-config.model';
|
export * from './status-bar/status-bar-config.model';
|
||||||
export * from './logo/logo.component';
|
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