File

angular/projects/researchdatabox/report/src/app/report.component.ts

Description

Report Component

Author: Shilo B

Extends

BaseComponent

Implements

RecordSource

Metadata

Index

Properties
Methods

Constructor

constructor(loggerService: LoggerService, reportService: ReportService, configService: ConfigService, translationService: TranslationService, elementRef: ElementRef)
Parameters :
Name Type Optional
loggerService LoggerService No
reportService ReportService No
configService ConfigService No
translationService TranslationService No
elementRef ElementRef No

Methods

Public Async filter
filter(event?: any)
Parameters :
Name Type Optional
event any Yes
Returns : any
getCurrentPage
getCurrentPage()
Returns : ReportResultDto
Public getDownloadCSVUrl
getDownloadCSVUrl()
Returns : string
Public getLuxonDateFromJs
getLuxonDateFromJs(srcDate: Date, tz: string, mode: string)
Parameters :
Name Type Optional
srcDate Date No
tz string No
mode string No
Returns : any
Public getParams
getParams()
Returns : any
Async gotoPage
gotoPage(pageNum: number)
Parameters :
Name Type Optional
pageNum number No
Returns : Promise<RecordPageDto>
Public Async headerSortChanged
headerSortChanged(event: any, data: any)
Parameters :
Name Type Optional
event any No
data any No
Returns : any
Protected Async initComponent
initComponent()
Inherited from BaseComponent
Defined in BaseComponent:77
Returns : Promise<void>
Public Async recordTableAction
recordTableAction(event: any, data: any, actionName: string)
Parameters :
Name Type Optional
event any No
data any No
actionName string No
Returns : any
getInitSubject
getInitSubject()
Inherited from BaseComponent
Defined in BaseComponent:71

For those interested in the init from RXJS-land.

Note that it returns a BehaviorSubject instance, and will have an initial value of false, so process the return value as needed.

Returns : Subject<any>
isInitializing
isInitializing()
Inherited from BaseComponent
Defined in BaseComponent:95

Main flag to indicate the init status

Returns : boolean
ngOnInit
ngOnInit()
Inherited from BaseComponent
Defined in BaseComponent:50
Returns : void
Async waitForDeps
waitForDeps()
Inherited from BaseComponent
Defined in BaseComponent:78

Wait for dependencies to initialise

Returns : Promise<any>
Async waitForInit
waitForInit()
Inherited from BaseComponent
Defined in BaseComponent:89

For those interested in the init from the Promise-land

Returns : Promise<any>

Properties

appName
Type : string
Default value : 'report'
dateParamTz
Type : string
Default value : 'utc'
datePickerOpts
Type : any
datePickerPlaceHolder
Type : string
Default value : ''
filterParams
Type : any
Default value : {}
initTracker
Type : any
Default value : { reportLoaded: false, resultsReturned: false }
optTemplateData
Type : any
Default value : {}
paginationMaxSize
Type : number
Default value : 10
recordsPerPage
Type : number
Default value : 10
report
Type : ReportDto
Default value : null as any
reportName
Type : string
Default value : ''
reportParams
Type : any
Default value : {}
reportResult
Type : ReportResultDto
Default value : null as any
tableHeaders
Type : RecordPropViewMetaDto[]
Default value : null as any
Protected brandingAndPortalUrl
Type : string
Default value : ''
Inherited from BaseComponent
Defined in BaseComponent:42
Private filterFn
Default value : function(initStat: boolean) { return initStat; }
Inherited from BaseComponent
Defined in BaseComponent:40
Protected initDependencies
Type : Initable[]
Default value : []
Inherited from BaseComponent
Defined in BaseComponent:39
Protected initSubject
Type : BehaviorSubject<any>
Default value : new BehaviorSubject(false)
Inherited from BaseComponent
Defined in BaseComponent:38
Protected isReady
Type : boolean
Default value : false
Inherited from BaseComponent
Defined in BaseComponent:37
import { Component, Inject, ElementRef } from '@angular/core';
import { ConfigService, LoggerService, TranslationService, ReportService, BaseComponent } from '@researchdatabox/portal-ng-common';
import { RecordSource } from '@researchdatabox/portal-ng-common';
import {  RecordPropViewMetaDto, ReportDto, ReportResultDto, RecordPageDto } from '@researchdatabox/sails-ng-common';
import { isEmpty as _isEmpty, set as _set, map as _map } from 'lodash-es';
import { DateTime } from 'luxon';
/**
 * Report Component
 *
 * Author: <a href='https://github.com/shilob' target='_blank'>Shilo B</a>
 */
@Component({
  selector: 'report',
  templateUrl: './report.component.html',
  styleUrls: ['./report.component.scss']
})
export class ReportComponent extends BaseComponent implements RecordSource {
  datePickerPlaceHolder: string = '';
  datePickerOpts: any;
  filterParams: any = {};
  initTracker: any = { reportLoaded: false, resultsReturned: false };
  report: ReportDto = null as any;
  reportResult: ReportResultDto = null as any;
  tableHeaders: RecordPropViewMetaDto[] = null as any;
  appName:string = 'report';
  optTemplateData:any = {};
  reportName: string = '';
  reportParams: any = {};
  recordsPerPage: number = 10;
  paginationMaxSize: number = 10;
  // See https://moment.github.io/luxon/docs/manual/zones.html#specifying-a-zone
  dateParamTz: string = 'utc';

  constructor(
    @Inject(LoggerService) private loggerService: LoggerService,
    @Inject(ReportService) protected reportService: ReportService,
    @Inject(ConfigService) private configService: ConfigService,
    @Inject(TranslationService) private translationService: TranslationService,
    @Inject(ElementRef) elementRef: ElementRef
  ) {
    super();
    this.initDependencies = [this.translationService, this.reportService];
    this.reportName = elementRef.nativeElement.getAttribute('reportName');
    this.loggerService.debug(`'${this.appName} - ${this.reportName}' waiting for deps to init...`);
  }

  getCurrentPage() {
    return this.reportResult;
  }

  async gotoPage(pageNum: number): Promise<RecordPageDto> {
    this.initTracker.resultsReturned = false;
    this.reportResult =  await this.reportService.getReportResult(this.reportName, pageNum, this.getParams(), this.recordsPerPage);
    this.initTracker.resultsReturned = true;
    return this.reportResult;
  }

  protected async initComponent(): Promise<void> {
    const sysConfig = await this.configService.getConfig();
    const defaultDatePickerOpts = { dateInputFormat: 'DD/MM/YYYY', containerClass: 'theme-dark-blue' };
    const defaultDatePickerPlaceHolder = 'dd/mm/yyyy';
    this.datePickerOpts = ConfigService._getAppConfigProperty(sysConfig, this.appName, 'datePickerOpts', defaultDatePickerOpts);
    this.datePickerPlaceHolder = ConfigService._getAppConfigProperty(sysConfig, this.appName, 'datePickerPlaceHolder', defaultDatePickerPlaceHolder);
    this.brandingAndPortalUrl = this.reportService.brandingAndPortalUrl;
    _set(this.optTemplateData, 'brandingAndPortalUrl', this.brandingAndPortalUrl);
    this.recordsPerPage = ConfigService._getAppConfigProperty(sysConfig, this.appName, 'recordsPerPage', this.recordsPerPage);
    this.dateParamTz = ConfigService._getAppConfigProperty(sysConfig, this.appName, 'dateParamTz', this.dateParamTz);
    this.paginationMaxSize = ConfigService._getAppConfigProperty(sysConfig, this.appName, 'paginationMaxSize', this.paginationMaxSize);
    this.report = await this.reportService.getReportConfig(this.reportName);
    this.tableHeaders = this.report.columns;
    this.initTracker.reportLoaded = true;
    this.gotoPage(1);
    this.loggerService.debug(`'${this.appName}' ready!`);
  }

  public async filter(event?: any) {
    await this.gotoPage(1);
  }

  public getDownloadCSVUrl() {
    let url = `${this.brandingAndPortalUrl}/admin/downloadReportCSV?name=${this.reportName}`;
    let params = this.getParams();
    for(var key in params) {
      url=url+'&'+key+"="+params[key];
    }
    return url;
  }

  public getLuxonDateFromJs(srcDate: Date, tz: string, mode: string) {
    if (mode == 'floor') {
      srcDate.setHours(0, 0, 0, 0);
    } else if (mode == 'ceil') {
      srcDate.setHours(23, 59, 59, 999);
    }
    return DateTime.fromJSDate(srcDate, {zone: tz});
  }

  public getParams() {
    var params:any = {};
    for(let filter of this.report.filter) {
      if (filter.type == 'date-range') {
        const fromDateJs = this.filterParams[filter.paramName + "_fromDate"];
        const toDateJs = this.filterParams[filter.paramName + "_toDate"];
        var fromDate = fromDateJs ? this.getLuxonDateFromJs(fromDateJs, this.dateParamTz, 'floor') : null;
        var toDate = toDateJs ? this.getLuxonDateFromJs(toDateJs, this.dateParamTz, 'ceil') : null;

        if (fromDate != null) {
          params[filter.paramName + "_fromDate"] = fromDate.toISO();
        }
        if (toDate != null) {
          params[filter.paramName + "_toDate"] = toDate.toISO();
        }
      } else {
        let paramValue = this.filterParams[filter.paramName];
        if(!_isEmpty(paramValue)) {
         params[filter.paramName] = paramValue;
        }
      }
    }
    return params;
  }

  public async recordTableAction(event: any, data: any, actionName: string) {
    console.log('recordTableAction', arguments);
  }

  public async headerSortChanged(event: any, data: any) {
    console.log('headerSortChanged', arguments);
  }
}
<ng-container *ngIf="isReady">
  <!-- The report title -->
  <div class="row">
    <div class="col-xs-12">
      <h1 class="text-center" *ngIf="report && report.title">
        {{ report.title }}
      </h1>
    </div>
  </div>
  <!-- Render the report's filter UI elements -->
  <div class="row" *ngIf="report && report.filter != null">
    <div class="panel panel-default">
      <div class="panel-body">
        <div class="row">
          <div class="text-center h4-header mb-2">
            {{ 'report-filters-heading' | i18next }}
          </div>
        </div>
        <ng-container *ngFor="let filter of report.filter">
          
          <!-- Text filter -->
          <div *ngIf="filter.type == 'text'" class="row">
            <div class="col-md-2"></div>
            <div class="col-xs-2">
              <label [for]="filter.paramName">{{filter.message}}</label>
            </div>
            <div class="col-xs-6">
              <input [id]="filter.paramName" type="text" class="form-control" [(ngModel)]="filterParams[ filter['paramName']]">
            </div>
            <div class="col-md-2"></div>
          </div>
          <!-- Date filter -->
          
          <div *ngIf="filter.type == 'date-range'" class="row">
            <div class="col-md-2"></div>
            <div class="col-12 col-sm-2 col-md-2">
              <label [for]="filter.paramName" class="report-filter-date-range-label">{{filter.message}}</label>
            </div>
            <div class="col-12 col-sm-3 col-md-3">
             
                <div class="form-group">
                  <label class="control-label mr-2">{{ 'report-filter-date-from' | i18next }}</label>

                    <input type="text" [id]="filter.paramName + '_fromDate'"
                      [bsConfig] = "datePickerOpts"
                      [placeholder] = "datePickerPlaceHolder"
                      [(ngModel)]="filterParams[ filter['paramName'] + '_fromDate']"
                      bsDatepicker />
             
              </div>
            </div>
            <div class="col-12 col-sm-3 col-md-3">
              
                <div class="form-group">
                  <label class="control-label mr-2">{{ 'report-filter-date-to' | i18next }}</label>    
                    <input type="text" [id]="filter.paramName + '_toDate'"
                    [bsConfig] = "datePickerOpts"
                    [placeholder] = "datePickerPlaceHolder"
                    [(ngModel)]="filterParams[ filter['paramName'] + '_toDate']"
                    bsDatepicker />
                  </div>
            </div>
            <div class="col-md-2"></div>
          </div>
          
        </ng-container>
        <div class="row">
          <div class="col-xs-2"></div>
          <div class="col-xs-8" style="text-align:right; padding-top:15px;">
            <a class="btn btn-large btn-primary" (click)="filter()">
              <span class="glyphicon glyphicon-search"></span>
              {{ 'report-filter-button' | i18next }}
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- Result overview  -->
  <div class="row" *ngIf="initTracker && initTracker.resultsReturned">
    <div class="col-xs-2">
      <span *ngIf="initTracker.resultsReturned == false">
        <span class="fa fa-spinner fa-spin fa-fw"></span>
          {{ 'report-retrieving-results' | i18next }}
      </span>
      <span *ngIf="initTracker.resultsReturned == true"
        [innerHTML]='"report-results-returned" | i18next: {count: reportResult.total }'>
      </span>
    </div>
    <div class="col-xs-8"></div>
    <div class="col-xs-2">
      <a class="btn btn-large btn-primary" [attr.href]='getDownloadCSVUrl()'>
        <span class="glyphicon glyphicon-download"></span>
        {{ 'report-csv-download' | i18next }}
      </a>
    </div>
  </div>
  <!-- Result details -->
  <record-table [columnConfig]="tableHeaders" [dataSource]="this" [optTemplateData]="optTemplateData" [paginationItemsPerPage]="recordsPerPage" [paginationMaxSize]="paginationMaxSize">
  </record-table>
</ng-container>

./report.component.scss

.report-filter-date-range-label
{
    margin-top: 10px;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""