diff --git a/src/app/clients/clients-view/documents-tab/documents-tab.component.html b/src/app/clients/clients-view/documents-tab/documents-tab.component.html index 0c12226c4..8c0dd9b62 100644 --- a/src/app/clients/clients-view/documents-tab/documents-tab.component.html +++ b/src/app/clients/clients-view/documents-tab/documents-tab.component.html @@ -1,47 +1,7 @@ -
- - - -

Documents

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name {{document.name}} Description {{document.description}} File Name {{document.fileName}} Actions - - -
- -
+ + diff --git a/src/app/clients/clients-view/documents-tab/documents-tab.component.ts b/src/app/clients/clients-view/documents-tab/documents-tab.component.ts index 3974aa67b..7f1872884 100644 --- a/src/app/clients/clients-view/documents-tab/documents-tab.component.ts +++ b/src/app/clients/clients-view/documents-tab/documents-tab.component.ts @@ -1,84 +1,45 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { MatTable } from '@angular/material/table'; import { MatDialog } from '@angular/material/dialog'; /** Custom Services */ import { ClientsService } from '../../clients.service'; -/** Custom Components */ -import { UploadDocumentDialogComponent } from '../custom-dialogs/upload-document-dialog/upload-document-dialog.component'; -import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component'; - - @Component({ selector: 'mifosx-documents-tab', templateUrl: './documents-tab.component.html', styleUrls: ['./documents-tab.component.scss'] }) export class DocumentsTabComponent implements OnInit { - @ViewChild('documentsTable', { static: true }) documentsTable: MatTable; - documentsColumns: string[] = ['name', 'description', 'fileName', 'actions']; - clientDocuments: any; - clientId: string; - + entityDocuments: any; + entityId: string; + entityType: string = 'clients'; constructor(private route: ActivatedRoute, - private clientService: ClientsService, + private clientsService: ClientsService, public dialog: MatDialog) { this.route.data.subscribe((data: { clientDocuments: any }) => { - this.clientDocuments = data.clientDocuments; + this.entityDocuments = data.clientDocuments; }); - this.clientId = this.route.parent.snapshot.paramMap.get('clientId'); + this.entityId = this.route.parent.snapshot.paramMap.get('clientId'); } ngOnInit() { } - download(parentEntityId: string, documentId: string) { - this.clientService.downloadClientDocument(parentEntityId, documentId).subscribe(res => { + downloadDocument(documentId: string) { + this.clientsService.downloadClientDocument(this.entityId, documentId).subscribe(res => { const url = window.URL.createObjectURL(res); window.open(url); }); } - deleteDocument(parentEntityId: string, documentId: string, index: number) { - const deleteDocumentDialogRef = this.dialog.open(DeleteDialogComponent, { - data: { deleteContext: `document id:${documentId}` } - }); - deleteDocumentDialogRef.afterClosed().subscribe((response: any) => { - if (response.delete) { - this.clientService.deleteClientDocument(parentEntityId, documentId).subscribe(res => { - this.clientDocuments.splice(index, 1); - this.documentsTable.renderRows(); - }); - } - }); + deleteDocument(documentId: string) { + this.clientsService.deleteClientDocument(this.entityId, documentId).subscribe(res => {}); } - uploadDocument() { - const uploadDocumentDialogRef = this.dialog.open(UploadDocumentDialogComponent, { - data: { documentIdentifier: false, entityType: 'Client' } - }); - uploadDocumentDialogRef.afterClosed().subscribe((dialogResponse: any) => { - if (dialogResponse) { - const formData: FormData = new FormData; - formData.append('name', dialogResponse.fileName); - formData.append('file', dialogResponse.file); - formData.append('description', dialogResponse.description); - this.clientService.uploadClientDocument(this.clientId, formData).subscribe((res: any) => { - this.clientDocuments.push({ - id: res.resourceId, - parentEntityType: 'clients', - parentEntityId: this.clientId, - name: dialogResponse.fileName, - description: dialogResponse.description, - fileName: dialogResponse.file.name - }); - this.documentsTable.renderRows(); - }); - } - }); + uploadDocument(formData: FormData): any { + return this.clientsService.uploadClientDocument(this.entityId, formData); } } diff --git a/src/app/clients/clients-view/notes-tab/notes-tab.component.html b/src/app/clients/clients-view/notes-tab/notes-tab.component.html index fc1353614..04cf7318f 100644 --- a/src/app/clients/clients-view/notes-tab/notes-tab.component.html +++ b/src/app/clients/clients-view/notes-tab/notes-tab.component.html @@ -1,43 +1,7 @@ -
- -

Notes

- -
- -
- - - - - - - -
- -
- - - - - -

{{clientNote.note}}

-

- Created by: {{clientNote.createdByUsername}}
- Date: {{clientNote.createdOn | dateFormat}} -

-
- - -
-
- -
- -
\ No newline at end of file + + diff --git a/src/app/clients/clients-view/notes-tab/notes-tab.component.scss b/src/app/clients/clients-view/notes-tab/notes-tab.component.scss index c802bd41d..e69de29bb 100644 --- a/src/app/clients/clients-view/notes-tab/notes-tab.component.scss +++ b/src/app/clients/clients-view/notes-tab/notes-tab.component.scss @@ -1,5 +0,0 @@ -.tab-container { - padding: 1%; - margin: 1%; - -} diff --git a/src/app/clients/clients-view/notes-tab/notes-tab.component.ts b/src/app/clients/clients-view/notes-tab/notes-tab.component.ts index 3203e8ade..33c79e2f6 100644 --- a/src/app/clients/clients-view/notes-tab/notes-tab.component.ts +++ b/src/app/clients/clients-view/notes-tab/notes-tab.component.ts @@ -1,12 +1,8 @@ /** Angular Imports */ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { MatDialog } from '@angular/material/dialog'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; /** Custom Components */ -import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component'; -import { EditNotesDialogComponent } from '../custom-dialogs/edit-notes-dialog/edit-notes-dialog.component'; /** Custom Services */ import { ClientsService } from '../../clients.service'; @@ -23,66 +19,39 @@ import { AuthenticationService } from 'app/core/authentication/authentication.se export class NotesTabComponent implements OnInit { /** Client ID */ - clientId: string; + entityId: string; /** Username */ username: string; /** Client Notes */ - clientNotes: any; - /** Note Form */ - noteForm: FormGroup; - - /** Notes Form Reference */ - @ViewChild('formRef', { static: true }) formRef: any; + entityNotes: any; /** * @param {ActivatedRoute} route Activated Route - * @param {FormBuilder} formBuilder Form Builder * @param {ClientsService} clientsService Clients Service * @param {AuthenticationService} authenticationService Authentication Service - * @param {MatDialog} dialog Mat Dialog */ constructor(private route: ActivatedRoute, - private formBuilder: FormBuilder, private clientsService: ClientsService, - private authenticationService: AuthenticationService, - public dialog: MatDialog) { + private authenticationService: AuthenticationService) { const credentials = this.authenticationService.getCredentials(); this.username = credentials.username; - this.clientId = this.route.parent.snapshot.params['clientId']; + this.entityId = this.route.parent.snapshot.params['clientId']; this.route.data.subscribe((data: { clientNotes: any }) => { - this.clientNotes = data.clientNotes; + this.entityNotes = data.clientNotes; }); } - ngOnInit() { - this.createNoteForm(); - } - - /** - * Creates the note form - */ - createNoteForm() { - this.noteForm = this.formBuilder.group({ - 'note': ['', Validators.required] - }); - } + ngOnInit() { } /** * Edits a client note. * @param {string} noteId Note Id - * @param {string} noteContent Note Content + * @param {any} noteContent Note Content * @param {number} index Index */ - editNote(noteId: string, noteContent: string, index: number) { - const editNoteDialogRef = this.dialog.open(EditNotesDialogComponent, { - data: { noteContent: noteContent } - }); - editNoteDialogRef.afterClosed().subscribe((response: { editForm: any }) => { - if (response.editForm) { - this.clientsService.editClientNote(this.clientId, noteId, response.editForm.value).subscribe(() => { - this.clientNotes[index].note = response.editForm.value.note; - }); - } + editNote(noteId: string, noteContent: any, index: number) { + this.clientsService.editClientNote(this.entityId, noteId, noteContent).subscribe(() => { + this.entityNotes[index].note = noteContent.note; }); } @@ -92,31 +61,23 @@ export class NotesTabComponent implements OnInit { * @param {number} index Index */ deleteNote(noteId: string, index: number) { - const deleteNoteDialogRef = this.dialog.open(DeleteDialogComponent, { - data: { deleteContext: `Note id:${noteId}` } - }); - deleteNoteDialogRef.afterClosed().subscribe((response: any) => { - if (response.delete) { - this.clientsService.deleteClientNote(this.clientId, noteId) - .subscribe(() => { - this.clientNotes.splice(index, 1); - }); - } - }); + this.clientsService.deleteClientNote(this.entityId, noteId) + .subscribe(() => { + this.entityNotes.splice(index, 1); + }); } /** * Creates a client note. */ - submit() { - this.clientsService.createClientNote(this.clientId, this.noteForm.value).subscribe((response: any) => { - this.clientNotes.push({ + addNote(noteContent: any) { + this.clientsService.createClientNote(this.entityId, noteContent).subscribe((response: any) => { + this.entityNotes.push({ id: response.resourceId, createdByUsername: this.username, createdOn: new Date(), - note: this.noteForm.value.note + note: noteContent.note }); - this.formRef.resetForm(); }); } diff --git a/src/app/clients/clients.component.html b/src/app/clients/clients.component.html index 983974fb9..0d25c511b 100644 --- a/src/app/clients/clients.component.html +++ b/src/app/clients/clients.component.html @@ -27,19 +27,19 @@ - Name + Name {{row.entityName}} - Account No. + Account No. {{row.entityAccountNo}} - External Id + External Id @@ -47,7 +47,7 @@ - Status + Status
@@ -75,7 +75,7 @@ -
diff --git a/src/app/clients/clients.component.ts b/src/app/clients/clients.component.ts index fd716f05d..782c09a29 100644 --- a/src/app/clients/clients.component.ts +++ b/src/app/clients/clients.component.ts @@ -7,6 +7,7 @@ import { MatTableDataSource } from '@angular/material/table'; /** Custom Services */ import { SearchService } from 'app/search/search.service'; +import { environment } from 'environments/environment'; @Component({ selector: 'mifosx-clients', @@ -29,7 +30,9 @@ export class ClientsComponent implements OnInit { constructor(private searchService: SearchService) { } ngOnInit() { - this.getClients(''); + if (environment.preloadClients) { + this.getClients(''); + } } /** diff --git a/src/app/loans/create-loans-account/create-loans-account.component.html b/src/app/loans/create-loans-account/create-loans-account.component.html index 43357c0e3..4327f7517 100644 --- a/src/app/loans/create-loans-account/create-loans-account.component.html +++ b/src/app/loans/create-loans-account/create-loans-account.component.html @@ -63,6 +63,14 @@ + + + {{datatable.registeredTableName}} + + + + + PREVIEW diff --git a/src/app/loans/create-loans-account/create-loans-account.component.ts b/src/app/loans/create-loans-account/create-loans-account.component.ts index cee8bbf0d..16791a2b8 100644 --- a/src/app/loans/create-loans-account/create-loans-account.component.ts +++ b/src/app/loans/create-loans-account/create-loans-account.component.ts @@ -1,5 +1,5 @@ /** Angular Imports */ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; /** Custom Services */ @@ -12,6 +12,7 @@ import { LoansAccountDetailsStepComponent } from '../loans-account-stepper/loans import { LoansAccountTermsStepComponent } from '../loans-account-stepper/loans-account-terms-step/loans-account-terms-step.component'; import { LoansAccountChargesStepComponent } from '../loans-account-stepper/loans-account-charges-step/loans-account-charges-step.component'; import { Dates } from 'app/core/utils/dates'; +import { LoansAccountDatatableStepComponent } from '../loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component'; /** * Create loans account @@ -27,6 +28,8 @@ export class CreateLoansAccountComponent implements OnInit { @ViewChild(LoansAccountDetailsStepComponent, { static: true }) loansAccountDetailsStep: LoansAccountDetailsStepComponent; @ViewChild(LoansAccountTermsStepComponent, { static: true }) loansAccountTermsStep: LoansAccountTermsStepComponent; @ViewChild(LoansAccountChargesStepComponent, { static: true }) loansAccountChargesStep: LoansAccountChargesStepComponent; + /** Get handle on dtloan tags in the template */ + @ViewChildren('dtloan') clientDatatables: QueryList; /** Loans Account Template */ loansAccountTemplate: any; @@ -38,6 +41,7 @@ export class CreateLoansAccountComponent implements OnInit { multiDisburseLoan: any; /** Principal Amount */ principal: any; + datatables: any = []; /** * Sets loans account create form. @@ -81,6 +85,16 @@ export class CreateLoansAccountComponent implements OnInit { }); } + setDatatables(): void { + this.datatables = []; + + if (this.loansAccountTemplate.datatables) { + this.loansAccountTemplate.datatables.forEach((datatable: any) => { + this.datatables.push(datatable); + }); + } + } + /** Get Loans Account Details Form Data */ get loansAccountDetailsForm() { return this.loansAccountDetailsStep.loansAccountDetailsForm; @@ -124,6 +138,14 @@ export class CreateLoansAccountComponent implements OnInit { const payload = this.loansService.buildLoanRequestPayload(this.loansAccount, this.loansAccountTemplate, this.loansAccountProductTemplate.calendarOptions, locale, dateFormat); + if (this.loansAccountTemplate.datatables && this.loansAccountTemplate.datatables.length > 0) { + const datatables: any[] = []; + this.loansAccountTemplate.forEach((loanDatatable: LoansAccountDatatableStepComponent) => { + datatables.push(loanDatatable.payload); + }); + payload['datatables'] = datatables; + } + this.loansService.createLoansAccount(payload).subscribe((response: any) => { this.router.navigate(['../', response.resourceId, 'general'], { relativeTo: this.route }); }); diff --git a/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.html b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.html new file mode 100644 index 000000000..980711b99 --- /dev/null +++ b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.html @@ -0,0 +1,51 @@ +
+ +
+ +
+ + + {{getInputName(datatableInput)}} + + + + {{ code.value }} + + + + + + + + + + + + + + + + + + {{getInputName(datatableInput)}} + +
+ +
+ +
+ + +
+ +
diff --git a/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.scss b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.scss new file mode 100644 index 000000000..8817bcc31 --- /dev/null +++ b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.scss @@ -0,0 +1,7 @@ +.date-picker { + width: 92%; +} + +mat-checkbox { + margin-top: 30px; +} diff --git a/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.spec.ts b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.spec.ts new file mode 100644 index 000000000..d826e3fef --- /dev/null +++ b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LoansAccountDatatableStepComponent } from './loans-account-datatable-step.component'; + +describe('LoansAccountDatatableStepComponent', () => { + let component: LoansAccountDatatableStepComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ LoansAccountDatatableStepComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(LoansAccountDatatableStepComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.ts b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.ts new file mode 100644 index 000000000..d4591a6d6 --- /dev/null +++ b/src/app/loans/loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component.ts @@ -0,0 +1,108 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { Dates } from 'app/core/utils/dates'; +import { SettingsService } from 'app/settings/settings.service'; + +@Component({ + selector: 'mifosx-loans-account-datatable-step', + templateUrl: './loans-account-datatable-step.component.html', + styleUrls: ['./loans-account-datatable-step.component.scss'] +}) +export class LoansAccountDatatableStepComponent implements OnInit { + /** Input Fields Data */ + @Input() datatableData: any; + /** Create Input Form */ + datatableForm: FormGroup; + + datatableInputs: any = []; + + constructor(private formBuilder: FormBuilder, + private settingsService: SettingsService, + private dateUtils: Dates) { } + + ngOnInit(): void { + this.datatableInputs = this.datatableData.columnHeaderData.filter((column: any) => { + return ((column.columnName !== 'id') && (column.columnName !== 'loan_id') && (column.columnName !== 'created_at') && (column.columnName !== 'updated_at')); + }); + const inputItems: any = {}; + this.datatableInputs.forEach((input: any) => { + input.controlName = this.getInputName(input); + if (!input.isColumnNullable) { + if (this.isNumeric(input.columnDisplayType)) { + inputItems[input.controlName] = new FormControl(0, [Validators.required]); + } else { + inputItems[input.controlName] = new FormControl('', [Validators.required]); + } + } else { + inputItems[input.controlName] = new FormControl(''); + } + }); + this.datatableForm = this.formBuilder.group(inputItems); + } + + getInputName(datatableInput: any): string { + if (datatableInput.columnName && datatableInput.columnName.includes('_cd_')) { + return datatableInput.columnName.split('_cd_')[0]; + } + return datatableInput.columnName; + } + + isNumeric(columnType: string) { + return this.isColumnType(columnType, 'INTEGER') || this.isColumnType(columnType, 'DECIMAL'); + } + + isDate(columnType: string) { + return this.isColumnType(columnType, 'DATE') || this.isColumnType(columnType, 'DATETIME'); + } + + isBoolean(columnType: string) { + return this.isColumnType(columnType, 'BOOLEAN'); + } + + isDropdown(columnType: string) { + return this.isColumnType(columnType, 'CODELOOKUP'); + } + + isString(columnType: string) { + return this.isColumnType(columnType, 'STRING'); + } + + isText(columnType: string) { + return this.isColumnType(columnType, 'TEXT'); + } + + isColumnType(columnType: string, expectedType: string) { + return (columnType === expectedType); + } + + get payload(): any { + const dateFormat = this.settingsService.dateFormat; + const datatableDataValues = this.datatableForm.value; + const data = { + locale: this.settingsService.language.code + }; + let existDate = false; + this.datatableInputs.forEach((input: any) => { + const controlName = this.getInputName(input); + if (this.isNumeric(input.columnDisplayType)) { + data[input.columnName] = datatableDataValues[controlName] * 1; + } else if (this.isDate(input.columnDisplayType)) { + data[input.columnName] = this.dateUtils.formatDate(datatableDataValues[controlName], dateFormat); + existDate = true; + } else { + data[input.columnName] = datatableDataValues[controlName]; + } + }); + + if (existDate) { + data['dateFormat'] = dateFormat; + } + + const payload = { + registeredTableName: this.datatableData.registeredTableName, + data: data + }; + return payload; + } + +} diff --git a/src/app/loans/loans-view/charges-tab/charges-tab.component.html b/src/app/loans/loans-view/charges-tab/charges-tab.component.html index d57bf0600..3a875926d 100644 --- a/src/app/loans/loans-view/charges-tab/charges-tab.component.html +++ b/src/app/loans/loans-view/charges-tab/charges-tab.component.html @@ -63,7 +63,7 @@ - diff --git a/src/app/loans/loans-view/charges-tab/charges-tab.component.ts b/src/app/loans/loans-view/charges-tab/charges-tab.component.ts index 994833926..97d4c73a9 100644 --- a/src/app/loans/loans-view/charges-tab/charges-tab.component.ts +++ b/src/app/loans/loans-view/charges-tab/charges-tab.component.ts @@ -84,15 +84,8 @@ export class ChargesTabComponent implements OnInit { */ payCharge(chargeId: any) { const formfields: FormfieldBase[] = [ - new InputBase({ - controlName: 'amount', - label: 'Amount', - value: '', - type: 'number', - required: true - }), new DatepickerBase({ - controlName: 'dueDate', + controlName: 'transactionDate', label: 'Payment Date', value: '', type: 'date', @@ -107,15 +100,15 @@ export class ChargesTabComponent implements OnInit { const payChargeDialogRef = this.dialog.open(FormDialogComponent, { data }); payChargeDialogRef.afterClosed().subscribe((response: any) => { if (response.data) { - const locale = 'en'; + const locale = this.settingsService.language.code; const dateFormat = this.settingsService.dateFormat; + const prevTransactionDate: Date = response.data.value.transactionDate; const dataObject = { - ...response.data.value, - dueDate: this.dateUtils.formatDate(response.data.value.dueDate, dateFormat), + transactionDate: this.dateUtils.formatDate(prevTransactionDate, dateFormat), dateFormat, locale }; - this.loansService.executeLoansAccountChargesCommand(this.loanDetails.id, 'paycharge', dataObject, chargeId) + this.loansService.executeLoansAccountChargesCommand(this.loanDetails.id, 'pay', dataObject, chargeId) .subscribe(() => { this.reload(); }); diff --git a/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.html b/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.html index a3c366a7b..8c0dd9b62 100644 --- a/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.html +++ b/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.html @@ -1,52 +1,7 @@ -
- -

Documents

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name {{ document.name }} Description {{ document.description }} File Name {{ document.fileName }} Actions - - - - - - -
- - - -
+ + diff --git a/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts b/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts index 6ffd5c156..64cd84c20 100644 --- a/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts +++ b/src/app/loans/loans-view/loan-documents-tab/loan-documents-tab.component.ts @@ -1,19 +1,11 @@ /** Angular Imports */ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource, MatTable } from '@angular/material/table'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; /** Custom Services */ import { environment } from 'environments/environment'; import { LoansService } from 'app/loans/loans.service'; - -/** Dialog Components */ -import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; import { SettingsService } from 'app/settings/settings.service'; -import { UploadDocumentDialogComponent } from 'app/clients/clients-view/custom-dialogs/upload-document-dialog/upload-document-dialog.component'; /** * Overdue charges tab component @@ -24,26 +16,12 @@ import { UploadDocumentDialogComponent } from 'app/clients/clients-view/custom-d styleUrls: ['./loan-documents-tab.component.scss'] }) export class LoanDocumentsTabComponent implements OnInit { - @ViewChild('documentsTable', { static: true }) documentsTable: MatTable; /** Stores the resolved loan documents data */ - loanDocuments: any; - /** Stores the resolved loan details data */ - loanDetailsData: any; - /** Status of the loan account */ - status: any; - /** Choice */ - choice: boolean; - - /** Columns to be displayed in loan documents table. */ - displayedColumns: string[] = ['name', 'description', 'filename', 'actions']; - /** Data source for loan documents table. */ - dataSource: MatTableDataSource; - - /** Paginator for codes table. */ - @ViewChild(MatPaginator) paginator: MatPaginator; - /** Sorter for codes table. */ - @ViewChild(MatSort) sort: MatSort; + entityDocuments: any; + /** Loan account Id */ + entityId: string; + entityType: string = 'loans'; /** * Retrieves the loans data from `resolve`. @@ -51,31 +29,19 @@ export class LoanDocumentsTabComponent implements OnInit { */ constructor(private route: ActivatedRoute, private loansService: LoansService, - private settingsService: SettingsService, - public dialog: MatDialog) { + private settingsService: SettingsService) { + this.entityId = this.route.parent.snapshot.params['loanId']; + this.route.data.subscribe((data: { loanDocuments: any }) => { this.getLoanDocumentsData(data.loanDocuments); }); - this.route.parent.data.subscribe((data: { loanDetailsData: any }) => { - this.loanDetailsData = data.loanDetailsData; - }); } - ngOnInit() { - this.status = this.loanDetailsData.status.value; - if (this.status === 'Submitted and pending approval' || this.status === 'Active' || this.status === 'Approved') { - this.choice = true; - } - this.dataSource = new MatTableDataSource(this.loanDocuments); - this.dataSource.paginator = this.paginator; - this.dataSource.sort = this.sort; - } + ngOnInit() { } getLoanDocumentsData(data: any) { data.forEach((ele: any) => { - let loandocs = {}; - loandocs = this.settingsService.serverUrl + '/loans/' + ele.parentEntityId + '/documents/' + ele.id + '/attachment?tenantIdentifier=' + environment.fineractPlatformTenantId; - ele.docUrl = loandocs; + ele.docUrl = this.settingsService.serverUrl + '/loans/' + ele.parentEntityId + '/documents/' + ele.id + '/attachment?tenantIdentifier=' + environment.fineractPlatformTenantId; if (ele.fileName) { if (ele.fileName.toLowerCase().indexOf('.jpg') !== -1 || ele.fileName.toLowerCase().indexOf('.jpeg') !== -1 || ele.fileName.toLowerCase().indexOf('.png') !== -1) { ele.fileIsImage = true; @@ -87,46 +53,22 @@ export class LoanDocumentsTabComponent implements OnInit { } } }); - this.loanDocuments = data; + this.entityDocuments = data; } - uploadDocument() { - const uploadDocumentDialogRef = this.dialog.open(UploadDocumentDialogComponent, { - data: { documentIdentifier: false, entityType: 'Loan' } - }); - uploadDocumentDialogRef.afterClosed().subscribe((dialogResponse: any) => { - if (dialogResponse) { - const formData: FormData = new FormData; - formData.append('name', dialogResponse.fileName); - formData.append('file', dialogResponse.file); - formData.append('description', dialogResponse.description); - this.loansService.loadLoanDocument(this.loanDetailsData.id, formData).subscribe((res: any) => { - this.loanDocuments.push({ - id: res.resourceId, - parentEntityType: 'loans', - parentEntityId: this.loanDetailsData.id, - name: dialogResponse.fileName, - description: dialogResponse.description, - fileName: dialogResponse.file.name - }); - this.documentsTable.renderRows(); - }); - } + downloadDocument(documentId: string) { + this.loansService.downloadLoanDocument(this.entityId, documentId).subscribe(res => { + const url = window.URL.createObjectURL(res); + window.open(url); }); } - deleteDocument(documentId: any, index: any) { - const deleteDocumentDialogRef = this.dialog.open(DeleteDialogComponent, { - data: { deleteContext: `document id:${documentId}` } - }); - deleteDocumentDialogRef.afterClosed().subscribe((response: any) => { - if (response.delete) { - this.loansService.deleteLoanDocument(this.loanDetailsData.id, documentId).subscribe((res: any) => { - this.loanDocuments.splice(index, 1); - this.documentsTable.renderRows(); - }); - } - }); + uploadDocument(formData: FormData): any { + return this.loansService.loadLoanDocument(this.entityId, formData); + } + + deleteDocument(documentId: any) { + this.loansService.deleteLoanDocument(this.entityId, documentId).subscribe((res: any) => {}); } } diff --git a/src/app/loans/loans-view/loans-view.component.ts b/src/app/loans/loans-view/loans-view.component.ts index 9699bbf62..a2afd5e33 100644 --- a/src/app/loans/loans-view/loans-view.component.ts +++ b/src/app/loans/loans-view/loans-view.component.ts @@ -54,7 +54,7 @@ export class LoansViewComponent implements OnInit { this.recalculateInterest = this.loanDetailsData.recalculateInterest || true; this.status = this.loanDetailsData.status.value; if (this.loanDetailsData.status.active && this.loanDetailsData.multiDisburseLoan) { - if (this.loanDetailsData) { + if (this.loanDetailsData && this.loanDetailsData.transactions) { this.loanDetailsData.transactions.forEach((transaction: any) => { if (transaction.type.disbursement) { this.disburseTransactionNo++; diff --git a/src/app/loans/loans-view/notes-tab/notes-tab.component.html b/src/app/loans/loans-view/notes-tab/notes-tab.component.html index 77371bf9d..04cf7318f 100644 --- a/src/app/loans/loans-view/notes-tab/notes-tab.component.html +++ b/src/app/loans/loans-view/notes-tab/notes-tab.component.html @@ -1,32 +1,7 @@ -
-

Notes

-
-
- - - - -
-
- - - -

{{loanNote.note}}

-

- Created by: {{loanNote.createdByUsername}}
- Date: {{loanNote.createdOn | dateFormat}} -

-
- - -
-
-
-
+ + diff --git a/src/app/loans/loans-view/notes-tab/notes-tab.component.scss b/src/app/loans/loans-view/notes-tab/notes-tab.component.scss index b40728956..e69de29bb 100644 --- a/src/app/loans/loans-view/notes-tab/notes-tab.component.scss +++ b/src/app/loans/loans-view/notes-tab/notes-tab.component.scss @@ -1,4 +0,0 @@ -.tab-container { - padding: 1%; - margin: 1%; -} diff --git a/src/app/loans/loans-view/notes-tab/notes-tab.component.ts b/src/app/loans/loans-view/notes-tab/notes-tab.component.ts index 8d992e09b..7944f713e 100644 --- a/src/app/loans/loans-view/notes-tab/notes-tab.component.ts +++ b/src/app/loans/loans-view/notes-tab/notes-tab.component.ts @@ -1,11 +1,7 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { MatDialog } from '@angular/material/dialog'; -import { FormGroup, FormBuilder, Validators } from '@angular/forms'; /** Custom Components */ -import { DeleteDialogComponent } from '../../../shared/delete-dialog/delete-dialog.component'; -import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component'; /** Custom Services */ import { LoansService } from '../../loans.service'; @@ -18,84 +14,44 @@ import { AuthenticationService } from '../../../core/authentication/authenticati }) export class NotesTabComponent implements OnInit { - loanId: string; + entityId: string; username: string; - loanNotes: any; - noteForm: FormGroup; - @ViewChild('formRef', { static: true }) formRef: any; - + entityNotes: any; constructor(private route: ActivatedRoute, - private formBuilder: FormBuilder, private loansService: LoansService, - private authenticationService: AuthenticationService, - private dialog: MatDialog) { + private authenticationService: AuthenticationService) { const savedCredentials = this.authenticationService.getCredentials(); this.username = savedCredentials.username; - this.loanId = this.route.parent.snapshot.params['loanId']; + this.entityId = this.route.parent.snapshot.params['loanId']; this.route.data.subscribe((data: { loanNotes: any }) => { - this.loanNotes = data.loanNotes; + this.entityNotes = data.loanNotes; }); } - ngOnInit() { - this.createNoteForm(); - } + ngOnInit() { } - createNoteForm() { - this.noteForm = this.formBuilder.group({ - 'note': ['', Validators.required] - }); - } - - submit() { - this.loansService.createLoanNote(this.loanId, this.noteForm.value).subscribe((response: any) => { - this.loanNotes.push({ + addNote(noteContent: any) { + this.loansService.createLoanNote(this.entityId, noteContent).subscribe((response: any) => { + this.entityNotes.push({ id: response.resourceId, createdByUsername: this.username, createdOn: new Date(), - note: this.noteForm.value.note + note: noteContent.note }); - this.formRef.resetForm(); }); } - editNote(noteId: string, noteContent: string, index: number) { - const editNoteDialogRef = this.dialog.open(FormDialogComponent, { - data: { formfields: [{ - controlName: 'note', - required: true, - value: noteContent, - controlType: 'input', - label: 'Note' - }], - layout: { - columns: 1, - addButtonText: 'Confirm' - }, - title: 'Edit Note' - } - }); - editNoteDialogRef.afterClosed().subscribe((response: any) => { - if (response.data) { - this.loansService.editLoanNote(this.loanId, noteId, response.data.value).subscribe(() => { - this.loanNotes[index].note = response.data.value.note; - }); - } + editNote(noteId: string, noteContent: any, index: number) { + this.loansService.editLoanNote(this.entityId, noteId, noteContent).subscribe(() => { + this.entityNotes[index].note = noteContent.note; }); } deleteNote(noteId: string, index: number) { - const deleteNoteDialogRef = this.dialog.open(DeleteDialogComponent, { - data: { deleteContext: `Note id:${noteId}` } - }); - deleteNoteDialogRef.afterClosed().subscribe((response: any) => { - if (response.delete) { - this.loansService.deleteLoanNote(this.loanId, noteId) - .subscribe(() => { - this.loanNotes.splice(index, 1); - }); - } + this.loansService.deleteLoanNote(this.entityId, noteId) + .subscribe(() => { + this.entityNotes.splice(index, 1); }); } diff --git a/src/app/loans/loans-view/view-charge/view-charge.component.html b/src/app/loans/loans-view/view-charge/view-charge.component.html index cfd2b1b43..9ab071e9f 100644 --- a/src/app/loans/loans-view/view-charge/view-charge.component.html +++ b/src/app/loans/loans-view/view-charge/view-charge.component.html @@ -37,6 +37,8 @@
+
+
Name diff --git a/src/app/loans/loans-view/view-charge/view-charge.component.scss b/src/app/loans/loans-view/view-charge/view-charge.component.scss index 56668f14f..7fa0ec4ad 100644 --- a/src/app/loans/loans-view/view-charge/view-charge.component.scss +++ b/src/app/loans/loans-view/view-charge/view-charge.component.scss @@ -1,6 +1,8 @@ +@import "assets/styles/helper"; + .container { max-width: 37rem; - + .content { div { margin: 1rem 0; @@ -8,3 +10,13 @@ } } } + +.paid { + background-color: $status-active; + height: 4px; +} + +.not-paid { + background-color: $status-active-overdue; + height: 4px; +} diff --git a/src/app/loans/loans-view/view-charge/view-charge.component.ts b/src/app/loans/loans-view/view-charge/view-charge.component.ts index 2378d21ca..cb77c65f2 100644 --- a/src/app/loans/loans-view/view-charge/view-charge.component.ts +++ b/src/app/loans/loans-view/view-charge/view-charge.component.ts @@ -52,7 +52,7 @@ export class ViewChargeComponent { private settingsService: SettingsService) { this.route.data.subscribe((data: { loansAccountCharge: any, loanDetailsData: any }) => { this.chargeData = data.loansAccountCharge; - this.allowPayCharge = (this.chargeData.chargeTimeType.code === 'chargeTimeType.instalmentFee'); + this.allowPayCharge = (this.chargeData.chargePayable && !this.chargeData.paid); this.allowWaive = !this.chargeData.chargeTimeType.waived; this.loansAccountData = data.loanDetailsData; }); @@ -72,7 +72,7 @@ export class ViewChargeComponent { }) ]; const data = { - title: 'Pay Charge', + title: `Pay Charge ${this.chargeData.id}`, layout: { addButtonText: 'Confirm' }, formfields: formfields }; @@ -173,6 +173,10 @@ export class ViewChargeComponent { }); } + loanChargeColor(): string { + return this.chargeData.paid ? 'paid' : 'not-paid'; + } + /** * Refetches data fot the component * TODO: Replace by a custom reload component instead of hard-coded back-routing. diff --git a/src/app/loans/loans.module.ts b/src/app/loans/loans.module.ts index 2952e51ed..70e9d348f 100644 --- a/src/app/loans/loans.module.ts +++ b/src/app/loans/loans.module.ts @@ -73,6 +73,7 @@ import { LoanDelinquencyTagsTabComponent } from './loans-view/loan-delinquency-t import { LoansAccountScheduleStepComponent } from './loans-account-stepper/loans-account-schedule-step/loans-account-schedule-step.component'; import { EditRepaymentScheduleComponent } from './loans-view/loan-account-actions/edit-repayment-schedule/edit-repayment-schedule.component'; import { DisburseToSavingsAccountComponent } from './loans-view/loan-account-actions/disburse-to-savings-account/disburse-to-savings-account.component'; +import { LoansAccountDatatableStepComponent } from './loans-account-stepper/loans-account-datatable-step/loans-account-datatable-step.component'; /** * Loans Module @@ -144,7 +145,8 @@ import { DisburseToSavingsAccountComponent } from './loans-view/loan-account-act LoanDelinquencyTagsTabComponent, LoansAccountScheduleStepComponent, EditRepaymentScheduleComponent, - DisburseToSavingsAccountComponent + DisburseToSavingsAccountComponent, + LoansAccountDatatableStepComponent ], providers: [ ], }) diff --git a/src/app/loans/loans.service.ts b/src/app/loans/loans.service.ts index ef813d93c..fa043dd6d 100644 --- a/src/app/loans/loans.service.ts +++ b/src/app/loans/loans.service.ts @@ -322,6 +322,10 @@ export class LoansService { return this.http.get(`/loans/${loanId}/documents`); } + downloadLoanDocument(parentEntityId: string, documentId: string) { + return this.http.get(`/loans/${parentEntityId}/documents/${documentId}/attachment`, { responseType: 'blob' }); + } + deleteLoanDocument(loanId: any, documentId: any): Observable { return this.http.delete(`/loans/${loanId}/documents/${documentId}`); } diff --git a/src/app/savings/common-resolvers/saving-documents.resolver.spec.ts b/src/app/savings/common-resolvers/saving-documents.resolver.spec.ts new file mode 100644 index 000000000..5531c2b4f --- /dev/null +++ b/src/app/savings/common-resolvers/saving-documents.resolver.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { SavingDocumentsResolver } from './saving-documents.resolver'; + +describe('SavingDocumentsResolver', () => { + let resolver: SavingDocumentsResolver; + + beforeEach(() => { + TestBed.configureTestingModule({}); + resolver = TestBed.inject(SavingDocumentsResolver); + }); + + it('should be created', () => { + expect(resolver).toBeTruthy(); + }); +}); diff --git a/src/app/savings/common-resolvers/saving-documents.resolver.ts b/src/app/savings/common-resolvers/saving-documents.resolver.ts new file mode 100644 index 000000000..519c7910b --- /dev/null +++ b/src/app/savings/common-resolvers/saving-documents.resolver.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { + Resolve, + ActivatedRouteSnapshot +} from '@angular/router'; +import { Observable } from 'rxjs'; +import { SavingsService } from '../savings.service'; + +@Injectable({ + providedIn: 'root' +}) +export class SavingDocumentsResolver implements Resolve { + + /** + * @param {SavingsService} savingsService Savings service. + */ + constructor(private savingsService: SavingsService) { } + + /** + * Returns the Savings data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const savingAccountId = route.parent.paramMap.get('savingAccountId'); + return this.savingsService.getSavingsDocuments(savingAccountId); + } +} diff --git a/src/app/savings/common-resolvers/saving-notes.resolver.spec.ts b/src/app/savings/common-resolvers/saving-notes.resolver.spec.ts new file mode 100644 index 000000000..24bc375e0 --- /dev/null +++ b/src/app/savings/common-resolvers/saving-notes.resolver.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { SavingNotesResolver } from './saving-notes.resolver'; + +describe('SavingNotesResolver', () => { + let resolver: SavingNotesResolver; + + beforeEach(() => { + TestBed.configureTestingModule({}); + resolver = TestBed.inject(SavingNotesResolver); + }); + + it('should be created', () => { + expect(resolver).toBeTruthy(); + }); +}); diff --git a/src/app/savings/common-resolvers/saving-notes.resolver.ts b/src/app/savings/common-resolvers/saving-notes.resolver.ts new file mode 100644 index 000000000..a418126de --- /dev/null +++ b/src/app/savings/common-resolvers/saving-notes.resolver.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { + Resolve, + ActivatedRouteSnapshot +} from '@angular/router'; +import { Observable } from 'rxjs'; +import { SavingsService } from '../savings.service'; + +@Injectable({ + providedIn: 'root' +}) +export class SavingNotesResolver implements Resolve { + + /** + * @param {SavingsService} savingsService Savings service. + */ + constructor(private savingsService: SavingsService) { } + + /** + * Returns the Savings data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const savingAccountId = route.parent.paramMap.get('savingAccountId'); + return this.savingsService.getSavingsNotes(savingAccountId); + } +} diff --git a/src/app/savings/savings-account-view/charges-tab/charges-tab.component.ts b/src/app/savings/savings-account-view/charges-tab/charges-tab.component.ts index a86cb3f8a..1bb0025d8 100644 --- a/src/app/savings/savings-account-view/charges-tab/charges-tab.component.ts +++ b/src/app/savings/savings-account-view/charges-tab/charges-tab.component.ts @@ -135,7 +135,7 @@ export class ChargesTabComponent implements OnInit { dateFormat, locale }; - this.savingsService.executeSavingsAccountChargesCommand(this.savingsAccountData.id, 'paycharge', dataObject, chargeId) + this.savingsService.executeSavingsAccountChargesCommand(this.savingsAccountData.id, 'pay', dataObject, chargeId) .subscribe(() => { this.reload(); }); diff --git a/src/app/savings/savings-account-view/notes-tab/notes-tab.component.html b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.html new file mode 100644 index 000000000..04cf7318f --- /dev/null +++ b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.html @@ -0,0 +1,7 @@ + + diff --git a/src/app/savings/savings-account-view/notes-tab/notes-tab.component.scss b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/savings/savings-account-view/notes-tab/notes-tab.component.spec.ts b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.spec.ts new file mode 100644 index 000000000..017254b1f --- /dev/null +++ b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotesTabComponent } from './notes-tab.component'; + +describe('NotesTabComponent', () => { + let component: NotesTabComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ NotesTabComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NotesTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/savings/savings-account-view/notes-tab/notes-tab.component.ts b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.ts new file mode 100644 index 000000000..98f0647cc --- /dev/null +++ b/src/app/savings/savings-account-view/notes-tab/notes-tab.component.ts @@ -0,0 +1,55 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { AuthenticationService } from 'app/core/authentication/authentication.service'; +import { SavingsService } from 'app/savings/savings.service'; + +@Component({ + selector: 'mifosx-notes-tab', + templateUrl: './notes-tab.component.html', + styleUrls: ['./notes-tab.component.scss'] +}) +export class NotesTabComponent implements OnInit { + + entityId: string; + username: string; + entityNotes: any; + + constructor(private route: ActivatedRoute, + private savingsService: SavingsService, + private authenticationService: AuthenticationService) { + const savedCredentials = this.authenticationService.getCredentials(); + this.username = savedCredentials.username; + this.entityId = this.route.parent.snapshot.params['savingAccountId']; + this.route.data.subscribe((data: { savingAccountNotes: any }) => { + this.entityNotes = data.savingAccountNotes; + }); + } + + ngOnInit() { + } + + addNote(noteContent: any) { + this.savingsService.createSavingsNote(this.entityId, noteContent).subscribe((response: any) => { + this.entityNotes.push({ + id: response.resourceId, + createdByUsername: this.username, + createdOn: new Date(), + note: noteContent + }); + }); + } + + editNote(noteId: string, noteContent: any, index: number) { + this.savingsService.editSavingsNote(this.entityId, noteId, noteContent).subscribe(() => { + this.entityNotes[index].note = noteContent.note; + }); + } + + deleteNote(noteId: string, index: number) { + this.savingsService.deleteSavingsNote(this.entityId, noteId) + .subscribe(() => { + this.entityNotes.splice(index, 1); + }); + } + +} diff --git a/src/app/savings/savings-account-view/savings-account-view.component.html b/src/app/savings/savings-account-view/savings-account-view.component.html index b2e186e22..ae15da436 100644 --- a/src/app/savings/savings-account-view/savings-account-view.component.html +++ b/src/app/savings/savings-account-view/savings-account-view.component.html @@ -34,10 +34,10 @@ {{entityType}} Name: {{savingsAccountData.clientName || savingsAccountData.groupName}} ({{savingsAccountData.clientAccountNo}})
- Current Balances: + Current Balances : {{savingsAccountData.currency.displaySymbol}}{{savingsAccountData.summary.accountBalance | number}}
- Available Balance: + Available Balance : {{savingsAccountData.currency.displaySymbol}}{{savingsAccountData.summary.availableBalance | number}}
@@ -310,6 +310,14 @@ [active]="charges.isActive"> Charges + + Savings Documents + + + Notes + + diff --git a/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.scss b/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.spec.ts b/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.spec.ts new file mode 100644 index 000000000..80b91a7fe --- /dev/null +++ b/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SavingsDocumentsTabComponent } from './savings-documents-tab.component'; + +describe('SavingsDocumentsTabComponent', () => { + let component: SavingsDocumentsTabComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SavingsDocumentsTabComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SavingsDocumentsTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.ts b/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.ts new file mode 100644 index 000000000..b0829ac7b --- /dev/null +++ b/src/app/savings/savings-account-view/savings-documents-tab/savings-documents-tab.component.ts @@ -0,0 +1,71 @@ +import { Component, OnInit } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute } from '@angular/router'; +import { UploadDocumentDialogComponent } from 'app/clients/clients-view/custom-dialogs/upload-document-dialog/upload-document-dialog.component'; +import { SavingsService } from 'app/savings/savings.service'; +import { SettingsService } from 'app/settings/settings.service'; +import { environment } from 'environments/environment'; + +@Component({ + selector: 'mifosx-savings-documents-tab', + templateUrl: './savings-documents-tab.component.html', + styleUrls: ['./savings-documents-tab.component.scss'] +}) +export class SavingsDocumentsTabComponent implements OnInit { + + /** Stores the resolved savings documents data */ + entityDocuments: any; + /** Stores the saving Account Id */ + entityId: string; + entityType: string = 'savings'; + + /** + * Retrieves the savings data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + */ + constructor(private route: ActivatedRoute, + private savingsService: SavingsService, + private settingsService: SettingsService, + public dialog: MatDialog) { + this.route.data.subscribe((data: { savingsDocuments: any }) => { + this.setSavingsDocumentsData(data.savingsDocuments); + }); + this.entityId = this.route.parent.snapshot.params['savingAccountId']; + } + + ngOnInit() { + } + + setSavingsDocumentsData(data: any) { + data.forEach((ele: any) => { + ele.docUrl = this.settingsService.serverUrl + '/savings/' + ele.parentEntityId + '/documents/' + ele.id + '/attachment?tenantIdentifier=' + environment.fineractPlatformTenantId; + if (ele.fileName) { + if (ele.fileName.toLowerCase().indexOf('.jpg') !== -1 || ele.fileName.toLowerCase().indexOf('.jpeg') !== -1 || ele.fileName.toLowerCase().indexOf('.png') !== -1) { + ele.fileIsImage = true; + } + } + if (ele.type) { + if (ele.type.toLowerCase().indexOf('image') !== -1) { + ele.fileIsImage = true; + } + } + }); + this.entityDocuments = data; + } + + downloadDocument(parentEntityId: string, documentId: string) { + this.savingsService.downloadSavingsDocument(parentEntityId, documentId).subscribe(res => { + const url = window.URL.createObjectURL(res); + window.open(url); + }); + } + + uploadDocument(formData: FormData): any { + return this.savingsService.loadSavingsDocument(this.entityId, formData); + } + + deleteDocument(documentId: any) { + this.savingsService.deleteSavingsDocument(this.entityId, documentId).subscribe((res: any) => {}); + } + +} diff --git a/src/app/savings/savings-account-view/view-charge/view-charge.component.ts b/src/app/savings/savings-account-view/view-charge/view-charge.component.ts index e337b4d59..23bdb777e 100644 --- a/src/app/savings/savings-account-view/view-charge/view-charge.component.ts +++ b/src/app/savings/savings-account-view/view-charge/view-charge.component.ts @@ -93,7 +93,7 @@ export class ViewChargeComponent { dateFormat, locale }; - this.savingsService.executeSavingsAccountChargesCommand(this.chargeData.accountId, 'paycharge', dataObject, this.chargeData.id) + this.savingsService.executeSavingsAccountChargesCommand(this.chargeData.accountId, 'pay', dataObject, this.chargeData.id) .subscribe(() => { this.reload(); }); diff --git a/src/app/savings/savings-routing.module.ts b/src/app/savings/savings-routing.module.ts index 327d5778b..2605e4565 100644 --- a/src/app/savings/savings-routing.module.ts +++ b/src/app/savings/savings-routing.module.ts @@ -37,6 +37,11 @@ import { GSIMAccountsResolver } from 'app/groups/common-resolvers/gsim-account-r import { GroupAccountsResolver } from 'app/groups/common-resolvers/group-account.resolver'; import { GSIMViewResolver } from './gsim-account/gsim-account.resolver'; import { GroupViewResolver } from 'app/groups/common-resolvers/group-view.resolver'; +import { SavingsDocumentsTabComponent } from './savings-account-view/savings-documents-tab/savings-documents-tab.component'; +import { NotesTabComponent } from './savings-account-view/notes-tab/notes-tab.component'; +import { SavingNotesResolver } from './common-resolvers/saving-notes.resolver'; +import { SavingDocumentsResolver } from './common-resolvers/saving-documents.resolver'; +import { DocumentsTabComponent } from 'app/clients/clients-view/documents-tab/documents-tab.component'; /** Savings Routes */ const routes: Routes = [ { @@ -91,6 +96,22 @@ const routes: Routes = [ component: StandingInstructionsTabComponent, data: { title: extract('Savings Account SIH'), breadcrumb: 'Standing Instructions', routeParamBreadcrumb: false } }, + { + path: 'notes', + component: NotesTabComponent, + data: { title: extract('Savings Account Notes'), breadcrumb: 'Notes', routeParamBreadcrumb: false }, + resolve: { + savingAccountNotes: SavingNotesResolver + } + }, + { + path: 'documents', + component: DocumentsTabComponent, + data: { title: extract('Savings Account Documents'), breadcrumb: 'Documents', routeParamBreadcrumb: false }, + resolve: { + savingAccountDocuments: SavingDocumentsResolver + } + }, { path: 'datatables', children: [ @@ -184,6 +205,26 @@ const routes: Routes = [ savingsAccountActionData: SavingsAccountActionsResolver } }, + { + path: 'documents', + data: { title: extract('Savings Account Documents'), breadcrumb: 'Documents', routeParamBreadcrumb: false }, + children: [ + { + path: '', + redirectTo: '../documents', pathMatch: 'prefix' + }, + ] + }, + { + path: 'notes', + data: { title: extract('Savings Account Notes'), breadcrumb: 'Notes', routeParamBreadcrumb: false }, + children: [ + { + path: '', + redirectTo: '../notes', pathMatch: 'prefix' + }, + ] + }, { path: 'transfer-funds', loadChildren: () => import('../account-transfers/account-transfers.module').then(m => m.AccountTransfersModule) diff --git a/src/app/savings/savings.module.ts b/src/app/savings/savings.module.ts index 643e96228..cd30dfd65 100644 --- a/src/app/savings/savings.module.ts +++ b/src/app/savings/savings.module.ts @@ -49,6 +49,8 @@ import { GsimAccountComponent } from './gsim-account/gsim-account.component'; import { CreateGsimAccountComponent } from './gsim-account/create-gsim-account/create-gsim-account.component'; import { ManageSavingsAccountComponent } from './saving-account-actions/manage-savings-account/manage-savings-account.component'; import { ReleaseAmountDialogComponent } from './savings-account-view/custom-dialogs/release-amount-dialog/release-amount-dialog.component'; +import { SavingsDocumentsTabComponent } from './savings-account-view/savings-documents-tab/savings-documents-tab.component'; +import { NotesTabComponent } from './savings-account-view/notes-tab/notes-tab.component'; /** @@ -104,7 +106,9 @@ import { ReleaseAmountDialogComponent } from './savings-account-view/custom-dial GsimAccountComponent, CreateGsimAccountComponent, ManageSavingsAccountComponent, - ReleaseAmountDialogComponent + ReleaseAmountDialogComponent, + SavingsDocumentsTabComponent, + NotesTabComponent ], providers: [ ] }) diff --git a/src/app/savings/savings.service.ts b/src/app/savings/savings.service.ts index a523ea0ac..3d1cda9d8 100644 --- a/src/app/savings/savings.service.ts +++ b/src/app/savings/savings.service.ts @@ -286,4 +286,61 @@ export class SavingsService { return this.http.post(`/savingsaccounts/gsim`, gsimData); } + /** + * @param savingAccountId Savings Id + * @returns The notes for particular loan + */ + getSavingsNotes(savingAccountId: string): Observable { + return this.http.get(`/savings/${savingAccountId}/notes`); + } + + /** + * Adds a note to the particular Savings Id + * @param savingAccountId Savings ID + * @param noteData Note Data to be added + * @returns {Observable} + */ + createSavingsNote(savingAccountId: string, noteData: any): Observable { + return this.http.post(`/savings/${savingAccountId}/notes`, noteData); + } + + /** + * Edits the Savings Note + * @param savingAccountId Savings ID + * @param noteId Note ID + * @param noteData Note Data + */ + editSavingsNote(savingAccountId: string, noteId: string, noteData: any) { + return this.http.put(`/savings/${savingAccountId}/notes/${noteId}`, noteData); + } + + /** + * Deletes the particular Note + * @param savingAccountId Savings ID + * @param noteId Note ID + */ + deleteSavingsNote(savingAccountId: string, noteId: string) { + return this.http.delete(`/savings/${savingAccountId}/notes/${noteId}`); + } + + /** + * @param savingAccountId Savings Account Id of account to get data for. + * @returns {Observable} Savings data. + */ + getSavingsDocuments(savingAccountId: any): Observable { + return this.http.get(`/savings/${savingAccountId}/documents`); + } + + downloadSavingsDocument(parentEntityId: string, documentId: string) { + return this.http.get(`/savings/${parentEntityId}/documents/${documentId}/attachment`, { responseType: 'blob' }); + } + + deleteSavingsDocument(savingAccountId: any, documentId: any): Observable { + return this.http.delete(`/savings/${savingAccountId}/documents/${documentId}`); + } + + loadSavingsDocument(savingAccountId: any, data: any): Observable { + return this.http.post(`/savings/${savingAccountId}/documents`, data); + } + } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index b17559b44..fe5368817 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -29,6 +29,9 @@ import { MaterialModule } from './material.module'; import { TranslateModule } from '@ngx-translate/core'; import { ExternalIdentifierComponent } from './external-identifier/external-identifier.component'; import { PipesModule } from 'app/pipes/pipes.module'; +import { EntityNotesTabComponent } from './tabs/entity-notes-tab/entity-notes-tab.component'; +import { EntityDocumentsTabComponent } from './tabs/entity-documents-tab/entity-documents-tab.component'; +import { DirectivesModule } from 'app/directives/directives.module'; /** * Shared Module @@ -42,7 +45,8 @@ import { PipesModule } from 'app/pipes/pipes.module'; MaterialModule, ReactiveFormsModule, TranslateModule.forRoot(), - PipesModule + PipesModule, + DirectivesModule ], declarations: [ FormfieldComponent, @@ -63,7 +67,9 @@ import { PipesModule } from 'app/pipes/pipes.module'; SearchToolComponent, ServerSelectorComponent, TenantSelectorComponent, - ExternalIdentifierComponent + ExternalIdentifierComponent, + EntityNotesTabComponent, + EntityDocumentsTabComponent ], exports: [ FileUploadComponent, @@ -81,7 +87,9 @@ import { PipesModule } from 'app/pipes/pipes.module'; ReactiveFormsModule, TranslateModule, TenantSelectorComponent, - ExternalIdentifierComponent + ExternalIdentifierComponent, + EntityNotesTabComponent, + EntityDocumentsTabComponent ] }) export class SharedModule { } diff --git a/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.html b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.html new file mode 100644 index 000000000..f9eee5951 --- /dev/null +++ b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.html @@ -0,0 +1,50 @@ +
+
+ +

Documents

+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Name {{ document.name }} Description {{ document.description }} File Name {{ document.fileName }} Actions + + +
+ + + +
diff --git a/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.scss b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.scss new file mode 100644 index 000000000..223688cb7 --- /dev/null +++ b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.scss @@ -0,0 +1,15 @@ +table { + width: 100%; + margin-top: 3%; + .document-action-button { + min-width: 26px; + padding: 0 6px; + margin: 4px; + line-height: 25px; + } +} + +.tab-container { + padding: 1%; + margin: 1%; +} diff --git a/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.spec.ts b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.spec.ts new file mode 100644 index 000000000..2db427eec --- /dev/null +++ b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EntityDocumentsTabComponent } from './entity-documents-tab.component'; + +describe('EntityDocumentsTabComponent', () => { + let component: EntityDocumentsTabComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EntityDocumentsTabComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EntityDocumentsTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.ts b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.ts new file mode 100644 index 000000000..45bc21233 --- /dev/null +++ b/src/app/shared/tabs/entity-documents-tab/entity-documents-tab.component.ts @@ -0,0 +1,108 @@ +import { Component, Input, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { MatTable, MatTableDataSource } from '@angular/material/table'; +import { UploadDocumentDialogComponent } from 'app/clients/clients-view/custom-dialogs/upload-document-dialog/upload-document-dialog.component'; +import { ClientsService } from 'app/clients/clients.service'; +import { LoansService } from 'app/loans/loans.service'; +import { SavingsService } from 'app/savings/savings.service'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'mifosx-entity-documents-tab', + templateUrl: './entity-documents-tab.component.html', + styleUrls: ['./entity-documents-tab.component.scss'] +}) +export class EntityDocumentsTabComponent implements OnInit { + @ViewChild('documentsTable', { static: true }) documentsTable: MatTable; + + @Input() entityId: string; + @Input() entityType: string; + @Input() entityDocuments: any; + + @Input() callbackUpload: (documentData: FormData) => Observable; + @Input() callbackDownload: (documentId: string) => void; + @Input() callbackDelete: (documentId: string) => void; + + /** Status of the loan account */ + status: any; + /** Choice */ + choice: boolean; + + /** Columns to be displayed in loan documents table. */ + displayedColumns: string[] = ['name', 'description', 'filename', 'actions']; + /** Data source for loan documents table. */ + dataSource: MatTableDataSource; + + /** Paginator for codes table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for codes table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * + * @param {MatDialog} dialog Dialog for Inputs. + * @param {SavingsService} savingsService Savings Account services. + * @param {LoansService} loansService Loan Account services. + * @param {ClientsService} clientsService Client services. + */ + constructor(public dialog: MatDialog, + private savingsService: SavingsService, + private loansService: LoansService, + private clientsService: ClientsService) { } + + ngOnInit() { + this.dataSource = new MatTableDataSource(this.entityDocuments); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + downloadDocument(documentId: string) { + this.callbackDownload(documentId); + } + + uploadDocument() { + const uploadDocumentDialogRef = this.dialog.open(UploadDocumentDialogComponent, { + data: { documentIdentifier: false, entityType: 'Loan' } + }); + uploadDocumentDialogRef.afterClosed().subscribe((dialogResponse: any) => { + if (dialogResponse) { + const formData: FormData = new FormData; + formData.append('name', dialogResponse.fileName); + formData.append('file', dialogResponse.file); + formData.append('description', dialogResponse.description); + this.callbackUpload(formData).subscribe((res: any) => { + this.entityDocuments.push({ + id: res.resourceId, + parentEntityType: this.entityType, + parentEntityId: this.entityId, + name: dialogResponse.fileName, + description: dialogResponse.description, + fileName: dialogResponse.file.name + }); + this.documentsTable.renderRows(); + }); + } + }); + } + + deleteDocument(documentId: string, name: number) { + const deleteDocumentDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `Document: ${name}` } + }); + deleteDocumentDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.callbackDelete(documentId); + for (let i = 0; i < this.entityDocuments.length; i++) { + if (this.entityDocuments[i].id === documentId) { + this.entityDocuments.splice(i, 1); + } + } + this.documentsTable.renderRows(); + } + }); + } + +} diff --git a/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.html b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.html new file mode 100644 index 000000000..5d8039bdc --- /dev/null +++ b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.html @@ -0,0 +1,35 @@ +
+ +

Notes

+ +
+
+ + + + +
+
+ + + + +

{{ entityNote.note }}

+

+ Created by: {{entityNote.createdByUsername}}
+ Date: {{entityNote.createdOn | dateFormat}} +

+
+ + +
+
+
+
diff --git a/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.scss b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.scss new file mode 100644 index 000000000..b40728956 --- /dev/null +++ b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.scss @@ -0,0 +1,4 @@ +.tab-container { + padding: 1%; + margin: 1%; +} diff --git a/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.spec.ts b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.spec.ts new file mode 100644 index 000000000..975aadeb4 --- /dev/null +++ b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EntityNotesTabComponent } from './entity-notes-tab.component'; + +describe('EntityNotesTabComponent', () => { + let component: EntityNotesTabComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EntityNotesTabComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EntityNotesTabComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.ts b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.ts new file mode 100644 index 000000000..ceab73be7 --- /dev/null +++ b/src/app/shared/tabs/entity-notes-tab/entity-notes-tab.component.ts @@ -0,0 +1,83 @@ +import { Component, Input, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ClientsService } from 'app/clients/clients.service'; +import { LoansService } from 'app/loans/loans.service'; +import { SavingsService } from 'app/savings/savings.service'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; +import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component'; + +@Component({ + selector: 'mifosx-entity-notes-tab', + templateUrl: './entity-notes-tab.component.html', + styleUrls: ['./entity-notes-tab.component.scss'] +}) +export class EntityNotesTabComponent implements OnInit { + + @ViewChild('formRef', { static: true }) formRef: any; + + @Input() entityId: string; + @Input() entityNotes: any; + + @Input() callbackAdd: (note: any) => void; + @Input() callbackEdit: (noteId: string, note: string, index: number) => void; + @Input() callbackDelete: (noteId: string, index: number) => void; + + noteForm: FormGroup; + + constructor(private formBuilder: FormBuilder, + private savingsService: SavingsService, + private loansService: LoansService, + private clientsService: ClientsService, + private dialog: MatDialog) { } + + ngOnInit() { + this.createNoteForm(); + } + + createNoteForm() { + this.noteForm = this.formBuilder.group({ + 'note': ['', Validators.required] + }); + } + + addNote() { + this.callbackAdd(this.noteForm.value); + this.formRef.resetForm(); + } + + editNote(noteId: string, noteContent: string, index: number) { + const editNoteDialogRef = this.dialog.open(FormDialogComponent, { + data: { formfields: [{ + controlName: 'note', + required: true, + value: noteContent, + controlType: 'input', + label: 'Note' + }], + layout: { + columns: 1, + addButtonText: 'Confirm' + }, + title: 'Edit Note' + } + }); + editNoteDialogRef.afterClosed().subscribe((response: any) => { + if (response.data && response.data.value.note !== noteContent) { + this.callbackEdit(noteId, response.data.value, index); + } + }); + } + + deleteNote(noteId: string, index: number) { + const deleteNoteDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `Note: ${this.entityNotes[index].note}` } + }); + deleteNoteDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.callbackDelete(noteId, index); + } + }); + } + +} diff --git a/src/assets/env.js b/src/assets/env.js index c3358b1c3..b6356d4ff 100644 --- a/src/assets/env.js +++ b/src/assets/env.js @@ -14,4 +14,6 @@ // Language Environment variables window["env"]["defaultLanguage"] = ''; window["env"]["supportedLanguages"] = ''; + + window['env']['preloadClients'] = ''; })(this); diff --git a/src/assets/env.template.js b/src/assets/env.template.js index 3a0566ee3..e011ea700 100644 --- a/src/assets/env.template.js +++ b/src/assets/env.template.js @@ -14,4 +14,6 @@ // Language Environment variables window["env"]["defaultLanguage"] = '$MIFOS_DEFAULT_LANGUAGE'; window["env"]["supportedLanguages"] = '$MIFOS_SUPPORTED_LANGUAGES'; + + window['env']['preloadClients'] = '$MIFOS_PRELOAD_CLIENTS'; })(this); diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 27251c5e9..9436d0a6c 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -22,7 +22,8 @@ export const environment = { serverUrl: '' }, defaultLanguage: window['env']['defaultLanguage'] || 'en-US', - supportedLanguages: window['env']['supportedLanguages'] || 'en-US,es-MX,fr-FR' + supportedLanguages: window['env']['supportedLanguages'] || 'en-US,es-MX,fr-FR', + preloadClients: window['env']['preloadClients'] || true }; // Server URL diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 38342b866..28061dfda 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -27,7 +27,8 @@ export const environment = { serverUrl: '' }, defaultLanguage: window['env']['defaultLanguage'] || 'en-US', - supportedLanguages: window['env']['supportedLanguages'] || 'en-US,es-MX,fr-FR' + supportedLanguages: window['env']['supportedLanguages'] || 'en-US,es-MX,fr-FR', + preloadClients: window['env']['preloadClients'] || true }; // Server URL