WEB-435 Unit Test Coverage for ViewCollateralComponent feat: replace CKEditor with self-hosted TinyMCE (no API key) Change ViewChild static option to false
306 lines
8.5 KiB
TypeScript
306 lines
8.5 KiB
TypeScript
/** Angular Imports */
|
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
|
import {
|
|
UntypedFormGroup,
|
|
UntypedFormBuilder,
|
|
UntypedFormControl,
|
|
Validators,
|
|
ReactiveFormsModule
|
|
} from '@angular/forms';
|
|
import { Router, ActivatedRoute, RouterLink } from '@angular/router';
|
|
|
|
/** Custom Imports */
|
|
import { clientParameterLabels, loanParameterLabels, repaymentParameterLabels } from '../template-parameter-labels';
|
|
|
|
/** Custom Services */
|
|
import { TemplatesService } from '../templates.service';
|
|
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
|
import { EditorComponent, EditorModule, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';
|
|
import {
|
|
MatAccordion,
|
|
MatExpansionPanel,
|
|
MatExpansionPanelHeader,
|
|
MatExpansionPanelTitle
|
|
} from '@angular/material/expansion';
|
|
import { STANDALONE_SHARED_IMPORTS } from 'app/standalone-shared.module';
|
|
|
|
/**
|
|
* Create Template Component.
|
|
*/
|
|
@Component({
|
|
selector: 'mifosx-create-edit-template',
|
|
templateUrl: './create-edit-template.component.html',
|
|
styleUrls: ['./create-edit-template.component.scss'],
|
|
imports: [
|
|
...STANDALONE_SHARED_IMPORTS,
|
|
FaIconComponent,
|
|
EditorModule,
|
|
MatAccordion,
|
|
MatExpansionPanel,
|
|
MatExpansionPanelHeader,
|
|
MatExpansionPanelTitle
|
|
],
|
|
providers: [
|
|
{
|
|
provide: TINYMCE_SCRIPT_SRC,
|
|
useValue: 'assets/tinymce/tinymce.min.js'
|
|
}
|
|
]
|
|
})
|
|
export class CreateEditComponent implements OnInit {
|
|
/** TinyMCE instance configuration */
|
|
tinymceConfig = {
|
|
base_url: 'assets/tinymce',
|
|
suffix: '.min',
|
|
menubar: false,
|
|
branding: false,
|
|
height: 320,
|
|
forced_root_block: false,
|
|
statusbar: false,
|
|
elementpath: false,
|
|
resize: false,
|
|
plugins: 'lists link table media codesample',
|
|
toolbar:
|
|
'undo redo | blocks | bold italic underline | link | numlist bullist outdent indent | alignleft aligncenter alignright alignjustify | table media | removeformat'
|
|
};
|
|
/** TinyMCE component reference */
|
|
@ViewChild('tinymceEditor', { static: false }) tinymceEditor: EditorComponent;
|
|
|
|
/** Template form. */
|
|
templateForm: UntypedFormGroup;
|
|
/** Create or Edit Template Data. */
|
|
templateData: any;
|
|
/** Template Mappers */
|
|
mappers: any[] = [];
|
|
/** Toggles Visibility of Advanced Options */
|
|
showAdvanceOptions = false;
|
|
/** mode */
|
|
mode: 'create' | 'edit';
|
|
|
|
/** 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: UntypedFormBuilder,
|
|
private route: ActivatedRoute,
|
|
private router: Router,
|
|
private templateService: TemplatesService
|
|
) {
|
|
this.route.data.subscribe((data: { templateData: any; mode: 'create' | 'edit' }) => {
|
|
this.templateData = data.templateData;
|
|
this.mode = data.mode;
|
|
if (this.mode === 'edit') {
|
|
this.mappers = this.templateData.template.mappers.map((mapper: any) => ({
|
|
mappersorder: mapper.mapperorder,
|
|
mapperskey: new UntypedFormControl(mapper.mapperkey),
|
|
mappersvalue: new UntypedFormControl(mapper.mappervalue)
|
|
}));
|
|
}
|
|
});
|
|
}
|
|
|
|
ngOnInit() {
|
|
this.createTemplateForm();
|
|
this.buildDependencies();
|
|
}
|
|
|
|
/**
|
|
* Creates the template form.
|
|
*/
|
|
createTemplateForm() {
|
|
if (this.mode === 'create') {
|
|
this.templateForm = this.formBuilder.group({
|
|
entity: [
|
|
'',
|
|
Validators.required
|
|
],
|
|
type: [
|
|
'',
|
|
Validators.required
|
|
],
|
|
name: [
|
|
'',
|
|
Validators.required
|
|
],
|
|
text: [
|
|
'',
|
|
Validators.required
|
|
]
|
|
});
|
|
} else {
|
|
this.templateForm = this.formBuilder.group({
|
|
entity: [
|
|
this.templateData.entities.find((entity: any) => entity.name === this.templateData.template.entity).id,
|
|
Validators.required
|
|
],
|
|
type: [
|
|
this.templateData.types.find((type: any) => type.name === this.templateData.template.type).id,
|
|
Validators.required
|
|
],
|
|
name: [
|
|
this.templateData.template.name,
|
|
Validators.required
|
|
],
|
|
text: [
|
|
this.templateData.template.text,
|
|
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 UntypedFormControl('client'),
|
|
mappersvalue: new UntypedFormControl('clients/{{clientId}}?tenantIdentifier=' + tenantIdentifier)
|
|
});
|
|
} else {
|
|
// loan
|
|
this.mappers.splice(0, 1, {
|
|
mappersorder: 0,
|
|
mapperskey: new UntypedFormControl('loan'),
|
|
mappersvalue: new UntypedFormControl('loans/{{loanId}}?associations=all&tenantIdentifier=' + tenantIdentifier)
|
|
});
|
|
}
|
|
this.setEditorContent('');
|
|
this.templateForm.get('text').setValue('');
|
|
});
|
|
if (this.mode === 'create') {
|
|
this.templateForm.get('entity').patchValue(0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a mapper.
|
|
*/
|
|
addMapper() {
|
|
this.mappers.push({
|
|
mappersorder: this.mappers.length,
|
|
mapperskey: new UntypedFormControl(''),
|
|
mappersvalue: new UntypedFormControl('')
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Removes a mapper
|
|
* @param {any} index Mapper Index
|
|
*/
|
|
removeMapper(index: any) {
|
|
this.mappers.splice(index, 1);
|
|
}
|
|
|
|
/**
|
|
* Adds text to the editor at cursor position.
|
|
* @param {string} label Template parameter label.
|
|
*/
|
|
addText(label: string) {
|
|
this.tinymceEditor?.editor?.insertContent(label);
|
|
}
|
|
|
|
/**
|
|
* Gets the contents of the editor.
|
|
*/
|
|
getEditorContent() {
|
|
return this.tinymceEditor?.editor?.getContent({ format: 'html' }) || '';
|
|
}
|
|
|
|
/**
|
|
* Sets the contents of the editor.
|
|
* @param {string} content Editor Content
|
|
*/
|
|
setEditorContent(content: string) {
|
|
if (this.tinymceEditor?.editor) {
|
|
this.tinymceEditor.editor.setContent(content || '');
|
|
}
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Submits 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()
|
|
};
|
|
if (this.mode === 'create') {
|
|
this.templateService.createTemplate(template).subscribe((response: any) => {
|
|
this.router.navigate(
|
|
[
|
|
'../',
|
|
response.resourceId
|
|
],
|
|
{ relativeTo: this.route }
|
|
);
|
|
});
|
|
} else {
|
|
this.templateService.updateTemplate(template, this.templateData.template.id).subscribe(() => {
|
|
this.router.navigate(['../'], { relativeTo: this.route });
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* TrackBy function for mappers array to improve ngFor performance.
|
|
* @param {number} index Index of the item
|
|
* @returns {number} Index as unique identifier
|
|
*/
|
|
trackByMapperIndex(index: number): number {
|
|
return index;
|
|
}
|
|
|
|
/**
|
|
* TrackBy function for parameter labels to improve ngFor performance.
|
|
* @param {number} index Index of the item
|
|
* @param {string} label Label string
|
|
* @returns {string} Label as unique identifier
|
|
*/
|
|
trackByLabel(index: number, label: string): string {
|
|
return label;
|
|
}
|
|
|
|
/**
|
|
* TrackBy function for entities dropdown to improve ngFor performance.
|
|
* @param {number} index Index of the item
|
|
* @param {any} entity Entity object
|
|
* @returns {number} Entity ID as unique identifier
|
|
*/
|
|
trackByEntityId(index: number, entity: any): number {
|
|
return entity.id;
|
|
}
|
|
|
|
/**
|
|
* TrackBy function for types dropdown to improve ngFor performance.
|
|
* @param {number} index Index of the item
|
|
* @param {any} type Type object
|
|
* @returns {number} Type ID as unique identifier
|
|
*/
|
|
trackByTypeId(index: number, type: any): number {
|
|
return type.id;
|
|
}
|
|
}
|