refactor: reports module (#1227)

Fixes: #1196
This commit is contained in:
Karan Takalkar
2020-08-26 01:53:10 +05:30
committed by GitHub
parent efdd779aa9
commit 0f83739080
19 changed files with 206 additions and 200 deletions
@@ -43,7 +43,7 @@ export class ChartComponent implements OnChanges {
}
getRunReportData() {
this.reportsService.getChartRunReportData(this.dataObject.reportData, this.dataObject.formData)
this.reportsService.getChartRunReportData(this.dataObject.report.name, this.dataObject.formData)
.subscribe((response: ChartData) => {
this.inputData = response;
this.setPieChart(this.inputData);
@@ -39,7 +39,7 @@ export class PentahoComponent implements OnChanges {
}
getRunReportData() {
this.reportsService.getPentahoRunReportData(this.dataObject.reportData, this.dataObject.formData, 'default', 'en', 'dd MMMM yyyy')
this.reportsService.getPentahoRunReportData(this.dataObject.report.name, this.dataObject.formData, 'default', 'en', 'dd MMMM yyyy')
.subscribe( (res: any) => {
const contentType = res.headers.get('Content-Type');
const file = new Blob([res.body], {type: contentType});
@@ -2,85 +2,76 @@
<mat-card *ngIf="!isCollapsed">
<form [formGroup]="ReportForm" (ngSubmit)="run()">
<form [formGroup]="reportForm" (ngSubmit)="run()">
<mat-card-content>
<div fxLayout="column" *ngFor="let param of paramData">
<mat-card-content fxLayout="column">
<div [ngSwitch]="param.displayType">
<div *ngIf="ReportForm.contains(param.name)">
<mat-form-field fxFlex="100%" *ngSwitchCase="'text'">
<mat-label>{{param.label}}</mat-label>
<input matInput required [formControlName]="param.name">
<mat-error *ngIf="ReportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong>
</mat-error>
</mat-form-field>
</div>
<div *ngIf="ReportForm.contains(param.name)">
<mat-form-field fxFlex="100%" *ngSwitchCase="'date'">
<mat-label>{{param.label}}</mat-label>
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="runReportDatePicker" required [formControlName]="param.name">
<mat-datepicker-toggle matSuffix [for]="runReportDatePicker"></mat-datepicker-toggle>
<mat-datepicker #runReportDatePicker></mat-datepicker>
<mat-error *ngIf="ReportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong>
</mat-error>
</mat-form-field>
</div>
<div *ngIf="ReportForm.contains(param.name) ">
<mat-form-field fxFlex="100%" *ngSwitchCase="'select'" >
<mat-label>{{param.label}}</mat-label>
<mat-select required [formControlName]="param.name">
<mat-option *ngFor="let option of param.selectOptions" [value]="option" >
<ng-container *ngFor="let param of paramData" [ngSwitch]="param.displayType">
<ng-container *ngIf="reportForm.contains(param.name)">
<mat-form-field fxFlex *ngSwitchCase="'text'">
<mat-label>{{param.label}}</mat-label>
<input matInput required [formControlName]="param.name">
<mat-error *ngIf="reportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex *ngSwitchCase="'date'">
<mat-label>{{param.label}}</mat-label>
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="runReportDatePicker" required
[formControlName]="param.name">
<mat-datepicker-toggle matSuffix [for]="runReportDatePicker"></mat-datepicker-toggle>
<mat-datepicker #runReportDatePicker></mat-datepicker>
<mat-error *ngIf="reportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong>
</mat-error>
</mat-form-field>
<mat-form-field fxFlex *ngSwitchCase="'select'">
<mat-label>{{param.label}}</mat-label>
<mat-select required [formControlName]="param.name">
<mat-option *ngFor="let option of param.selectOptions" [value]="option">
{{option.name}}
</mat-option>
</mat-select>
<mat-error *ngIf="ReportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong>
</mat-error>
</mat-form-field>
</div>
</div>
</div>
<div>
<mat-form-field fxFlex="100%">
<mat-label>Decimal Places</mat-label>
<mat-select [formControl]="decimalChoice">
<mat-option value="0">0</mat-option>
<mat-option value="1">1</mat-option>
<mat-option value="2">2</mat-option>
<mat-option value="3">3</mat-option>
<mat-option value="4">4</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngIf="report.type === 'Pentaho' && ReportForm.contains('outputType')">
<mat-form-field fxFlex="100%">
<mat-label>Output Type</mat-label>
<mat-select formControlName="outputType" value="HTML">
<mat-option value="HTML">Normal format</mat-option>
<mat-option value="XLS">Excel format</mat-option>
<mat-option value="XLSX">Excel 2007 format</mat-option>
<mat-option value="CSV">CSV format</mat-option>
<mat-option value="PDF">PDF format</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-option>
</mat-select>
<mat-error *ngIf="reportForm.controls[param.name].hasError('required')">
{{param.label}} is <strong>required</strong>
</mat-error>
</mat-form-field>
</ng-container>
</ng-container>
<mat-form-field fxFlex>
<mat-label>Decimal Places</mat-label>
<mat-select [formControl]="decimalChoice">
<mat-option value="0">0</mat-option>
<mat-option value="1">1</mat-option>
<mat-option value="2">2</mat-option>
<mat-option value="3">3</mat-option>
<mat-option value="4">4</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex *ngIf="report.type === 'Pentaho' && reportForm.contains('outputType')">
<mat-label>Output Type</mat-label>
<mat-select formControlName="outputType" value="HTML">
<mat-option value="HTML">Normal format</mat-option>
<mat-option value="XLS">Excel format</mat-option>
<mat-option value="XLSX">Excel 2007 format</mat-option>
<mat-option value="CSV">CSV format</mat-option>
<mat-option value="PDF">PDF format</mat-option>
</mat-select>
</mat-form-field>
</mat-card-content>
<mat-card-actions fxLayout="row" fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap="5px">
<button type="button" mat-raised-button [routerLink]="['/reports']">Cancel</button>
<button mat-raised-button color="primary" [disabled]="!ReportForm.valid" id="runReport">
<button mat-raised-button color="primary" [disabled]="!reportForm.valid" id="runReport">
<fa-icon icon="cogs"></fa-icon>
&nbsp; Run Report
</button>
@@ -25,20 +25,23 @@ export class RunReportComponent implements OnInit {
minDate = new Date(2000, 0, 1);
/** Maximum date allowed. */
maxDate = new Date();
/** Contains report specifications i.e: name, type and id */
report: any = {};
/** Formatted data post labeling of report parameters fetched from API */
paramData: any = [];
paramData: ReportParameter[] = [];
/** Array of all parent parameters */
parentParameters: any[] = [];
/** Parameter data to configure pentaho output */
pentahoReportParameters: any[] = [];
/** Data to be passed on to component selectors */
dataObject: any;
/** Initializes new form group 'ReportForm */
ReportForm = new FormGroup({});
/** Initializes new form group eportForm */
reportForm = new FormGroup({});
/** Static Form control for decimal places in output */
decimalChoice = new FormControl();
/** Toggles Report form */
isCollapsed = false;
/** Toggles Table output. */
@@ -51,18 +54,19 @@ export class RunReportComponent implements OnInit {
/**
* Fetches report specifications from route params and retrieves report parameters data from `resolve`.
* @param {ActivatedRoute} route ActivatedRoute.
* @param {DomSanitizer} sanitizer DomSanitizer.
* @param {ReportsService} reportsService ReportsService
* @param {DatePipe} datePipe Date Pipe
*/
constructor(private route: ActivatedRoute,
private reportsService: ReportsService,
private datePipe: DatePipe) {
this.report.name = this.route.snapshot.params['report-name'];
this.report.type = this.route.snapshot.params['report-type'];
this.report.id = this.route.snapshot.params['report-id'];
this.route.data.subscribe((data: any) => {
this.paramData = data.params;
this.report.name = this.route.snapshot.params['name'];
this.route.queryParams.subscribe((queryParams: { type: any, id: any }) => {
this.report.type = queryParams.type;
this.report.id = queryParams.id;
});
this.route.data.subscribe((data: { reportParameters: ReportParameter[] }) => {
this.paramData = data.reportParameters;
});
}
@@ -79,39 +83,39 @@ export class RunReportComponent implements OnInit {
*/
createRunReportForm() {
this.paramData.forEach(
(param: any) => {
if (!param.parentParameterName) {
this.ReportForm.addControl(param.name, new FormControl('', Validators.required));
(param: ReportParameter) => {
if (!param.parentParameterName) { // Non Child Parameter
this.reportForm.addControl(param.name, new FormControl('', Validators.required));
if (param.displayType === 'select') {
this.fetchSelectOptions(param, param.name);
}
} else {
} else { // Child Parameter
const parent: ReportParameter = this.paramData
.find((entry: any) => entry.name === param.parentParameterName);
parent.childParameter = param;
this.parentParameters.push(parent);
parent.childParameters.push(param);
this.updateParentParameters(parent);
}
});
if (this.report.type === 'Pentaho') {
this.ReportForm.addControl('outputType', new FormControl(''));
this.reportForm.addControl('outputType', new FormControl(''));
this.mapPentahoParams();
}
this.decimalChoice.patchValue('0');
this.setChildControls();
}
/**
* Fetches Select Dropdown options for param type "Select".
* @param {ReportParameter} param Parameter for which dropdown options are required.
* @param {string} inputstring url substring for API call.
*/
fetchSelectOptions(param: ReportParameter, inputstring: string) {
this.reportsService.getSelectOptions(inputstring).subscribe((options: SelectOption[]) => {
param.selectOptions = options;
if (param.selectAll === 'Y') {
param.selectOptions.push({id: '-1', name: 'All'});
}
});
/**
* Updates the array of parent parameters.
* @param {ReportParameter} parent Parent report parameter
*/
updateParentParameters(parent: ReportParameter) {
const parentNames = this.parentParameters.map(parameter => parameter.name);
if (!parentNames.includes(parent.name)) { // Parent's first child.
this.parentParameters.push(parent);
} else { // Parent already has a child
const index = parentNames.indexOf(parent.name);
this.parentParameters[index] = parent;
}
}
/**
@@ -132,16 +136,36 @@ export class RunReportComponent implements OnInit {
*/
setChildControls() {
this.parentParameters.forEach((param: ReportParameter) => {
this.ReportForm.get(param.name).valueChanges.subscribe((option: any) => {
this.ReportForm.addControl(param.childParameter.name, new FormControl('', Validators.required));
if (param.childParameter.displayType === 'select') {
const inputstring = `${param.childParameter.name}?${param.inputName}=${option.id}`;
this.fetchSelectOptions(param.childParameter, inputstring);
}
this.reportForm.get(param.name).valueChanges.subscribe((option: any) => {
param.childParameters.forEach((child: ReportParameter) => {
if (child.displayType === 'none') {
this.reportForm.addControl(child.name, new FormControl(child.defaultVal));
} else {
this.reportForm.addControl(child.name, new FormControl('', Validators.required));
}
if (child.displayType === 'select') {
const inputstring = `${child.name}?${param.inputName}=${option.id}`;
this.fetchSelectOptions(child, inputstring);
}
});
});
});
}
/**
* Fetches Select Dropdown options for param type "Select".
* @param {ReportParameter} param Parameter for which dropdown options are required.
* @param {string} inputstring url substring for API call.
*/
fetchSelectOptions(param: ReportParameter, inputstring: string) {
this.reportsService.getSelectOptions(inputstring).subscribe((options: SelectOption[]) => {
param.selectOptions = options;
if (param.selectAll === 'Y') {
param.selectOptions.push({id: '-1', name: 'All'});
}
});
}
/**
* Formats user response and readies it for utilization by run report function.
* @param {any} response Object containing formcontrol values.
@@ -168,6 +192,9 @@ export class RunReportComponent implements OnInit {
const dateFormat = 'yyyy-MM-dd';
formattedResponse[newKey] = this.datePipe.transform(value, dateFormat);
break;
case 'none':
formattedResponse[newKey] = value;
break;
}
}
return formattedResponse;
@@ -178,10 +205,10 @@ export class RunReportComponent implements OnInit {
*/
run() {
this.isCollapsed = true;
const userResponse = this.formatUserResponse(this.ReportForm.value);
const userResponse = this.formatUserResponse(this.reportForm.value);
this.dataObject = {
formData: userResponse,
reportData: this.report,
report: this.report,
decimalChoice: this.decimalChoice.value
};
switch (this.report.type) {
@@ -1,6 +1,6 @@
<div *ngIf = "!hideOutput">
<div class="m-b-10" *ngIf = "dataObject.reportData.type === 'Table'" fxLayoutAlign="end">
<div class="m-b-10" *ngIf = "dataObject.report.type === 'Table'" fxLayoutAlign="end">
<button mat-raised-button color="primary" (click)="downloadCSV()" >
Export CSV
</button>
@@ -52,7 +52,7 @@ export class TableAndSmsComponent implements OnChanges {
}
getRunReportData() {
this.reportsService.getRunReportData(this.dataObject.reportData, this.dataObject.formData)
this.reportsService.getRunReportData(this.dataObject.report.name, this.dataObject.formData)
.subscribe( (res: any) => {
this.csvData = res.data;
this.setOutputTable(res.data);
@@ -85,7 +85,7 @@ export class TableAndSmsComponent implements OnChanges {
csv = csv.join('\r\n');
const link = document.createElement('a');
link.setAttribute('href', encodeURI(csv));
link.setAttribute('download', `${this.dataObject.reportData.name}.csv`);
link.setAttribute('download', `${this.dataObject.report.name}.csv`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);