From bab75357b4836287e3988eb9446e8c59c1a32d52 Mon Sep 17 00:00:00 2001 From: Chirag Date: Mon, 25 Nov 2019 23:54:23 +0530 Subject: [PATCH] feat: create, view, edit, delete for reports - Add manage-reports - Add view-report - Add create-report - Add edit-report #174 --- .../create-report.component.html | 134 +++++++++++ .../create-report.component.scss | 17 ++ .../create-report.component.spec.ts | 25 +++ .../create-report/create-report.component.ts | 193 ++++++++++++++++ .../edit-report/edit-report.component.html | 134 +++++++++++ .../edit-report/edit-report.component.scss | 17 ++ .../edit-report/edit-report.component.spec.ts | 25 +++ .../edit-report/edit-report.component.ts | 208 ++++++++++++++++++ .../manage-reports.component.html | 69 ++++++ .../manage-reports.component.scss | 16 ++ .../manage-reports.component.spec.ts | 25 +++ .../manage-reports.component.ts | 62 ++++++ .../report-parameter-dialog.component.html | 36 +++ .../report-parameter-dialog.component.scss | 0 .../report-parameter-dialog.component.spec.ts | 25 +++ .../report-parameter-dialog.component.ts | 46 ++++ .../report-template.resolver.ts | 30 +++ .../system/manage-reports/report.resolver.ts | 31 +++ .../system/manage-reports/reports.resolver.ts | 30 +++ .../view-report/view-report.component.html | 69 ++++++ .../view-report/view-report.component.scss | 10 + .../view-report/view-report.component.spec.ts | 25 +++ .../view-report/view-report.component.ts | 60 +++++ src/app/system/system-routing.module.ts | 55 ++++- src/app/system/system.component.html | 2 +- src/app/system/system.module.ts | 17 +- src/app/system/system.service.ts | 47 ++++ 27 files changed, 1405 insertions(+), 3 deletions(-) create mode 100644 src/app/system/manage-reports/create-report/create-report.component.html create mode 100644 src/app/system/manage-reports/create-report/create-report.component.scss create mode 100644 src/app/system/manage-reports/create-report/create-report.component.spec.ts create mode 100644 src/app/system/manage-reports/create-report/create-report.component.ts create mode 100644 src/app/system/manage-reports/edit-report/edit-report.component.html create mode 100644 src/app/system/manage-reports/edit-report/edit-report.component.scss create mode 100644 src/app/system/manage-reports/edit-report/edit-report.component.spec.ts create mode 100644 src/app/system/manage-reports/edit-report/edit-report.component.ts create mode 100644 src/app/system/manage-reports/manage-reports.component.html create mode 100644 src/app/system/manage-reports/manage-reports.component.scss create mode 100644 src/app/system/manage-reports/manage-reports.component.spec.ts create mode 100644 src/app/system/manage-reports/manage-reports.component.ts create mode 100644 src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.html create mode 100644 src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.scss create mode 100644 src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.spec.ts create mode 100644 src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.ts create mode 100644 src/app/system/manage-reports/report-template.resolver.ts create mode 100644 src/app/system/manage-reports/report.resolver.ts create mode 100644 src/app/system/manage-reports/reports.resolver.ts create mode 100644 src/app/system/manage-reports/view-report/view-report.component.html create mode 100644 src/app/system/manage-reports/view-report/view-report.component.scss create mode 100644 src/app/system/manage-reports/view-report/view-report.component.spec.ts create mode 100644 src/app/system/manage-reports/view-report/view-report.component.ts diff --git a/src/app/system/manage-reports/create-report/create-report.component.html b/src/app/system/manage-reports/create-report/create-report.component.html new file mode 100644 index 000000000..22bd76116 --- /dev/null +++ b/src/app/system/manage-reports/create-report/create-report.component.html @@ -0,0 +1,134 @@ +
+ + + +
+ + + +
+ + + Report Name + + + Report Name is required + + + + + Report Type + + + {{ allowedReportType }} + + + + Report Type is required + + + + + Report Sub Type + + + {{ allowedReportSubType }} + + + + +
+ +
+ + + Report Category + + + +
+ + User Report (UI) + +
+ +
+ +
+ + + Description + + + + + SQL + + + SQL is required + + + +
+ +
+ +
+ +

Report Parameters

+ + + +
+ + + + + + + + + + + + + + + + + + + + + +
Parameter {{ reportParameter.parameterName }} Parameter Name Passed to Pentaho {{ reportParameter.reportParameterName }} Actions + + +
+ + + +
+ + + + + + +
+ +
+ +
diff --git a/src/app/system/manage-reports/create-report/create-report.component.scss b/src/app/system/manage-reports/create-report/create-report.component.scss new file mode 100644 index 000000000..e12a7bca2 --- /dev/null +++ b/src/app/system/manage-reports/create-report/create-report.component.scss @@ -0,0 +1,17 @@ +@media (min-width: 992px) { + + .user-report-wrapper { + position: relative; + + .user-report { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + } + } + +} + +table { + width: 100%; +} diff --git a/src/app/system/manage-reports/create-report/create-report.component.spec.ts b/src/app/system/manage-reports/create-report/create-report.component.spec.ts new file mode 100644 index 000000000..00e5344fb --- /dev/null +++ b/src/app/system/manage-reports/create-report/create-report.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateReportComponent } from './create-report.component'; + +describe('CreateReportComponent', () => { + let component: CreateReportComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CreateReportComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CreateReportComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-reports/create-report/create-report.component.ts b/src/app/system/manage-reports/create-report/create-report.component.ts new file mode 100644 index 000000000..94a37071b --- /dev/null +++ b/src/app/system/manage-reports/create-report/create-report.component.ts @@ -0,0 +1,193 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material'; + +/** Custom Services */ +import { SystemService } from 'app/system/system.service'; + +/** Custom Components */ +import { ReportParameterDialogComponent } from '../report-parameter-dialog/report-parameter-dialog.component'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * Create Report Component. + */ +@Component({ + selector: 'mifosx-create-report', + templateUrl: './create-report.component.html', + styleUrls: ['./create-report.component.scss'] +}) +export class CreateReportComponent implements OnInit { + + /** Report Form. */ + reportForm: FormGroup; + /** Report Template Data. */ + reportTemplateData: any; + /** Data passed to dialog. */ + dataForDialog: { allowedParameters: any[], parameterName: string, reportParameterName: string } = + { + allowedParameters: undefined, + parameterName: undefined, + reportParameterName: undefined + }; + /** Columns to be displayed in report parameters table. */ + displayedColumns: string[] = ['parameterName', 'parameterNamePassed', 'actions']; + /** Data source for report parameters table. */ + dataSource: MatTableDataSource; + /** Report Parameters Data. */ + reportParametersData: any[] = []; + /** Paginator for report parameters table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for report parameters table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the report template data from `resolve`. + * @param {FormBuilder} formBuilder Form Builder. + * @param {SystemService} systemService System Service. + * @param {ActivatedRoute} route Activated Route. + * @param {Router} router Router for navigation. + * @param {MatDialog} dialog Dialog Reference. + */ + constructor(private formBuilder: FormBuilder, + private systemService: SystemService, + private route: ActivatedRoute, + private router: Router, + private dialog: MatDialog) { + this.route.data.subscribe((data: { reportTemplate: any }) => { + this.reportTemplateData = data.reportTemplate; + this.dataForDialog.allowedParameters = this.reportTemplateData.allowedParameters; + }); + } + + /** + * Creates the report form. + */ + ngOnInit() { + this.createReportForm(); + this.toggleVisibility(); + this.setReportParameters(); + } + + /** + * Initializes the data source, paginator and sorter for report parameters table. + */ + setReportParameters() { + this.dataSource = new MatTableDataSource(this.reportParametersData); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + /** + * Creates the report form. + */ + createReportForm() { + this.reportForm = this.formBuilder.group({ + 'reportName': ['', Validators.required], + 'reportCategory': [''], + 'description': [''], + 'reportType': ['', Validators.required], + 'reportSubType': [{ value: '', disabled: true }], + 'useReport': [false], + 'reportSql': ['', Validators.required] + }); + } + + /** + * Adds a new report parameter. + */ + addReportParameter() { + this.dataForDialog.parameterName = undefined; + this.dataForDialog.reportParameterName = undefined; + const addReportParameterDialogRef = this.dialog.open(ReportParameterDialogComponent, { + data: this.dataForDialog + }); + addReportParameterDialogRef.afterClosed().subscribe((response: any) => { + if (response !== '') { + this.reportParametersData.push({ id: '', + parameterName: this.reportTemplateData.allowedParameters.find((allowedParameter: any) => allowedParameter.id === response.parameterName).parameterName, + parameterId: response.parameterName, + reportParameterName: response.reportParameterName }); + this.dataSource.connect().next(this.reportParametersData); + } + }); + } + + /** + * Edits report parameter. + * @param {any} reportParameter Report Parameter. + */ + editReportParameter(reportParameter: any) { + this.dataForDialog.parameterName = reportParameter.parameterId; + this.dataForDialog.reportParameterName = reportParameter.reportParameterName; + const editReportParameterDialogRef = this.dialog.open(ReportParameterDialogComponent, { + data: this.dataForDialog + }); + editReportParameterDialogRef.afterClosed().subscribe((response: any) => { + if (response !== '') { + this.reportParametersData[this.reportParametersData.indexOf(reportParameter)] = { id: '', + parameterName: this.reportTemplateData.allowedParameters.find((allowedParameter: any) => allowedParameter.id === response.parameterName).parameterName, + parameterId: response.parameterName, + reportParameterName: response.reportParameterName }; + this.dataSource.connect().next(this.reportParametersData); + } + }); + } + + /** + * Deletes the report parameter. + * @param {any} reportParameter Report Parameter. + */ + deleteReportParameter(reportParameter: any) { + const deleteReportDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `report parameter ${reportParameter.parameterName}` } + }); + deleteReportDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.reportParametersData.splice(this.reportParametersData.indexOf(reportParameter), 1); + this.dataSource.connect().next(this.reportParametersData); + } + }); + } + + /** + * Toggles the visibility status of Report Sub Type dropdown. + */ + toggleVisibility() { + this.reportForm.get('reportType').valueChanges + .subscribe(type => { + switch (type) { + case 'Chart': + this.reportForm.get('reportSubType').enable(); + this.reportForm.get('reportSql').enable(); + break; + case 'Pentaho': + this.reportForm.get('reportSql').disable(); + this.reportForm.get('reportSubType').disable(); + break; + default: + this.reportForm.get('reportSql').enable(); + this.reportForm.get('reportSubType').disable(); + } + }); + } + + /** + * Submits the report form and creates report, + * if successful redirects to view created report. + */ + submit() { + this.reportForm.value.reportParameters = this.reportParametersData.map( function(reportParameter: any) { + reportParameter.parameterName = undefined; + return reportParameter; + }); + this.systemService.createReport(this.reportForm.value) + .subscribe((response: any) => { + // TODO: Implement Maker Checker Component. + this.router.navigate(['../', response.resourceId], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/system/manage-reports/edit-report/edit-report.component.html b/src/app/system/manage-reports/edit-report/edit-report.component.html new file mode 100644 index 000000000..73389e319 --- /dev/null +++ b/src/app/system/manage-reports/edit-report/edit-report.component.html @@ -0,0 +1,134 @@ +
+ + + +
+ + + +
+ + + Report Name + + + Report Name is required + + + + + Report Type + + + {{ allowedReportType }} + + + + Report Type is required + + + + + Report Sub Type + + + {{ allowedReportSubType }} + + + + +
+ +
+ + + Report Category + + + +
+ + User Report (UI) + +
+ +
+ +
+ + + Description + + + + + SQL + + + SQL is required + + + +
+ +
+ +
+ +

Report Parameters

+ + + +
+ + + + + + + + + + + + + + + + + + + + + +
Parameter {{ reportParameter.parameterName }} Parameter Name Passed to Pentaho {{ reportParameter.reportParameterName }} Actions + + +
+ + + +
+ + + + + + +
+ +
+ +
diff --git a/src/app/system/manage-reports/edit-report/edit-report.component.scss b/src/app/system/manage-reports/edit-report/edit-report.component.scss new file mode 100644 index 000000000..e12a7bca2 --- /dev/null +++ b/src/app/system/manage-reports/edit-report/edit-report.component.scss @@ -0,0 +1,17 @@ +@media (min-width: 992px) { + + .user-report-wrapper { + position: relative; + + .user-report { + padding: 0 0 17.5px 0; + position: absolute; + bottom: 0; + } + } + +} + +table { + width: 100%; +} diff --git a/src/app/system/manage-reports/edit-report/edit-report.component.spec.ts b/src/app/system/manage-reports/edit-report/edit-report.component.spec.ts new file mode 100644 index 000000000..364b58bfc --- /dev/null +++ b/src/app/system/manage-reports/edit-report/edit-report.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditReportComponent } from './edit-report.component'; + +describe('EditReportComponent', () => { + let component: EditReportComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ EditReportComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditReportComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-reports/edit-report/edit-report.component.ts b/src/app/system/manage-reports/edit-report/edit-report.component.ts new file mode 100644 index 000000000..d5705a31e --- /dev/null +++ b/src/app/system/manage-reports/edit-report/edit-report.component.ts @@ -0,0 +1,208 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatTableDataSource, MatPaginator, MatSort, MatDialog } from '@angular/material'; + +/** Custom Services */ +import { SystemService } from 'app/system/system.service'; + +/** Custom Components */ +import { ReportParameterDialogComponent } from '../report-parameter-dialog/report-parameter-dialog.component'; +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * Edit Report Component. + */ +@Component({ + selector: 'mifosx-edit-report', + templateUrl: './edit-report.component.html', + styleUrls: ['./edit-report.component.scss'] +}) +export class EditReportComponent implements OnInit { + + /** Report Data. */ + reportData: any; + /** Report Template Data. */ + reportTemplateData: any; + /** Report Parameters Data. */ + reportParametersData: any[] = []; + /** Data passed to dialog. */ + dataForDialog: { allowedParameters: any[], parameterName: string, reportParameterName: string } = + { + allowedParameters: undefined, + parameterName: undefined, + reportParameterName: undefined + }; + /** Report Form. */ + reportForm: FormGroup; + /** Columns to be displayed in report parameters table. */ + displayedColumns: string[] = ['parameterName', 'parameterNamePassed', 'actions']; + /** Data source for report parameters table. */ + dataSource: MatTableDataSource; + /** Boolean to check if report parameters data is changed or not. */ + isReportParametersChanged: Boolean = false; + + /** Paginator for report parameters table. */ + @ViewChild(MatPaginator) paginator: MatPaginator; + /** Sorter for report parameters table. */ + @ViewChild(MatSort) sort: MatSort; + + /** + * Retrieves the report and report template data from `resolve`. + * @param {FormBuilder} formBuilder Form Builder. + * @param {SystemService} systemService System Service. + * @param {ActivatedRoute} route Activated Route. + * @param {Router} router Router for navigation. + * @param {MatDialog} dialog Dialog Reference. + */ + constructor(private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private systemService: SystemService, + private dialog: MatDialog) { + this.route.data.subscribe((data: { report: any, reportTemplate: any }) => { + this.reportData = data.report; + this.reportParametersData = data.report.reportParameters ? data.report.reportParameters : []; + this.reportTemplateData = data.reportTemplate; + this.dataForDialog.allowedParameters = this.reportData.allowedParameters; + }); + } + + /** + * Creates the report form. + */ + ngOnInit() { + this.createReportForm(); + this.setReportParameters(); + this.toggleVisibility(); + } + + /** + * Initializes the data source, paginator and sorter for report parameters table. + */ + setReportParameters() { + this.dataSource = new MatTableDataSource(this.reportParametersData); + this.dataSource.paginator = this.paginator; + this.dataSource.sort = this.sort; + } + + /** + * Creates and sets the report form. + */ + createReportForm() { + this.reportForm = this.formBuilder.group({ + 'reportName': [{ value: this.reportData.reportName, disabled: this.reportData.coreReport }, Validators.required], + 'reportCategory': [{ value: this.reportData.reportCategory ? this.reportData.reportCategory : '', disabled: this.reportData.coreReport }], + 'description': [{ value: this.reportData.description ? this.reportData.description : '', disabled: this.reportData.coreReport }], + 'reportType': [{ value: this.reportData.reportType, disabled: this.reportData.coreReport }, Validators.required], + 'reportSubType': [{ value: this.reportData.reportSubType ? this.reportData.reportSubType : '', disabled: this.reportData.reportType !== 'Chart' || this.reportData.coreReport }], + 'useReport': [this.reportData.useReport ? this.reportData.useReport : false], + 'reportSql': [{ value: this.reportData.reportSql, disabled: this.reportData.coreReport || this.reportData.reportType === 'Pentaho' }, Validators.required] + }); + } + + /** + * Adds a new report parameter. + */ + addReportParameter() { + this.dataForDialog.parameterName = undefined; + this.dataForDialog.reportParameterName = undefined; + const addReportParameterDialogRef = this.dialog.open(ReportParameterDialogComponent, { + data: this.dataForDialog + }); + addReportParameterDialogRef.afterClosed().subscribe((response: any) => { + if (response !== '') { + this.reportParametersData.push({ id: '', + parameterName: this.reportTemplateData.allowedParameters.find((allowedParameter: any) => allowedParameter.id === response.parameterName).parameterName, + parameterId: response.parameterName, + reportParameterName: response.reportParameterName ? response.reportParameterName : undefined }); + this.dataSource.connect().next(this.reportParametersData); + this.isReportParametersChanged = true; + } + }); + } + + /** + * Edits report parameter. + * @param {any} reportParameter Report Parameter. + */ + editReportParameter(reportParameter: any) { + this.dataForDialog.parameterName = reportParameter.parameterId; + this.dataForDialog.reportParameterName = reportParameter.reportParameterName; + const editReportParameterDialogRef = this.dialog.open(ReportParameterDialogComponent, { + data: this.dataForDialog + }); + editReportParameterDialogRef.afterClosed().subscribe((response: any) => { + if (response !== '') { + this.reportParametersData[this.reportParametersData.indexOf(reportParameter)] = { id: reportParameter.id, + parameterName: this.reportTemplateData.allowedParameters.find((allowedParameter: any) => allowedParameter.id === response.parameterName).parameterName, + parameterId: response.parameterName, + reportParameterName: response.reportParameterName }; + this.dataSource.connect().next(this.reportParametersData); + this.isReportParametersChanged = true; + } + }); + } + + /** + * Deletes the report parameter. + * @param {any} reportParameter Report Parameter. + */ + deleteReportParameter(reportParameter: any) { + const deleteReportDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `report parameter ${reportParameter.parameterName}` } + }); + deleteReportDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.reportParametersData.splice(this.reportParametersData.indexOf(reportParameter), 1); + this.dataSource.connect().next(this.reportParametersData); + this.isReportParametersChanged = true; + } + }); + } + + /** + * Toggles the visibility status of Report Sub Type dropdown. + */ + toggleVisibility() { + this.reportForm.get('reportType').valueChanges + .subscribe(type => { + switch (type) { + case 'Chart': + this.reportForm.get('reportSubType').enable(); + this.reportForm.get('reportSql').enable(); + break; + case 'Pentaho': + this.reportForm.get('reportSql').disable(); + this.reportForm.get('reportSubType').disable(); + break; + default: + this.reportForm.get('reportSql').enable(); + this.reportForm.get('reportSubType').disable(); + } + }); + } + + /** + * Submits the report form and updates report, + * if successful redirects to view updated report. + */ + submit() { + console.log(this.reportParametersData); + if (this.reportData.coreReport) { + this.reportForm.value.reportParameters = undefined; + } else { + this.reportForm.value.reportParameters = this.reportParametersData; + this.reportForm.value.reportParameters.map( function(reportParameter: any) { + reportParameter.parameterName = undefined; + return reportParameter; + }); + } + this.systemService.updateReport(this.reportData.id, this.reportForm.value) + .subscribe(() => { + this.router.navigate(['../'], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/system/manage-reports/manage-reports.component.html b/src/app/system/manage-reports/manage-reports.component.html new file mode 100644 index 000000000..edc2746fe --- /dev/null +++ b/src/app/system/manage-reports/manage-reports.component.html @@ -0,0 +1,69 @@ +
+ +
+ +
+ +
+ + Filter + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Report Name {{ report.reportName }} Report Type {{ report.reportType }} Report Sub Type {{ report.reportSubType }} Report Category {{ report.reportCategory }} Core Report + + + User Report + + +
+ + + +
+
diff --git a/src/app/system/manage-reports/manage-reports.component.scss b/src/app/system/manage-reports/manage-reports.component.scss new file mode 100644 index 000000000..fe0bbd1cc --- /dev/null +++ b/src/app/system/manage-reports/manage-reports.component.scss @@ -0,0 +1,16 @@ +table { + width: 100%; + + .select-row:hover { + cursor: pointer; + } +} + +// TODO: CONFIGURE THESE CLASSES GLOBALLY +.true { + color: #32cd32; +} + +.false { + color: #f44366; +} diff --git a/src/app/system/manage-reports/manage-reports.component.spec.ts b/src/app/system/manage-reports/manage-reports.component.spec.ts new file mode 100644 index 000000000..f38934028 --- /dev/null +++ b/src/app/system/manage-reports/manage-reports.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ManageReportsComponent } from './manage-reports.component'; + +describe('ManageReportsComponent', () => { + let component: ManageReportsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ManageReportsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ManageReportsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-reports/manage-reports.component.ts b/src/app/system/manage-reports/manage-reports.component.ts new file mode 100644 index 000000000..5f5481838 --- /dev/null +++ b/src/app/system/manage-reports/manage-reports.component.ts @@ -0,0 +1,62 @@ +/** Angular Imports */ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material'; + +/** + * Manage Reports Component. + */ +@Component({ + selector: 'mifosx-manage-reports', + templateUrl: './manage-reports.component.html', + styleUrls: ['./manage-reports.component.scss'] +}) +export class ManageReportsComponent implements OnInit { + + /** Reports Data. */ + reportsData: any; + /** Columns to be displayed in reports table. */ + displayedColumns: string[] = ['reportName', 'reportType', 'reportSubType', 'reportCategory', 'coreReport', 'userReport']; + /** Data source for reports table. */ + dataSource: 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. + */ + constructor(private route: ActivatedRoute) { + this.route.data.subscribe((data: { reports: any }) => { + this.reportsData = data.reports; + }); + } + + /** + * Sets the reports table. + */ + ngOnInit() { + this.setReports(); + } + + /** + * 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 data in reports table based on passed value. + * @param {string} filterValue Value to filter data. + */ + applyFilter(filterValue: string) { + this.dataSource.filter = filterValue.trim().toLowerCase(); + } + +} diff --git a/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.html b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.html new file mode 100644 index 000000000..97239890c --- /dev/null +++ b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.html @@ -0,0 +1,36 @@ +

{{ data.parameterName ? "Edit" : "Add" }} Report Parameter

+ + + +
+ +
+ + + Select allowed parameter + + + {{ allowedParameter.parameterName }} + + + + Report Parameter is required + + + + + Parameter name passed to Pentaho + + + +
+ +
+ +
+ + + + + diff --git a/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.scss b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.spec.ts b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.spec.ts new file mode 100644 index 000000000..f43221f11 --- /dev/null +++ b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ReportParameterDialogComponent } from './report-parameter-dialog.component'; + +describe('AddReportParameterDialogComponent', () => { + let component: ReportParameterDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ReportParameterDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ReportParameterDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.ts b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.ts new file mode 100644 index 000000000..3774f1881 --- /dev/null +++ b/src/app/system/manage-reports/report-parameter-dialog/report-parameter-dialog.component.ts @@ -0,0 +1,46 @@ +/** Angular Imports */ +import { Component, OnInit, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; + +/** + * Report Parameter Dialog Component. + */ +@Component({ + selector: 'mifosx-add-report-parameter-dialog', + templateUrl: './report-parameter-dialog.component.html', + styleUrls: ['./report-parameter-dialog.component.scss'] +}) +export class ReportParameterDialogComponent implements OnInit { + + /** Report Parameter Form. */ + reportParameterForm: FormGroup; + + /** + * @param {MatDialogRef} dialogRef Component reference to dialog. + * @param {FormBuilder} formBuilder Form Builder. + * @param {any} data Provides the allowed parameters and values for the form (if available). + */ + constructor(public dialogRef: MatDialogRef, + public formBuilder: FormBuilder, + @Inject(MAT_DIALOG_DATA) public data: any) { + } + + /** + * Creates the add report parameter form. + */ + ngOnInit() { + this.reportParameterForm = this.formBuilder.group({ + 'parameterName': [this.data.parameterName, Validators.required], + 'reportParameterName': [this.data.reportParameterName] + }); + } + + /** + * Closes the dialog and returns value of the form. + */ + submit() { + this.dialogRef.close(this.reportParameterForm.value); + } + +} diff --git a/src/app/system/manage-reports/report-template.resolver.ts b/src/app/system/manage-reports/report-template.resolver.ts new file mode 100644 index 000000000..a9c58e281 --- /dev/null +++ b/src/app/system/manage-reports/report-template.resolver.ts @@ -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 { SystemService } from '../system.service'; + +/** + * Report Template data resolver. + */ +@Injectable() +export class ReportTemplateResolver implements Resolve { + + /** + * @param {SystemService} systemService System service. + */ + constructor(private systemService: SystemService) {} + + /** + * Returns the Report Template data. + * @returns {Observable} + */ + resolve(): Observable { + return this.systemService.getReportTemplate(); + } + +} diff --git a/src/app/system/manage-reports/report.resolver.ts b/src/app/system/manage-reports/report.resolver.ts new file mode 100644 index 000000000..7f062f44e --- /dev/null +++ b/src/app/system/manage-reports/report.resolver.ts @@ -0,0 +1,31 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { SystemService } from '../system.service'; + +/** + * Report data resolver. + */ +@Injectable() +export class ReportResolver implements Resolve { + + /** + * @param {SystemService} systemService System service. + */ + constructor(private systemService: SystemService) {} + + /** + * Returns the Report data. + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const reportId = route.paramMap.get('id'); + return this.systemService.getReport(reportId); + } + +} diff --git a/src/app/system/manage-reports/reports.resolver.ts b/src/app/system/manage-reports/reports.resolver.ts new file mode 100644 index 000000000..7cf44177c --- /dev/null +++ b/src/app/system/manage-reports/reports.resolver.ts @@ -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 { SystemService } from '../system.service'; + +/** + * Reports data resolver. + */ +@Injectable() +export class ReportsResolver implements Resolve { + + /** + * @param {SystemService} systemService System service. + */ + constructor(private systemService: SystemService) {} + + /** + * Returns the Reports data. + * @returns {Observable} + */ + resolve(): Observable { + return this.systemService.getReports(); + } + +} diff --git a/src/app/system/manage-reports/view-report/view-report.component.html b/src/app/system/manage-reports/view-report/view-report.component.html new file mode 100644 index 000000000..abc36c625 --- /dev/null +++ b/src/app/system/manage-reports/view-report/view-report.component.html @@ -0,0 +1,69 @@ +
+ + + + + +
+ +
+ + + + {{ reportData.reportName }} + + + +
+ +
+ Report Type: +
+ +
+ {{ reportData.reportType }} +
+ +
+ Report Subtype: +
+ +
+ {{ reportData.reportSubType }} +
+ +
+ Report Category: +
+ +
+ {{ reportData.reportCategory }} +
+ +
+ Core Report: +
+ +
+ {{ reportData.coreReport ? 'Yes' : 'No' }} +
+ +
+ User Report: +
+ +
+ {{ reportData.useReport ? 'Yes' : 'No' }} +
+ +
+ +
+ +
diff --git a/src/app/system/manage-reports/view-report/view-report.component.scss b/src/app/system/manage-reports/view-report/view-report.component.scss new file mode 100644 index 000000000..9486249a1 --- /dev/null +++ b/src/app/system/manage-reports/view-report/view-report.component.scss @@ -0,0 +1,10 @@ +.container { + max-width: 37rem; + + .content { + div { + margin: 1rem 0; + word-wrap: break-word; + } + } +} diff --git a/src/app/system/manage-reports/view-report/view-report.component.spec.ts b/src/app/system/manage-reports/view-report/view-report.component.spec.ts new file mode 100644 index 000000000..9b75b70f5 --- /dev/null +++ b/src/app/system/manage-reports/view-report/view-report.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ViewReportComponent } from './view-report.component'; + +describe('ViewReportComponent', () => { + let component: ViewReportComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ViewReportComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ViewReportComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/system/manage-reports/view-report/view-report.component.ts b/src/app/system/manage-reports/view-report/view-report.component.ts new file mode 100644 index 000000000..4bb09b519 --- /dev/null +++ b/src/app/system/manage-reports/view-report/view-report.component.ts @@ -0,0 +1,60 @@ +/** Angular Imports */ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { MatDialog } from '@angular/material'; + +/** Custom Services */ +import { SystemService } from 'app/system/system.service'; + +/** Custom Components */ +import { DeleteDialogComponent } from 'app/shared/delete-dialog/delete-dialog.component'; + +/** + * View Report Component. + */ +@Component({ + selector: 'mifosx-view-report', + templateUrl: './view-report.component.html', + styleUrls: ['./view-report.component.scss'] +}) +export class ViewReportComponent implements OnInit { + + /** Report Data. */ + reportData: any; + + /** + * Retrieves the report data from `resolve`. + * @param {ActivatedRoute} route Activated Route. + * @param {SystemService} systemService System Service. + * @param {MatDialog} dialog Dialog Reference. + * @param {Router} router Router for navigation. + */ + constructor(private route: ActivatedRoute, + private systemService: SystemService, + private dialog: MatDialog, + private router: Router) { + this.route.data.subscribe((data: { report: any }) => { + this.reportData = data.report; + }); + } + + ngOnInit() { + } + + /** + * Deletes the current report. + */ + delete() { + const deleteReportDialogRef = this.dialog.open(DeleteDialogComponent, { + data: { deleteContext: `report ${this.reportData.id}` } + }); + deleteReportDialogRef.afterClosed().subscribe((response: any) => { + if (response.delete) { + this.systemService.deleteReport(this.reportData.id) + .subscribe(() => { + this.router.navigate(['/system/reports']); + }); + } + }); + } +} diff --git a/src/app/system/system-routing.module.ts b/src/app/system/system-routing.module.ts index 5ea27adf1..c7b379314 100644 --- a/src/app/system/system-routing.module.ts +++ b/src/app/system/system-routing.module.ts @@ -31,6 +31,10 @@ import { AccountNumberPreferencesComponent } from './account-number-preferences/ import { CreateAccountNumberPreferenceComponent } from './account-number-preferences/create-account-number-preference/create-account-number-preference.component'; import { ViewAccountNumberPreferenceComponent } from './account-number-preferences/view-account-number-preference/view-account-number-preference.component'; import { EditAccountNumberPreferenceComponent } from './account-number-preferences/edit-account-number-preference/edit-account-number-preference.component'; +import { ManageReportsComponent } from './manage-reports/manage-reports.component'; +import { EditReportComponent } from './manage-reports/edit-report/edit-report.component'; +import { CreateReportComponent } from './manage-reports/create-report/create-report.component'; +import { ViewReportComponent } from './manage-reports/view-report/view-report.component'; /** Custom Resolvers */ import { CodesResolver } from './codes/codes.resolver'; @@ -50,6 +54,9 @@ import { NotificationConfigurationResolver } from './external-services/notificat import { AccountNumberPreferencesResolver } from './account-number-preferences/account-number-preferences.resolver'; import { AccountNumberPreferencesTemplateResolver } from './account-number-preferences/create-account-number-preference/account-number-preferences-template.resolver'; import { AccountNumberPreferenceResolver } from './account-number-preferences/view-account-number-preference/account-number-preference.resolver'; +import { ReportsResolver } from './manage-reports/reports.resolver'; +import { ReportResolver } from './manage-reports/report.resolver'; +import { ReportTemplateResolver } from './manage-reports/report-template.resolver'; const routes: Routes = [ Route.withShell([ @@ -299,6 +306,49 @@ const routes: Routes = [ ] } ] + }, + { + path: 'reports', + data: { title: extract('Manage Reports'), breadcrumb: 'Manage Reports' }, + children: [ + { + path: '', + component: ManageReportsComponent, + resolve: { + reports: ReportsResolver + } + }, + { + path: 'create', + component: CreateReportComponent, + data: { title: extract('Create Report'), breadcrumb: 'Create' }, + resolve: { + reportTemplate: ReportTemplateResolver + } + }, + { + path: ':id', + data: { title: extract('View Report'), routeParamBreadcrumb: 'id' }, + children: [ + { + path: '', + component: ViewReportComponent, + resolve: { + report: ReportResolver + } + }, + { + path: 'edit', + component: EditReportComponent, + data: { title: extract('Edit Report'), routeParamBreadcrumb: false, breadcrumb: 'Edit' }, + resolve: { + report: ReportResolver, + reportTemplate: ReportTemplateResolver + } + } + ] + } + ] } ] } @@ -325,7 +375,10 @@ const routes: Routes = [ NotificationConfigurationResolver, AccountNumberPreferencesResolver, AccountNumberPreferencesTemplateResolver, - AccountNumberPreferenceResolver + AccountNumberPreferenceResolver, + ReportsResolver, + ReportResolver, + ReportTemplateResolver ] }) export class SystemRoutingModule { } diff --git a/src/app/system/system.component.html b/src/app/system/system.component.html index ff79f6c60..98025aa14 100644 --- a/src/app/system/system.component.html +++ b/src/app/system/system.component.html @@ -80,7 +80,7 @@

Audit logs of all the activities, such as create client, disburse loans etc

- + diff --git a/src/app/system/system.module.ts b/src/app/system/system.module.ts index f6e767b65..9eb800f8a 100644 --- a/src/app/system/system.module.ts +++ b/src/app/system/system.module.ts @@ -31,6 +31,13 @@ import { AccountNumberPreferencesComponent } from './account-number-preferences/ import { CreateAccountNumberPreferenceComponent } from './account-number-preferences/create-account-number-preference/create-account-number-preference.component'; import { ViewAccountNumberPreferenceComponent } from './account-number-preferences/view-account-number-preference/view-account-number-preference.component'; import { EditAccountNumberPreferenceComponent } from './account-number-preferences/edit-account-number-preference/edit-account-number-preference.component'; +import { ManageReportsComponent } from './manage-reports/manage-reports.component'; +import { ViewReportComponent } from './manage-reports/view-report/view-report.component'; +import { CreateReportComponent } from './manage-reports/create-report/create-report.component'; +import { EditReportComponent } from './manage-reports/edit-report/edit-report.component'; + +/** Dialog Component Imports */ +import { ReportParameterDialogComponent } from './manage-reports/report-parameter-dialog/report-parameter-dialog.component'; @NgModule({ imports: [ @@ -62,7 +69,15 @@ import { EditAccountNumberPreferenceComponent } from './account-number-preferenc AccountNumberPreferencesComponent, CreateAccountNumberPreferenceComponent, ViewAccountNumberPreferenceComponent, - EditAccountNumberPreferenceComponent + EditAccountNumberPreferenceComponent, + ManageReportsComponent, + ViewReportComponent, + CreateReportComponent, + EditReportComponent, + ReportParameterDialogComponent + ], + entryComponents: [ + ReportParameterDialogComponent ] }) export class SystemModule { } diff --git a/src/app/system/system.service.ts b/src/app/system/system.service.ts index 5714d3e58..98b5824fe 100644 --- a/src/app/system/system.service.ts +++ b/src/app/system/system.service.ts @@ -224,4 +224,51 @@ export class SystemService { return this.http.put(`/accountnumberformats/${accountNumberPreferenceId}`, accountNumberPreferenceChanges); } + /** + * @returns {Observable} Reports. + */ + getReports(): Observable { + return this.http.get('/reports'); + } + + /** + * @param {string} reportId Report ID. + * @returns {Observable} Report. + */ + getReport(reportId: string): Observable { + return this.http.get(`/reports/${reportId}?template=true`); + } + + /** + * @returns {Observable} Report Template. + */ + getReportTemplate(): Observable { + return this.http.get('/reports/template'); + } + + /** + * @param {any} report Report. + * @returns {Observable} + */ + createReport(report: any): Observable { + return this.http.post('/reports', report); + } + + /** + * @param {string} reportId Report ID. + * @param {any} report Report. + * @returns {Observable} + */ + updateReport(reportId: string, report: any): Observable { + return this.http.put(`/reports/${reportId}`, report); + } + + /** + * @param {string} reportId Report ID. + * @returns {Observable} + */ + deleteReport(reportId: string): Observable { + return this.http.delete(`/reports/${reportId}`); + } + }