Enhacement to management funds (#1735)
Co-authored-by: Jose Alberto Hernandez <alberto@MacBook-Pro.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
452a1adc17
commit
bf700cc100
@@ -10,7 +10,7 @@ export class DatatableTabComponent {
|
||||
|
||||
entityId: string;
|
||||
/** Loan Datatable */
|
||||
entityDatatable: any;
|
||||
entityDatatable: any = null;
|
||||
/** Multi Row Datatable Flag */
|
||||
multiRowDatatableFlag: boolean;
|
||||
|
||||
@@ -20,9 +20,10 @@ export class DatatableTabComponent {
|
||||
*/
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.entityId = this.route.parent.parent.snapshot.paramMap.get('loanId');
|
||||
|
||||
this.entityDatatable = null;
|
||||
this.route.data.subscribe((data: { loanDatatable: any }) => {
|
||||
this.entityDatatable = data.loanDatatable;
|
||||
console.log(this.entityDatatable);
|
||||
this.multiRowDatatableFlag = this.entityDatatable.columnHeaders[0].columnName === 'id' ? true : false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<div class="tab-container mat-typography">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="start">
|
||||
<div class="m-b-10">
|
||||
<h3>{{datatableName}}</h3>
|
||||
</div>
|
||||
<div class="action-button m-b-5" fxLayoutGap="10px">
|
||||
<span>
|
||||
<button mat-raised-button color="primary" (click)="add()">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>Add
|
||||
</button>
|
||||
</span>
|
||||
<span>
|
||||
<button class="delete-button" mat-raised-button color="warn" (click)="delete()" *ngIf="showDeleteBotton">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>Delete All
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<table #dataTable mat-table [hidden]="!datatableData[0]" [dataSource]="datatableData" class="mat-elevation-z1 m-b-25">
|
||||
|
||||
<ng-container *ngFor="let datatableColumn of datatableColumns;let i = index" [matColumnDef]="datatableColumn">
|
||||
<th mat-header-cell class="right" *matHeaderCellDef> {{datatableColumn}} </th>
|
||||
<td mat-cell class="right" *matCellDef="let data">{{ formatValue(i, data.row[i]) }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="datatableColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: datatableColumns;"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
@@ -1,10 +0,0 @@
|
||||
.tab-container {
|
||||
padding: 1%;
|
||||
margin: 1%;
|
||||
.action-button{
|
||||
margin-left: auto;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MultiRowComponent } from './multi-row.component';
|
||||
|
||||
describe('MultiRowComponent', () => {
|
||||
let component: MultiRowComponent;
|
||||
let fixture: ComponentFixture<MultiRowComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MultiRowComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MultiRowComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,155 +0,0 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnChanges, OnInit, Input, ViewChild } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { MatTable } from '@angular/material/table';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
|
||||
/** Custom Dialogs */
|
||||
import { FormDialogComponent } from 'app/shared/form-dialog/form-dialog.component';
|
||||
import { DeleteDialogComponent } from '../../../../shared/delete-dialog/delete-dialog.component';
|
||||
import { SettingsService } from 'app/settings/settings.service';
|
||||
|
||||
/** Custom Models */
|
||||
import { FormfieldBase } from 'app/shared/form-dialog/formfield/model/formfield-base';
|
||||
|
||||
/** Custom Services */
|
||||
import { LoansService } from '../../../loans.service';
|
||||
import { Dates } from 'app/core/utils/dates';
|
||||
import { Datatables } from 'app/core/utils/datatables';
|
||||
import { DateFormatPipe } from 'app/pipes/date-format.pipe';
|
||||
import { DatetimeFormatPipe } from 'app/pipes/datetime-format.pipe';
|
||||
import { DecimalPipe, NumberFormatStyle } from '@angular/common';
|
||||
|
||||
/**
|
||||
* Loan Multi Row Data Tables
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-multi-row',
|
||||
templateUrl: './multi-row.component.html',
|
||||
styleUrls: ['./multi-row.component.scss']
|
||||
})
|
||||
export class MultiRowComponent implements OnInit, OnChanges {
|
||||
|
||||
/** Data Object */
|
||||
@Input() dataObject: any;
|
||||
|
||||
/** Data Table Name */
|
||||
datatableName: string;
|
||||
/** Data Table Columns */
|
||||
datatableColumns: string[] = [];
|
||||
/** Data Table Data */
|
||||
datatableData: any;
|
||||
/** Loan Id */
|
||||
loanId: string;
|
||||
/** Toggle button visibility */
|
||||
showDeleteBotton: boolean;
|
||||
|
||||
/** Data Table Reference */
|
||||
@ViewChild('dataTable', { static: true }) dataTableRef: MatTable<Element>;
|
||||
|
||||
/**
|
||||
* Fetches loan Id from parent route params.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
* @param {Dates} dateUtils Date Utils.
|
||||
* @param {LoansService} loansService Loans Service.
|
||||
* @param {MatDialog} dialog Mat Dialog.
|
||||
* @param {SettingsService} settingsService Settings Service
|
||||
* @param {Datatables} datatables Datatable utils
|
||||
*/
|
||||
constructor(private route: ActivatedRoute,
|
||||
private dateUtils: Dates,
|
||||
private loansService: LoansService,
|
||||
private dialog: MatDialog,
|
||||
private settingsService: SettingsService,
|
||||
private datatables: Datatables,
|
||||
private dateFormat: DateFormatPipe,
|
||||
private dateTimeFormat: DatetimeFormatPipe,
|
||||
private numberFormat: DecimalPipe) {
|
||||
this.loanId = this.route.parent.parent.snapshot.paramMap.get('loanId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates related variables on changes to dataObject.
|
||||
*/
|
||||
ngOnChanges() {
|
||||
this.datatableColumns = this.dataObject.columnHeaders.map((columnHeader: any) => {
|
||||
return columnHeader.columnName;
|
||||
});
|
||||
this.datatableData = this.dataObject.data;
|
||||
this.showDeleteBotton = this.datatableData[0] ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches data table name from route params.
|
||||
* subscription is required due to asynchronicity.
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.route.params.subscribe((routeParams: any) => {
|
||||
this.datatableName = routeParams.datatableName;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new row to the given multi row data table.
|
||||
*/
|
||||
add() {
|
||||
let dataTableEntryObject: any = { locale: this.settingsService.language.code };
|
||||
const dateTransformColumns: string[] = [];
|
||||
const columns = this.dataObject.columnHeaders.filter((column: any) => {
|
||||
return ((column.columnName !== 'id') && (column.columnName !== 'loan_id') && (column.columnName !== 'created_at') && (column.columnName !== 'updated_at'));
|
||||
});
|
||||
const formfields: FormfieldBase[] = this.datatables.getFormfields(columns, dateTransformColumns, dataTableEntryObject);
|
||||
const data = {
|
||||
title: 'Add ' + this.datatableName,
|
||||
formfields: formfields
|
||||
};
|
||||
const addDialogRef = this.dialog.open(FormDialogComponent, { data });
|
||||
addDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.data) {
|
||||
dateTransformColumns.forEach((column) => {
|
||||
response.data.value[column] = this.dateUtils.formatDate(response.data.value[column], dataTableEntryObject.dateFormat);
|
||||
});
|
||||
dataTableEntryObject = { ...response.data.value, ...dataTableEntryObject };
|
||||
this.loansService.addLoanDatatableEntry(this.loanId, this.datatableName, dataTableEntryObject).subscribe(() => {
|
||||
this.loansService.getLoanDatatable(this.loanId, this.datatableName).subscribe((dataObject: any) => {
|
||||
this.datatableData = dataObject.data;
|
||||
this.dataTableRef.renderRows();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all rows of the given multi row data table.
|
||||
*/
|
||||
delete() {
|
||||
const deleteDataTableDialogRef = this.dialog.open(DeleteDialogComponent, {
|
||||
data: { deleteContext: `the contents of ${this.datatableName}` }
|
||||
});
|
||||
deleteDataTableDialogRef.afterClosed().subscribe((response: any) => {
|
||||
if (response.delete) {
|
||||
this.loansService.deleteDatatableContent(this.loanId, this.datatableName).subscribe(() => {
|
||||
this.loansService.getLoanDatatable(this.loanId, this.datatableName).subscribe((dataObject: any) => {
|
||||
this.datatableData = dataObject.data;
|
||||
this.showDeleteBotton = false;
|
||||
this.dataTableRef.renderRows();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
formatValue(index: number, value: any): any {
|
||||
const columnDisplayType = this.dataObject.columnHeaders[index].columnDisplayType;
|
||||
if (columnDisplayType === 'DATE') {
|
||||
return this.dateFormat.transform(value);
|
||||
} else if (columnDisplayType === 'DATETIME') {
|
||||
return this.dateTimeFormat.transform(value);
|
||||
} else if (columnDisplayType === 'INTEGER' || columnDisplayType === 'DECIMAL') {
|
||||
return this.numberFormat.transform(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<div class="container">
|
||||
|
||||
<mat-card>
|
||||
|
||||
<form [formGroup]="fundForm" (ngSubmit)="submit()">
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<div fxLayout="column">
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput required autofocus formControlName="name">
|
||||
<mat-error *ngIf="fundForm.controls.name.hasError('required')">
|
||||
Name <strong>is required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>External Id</mat-label>
|
||||
<input matInput autofocus formControlName="externalId">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">Cancel</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!fundForm.valid" *mifosxHasPermission="'CREATE_FUND'">Submit</button>
|
||||
</mat-card-actions>
|
||||
|
||||
</form>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CreateFundComponent } from './create-fund.component';
|
||||
|
||||
describe('CreateFundComponent', () => {
|
||||
let component: CreateFundComponent;
|
||||
let fixture: ComponentFixture<CreateFundComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ CreateFundComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CreateFundComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { OrganizationService } from 'app/organization/organization.service';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-create-fund',
|
||||
templateUrl: './create-fund.component.html',
|
||||
styleUrls: ['./create-fund.component.scss']
|
||||
})
|
||||
export class CreateFundComponent implements OnInit {
|
||||
|
||||
/** Charge form. */
|
||||
fundForm: FormGroup;
|
||||
|
||||
/**
|
||||
* Retrieves the charge data from `resolve`.
|
||||
* @param {ProductsService} productsService Products Service.
|
||||
* @param {FormBuilder} formBuilder Form Builder.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
* @param {Router} router Router for navigation.
|
||||
*/
|
||||
constructor(private organizationService: OrganizationService,
|
||||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.createFundForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Fund form.
|
||||
*/
|
||||
createFundForm() {
|
||||
this.fundForm = this.formBuilder.group({
|
||||
'name': ['', Validators.required],
|
||||
'externalId': ['']
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
submit() {
|
||||
const payload = this.fundForm.getRawValue();
|
||||
this.organizationService.createFund(payload)
|
||||
.subscribe((response: any) => {
|
||||
this.router.navigate(['../'], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<div class="container">
|
||||
|
||||
<mat-card>
|
||||
|
||||
<form [formGroup]="fundForm" (ngSubmit)="submit()">
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<div fxLayout="column">
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Name</mat-label>
|
||||
<input matInput required autofocus formControlName="name">
|
||||
<mat-error *ngIf="fundForm.controls.name.hasError('required')">
|
||||
Name <strong>is required</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>External Id</mat-label>
|
||||
<input matInput autofocus formControlName="externalId">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
|
||||
<button type="button" mat-raised-button [routerLink]="['../']">Cancel</button>
|
||||
<button mat-raised-button color="primary" [disabled]="!fundForm.valid" *mifosxHasPermission="'UPDATE_FUND'">Submit</button>
|
||||
</mat-card-actions>
|
||||
|
||||
</form>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EditFundComponent } from './edit-fund.component';
|
||||
|
||||
describe('EditFundComponent', () => {
|
||||
let component: EditFundComponent;
|
||||
let fixture: ComponentFixture<EditFundComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ EditFundComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditFundComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { OrganizationService } from 'app/organization/organization.service';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-edit-fund',
|
||||
templateUrl: './edit-fund.component.html',
|
||||
styleUrls: ['./edit-fund.component.scss']
|
||||
})
|
||||
export class EditFundComponent implements OnInit {
|
||||
|
||||
/** Selected Data. */
|
||||
fundData: any;
|
||||
/** Charge form. */
|
||||
fundForm: FormGroup;
|
||||
|
||||
/**
|
||||
* Retrieves the charge data from `resolve`.
|
||||
* @param {ProductsService} productsService Products Service.
|
||||
* @param {FormBuilder} formBuilder Form Builder.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
* @param {Router} router Router for navigation.
|
||||
*/
|
||||
constructor(private organizationService: OrganizationService,
|
||||
private formBuilder: FormBuilder,
|
||||
private router: Router,
|
||||
private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { fundData: any }) => {
|
||||
this.fundData = data.fundData;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.createFundForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Fund form.
|
||||
*/
|
||||
createFundForm() {
|
||||
this.fundForm = this.formBuilder.group({
|
||||
'name': [this.fundData.name, Validators.required],
|
||||
'externalId': [this.fundData.externalId]
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
submit() {
|
||||
const payload = this.fundForm.getRawValue();
|
||||
this.organizationService.editFund(this.fundData.id.toString(), payload)
|
||||
.subscribe((response: any) => {
|
||||
this.router.navigate(['../'], { relativeTo: this.route });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ManageFundResolver } from './manage-fund.resolver';
|
||||
|
||||
describe('ManageFundResolver', () => {
|
||||
let resolver: ManageFundResolver;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
resolver = TestBed.inject(ManageFundResolver);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(resolver).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { OrganizationService } from '../organization.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ManageFundResolver implements Resolve<boolean> {
|
||||
/**
|
||||
* @param {OrganizationService} organizationService Organization service.
|
||||
*/
|
||||
constructor(private organizationService: OrganizationService) {}
|
||||
|
||||
/**
|
||||
* Returns the manage funds data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<any> {
|
||||
const fundId = route.paramMap.get('id');
|
||||
return this.organizationService.getFund(fundId);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +1,46 @@
|
||||
<div class="container m-b-20" fxLayout="row" fxLayoutAlign="end" fxLayoutGap="20px">
|
||||
<div #buttonCreateCharge class="in-block">
|
||||
<button mat-raised-button color="primary" [routerLink]="['create']" *mifosxHasPermission="'CREATE_FUND'">
|
||||
<fa-icon icon="plus" class="m-r-10"></fa-icon>
|
||||
Create Fund
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<mat-card>
|
||||
<div #filter fxLayout="row" fxLayoutGap="20px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>{{ 'labels.inputs.Filter' | translate }}</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div #fundFormRef>
|
||||
<div #chargesTable class="mat-elevation-z8">
|
||||
|
||||
<form #formRef="ngForm" [formGroup]="fundForm" fxLayout="row" fxLayoutAlign="start baseline" fxLayoutGap="20px"
|
||||
(ngSubmit)="addFund()" *mifosxHasPermission="'CREATE_FUND'">
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
|
||||
<mat-form-field fxFlex="calc(90%-20px)">
|
||||
<textarea formControlName="name" matInput placeholder="New Fund"></textarea>
|
||||
<mat-error *ngIf="fundForm.controls.name.hasError('required')">
|
||||
<strong>Required field</strong>
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
<ng-container matColumnDef="name">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
|
||||
<td mat-cell *matCellDef="let charge"> {{ charge.name }} </td>
|
||||
</ng-container>
|
||||
|
||||
<div #buttonAddFund fxFlex>
|
||||
<button mat-raised-button color="primary" [disabled]="!fundForm.valid">
|
||||
<fa-icon icon="plus"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
<ng-container matColumnDef="externalId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> External Id </th>
|
||||
<td mat-cell *matCellDef="let charge"> {{ charge.externalId }} </td>
|
||||
</ng-container>
|
||||
|
||||
</form>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [routerLink]="[row.id]" class="select-row"></tr>
|
||||
|
||||
</div>
|
||||
</table>
|
||||
|
||||
<mat-grid-list cols="2" rowHeight="50px">
|
||||
|
||||
<mat-grid-tile *ngFor="let fund of fundsData; index as i">
|
||||
|
||||
<input matInput [value]="fund.name">
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="flex-start">
|
||||
<button mat-button color="primary" (click)="editFund(fund.id,fund.name,i)" *mifosxHasPermission="'UPDATE_FUND'">
|
||||
<fa-icon icon="edit"></fa-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</mat-grid-tile>
|
||||
|
||||
</mat-grid-list>
|
||||
|
||||
</mat-card>
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<ng-template #templateFundFormRef let-popover="popover">
|
||||
<h2>Manage Funds</h2>
|
||||
<p class="mw300">This form will be used to add fund. If you would like to add fund click on add funds button and fill the fund name then click on + button else click Next or Back. For more details click: <a href="https://mifosforge.jira.com/wiki/spaces/docs/pages/67141736/Manage+Funds" target="_blank">Manage Funds</a></p>
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
.container{
|
||||
width: 74rem;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
.select-row:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ import { ConfigurationWizardService } from '../../configuration-wizard/configura
|
||||
|
||||
/** Custom Dialog Component */
|
||||
import { ContinueSetupDialogComponent } from '../../configuration-wizard/continue-setup-dialog/continue-setup-dialog.component';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
|
||||
/**
|
||||
* Manage Funds component.
|
||||
@@ -40,6 +43,15 @@ export class ManageFundsComponent implements OnInit, AfterViewInit {
|
||||
@ViewChild('fundFormRef') fundFormRef: ElementRef<any>;
|
||||
/* Template for popover on funds form */
|
||||
@ViewChild('templateFundFormRef') templateFundFormRef: TemplateRef<any>;
|
||||
/** Columns to be displayed in funds table. */
|
||||
displayedColumns: string[] = ['name', 'externalId'];
|
||||
/** Data source for Funds table. */
|
||||
dataSource: MatTableDataSource<any>;
|
||||
|
||||
/** Paginator for charges table. */
|
||||
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
|
||||
/** Sorter for charges table. */
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
|
||||
/**
|
||||
* Retrieves the manage funds data from `resolve`.
|
||||
@@ -64,7 +76,18 @@ export class ManageFundsComponent implements OnInit, AfterViewInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.createFundForm();
|
||||
this.dataSource = new MatTableDataSource(this.fundsData);
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters data in charges table based on passed value.
|
||||
* @param {string} filterValue Value to filter data.
|
||||
*/
|
||||
applyFilter(filterValue: string) {
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<div fxLayout="row" fxLayoutAlign="end" fxLayoutGap="2%" fxLayout.lt-md="column" class="container m-b-20">
|
||||
<button mat-raised-button color="primary" [routerLink]="['edit']" *mifosxHasPermission="'UPDATE_FUND'">
|
||||
<fa-icon icon="edit" class="m-r-10"></fa-icon>
|
||||
Edit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
<mat-card>
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<div fxLayout="row wrap" class="content">
|
||||
|
||||
<div fxFlex="50%" class="mat-body-strong">
|
||||
Name
|
||||
</div>
|
||||
|
||||
<div fxFlex="50%">
|
||||
{{ fundData.name }}
|
||||
</div>
|
||||
|
||||
<div fxFlex="50%" class="mat-body-strong">
|
||||
External Id
|
||||
</div>
|
||||
|
||||
<div fxFlex="50%">
|
||||
{{ fundData.externalId }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
<button type="button" mat-raised-button color="primary" [routerLink]="['../']">{{ 'Back' | translate }}</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
.container {
|
||||
max-width: 37rem;
|
||||
|
||||
.content {
|
||||
div {
|
||||
margin: 1rem 0;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ViewFundComponent } from './view-fund.component';
|
||||
|
||||
describe('ViewFundComponent', () => {
|
||||
let component: ViewFundComponent;
|
||||
let fixture: ComponentFixture<ViewFundComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ViewFundComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ViewFundComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-view-fund',
|
||||
templateUrl: './view-fund.component.html',
|
||||
styleUrls: ['./view-fund.component.scss']
|
||||
})
|
||||
export class ViewFundComponent implements OnInit {
|
||||
|
||||
/** Fund data. */
|
||||
fundData: any;
|
||||
|
||||
/**
|
||||
* Retrieves the charge data from `resolve`.
|
||||
* @param {Router} router Router for navigation.
|
||||
*/
|
||||
constructor(private route: ActivatedRoute) {
|
||||
this.route.data.subscribe((data: { fundData: any }) => {
|
||||
this.fundData = data.fundData;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -101,6 +101,10 @@ import { LoanProvisioningCriteriaTemplateResolver } from './loan-provisioning-cr
|
||||
import { LoanProvisioningCriteriaAndTemplateResolver } from './loan-provisioning-criteria/common-resolvers/loan-provisioning-criteria-and-template.resolver';
|
||||
import { StandingInstructionsTemplateResolver } from './standing-instructions-history/standing-instructions-template.resolver';
|
||||
import { AdvanceSearchTemplateResolver } from './fund-mapping/advance-search-template.resolver';
|
||||
import { ManageFundResolver } from './manage-funds/manage-fund.resolver';
|
||||
import { ViewFundComponent } from './manage-funds/view-fund/view-fund.component';
|
||||
import { EditFundComponent } from './manage-funds/edit-fund/edit-fund.component';
|
||||
import { CreateFundComponent } from './manage-funds/create-fund/create-fund.component';
|
||||
|
||||
/** Organization Routes */
|
||||
const routes: Routes = [
|
||||
@@ -570,8 +574,45 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'manage-funds',
|
||||
component: ManageFundsComponent,
|
||||
data: { title: extract('Manage Funds Days'), breadcrumb: 'Manage Funds' },
|
||||
data: { title: extract('Manage Funds'), breadcrumb: 'Manage Funds' },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: ManageFundsComponent,
|
||||
resolve: {
|
||||
funds: ManageFundsResolver
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: CreateFundComponent,
|
||||
data: { title: extract('Create Fund'), breadcrumb: 'Create' }
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
data: { title: extract('View Fund'), breadcrumb: 'id', routeParamBreadcrumb: 'id' },
|
||||
resolve: {
|
||||
fundData: ManageFundResolver
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: ViewFundComponent,
|
||||
resolve: {
|
||||
fundData: ManageFundResolver
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'edit',
|
||||
component: EditFundComponent,
|
||||
data: { title: extract('Edit Fund'), breadcrumb: 'Edit', routeParamBreadcrumb: false },
|
||||
resolve: {
|
||||
fundData: ManageFundResolver
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
resolve: {
|
||||
funds: ManageFundsResolver
|
||||
}
|
||||
|
||||
@@ -74,6 +74,9 @@ import { OfficeItemNode } from './holidays/create-holiday/office-item.class';
|
||||
import { OfficeItemFlatNode } from './holidays/create-holiday/office-flat-item.class';
|
||||
import { ChecklistDatabase } from './holidays/create-holiday/checklist-db.class';
|
||||
import { CreateHoliday } from './holidays/create-holiday/create-holiday.service';
|
||||
import { CreateFundComponent } from './manage-funds/create-fund/create-fund.component';
|
||||
import { EditFundComponent } from './manage-funds/edit-fund/edit-fund.component';
|
||||
import { ViewFundComponent } from './manage-funds/view-fund/view-fund.component';
|
||||
|
||||
|
||||
/**
|
||||
@@ -148,6 +151,9 @@ import { CreateHoliday } from './holidays/create-holiday/create-holiday.service'
|
||||
StandingInstructionsHistoryComponent,
|
||||
FundMappingComponent,
|
||||
CreateHolidayComponent,
|
||||
CreateFundComponent,
|
||||
EditFundComponent,
|
||||
ViewFundComponent,
|
||||
],
|
||||
providers: [
|
||||
CreateHoliday,
|
||||
|
||||
@@ -680,6 +680,13 @@ export class OrganizationService {
|
||||
return this.http.get('/funds');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Observable<any>} Fund data
|
||||
*/
|
||||
getFund(fundId: string): Observable<any> {
|
||||
return this.http.get(`/funds/${fundId}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} fund Fund to be created.
|
||||
* @returns {Observable<any>}
|
||||
|
||||
+2
-2
@@ -11,14 +11,14 @@
|
||||
</button>
|
||||
</span>
|
||||
<span *mifosxHasPermission="'DELETE_' + datatableName">
|
||||
<button class="delete-button" mat-raised-button color="warn" (click)="delete()" *ngIf="showDeleteBotton">
|
||||
<button class="delete-button" mat-raised-button color="warn" (click)="delete()" *ngIf="hasEntityData">
|
||||
<fa-icon icon="trash" class="m-r-10"></fa-icon>Delete All
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table #dataTable mat-table [hidden]="!datatableData[0]" [dataSource]="datatableData" class="mat-elevation-z1 m-b-25">
|
||||
<table #dataTable mat-table [hidden]="!hasEntityData" [dataSource]="datatableData" class="mat-elevation-z1 m-b-25">
|
||||
|
||||
<ng-container *ngFor="let datatableColumn of datatableColumns;let i = index" [matColumnDef]="datatableColumn">
|
||||
<th mat-header-cell class="right" *matHeaderCellDef> {{datatableColumn}} </th>
|
||||
|
||||
+22
-5
@@ -1,5 +1,5 @@
|
||||
import { DecimalPipe } from '@angular/common';
|
||||
import { Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||
import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatTable } from '@angular/material/table';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
@@ -18,7 +18,7 @@ import { SystemService } from 'app/system/system.service';
|
||||
templateUrl: './datatable-multi-row.component.html',
|
||||
styleUrls: ['./datatable-multi-row.component.scss']
|
||||
})
|
||||
export class DatatableMultiRowComponent implements OnInit {
|
||||
export class DatatableMultiRowComponent implements OnInit, OnDestroy {
|
||||
|
||||
/** Data Object */
|
||||
@Input() dataObject: any;
|
||||
@@ -34,6 +34,7 @@ export class DatatableMultiRowComponent implements OnInit {
|
||||
|
||||
/** Toggle button visibility */
|
||||
showDeleteBotton: boolean;
|
||||
hasEntityData = false;
|
||||
|
||||
/** Data Table Reference */
|
||||
@ViewChild('dataTable', { static: true }) dataTableRef: MatTable<Element>;
|
||||
@@ -55,7 +56,9 @@ export class DatatableMultiRowComponent implements OnInit {
|
||||
private datatables: Datatables,
|
||||
private dateFormat: DateFormatPipe,
|
||||
private dateTimeFormat: DatetimeFormatPipe,
|
||||
private numberFormat: DecimalPipe) { }
|
||||
private numberFormat: DecimalPipe) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches data table name from route params.
|
||||
@@ -69,7 +72,17 @@ export class DatatableMultiRowComponent implements OnInit {
|
||||
return columnHeader.columnName;
|
||||
});
|
||||
this.datatableData = this.dataObject.data;
|
||||
this.showDeleteBotton = this.datatableData[0] ? true : false;
|
||||
this.hasEntityData = (this.datatableData && this.datatableData.length > 0);
|
||||
console.log(this.hasEntityData);
|
||||
console.log(this.dataObject.data);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.datatableColumns = null;
|
||||
this.datatableData = null;
|
||||
this.hasEntityData = false;
|
||||
console.log(this.hasEntityData);
|
||||
console.log(this.dataObject.data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +141,11 @@ export class DatatableMultiRowComponent implements OnInit {
|
||||
} else if (columnDisplayType === 'DATETIME') {
|
||||
return this.dateTimeFormat.transform(value);
|
||||
} else if (columnDisplayType === 'INTEGER' || columnDisplayType === 'DECIMAL') {
|
||||
return this.numberFormat.transform(value);
|
||||
if (typeof value === 'number') {
|
||||
return this.numberFormat.transform(value);
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,9 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="center" fxLayoutGap="2%" fxLayout.lt-md="column">
|
||||
<button type="button" mat-raised-button color="primary" [routerLink]="['../']">{{ 'Back' | translate }}</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
||||
</mat-card>
|
||||
|
||||
Reference in New Issue
Block a user