File

src/app/modules/shared/components/on-demand-reports/on-demand-reports.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs

Constructor

constructor(resourceService: ResourceService, telemetryService: TelemetryService, onDemandReportService: OnDemandReportService, toasterService: ToasterService)
Parameters :
Name Type Optional
resourceService ResourceService No
telemetryService TelemetryService No
onDemandReportService OnDemandReportService No
toasterService ToasterService No

Inputs

batch
Type : any
reportTypes
Type : any
tag
Type : any
userId
Type : any

Methods

checkStatus
checkStatus()
Returns : boolean
dataModification
dataModification(row)
Parameters :
Name Optional
row No
Returns : any
generateTelemetry
generateTelemetry(fieldType, batchId, courseId)
Parameters :
Name Optional
fieldType No
batchId No
courseId No
Returns : void
loadReports
loadReports(batchDetails?: any)
Parameters :
Name Type Optional
batchDetails any Yes
Returns : void
ngOnInit
ngOnInit()
Returns : void
onDownloadLinkFail
onDownloadLinkFail(data)
Parameters :
Name Optional
data No
Returns : void
reportChanged
reportChanged(ev)
Parameters :
Name Optional
ev No
Returns : void
submitRequest
submitRequest()
Returns : void

Properties

Public columns
Type : []
Default value : [ {name: 'Report type', isSortable: true, prop: 'title', placeholder: 'Filter report type'}, {name: 'Request date', isSortable: true, prop: 'jobStats.dtJobSubmitted', placeholder: 'Filter request date', type: 'date'}, {name: 'Status', isSortable: false, prop: 'status', placeholder: 'Filter status'}, {name: 'Report link', isSortable: false, prop: 'downloadUrls', placeholder: 'Filter download link'}, {name: 'Generated date', isSortable: true, prop: 'jobStats.dtJobCompleted', placeholder: 'Filter generated date', type: 'dateTime'}, // { name: 'Requested by', isSortable: true, prop: 'requested_by', placeholder: 'Filter request by' }, ]
Public fileName
Type : string
Default value : ''
instance
Type : string
Public isDownloadReport
Default value : false
Public isProcessed
Default value : false
Public message
Type : string
Default value : 'There is no data available'
Public onDemandReportData
Type : any[]
Public onDemandReportService
Type : OnDemandReportService
Public reportForm
Type : UntypedFormGroup
reportStatus
Type : object
Default value : { 'submitted': 'SUBMITTED', 'processing': 'PROCESSING', 'failed': 'FAILED', 'success': 'SUCCESS', }
Public resourceService
Type : ResourceService
Public selectedReport
Public telemetryService
Type : TelemetryService
Public toasterService
Type : ToasterService
import {Component, OnInit, Input} from '@angular/core';
import {ResourceService, ToasterService} from '../../services';
import {OnDemandReportService} from '../../services/on-demand-report/on-demand-report.service';
import * as _ from 'lodash-es';
import {Validators, UntypedFormControl, UntypedFormGroup} from '@angular/forms';
import {TelemetryService} from '@sunbird/telemetry';

@Component({
  selector: 'app-on-demand-reports',
  templateUrl: './on-demand-reports.component.html',
  styleUrls: ['./on-demand-reports.component.scss']
})
export class OnDemandReportsComponent implements OnInit {

  @Input() reportTypes;
  @Input() tag;
  @Input() userId;
  @Input() batch;
  public columns = [
    {name: 'Report type', isSortable: true, prop: 'title', placeholder: 'Filter report type'},
    {name: 'Request date', isSortable: true, prop: 'jobStats.dtJobSubmitted', placeholder: 'Filter request date', type: 'date'},
    {name: 'Status', isSortable: false, prop: 'status', placeholder: 'Filter status'},
    {name: 'Report link', isSortable: false, prop: 'downloadUrls', placeholder: 'Filter download link'},
    {name: 'Generated date', isSortable: true, prop: 'jobStats.dtJobCompleted', placeholder: 'Filter generated date', type: 'dateTime'},
    // { name: 'Requested by', isSortable: true, prop: 'requested_by', placeholder: 'Filter request by' },
  ];
  public onDemandReportData: any[];
  public isDownloadReport = false;
  public fileName = '';
  public selectedReport;
  public reportForm: UntypedFormGroup;
  // public password = new FormControl('', [Validators.minLength(6), Validators.required, Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$')]);
  public message = 'There is no data available';
  public isProcessed = false;
  reportStatus = {
    'submitted': 'SUBMITTED',
    'processing': 'PROCESSING',
    'failed': 'FAILED',
    'success': 'SUCCESS',
  };
  instance: string;

  constructor(public resourceService: ResourceService, public telemetryService: TelemetryService,
    public onDemandReportService: OnDemandReportService, public toasterService: ToasterService) {
      this.reportForm = new UntypedFormGroup({
        reportType: new UntypedFormControl('', [Validators.required]),
        password : new UntypedFormControl('', [Validators.minLength(6), Validators.required, Validators.pattern('^(?=.*[0-9])(?=.*[a-zA-Z])([a-zA-Z0-9]+)$')])
      });
  }

  ngOnInit() {
    this.instance = _.upperCase(this.resourceService.instance || 'SUNBIRD');
  }

  loadReports(batchDetails?: any) {
    if (batchDetails) {
      this.batch = batchDetails;
      this.tag = batchDetails.courseId + '_' + batchDetails.batchId;
    }
    if (this.batch) {
      this.onDemandReportService.getReportList(this.tag).subscribe((data) => {
        if (data) {
          const reportData = _.get(data, 'result.jobs');
          this.onDemandReportData = _.map(reportData, (row) => this.dataModification(row));
          this.onDemandReportData = [...this.onDemandReportData];
        }
      }, error => {
        this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
      });
    }
  }

  reportChanged(ev) {
    this.selectedReport = _.get(ev, 'value');
  }

  generateTelemetry(fieldType, batchId, courseId) {
    const interactData = {
      context: {
        env: 'reports',
        cdata: [{id: courseId, type: 'Course'}, {id: batchId, type: 'Batch'}]
      },
      edata: {
        id: fieldType,
        type: 'click',
        pageid: 'on-demand-reports'
      }
    };
    this.telemetryService.interact(interactData);
  }

  onDownloadLinkFail(data) {
    const tagId = data && data.tag && data.tag.split(':');
    this.onDemandReportService.getReport(_.head(tagId), data.requestId).subscribe((data: any) => {
      if (data) {
        const downloadUrls = _.get(data, 'result.downloadUrls') || [];
        const downloadPath = _.head(downloadUrls);
        if (downloadPath) {
          window.open(downloadPath, '_blank');
        } else {
          this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
        }
      }
    }, error => {
      this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
    });
  }

  submitRequest() {
    const isRequestAllowed = this.checkStatus();
    if (isRequestAllowed) {
      this.isProcessed = false;
      const request = {
        request: {
          tag: this.tag,
          requestedBy: this.userId,
          dataset: this.selectedReport.dataset,
          datasetConfig: {
            batchId: this.batch.batchId
          },
          output_format: 'csv'
        }
      };
      if (this.selectedReport.encrypt === 'true') {
        request.request['encryptionKey'] = this.reportForm.controls.password.value;
      }
      console.log('submit the report');
      this.generateTelemetry(this.selectedReport.dataset, this.batch.batchId, this.batch.courseId);
      this.onDemandReportService.submitRequest(request).subscribe((data: any) => {
        if (data && data.result) {
          if (data.result.status === this.reportStatus.failed) {
            const error = _.get(data, 'result.statusMessage') || _.get(this.resourceService, 'frmelmnts.lbl.requestFailed');
            this.toasterService.error(error);
          }
          data = this.dataModification(data['result']);
          const updatedReportList = [data, ...this.onDemandReportData];
          this.onDemandReportData = _.slice(updatedReportList, 0, 10);
        }
        this.reportForm.reset();
      }, error => {
        this.reportForm.reset();
        this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
      });
    } else {
      this.isProcessed = true;
      setTimeout(() => {
        this.isProcessed = false;
      }, 5000);
      this.toasterService.error(_.get(this.resourceService, 'frmelmnts.lbl.requestFailed'));
    }
  }

  checkStatus() {
    let requestStatus = true;
    const selectedReportList = [];
    _.forEach(this.onDemandReportData, (value) => {
      if (value.dataset === this.selectedReport.dataset) {
        selectedReportList.push(value);
      }
    });
    const sortedReportList = _.sortBy(selectedReportList, [(data) => {
      return data && data.jobStats && data.jobStats.dtJobSubmitted;
    }]);
    const reportListData = _.last(sortedReportList) || {};
    let batchEndDate;
    if (this.batch.endDate) {
      batchEndDate = new Date(`${this.batch.endDate} 23:59:59`).getTime();
    }
    if (!_.isEmpty(reportListData)) { // checking the report is already created or not
      const isInProgress = this.onDemandReportService.isInProgress(reportListData, this.reportStatus); // checking the report is in SUBMITTED/PROCESSING state
      if (!isInProgress) {
        requestStatus = true;
        // TODO: The below code has commented because of API lag to generate the reports
        // requestStatus = this.onDemandReportService.canRequestReport(_.get(reportListData, 'jobStats.dtJobSubmitted'), batchEndDate); // performing the date checks if the report is not in SUBMITTED/PROCESSING state
      } else {
        requestStatus = false; // report is in SUBMITTED/PROCESSING state and can not create new report
      }
    }
    return requestStatus;
  }


  dataModification(row) {
    const dataSet = _.find(this.reportTypes, {dataset: row.dataset}) || {};
    row.title = dataSet.title;
    return row;
  }
}
<div class='ui stackable grid mt-0'>
  <div class="twelve wide column pt-0">
    <div class="d-flex flex-dc">
      <!-- <label class="request-report-label font-weight-normal">{{resourceService?.frmelmnts?.lbl?.requestReport}}</label> -->
      <div [formGroup]="reportForm" class="d-flex flex-ai-center">
        <div class="sb-field w-25">
        <mat-form-field appearance="fill" class="sb-mat__dropdown w-100 mb-16">
          <mat-label>Choose your report</mat-label>
          <mat-select formControlName="reportType" role="listbox" aria-label="Choose your report" class="selection"
            (selectionChange)="reportChanged($event)">
            <mat-option class="mat-dropdown__options" role="option" *ngFor="let option of reportTypes" [value]="option"
            attr.aria-label="{{option.title}}">{{option.title}}</mat-option>
          </mat-select>
        </mat-form-field>
      </div>

        <div class="sb-field filterTable mx-16 mb-0">
          <input class="sb-form-control" type="text" formControlName="password" placeholder="Enter password" aria-label="enter password">
        </div>
        <button type="button" [disabled]="(!selectedReport || (selectedReport?.encrypt === 'true' && !reportForm.valid))"
        [ngClass]="{'sb-btn-disabled': (!selectedReport || (selectedReport?.encrypt === 'true' && !reportForm.valid))}"
        tabindex="0" (click)="submitRequest()" class="sb-btn sb-btn-normal sb-btn-primary">
          {{resourceService?.frmelmnts?.lbl?.request}}
        </button>
      </div>
      <!-- <p *ngIf="!isProcessed" class="fnormal note-text mt-8 mb-24 administrator-text">{{resourceService.frmelmnts?.lbl?.downloadReqNote}}</p> -->
      <div *ngIf="isProcessed" class="d-flex">
        <div class="information-icon">
          <img src="assets/images/error-icon.svg" width="18px"></div>
        <p class="fsmall note-text my-8 administrator-text">{{resourceService.frmelmnts?.lbl?.reportStatus}}</p>
      </div>
      <!-- <p class="administrator-text">{{resourceService.frmelmnts?.lbl?.ondemandReportNote | interpolate:'{instance}': instance}}</p> -->

      <p class="fsmall note-text my-8 administrator-text" *ngIf="!isProcessed"> 
       {{resourceService?.frmelmnts?.lbl?.pswdRule}}
        </p>
     
         
    </div>
  </div>
</div>
<div class="fsmall font-weight-bold download-section-text">{{resourceService.frmelmnts?.lbl?.downloadSectionNote}}</div>
<p class="fsmall mt-8 mb-16 administrator-text">{{resourceService?.frmelmnts?.lbl?.repgenAdminNote | interpolate:'{instance_course_terms}': instance}}</p>

<sb-datatable [name]="fileName" [message]="message" [data]="onDemandReportData" [columns]="columns"
              [downloadCSV]="isDownloadReport" (downloadLink)="onDownloadLinkFail($event)" ></sb-datatable>

./on-demand-reports.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;

.information-icon{
    position: relative;
    top: calculateRem(8px);
  }

  .administrator-text {
    font-style: italic;
  }


  .administrator-text {
    font-style: italic;
    color:var(--gray-200);
  }
  .download-section-text{
    font-size: calculateRem(14px);
    color: var(--gray-800);
  }
  ::ng-deep {
    html[layout=joy] .sb-btn-normal {
      height: 2rem;
      box-shadow: none;
   }
  }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""