diff --git a/src/app/shared/form-dialog/form-dialog.component.html b/src/app/shared/form-dialog/form-dialog.component.html new file mode 100644 index 000000000..b753bbcb4 --- /dev/null +++ b/src/app/shared/form-dialog/form-dialog.component.html @@ -0,0 +1,14 @@ +

{{ data.title }}

+ +
+ +
+ +
+ +
+ + + + + diff --git a/src/app/shared/form-dialog/form-dialog.component.scss b/src/app/shared/form-dialog/form-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shared/form-dialog/form-dialog.component.spec.ts b/src/app/shared/form-dialog/form-dialog.component.spec.ts new file mode 100644 index 000000000..6a3fc0058 --- /dev/null +++ b/src/app/shared/form-dialog/form-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FormDialogComponent } from './form-dialog.component'; + +describe('FormDialogComponent', () => { + let component: FormDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FormDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FormDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/form-dialog/form-dialog.component.ts b/src/app/shared/form-dialog/form-dialog.component.ts new file mode 100644 index 000000000..fc276d242 --- /dev/null +++ b/src/app/shared/form-dialog/form-dialog.component.ts @@ -0,0 +1,51 @@ +import { Component, OnInit, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { FormGroup } from '@angular/forms'; + +import { FormfieldBase } from './formfield/model/formfield-base'; + +import { FormGroupService } from './form-group.service'; + +const layoutGap = 2; + +@Component({ + selector: 'mifosx-form-dialog', + templateUrl: './form-dialog.component.html', + styleUrls: ['./form-dialog.component.scss'] +}) +export class FormDialogComponent implements OnInit { + + layout: { + columns: number, + columnWidth?: number, + flex?: number, + gap?: number, + cancelButtonText?: string, + addButtonText?: string + } = { + columns: 1, + columnWidth: 400, + flex: 100, + cancelButtonText: 'Cancel', + addButtonText: 'Add' + }; + + form: FormGroup; + formfields: FormfieldBase[]; + + constructor(public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any, + private formGroupService: FormGroupService) { + this.dialogRef.disableClose = !data.disableClose; + this.formfields = data.formfields.sort((formfieldA: FormfieldBase, formfieldB: FormfieldBase) => formfieldA.order - formfieldB.order); + this.layout = { ...this.layout, ...data.layout }; + this.layout.gap = this.layout.columns > 1 ? layoutGap : 0; + this.layout.flex = (this.layout.flex / this.layout.columns) - this.layout.gap; + } + + ngOnInit() { + this.dialogRef.updateSize(`${this.layout.columnWidth * this.layout.columns}px`); + this.form = this.formGroupService.createFormGroup(this.formfields); + } + +} diff --git a/src/app/shared/form-dialog/form-group.service.spec.ts b/src/app/shared/form-dialog/form-group.service.spec.ts new file mode 100644 index 000000000..f99cfddb5 --- /dev/null +++ b/src/app/shared/form-dialog/form-group.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { FormGroupService } from './form-group.service'; + +describe('FormGroupService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: FormGroupService = TestBed.get(FormGroupService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/shared/form-dialog/form-group.service.ts b/src/app/shared/form-dialog/form-group.service.ts new file mode 100644 index 000000000..175592f22 --- /dev/null +++ b/src/app/shared/form-dialog/form-group.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; + +import { FormfieldBase } from './formfield/model/formfield-base'; + +@Injectable({ + providedIn: 'root' +}) +export class FormGroupService { + + constructor() { } + + createFormGroup(formfields: FormfieldBase[]) { + const group: any = {}; + + formfields.forEach(formfield => { + group[formfield.controlName] = formfield.required ? new FormControl(formfield.value, Validators.required) : new FormControl(formfield.value); + }); + + return new FormGroup(group); + } + +} diff --git a/src/app/shared/form-dialog/formfield/formfield.component.html b/src/app/shared/form-dialog/formfield/formfield.component.html new file mode 100644 index 000000000..c2c96c7cd --- /dev/null +++ b/src/app/shared/form-dialog/formfield/formfield.component.html @@ -0,0 +1,25 @@ +
+ + + + {{ formfield.label }} + +
+ + + + + + {{ option[formfield.options.label] }} + + + +
+ + + {{ formfield.label }} is required + + +
+ +
diff --git a/src/app/shared/form-dialog/formfield/formfield.component.scss b/src/app/shared/form-dialog/formfield/formfield.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shared/form-dialog/formfield/formfield.component.spec.ts b/src/app/shared/form-dialog/formfield/formfield.component.spec.ts new file mode 100644 index 000000000..6c15a1935 --- /dev/null +++ b/src/app/shared/form-dialog/formfield/formfield.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FormfieldComponent } from './formfield.component'; + +describe('FormfieldComponent', () => { + let component: FormfieldComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ FormfieldComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FormfieldComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/form-dialog/formfield/formfield.component.ts b/src/app/shared/form-dialog/formfield/formfield.component.ts new file mode 100644 index 000000000..977f5b34a --- /dev/null +++ b/src/app/shared/form-dialog/formfield/formfield.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { FormGroup } from '@angular/forms'; + +import { FormfieldBase } from './model/formfield-base'; + +@Component({ + selector: 'mifosx-formfield', + templateUrl: './formfield.component.html', + styleUrls: ['./formfield.component.scss'] +}) +export class FormfieldComponent implements OnInit { + + @Input() form: FormGroup; + @Input() formfield: FormfieldBase; + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/shared/form-dialog/formfield/model/formfield-base.ts b/src/app/shared/form-dialog/formfield/model/formfield-base.ts new file mode 100644 index 000000000..4046e1ee0 --- /dev/null +++ b/src/app/shared/form-dialog/formfield/model/formfield-base.ts @@ -0,0 +1,26 @@ +export class FormfieldBase { + + controlType: string; + controlName: string; + label: string; + value: string; + required: boolean; + order: number; + + constructor(options: { + controlType?: string, + controlName?: string, + label?: string, + value?: string, + required?: boolean, + order?: number + } = {}) { + this.controlType = options.controlType || ''; + this.controlName = options.controlName || ''; + this.label = options.label || ''; + this.value = options.value || ''; + this.required = !!options.required; + this.order = options.order === undefined ? 1 : options.order; + } + +} diff --git a/src/app/shared/form-dialog/formfield/model/input-base.ts b/src/app/shared/form-dialog/formfield/model/input-base.ts new file mode 100644 index 000000000..bd73ae318 --- /dev/null +++ b/src/app/shared/form-dialog/formfield/model/input-base.ts @@ -0,0 +1,13 @@ +import { FormfieldBase } from './formfield-base'; + +export class InputBase extends FormfieldBase { + + controlType = 'input'; + type: string; + + constructor(options: any) { + super(options); + this.type = options['type'] || 'text'; + } + +} diff --git a/src/app/shared/form-dialog/formfield/model/select-base.ts b/src/app/shared/form-dialog/formfield/model/select-base.ts new file mode 100644 index 000000000..fae07d6fd --- /dev/null +++ b/src/app/shared/form-dialog/formfield/model/select-base.ts @@ -0,0 +1,17 @@ +import { FormfieldBase } from './formfield-base'; + +export class SelectBase extends FormfieldBase { + + controlType = 'select'; + options: { + label: string, + value: string, + data: {}[] + }; + + constructor(options: {} = {}) { + super(options); + this.options = options['options']; + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index e43e11951..aead29200 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -4,6 +4,8 @@ import { CommonModule } from '@angular/common'; import { ReactiveFormsModule, FormsModule } from '@angular/forms'; /** Custom Components */ +import { FormfieldComponent } from './form-dialog/formfield/formfield.component'; +import { FormDialogComponent } from './form-dialog/form-dialog.component'; import { DeleteDialogComponent } from './delete-dialog/delete-dialog.component'; import { FileUploadComponent } from './file-upload/file-upload.component'; import { FooterComponent } from './footer/footer.component'; @@ -27,6 +29,8 @@ import { MaterialModule } from './material.module'; ReactiveFormsModule ], declarations: [ + FormfieldComponent, + FormDialogComponent, DeleteDialogComponent, FileUploadComponent, FooterComponent, @@ -45,6 +49,7 @@ import { MaterialModule } from './material.module'; ReactiveFormsModule ], entryComponents: [ + FormDialogComponent, DeleteDialogComponent ] })