Skip to content

Commit

Permalink
feat(common): enhance dialog components (select, checkbox, form based)
Browse files Browse the repository at this point in the history
* fix(common): json dialog service with undefined ignorekeys

* feat(common): add a dialog to select values

* wip

* feat(common): enhance the confirm dialog with a yes no option

* feat(common): form field, allow multiple selections

* feat(common): add a dialog to select value from a scrolling list

* feat(common): add a dialog to select value from checkboxes or radio

* wip

* wip

* feat(common): enhance text field to handle password type

* feat(common): add a dialog based on igo-form

* feat(demo): add a dialog example section

* chore(common): delete code, remplaced bu form-dialog component

* chore(demo): merge conflicts resolution

* chore(common): changes based on review comments

* chore(common): review comments

* wip

* wip

* chore(common): confirm dialog optional options now have an interface

* chore(form-dialog): css ng-deep removal (review comment)

* chore(common): form-dialog optional options now have an interface

* chore(common): form dialog data is now mandatory

* chore(common): form dialog, use a behaviorSubject to handle field content

* chore(common): select value review comments

* chore(common): form-dialog reviews

* chore(common): add select-value-dialog dialog options

* chore(demo): changes based on review

* chore(common): form field text icon to icon-button

* wip
  • Loading branch information
pelord authored Dec 4, 2023
1 parent 9dd59a8 commit 52d7ace
Show file tree
Hide file tree
Showing 39 changed files with 889 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
<h2 mat-dialog-title class="mat-typography">
{{ 'igo.common.confirmDialog.title' | translate }}
{{ titleKey | translate }}
</h2>
<div mat-dialog-content class="mat-typography">{{ confirmMessage }}</div>
<div mat-dialog-content class="mat-typography">
{{ confirmMessage | translate }}
</div>
<div mat-dialog-actions>
<button mat-button color="primary" (click)="dialogRef.close(true)">
{{ 'igo.common.confirmDialog.confirmBtn' | translate }}
<button mat-raised-button color="primary" (click)="dialogRef.close(true)">
{{ proccessKey | translate }}
</button>
<button mat-button (click)="dialogRef.close(false)">
{{ 'igo.common.confirmDialog.cancelBtn' | translate }}
<button mat-flat-button (click)="dialogRef.close(false)">
{{ cancelKey | translate }}
</button>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { MatDialogRef } from '@angular/material/dialog';
})
export class ConfirmDialogComponent {
public confirmMessage: string;
public titleKey: string = 'igo.common.confirmDialog.title';
public proccessKey: string = 'igo.common.confirmDialog.confirmBtn';
public cancelKey: string = 'igo.common.confirmDialog.cancelBtn';

constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ConfirmDialogOptions {
title?: string;
modeYesNo?: boolean;
}
27 changes: 17 additions & 10 deletions packages/common/src/lib/confirm-dialog/confirm-dialog.service.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';

import { LanguageService } from '@igo2/core';

import { Observable } from 'rxjs';

import { ConfirmDialogComponent } from './confirm-dialog.component';
import { ConfirmDialogOptions } from './confirm-dialog.interface';

@Injectable()
export class ConfirmDialogService {
constructor(
private dialog: MatDialog,
private languageService: LanguageService
) {}
constructor(private dialog: MatDialog) {}

public open(message: string): Observable<any> {
public open(
message: string,
options?: ConfirmDialogOptions
): Observable<boolean> {
const _options: ConfirmDialogOptions = {
title: 'igo.common.confirmDialog.title',
modeYesNo: false,
...options
};
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
disableClose: false
});
dialogRef.componentInstance.confirmMessage =
this.languageService.translate.instant(message);

dialogRef.componentInstance.confirmMessage = message;
dialogRef.componentInstance.titleKey = _options.title;
if (_options.modeYesNo) {
dialogRef.componentInstance.proccessKey = 'igo.common.confirmDialog.yes';
dialogRef.componentInstance.cancelKey = 'igo.common.confirmDialog.no';
}
return dialogRef.afterClosed();
}
}
1 change: 1 addition & 0 deletions packages/common/src/lib/confirm-dialog/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './confirm-dialog.component';
export * from './confirm-dialog.interface';
export * from './confirm-dialog.service';
35 changes: 35 additions & 0 deletions packages/common/src/lib/form-dialog/form-dialog.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<h1 mat-dialog-title>{{ data.title | translate }}</h1>

<igo-form
*ngIf="form$ | async as form"
[form]="form"
[formData]="data$ | async"
(submitForm)="onSubmit($event)"
>
<div *ngIf="form.fields.length" class="form-dialog-container">
<igo-form-field
*ngFor="let field of form.fields"
[field]="field"
></igo-form-field>
<igo-form-group
*ngFor="let group of form.groups"
[group]="group"
></igo-form-group>
</div>

<div formButtons mat-dialog-actions>
<button mat-stroked-button type="button" color="primary" (click)="cancel()">
{{ data.cancelButtonText | translate }}
</button>
<button mat-flat-button type="submit" color="primary">
{{ data.processButtonText | translate }}
</button>
</div>
</igo-form>
<div>
<igo-custom-html
*ngIf="data.notice && data.notice !== ''"
[html]="data.notice"
>
</igo-custom-html>
</div>
15 changes: 15 additions & 0 deletions packages/common/src/lib/form-dialog/form-dialog.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
:host {
div[mat-dialog-actions] {
margin: 10px 0 0 0;
}
.form-dialog-container {
width: 100%;
padding: 10px;

igo-form-field,
igo-form-group {
display: block;
height: auto;
}
}
}
81 changes: 81 additions & 0 deletions packages/common/src/lib/form-dialog/form-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';

import { LanguageService } from '@igo2/core';

import { BehaviorSubject } from 'rxjs';

import {
Form,
FormField,
FormFieldGroup,
FormFieldInputs
} from '../form/shared/form.interfaces';
import { FormService } from '../form/shared/form.service';
import { FormDialogData } from './form-dialog.interface';

@Component({
selector: 'igo-form-dialog',
templateUrl: './form-dialog.component.html',
styleUrls: ['./form-dialog.component.scss']
})
export class FormDialogComponent {
form$ = new BehaviorSubject<Form>(undefined);
data$ = new BehaviorSubject<{ [key: string]: any }>(undefined);
constructor(
public languageService: LanguageService,
public dialogRef: MatDialogRef<FormDialogComponent>,
private formService: FormService,
@Inject(MAT_DIALOG_DATA)
public data: FormDialogData
) {
this.data.processButtonText =
this.data.processButtonText ?? 'igo.common.formDialog.processButtonText';
this.data.cancelButtonText =
this.data.cancelButtonText ?? 'igo.common.formDialog.cancelButtonText';
this.data.title = this.data.title ?? 'igo.common.formDialog.title';
this.data$ = this.data.data$;

let fields: FormField<FormFieldInputs>[] = [];
let groups: FormFieldGroup[] = [];
this.data.formFieldConfigs?.map((config) =>
fields.push(this.formService.field(config))
);

this.data.formGroupsConfigs?.map((formGroupsConfig) => {
const fields = formGroupsConfig.formFieldConfigs?.map((config) =>
this.formService.field(config)
);
groups.push(
this.formService.group({ name: formGroupsConfig.name }, fields)
);
});
const form = this.formService.form(fields, groups);

this.form$.next(form);
}

onSubmit(data: { [key: string]: any }) {
const form = this.form$.getValue();
if (form.control.valid) {
this.dialogRef.close(data);
} else {
if (form.groups?.length) {
form.groups.map((group) => {
Object.keys(group.control.controls).map((k) => {
group.control.controls[k].markAsTouched();
group.control.controls[k].updateValueAndValidity();
});
});
} else {
form.fields.map((f) => {
f.control.markAsTouched();
f.control.updateValueAndValidity();
});
}
}
}
cancel() {
this.dialogRef.close();
}
}
23 changes: 23 additions & 0 deletions packages/common/src/lib/form-dialog/form-dialog.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MatDialogConfig } from '@angular/material/dialog';

import { BehaviorSubject } from 'rxjs';

import {
FormFieldConfig,
FormGroupsConfig
} from '../form/shared/form.interfaces';

export interface FormDialogFormConfig {
formFieldConfigs?: FormFieldConfig[];
formGroupsConfigs?: FormGroupsConfig[];
}
export interface FormDialogData
extends FormDialogOptions,
FormDialogFormConfig {}
export interface FormDialogOptions extends MatDialogConfig {
data$?: BehaviorSubject<{ [key: string]: any }>;
title?: string;
processButtonText?: string;
cancelButtonText?: string;
notice?: string;
}
35 changes: 35 additions & 0 deletions packages/common/src/lib/form-dialog/form-dialog.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { CommonModule } from '@angular/common';
import { ModuleWithProviders, NgModule } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';

import { IgoLanguageModule } from '@igo2/core';

import { IgoCustomHtmlModule } from '../custom-html/custom-html.module';
import { IgoFormModule } from '../form/form.module';
import { FormDialogComponent } from './form-dialog.component';
import { FormDialogService } from './form-dialog.service';

@NgModule({
imports: [
CommonModule,
MatButtonModule,
MatDialogModule,
IgoCustomHtmlModule,
IgoLanguageModule,
IgoFormModule,
MatDividerModule
],
declarations: [FormDialogComponent],
exports: [FormDialogComponent],
providers: [FormDialogService]
})
export class IgoFormDialogModule {
static forRoot(): ModuleWithProviders<IgoFormDialogModule> {
return {
ngModule: IgoFormDialogModule,
providers: []
};
}
}
33 changes: 33 additions & 0 deletions packages/common/src/lib/form-dialog/form-dialog.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';

import { Observable } from 'rxjs';

import { FormDialogComponent } from './form-dialog.component';
import {
FormDialogData,
FormDialogFormConfig,
FormDialogOptions
} from './form-dialog.interface';

@Injectable()
export class FormDialogService {
constructor(private dialog: MatDialog) {}

public open(
formDialogConfig?: FormDialogFormConfig,
options?: FormDialogOptions
): Observable<{ [key: string]: any }> {
const data: FormDialogData = {
formFieldConfigs: formDialogConfig.formFieldConfigs,
formGroupsConfigs: formDialogConfig.formGroupsConfigs,
...options
};
const dialogRef = this.dialog.open(FormDialogComponent, {
disableClose: false,
data,
...options
});
return dialogRef.afterClosed();
}
}
3 changes: 3 additions & 0 deletions packages/common/src/lib/form-dialog/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './form-dialog.component';
export * from './form-dialog.interface';
export * from './form-dialog.service';
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<mat-form-field>
<mat-select
[multiple]="multiple"
[required]="required"
[placeholder]="placeholder"
[formControl]="formControl"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export class FormFieldSelectComponent implements OnInit {
readonly choices$: BehaviorSubject<FormFieldSelectChoice[]> =
new BehaviorSubject([]);

/**
* If the select allow multiple selections
*/
@Input() multiple: boolean = false;

/**
* The field's form control
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<mat-form-field>
<input
matInput
[required]="required"
(blur)="hide = true"
[type]="isPassword ? (hide ? 'password' : 'text') : 'text'"
[required]="isPassword ? 'true' : required"
[placeholder]="placeholder"
[formControl]="formControl"
/>
Expand All @@ -17,6 +19,16 @@
matPrefix
>
</mat-icon>

<button
*ngIf="isPassword"
matSuffix
mat-icon-button
(click)="togglePassword()"
>
<mat-icon color="primary" [svgIcon]="hide ? 'eye-off' : 'eye'"></mat-icon>
</button>

<mat-error *ngIf="formControl.errors">{{
getErrorMessage() | translate
}}</mat-error>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
})
export class FormFieldTextComponent implements OnInit {
disabled$: BehaviorSubject<boolean> = new BehaviorSubject(false);

hide: boolean = true;
/**
* The field's form control
*/
Expand All @@ -36,6 +36,11 @@ export class FormFieldTextComponent implements OnInit {
*/
@Input() placeholder: string;

/**
* if the input is a password
*/
@Input() isPassword: boolean;

/**
* Field placeholder
*/
Expand Down Expand Up @@ -77,4 +82,8 @@ export class FormFieldTextComponent implements OnInit {
}
this.disabled$.next(disabled);
}

togglePassword() {
this.hide = !this.hide;
}
}
Loading

0 comments on commit 52d7ace

Please sign in to comment.