File

src/app/modules/dashboard/components/usage-reports/usage-reports.component.ts

Implements

OnInit AfterViewInit

Metadata

Index

Properties
Methods

Constructor

constructor(usageService: UsageService, sanitizer: DomSanitizer, userService: UserService, toasterService: ToasterService, resourceService: ResourceService, activatedRoute: ActivatedRoute, router: Router, navigationhelperService: NavigationHelperService, layoutService: LayoutService, courseProgressService: CourseProgressService, tncService: TncService)
Parameters :
Name Type Optional
usageService UsageService No
sanitizer DomSanitizer No
userService UserService No
toasterService ToasterService No
resourceService ResourceService No
activatedRoute ActivatedRoute No
router Router No
navigationhelperService NavigationHelperService No
layoutService LayoutService No
courseProgressService CourseProgressService No
tncService TncService No

Methods

createChartData
createChartData(charts, data, downloadUrl)
Parameters :
Name Optional
charts No
data No
downloadUrl No
Returns : void
downloadCSV
downloadCSV(filepath)
Parameters :
Name Optional
filepath No
Returns : void
getReportViewerTncPolicy
getReportViewerTncPolicy()
Returns : void
goBack
goBack()
Returns : void
initLayout
initLayout()
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnInit
ngOnInit()
Returns : void
renderFiles
renderFiles(files, data)
Parameters :
Name Optional
files No
data No
Returns : void
renderReport
renderReport(report: any)
Parameters :
Name Type Optional
report any No
Returns : void
renderTable
renderTable(tables, data)
Parameters :
Name Optional
tables No
data No
Returns : void
selectedTabChange
selectedTabChange(event)
Parameters :
Name Optional
event No
Returns : void
setDownloadUrl
setDownloadUrl(url)
Parameters :
Name Optional
url No
Returns : void
setTelemetryInteractEdata
setTelemetryInteractEdata(val)
Parameters :
Name Optional
val No
setTelemetryInteractObject
setTelemetryInteractObject(val)
Parameters :
Name Optional
val No
showReportViewerTncForFirstUser
showReportViewerTncForFirstUser()
Returns : void
transformHTML
transformHTML(data: any)
Parameters :
Name Type Optional
data any No
Returns : any

Properties

Private activatedRoute
Type : ActivatedRoute
chartData
Type : Array<object>
Default value : []
Public courseProgressService
Type : CourseProgressService
currentReport
Type : any
downloadUrl
files
Type : any
isFileDataLoaded
Default value : false
isTableDataLoaded
Default value : false
layoutConfiguration
Type : any
Public layoutService
Type : LayoutService
Public navigationhelperService
Type : NavigationHelperService
noResult
Type : boolean
noResultMessage
Type : INoResultMessage
reportMetaData
Type : any
reportViewerTncUrl
Type : string
reportViewerTncVersion
Type : string
Public resourceService
Type : ResourceService
showLoader
Default value : false
showTncPopup
Default value : false
slug
Type : string
tables
Type : any
telemetryImpression
Type : IImpressionEventInput
telemetryInteractDirective
Decorators :
@ViewChild(TelemetryInteractDirective)
telemetryInteractDownloadEdata
Type : IInteractEventEdata
telemetryInteractEdata
Type : IInteractEventEdata
Public tncService
Type : TncService
Private unsubscribe$
Default value : new Subject<void>()
userProfile
Public userService
Type : UserService
import { IInteractEventEdata, TelemetryInteractDirective, IImpressionEventInput } from '@sunbird/telemetry';
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { CourseProgressService, UsageService } from './../../services';
import * as _ from 'lodash-es';
import dayjs from 'dayjs';
import { DomSanitizer } from '@angular/platform-browser';
import { UserService, TncService } from '@sunbird/core';
import {
  ToasterService,
  ResourceService,
  INoResultMessage,
  NavigationHelperService,
  LayoutService
} from '@sunbird/shared';
import { ActivatedRoute, Router } from '@angular/router';
import {Subject} from 'rxjs';
import {first, takeUntil} from 'rxjs/operators';

@Component({
  selector: 'app-usage-reports',
  templateUrl: './usage-reports.component.html',
  styleUrls: ['./usage-reports.component.scss']
})
export class UsageReportsComponent implements OnInit, AfterViewInit {
  reportMetaData: any;
  chartData: Array<object> = [];
  tables: any;
  files: any;
  isTableDataLoaded = false;
  isFileDataLoaded = false;
  currentReport: any;
  slug: string;
  noResult: boolean;
  showLoader = false;
  noResultMessage: INoResultMessage;
  private activatedRoute: ActivatedRoute;
  telemetryImpression: IImpressionEventInput;
  telemetryInteractEdata: IInteractEventEdata;
  telemetryInteractDownloadEdata: IInteractEventEdata;
  downloadUrl;
  public courseProgressService: CourseProgressService;
  layoutConfiguration: any;
  private unsubscribe$ = new Subject<void>();
  reportViewerTncVersion: string;
  reportViewerTncUrl: string;
  showTncPopup = false;
  userProfile;
  @ViewChild(TelemetryInteractDirective) telemetryInteractDirective;
  constructor(private usageService: UsageService, private sanitizer: DomSanitizer,
    public userService: UserService, private toasterService: ToasterService,
    public resourceService: ResourceService, activatedRoute: ActivatedRoute, private router: Router,
    public navigationhelperService: NavigationHelperService, public layoutService: LayoutService,
    courseProgressService: CourseProgressService, public tncService: TncService
  ) {
    this.activatedRoute = activatedRoute;
    this.courseProgressService = courseProgressService;
  }

  ngOnInit() {
    this.initLayout();
    const reportsLocation = (<HTMLInputElement>document.getElementById('reportsLocation')) ? (<HTMLInputElement>document.getElementById('reportsLocation')).value : '';
    this.slug = _.get(this.userService, 'userProfile.rootOrg.slug');
    this.userService.userData$.pipe(first()).subscribe(async (user) => {
      if (user && user.userProfile) {
        this.userProfile = user.userProfile;
        this.getReportViewerTncPolicy();
      }
    });
    this.usageService.getData(`/${reportsLocation}/${this.slug}/config.json`)
      .subscribe(data => {
        if (_.get(data, 'responseCode') === 'OK') {
          this.noResult = false;
          this.reportMetaData = _.get(data, 'result');
          if (this.reportMetaData[0]) { this.renderReport(this.reportMetaData[0]); }
        }
      }, (err) => {
        console.log(err);
        this.noResultMessage = {
          'messageText': 'messages.stmsg.m0131'
        };
        this.noResult = true;
      });
  }

  setTelemetryInteractObject(val) {
    return {
      id: val,
      type: 'Report',
      ver: '1.0'
    };
  }

  initLayout() {
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.layoutService.switchableLayout().pipe(takeUntil(this.unsubscribe$)).subscribe(layoutConfig => {
      if (layoutConfig != null) {
        this.layoutConfiguration = layoutConfig.layout;
      }
    });
  }

  setTelemetryInteractEdata(val) {
    return {
      id: val,
      type: 'click',
      pageid: this.activatedRoute.snapshot.data.telemetry.pageid
    };
  }
  renderReport(report: any) {
    this.chartData = [];
    this.tables = [];
    this.files = [];
    this.currentReport = report;
    this.isTableDataLoaded = false;
    const url = report.dataSource;
    this.showLoader = true;
    this.downloadUrl = report.downloadUrl;
    this.usageService.getData(url)
      .subscribe((response) => {
        if (_.get(response, 'responseCode') === 'OK') {
          const data = _.get(response, 'result');
          this.showLoader = false;
          if (_.get(report, 'charts')) {
            this.createChartData(_.get(report, 'charts'), data, url);
          }
          if (_.get(report, 'table')) {
            this.renderTable(_.get(report, 'table'), data);
          } else {
            this.renderTable({}, data);
          }
          if (_.get(report, 'files')) {
            this.renderFiles(_.get(report, 'files'), data);
          } else {
            this.renderFiles({}, data);
          }
        } else {
        }

      }, err => { console.log(err); });
  }

  renderFiles(files, data) {
    this.files = [];
    _.forEach(files, file => {
      const fileData: any = {};
      fileData.id = _.get(file, 'id');
      fileData.name = _.get(file, 'name');
      fileData.desc = _.get(file, 'description');
      fileData.size = _.get(file, 'fileSize');
      fileData.createdOn = _.get(file, 'createdOn');
      fileData.downloadUrl = _.get(file, 'downloadUrl');
      this.files.push(fileData);
    });
    if (this.files.length) {
      this.isFileDataLoaded = true;
    } else {
      this.isFileDataLoaded = false;
    }
    _.forEach(this.files, file => {
      const path = (file.downloadUrl).replace('/reports/', '');
      const requestParams = {
        params: {
          fileNames: JSON.stringify({ path })
        },
        telemetryData: this.activatedRoute
      };
      this.courseProgressService.getReportsMetaData(requestParams).subscribe((response) => {
        if (_.get(response, 'responseCode') === 'OK') {
          file.size = (_.get(response, 'result.path.fileSize')) / 1024;
          if (_.get(response, 'result.path.lastModified')) {
            file.createdOn = dayjs(new Date(_.get(response, 'result.path.lastModified'))).format('DD MMM YYYY');
          } else {
            file.createdOn = '';
          }
        }
      });
    });
  }

  createChartData(charts, data, downloadUrl) {
    this.chartData = [];
    _.forEach(charts, chart => {
      const chartObj: any = {};
      chartObj.chartConfig = chart;
      chartObj.downloadUrl = downloadUrl;
      chartObj.chartData = _.get(data, 'data');
      chartObj.lastUpdatedOn = _.get(data, 'metadata.lastUpdatedOn');
      this.chartData.push(chartObj);
    });
  }

  renderTable(tables, data) {
    this.tables = [];
    tables = _.isArray(tables) ? tables : [tables];
    _.forEach(tables, table => {
      const tableData: any = {};
      tableData.id = _.get(table, 'id') || `table-${_.random(1000)}`;
      tableData.name = _.get(table, 'name') || 'Table';
      tableData.header = _.get(table, 'columns') || _.get(data, _.get(table, 'columnsExpr'));
      tableData.data = _.get(table, 'values') || _.get(data, _.get(table, 'valuesExpr'));
      tableData.downloadUrl = _.get(table, 'downloadUrl') || this.downloadUrl;
      this.tables.push(tableData);
    });
    this.isTableDataLoaded = true;
  }

  ngAfterViewInit() {
    setTimeout(() => {
      this.telemetryImpression = {
        context: {
          env: this.activatedRoute.snapshot.data.telemetry.env
        },
        object: {
          id: this.userService.userid,
          type: 'user',
          ver: '1.0'
        },
        edata: {
          type: this.activatedRoute.snapshot.data.telemetry.type,
          pageid: this.activatedRoute.snapshot.data.telemetry.pageid,
          uri: this.router.url,
          duration: this.navigationhelperService.getPageLoadTime()
        }
      };
    });
  }

  setDownloadUrl(url) {
    this.downloadUrl = url;
  }

  downloadCSV(filepath) {
    if (!filepath) {
      filepath = this.downloadUrl;
    }
    this.usageService.getData(filepath).subscribe((response) => {
      if (_.get(response, 'responseCode') === 'OK') {
        const url = _.get(response, 'result.signedUrl');
        if (url) { window.open(url, '_blank'); }
      } else {
        this.toasterService.error(this.resourceService.messages.emsg.m0076);
      }
    }, (err) => {
      this.toasterService.error(this.resourceService.messages.emsg.m0076);
    });
  }

  transformHTML(data: any) {
    return this.sanitizer.bypassSecurityTrustHtml(data);
  }

  selectedTabChange(event) {
    const { downloadURL } = _.get(event, 'tab.textLabel');
    downloadURL && this.setDownloadUrl(downloadURL);
  }

  getReportViewerTncPolicy() {
    this.tncService.getReportViewerTnc().subscribe((data) => {
      const reportViewerTncData = JSON.parse(_.get(data, 'result.response.value'));
      if (_.get(reportViewerTncData, 'latestVersion')) {
        this.reportViewerTncVersion = _.get(reportViewerTncData, 'latestVersion');
        this.reportViewerTncUrl = _.get(_.get(reportViewerTncData, _.get(reportViewerTncData, 'latestVersion')), 'url');
        this.showReportViewerTncForFirstUser();
      }
  });
}

goBack() {
  this.navigationhelperService.goBack();
}

  showReportViewerTncForFirstUser() {
     const reportViewerTncObj = _.get(this.userProfile, 'allTncAccepted.reportViewerTnc');
     if (!reportViewerTncObj) {
     this.showTncPopup = true;
     }
  }
}
<app-landing-section [noTitle]="true" [layoutConfiguration]="layoutConfiguration">
</app-landing-section>
<div
  [ngClass]="layoutConfiguration ? 'sb-back-actionbar' : 'sb-bg-color-white back-btn-container cc-player__btn-back relative9'"
  class="relative position mt-0">
  <div class="ui container py-0 px-0 d-flex flex-ai-center">
    <div class="py-0 d-flex flex-ai-center w-100">
      <!-- /* Back button */ -->
      <button type="button" [ngClass]="layoutConfiguration ? 'sb-btn-primary sb-btn-round' : 'sb-btn-link sb-btn-link-primary sb-left-icon-btn px-0'" class="sb-btn sb-btn-normal" tabindex="0" (click)="goBack()" attr.aria-label="{{resourceService?.frmelmnts?.btn?.back}}">
        <em class="icon-svg icon-svg--xxs icon-back mr-4"><svg class="icon icon-svg--primary">
            <use xlink:href="assets/images/sprite.svg#arrow-long-left"></use>
          </svg></em>
        <span>{{resourceService?.frmelmnts?.btn?.back}}</span>
      </button>
     <div class="textbook d-flex flex-ai-center flex-jc-space-between w-100 ml-16">
        <!-- title -->
        <h5 class="textbook__title sb-color-primary font-weight-bold mb-0" tabindex="0">{{resourceService.frmelmnts?.lnk?.dashboard}}</h5>
    </div>
    </div>
  </div>
</div>

<div [ngClass]="layoutConfiguration ? 'sbt-inside-page-container' : 'pt-16'">
  <div class="ui" [appTelemetryImpression]="telemetryImpression">
    <div class="twelve wide column px-0 sb-workspace-bg">
      <div class="ui container stackable grid m-0 sb-mid-container-min-height dashboard-body-scroll" *ngIf="!noResult">
        <div class="two wide column sb-sidebar-menu p-0">
          <h5 class="p-16">{{resourceService.frmelmnts?.lnk?.dashboard}}</h5>
          <ul class="m-0">
            <li appTelemetryInteract [telemetryInteractObject]="setTelemetryInteractObject(report.id)"
              [telemetryInteractEdata]="setTelemetryInteractEdata('report-view')" *ngFor="let report of reportMetaData"
              (click)="renderReport(report)" tabindex="0" class="item m-0"
              [ngClass]="{'active': currentReport.id === report.id}">
              {{report.label || report.title}}</li>
          </ul>
        </div>
        <div class="ten wide column sb-sideview-tab-container pl-40 pt-72 pb-48" *ngIf="currentReport">
          <h3 class="mb-16">
            {{currentReport?.title || currentReport?.label}}
          </h3>
          <p *ngIf="currentReport?.description" [innerHTML]="transformHTML(currentReport.description)"></p>
          <ng-container *ngIf="!showLoader">
            <mat-tab-group (selectedTabChange)="selectedTabChange($event)" class="mat-tab__usage-report">
              <mat-tab appTelemetryInteract [telemetryInteractObject]="setTelemetryInteractObject(currentReport.id)"
                [telemetryInteractEdata]="setTelemetryInteractEdata('report-graph')"
                [label]="{'type': 'chart', 'downloadURL': currentReport.downloadUrl}">
                <div class="p-0 b-0 no-bg py-24">
                  <ng-template mat-tab-label>
                    <span>{{resourceService?.frmelmnts?.lbl?.graphs}}</span>
                  </ng-template>
                  <ng-container *ngTemplateOutlet="commonReportActions">
                  </ng-container>
                  <div class="sb-graph-section p-24 my-24"
                    *ngFor="let chart of chartData; let i = index; let l = last;">
                    <app-data-chart [telemetryInteractObject]="setTelemetryInteractObject(currentReport.id)"
                      [chartInfo]="chart"></app-data-chart>
                    <!-- <hr *ngIf="!l" /> -->
                  </div>
                  <div class="ui warning message" *ngIf="!chartData.length">
                    {{resourceService?.frmelmnts?.lbl?.graphNotAvailable}}
                  </div>
                </div>
              </mat-tab>
              <ng-container *ngFor="let table of tables">
                <mat-tab [label]="{'type': 'table', 'downloadURL': table?.downloadUrl}">
                  <ng-template mat-tab-label>
                    <span>{{table?.name}}</span>
                  </ng-template>
                  <ng-template matTabContent>
                    <div class="p-0 b-0 no-bg py-24">
                      <ng-container *ngTemplateOutlet="commonReportActions">
                      </ng-container>
                      <div class="p-0 b-0 no-bg py-24">
                        <div *ngIf="table.data">
                          <app-data-table [tableId]="table.id" [headerData]="table.header" [rowsData]="table.data">
                          </app-data-table>
                        </div>
                        <div class="ui warning message" *ngIf="!table.data">
                          {{resourceService?.frmelmnts?.lbl?.tableNotAvailable}}
                        </div>
                      </div>
                    </div>
                  </ng-template>
                </mat-tab>
              </ng-container>
              <mat-tab label="{{resourceService?.frmelmnts?.lbl?.dashboard?.download}}" *ngIf="isFileDataLoaded">
                <div class="p-0 b-0 no-bg py-24">
                  <ng-container *ngTemplateOutlet="commonReportActions">
                  </ng-container>
                  <div class="sb-graph-section p-24 my-24">
                    <table *ngIf="isFileDataLoaded" id="downloadTable"
                      class="sb-table sb-table-striped sb-table-sortable sb-table-fixed sb-table-course-dashboard"
                      cellspacing="0">
                      <thead>
                        <tr>
                          <th>
                            <div class="cursor-pointer">
                              {{resourceService?.frmelmnts?.lbl?.dashboard?.fileName}}
                            </div>
                          </th>
                          <th>
                            <div class="cursor-pointer">
                              {{resourceService?.frmelmnts?.lbl?.dashboard?.description}}
                            </div>
                          </th>
                          <th>
                            <div class="cursor-pointer">
                              {{resourceService?.frmelmnts?.lbl?.dashboard?.fileSize}}
                            </div>
                          </th>
                          <th>
                            <div class="cursor-pointer">
                              {{resourceService?.frmelmnts?.lbl?.createdon}}
                            </div>
                          </th>
                          <th class="table-headerDashboard">
                            <div class="cursor-pointer">
                              {{resourceService?.frmelmnts?.lbl?.dashboard?.action}}
                            </div>
                          </th>
                        </tr>
                      </thead>
                      <tbody class="sb-table-body">
                        <tr *ngFor="let file of files; let i = index; let l = last;">
                          <td *ngIf="file.name">
                            {{file.name}}
                          </td>
                          <td *ngIf="!file.name">
                            --
                          </td>
                          <td *ngIf="file.desc">
                            {{file.desc}}
                          </td>
                          <td *ngIf="!file.desc">
                            --
                          </td>
                          <td *ngIf="file.size">
                            {{file.size}}
                          </td>
                          <td *ngIf="!file.size">
                            --
                          </td>
                          <td *ngIf="file.createdOn">
                            {{file.createdOn}}
                          </td>
                          <td *ngIf="!file.createdOn">
                            --
                          </td>
                          <td>
                            <button type="button" class="sb-btn sb-btn-primary sb-btn-normal ml-auto mr-8"
                              appTelemetryInteract
                              [telemetryInteractObject]="setTelemetryInteractObject(currentReport.id)"
                              [telemetryInteractEdata]="setTelemetryInteractEdata('report-download')"
                              (click)="downloadCSV(file.downloadUrl)" tabindex="0"><i class="icon"></i>
                              {{resourceService?.frmelmnts?.lbl?.dashboard?.downloadfile}}</button>
                          </td>
                      </tbody>
                    </table>
                    <div class="ui warning message" *ngIf="!files.length">
                      File Not Available
                    </div>
                  </div>
                </div>
              </mat-tab>
            </mat-tab-group>
          </ng-container>
          <div class="nine wide column workspacesegment" *ngIf="showLoader">
            <app-loader></app-loader>
          </div>
        </div>
      </div>
      <div *ngIf="noResult">
        <app-no-result [data]="noResultMessage"></app-no-result>
      </div>
    </div>
    <div *ngIf="!noResult">
      <app-tnc-popup [showAcceptTnc]="showTncPopup" [reportViewerTncVersion]="reportViewerTncVersion" [tncUrl]="reportViewerTncUrl" #termsAndCondPopUp *ngIf="showTncPopup">
      </app-tnc-popup>
    </div>
  </div>
</div>

<ng-template #commonReportActions>
  <div class="my-0">
    <div class="d-flex flex-ai-center flex-jc-flex-end">
      <button appTelemetryInteract [telemetryInteractObject]="setTelemetryInteractObject(currentReport.id)"
        [telemetryInteractEdata]="setTelemetryInteractEdata('report-download')" type="button"
        *ngIf="!isFileDataLoaded && currentReport?.downloadUrl"
        class="sb-left-icon-btn sb-btn sb-btn-tertiary sb-btn-normal mr-8" (click)="downloadCSV()" tabindex="0"><i
          class="icon"></i>
        {{resourceService?.frmelmnts?.lbl?.downloadCsv}}</button>
    </div>
  </div>
</ng-template>

./usage-reports.component.scss

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

.sb-graph-section{
    border: calculateRem(1px) solid var(--rc-dddddd);
    padding: calculateRem(24px);
    margin-top: calculateRem(24px);
    background: var(--sb-graph-section-bg);
    box-shadow: 0 calculateRem(2px) calculateRem(7px) 0 rgba(var(--rc-rgba-black), 0.16);
    border-radius: calculateRem(4px);
    .sb-table-fixed .sb-table tbody td, .sb-table-fixed .sb-table-body td {
        text-overflow: initial;
        overflow: initial;
        white-space: unset;
    }
}
.sb-btn-normal i::after {
    content: "\f019";
    font-size: calculateRem(13px);
}
.no-bg {
    background:none;
}

.dashboard-body-scroll{
    display: flex;
    align-items: flex-start;
}

.sb-sidebar-menu{
    position: sticky !important;
    position: -webkit-sticky !important;
    top: 0;
}
.table-headerDashboard{
    width:calculateRem(200px);
    color: var(--primary-color);
  font-weight: bold;
}
.sb-workspace-bg{
    position: relative;
    height: auto;
  }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""