File

src/app/modules/dial-code-search/components/dial-code/dial-code.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods
HostListeners

Constructor

constructor(resourceService: ResourceService, userService: UserService, coursesService: CoursesService, router: Router, activatedRoute: ActivatedRoute, searchService: SearchService, toasterService: ToasterService, configService: ConfigService, utilService: UtilService, navigationHelperService: NavigationHelperService, playerService: PlayerService, telemetryService: TelemetryService, publicPlayerService: PublicPlayerService, dialCodeService: DialCodeService, layoutService: LayoutService)
Parameters :
Name Type Optional
resourceService ResourceService No
userService UserService No
coursesService CoursesService No
router Router No
activatedRoute ActivatedRoute No
searchService SearchService No
toasterService ToasterService No
configService ConfigService No
utilService UtilService No
navigationHelperService NavigationHelperService No
playerService PlayerService No
telemetryService TelemetryService No
publicPlayerService PublicPlayerService No
dialCodeService DialCodeService No
layoutService LayoutService No

HostListeners

window:popstate
Arguments : '$event'
window:popstate(event)

Methods

appendItems
appendItems(startIndex, endIndex)
Parameters :
Name Optional
startIndex No
endIndex No
Returns : void
closeMobileAppPopup
closeMobileAppPopup()
Returns : void
Public getEvent
getEvent(event)
Parameters :
Name Optional
event No
Returns : void
goBack
goBack()
Returns : any
Public handleCloseButton
handleCloseButton()
Returns : any
handleMobilePopupBanner
handleMobilePopupBanner()
Returns : void
initLayout
initLayout()
Returns : void
inview
inview(event)
Parameters :
Name Optional
event No
Returns : void
logInteractEvent
logInteractEvent(undefined)
Parameters :
Name Optional
No
Returns : void
logTelemetryEvents
logTelemetryEvents(status: boolean)
Parameters :
Name Type Optional
status boolean No
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onPopState
onPopState(event)
Decorators :
@HostListener('window:popstate', ['$event'])
Parameters :
Name Optional
event No
Returns : void
onScrollDown
onScrollDown()
Returns : void
Public playCourse
playCourse(undefined)
Parameters :
Name Optional
No
Returns : void
Private processDialCode
processDialCode(params)
Parameters :
Name Optional
params No
Returns : any
Private processTextBook
processTextBook(params)
Parameters :
Name Optional
params No
Returns : any
Public redirectToDetailsPage
redirectToDetailsPage(contentId)
Parameters :
Name Optional
contentId No
Returns : void
redirectToDikshaApp
redirectToDikshaApp()
Returns : void
setTelemetryData
setTelemetryData()
Returns : void
updateCardData
updateCardData(downloadListdata)
Parameters :
Name Optional
downloadListdata No
Returns : void

Properties

Public activatedRoute
Type : ActivatedRoute
Public appMobileDownloadInteractData
Type : any
Public backInteractEdata
Type : IInteractEventEdata
chapterName
Type : string
Public closeMobilePopupInteractData
Type : any
Public configService
Type : ConfigService
contentName
Type : string
courseList
Type : []
Default value : []
Public coursesService
Type : CoursesService
Public dialCode
dialContentId
Type : string
Public dialResultImpression
Type : IImpressionEventInput
Public dialSearchSource
Type : string
Private initialize
Default value : () => {...}
instance
Type : string
Public inviewLogs
Type : any
Default value : []
isBrowse
Default value : false
Public isRedirectToDikshaApp
Default value : false
isTextbookDetailsPage
Default value : false
Public itemsToDisplay
Type : any
Default value : []

Initializing the infinite scroller

Public itemsToLoad
Type : number
Default value : 50
layoutConfiguration
Type : any
Public layoutService
Type : LayoutService
Public loaderMessage
Type : any
Public navigationHelperService
Type : NavigationHelperService
Public numberOfSections
Default value : new Array(this.configService.appConfig.DIAL_CODE.PAGE_LIMIT)
Public numOfItemsToAddOnScroll
Type : number
Default value : 20
Public playerService
Type : PlayerService
Public publicPlayerService
Type : PublicPlayerService
redirectCollectionUrl
Type : string
redirectContentUrl
Type : string
redirectQuestionsetUrl
Type : string
Public resourceService
Type : ResourceService
Public router
Type : Router
Public scrollDistance
Type : number
Default value : 2
Public searchResults
Type : Array<any>
Default value : []
Public searchService
Type : SearchService
Public selectChapterInteractEdata
Type : IInteractEventEdata
Public selectChapterTelemetryCdata
Type : Array<literal type>
Default value : []
Public selectedCourseBatches
Type : any
Public showBatchInfo
Default value : false
showDownloadLoader
Default value : false
showExportLoader
Default value : false
Public showLoader
Default value : true
Public showMobilePopup
Default value : false
showSelectChapter
Default value : false
Public singleContentRedirect
Type : string
Default value : ''
Public telemetryCdata
Type : Array<literal type>
Default value : []
Public telemetryImpression
Type : IImpressionEventInput

telemetryImpression

Public telemetryService
Type : TelemetryService
textbookList
Type : []
Default value : []
Public throttle
Type : number
Default value : 50
Public toasterService
Type : ToasterService
Public unsubscribe$
Default value : new Subject<void>()
Public userService
Type : UserService
Public utilService
Type : UtilService
import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';
import { combineLatest as observableCombineLatest, of } from 'rxjs';
import { ResourceService, ToasterService, ConfigService, UtilService, NavigationHelperService, LayoutService} from '@sunbird/shared';
import { Router, ActivatedRoute } from '@angular/router';
import { SearchService, PlayerService, CoursesService, UserService } from '@sunbird/core';
import { PublicPlayerService } from '@sunbird/public';
import * as _ from 'lodash-es';
import { IInteractEventEdata, IImpressionEventInput, TelemetryService } from '@sunbird/telemetry';
import {mergeMap, tap, retry, catchError, map, finalize, debounceTime, takeUntil} from 'rxjs/operators';
import { Subject } from 'rxjs';
import { DialCodeService } from '../../services/dial-code/dial-code.service';

@Component({
  selector: 'app-dial-code',
  templateUrl: './dial-code.component.html',
  styleUrls: ['./dial-code.component.scss']
})
export class DialCodeComponent implements OnInit, OnDestroy {
  public inviewLogs: any = [];
  /**
	 * telemetryImpression
	*/
  public telemetryImpression: IImpressionEventInput;
  public dialResultImpression: IImpressionEventInput;
  /**
   * Initializing the infinite scroller
   */
  public itemsToDisplay: any = [];
  public itemsToLoad = 50;
  public throttle = 50;
  public numOfItemsToAddOnScroll = 20;
  public scrollDistance = 2;
  public dialCode;
  public showLoader = true;
  public loaderMessage: any;
  public searchResults: Array<any> = [];
  public unsubscribe$ = new Subject<void>();
  public telemetryCdata: Array<{}> = [];
  public backInteractEdata: IInteractEventEdata;
  public selectChapterTelemetryCdata: Array<{}> = [];
  public selectChapterInteractEdata: IInteractEventEdata;
  public showMobilePopup = false;
  public isRedirectToDikshaApp = false;
  public closeMobilePopupInteractData: any;
  public appMobileDownloadInteractData: any;
  public dialSearchSource: string;
  public showBatchInfo = false;
  public selectedCourseBatches: any;
  public singleContentRedirect = '';
  public numberOfSections = new Array(this.configService.appConfig.DIAL_CODE.PAGE_LIMIT);
  showExportLoader = false;
  contentName: string;
  instance: string;
  redirectCollectionUrl: string;
  redirectContentUrl: string;
  redirectQuestionsetUrl: string;
  showDownloadLoader = false;
  isBrowse = false;
  showSelectChapter = false;
  chapterName: string;
  dialContentId: string;
  textbookList = [];
  courseList = [];
  isTextbookDetailsPage = false;
  layoutConfiguration: any;

  constructor(public resourceService: ResourceService, public userService: UserService,
    public coursesService: CoursesService, public router: Router, public activatedRoute: ActivatedRoute,
    public searchService: SearchService, public toasterService: ToasterService, public configService: ConfigService,
    public utilService: UtilService, public navigationHelperService: NavigationHelperService,
    public playerService: PlayerService, public telemetryService: TelemetryService,
    public publicPlayerService: PublicPlayerService, private dialCodeService: DialCodeService,
    public layoutService: LayoutService) {
  }

  ngOnInit() {
    this.initLayout();
    observableCombineLatest(this.activatedRoute.params, this.activatedRoute.queryParams,
      (params, queryParams) => {
        return { ...params, ...queryParams };
      }).pipe(
        debounceTime(10),
        tap(this.initialize),
        mergeMap(params => _.get(params, 'textbook') ? this.processTextBook(params) : this.processDialCode(params)),
      ).subscribe(res => {
        const linkedContents = _.flatMap(_.values(res));
        const { constantData, metaData, dynamicFields } = this.configService.appConfig.GetPage;
        this.searchResults = this.utilService.getDataForCard(linkedContents, constantData, dynamicFields, metaData);
        if (_.get(this.searchResults[0], 'contentType') === 'TextBook') {
          sessionStorage.setItem('l1parent', this.searchResults[0].identifier);
        }
        this.appendItems(0, this.itemsToLoad);
        if (this.searchResults.length === 1) {
          if (_.get(this.searchResults[0], 'metaData.mimeType') === 'application/vnd.ekstep.content-collection' ||
            !sessionStorage.getItem('singleContentRedirect')) {
            this.singleContentRedirect = this.searchResults[0]['name'];
            if (this.searchResults[0].contentType.toLowerCase() !== 'course') {
              this.getEvent({
                data: this.searchResults[0]
              });
            }
          }
        }
        this.showLoader = false;
        const telemetryInteractEdata = {
          id: 'content-explode',
          type: 'view',
          subtype: 'post-populate'
        };
        if (_.get(res, 'collection.length') > 1) {
          telemetryInteractEdata.id = 'content-collection';
        }
        if (this.searchResults.length !== 1) {
          this.logInteractEvent(telemetryInteractEdata);
        }
      }, err => {
        this.showLoader = false;
        this.toasterService.error(this.resourceService.messages.fmsg.m0049);
      }, () => {
        this.showLoader = false;
      });
  }

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

  private initialize = (params) => {
    EkTelemetry.config.batchsize = 2;
    this.isBrowse = Boolean(this.router.url.includes('browse'));
    this.dialSearchSource = _.get(params, 'source') || 'search';
    this.isTextbookDetailsPage = !!_.get(params, 'textbook');
    this.itemsToDisplay = [];
    this.searchResults = [];
    this.dialCode = _.get(params, 'dialCode');
    this.showLoader = true;
    this.instance = _.upperCase(_.get(this.resourceService, 'instance'));
    this.handleMobilePopupBanner();
    this.setTelemetryData();
    this.inview({ inview: [] })
  }

  private processDialCode(params) {
    return of(params).pipe(
      finalize(() => {
        this.logInteractEvent({
          id: 'search-dial-init',
          type: 'view',
          subtype: 'auto',
        });
      }),
      mergeMap(param => this.dialCodeService.searchDialCodeAssemble(_.get(param, 'dialCode'), this.isBrowse)
        .pipe(
          tap(value => {
            this.logInteractEvent({
              id: 'search-dial-success',
              type: 'view',
              subtype: 'auto',
            });
            this.logTelemetryEvents(true);
          }, err => {
            this.logInteractEvent({
              id: 'search-dial-failed',
              type: 'view',
              subtype: 'auto',
            });
            this.logTelemetryEvents(false);
          }),
          retry(1),
          catchError(error => {
            return of({
              content: [],
              collections: []
            });
          }),
          mergeMap(this.dialCodeService.filterDialSearchResults),
          tap((res) => {
            this.showSelectChapter = false;
          })
        ))
    );
  }
  private processTextBook(params) {
    const textBookUnit = _.get(params, 'textbook');
    const content = _.find(_.get(this.dialCodeService, 'dialCodeResult.contents'), contentObj => {
      return (_.get(contentObj, 'identifier') === textBookUnit);
    });
    if (content) {
      if (_.toLower(_.get(content, 'contentType')) === 'textbook') {
        this.chapterName = _.get(content, 'name');
        this.dialContentId = _.get(content, 'identifier');
        this.showSelectChapter = true;
      }
      return this.dialCodeService.getAllPlayableContent([textBookUnit]).pipe(
        map(contents => {
          return { contents };
        })
      );
    } else {
      this.router.navigate(['/get/dial', _.get(this.activatedRoute, 'snapshot.params.dialCode')]);
      return of([]);
    }
  }
  onScrollDown() {
    const startIndex = this.itemsToLoad;
    this.itemsToLoad = this.itemsToLoad + this.numOfItemsToAddOnScroll;
    this.appendItems(startIndex, this.itemsToLoad);
  }

  appendItems(startIndex, endIndex) {
    this.itemsToDisplay.push(...this.searchResults.slice(startIndex, endIndex));
    this.courseList = this.itemsToDisplay.filter(item => item.contentType.toLowerCase() === 'course');
    this.textbookList = this.itemsToDisplay.filter(item => item.contentType.toLowerCase() !== 'course');
  }

  public playCourse({ section, data }) {
    const metaData = data;
    if (this.userService.loggedIn) {
      this.coursesService.getEnrolledCourses().subscribe(() => {
        const { onGoingBatchCount, expiredBatchCount, openBatch, inviteOnlyBatch } =
          this.coursesService.findEnrolledCourses(metaData.identifier);
        if (!expiredBatchCount && !onGoingBatchCount) { // go to course preview page, if no enrolled batch present
          return this.playerService.playContent(metaData);
        }
        if (onGoingBatchCount === 1) { // play course if only one open batch is present
          metaData.batchId = openBatch.ongoing.length ? openBatch.ongoing[0].batchId : inviteOnlyBatch.ongoing[0].batchId;
          return this.playerService.playContent(metaData);
        }
        this.selectedCourseBatches = { onGoingBatchCount, expiredBatchCount, openBatch, inviteOnlyBatch, courseId: metaData.identifier };
        this.showBatchInfo = true;
      }, error => {
        this.publicPlayerService.playContent(metaData);
      });
    } else {
      this.publicPlayerService.playContent(metaData);
    }
  }

  public getEvent(event) {

    this.redirectCollectionUrl = 'play/collection';
    this.redirectContentUrl = 'play/content';
    this.redirectQuestionsetUrl = 'play/questionset';

    if (event.data.metaData.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.collection) {
      if (_.get(event, 'data.metaData.childTextbookUnit') || _.toLower(_.get(event, 'data.contentType') === 'textbook')) {
        this.router.navigate([], {
          relativeTo: this.activatedRoute,
          queryParams: {
            l1Parent: event.data.metaData.l1Parent,
            textbook: _.get(event, 'data.metaData.childTextbookUnit.identifier') || _.get(event, 'data.metaData.identifier')
          }
        });
      } else {
        this.router.navigate([this.redirectCollectionUrl, event.data.metaData.identifier],
          { queryParams: { dialCode: this.dialCode, l1Parent: event.data.metaData.l1Parent } });
      }
    } else if (event.data.metaData.mimeType === this.configService.appConfig.PLAYER_CONFIG.MIME_TYPE.questionset) {
      this.router.navigate([this.redirectQuestionsetUrl, event.data.metaData.identifier],
        { queryParams: { dialCode: this.dialCode, l1Parent: sessionStorage.getItem('l1parent') || event.data.metaData.l1Parent },
          state: { 'isSingleContent': this.searchResults.length > 1 ? false : true} });
    } else {
      this.router.navigate([this.redirectContentUrl, event.data.metaData.identifier],
        { queryParams: { dialCode: this.dialCode, l1Parent: sessionStorage.getItem('l1parent') || event.data.metaData.l1Parent },
          state: { 'isSingleContent': this.searchResults.length > 1 ? false : true} });
    }
  }

  inview(event) {
    _.forEach(event.inview, (inview, key) => {
      const obj = _.find(this.inviewLogs, (o) => {
        return o.objid === inview.data.metaData.identifier;
      });
      if (obj === undefined) {
        this.inviewLogs.push({
          objid: inview.data.metaData.identifier,
          objtype: inview.data.metaData.contentType || 'content',
          index: inview.id
        });
      }
    });
    this.telemetryImpression.edata.visits = this.inviewLogs;
    this.telemetryImpression.edata.pageid = this.activatedRoute.snapshot.data.telemetry.pageid;
    this.telemetryImpression.edata.subtype = 'pageexit';
    this.telemetryImpression = Object.assign({}, this.telemetryImpression);
  }
  closeMobileAppPopup() {
    if (localStorage) {
      localStorage.setItem('showMobilePopUp', 'true');
    }
    if (!this.isRedirectToDikshaApp) {
      this.telemetryService.interact(this.closeMobilePopupInteractData);
      (document.querySelector('.mobile-app-popup') as HTMLElement).style.bottom = '-999px';
      (document.querySelector('.mobile-popup-dimmer') as HTMLElement).style.display = 'none';
    }
  }
  redirectToDikshaApp() {
    this.isRedirectToDikshaApp = true;
    this.telemetryService.interact(this.appMobileDownloadInteractData);
    let applink = this.configService.appConfig.UrlLinks.downloadDikshaApp;
    const utm_source = this.userService.slug ? `diksha-${this.userService.slug}` : 'diksha';
    applink = `${applink}&utm_source=${utm_source}&utm_medium=${this.dialSearchSource}&utm_campaign=dial&utm_term=${this.dialCode}`;
    window.location.href = applink.replace(/\s+/g, '');
  }
  setTelemetryData() {
    if (this.dialCode) {
      this.telemetryCdata = [{ 'type': 'DialCode', 'id': this.dialCode }];
    }
    this.closeMobilePopupInteractData = {
      context: {
        cdata: this.telemetryCdata,
        env: this.activatedRoute.snapshot.data.telemetry.env,
      },
      edata: {
        id: 'mobile-popup-close',
        type: 'click',
        pageid: 'get-dial'
      }
    };

    this.backInteractEdata = {
      id: 'dialpage-back',
      type: 'click',
      pageid: 'get-dial',
    };

    this.selectChapterInteractEdata = {
      id: 'select-chapter-button',
      type: 'click',
      pageid: 'get-dial'
    };

    this.selectChapterTelemetryCdata = [
      { 'type': 'DialCode', 'id': this.dialCode },
      { 'id': 'scan:result:collection:list', 'type': 'Feature' },
      { 'id': 'SB-15628', 'type': 'Task' }];

    this.appMobileDownloadInteractData = {
      context: {
        cdata: this.telemetryCdata,
        env: this.activatedRoute.snapshot.data.telemetry.env,
      },
      edata: {
        id: 'app-download-mobile',
        type: 'click',
        pageid: 'get-dial'
      }
    };
    this.telemetryImpression = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: [{
          type: 'DialCode',
          id: this.activatedRoute.snapshot.params.dialCode
        }]
      },
      object: {
        id: this.activatedRoute.snapshot.params.dialCode,
        type: 'DialCode',
        ver: '1.0'
      },
      edata: {
        type: this.activatedRoute.snapshot.data.telemetry.type,
        pageid: `${this.activatedRoute.snapshot.data.telemetry.pageid}`,
        uri: this.userService.slug ? '/' + this.userService.slug + this.router.url : this.router.url,
        subtype: _.get(this.activatedRoute, 'snapshot.data.telemetry.subtype'),
        duration: this.navigationHelperService.getPageLoadTime()
      }
    };
  }
  ngOnDestroy() {
    sessionStorage.removeItem('singleContentRedirect');
    EkTelemetry.config.batchsize = 10;
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
  handleMobilePopupBanner() {
    setTimeout(() => {
      if (localStorage && !localStorage.getItem('showMobilePopUp')) {
        this.showMobilePopup = true;
      }
    }, 500);
  }
  updateCardData(downloadListdata) {
    _.each(this.itemsToDisplay, (contents) => {
      this.publicPlayerService.updateDownloadStatus(downloadListdata, contents);
    });
  }
  logTelemetryEvents(status: boolean) {
    let level = 'ERROR';
    let msg = 'Search Dialcode failed';
    if (status) {
      level = 'SUCCESS';
      msg = 'Search Dialcode was success';
    }
    const event = {
      context: {
        env: 'dialcode',
        cdata: this.telemetryCdata
      },
      edata: {
        type: 'search-dialcode',
        level: level,
        message: msg,
        pageid: this.router.url.split('?')[0]
      }
    };
    this.telemetryService.log(event);
  }
  public handleCloseButton() {
    if (_.get(this.activatedRoute, 'snapshot.queryParams.textbook') && _.get(this.dialCodeService, 'dialCodeResult.count') > 1) {
      return this.router.navigate(['/get/dial', _.get(this.activatedRoute, 'snapshot.params.dialCode')]);
    }
    const previousUrl = _.get(this.navigationHelperService.getPreviousUrl(), 'url') || '/get';
    if (_.includes(previousUrl, 'play')) {
      if (this.userService.loggedIn) {
        this.router.navigate(['/resources']);
      } else {
        this.router.navigate(['/explore']);
      }
    }
  }

  goBack() {
    /*istanbul ignore else */
    if (_.get(this.activatedRoute, 'snapshot.queryParams.textbook') && _.get(this.dialCodeService, 'dialCodeResult.count') > 1) {
      return this.router.navigate(['/get/dial', _.get(this.activatedRoute, 'snapshot.params.dialCode')]);
    }
    if (this.userService.loggedIn) {
      this.router.navigate(['/resources']);
    } else {
      this.router.navigate(['/explore']);
    }
  }
  public redirectToDetailsPage(contentId) {
    if (this.userService.loggedIn) {
      this.router.navigate(['/resources/play/collection', contentId], {
        queryParams: { contentType: 'TextBook', 'dialCode': this.dialCode },
        state: { action: 'dialcode' }
      });
    } else {
      this.router.navigate(['/play/collection', contentId], { queryParams: { contentType: 'TextBook', 'dialCode': this.dialCode } });
    }
  }

  logInteractEvent({ id, type, subtype }) {
    const telemetry = {
      context: { env: _.get(this.activatedRoute, 'snapshot.data.telemetry.env'), cdata: this.telemetryCdata },
      edata: {
        id,
        type,
        pageid: 'get-dial'
      }
    };
    if (subtype) {
      telemetry.edata['subtype'] = subtype;
    }
    this.telemetryService.interact(telemetry);
  }


  @HostListener('window:popstate', ['$event'])
  onPopState(event) {
    if (event && this.router.url.includes('/get/dial')) {
      this.goBack();
    }
  }

}
<app-landing-section [noTitle]="true" [layoutConfiguration]="layoutConfiguration">
</app-landing-section>

<div [ngClass]="layoutConfiguration ? 'sbt-center-container relative9 sbt-dial-code sbt-inside-page-container':''" >
<!-- Back button -->
<div class="sb-bg-color-white sb-back-btn-panel">
  <div class="ui container py-8">
    <button type="button" appTelemetryInteract [telemetryInteractEdata]="backInteractEdata"
      [telemetryInteractCdata]="telemetryCdata" class="sb-btn sb-btn-normal sb-btn-link
      sb-btn-link-primary sb-left-icon-btn px-0" (click)="goBack()" tabindex="0">
      <i class="icon-svg icon-svg--xxs icon-back mr-4" aria-hidden="true">
        <svg class="icon icon-svg--primary">
          <use xlink:href="./assets/images/sprite.svg#arrow-long-left"></use>
        </svg>
      </i> {{resourceService?.frmelmnts?.btn?.back}}
    </button>
  </div>
</div>

<!-- Main container -->
<div class="ui container py-24" [appTelemetryImpression]="telemetryImpression">
  <div class="sb-grid" *ngIf="showLoader">
    <div [id]="i" [data]=[] class="sb-grid--item" *ngFor="let i of numberOfSections">
      <sb-library-card [indexToDisplay]="i" [layoutConfig]="layoutConfiguration" [type]="'portal_qrcode_flatresult'" [isLoading]="true"></sb-library-card>
    </div>
  </div>
  <div class="dial-code-section-result">
    <div class="sb-pageSection" *ngIf="!showLoader && searchResults.length > 0">
      <div class="section-header">
        <p>
          {{resourceService?.frmelmnts?.lbl?.showingResultsForWithCount | interpolate:'{resultCount}' : searchResults.length}}&nbsp;"<strong>{{dialCode}}</strong>"
        </p>
      </div>
    </div>
    <div *ngIf="showSelectChapter && !showLoader && searchResults?.length > 0" class="my-24">
      <button appTelemetryInteract [telemetryInteractEdata]="selectChapterInteractEdata"
        [telemetryInteractCdata]="selectChapterTelemetryCdata" tabindex="0" (click)="redirectToDetailsPage(dialContentId)"
        class="sb-btn sb-btn-normal sb-btn-primary sb-right-icon-btn"
        type="button">{{resourceService.frmelmnts?.lbl?.selectChapter}}
        <i class="icon chevron circle right" aria-hidden="true"></i></button>
      <span class="ml-8 fmedium">{{resourceService.frmelmnts?.lbl?.fromTheTextBook}}&nbsp;
        <strong>"{{chapterName}}"</strong>
      </span>
    </div>
  </div>

  <!-- START - CCD for DIAL Code search result(s) For Textbooks -->
  <div [appTelemetryImpression]="dialResultImpression">
      <div>
      <div *ngIf="!showLoader && textbookList?.length" in-view-container (inview)="inview($event)" [throttle]="[1000]"
        [trigger]="textbookList" class="twelve wide column mb-16">
        <div class="header" *ngIf="!isTextbookDetailsPage">
          <div class="title">
            {{resourceService?.frmelmnts?.lbl?.textbooks}}
            <span class="badge">{{textbookList?.length}}</span>
          </div>
        </div>
        <div class="sb-grid mt-16">
          <div [id]="i" [data]="content" class="sb-grid--item grey-background"
            *ngFor="let content of textbookList;let i = index;">

            <!-- START - Results page -->
            <sb-library-card [indexToDisplay]="i" [layoutConfig]="layoutConfiguration" *ngIf="content.contentType.toLowerCase() !== 'course' && !isTextbookDetailsPage"
              (cardClick)="getEvent($event)" (enterKey)="getEvent($event)" [content]="content" [cardImg]="content?.image || 'assets/images/book.png'"
              appTelemetryInteract appContentDirection [data]="content" [type]="'qrcode_result'"
              [moreInfoLabel]="resourceService?.frmelmnts?.lbl?.section"
              [section]="content?.metaData?.childTextbookUnit?.name || ''"
              [telemetryInteractObject]="{id:content.metaData.identifier,type:content.contentType,ver:content.metaData.pkgVersion ? content.metaData.pkgVersion.toString():'1.0'}"
              [telemetryInteractEdata]="content.telemetryInteractEdata"
              [telemetryInteractCdata]="[{ 'type': 'DialCode', 'id': dialCode}]">
            </sb-library-card>
            <!-- END - Results page -->

            <!-- START - Flattened page -->
            <sb-library-card [indexToDisplay]="i" [layoutConfig]="layoutConfiguration" [type]="'portal_qrcode_flatresult'" [btnlabel]="resourceService.frmelmnts?.lbl?.play"
              *ngIf="content.contentType.toLowerCase() !== 'course' && !content.metaData.childTextbookUnit && isTextbookDetailsPage"
              (cardClick)="getEvent($event)" (enterKey)="getEvent($event)"  [content]="content" [cardImg]="content?.image || 'assets/images/book.png'"
              appTelemetryInteract appContentDirection [data]="content"
              [telemetryInteractObject]="{id:content.metaData.identifier,type:content.contentType,ver:content.metaData.pkgVersion ? content.metaData.pkgVersion.toString():'1.0'}"
              [telemetryInteractEdata]="content.telemetryInteractEdata"
              [telemetryInteractCdata]="[{ 'type': 'DialCode', 'id': dialCode}]">
            </sb-library-card>
            <!-- END - Flattened page -->
          </div>
        </div>
      </div>
    </div>
  </div>
  <!-- END - CCD for DIAL Code search result(s) -->

  <div [appTelemetryImpression]="dialResultImpression">
      <div class="content-grid">
      <div *ngIf="!showLoader && courseList?.length" in-view-container (inview)="inview($event)" [throttle]="[1000]"
        [trigger]="courseList" class="twelve wide column">
        <div class="header" *ngIf="!isTextbookDetailsPage">
          <div class="title">
            {{resourceService?.frmelmnts?.tab?.courses}}
            <span class="badge">{{courseList?.length}}</span>
          </div>
        </div>
        <div class="sb-card-grid mt-16">
          <div [id]="i" [data]="content" *ngFor="let content of courseList;let i = index;">
            <sb-course-card appContentDirection [data]="content" class="sb-card-grid__item" [course]="content"
              [cardImg]="content?.image || 'assets/images/book.png'" (cardClick)="playCourse($event)" [section]="null"
              appTelemetryInteract [telemetryInteractCdata]="[{ 'type': 'DialCode', 'id': dialCode}]"
              [telemetryInteractObject]="{id:content.metaData.identifier,type:content.contentType,ver:content.metaData.pkgVersion ? content.metaData.pkgVersion.toString():'1.0'}"
              [telemetryInteractEdata]="content.telemetryInteractEdata">
            </sb-course-card>
          </div>
        </div>
      </div>
    </div>
    <div class="sb-placeholder">
      <div *ngIf="!showLoader && !searchResults.length">
        <app-comming-soon></app-comming-soon>
      </div>
    </div>
  </div>
</div>

<div class="mobile-popup-dimmer" *ngIf="showMobilePopup" tabindex="0" (click)="closeMobileAppPopup()"
  [ngClass]="{'bottom-0': showMobilePopup}">
  <div class="mobile-app-popup" [ngClass]="{'bottom-0': showMobilePopup}">
    <div class="download-mobile-app">
      <div class="mobile-app-popup-close">
        <i class="close icon" aria-hidden="true"></i>
      </div>
      <div class="download-mobile-app-logo p-15" tabindex="0" (click)="redirectToDikshaApp()">
        <div class="mobile-circles">
          <div class="big-box border-round border-r50"></div>
          <div class="oval-box border-round ml-24"></div>
          <div class="small-box border-round border-r50 ml-16 mr-8"></div>
          <div class="small-box border-round border-r50"></div>
        </div>
        <label
          class="d-block text-center">{{resourceService?.frmelmnts?.lbl?.downloadDikshaForMobile | interpolate:'{instance}': instance}}</label>
        <a id='app-download-mobile' class="d-block pb-10 text-center app-download">
          <img class="playStore-img" src="assets/images/google_playstore.png"
            alt="{{resourceService?.frmelmnts?.lbl?.dikshaForMobile | interpolate:'{instance}':instance}}"
            title="{{resourceService?.frmelmnts?.lbl?.dikshaForMobile | interpolate:'{instance}':instance}}">
        </a>
        <p class="d-block text-center py-8">{{resourceService.frmelmnts?.lbl?.getUnlimitedAccess}}
        </p>
      </div>
    </div>
  </div>
</div>
</div>
<app-batch-info *ngIf="showBatchInfo" [enrolledBatchInfo]="selectedCourseBatches" (modelClose)="showBatchInfo = false">
</app-batch-info>

./dial-code.component.scss

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

/*get dial code page responsive css*/
.mobile-popup-dimmer {
  background: rgba(var(--rc-rgba-black), 0.5);
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: -999px;
  z-index: 9998;
  transition: 0.75s ease;
  .mobile-app-popup {
    display: none;
    position: fixed;
    bottom: -999px;
    z-index: 9999;
    left: 0;
    right: 0;
    transition: 0.75s ease;
    .download-mobile-app {
      border-radius: calculateRem(20px) calculateRem(20px) 0 0;
      position: absolute;
      bottom: 0 !important;
      padding: calculateRem(32px) calculateRem(12px) 0 calculateRem(12px);
      background: var(--gray-800);
      box-shadow: 0 calculateRem(20px) calculateRem(20px) calculateRem(10px) rgba(var(--rc-rgba-black), 0.2);
      max-width: calculateRem(250px);
      right: 0;
      left: 0;
      margin: 0 auto;
      transition: 0.75s ease-in-out;
      .mobile-app-popup-close {
        position: absolute;
        top: calculateRem(-15px);
        right: calculateRem(15px);
        width: calculateRem(25px);
        height: calculateRem(25px);
        background: var(--white);
        margin: 0;
        border-radius: calculateRem(25px);
        z-index: 9999;
        text-align: center;
        cursor: pointer;
        .icon {
          margin: 0 !important;
          color: var(--gray-400);
        }
      }
      img {
        width: calculateRem(120px);
      }
      .download-mobile-app-logo {
        background: var(--white);
        color: var(--black);
        border-radius: calculateRem(8px) calculateRem(8px) 0 0;
        p {
          font-size: calculateRem(12px);
          line-height: calculateRem(16px);
        }
        label {
          font-size: calculateRem(12px);
        }
      }
      label {
        font-weight: bold;
      }
      .close {
        line-height: normal;
        margin: 0 0 calculateRem(2px) 0 !important;
      }
      .mobile-circles {
        position: absolute;
        top: calculateRem(10px);
        display: flex;
        align-items: center;
        margin: 0 calculateRem(20px);
      }
      .mobile-circles .border-round {
        background: var(--gray-400);
        border: none;
      }

      .mobile-circles .border-r50 {
        border-radius: 50%;
      }

      .mobile-circles .big-box {
        height: calculateRem(14px);
        width: calculateRem(14px);
      }

      .mobile-circles .oval-box {
        height: calculateRem(6px);
        width: calculateRem(76px);
        border-radius: calculateRem(3px);
        margin-left: calculateRem(10px);
      }

      .mobile-circles .small-box {
        height: calculateRem(8px);
        width: calculateRem(8px);
      }
    }
  }
}

.bottom-0 {
  bottom: 0;
}
.dial-code-section-result {
  align-items: center !important;
  .header {
    display: inline-flex;
    align-items: center;
  }
  .header-label {
    font-size: calculateRem(12px);
  }
}

@media screen and (min-width: 240px) and (max-width: 767px) {
  .mobile-popup-dimmer {
    display: block;
    .mobile-app-popup {
      display: block;
      .download-mobile-app {
        display: block;
        bottom: 0;
        margin: 0 auto;
        right: 0;
        left: 0;
        box-shadow: 0 0 calculateRem(20px) calculateRem(10px) rgba(var(--rc-rgba-black), 0.2);
        height: calculateRem(185px);
        p {
          display: block !important;
        }
        .close-mobile-div {
          display: flex;
        }
        .download-mobile-app-logo {
          height: calculateRem(160px);
          overflow: hidden;
        }
      }
    }
  }
}
.sb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
  grid-gap: 1rem;
  grid-row-gap: 1.5rem;
}

.section-header {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.header {
  display: flex;
  flex-direction: row;
  margin:1rem 0 0 0;
  padding: 0px 0;
  align-items: center;

  .title {
    font-family: inherit;
    text-overflow: ellipsis;
    overflow: hidden;
    flex: 1;
    height: calculateRem(24px);
    color: var(--primary-color);
    font-size: calculateRem(18px);
    font-weight: bold;
    text-transform: capitalize;
    line-height: calculateRem(26px);
    display: flex;
    align-items: center;

    .badge {
      display: inline-block;
      background: var(--sbt-badge-bg);
      color: var(--gray-800);
      text-align: center;
      padding: calculateRem(0px) calculateRem(12px);
      border-radius: calculateRem(4px);
      height: calculateRem(24px);
      line-height: calculateRem(24px);
      font-size: calculateRem(16px);
      font-weight: normal;
      margin-left: calculateRem(8px);
    }
  }
}
.sb-placeholder {
  justify-content: center !important;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""