diff --git a/src/app/templates/common-resolvers/create-template.resolver.ts b/src/app/templates/common-resolvers/create-template.resolver.ts new file mode 100644 index 000000000..0e23d2884 --- /dev/null +++ b/src/app/templates/common-resolvers/create-template.resolver.ts @@ -0,0 +1,30 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { TemplatesService } from '../templates.service'; + +/** + * Create Template data resolver. + */ +@Injectable() +export class CreateTemplateResolver implements Resolve { + + /** + * @param {TemplatesService} templatesService Templates service. + */ + constructor(private templatesService: TemplatesService) {} + + /** + * Returns the template data. + * @returns {Observable} + */ + resolve(): Observable { + return this.templatesService.getCreateTemplateData(); + } + +} diff --git a/src/app/templates/create-template/create-template.component.html b/src/app/templates/create-template/create-template.component.html new file mode 100644 index 000000000..709b2641f --- /dev/null +++ b/src/app/templates/create-template/create-template.component.html @@ -0,0 +1,152 @@ +
+ + + +
+ + + +
+ + + Entity + + + {{ entity.name }} + + + + Entity is required + + + + + Type + + + {{ type.name }} + + + + Type is required + + + + + Name + + + Name is required + + + +
+ +
+ +
+ +
+ + + +
+ + + +
+ + + Mapper Key + + + + + Mapper Value + + + + + + +
+ +
+ +
+ + + +
+ +
+ + + + + + + + Client Parameters + + + +
+ +
+ +
+ + + + + + Loan Parameters + + + +
+ +
+ +
+ + + + + + Repayment Schedule Parameters + + + +
+ +
+ +
+ +
+ +
+ + + + + + +
+ +
diff --git a/src/app/templates/create-template/create-template.component.scss b/src/app/templates/create-template/create-template.component.scss new file mode 100644 index 000000000..de3be7ac4 --- /dev/null +++ b/src/app/templates/create-template/create-template.component.scss @@ -0,0 +1,12 @@ +.container { + + .mapper-button { + max-height: 2.25rem; + margin-top: 1rem; + } + + .parameter { + margin: 1%; + } + +} diff --git a/src/app/templates/create-template/create-template.component.spec.ts b/src/app/templates/create-template/create-template.component.spec.ts new file mode 100644 index 000000000..890adc35b --- /dev/null +++ b/src/app/templates/create-template/create-template.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateTemplateComponent } from './create-template.component'; + +describe('CreateTemplateComponent', () => { + let component: CreateTemplateComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateTemplateComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateTemplateComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/templates/create-template/create-template.component.ts b/src/app/templates/create-template/create-template.component.ts new file mode 100644 index 000000000..11863f78b --- /dev/null +++ b/src/app/templates/create-template/create-template.component.ts @@ -0,0 +1,173 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormGroup, FormBuilder, FormControl, Validators } from '@angular/forms'; +import { Router, ActivatedRoute } from '@angular/router'; + +/** CKEditor5 Imports */ +import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic'; + +/** Custom Imports */ +import { clientParameterLabels, loanParameterLabels, repaymentParameterLabels } from '../template-parameter-labels'; + +/** Custom Services */ +import { TemplatesService } from '../templates.service'; + +/** + * Create Template Component. + */ +@Component({ + selector: 'mifosx-create-template', + templateUrl: './create-template.component.html', + styleUrls: ['./create-template.component.scss'] +}) +export class CreateTemplateComponent implements OnInit { + + /** CKEditor5 */ + public Editor = ClassicEditor; + /** CKEditor5 Template Reference */ + @ViewChild('ckEditor') ckEditor: any; + + /** Template form. */ + templateForm: FormGroup; + /** Edit Template Data. */ + createTemplateData: any; + /** Template Mappers */ + mappers: any[] = []; + /** Toggles Visibility of Advance Options */ + showAdvanceOptions = false; + + /** Client Parameter Labels */ + clientParameterLabels: string[] = clientParameterLabels; + /** Loan Parameter Labels */ + loanParameterLabels: string[] = loanParameterLabels; + /** Repayment Parameter Labels */ + repaymentParameterLabels: string[] = repaymentParameterLabels; + + /** + * Retrieves the template data from `resolve`. + * @param {FormBuilder} formBuilder Form Builder. + * @param {ActivatedRoute} route Activated Route. + * @param {Router} router Router for navigation. + * @param {TemplateService} templateService Templates Service + */ + constructor(private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private templateService: TemplatesService) { + this.route.data.subscribe((data: { createTemplateData: any }) => { + this.createTemplateData = data.createTemplateData; + }); + } + + ngOnInit() { + this.createTemplateForm(); + this.buildDependencies(); + } + + /** + * Creates the template form. + */ + createTemplateForm() { + this.templateForm = this.formBuilder.group({ + 'entity': ['', Validators.required], + 'type': ['', Validators.required], + 'name': ['', Validators.required] + }); + } + + /** + * Subscribe to value changes of entity to set default mapper. + */ + buildDependencies() { + const tenantIdentifier = 'default'; // update once global settings are setup. + this.templateForm.get('entity').valueChanges.subscribe((value: any) => { + if (value === 0) { // client + this.mappers.splice(0, 1, { + mappersorder: 0, + mapperskey: new FormControl('client'), + mappersvalue: new FormControl('clients/{{clientId}}?tenantIdentifier=' + tenantIdentifier) + }); + } else { // loan + this.mappers.splice(0, 1, { + mappersorder: 0, + mapperskey: new FormControl('loan'), + mappersvalue: new FormControl('loans/{{loanId}}?associations=all&tenantIdentifier=' + tenantIdentifier ) + }); + } + this.setEditorContent(''); + }); + this.templateForm.get('entity').patchValue(0); + } + + /** + * Adds a mapper. + */ + addMapper() { + this.mappers.push({ + mappersorder: this.mappers.length, + mapperskey: new FormControl(''), + mappersvalue: new FormControl('') + }); + } + + /** + * Removes a mapper + * @param {any} index Mapper Index + */ + removeMapper(index: any) { + this.mappers.splice(index, 1); + } + + /** + * Adds text to CKEditor at cursor position. + * @param {string} label Template parameter label. + */ + addText(label: string) { + if (this.ckEditor && this.ckEditor.editorInstance) { + this.ckEditor.editorInstance.model.change((writer: any) => { + const insertPosition = this.ckEditor.editorInstance.model.document.selection.getFirstPosition(); + writer.insertText(label, insertPosition); + } ); + } + } + + /** + * Gets the contents of CKEditor. + */ + getEditorContent() { + if (this.ckEditor && this.ckEditor.editorInstance) { + return this.ckEditor.editorInstance.getData(); + } + return ''; + } + + /** + * Sets the contents of CKEditor. + * @param {string} content Editor Content + */ + setEditorContent(content: string) { + if (this.ckEditor && this.ckEditor.editorInstance) { + return this.ckEditor.editorInstance.setData(content); + } + return ''; + } + + /** + * Creates a template. + */ + submit() { + const template: any = { + ...this.templateForm.value, + mappers: this.mappers.map((mapper: any) => ({ + mappersorder: mapper.mappersorder, + mapperskey: mapper.mapperskey.value, + mappersvalue: mapper.mappersvalue.value + })), + text: this.getEditorContent() + }; + this.templateService.createTemplate(template).subscribe((response: any) => { + this.router.navigate(['../', response.resourceId], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/templates/edit-template/edit-template.component.ts b/src/app/templates/edit-template/edit-template.component.ts index 9effb4725..08d5cbb99 100644 --- a/src/app/templates/edit-template/edit-template.component.ts +++ b/src/app/templates/edit-template/edit-template.component.ts @@ -1,8 +1,7 @@ /** Angular Imports */ import { Component, OnInit, ViewChild } from '@angular/core'; -import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms'; +import { FormGroup, FormBuilder, FormControl } from '@angular/forms'; import { Router, ActivatedRoute } from '@angular/router'; -import { DatePipe } from '@angular/common'; /** CKEditor5 Imports */ import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic'; @@ -49,7 +48,7 @@ export class EditTemplateComponent implements OnInit { * @param {FormBuilder} formBuilder Form Builder. * @param {ActivatedRoute} route Activated Route. * @param {Router} router Router for navigation. - * @param {DatePipe} datePipe Date Pipe to format date. + * @param {TemplateService} templateService Templates Service */ constructor(private formBuilder: FormBuilder, private route: ActivatedRoute, @@ -158,6 +157,9 @@ export class EditTemplateComponent implements OnInit { return ''; } + /** + * Edits an existing template. + */ submit() { const template: any = { ...this.templateForm.value, diff --git a/src/app/templates/templates-routing.module.ts b/src/app/templates/templates-routing.module.ts index b21cd236c..0c1d131da 100644 --- a/src/app/templates/templates-routing.module.ts +++ b/src/app/templates/templates-routing.module.ts @@ -12,11 +12,13 @@ import { extract } from '../core/i18n/i18n.service'; import { TemplatesComponent } from './templates.component'; import { ViewTemplateComponent } from './view-template/view-template.component'; import { EditTemplateComponent } from './edit-template/edit-template.component'; +import { CreateTemplateComponent } from './create-template/create-template.component'; /** Custom Resolvers */ import { TemplatesResolver } from './common-resolvers/templates.resolver'; import { TemplateResolver } from './common-resolvers/template.resolver'; import { EditTemplateResolver } from './common-resolvers/edit-template.resolver'; +import { CreateTemplateResolver } from './common-resolvers/create-template.resolver'; /** Templates Routes */ const routes: Routes = [ @@ -32,6 +34,14 @@ const routes: Routes = [ templates: TemplatesResolver } }, + { + path: 'create', + data: { title: extract('Create Template'), breadcrumb: 'Create Template' }, + component: CreateTemplateComponent, + resolve: { + createTemplateData: CreateTemplateResolver + } + }, { path: ':id', data: { title: extract('View Template'), routeParamBreadcrumb: 'id' }, @@ -69,7 +79,8 @@ const routes: Routes = [ providers: [ TemplatesResolver, TemplateResolver, - EditTemplateResolver + EditTemplateResolver, + CreateTemplateResolver ] }) export class TemplatesRoutingModule { } diff --git a/src/app/templates/templates.component.html b/src/app/templates/templates.component.html index 2be3f8dc5..4be2a8fec 100644 --- a/src/app/templates/templates.component.html +++ b/src/app/templates/templates.component.html @@ -1,5 +1,5 @@
- diff --git a/src/app/templates/templates.module.ts b/src/app/templates/templates.module.ts index 0dc5934f2..1eae38fb6 100644 --- a/src/app/templates/templates.module.ts +++ b/src/app/templates/templates.module.ts @@ -10,6 +10,7 @@ import { TemplatesRoutingModule } from './templates-routing.module'; import { TemplatesComponent } from './templates.component'; import { ViewTemplateComponent } from './view-template/view-template.component'; import { EditTemplateComponent } from './edit-template/edit-template.component'; +import { CreateTemplateComponent } from './create-template/create-template.component'; /** * Templates Module @@ -26,6 +27,7 @@ import { EditTemplateComponent } from './edit-template/edit-template.component'; TemplatesComponent, ViewTemplateComponent, EditTemplateComponent, + CreateTemplateComponent, ] }) export class TemplatesModule { } diff --git a/src/app/templates/templates.service.ts b/src/app/templates/templates.service.ts index 0640ce7e5..8d7f9ea16 100644 --- a/src/app/templates/templates.service.ts +++ b/src/app/templates/templates.service.ts @@ -33,6 +33,13 @@ export class TemplatesService { return this.http.get(`/templates/${templateId}`); } + /** + * @returns {Observable}. + */ + getCreateTemplateData(): Observable { + return this.http.get('/templates/template'); + } + /** * @param templateId Template Id. * @returns {Observable}. @@ -41,6 +48,15 @@ export class TemplatesService { return this.http.get(`/templates/${templateId}/template`); } + /** + * @param templateData Template to be created. + * @param templateId Template Id. + * @returns {Observable}. + */ + createTemplate(templateData: any): Observable { + return this.http.post(`/templates`, templateData); + } + /** * @param templateData Templete Data to be edited. * @param templateId Template Id.