diff --git a/src/lib/common-ui.module.ts b/src/lib/common-ui.module.ts index ea17ad9..3a0a1d3 100644 --- a/src/lib/common-ui.module.ts +++ b/src/lib/common-ui.module.ts @@ -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 {} diff --git a/src/lib/misc/confirmation-dialog/confirmation-dialog.component.html b/src/lib/misc/confirmation-dialog/confirmation-dialog.component.html new file mode 100644 index 0000000..c9bc3df --- /dev/null +++ b/src/lib/misc/confirmation-dialog/confirmation-dialog.component.html @@ -0,0 +1,37 @@ +
+
+ {{ config.title }} +
+ +
+

+

+ +
+ + +
+
+ +
+ + + + +
+ {{ config.denyText }} +
+
+ + +
diff --git a/src/lib/misc/confirmation-dialog/confirmation-dialog.component.scss b/src/lib/misc/confirmation-dialog/confirmation-dialog.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/misc/confirmation-dialog/confirmation-dialog.component.ts b/src/lib/misc/confirmation-dialog/confirmation-dialog.component.ts new file mode 100644 index 0000000..c32b62e --- /dev/null +++ b/src/lib/misc/confirmation-dialog/confirmation-dialog.component.ts @@ -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; + + 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, + 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 }); + }); + } +} diff --git a/src/lib/misc/index.ts b/src/lib/misc/index.ts index 7a0605c..353f04e 100644 --- a/src/lib/misc/index.ts +++ b/src/lib/misc/index.ts @@ -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';