Export report table to CSV file using defined delimiter (#1798)
Co-authored-by: Jose Alberto Hernandez <alberto@blue-daemon.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
dd4b37c060
commit
3b140e6f34
@@ -152,6 +152,18 @@ MIFOS_DEFAULT_LANGUAGE=en-US
|
|||||||
MIFOS_SUPPORTED_LANGUAGES=en-US,fr-FR
|
MIFOS_SUPPORTED_LANGUAGES=en-US,fr-FR
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Setting for applying the Client preload in the Clients view, Default true
|
||||||
|
```
|
||||||
|
MIFOS_PRELOAD_CLIENTS=false
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Setting for exporting report table to CSV file using this field delimiter
|
||||||
|
```
|
||||||
|
MIFOS_DEFAULT_CHAR_DELIMITER=,
|
||||||
|
```
|
||||||
|
|
||||||
For more information look the env.sample file in the root directory of the project
|
For more information look the env.sample file in the root directory of the project
|
||||||
|
|
||||||
## Want to help? [](https://github.com/openMF/web-app/issues)
|
## Want to help? [](https://github.com/openMF/web-app/issues)
|
||||||
|
|||||||
+5
-1
@@ -10,9 +10,13 @@ FINERACT_API_VERSION=/v1
|
|||||||
|
|
||||||
FINERACT_PLATFORM_TENANT_IDENTIFIER=default
|
FINERACT_PLATFORM_TENANT_IDENTIFIER=default
|
||||||
|
|
||||||
# Tenant Identifiers list delimited by colon
|
# Tenant Identifiers list delimited by comma
|
||||||
FINERACT_PLATFORM_TENANTS_IDENTIFIER=default
|
FINERACT_PLATFORM_TENANTS_IDENTIFIER=default
|
||||||
|
|
||||||
MIFOS_DEFAULT_LANGUAGE=en-US
|
MIFOS_DEFAULT_LANGUAGE=en-US
|
||||||
|
|
||||||
MIFOS_SUPPORTED_LANGUAGES=en-US,fr-FR
|
MIFOS_SUPPORTED_LANGUAGES=en-US,fr-FR
|
||||||
|
|
||||||
|
MIFOS_PRELOAD_CLIENTS=true
|
||||||
|
|
||||||
|
MIFOS_DEFAULT_CHAR_DELIMITER=,
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface DialogData {
|
||||||
|
heading?: string;
|
||||||
|
dialogContext: any;
|
||||||
|
submitLabel?: string;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class Dialogs {
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
public setColor(dataType: string): string {
|
||||||
|
let color = 'primary';
|
||||||
|
switch (dataType) {
|
||||||
|
case 'Basic':
|
||||||
|
color = 'primary';
|
||||||
|
break;
|
||||||
|
case 'Mild':
|
||||||
|
color = 'primary';
|
||||||
|
break;
|
||||||
|
case 'Strong':
|
||||||
|
color = 'warn';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
color = 'warn';
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -155,6 +155,7 @@ export class EditLoansAccountComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
loansAccountData.principal = loansAccountData.principalAmount;
|
loansAccountData.principal = loansAccountData.principalAmount;
|
||||||
delete loansAccountData.principalAmount;
|
delete loansAccountData.principalAmount;
|
||||||
|
delete loansAccountData.multiDisburseLoan;
|
||||||
this.loansService.updateLoansAccount(this.loanId, loansAccountData).subscribe((response: any) => {
|
this.loansService.updateLoansAccount(this.loanId, loansAccountData).subscribe((response: any) => {
|
||||||
this.router.navigate(['../'], { relativeTo: this.route });
|
this.router.navigate(['../'], { relativeTo: this.route });
|
||||||
});
|
});
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<mat-form-field fxFlex>
|
<mat-form-field fxFlex>
|
||||||
<mat-label>Note</mat-label>
|
<mat-label>Note</mat-label>
|
||||||
<textarea matInput required [formControl]="note" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
<textarea matInput [formControl]="note" cdkTextareaAutosize cdkAutosizeMinRows="2"></textarea>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
<ng-container matColumnDef="fromDate">
|
<ng-container matColumnDef="fromDate">
|
||||||
<th mat-header-cell *matHeaderCellDef matTooltip="Interest effective from date" mat-sort-header> From Date </th>
|
<th mat-header-cell *matHeaderCellDef matTooltip="Interest effective from date" mat-sort-header> From Date </th>
|
||||||
<td mat-cell *matCellDef="let floatingRatePeriod"> {{ floatingRatePeriod.fromDate | dateFormat : 'dd MMMM yyyy' }} </td>
|
<td mat-cell *matCellDef="let floatingRatePeriod"> {{ floatingRatePeriod.fromDate | dateFormat }} </td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="interestRate">
|
<ng-container matColumnDef="interestRate">
|
||||||
|
|||||||
+9
-23
@@ -12,8 +12,8 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan
|
|||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { ProductsService } from 'app/products/products.service';
|
import { ProductsService } from 'app/products/products.service';
|
||||||
import { SettingsService } from 'app/settings/settings.service';
|
|
||||||
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
||||||
|
import { LoanProducts } from '../loan-products';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-create-loan-product',
|
selector: 'mifosx-create-loan-product',
|
||||||
@@ -31,34 +31,28 @@ export class CreateLoanProductComponent implements OnInit {
|
|||||||
|
|
||||||
loanProductsTemplate: any;
|
loanProductsTemplate: any;
|
||||||
accountingRuleData = ['None', 'Cash', 'Accrual (periodic)', 'Accrual (upfront)'];
|
accountingRuleData = ['None', 'Cash', 'Accrual (periodic)', 'Accrual (upfront)'];
|
||||||
|
itemsByDefault: any[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ActivatedRoute} route Activated Route.
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
* @param {ProductsService} productsService Product Service.
|
* @param {ProductsService} productsService Product Service.
|
||||||
* @param {SettingsService} settingsService Settings Service
|
* @param {LoanProducts} loanProducts LoanProducts
|
||||||
* @param {Router} router Router for navigation.
|
* @param {Router} router Router for navigation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
private productsService: ProductsService,
|
private productsService: ProductsService,
|
||||||
private settingsService: SettingsService,
|
private loanProducts: LoanProducts,
|
||||||
private router: Router) {
|
private router: Router) {
|
||||||
this.route.data.subscribe((data: { loanProductsTemplate: any, configurations: any }) => {
|
this.route.data.subscribe((data: { loanProductsTemplate: any, configurations: any }) => {
|
||||||
this.loanProductsTemplate = data.loanProductsTemplate;
|
this.loanProductsTemplate = data.loanProductsTemplate;
|
||||||
const assetAccountData = this.loanProductsTemplate.accountingMappingOptions.assetAccountOptions || [];
|
const assetAccountData = this.loanProductsTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||||
const liabilityAccountData = this.loanProductsTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
const liabilityAccountData = this.loanProductsTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||||
this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
this.loanProductsTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
||||||
const itemsByDefault: string[] = [];
|
|
||||||
data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => {
|
this.itemsByDefault = loanProducts.setItemsByDefault(data.configurations);
|
||||||
if (config.name === 'days-before-repayment-is-due') {
|
this.loanProductsTemplate['itemsByDefault'] = this.itemsByDefault;
|
||||||
this.loanProductsTemplate['dueDaysForRepaymentEvent'] = config.value;
|
this.loanProductsTemplate = loanProducts.updateLoanProductDefaults(this.loanProductsTemplate);
|
||||||
itemsByDefault.push('dueDaysForRepaymentEvent');
|
|
||||||
} else if (config.name === 'days-after-repayment-is-overdue') {
|
|
||||||
this.loanProductsTemplate['overDueDaysForRepaymentEvent'] = config.value;
|
|
||||||
itemsByDefault.push('overDueDaysForRepaymentEvent');
|
|
||||||
}
|
|
||||||
this.loanProductsTemplate['itemsByDefault'] = itemsByDefault;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,15 +100,7 @@ export class CreateLoanProductComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submit() {
|
submit() {
|
||||||
const dateFormat = this.settingsService.dateFormat;
|
const loanProduct = this.loanProducts.buildPayload(this.loanProduct, this.itemsByDefault);
|
||||||
const loanProduct = {
|
|
||||||
...this.loanProduct,
|
|
||||||
charges: this.loanProduct.charges.map((charge: any) => ({ id: charge.id })),
|
|
||||||
dateFormat,
|
|
||||||
locale: this.settingsService.language.code
|
|
||||||
};
|
|
||||||
delete loanProduct.allowAttributeConfiguration;
|
|
||||||
delete loanProduct.advancedAccountingRules;
|
|
||||||
|
|
||||||
this.productsService.createLoanProduct(loanProduct)
|
this.productsService.createLoanProduct(loanProduct)
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import { LoanProductAccountingStepComponent } from '../loan-product-stepper/loan
|
|||||||
|
|
||||||
/** Custom Services */
|
/** Custom Services */
|
||||||
import { ProductsService } from 'app/products/products.service';
|
import { ProductsService } from 'app/products/products.service';
|
||||||
import { SettingsService } from 'app/settings/settings.service';
|
|
||||||
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
||||||
|
import { LoanProducts } from '../loan-products';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-edit-loan-product',
|
selector: 'mifosx-edit-loan-product',
|
||||||
@@ -31,38 +31,28 @@ export class EditLoanProductComponent implements OnInit {
|
|||||||
|
|
||||||
loanProductAndTemplate: any;
|
loanProductAndTemplate: any;
|
||||||
accountingRuleData = ['None', 'Cash', 'Accrual (periodic)', 'Accrual (upfront)'];
|
accountingRuleData = ['None', 'Cash', 'Accrual (periodic)', 'Accrual (upfront)'];
|
||||||
|
itemsByDefault: GlobalConfiguration[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ActivatedRoute} route Activated Route.
|
* @param {ActivatedRoute} route Activated Route.
|
||||||
* @param {ProductsService} productsService Product Service.
|
* @param {ProductsService} productsService Product Service.
|
||||||
* @param {SettingsService} settingsService Settings Service
|
* @param {LoanProducts} loanProducts LoanProducts
|
||||||
* @param {Router} router Router for navigation.
|
* @param {Router} router Router for navigation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
private productsService: ProductsService,
|
private productsService: ProductsService,
|
||||||
private settingsService: SettingsService,
|
private loanProducts: LoanProducts,
|
||||||
private router: Router) {
|
private router: Router) {
|
||||||
this.route.data.subscribe((data: { loanProductAndTemplate: any, configurations: any }) => {
|
this.route.data.subscribe((data: { loanProductAndTemplate: any, configurations: any }) => {
|
||||||
this.loanProductAndTemplate = data.loanProductAndTemplate;
|
this.loanProductAndTemplate = data.loanProductAndTemplate;
|
||||||
const assetAccountData = this.loanProductAndTemplate.accountingMappingOptions.assetAccountOptions || [];
|
const assetAccountData = this.loanProductAndTemplate.accountingMappingOptions.assetAccountOptions || [];
|
||||||
const liabilityAccountData = this.loanProductAndTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
const liabilityAccountData = this.loanProductAndTemplate.accountingMappingOptions.liabilityAccountOptions || [];
|
||||||
this.loanProductAndTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
this.loanProductAndTemplate.accountingMappingOptions.assetAndLiabilityAccountOptions = assetAccountData.concat(liabilityAccountData);
|
||||||
const itemsByDefault: string[] = [];
|
|
||||||
data.configurations.globalConfiguration.forEach((config: GlobalConfiguration) => {
|
this.itemsByDefault = loanProducts.setItemsByDefault(data.configurations);
|
||||||
if (config.name === 'days-before-repayment-is-due') {
|
this.loanProductAndTemplate['itemsByDefault'] = this.itemsByDefault;
|
||||||
if (this.loanProductAndTemplate['dueDaysForRepaymentEvent'] == null) {
|
this.loanProductAndTemplate = loanProducts.updateLoanProductDefaults(this.loanProductAndTemplate);
|
||||||
this.loanProductAndTemplate['dueDaysForRepaymentEvent'] = config.value;
|
|
||||||
itemsByDefault.push('dueDaysForRepaymentEvent');
|
|
||||||
}
|
|
||||||
} else if (config.name === 'days-after-repayment-is-overdue') {
|
|
||||||
if (this.loanProductAndTemplate['overDueDaysForRepaymentEvent'] == null) {
|
|
||||||
this.loanProductAndTemplate['overDueDaysForRepaymentEvent'] = config.value;
|
|
||||||
itemsByDefault.push('overDueDaysForRepaymentEvent');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.loanProductAndTemplate['itemsByDefault'] = itemsByDefault;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,16 +109,8 @@ export class EditLoanProductComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
submit() {
|
submit() {
|
||||||
// TODO: Update once language and date settings are setup
|
const loanProduct = this.loanProducts.buildPayload(this.loanProduct, this.itemsByDefault);
|
||||||
const dateFormat = this.settingsService.dateFormat;
|
|
||||||
const loanProduct = {
|
|
||||||
...this.loanProduct,
|
|
||||||
charges: this.loanProduct.charges.map((charge: any) => ({ id: charge.id })),
|
|
||||||
dateFormat,
|
|
||||||
locale: this.settingsService.language.code
|
|
||||||
};
|
|
||||||
delete loanProduct.allowAttributeConfiguration;
|
|
||||||
delete loanProduct.advancedAccountingRules;
|
|
||||||
this.productsService.updateLoanProduct(this.loanProductAndTemplate.id, loanProduct)
|
this.productsService.updateLoanProduct(this.loanProductAndTemplate.id, loanProduct)
|
||||||
.subscribe((response: any) => {
|
.subscribe((response: any) => {
|
||||||
this.router.navigate(['../../', response.resourceId], { relativeTo: this.route });
|
this.router.navigate(['../../', response.resourceId], { relativeTo: this.route });
|
||||||
|
|||||||
+6
-7
@@ -1,5 +1,6 @@
|
|||||||
import { Component, OnInit, Input } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
|
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
|
||||||
|
import { LoanProducts } from '../../loan-products';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-loan-product-settings-step',
|
selector: 'mifosx-loan-product-settings-step',
|
||||||
@@ -28,9 +29,8 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
|||||||
interestRecalculationOnDayTypeData: any;
|
interestRecalculationOnDayTypeData: any;
|
||||||
delinquencyBucketData: any;
|
delinquencyBucketData: any;
|
||||||
|
|
||||||
itemsByDefault: string[] = [];
|
constructor(private formBuilder: FormBuilder,
|
||||||
|
private loanProducts: LoanProducts) {
|
||||||
constructor(private formBuilder: FormBuilder) {
|
|
||||||
this.createLoanProductSettingsForm();
|
this.createLoanProductSettingsForm();
|
||||||
this.setConditionalControls();
|
this.setConditionalControls();
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,6 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
|||||||
this.interestRecalculationOnDayTypeData = Array.from({ length: 28 }, (_, index) => index + 1);
|
this.interestRecalculationOnDayTypeData = Array.from({ length: 28 }, (_, index) => index + 1);
|
||||||
this.delinquencyBucketData = this.loanProductsTemplate.delinquencyBucketOptions;
|
this.delinquencyBucketData = this.loanProductsTemplate.delinquencyBucketOptions;
|
||||||
|
|
||||||
this.itemsByDefault = this.loanProductsTemplate.itemsByDefault || [];
|
|
||||||
this.loanProductSettingsForm.patchValue({
|
this.loanProductSettingsForm.patchValue({
|
||||||
'amortizationType': this.loanProductsTemplate.amortizationType.id,
|
'amortizationType': this.loanProductsTemplate.amortizationType.id,
|
||||||
'interestType': this.loanProductsTemplate.interestType.id,
|
'interestType': this.loanProductsTemplate.interestType.id,
|
||||||
@@ -187,8 +186,8 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
|||||||
'graceOnArrearsAgeing': [true]
|
'graceOnArrearsAgeing': [true]
|
||||||
}),
|
}),
|
||||||
'delinquencyBucketId': ['', Validators.required],
|
'delinquencyBucketId': ['', Validators.required],
|
||||||
'dueDaysForRepaymentEvent': ['', Validators.required],
|
'dueDaysForRepaymentEvent': [''],
|
||||||
'overDueDaysForRepaymentEvent': ['', Validators.required]
|
'overDueDaysForRepaymentEvent': ['']
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +361,7 @@ export class LoanProductSettingsStepComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
styleByDefault(input: string): string {
|
styleByDefault(input: string): string {
|
||||||
if (this.itemsByDefault.includes(input)) {
|
if (this.loanProducts.isItemByDefault(input)) {
|
||||||
return 'by-default';
|
return 'by-default';
|
||||||
}
|
}
|
||||||
return '';
|
return '';
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { SettingsService } from 'app/settings/settings.service';
|
||||||
|
import { GlobalConfiguration } from 'app/system/configurations/global-configurations-tab/configuration.model';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class LoanProducts {
|
||||||
|
|
||||||
|
globalConfigurations: string[] = ['days-before-repayment-is-due', 'days-after-repayment-is-overdue'];
|
||||||
|
propertyNames: string[] = ['dueDaysForRepaymentEvent', 'overDueDaysForRepaymentEvent'];
|
||||||
|
|
||||||
|
constructor(private settingsService: SettingsService) { }
|
||||||
|
|
||||||
|
public setItemsByDefault(configurations: any) {
|
||||||
|
const itemsByDefault: GlobalConfiguration[] = [];
|
||||||
|
configurations.globalConfiguration.forEach((config: GlobalConfiguration) => {
|
||||||
|
if (this.globalConfigurations.includes(config.name)) {
|
||||||
|
itemsByDefault.push(config);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return itemsByDefault;
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateLoanProductDefaults(loanProductTemplate: any) {
|
||||||
|
const itemsByDefault: GlobalConfiguration[] = loanProductTemplate['itemsByDefault'];
|
||||||
|
itemsByDefault.forEach((config: GlobalConfiguration) => {
|
||||||
|
const propertyName = this.resolvePropertyName(config.name);
|
||||||
|
if (propertyName !== '') {
|
||||||
|
loanProductTemplate[propertyName] = config.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return loanProductTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public buildPayload(loanProductData: any, itemsByDefault: any) {
|
||||||
|
const dateFormat: string = this.settingsService.dateFormat;
|
||||||
|
const locale: string = this.settingsService.language.code;
|
||||||
|
|
||||||
|
const loanProduct = {
|
||||||
|
...loanProductData,
|
||||||
|
charges: loanProductData.charges.map((charge: any) => ({ id: charge.id })),
|
||||||
|
dateFormat,
|
||||||
|
locale
|
||||||
|
};
|
||||||
|
// Remove unnecessary properties
|
||||||
|
delete loanProduct.allowAttributeConfiguration;
|
||||||
|
delete loanProduct.advancedAccountingRules;
|
||||||
|
|
||||||
|
// Set Default values If they were not set
|
||||||
|
itemsByDefault.forEach((config: GlobalConfiguration) => {
|
||||||
|
const propertyName = this.resolvePropertyName(config.name);
|
||||||
|
if (propertyName !== '') {
|
||||||
|
if (!loanProduct[propertyName] || loanProduct[propertyName] === '') {
|
||||||
|
loanProduct[propertyName] = config.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return loanProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isItemByDefault(propertyName: string): boolean {
|
||||||
|
return (this.propertyNames.includes(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private resolvePropertyName(configName: string): string {
|
||||||
|
if (this.globalConfigurations.includes(configName)) {
|
||||||
|
const idx = this.globalConfigurations.indexOf(configName);
|
||||||
|
if (idx > -1) {
|
||||||
|
return this.propertyNames[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<div *ngIf="!hideOutput && !toBeExportedToRepo">
|
<div *ngIf="!hideOutput && !toBeExportedToRepo">
|
||||||
|
|
||||||
<div class="m-b-10" *ngIf="dataObject.report.type === 'Table'" fxLayoutAlign="end">
|
<div class="m-b-10" *ngIf="dataObject.report.type === 'Table'" fxLayoutAlign="end">
|
||||||
<button mat-raised-button color="primary" (click)="downloadCSV()" [disabled]="notExistsReportData"
|
<button mat-raised-button color="primary" (click)="exportFile()" [disabled]="notExistsReportData"
|
||||||
matToolTip="Export the data to CSV file">
|
matToolTip="Export the data to CSV file">
|
||||||
Export CSV
|
Export CSV
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ import { DecimalPipe, NumberSymbol, getLocaleNumberSymbol } from '@angular/commo
|
|||||||
|
|
||||||
/** Custom Servies */
|
/** Custom Servies */
|
||||||
import { ReportsService } from '../../reports.service';
|
import { ReportsService } from '../../reports.service';
|
||||||
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||||
|
import { SelectBase } from 'app/shared/form-dialog/formfield/model/select-base';
|
||||||
|
import { InputBase } from 'app/shared/form-dialog/formfield/model/input-base';
|
||||||
|
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||||
|
import { Dates } from 'app/core/utils/dates';
|
||||||
|
import { environment } from 'environments/environment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table and SMS Component
|
* Table and SMS Component
|
||||||
@@ -41,7 +48,9 @@ export class TableAndSmsComponent implements OnChanges {
|
|||||||
* @param {DecimalPipe} decimalPipe Decimal Pipe
|
* @param {DecimalPipe} decimalPipe Decimal Pipe
|
||||||
*/
|
*/
|
||||||
constructor(private reportsService: ReportsService,
|
constructor(private reportsService: ReportsService,
|
||||||
private decimalPipe: DecimalPipe ) { }
|
public dialog: MatDialog,
|
||||||
|
private decimalPipe: DecimalPipe,
|
||||||
|
private dateUtils: Dates) { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches run report data post changes in run report form.
|
* Fetches run report data post changes in run report form.
|
||||||
@@ -85,19 +94,57 @@ export class TableAndSmsComponent implements OnChanges {
|
|||||||
/**
|
/**
|
||||||
* Generates the CSV file dynamically for run report data.
|
* Generates the CSV file dynamically for run report data.
|
||||||
*/
|
*/
|
||||||
downloadCSV() {
|
exportFile() {
|
||||||
const userLang = navigator.language;
|
const delimiterOptions: any[] = [
|
||||||
|
{name: 'Comma (,)', char: ','},
|
||||||
|
{name: 'Colon (:)', char: ':'},
|
||||||
|
{name: 'SemiColon (;)', char: ';'},
|
||||||
|
{name: 'Pipe (|)', char: '|'},
|
||||||
|
{name: 'Space ( )', char: ' '},
|
||||||
|
];
|
||||||
|
const fileName = `${this.dataObject.report.name}.csv`;
|
||||||
|
const formfields: FormfieldBase[] = [
|
||||||
|
new SelectBase({
|
||||||
|
controlName: 'delimiter',
|
||||||
|
label: 'Delimiter',
|
||||||
|
value: environment.defaultCharDelimiter,
|
||||||
|
options: { label: 'name', value: 'char', data: delimiterOptions },
|
||||||
|
required: true,
|
||||||
|
order: 1
|
||||||
|
}),
|
||||||
|
new InputBase({
|
||||||
|
controlName: 'fileName',
|
||||||
|
label: 'File Name',
|
||||||
|
value: fileName,
|
||||||
|
type: 'text',
|
||||||
|
required: true,
|
||||||
|
order: 2
|
||||||
|
})
|
||||||
|
];
|
||||||
|
const data = {
|
||||||
|
title: 'Export data to File',
|
||||||
|
layout: { addButtonText: 'Export to File' },
|
||||||
|
formfields: formfields
|
||||||
|
};
|
||||||
|
const exportDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||||
|
exportDialogRef.afterClosed().subscribe((response: { data: any }) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.downloadCSV(response.data.value.fileName, response.data.value.delimiter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the CSV file dynamically for run report data.
|
||||||
|
*/
|
||||||
|
downloadCSV(fileName: string, delimiter: string) {
|
||||||
const headers = this.displayedColumns;
|
const headers = this.displayedColumns;
|
||||||
let delimiter = ',';
|
|
||||||
if (getLocaleNumberSymbol(userLang, NumberSymbol.CurrencyDecimal) !== '.') {
|
|
||||||
delimiter = ';';
|
|
||||||
}
|
|
||||||
let csv = this.csvData.map((object: any) => object.row.join(delimiter));
|
let csv = this.csvData.map((object: any) => object.row.join(delimiter));
|
||||||
csv.unshift(`data:text/csv;charset=utf-8,${headers.join(delimiter)}`);
|
csv.unshift(`data:text/csv;charset=utf-8,${headers.join(delimiter)}`);
|
||||||
csv = csv.join('\r\n');
|
csv = csv.join('\r\n');
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.setAttribute('href', encodeURI(csv));
|
link.setAttribute('href', encodeURI(csv));
|
||||||
link.setAttribute('download', `${this.dataObject.report.name}.csv`);
|
link.setAttribute('download', fileName);
|
||||||
document.body.appendChild(link);
|
document.body.appendChild(link);
|
||||||
link.click();
|
link.click();
|
||||||
document.body.removeChild(link);
|
document.body.removeChild(link);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
/** Angular Imports */
|
/** Angular Imports */
|
||||||
import { Component, OnInit, Inject } from '@angular/core';
|
import { Component, OnInit, Inject } from '@angular/core';
|
||||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
|
import { DialogData } from 'app/core/dialogs/dialog-data.model';
|
||||||
|
import { Dialogs } from 'app/core/dialogs/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete dialog component.
|
* Delete dialog component.
|
||||||
@@ -18,27 +20,15 @@ export class ConfirmationDialogComponent implements OnInit {
|
|||||||
* @param {any} data Provides a deleteContext.
|
* @param {any} data Provides a deleteContext.
|
||||||
*/
|
*/
|
||||||
constructor(public dialogRef: MatDialogRef<ConfirmationDialogComponent>,
|
constructor(public dialogRef: MatDialogRef<ConfirmationDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any) { }
|
private dialogs: Dialogs,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: DialogData) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.setColor();
|
this.setColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor() {
|
setColor() {
|
||||||
switch (this.data.type) {
|
this.color = this.dialogs.setColor(this.data.type);
|
||||||
case 'Basic':
|
|
||||||
this.color = 'primary';
|
|
||||||
break;
|
|
||||||
case 'Mild':
|
|
||||||
this.color = 'primary';
|
|
||||||
break;
|
|
||||||
case 'Strong':
|
|
||||||
this.color = 'warn';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.color = 'warn';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,5 +10,5 @@
|
|||||||
|
|
||||||
<mat-dialog-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
<mat-dialog-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="2%">
|
||||||
<button mat-raised-button mat-dialog-close>{{ layout.cancelButtonText }}</button>
|
<button mat-raised-button mat-dialog-close>{{ layout.cancelButtonText }}</button>
|
||||||
<button mat-raised-button color="primary" [mat-dialog-close]="{ data: form }" [disabled]="!form.valid || form.pristine">{{ layout.addButtonText }}</button>
|
<button mat-raised-button color="primary" [mat-dialog-close]="{ data: form }" [disabled]="!form.valid">{{ layout.addButtonText }}</button>
|
||||||
</mat-dialog-actions>
|
</mat-dialog-actions>
|
||||||
|
|||||||
-1
@@ -8,7 +8,6 @@ import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.co
|
|||||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||||
import { SystemService } from 'app/system/system.service';
|
import { SystemService } from 'app/system/system.service';
|
||||||
import { TouchSequence } from 'selenium-webdriver';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'mifosx-datatable-single-row',
|
selector: 'mifosx-datatable-single-row',
|
||||||
|
|||||||
@@ -16,4 +16,7 @@
|
|||||||
window["env"]["supportedLanguages"] = '';
|
window["env"]["supportedLanguages"] = '';
|
||||||
|
|
||||||
window['env']['preloadClients'] = '';
|
window['env']['preloadClients'] = '';
|
||||||
|
|
||||||
|
// Char delimiter to Export CSV options: ',' ';' '|' ' '
|
||||||
|
window['env']['defaultCharDelimiter'] = ',';
|
||||||
})(this);
|
})(this);
|
||||||
|
|||||||
@@ -16,4 +16,7 @@
|
|||||||
window["env"]["supportedLanguages"] = '$MIFOS_SUPPORTED_LANGUAGES';
|
window["env"]["supportedLanguages"] = '$MIFOS_SUPPORTED_LANGUAGES';
|
||||||
|
|
||||||
window['env']['preloadClients'] = '$MIFOS_PRELOAD_CLIENTS';
|
window['env']['preloadClients'] = '$MIFOS_PRELOAD_CLIENTS';
|
||||||
|
|
||||||
|
// Char delimiter to Export CSV options: ',' ';' '|' ' '
|
||||||
|
window['env']['defaultCharDelimiter'] = '$MIFOS_DEFAULT_CHAR_DELIMITER';
|
||||||
})(this);
|
})(this);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const environment = {
|
|||||||
fineractPlatformTenantIds: window['env']['fineractPlatformTenantIds'] || 'default',
|
fineractPlatformTenantIds: window['env']['fineractPlatformTenantIds'] || 'default',
|
||||||
// For connecting to others servers running elsewhere update the base API URL
|
// For connecting to others servers running elsewhere update the base API URL
|
||||||
baseApiUrls: window['env']['fineractApiUrls'] ||
|
baseApiUrls: window['env']['fineractApiUrls'] ||
|
||||||
'https://dev.mifos.io,https://demo.mifos.io,https://qa.mifos.io,https://staging.mifos.io,https://mobile.mifos.io,https://demo.fineract.dev,https://localhost:8443',
|
'https://dev.mifos.io,https://demo.mifos.io,https://qa.mifos.io,https://staging.mifos.io,https://mobile.mifos.io,https://demo.fineract.dev,https://localhost:8443',
|
||||||
// For connecting to server running elsewhere set the base API URL
|
// For connecting to server running elsewhere set the base API URL
|
||||||
baseApiUrl: window['env']['fineractApiUrl'] || 'https://demo.fineract.dev',
|
baseApiUrl: window['env']['fineractApiUrl'] || 'https://demo.fineract.dev',
|
||||||
allowServerSwitch: env.allow_switching_backend_instance,
|
allowServerSwitch: env.allow_switching_backend_instance,
|
||||||
@@ -23,7 +23,9 @@ export const environment = {
|
|||||||
},
|
},
|
||||||
defaultLanguage: window['env']['defaultLanguage'] || 'en-US',
|
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
|
preloadClients: window['env']['preloadClients'] || true,
|
||||||
|
|
||||||
|
defaultCharDelimiter: window['env']['defaultCharDelimiter'] || ','
|
||||||
};
|
};
|
||||||
|
|
||||||
// Server URL
|
// Server URL
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ export const environment = {
|
|||||||
},
|
},
|
||||||
defaultLanguage: window['env']['defaultLanguage'] || 'en-US',
|
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
|
preloadClients: window['env']['preloadClients'] || true,
|
||||||
|
|
||||||
|
defaultCharDelimiter: window['env']['defaultCharDelimiter'] || ','
|
||||||
};
|
};
|
||||||
|
|
||||||
// Server URL
|
// Server URL
|
||||||
|
|||||||
Reference in New Issue
Block a user