@@ -36,6 +36,7 @@ import { ProductsModule } from './products/products.module';
|
||||
import { OrganizationModule } from './organization/organization.module';
|
||||
import { TemplatesModule } from './templates/templates.module';
|
||||
import { UsersModule } from './users/users.module';
|
||||
import { ReportsModule } from './reports/reports.module';
|
||||
|
||||
|
||||
|
||||
@@ -61,6 +62,7 @@ import { AppRoutingModule } from './app-routing.module';
|
||||
SettingsModule,
|
||||
NavigationModule,
|
||||
ClientsModule,
|
||||
ReportsModule,
|
||||
GroupsModule,
|
||||
CentersModule,
|
||||
AccountingModule,
|
||||
|
||||
@@ -90,12 +90,12 @@
|
||||
|
||||
<!-- Toolbar Menus -->
|
||||
<mat-menu #reportsMenu="matMenu" [overlapTrigger]="false">
|
||||
<button mat-menu-item>All</button>
|
||||
<button mat-menu-item>Clients</button>
|
||||
<button mat-menu-item>Loans</button>
|
||||
<button mat-menu-item>Savings</button>
|
||||
<button mat-menu-item>Funds</button>
|
||||
<button mat-menu-item>Accounting</button>
|
||||
<button mat-menu-item [routerLink]="['/reports']">All</button>
|
||||
<button mat-menu-item [routerLink]="['/reports', 'Client']">Clients</button>
|
||||
<button mat-menu-item [routerLink]="['/reports', 'Loan']">Loans</button>
|
||||
<button mat-menu-item [routerLink]="['/reports', 'Savings']">Savings</button>
|
||||
<button mat-menu-item [routerLink]="['/reports', 'Fund']">Funds</button>
|
||||
<button mat-menu-item [routerLink]="['/reports', 'Accounting']">Accounting</button>
|
||||
<button mat-menu-item>XBRL</button>
|
||||
</mat-menu>
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/** Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
/** Routing Imports */
|
||||
import { Route } from '../core/route/route.service';
|
||||
|
||||
/** Translation Imports */
|
||||
import { extract } from '../core/i18n/i18n.service';
|
||||
|
||||
/** Custom Components */
|
||||
import { ReportsComponent } from './reports.component';
|
||||
|
||||
/** Custom Resolvers */
|
||||
import { ReportsResolver } from './reports.resolver';
|
||||
|
||||
/** Reports Routes */
|
||||
const routes: Routes = [
|
||||
Route.withShell([
|
||||
{
|
||||
path: 'reports',
|
||||
data: { title: extract('Reports'), breadcrumb: 'Reports' },
|
||||
resolve: {
|
||||
reports: ReportsResolver
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: ReportsComponent,
|
||||
},
|
||||
{
|
||||
path: ':filter',
|
||||
data: { routeParamBreadcrumb: 'filter' },
|
||||
component: ReportsComponent,
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
];
|
||||
|
||||
/**
|
||||
* Reports Routing Module
|
||||
*
|
||||
* Configures the reports routes.
|
||||
*/
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
providers: [
|
||||
ReportsResolver
|
||||
]
|
||||
})
|
||||
export class ReportsRoutingModule { }
|
||||
@@ -0,0 +1,39 @@
|
||||
<div class="container">
|
||||
|
||||
<div fxLayout="row" fxLayoutGap="20px">
|
||||
<mat-form-field fxFlex>
|
||||
<mat-label>Filter</mat-label>
|
||||
<input matInput (keyup)="applyFilter($event.target.value)">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
|
||||
<ng-container matColumnDef="reportName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
|
||||
<td mat-cell *matCellDef="let report"> {{ report.reportName }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="reportType">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Type </th>
|
||||
<td mat-cell *matCellDef="let report"> {{ report.reportType }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="reportCategory">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Category </th>
|
||||
<td mat-cell *matCellDef="let report"> {{ report.reportCategory }} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" class="select-row"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
table {
|
||||
width: 100%;
|
||||
|
||||
.select-row:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/** Angular Imports */
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import {MatPaginator, MatSort, MatTableDataSource} from '@angular/material';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
/**
|
||||
* Reports component.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'mifosx-reports',
|
||||
templateUrl: './reports.component.html',
|
||||
styleUrls: ['./reports.component.scss']
|
||||
})
|
||||
export class ReportsComponent implements OnInit {
|
||||
|
||||
/** Reports data. */
|
||||
reportsData: any;
|
||||
/** Report category filter. */
|
||||
filter: string;
|
||||
/** Columns to be displayed in reports table. */
|
||||
displayedColumns: string[] = ['reportName', 'reportType', 'reportCategory'];
|
||||
/** Data source for reports table. */
|
||||
dataSource = new MatTableDataSource();
|
||||
|
||||
/** Paginator for reports table. */
|
||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
/** Sorter for reports table. */
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
/**
|
||||
* Retrieves the reports data from `resolve`.
|
||||
* @param {ActivatedRoute} route Activated Route.
|
||||
* Prevents reuse of route parameter `filter`.
|
||||
* @param {Router} router: Router.
|
||||
*/
|
||||
constructor(private route: ActivatedRoute,
|
||||
private router: Router) {
|
||||
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
|
||||
this.route.data.subscribe(( data: { reports: any }) => {
|
||||
this.reportsData = data.reports;
|
||||
});
|
||||
this.filter = this.route.snapshot.params['filter'];
|
||||
}
|
||||
|
||||
/*
|
||||
*Sets and filters the reports table by category.
|
||||
*/
|
||||
ngOnInit() {
|
||||
this.setReports();
|
||||
this.filterReportsByCategory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches filterPredicate if filterValue is not null.
|
||||
* @param {string} filterValue filter string for mat-table.
|
||||
*/
|
||||
applyFilter(filterValue: string) {
|
||||
if (filterValue.length) {
|
||||
this.setCustomFilterPredicate();
|
||||
this.dataSource.filter = filterValue.trim().toLowerCase();
|
||||
} else {
|
||||
this.filterReportsByCategory();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the data source, paginator and sorter for reports table.
|
||||
*/
|
||||
setReports() {
|
||||
this.dataSource = new MatTableDataSource(this.reportsData);
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the data source only for report category passed in route params.
|
||||
*/
|
||||
filterReportsByCategory() {
|
||||
this.dataSource.filterPredicate = (data: any, filter: string) => {
|
||||
return data.reportCategory === filter;
|
||||
};
|
||||
this.dataSource.filter = this.filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters Reports for filter value string and report category.
|
||||
*/
|
||||
setCustomFilterPredicate() {
|
||||
this.dataSource.filterPredicate = (data: any, filter: string) => {
|
||||
/** Transform the data into a lowercase string of all property values. */
|
||||
const dataStr = Object.keys(data).reduce(function (currentTerm: string, key: string) {
|
||||
/** Use an obscure Unicode character to delimit the words in the concatenated string.
|
||||
* This avoids matches where the values of two columns combined will match the user's query
|
||||
*/
|
||||
return currentTerm + ((/** @type {any} */ (data)))[key] + '◬';
|
||||
}, '').toLowerCase();
|
||||
/** Transform the filter by converting it to lowercase and removing whitespace. */
|
||||
const transformedFilter = filter.trim().toLowerCase();
|
||||
/* Seperates filter for All reports page.*/
|
||||
if (this.filter) {
|
||||
return dataStr.indexOf(transformedFilter) !== -1 && data.reportCategory === this.filter;
|
||||
} else {
|
||||
return dataStr.indexOf(transformedFilter) !== -1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/** Angular Imports */
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
/** Custom Modules */
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { ReportsRoutingModule } from 'app/reports/reports-routing.module';
|
||||
|
||||
/** Custom Components */
|
||||
import { ReportsComponent } from './reports.component';
|
||||
|
||||
/**
|
||||
* Reports Module
|
||||
*
|
||||
* Reports components should be declared here.
|
||||
*/
|
||||
@NgModule({
|
||||
imports: [
|
||||
SharedModule,
|
||||
ReportsRoutingModule
|
||||
],
|
||||
declarations: [ReportsComponent],
|
||||
})
|
||||
export class ReportsModule { }
|
||||
@@ -0,0 +1,30 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Resolve } from '@angular/router';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/** Custom Services */
|
||||
import { ReportsService } from './reports.service';
|
||||
|
||||
/**
|
||||
* Reports data resolver.
|
||||
*/
|
||||
@Injectable()
|
||||
export class ReportsResolver implements Resolve<Object> {
|
||||
|
||||
/**
|
||||
* @param {ReportsService} reportsService Reports service.
|
||||
*/
|
||||
constructor(private reportsService: ReportsService) {}
|
||||
|
||||
/**
|
||||
* Returns the reports data.
|
||||
* @returns {Observable<any>}
|
||||
*/
|
||||
resolve(): Observable<any> {
|
||||
return this.reportsService.getReports();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/** Angular Imports */
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
|
||||
/** rxjs Imports */
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Reports service.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ReportsService {
|
||||
|
||||
/**
|
||||
* @param {HttpClient} http Http Client to send requests.
|
||||
*/
|
||||
constructor(private http: HttpClient) { }
|
||||
|
||||
/**
|
||||
* @returns {Observable<any>} Reports data
|
||||
*/
|
||||
getReports(): Observable<any> {
|
||||
return this.http.get('/reports');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user