File

src/app/collection-detail-etb/collection-detail-etb.page.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Accessors

Constructor

constructor(contentService: ContentService, eventBusService: EventsBusService, profileService: ProfileService, storageService: StorageService, downloadService: DownloadService, zone: NgZone, events: Events, popoverCtrl: PopoverController, platform: Platform, appGlobalService: AppGlobalService, commonUtilService: CommonUtilService, navService: NavigationService, telemetryGeneratorService: TelemetryGeneratorService, fileSizePipe: FileSizePipe, headerService: AppHeaderService, location: Location, router: Router, changeDetectionRef: ChangeDetectorRef, textbookTocService: TextbookTocService, contentPlayerHandler: ContentPlayerHandler, contentDeleteHandler: ContentDeleteHandler, sbProgressLoader: SbProgressLoader)
Parameters :
Name Type Optional
contentService ContentService No
eventBusService EventsBusService No
profileService ProfileService No
storageService StorageService No
downloadService DownloadService No
zone NgZone No
events Events No
popoverCtrl PopoverController No
platform Platform No
appGlobalService AppGlobalService No
commonUtilService CommonUtilService No
navService NavigationService No
telemetryGeneratorService TelemetryGeneratorService No
fileSizePipe FileSizePipe No
headerService AppHeaderService No
location Location No
router Router No
changeDetectionRef ChangeDetectorRef No
textbookTocService TextbookTocService No
contentPlayerHandler ContentPlayerHandler No
contentDeleteHandler ContentDeleteHandler No
sbProgressLoader SbProgressLoader No

Methods

Private assignCardData
assignCardData()
Returns : void
cancelDownload
cancelDownload()
Returns : void
changeValue
changeValue(text)
Parameters :
Name Optional
text No
Returns : void
contentInfo
contentInfo()
Returns : void
downloadAllContent
downloadAllContent()

Download single content

Returns : void
extractApiResponse
extractApiResponse(data: Content)

Function to extract api response.

Parameters :
Name Type Optional
data Content No
Returns : void
generateCancelDownloadTelemetry
generateCancelDownloadTelemetry()
Returns : void
generateEndEvent
generateEndEvent(objectId, objectType, objectVersion)
Parameters :
Name Optional
objectId No
objectType No
objectVersion No
Returns : void
generateImpressionEvent
generateImpressionEvent(objectId, objectType, objectVersion)
Parameters :
Name Optional
objectId No
objectType No
objectVersion No
Returns : void
generateQRSessionEndEvent
generateQRSessionEndEvent(pageId: string, qrData: string)
Parameters :
Name Type Optional
pageId string No
qrData string No
Returns : void
generateStartEvent
generateStartEvent(objectId, objectType, objectVersion)
Parameters :
Name Optional
objectId No
objectType No
objectVersion No
Returns : void
getContentsSize
getContentsSize(data)
Parameters :
Name Optional
data No
Returns : void
getImportContentRequestBody
getImportContentRequestBody(identifiers: Array, isChild: boolean)

Function to get import content api request params

Parameters :
Name Type Optional Description
identifiers Array<string> No

contains list of content identifier(s)

isChild boolean No
Returns : Array<ContentImport>
handleBackButton
handleBackButton()
Returns : void
handleHeaderEvents
handleHeaderEvents($event)
Parameters :
Name Optional
$event No
Returns : void
importContent
importContent(identifiers: Array, isChild: boolean, isDownloadAllClicked?)

Function to get import content api request params

Parameters :
Name Type Optional Description
identifiers Array<string> No

contains list of content identifier(s)

isChild boolean No
isDownloadAllClicked Yes
Returns : void
importContentInBackground
importContentInBackground(identifiers: Array, isChild: boolean)
Parameters :
Name Type Optional
identifiers Array<string> No
isChild boolean No
Returns : void
ionViewDidEnter
ionViewDidEnter()
Returns : void
ionViewWillEnter
ionViewWillEnter()
Returns : void
ionViewWillLeave
ionViewWillLeave()

Ionic life cycle hook

Returns : void
isGroupShown
isGroupShown(group)
Parameters :
Name Optional
group No
Returns : boolean
markContent
markContent()
Returns : void
mergeProperties
mergeProperties(mergeProp)
Parameters :
Name Optional
mergeProp No
Returns : any
navigateToDetailsPage
navigateToDetailsPage(content: any, depth, corRelationData?)
Parameters :
Name Type Optional
content any No
depth No
corRelationData Yes
Returns : void
ngOnInit
ngOnInit()
Returns : void
Async onFilterMimeTypeChange
onFilterMimeTypeChange(val, idx, currentFilter?)
Parameters :
Name Optional
val No
idx No
currentFilter Yes
Returns : any
onScroll
onScroll(event)
Parameters :
Name Optional
event No
Returns : void
openBrowser
openBrowser(url)
Parameters :
Name Optional
url No
Returns : void
openTextbookToc
openTextbookToc()
Returns : void
playButtonClick
playButtonClick(event)
Parameters :
Name Optional
event No
Returns : void
playContent
playContent(event, corRelationData?)
Parameters :
Name Optional
event No
corRelationData Yes
Returns : void
Private redirectToActivedownloads
redirectToActivedownloads()
Returns : void
refreshContentDetails
refreshContentDetails(data)
Parameters :
Name Optional
data No
Returns : void
refreshHeader
refreshHeader()
Returns : void
registerDeviceBackButton
registerDeviceBackButton()
Returns : void
resetVariables
resetVariables()

Reset all values

Returns : void
Private setActiveContentData
setActiveContentData(event, telemetrySubType, corRelationData)
Parameters :
Name Optional
event No
telemetrySubType No
corRelationData No
Returns : void
setChildContents
setChildContents()

Function to set child contents

Returns : void
setCollectionStructure
setCollectionStructure()
Returns : void
Async setContentDetails
setContentDetails(identifier, refreshContentDetails: boolean)

To set content details in local variable

Parameters :
Name Type Optional Description
identifier No

identifier of content / course

refreshContentDetails boolean No
Returns : any
Private setExtrasData
setExtrasData(extras)
Parameters :
Name Optional
extras No
Returns : void
Private setTocData
setTocData(content)
Parameters :
Name Optional
content No
Returns : void
Async share
share()
Returns : any
Async showDeletePopOver
showDeletePopOver()
Returns : any
Async showDownloadConfirmationAlert
showDownloadConfirmationAlert()
Returns : any
subscribeSdkEvent
subscribeSdkEvent()

Subscribe Sunbird-SDK event to get content download progress

Returns : void
tocCardClick
tocCardClick(event)
Parameters :
Name Optional
event No
Returns : void
toggleGroup
toggleGroup(group, content, openCarousel?)
Parameters :
Name Optional
group No
content No
openCarousel Yes
Returns : void
updateSavedResources
updateSavedResources()
Returns : void

Properties

_licenseDetails
Type : any
accordianConfig
Type : IAccordianConfig
Default value : { expandMode: ExpandMode.SINGLE, expandBehavior: ExpandBehavior.EXPAND_FIRST }
activeContent
activeMimeTypeFilter
Type : []
Default value : ['all']
appName
Type : any
Public backButtonFunc
Type : Subscription
Public baseUrl
Type : string
Default value : ''
batchDetails
Type : any
breadCrumb
Default value : new Map()
cardData
Type : any

Contains card data of previous state

Optional childrenData
Type : Array<any>
collectionChildComp
Type : CollectionChildComponent
Decorators :
@ViewChild('collectionChildComp', {static: false})
collectionTocData
Type : Content
content
Type : any
contentDeleteObservable
Type : any
Optional contentDetail
Type : Content
contentId
Type : string
contentTypesCount
Type : any
Public corRelationList
Type : Array<CorrelationData>
currentCount
Type : number
Default value : 0

Current download count

currentFilter
Type : string
Default value : 'ALL'
data
Type : any
defaultAppIcon
Type : string
depth
Type : string
Default value : '1'

Contains current course depth

Public didViewLoad
Type : boolean
downloadContentsSize
Type : string

Contains total size of locally not available content(s)

downloadIdentifiers
Type : Set<string>
Default value : new Set()

Contains identifier(s) of locally not available content(s)

downloadPercentage
Type : number
downloadProgress
Type : any

Contains child content import / download progress

downloadSize
Type : number
Default value : 0

Child content size

Private eventSubscription
Type : Subscription
facets
Type : any
faultyIdentifiers
Type : Array<any>
Default value : []
fromCoursesPage
Default value : false

sets true , if it comes from courses

headerConfig
Type : object
Default value : { showHeader: true, showBurgerMenu: false, actionButtons: [] }
headerObservable
Type : any
hiddenGroups
Default value : new Set()
identifier
Type : string

To hold identifier

importProgressMessage
Type : string
ionContent
Type : iContent
Decorators :
@ViewChild(iContent, {static: false})
isAlreadyEnrolled
Default value : false
isChapterVisible
Default value : false
isChild
Default value : false
isChildClickable
Default value : false
isContentPlayed
Default value : false
isDepthChild
Default value : false

Its get true when child is collection. Used to show content depth

isDownloadCompleted
Default value : false

Download complete falg

isDownloadStarted
Default value : false

Flag downlaoded started

isSelected
Type : boolean
isUpdateAvailable
Default value : false

Needed to handle collection auto update workflow

localImage
Type : string
Default value : ''
localResourseCount
Type : number
mimeTypes
Type : []
Default value : [ { name: 'ALL', selected: true, value: ['all'], iconNormal: '', iconActive: '' }, { name: 'VIDEO', value: ['video/mp4', 'video/x-youtube', 'video/webm'], iconNormal: './assets/imgs/play.svg', iconActive: './assets/imgs/play-active.svg' }, { name: 'DOC', value: ['application/pdf', 'application/epub', 'application/msword'], iconNormal: './assets/imgs/doc.svg', iconActive: './assets/imgs/doc-active.svg' }, { name: 'INTERACTION', value: ['application/vnd.ekstep.ecml-archive', 'application/vnd.ekstep.h5p-archive', 'application/vnd.ekstep.html-archive'], iconNormal: './assets/imgs/touch.svg', iconActive: './assets/imgs/touch-active.svg' }, // { name: 'AUDIOS', value: MimeType.AUDIO, iconNormal: './assets/imgs/audio.svg', iconActive: './assets/imgs/audio-active.svg'}, ]
objectKeys
Default value : Object.keys

To get course structure keys

objId
Public objRollup
Type : Rollup

Telemetry roll up object

objType
objVer
pageId
Type : string
Default value : PageId.COLLECTION_DETAIL
pageName
Type : any
parentContent
Type : any

Contains Parent Content Details

playBtnConfig
Type : IButtonConfig
Private Optional previousHeaderBottomOffset
Type : number
queuedIdentifiers
Type : Array<any>
Default value : []

To hold content identifiers

ratingComment
Type : string
Default value : ''

Rating comment

Public rollUpMap
Type : literal type
Default value : {}
scrollPosition
Type : number
Default value : 0
selected
Type : boolean
Public shouldGenerateEndTelemetry
Default value : false
shouldPillsStick
Default value : false
showChildrenLoader
Type : boolean

Show loader while importing content

showCollapsedPopup
Default value : true
showContentDetails
Default value : false
showCredits
Default value : false
showDownload
Type : boolean
showDownloadBtn
Default value : false

Contains

Public showLoading
Default value : false
shownGroups
Default value : undefined
showSheenAnimation
Default value : true
Public source
Type : string
Default value : ''
stateData
Type : any
Optional stckyUnitTitle
Type : string
stickyPillsRef
Type : ElementRef
Decorators :
@ViewChild('stickyPillsRef', {static: false})
Public telemetryObject
Type : TelemetryObject
TocCardType
Default value : TocCardType
totalDownload
Type : number

Total download count

trackDownloads$
Type : Observable<DownloadTracking>
userRating
Type : number
Default value : 0

To hold rating data

Accessors

licenseDetails
getlicenseDetails()
setlicenseDetails(val)
Parameters :
Name Optional
val No
Returns : void
import { Location } from '@angular/common';
import {
  ChangeDetectorRef,
  Component,
  ElementRef,
  Inject,
  NgZone,
  OnInit,
  ViewChild,
  ViewEncapsulation
} from '@angular/core';
import { Router } from '@angular/router';
import { FileSizePipe } from '@app/pipes/file-size/file-size';
import { ContentDeleteHandler } from '@app/services/content/content-delete-handler';
import { ContentInfo } from '@app/services/content/content-info';
import { ContentPlayerHandler } from '@app/services/content/player/content-player-handler';
import { NavigationService } from '@app/services/navigation-handler.service';
import { ContentUtil } from '@app/util/content-util';
import { IonContent as iContent, Platform, PopoverController } from '@ionic/angular';
import { Events } from '@app/util/events';
import { CsPrimaryCategory } from '@project-sunbird/client-services/services/content';
import { ExpandBehavior, ExpandMode, IAccordianConfig, IButtonConfig, TocCardType } from '@project-sunbird/common-consumption';
import isObject from 'lodash/isObject';
import { Observable, Subscription } from 'rxjs';
import { share } from 'rxjs/operators';
import {
  Content,
  ContentAccess,
  ContentAccessStatus,
  ContentDetailRequest,
  ContentEventType,
  ContentImport,
  ContentImportCompleted,
  ContentImportRequest,
  ContentImportResponse,
  ContentImportStatus,
  ContentMarkerRequest,
  ContentService,
  ContentUpdate,
  CorrelationData,
  DownloadEventType,
  DownloadProgress,
  DownloadService,
  DownloadTracking,
  EventsBusEvent,
  EventsBusService,
  MarkerType,
  Profile,
  ProfileService,
  Rollup,
  StorageService,
  TelemetryErrorCode,
  TelemetryObject
} from 'sunbird-sdk';
import { EventTopics, RouterLinks, ShareItemType } from '../../app/app.constant';
import {
  AppGlobalService, AppHeaderService, CommonUtilService,
  TelemetryGeneratorService
} from '../../services';
import { SbProgressLoader } from '../../services/sb-progress-loader.service';
import { CorReleationDataType, Environment, ErrorType, ImpressionType, InteractSubtype, InteractType, Mode, PageId } from '../../services/telemetry-constants';
import { CollectionChildComponent, ConfirmAlertComponent } from '../components';
import { SbSharePopupComponent } from '../components/popups/sb-share-popup/sb-share-popup.component';
import { TextbookTocService } from './textbook-toc-service';
import { TagPrefixConstants } from '@app/services/segmentation-tag/segmentation-tag.service';

@Component({
  selector: 'app-collection-detail-etb',
  templateUrl: './collection-detail-etb.page.html',
  styleUrls: ['./collection-detail-etb.page.scss'],
  encapsulation: ViewEncapsulation.None,
})
export class CollectionDetailEtbPage implements OnInit {

  facets: any;
  selected: boolean;
  isSelected: boolean;
  headerConfig = {
    showHeader: true,
    showBurgerMenu: false,
    actionButtons: []
  };

  contentDetail?: Content;
  childrenData?: Array<any>;
  mimeTypes = [
    { name: 'ALL', selected: true, value: ['all'], iconNormal: '', iconActive: '' },
    {
      name: 'VIDEO', value: ['video/mp4', 'video/x-youtube', 'video/webm'], iconNormal: './assets/imgs/play.svg',
      iconActive: './assets/imgs/play-active.svg'
    },
    {
      name: 'DOC', value: ['application/pdf', 'application/epub', 'application/msword'], iconNormal: './assets/imgs/doc.svg',
      iconActive: './assets/imgs/doc-active.svg'
    },
    {
      name: 'INTERACTION',
      value: ['application/vnd.ekstep.ecml-archive', 'application/vnd.ekstep.h5p-archive', 'application/vnd.ekstep.html-archive'],
      iconNormal: './assets/imgs/touch.svg', iconActive: './assets/imgs/touch-active.svg'
    },
    // { name: 'AUDIOS', value: MimeType.AUDIO, iconNormal: './assets/imgs/audio.svg', iconActive: './assets/imgs/audio-active.svg'},
  ];
  activeMimeTypeFilter = ['all'];
  /**
   * Show loader while importing content
   */
  showChildrenLoader: boolean;

  /**
   * Contains card data of previous state
   */
  cardData: any;

  /**
   * Contains Parent Content Details
   */
  parentContent: any;

  /**
   * To hold identifier
   */
  identifier: string;

  /**
   * Contains child content import / download progress
   */
  downloadProgress: any;

  /**
   * To get course structure keys
   */
  objectKeys = Object.keys;

  /**
   * Contains
   */
  showDownloadBtn = false;

  /**
   * Flag downlaoded started
   */
  isDownloadStarted = false;

  /**
   * Contains current course depth
   */
  depth = '1';

  /**
   * Its get true when child is collection.
   * Used to show content depth
   *
   * @example 1.1 Collection 1
   */
  isDepthChild = false;

  /**
   * To hold content identifiers
   */
  queuedIdentifiers: Array<any> = [];

  faultyIdentifiers: Array<any> = [];

  /**
   * Download complete falg
   */
  isDownloadCompleted = false;

  /**
   * Total download count
   */
  totalDownload: number;

  /**
   * Current download count
   */
  currentCount = 0;

  /**
   * Contains identifier(s) of locally not available content(s)
   */
  downloadIdentifiers: Set<string> = new Set();

  /**
   * Child content size
   */
  downloadSize = 0;
  showCredits = false;

  /**
   * Contains total size of locally not available content(s)
   */
  downloadContentsSize: string;
  downloadPercentage: number;
  objId;
  objType;
  objVer;
  public showLoading = false;

  /**
   * Needed to handle collection auto update workflow
   */
  isUpdateAvailable = false;

  /**
   * To hold rating data
   */
  userRating = 0;
  isAlreadyEnrolled = false;
  /** sets true , if it comes from courses */
  fromCoursesPage = false;
  /**
   * Rating comment
   */
  ratingComment = '';
  // defaultIcon
  defaultAppIcon: string;

  localResourseCount: number;
  /**
   * Telemetry roll up object
   */
  public objRollup: Rollup;
  public didViewLoad: boolean;
  public backButtonFunc: Subscription;
  public baseUrl = '';
  public corRelationList: Array<CorrelationData>;
  public shouldGenerateEndTelemetry = false;
  public source = '';
  isChildClickable = false;
  hiddenGroups = new Set();
  shownGroups = undefined;
  content: any;
  data: any;
  isChild = false;
  contentId: string;
  batchDetails: any;
  pageName: any;
  headerObservable: any;
  breadCrumb = new Map();
  scrollPosition = 0;
  currentFilter = 'ALL';
  localImage = '';
  appName: any;
  @ViewChild(iContent, { static: false }) ionContent: iContent;
  @ViewChild('stickyPillsRef', { static: false }) stickyPillsRef: ElementRef;
  @ViewChild('collectionChildComp', { static: false }) collectionChildComp: CollectionChildComponent;
  private eventSubscription: Subscription;

  showDownload: boolean;
  contentTypesCount: any;
  stateData: any;
  stckyUnitTitle?: string;
  isChapterVisible = false;
  shouldPillsStick = false;
  importProgressMessage: string;
  showSheenAnimation = true;

  public telemetryObject: TelemetryObject;
  public rollUpMap: { [key: string]: Rollup } = {};
  private previousHeaderBottomOffset?: number;
  isContentPlayed = false;
  contentDeleteObservable: any;

  _licenseDetails: any;
  trackDownloads$: Observable<DownloadTracking>;
  showCollapsedPopup = true;
  get licenseDetails() {
    return this._licenseDetails;
  }
  set licenseDetails(val) {
    if (!this._licenseDetails && val) {
      this._licenseDetails = val;
    }
  }
  pageId: string = PageId.COLLECTION_DETAIL;
  collectionTocData: Content;
  TocCardType = TocCardType;
  activeContent;
  playBtnConfig: IButtonConfig;
  accordianConfig: IAccordianConfig = {
    expandMode: ExpandMode.SINGLE,
    expandBehavior: ExpandBehavior.EXPAND_FIRST
  };
  showContentDetails = false;

  constructor(
    @Inject('CONTENT_SERVICE') private contentService: ContentService,
    @Inject('EVENTS_BUS_SERVICE') private eventBusService: EventsBusService,
    @Inject('PROFILE_SERVICE') private profileService: ProfileService,
    @Inject('STORAGE_SERVICE') private storageService: StorageService,
    @Inject('DOWNLOAD_SERVICE') private downloadService: DownloadService,
    private zone: NgZone,
    private events: Events,
    private popoverCtrl: PopoverController,
    private platform: Platform,
    private appGlobalService: AppGlobalService,
    private commonUtilService: CommonUtilService,
    private navService: NavigationService,
    private telemetryGeneratorService: TelemetryGeneratorService,
    private fileSizePipe: FileSizePipe,
    private headerService: AppHeaderService,
    private location: Location,
    private router: Router,
    private changeDetectionRef: ChangeDetectorRef,
    private textbookTocService: TextbookTocService,
    private contentPlayerHandler: ContentPlayerHandler,
    private contentDeleteHandler: ContentDeleteHandler,
    private sbProgressLoader: SbProgressLoader
  ) {
    this.objRollup = new Rollup();
    this.defaultAppIcon = 'assets/imgs/ic_launcher.png';
    const extras = this.router.getCurrentNavigation().extras.state;

    if (extras) {
      this.setExtrasData(extras);
    }
  }

  private setExtrasData(extras) {
    this.content = extras.content;
    this.data = extras.data;
    this.cardData = extras.content;
    this.batchDetails = extras.batchDetails;
    this.pageName = extras.pageName;
    this.depth = extras.depth;
    this.corRelationList = extras.corRelation || [];
    this.shouldGenerateEndTelemetry = extras.shouldGenerateEndTelemetry;
    this.source = extras.source;
    this.fromCoursesPage = extras.fromCoursesPage;
    this.isAlreadyEnrolled = extras.isAlreadyEnrolled;
    this.isChildClickable = extras.isChildClickable;
    this.facets = extras.facets;
    this.telemetryObject = ContentUtil.getTelemetryObject(extras.content);
    this.parentContent = extras.parentContent;
    if (this.depth) {
      this.showDownloadBtn = false;
      this.isDepthChild = true;
    } else {
      this.isDepthChild = false;
    }
    this.pageId = this.commonUtilService.appendTypeToPrimaryCategory(this.content) || this.pageId;
    this.identifier = this.cardData.contentId || this.cardData.identifier;
    window['segmentation'].SBTagService.pushTag(
      window['segmentation'].SBTagService.getTags(TagPrefixConstants.CONTENT_ID) ? this.identifier : [this.identifier],
      TagPrefixConstants.CONTENT_ID,
      window['segmentation'].SBTagService.getTags(TagPrefixConstants.CONTENT_ID) ? false : true
    );
  }

  ngOnInit() {
    this.playBtnConfig = {
      label: this.commonUtilService.translateMessage('PLAY'),
      show: true
    };

    this.commonUtilService.getAppName().then((res) => { this.appName = res; });
    window['scrollWindow'] = this.ionContent;
      this.trackDownloads$ = this.downloadService.trackDownloads({ groupBy: { fieldPath: 'rollUp.l1', value: this.identifier } }).pipe(
        share());
    
  }

  ionViewWillEnter() {
    this.headerService.showStatusBar();
    this.registerDeviceBackButton();
    this.zone.run(() => {
      this.headerObservable = this.headerService.headerEventEmitted$.subscribe(eventName => {
        this.handleHeaderEvents(eventName);
      });
      this.headerConfig = this.headerService.getDefaultPageConfig();
      this.headerConfig.actionButtons = ['download'];
      this.headerConfig.showHeader = false;
      this.headerConfig.showBurgerMenu = false;
      this.headerService.updatePageConfig(this.headerConfig);
      this.hiddenGroups.clear();
      this.shownGroups = undefined;
      this.assignCardData();
      this.resetVariables();
      this.setContentDetails(this.identifier, true);
      this.events.subscribe(EventTopics.CONTENT_TO_PLAY, (data) => {
        this.playContent(data);
      });
      this.subscribeSdkEvent();
    });
    this.ionContent.ionScroll.subscribe((event) => {
      this.scrollPosition = event.scrollTop;
    });

    this.events.subscribe(EventTopics.DEEPLINK_COLLECTION_PAGE_OPEN, (data) => {
      if (data.content) {
        this.refreshContentDetails(data);
      }
    });
    this.events.subscribe(EventTopics.NEXT_CONTENT, async (data) => {
      console.log('Next Content', data);
      this.content = data.content;
      this.playContent(data);
      setTimeout(() => {
        this.contentPlayerHandler.setLastPlayedContentId('');
      }, 1000);
    });
  }

  ionViewDidEnter() {
    this.sbProgressLoader.hide({ id: this.identifier });
  }

  private assignCardData() {
    if (!this.didViewLoad) {
      this.objRollup = ContentUtil.generateRollUp(this.cardData.hierarchyInfo, this.cardData.identifier);
      const contentType = this.cardData.contentData ? this.cardData.contentData.contentType : this.cardData.contentType;
      this.objType = contentType;
      this.generateStartEvent(this.cardData.identifier, contentType, this.cardData.pkgVersion);
      this.generateImpressionEvent(this.cardData.identifier, contentType, this.cardData.pkgVersion);
      this.markContent();
    }
    this.didViewLoad = true;
  }

  refreshContentDetails(data) {
    this.resetVariables();
    this.shownGroups = undefined;
    this.hiddenGroups.clear();
    this.setExtrasData(data);
    this.didViewLoad = false;
    this.assignCardData();
    this.setContentDetails(this.identifier, true);
    this.subscribeSdkEvent();
  }

  openBrowser(url) {
    this.commonUtilService.openUrlInBrowser(url);
  }

  markContent() {
    const addContentAccessRequest: ContentAccess = {
      status: ContentAccessStatus.PLAYED,
      contentId: this.identifier,
      contentType: this.content.contentType
    };
    const profile: Profile = this.appGlobalService.getCurrentUser();
    this.profileService.addContentAccess(addContentAccessRequest).toPromise().then((data) => {
      if (data) {
        this.events.publish(EventTopics.LAST_ACCESS_ON, true);
      }
    });
    const contentMarkerRequest: ContentMarkerRequest = {
      uid: profile.uid,
      contentId: this.identifier,
      data: JSON.stringify(this.content.contentData),
      marker: MarkerType.PREVIEWED,
      isMarked: true,
      extraInfo: {}
    };
    this.contentService.setContentMarker(contentMarkerRequest).toPromise().then();
  }

  // toggle the card
  toggleGroup(group, content, openCarousel?) {
    let isCollapsed = true;
    if (!openCarousel && this.isGroupShown(group)) {
      isCollapsed = false;
      this.shownGroups = undefined;
      this.hiddenGroups.add(group);
    } else {
      isCollapsed = false;
      this.shownGroups = group;
      this.hiddenGroups.delete(group);
    }
    const values = new Map();
    values['isCollapsed'] = isCollapsed;

    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.UNIT_CLICKED,
      Environment.HOME,
      PageId.COLLECTION_DETAIL,
      this.telemetryObject,
      values,
      this.objRollup,
      this.corRelationList
    );
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.UNIT_CLICKED,
      Environment.HOME,
      this.pageId,
      this.telemetryObject,
      values,
      this.objRollup,
      this.corRelationList
    );
  }

  // to check whether the card is toggled or not
  isGroupShown(group) {
    if (this.activeMimeTypeFilter.indexOf('all') === 0) {
      return this.shownGroups === group;
    } else {
      return !this.hiddenGroups.has(group);
    }
  }

  changeValue(text) {
    if (!text) {
      this.isSelected = false;
    } else {
      this.isSelected = true;
    }
  }

  handleBackButton() {
    this.didViewLoad = false;
    this.generateEndEvent(this.objId, this.objType, this.objVer);

    if (this.shouldGenerateEndTelemetry) {
      this.generateQRSessionEndEvent(this.source, this.cardData.identifier);
    }
    if (this.source === PageId.ONBOARDING_PROFILE_PREFERENCES) {
      this.router.navigate([`/${RouterLinks.PROFILE_SETTINGS}`], { state: { showFrameworkCategoriesMenu: true }, replaceUrl: true });
    } else {
      this.location.back();
    }
  }

  registerDeviceBackButton() {
    this.backButtonFunc = this.platform.backButton.subscribeWithPriority(10, () => {
      this.telemetryGeneratorService.generateBackClickedTelemetry(PageId.COLLECTION_DETAIL, Environment.HOME,
        false, this.cardData.identifier, this.corRelationList);
      this.telemetryGeneratorService.generateBackClickedTelemetry(this.pageId, Environment.HOME,
          false, this.cardData.identifier, this.corRelationList);
      this.handleBackButton();
    });
  }

  /**
   * To set content details in local variable
   * @param identifier identifier of content / course
   */
  async setContentDetails(identifier, refreshContentDetails: boolean) {
    const option: ContentDetailRequest = {
      contentId: identifier,
      objectType: this.cardData.objectType,
      attachFeedback: true,
      attachContentAccess: true,
      emitUpdateIfAny: refreshContentDetails
    };
    this.contentService.getContentDetails(option).toPromise()
      .then((data: Content | any) => {
        if (data) {
          this.licenseDetails = data.contentData.licenseDetails || this.licenseDetails;
          if (data.contentData.attributions && data.contentData.attributions.length) {
            data.contentData.attributions = (data.contentData.attributions.sort()).join(', ');
          }
          if (!data.isAvailableLocally) {
            this.contentDetail = data;
            this.telemetryGeneratorService.generatefastLoadingTelemetry(
              InteractSubtype.FAST_LOADING_INITIATED,
              PageId.COLLECTION_DETAIL,
              this.telemetryObject,
              undefined,
              this.objRollup,
              this.corRelationList
            );
            this.telemetryGeneratorService.generatefastLoadingTelemetry(
              InteractSubtype.FAST_LOADING_INITIATED,
              this.pageId,
              this.telemetryObject,
              undefined,
              this.objRollup,
              this.corRelationList
            );
            this.contentService.getContentHeirarchy(option).toPromise()
              .then((content: Content) => {
                this.setTocData(content);
                this.showSheenAnimation = false;
                this.toggleGroup(0, this.content);
                this.telemetryGeneratorService.generatefastLoadingTelemetry(
                  InteractSubtype.FAST_LOADING_FINISHED,
                  PageId.COLLECTION_DETAIL,
                  this.telemetryObject,
                  undefined,
                  this.objRollup,
                  this.corRelationList
                );
                this.telemetryGeneratorService.generatefastLoadingTelemetry(
                  InteractSubtype.FAST_LOADING_FINISHED,
                  this.pageId,
                  this.telemetryObject,
                  undefined,
                  this.objRollup,
                  this.corRelationList
                );
              }).catch(() => {
                this.showSheenAnimation = false;
              });
            this.importContentInBackground([this.identifier], false);
          } else {
            this.showSheenAnimation = false;
            this.extractApiResponse(data);
          }
        }
      }).catch((error) => {
        console.log('error while loading content details', error);
        this.showSheenAnimation = false;
        this.commonUtilService.showToast('ERROR_CONTENT_NOT_AVAILABLE');
        this.location.back();
      });
  }

  /**
   * Function to extract api response.
   */
  extractApiResponse(data: Content) {
    this.contentDetail = data;
    this.contentDetail.contentData.appIcon = ContentUtil.getAppIcon(this.contentDetail.contentData.appIcon,
      this.contentDetail.basePath, this.commonUtilService.networkInfo.isNetworkAvailable);
    this.objId = this.contentDetail.identifier;
    this.objVer = this.contentDetail.contentData.pkgVersion;

    // User Rating
    const contentFeedback: any = data.contentFeedback ? data.contentFeedback : [];
    if (contentFeedback !== undefined && contentFeedback.length !== 0) {
      this.userRating = contentFeedback[0].rating;
      this.ratingComment = contentFeedback[0].comments;
    }

    if (Boolean(data.isAvailableLocally)) {
      this.showLoading = false;
      this.refreshHeader();
      if (data.isUpdateAvailable && !this.isUpdateAvailable) {
        this.isUpdateAvailable = true;
        this.showLoading = true;
        this.telemetryGeneratorService.generateSpineLoadingTelemetry(this.contentDetail, false);
        this.importContent([this.identifier], false);
      } else {
        this.isUpdateAvailable = false;
        this.setChildContents();
      }
    } else {
      this.showLoading = true;
      this.telemetryGeneratorService.generateSpineLoadingTelemetry(this.contentDetail, true);
      this.importContent([this.identifier], false);
    }

    if (this.contentDetail.contentData.me_totalDownloads) {
      this.contentDetail.contentData.me_totalDownloads = this.contentDetail.contentData.me_totalDownloads.split('.')[0];
    }
    this.setCollectionStructure();
  }

  setCollectionStructure() {
    this.showChildrenLoader = true;
    if (this.contentDetail.contentData.contentTypesCount) {
      if (!isObject(this.contentDetail.contentData.contentTypesCount)) {
        this.contentTypesCount = JSON.parse(this.contentDetail.contentData.contentTypesCount);
      } else {
        this.contentTypesCount = this.contentDetail.contentData.contentTypesCount;
      }
    } else if (this.cardData.contentTypesCount) {
      if (!isObject(this.cardData.contentTypesCount)) {
        this.contentTypesCount = JSON.parse(this.cardData.contentTypesCount);
      }
    }
  }

  /**
   * Function to get import content api request params
   *
   * @param identifiers contains list of content identifier(s)
   */
  getImportContentRequestBody(identifiers: Array<string>, isChild: boolean): Array<ContentImport> {
    const requestParams: ContentImport[] = [];
    const folderPath = this.platform.is('ios') ? cordova.file.documentsDirectory : this.storageService.getStorageDestinationDirectoryPath();
   
    identifiers.forEach((value) => {
      requestParams.push({
        isChildContent: isChild,
        destinationFolder: folderPath,
        contentId: value,
        correlationData: this.corRelationList ? this.corRelationList : [],
        rollUp: this.rollUpMap[value]
      });
    });

    return requestParams;
  }

  /**
   * Function to get import content api request params
   *
   * @param  identifiers contains list of content identifier(s)
   */
  importContent(identifiers: Array<string>, isChild: boolean, isDownloadAllClicked?) {
    if (this.showLoading && !this.isDownloadStarted) {
      this.headerService.hideHeader();
    }
    const option: ContentImportRequest = {
      contentImportArray: this.getImportContentRequestBody(identifiers, isChild),
      contentStatusArray: ['Live'],
      fields: ['appIcon', 'name', 'subject', 'size', 'gradeLevel'],
    };
    // Call content service
    this.contentService.importContent(option).toPromise()
      .then((data: ContentImportResponse[]) => {
        this.zone.run(() => {
          if (data && data.length && this.isDownloadStarted) {
            data.forEach((value) => {
              if (value.status === ContentImportStatus.ENQUEUED_FOR_DOWNLOAD) {
                this.queuedIdentifiers.push(value.identifier);
              } else if (value.status === ContentImportStatus.NOT_FOUND) {
                this.faultyIdentifiers.push(value.identifier);
              }
            });

            if (isDownloadAllClicked) {
              this.telemetryGeneratorService.generateDownloadAllClickTelemetry(
                PageId.COLLECTION_DETAIL,
                this.contentDetail,
                this.queuedIdentifiers,
                identifiers.length
              );
              this.telemetryGeneratorService.generateDownloadAllClickTelemetry(
                this.pageId,
                this.contentDetail,
                this.queuedIdentifiers,
                identifiers.length
              );
            }

            if (this.queuedIdentifiers.length === 0) {
              if (this.isDownloadStarted) {
                this.showDownloadBtn = true;
                this.isDownloadStarted = false;
                this.showLoading = false;
                this.refreshHeader();
              }
            }
            if (this.faultyIdentifiers.length > 0) {
              const stackTrace: any = {};
              stackTrace.parentIdentifier = this.cardData.identifier;
              stackTrace.faultyIdentifiers = this.faultyIdentifiers;
              this.telemetryGeneratorService.generateErrorTelemetry(Environment.HOME,
                TelemetryErrorCode.ERR_DOWNLOAD_FAILED,
                ErrorType.SYSTEM,
                PageId.COLLECTION_DETAIL,
                JSON.stringify(stackTrace),
              );
              this.telemetryGeneratorService.generateErrorTelemetry(Environment.HOME,
                TelemetryErrorCode.ERR_DOWNLOAD_FAILED,
                ErrorType.SYSTEM,
                this.pageId,
                JSON.stringify(stackTrace),
              );
              this.commonUtilService.showToast('UNABLE_TO_FETCH_CONTENT');
            }
          } else if (data && data[0].status === ContentImportStatus.NOT_FOUND) {
            this.showLoading = false;
            this.refreshHeader();
            this.showChildrenLoader = false;
            this.childrenData.length = 0;
            this.collectionTocData.children.length = 0;
          }
        });
      })
      .catch((error: any) => {
        this.zone.run(() => {
          this.showDownloadBtn = true;
          this.isDownloadStarted = false;
          this.showLoading = false;
          this.refreshHeader();
          if (Boolean(this.isUpdateAvailable)) {
            this.setChildContents();
          } else {
            if (error && (error.error === 'NETWORK_ERROR' || error.error === 'CONNECTION_ERROR')) {
              this.commonUtilService.showToast('NEED_INTERNET_TO_CHANGE');
            } else {
              this.commonUtilService.showToast('UNABLE_TO_FETCH_CONTENT');
            }
            this.showChildrenLoader = false;
            this.location.back();
          }
        });
      });
  }

  /**
   * Function to set child contents
   */
  setChildContents() {
    this.showChildrenLoader = true;
    const hierarchyInfo = this.cardData.hierarchyInfo ? this.cardData.hierarchyInfo : null;
    const option = { contentId: this.identifier, hierarchyInfo }; 
    this.contentService.getChildContents(option).toPromise()
      .then((data: Content) => {
        this.zone.run(() => {
          if (data && data.children) {
            this.breadCrumb.set(data.identifier, data.contentData.name);
            if (this.textbookTocService.textbookIds.rootUnitId && this.activeMimeTypeFilter !== ['all']) {
              this.onFilterMimeTypeChange(this.mimeTypes[0].value, 0, this.mimeTypes[0].name);
            }
            if (this.textbookTocService.textbookIds.content) {
              this.activeContent = this.textbookTocService.textbookIds.content;
            }
            this.setTocData(data);
            this.changeDetectionRef.detectChanges();
          }

          if (!this.isDepthChild) {
            this.downloadSize = 0;
            this.localResourseCount = 0;
            this.getContentsSize(data.children || []);
          }
          this.showChildrenLoader = false;
          if (this.textbookTocService.textbookIds.contentId) {
            setTimeout(() => {
              (this.stickyPillsRef.nativeElement as HTMLDivElement).classList.add('sticky');
              window['scrollWindow'].getScrollElement().then(() => {
                document.getElementById(this.textbookTocService.textbookIds.contentId).scrollIntoView({ behavior: 'smooth' });
                this.textbookTocService.resetTextbookIds();
              });
            }, 0);
          }

          this.telemetryGeneratorService.generateInteractTelemetry(
            InteractType.OTHER,
            InteractSubtype.IMPORT_COMPLETED,
            Environment.HOME,
            PageId.COLLECTION_DETAIL,
            this.telemetryObject,
            undefined,
            this.objRollup,
            this.corRelationList
          );
          this.telemetryGeneratorService.generateInteractTelemetry(
            InteractType.OTHER,
            InteractSubtype.IMPORT_COMPLETED,
            Environment.HOME,
            this.pageId,
            this.telemetryObject,
            undefined,
            this.objRollup,
            this.corRelationList
          );
        });
      })
      .catch(() => {
        this.zone.run(() => {
          this.showChildrenLoader = false;
        });
      });
  }

  private setTocData(content) {
    this.childrenData = content.children;
    this.collectionTocData = content;
  }

  getContentsSize(data) {
    data.forEach((value) => {
      this.breadCrumb.set(value.identifier, value.contentData.name);
      if (value.contentData.size) {
        this.downloadSize += Number(value.contentData.size);
      }
      if (!value.children) {
        if (value.isAvailableLocally) {
          this.localResourseCount++;
        }
      }

      if (value.children) {
        this.getContentsSize(value.children);
      }
      if (!value.isAvailableLocally && value.contentData.downloadUrl) {
        this.downloadIdentifiers.add(value.contentData.identifier);
        this.rollUpMap[value.contentData.identifier] = ContentUtil.generateRollUp(value.hierarchyInfo, undefined);
      }

    });
    if (this.downloadIdentifiers.size && !this.isDownloadCompleted) {
      this.showDownloadBtn = true;
    }
  }


  navigateToDetailsPage(content: any, depth, corRelationData?) {
    const corRelationList = [...this.corRelationList];
    if (corRelationData) {
      corRelationList.push(corRelationData);
    }
    this.zone.run(() => {
      switch (ContentUtil.isTrackable(content)) {
        case 1:
        case 0:
          this.navService.navigateToTrackableCollection({
            content,
            depth,
            contentState: this.stateData,
            corRelation: corRelationList
          });
          break;
        case -1:
          this.navService.navigateToContent({
            isChildContent: true,
            content,
            depth,
            contentState: this.stateData,
            corRelation: corRelationList,
            breadCrumb: this.breadCrumb
          });
      }
    });
  }

  /**
   * Reset all values
   */
  resetVariables() {
    this.isDownloadStarted = false;
    this.showLoading = false;
    this.refreshHeader();
    this.downloadProgress = 0;
    this.cardData = '';
    this.contentDetail = undefined;
    this.showDownload = false;
    this.showDownloadBtn = false;
    this.downloadIdentifiers = new Set();
    this.queuedIdentifiers = [];
    this.isDownloadCompleted = false;
    this.currentCount = 0;
    this.downloadPercentage = 0;
    this.isUpdateAvailable = false;
  }

  /**
   * Subscribe Sunbird-SDK event to get content download progress
   */
  subscribeSdkEvent() {
    this.eventSubscription = this.eventBusService.events().subscribe((event: EventsBusEvent) => {
      this.zone.run(() => {
        if (event.type === DownloadEventType.PROGRESS) {
          const downloadEvent = event as DownloadProgress;

          if (downloadEvent.payload.identifier === this.contentDetail.identifier) {
            this.downloadProgress = downloadEvent.payload.progress === -1 ? 0 : downloadEvent.payload.progress;
            if (this.downloadProgress === 100) {
              this.showLoading = false;
              this.refreshHeader();
              this.contentDetail.isAvailableLocally = true;
            }
          }
        }

        if (event.payload && event.type === ContentEventType.SERVER_CONTENT_DATA) {
          this.licenseDetails = event.payload.licenseDetails;
        }

        // Get child content
        if (event.type === ContentEventType.CONTENT_EXTRACT_COMPLETED) {
          const contentImportedEvent = event as ContentImportCompleted;

          if (this.queuedIdentifiers.length && this.isDownloadStarted) {
            if (this.queuedIdentifiers.includes(contentImportedEvent.payload.contentId)) {
              this.currentCount++;
              this.downloadPercentage = +((this.currentCount / this.queuedIdentifiers.length) * (100)).toFixed(0);
            }
            if (this.queuedIdentifiers.length === this.currentCount) {
              this.showLoading = false;
              this.refreshHeader();
              this.isDownloadStarted = false;
              this.showDownloadBtn = false;
              this.isDownloadCompleted = true;
              this.showDownload = false;
              if (this.contentDetail) {
                this.contentDetail.isAvailableLocally = true;
              }
              this.downloadPercentage = 0;
              this.updateSavedResources();
              this.setChildContents();
            }
          } else if (this.parentContent && contentImportedEvent.payload.contentId === this.contentDetail.identifier) {
            // this condition is for when the child content update is available and we have downloaded parent content
            // but we have to refresh only the child content.
            this.showLoading = false;
            this.refreshHeader();
            this.setContentDetails(this.identifier, false);
          } else {
            if (this.isUpdateAvailable && contentImportedEvent.payload.contentId === this.contentDetail.identifier) {
              this.showLoading = false;
              this.refreshHeader();
              this.setContentDetails(this.identifier, false);
            } else {
              if (contentImportedEvent.payload.contentId === this.contentDetail.identifier) {
                this.showLoading = false;
                this.refreshHeader();
                this.updateSavedResources();
                this.setChildContents();
                this.contentDetail.isAvailableLocally = true;
              }

            }
          }
        }

        if (event.type === ContentEventType.IMPORT_PROGRESS) {
          const totalCountMsg = Math.floor((event.payload.currentCount / event.payload.totalCount) * 100) +
            '% (' + event.payload.currentCount + ' / ' + event.payload.totalCount + ')';
          this.importProgressMessage = this.commonUtilService.translateMessage('EXTRACTING_CONTENT', totalCountMsg);
          if (event.payload.currentCount === event.payload.totalCount) {
            let timer = 30;
            const interval = setInterval(() => {
              this.importProgressMessage = `Getting things ready in ${timer--}  seconds`;
              if (timer === 0) {
                this.importProgressMessage = 'Getting things ready';
                clearInterval(interval);
              }
            }, 1000);
          }
        }

        // For content update available
        const hierarchyInfo = this.cardData.hierarchyInfo ? this.cardData.hierarchyInfo : null;
        const contentUpdateEvent = event as ContentUpdate;
        if (contentUpdateEvent.type === ContentEventType.UPDATE && hierarchyInfo === null) {
          this.zone.run(() => {
            if (this.parentContent) {
              const parentIdentifier = this.parentContent.contentId || this.parentContent.identifier;
              this.showLoading = true;
              this.telemetryGeneratorService.generateSpineLoadingTelemetry(this.contentDetail, false);
              this.importContent([parentIdentifier], false);
            } else {
              this.setContentDetails(this.identifier, false);
            }
          });
        }
      });
    }) as any;
  }

  updateSavedResources() {
    this.events.publish('savedResources:update', {
      update: true
    });
  }

  async share() {
    const popover = await this.popoverCtrl.create({
      component: SbSharePopupComponent,
      componentProps: {
        content: this.contentDetail,
        corRelationList: this.corRelationList,
        objRollup: this.objRollup,
        pageId: this.pageId,
        shareItemType: ShareItemType.ROOT_COLECTION
      },
      cssClass: 'sb-popover',
    });
    await popover.present();
  }

  /**
   * Download single content
   */
  downloadAllContent(): void {
    this.downloadProgress = 0;
    this.showLoading = true;
    this.isDownloadStarted = true;
    this.downloadPercentage = 0;
    this.showDownload = true;
    this.showCollapsedPopup = false;
    this.importContent(Array.from(this.downloadIdentifiers), true, true);
  }

  generateImpressionEvent(objectId, objectType, objectVersion) {
    this.telemetryGeneratorService.generateImpressionTelemetry(
      ImpressionType.DETAIL, '',
      PageId.COLLECTION_DETAIL,
      Environment.HOME,
      objectId,
      objectType,
      objectVersion,
      this.objRollup,
      this.corRelationList);
    this.telemetryGeneratorService.generateImpressionTelemetry(
      ImpressionType.DETAIL, '',
      this.pageId,
      Environment.HOME,
      objectId,
      objectType,
      objectVersion,
      this.objRollup,
      this.corRelationList);
  }

  generateStartEvent(objectId, objectType, objectVersion) {
    const telemetryObject = new TelemetryObject(objectId, objectType, objectVersion);
    this.telemetryGeneratorService.generateStartTelemetry(
      PageId.COLLECTION_DETAIL,
      telemetryObject,
      this.objRollup,
      this.corRelationList);
      this.telemetryGeneratorService.generateStartTelemetry(
        this.pageId,
        telemetryObject,
        this.objRollup,
        this.corRelationList);
  }

  generateEndEvent(objectId, objectType, objectVersion) {
    const telemetryObject = new TelemetryObject(objectId, objectType, objectVersion);
    this.telemetryGeneratorService.generateEndTelemetry(
      objectType ? objectType : CsPrimaryCategory.DIGITAL_TEXTBOOK,
      Mode.PLAY,
      PageId.COLLECTION_DETAIL,
      Environment.HOME,
      telemetryObject,
      this.objRollup,
      this.corRelationList);
      this.telemetryGeneratorService.generateEndTelemetry(
        objectType ? objectType : CsPrimaryCategory.DIGITAL_TEXTBOOK,
        Mode.PLAY,
        this.pageId,
        Environment.HOME,
        telemetryObject,
        this.objRollup,
        this.corRelationList);
  }

  generateQRSessionEndEvent(pageId: string, qrData: string) {
    if (pageId !== undefined) {
      const telemetryObject = new TelemetryObject(qrData, 'qr', '');
      this.telemetryGeneratorService.generateEndTelemetry(
        'qr',
        Mode.PLAY,
        pageId,
        Environment.HOME,
        telemetryObject,
        undefined,
        this.corRelationList);

    }
  }

  async showDownloadConfirmationAlert() {
    this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
      InteractSubtype.DOWNLOAD_CLICKED,
      Environment.HOME,
      PageId.COLLECTION_DETAIL,
      this.telemetryObject,
      undefined,
      this.objRollup,
      this.corRelationList);
      this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
        InteractSubtype.DOWNLOAD_CLICKED,
        Environment.HOME,
        this.pageId,
        this.telemetryObject,
        undefined,
        this.objRollup,
        this.corRelationList);
    if (this.commonUtilService.networkInfo.isNetworkAvailable) {
      const contentTypeCount = this.downloadIdentifiers.size ? this.downloadIdentifiers.size : '';
      const popover = await this.popoverCtrl.create({
        component: ConfirmAlertComponent,
        componentProps: {
          sbPopoverHeading: this.commonUtilService.translateMessage('DOWNLOAD'),
          sbPopoverMainTitle: this.contentDetail.contentData.name,
          actionsButtons: [
            {
              btntext: this.commonUtilService.translateMessage('DOWNLOAD'),
              btnClass: 'popover-color'
            },
          ],
          icon: null,
          metaInfo: this.commonUtilService.translateMessage('ITEMS', contentTypeCount)
            + ' (' + this.fileSizePipe.transform(this.downloadSize, 2) + ')',
        },
        cssClass: 'sb-popover info',
      });
      await popover.present();
      this.telemetryGeneratorService.generateImpressionTelemetry(ImpressionType.VIEW, '',
        PageId.DOWNLOAD_ALL_CONFIRMATION_POPUP,
        Environment.HOME,
        this.contentDetail.identifier,
        this.contentDetail.contentData.contentType,
        this.contentDetail.contentData.pkgVersion,
        this.objRollup,
        this.corRelationList);

      const response = await popover.onDidDismiss();
      if (response && response.data) {
        this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
          InteractSubtype.DOWNLOAD_ALL_CLICKED,
          Environment.HOME,
          PageId.COLLECTION_DETAIL,
          this.telemetryObject,
          undefined,
          this.objRollup,
          this.corRelationList);
          this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
            InteractSubtype.DOWNLOAD_ALL_CLICKED,
            Environment.HOME,
            this.pageId,
            this.telemetryObject,
            undefined,
            this.objRollup,
            this.corRelationList);
        this.downloadAllContent();
        this.events.publish('header:decreasezIndex');
      } else {
        this.generateCancelDownloadTelemetry();
      }
    } else {
      this.commonUtilService.showToast('ERROR_NO_INTERNET_MESSAGE');
    }
  }

  mergeProperties(mergeProp) {
    return ContentUtil.mergeProperties(this.contentDetail.contentData, mergeProp);
  }

  cancelDownload() {
    this.telemetryGeneratorService.generateCancelDownloadTelemetry(this.contentDetail);
    this.contentService.cancelDownload(this.identifier).toPromise().finally(() => {
      this.zone.run(() => {
        this.showLoading = false;
        this.refreshHeader();
        this.location.back();
      });
    });
  }

  generateCancelDownloadTelemetry() {
    const values = new Map();
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.CLOSE_CLICKED,
      Environment.HOME,
      PageId.COLLECTION_DETAIL,
      this.telemetryObject,
      values, this.objRollup,
      this.corRelationList);
      this.telemetryGeneratorService.generateInteractTelemetry(
        InteractType.TOUCH,
        InteractSubtype.CLOSE_CLICKED,
        Environment.HOME,
        this.pageId,
        this.telemetryObject,
        values, this.objRollup,
        this.corRelationList);
  }

  /**
   * Ionic life cycle hook
   */
  ionViewWillLeave() {
    this.downloadProgress = 0;
    this.headerObservable.unsubscribe();
    this.events.unsubscribe(EventTopics.CONTENT_TO_PLAY);
    this.events.publish('header:setzIndexToNormal');
    if (this.eventSubscription) {
      this.eventSubscription.unsubscribe();
    }
    if (this.backButtonFunc) {
      this.backButtonFunc.unsubscribe();
    }
    this.events.unsubscribe(EventTopics.DEEPLINK_COLLECTION_PAGE_OPEN);
  }
  async showDeletePopOver() {
    this.contentDeleteObservable = this.contentDeleteHandler.contentDeleteCompleted$.subscribe(() => {
      this.location.back();
    });

    const contentInfo: ContentInfo = {
      telemetryObject: this.telemetryObject,
      rollUp: this.objRollup,
      correlationList: this.corRelationList,
      hierachyInfo: undefined,
    };
    this.contentDeleteHandler.showContentDeletePopup(this.contentDetail, this.isChild, contentInfo, this.pageId);
  }

  refreshHeader() {
    this.headerConfig = this.headerService.getDefaultPageConfig();
    this.headerConfig.actionButtons = ['download'];
    this.headerConfig.showBurgerMenu = false;
    this.headerConfig.showHeader = true;
    this.headerService.updatePageConfig(this.headerConfig);
    this.events.publish('header:setzIndexToNormal');
  }

  handleHeaderEvents($event) {
    switch ($event.name) {
      case 'back':
        this.telemetryGeneratorService.generateBackClickedTelemetry(PageId.COLLECTION_DETAIL, Environment.HOME,
          true, this.cardData.identifier, this.corRelationList);
          this.telemetryGeneratorService.generateBackClickedTelemetry(this.pageId, Environment.HOME,
            true, this.cardData.identifier, this.corRelationList);
        this.handleBackButton();
        break;
      case 'download':
        this.redirectToActivedownloads();
        break;
    }
  }

  private redirectToActivedownloads() {
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.ACTIVE_DOWNLOADS_CLICKED,
      Environment.HOME,
      PageId.COLLECTION_DETAIL,
      this.telemetryObject,
      undefined, this.objRollup,
      this.corRelationList);
      this.telemetryGeneratorService.generateInteractTelemetry(
        InteractType.TOUCH,
        InteractSubtype.ACTIVE_DOWNLOADS_CLICKED,
        Environment.HOME,
        this.pageId,
        this.telemetryObject,
        undefined, this.objRollup,
        this.corRelationList);
    this.router.navigate([RouterLinks.ACTIVE_DOWNLOADS]);
  }

  async onFilterMimeTypeChange(val, idx, currentFilter?) {  
    this.activeMimeTypeFilter = val;
    this.currentFilter = this.commonUtilService.translateMessage(currentFilter);
    this.mimeTypes.forEach((type) => {
      type.selected = false;
    });
    this.mimeTypes[idx].selected = true;
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.FILTER_CLICKED,
      Environment.HOME,
      PageId.COLLECTION_DETAIL,
      this.telemetryObject,
      undefined,
      this.objRollup,
      this.corRelationList);
      this.telemetryGeneratorService.generateInteractTelemetry(
        InteractType.TOUCH,
        InteractSubtype.FILTER_CLICKED,
        Environment.HOME,
        this.pageId,
        this.telemetryObject,
        undefined,
        this.objRollup,
        this.corRelationList);
  }

  openTextbookToc() {
    this.hiddenGroups.clear();
    this.shownGroups = undefined;
    this.navService.navigateTo([`/${RouterLinks.COLLECTION_DETAIL_ETB}/${RouterLinks.TEXTBOOK_TOC}`],
      { childrenData: this.childrenData, parentId: this.identifier });
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.DROPDOWN_CLICKED,
      Environment.HOME,
      PageId.COLLECTION_DETAIL,
      this.telemetryObject,
      undefined,
      this.objRollup,
      this.corRelationList
    );
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.DROPDOWN_CLICKED,
      Environment.HOME,
      this.pageId,
      this.telemetryObject,
      undefined,
      this.objRollup,
      this.corRelationList
    );
  }

  onScroll(event) {
    if (event.detail.scrollTop >= 205) {
      (this.stickyPillsRef.nativeElement as HTMLDivElement).classList.add('sticky');

      const boxes: HTMLElement[] = Array.from(document.getElementsByClassName('sticky-header-title-box')) as HTMLElement[];

      let headerBottomOffset = (this.stickyPillsRef.nativeElement as HTMLDivElement).getBoundingClientRect().bottom;

      if (this.previousHeaderBottomOffset && this.previousHeaderBottomOffset > headerBottomOffset) {
        headerBottomOffset = this.previousHeaderBottomOffset;
      }

      this.previousHeaderBottomOffset = headerBottomOffset;

      const boxesData = boxes.map(b => {
        return {
          elem: b,
          text: b.dataset['text'],
          renderLevel: parseInt(b.dataset['renderLevel'], 10),
          offsetTop: b.getBoundingClientRect().top
        };
      });

      const activeBoxes = boxesData.filter(data => {
        return data.offsetTop < headerBottomOffset
          && (data.offsetTop + data.elem.getBoundingClientRect().height) > headerBottomOffset;
      });

      if (!activeBoxes.length) {
        return;
      }

      const activeBox = activeBoxes.reduce((acc, box) => {
        if (acc.renderLevel > box.renderLevel) {
          return acc;
        } else {
          return box;
        }
      }, activeBoxes[0]);

      if (activeBox.text) {
        this.stckyUnitTitle = activeBox.text;
      }
      return;
    }

    (this.stickyPillsRef.nativeElement as HTMLDivElement).classList.remove('sticky');
  }

  importContentInBackground(identifiers: Array<string>, isChild: boolean) {
    if (this.showLoading && !this.isDownloadStarted) {
      this.headerService.hideHeader();
    }
    const option: ContentImportRequest = {
      contentImportArray: this.getImportContentRequestBody(identifiers, isChild),
      contentStatusArray: ['Live'],
      fields: ['appIcon', 'name', 'subject', 'size', 'gradeLevel'],
    };
    // Call content service
    this.contentService.importContent(option).toPromise()
      .then((data: ContentImportResponse[]) => {
        this.zone.run(() => {
          if (data && data.length && this.isDownloadStarted) {
            data.forEach((value) => {
              if (value.status === ContentImportStatus.ENQUEUED_FOR_DOWNLOAD) {
                this.queuedIdentifiers.push(value.identifier);
              } else if (value.status === ContentImportStatus.NOT_FOUND) {
                this.faultyIdentifiers.push(value.identifier);
              }
            });

            if (this.faultyIdentifiers.length > 0) {
              const stackTrace: any = {};
              stackTrace.parentIdentifier = this.cardData.identifier;
              stackTrace.faultyIdentifiers = this.faultyIdentifiers;
              this.telemetryGeneratorService.generateErrorTelemetry(Environment.HOME,
                TelemetryErrorCode.ERR_DOWNLOAD_FAILED,
                ErrorType.SYSTEM,
                PageId.COLLECTION_DETAIL,
                JSON.stringify(stackTrace),
              );
              this.telemetryGeneratorService.generateErrorTelemetry(Environment.HOME,
                TelemetryErrorCode.ERR_DOWNLOAD_FAILED,
                ErrorType.SYSTEM,
                this.pageId,
                JSON.stringify(stackTrace),
              );
            }
          } else if (data && data[0].status === ContentImportStatus.NOT_FOUND) {
            this.showLoading = false;
            this.showChildrenLoader = false;
            this.childrenData.length = 0;
          }
        });
      })
      .catch((error: any) => {
        this.zone.run(() => {
          this.showDownloadBtn = true;
          this.isDownloadStarted = false;
          this.showLoading = false;
          if (error && (error.error === 'NETWORK_ERROR' || error.error === 'CONNECTION_ERROR')) {
            this.commonUtilService.showToast('NEED_INTERNET_TO_CHANGE');
          } else {
            this.commonUtilService.showToast('UNABLE_TO_FETCH_CONTENT');
          }
          this.showChildrenLoader = false;
          this.location.back();
        });
      });
  }

  playContent(event, corRelationData?) {
    const corRelationList = [...this.corRelationList];
    if (corRelationData) {
      corRelationList.push(corRelationData);
    }

    const telemetryDetails = {
      pageId: this.pageId,
      corRelationList
    };

    const navExtras = {
      state: {
        isChildContent: true,
        content: event.content,
        depth: 1,
        contentState: this.stateData,
        corRelation: corRelationList,
        breadCrumb: this.breadCrumb
      }
    };

    this.contentPlayerHandler.playContent(event.content, navExtras, telemetryDetails, false);

  }

  tocCardClick(event) {
    if (!(event.event instanceof Event)) {
      return;
    }

    const corRelationData = {
      id: (event && event.rollup[0]) || '',
      type: CorReleationDataType.ROOT_ID
    };

    this.setActiveContentData(event, InteractSubtype.CONTENT_CLICKED, corRelationData);

    this.navigateToDetailsPage(event.data, 1, corRelationData);
  }

  playButtonClick(event) {
    const corRelationData = {
      id: (event && event.rollup[0]) || '',
      type: CorReleationDataType.ROOT_ID
    };

    this.setActiveContentData(event, InteractSubtype.PLAY_CLICKED, corRelationData);

    this.playContent({ content: event.data }, corRelationData);
  }

  private setActiveContentData(event, telemetrySubType, corRelationData) {
    this.activeContent = event.data;
    this.textbookTocService.setTextbookIds({ contentId: event.data.identifier, rootUnitId: undefined });

    const corRelationList = [...this.corRelationList];
    if (corRelationData) {
      corRelationList.push(corRelationData);
    }
    const values = {
      contentClicked: event.data && event.data.identifier
    };

    const telemetryObj = ContentUtil.getTelemetryObject(event.data);

    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      telemetrySubType,
      Environment.HOME,
      PageId.TEXTBOOK_TOC, telemetryObj,
      values,
      this.objRollup, corRelationList
    );
  }

  contentInfo() {
    this.showContentDetails = !this.showContentDetails;
  }
}
<ion-content class="ion-no-padding" [scrollEvents]="true" (ionScroll)="onScroll($event)">
  <div class="content-padding">
    <app-detail-card 
    (downloadAllContent)="showDownloadConfirmationAlert()" 
    (shareEvent)="share()"  
    (showOverflowMenuEvent)="showDeletePopOver()" 
    [contentDetail]="contentDetail" 
    [localImage]="contentDetail?.contentData?.appIcon" 
    [showDownloadBtn]="showDownloadBtn"
    [isDepthChild]='isDepthChild' 
    [defaultAppIcon]="defaultAppIcon"
    [trackDownloads]="trackDownloads$">
    </app-detail-card>
    <!-- End of the Parent Card -->

    <!-- End import content -->
    <div class="m-n" *ngIf="showSheenAnimation">
      <div class="skeleton-search-card" *ngFor="let i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13]">
        <div style=" flex: 22 auto;">
          <app-skeleton-item height="60px" width="100%" style="height:3.75rem; width:100%; margin-bottom: 10px;">
          </app-skeleton-item>
        </div>
      </div>
    </div>
    <div #stickyPillsRef *ngIf="!showSheenAnimation && childrenData && childrenData?.length"
      class="collection-etb-filter">
      <div class="sb-chapter-dd pl-16" role="button" (click)="openTextbookToc()">
        <span class="pull-left">{{stckyUnitTitle || ('SELECT_CHAPTER' | translate)}}</span>
        <!-- set aria hidden true because in device the icon is not showing and talkback is speak that text -->
        <span class="pull-right" aria-hidden="true">
          <ion-icon md="caret-forward-circle" ios="chevron-forward-circle"></ion-icon>
        </span>
      </div>
      <div class="sb-slider-pills-container">
        <div class="sb-pills-container sb-grade-pills-container" id="gradeScroll">
          <div role="button" class="pill" *ngFor="let type of mimeTypes; let i = index; let first = first"
            [ngClass]="{'active': type?.selected, '': !type?.selected}" attr.id="class{{i}}" [attr.aria-selected]="type?.selected"
            (click)="onFilterMimeTypeChange(type.value, i, type.name);">
            <span class="img-align" *ngIf="type?.iconNormal && type?.selected">
              <img aria-hidden="true" class="filter-icon" src="{{type?.iconActive}}" alt="video">
            </span>
            <span class="img-align" *ngIf="type?.iconNormal && !type?.selected">
              <img aria-hidden="true" class="filter-icon" src="{{type?.iconNormal}}" alt="interactive">
            </span>
            <span  class="allign-middle" attr.aria-label="{{type?.name | translate}}">{{type?.name | translate}}</span>
          </div>
        </div>
      </div>
    </div>

  </div>
  <div *ngIf="shouldPillsStick" style="height: 3rem;"></div>
  <div>
    <!-- Looping Inside Children Data Textbook -->
    <section *ngIf="!showSheenAnimation && childrenData" class="textbook-accordian">
      <sb-toc-item
      [accordianConfig]="accordianConfig"
      [type]="TocCardType.TRACKABLE"
      [tocData]="collectionTocData"
      [playBtnConfig]="playBtnConfig"
      (tocCardClick)="tocCardClick($event)"
      [activeMimeTypeFilter]="activeMimeTypeFilter"
      [activeContent]="activeContent"
      (playButtonClick)="playButtonClick($event)"
      [trackableDefaultImage]="'assets/imgs/ic_courses_selected_joyful.svg'">
    </sb-toc-item>

    </section>
  </div>
  <div *ngIf="contentDetail?.contentData?.author || contentDetail?.contentData?.organisation 
        ||contentDetail?.contentData?.license || licenseDetails || contentDetail?.contentData?.copyright">
    <div class="m-8">
      <div class="collection-etb-details">
        <div class="title" (click)="contentInfo()">
          <strong class="pull-left">{{'DETAILS' | translate}}</strong>
          <span class="pull-right">
            <ion-icon md="caret-forward-circle" ios="chevron-forward-circle"></ion-icon>
          </span>
        </div>
        <div *ngIf="content && showContentDetails">
          <app-relevant-content-card 
            [contentData]="contentDetail?.contentData" 
            [isAlreadyEnrolled]="isAlreadyEnrolled">
          </app-relevant-content-card>
        </div>
      </div>
      <app-license-card-component 
        [content]="contentDetail?.contentData" 
        [licenseDetails]="licenseDetails" 
        [appName]="appName"
        [objRollup]="objRollup" 
        [corRelationList]="corRelationList" 
        [pageId]="pageId">
      </app-license-card-component>
    </div>
  </div>
</ion-content>

<div>
  <add-activity-to-group [pageId]="pageId" [identifier]="identifier"></add-activity-to-group>
</div>

<ng-container *ngIf="trackDownloads$ | async; let downloads">
  <app-sb-download-popup *ngIf="downloads.queued.length"
    (cancelDownloadEmit)="cancelDownload($event)" 
    [currentCount]="downloads.completed.length"
    [queuedIdentifiers]="(downloads.queued.length+downloads.completed.length)" 
    [downloadSize]="downloadSize"
    [collectionName]="contentDetail?.contentData?.name" 
    [showDownload]="true"
    [showPopover]="showCollapsedPopup">
  </app-sb-download-popup>
</ng-container>

./collection-detail-etb.page.scss

@import "src/assets/styles/base/_variables.scss";
@import "src/assets/styles/_custom-mixins.scss";
@import "src/assets/styles/_variables.scss";

// :host {
.sb-slider-pills-container {
  .sb-grade-pills-container {
    .pill {
      min-height: 2.188rem;
      border-radius: 50px;
    }
  }
}

.heading {
  margin-top: 50px;
  font-size: $font-size-base;
  font-weight: bold;
  line-height: 1.188rem;
  text-align: center;
  color: map-get($colors, granite_gray);
}

.sub-heading {
  color: map-get($colors, granite_gray);
  font-size: 0.75rem;
  line-height: 1.063rem;
  text-align: center;
}

.filter-icon {
  // margin-right: 8px;
  height: 0.938rem;
  width: 0.938rem;
}

.img-align {
  margin-top: 5px;
  display: inline-block;
  vertical-align: middle;
  width: 0.938rem;
  margin-right: 8px;
}

.allign-middle {
  display: inline-block;
  vertical-align: middle;
}

.collection-etb-filter {
  &.sticky {
    position: sticky;
    top: 0;
    left: 0;
    z-index: 10;
  }
}

.loading-backdrop {
  .backdrop-container {
    width: 100%;
    padding: 16px;
    text-align: center;
    position: absolute;
    top: 50%;
    margin-top: -50px;
  }

  .backdrop-footer {
    position: absolute;
    width: 100%;
    bottom: 0;
    padding-bottom: 16px;
  }

  background-color: map-get($colors, white);
  height: 100%;
  z-index: 1000;
  opacity: 1 !important;
}

ion-card {
  display: flex;
  flex-direction: column;
  width: 100% !important;
  box-shadow: 0 3px 5px 4px rgba(0, 0, 0, 0.05);
  margin: 1px;
}

ion-card .card .card-md {
  margin: 0;
}

.M0 {
  margin: 0 !important;
}

.P15 {
  padding: 15px !important;
}

.M5 {
  margin: 5px;
}

.P5 {
  padding: 5px;
}

.MT20 {
  margin-top: 20px;
}

.MT10 {
  margin-top: 10px;
}

.MB16 {
  margin-bottom: 16px;
}

.MR5 {
  margin-right: 5px;
}

.ML5 {
  margin-left: 5px;
}

.ML10 {
  margin-left: 10px;
}

.MLR0 {
  margin-left: 0 !important;
  margin-right: 0 !important;
}

.ML20 {
  margin-left: 20px;
}

.P10 {
  padding: 10px;
}

.secondChildren {
  margin-left: 15px;
}

.thirdChildren {
  margin-left: 25px;
}

.margin-10 {
  margin-left: 10px;
}

.f24 {
  font-size: 1.5rem;
}

.yellow-gold {
  color: map-get($colors, bright_yellow);
}

.font-blue {
  color: $blue;
  font-size: 1.875rem;
}

.text-selected {
  padding: 4px;
  color: $blue;
  font-weight: bolder;
}

.text-unselected {
  padding: 4px;
  color: map-get($colors, bright_blue);
}

.play-icon {
  color: map-get($colors, vivid_green);
  font-size: 1.875rem;
}

.font-14 {
  font-size: $font-size-base !important;
}

.view-credits {
  span {
    color: $blue;

    ion-icon {
      padding: 0 0 4px 8px;
      vertical-align: middle;
      font-size: 1.125rem;
      float: right !important;
    }
  }

}

.credit-label-padding {
  padding: 14px 14px 8px 14px;
  background-color: map-get($colors, white_f2);
}

.content-padding {
  padding: 8px 8px 0 8px;
}

.subtitle-color {
  color: map-get($colors, granite_gray);
}

.label-margin-bottom {
  margin-bottom: 3px !important;
}

.traning-derived-label-background {
  background-color: map-get($colors, white_f2);
  padding: 8px 0px 8px 15px;
}

.font-12 {
  font-size: 0.75rem !important;
}

.showLicensce {
  p {
    margin-bottom: 16px;
  }
}

.grey-icon-span {
  position: relative;
  top: 0.5rem;
  vertical-align: super;
}

.checkmark-icon {
  color: map-get($colors, vivid_green);
  font-size: 1.125rem;
  margin-left: 5px;
}

.font-blue-text {
  padding: 4px;
  color: $blue;
}

.font-grey-text {
  //  padding: 4px;
  color: map-get($colors, dark_gray);
}

.grey-icon {
  color: map-get($colors, dark_gray);
  font-size: ($font-size-base + 0.25);
}

.horizontal-scroll {
  display: flex;
  overflow-x: auto;
}

.separator-dot {
  width: 0.25rem;
  height: 0.25rem;
  background-color: map-get($colors, light_silver);
  border-radius: 50%;
  display: inline-block;
  vertical-align: middle;
}

.separator-line {
  height: 0.063rem;
  opacity: 0.36;
  background-color: map-get($colors, dark_gray);
  width: 100%;
}

.white {
  color: map-get($colors, white);
}

.light-black {
  color: map-get($colors, light_black_51);
}

.bg-white {
  background-color: map-get($colors, white);
}

.bg-sucess {
  background-color: $green;
}

.bg-primary {
  background-color: $blue;
}

.bg-danger {
  background-color: $orange;
}

.bg-dark-danger {
  background-color: $red;
}

.danger {
  color: $orange;
}

//  Details card
.details-card {
  border-radius: 2px;
  box-shadow: 0 3px 5px 4px rgba(0, 0, 0, 0.05);
  background-color: map-get($colors, white);

  .content-unit {
    display: grid;
    //grid-gap: 13px;
    grid-template-columns: 3fr .4fr;

    .pull-right {
      overflow: hidden;
      display: grid;
      grid-template-columns: 1fr;
      margin-right: 5px;
      padding: 10px;
      font-size: 2rem;

      .item {
        flex: 1 1 auto;
        justify-content: right;
        align-items: center;
        display: flex;
      }
    }

    .left {
      overflow: hidden;
      grid-template-columns: 1fr;
      display: flex;
      flex-direction: column;
      @include padding(15px, 0, 15px, 15px);

      .item {
        flex: 1 1 auto;
        justify-content: left;
        align-items: center;
        display: flex;
      }
    }
  }

  .W-88 {
    width: 5.5rem;
  }

  .rating {
    display: flex;
    justify-content: flex-end;
    align-items: end;
  }

  .content {
    display: grid;
    //grid-gap: 13px;
    grid-template-columns: 2.9fr 1fr;

    .pull-right {
      overflow: hidden;
      display: grid;
      grid-template-columns: 1fr;
      margin-right: 5px;
      padding: 10px;
      font-size: 2rem;
    }

    .right {
      overflow: hidden;
      display: grid;
      grid-template-columns: 1fr;
      padding: 15px;

      //grid-template-rows: 1fr;
      .img-container {
        // background-color: grey;
        width: 100%;
        min-height: 3.375rem;
        max-height: 3.375rem;
      }
    }

    .left {
      overflow: hidden;
      grid-template-columns: 1fr;
      display: flex;
      flex-direction: column;
      @include padding(15px, 0, 15px, 15px);

      .item {
        flex: 1 1 auto;
        justify-content: left;
        align-items: center;
        display: flex;
      }

      .title {
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        margin: 0 0 3px;
        padding: 0;
        font-weight: 500;
        font-style: normal;
        font-stretch: normal;
        line-height: normal;
        letter-spacing: -0.4px;
        color: map-get($colors, primary_black);
        height: 2.625rem;
      }

      .info {
        font-size: 0.75rem;
        font-weight: 500;
        font-style: normal;
        font-stretch: normal;
        line-height: normal;
        letter-spacing: -0.4px;
        color: map-get($colors, dark_gray);
      }
    }

    &.single-column {
      display: grid;
      grid-template-columns: 1fr;

      .left {
        @include padding(15px);
      }

      .tag {
        border-radius: 2px;
        @include padding(3px, 7px);
        color: map-get($colors, light-blue);
        font-size: 0.625rem;
        font-weight: normal;
        font-style: normal;
        font-stretch: normal;
        line-height: 1.1;
        letter-spacing: -0.4px;
        border: 1px solid map-get($colors, light-blue);
        display: inline-flex;

        &:not(:last-child) {
          @include margin(null, 10px, null, null);
        }
      }
    }

  }

  .btn-caption-container {
    display: inline-grid;
    grid-template-columns: 1fr;
    @include margin(null, 20px, null, null);

    &:last-child {
      @include margin(null, 0, null, null);
    }

    .btn-caption {
      color: map-get($colors, secondary-light);
      text-transform: capitalize;
      font-weight: 500;
      font-style: normal;
      font-stretch: normal;
      line-height: normal;
      letter-spacing: -0.3px;
      display: inline-block;
      text-align: center;
    }

    .action-btn {
      height: auto;

      ion-icon {
        line-height: 1.88rem;

      }

    }
  }
}

.scroll-content {
  padding-bottom: 20% !important;
}

.sb-row {
  width: 100%;
}

.sb-topics-containe {
  padding-right: 5%;
}

.sb-hidden-content {
  background-color: map-get($colors, white_f2);
  height: 34.15%;
  width: 100%;
  border-radius: 0 0 2px 2px;
  padding-top: 2%;
  padding-bottom: 5%;
}

.sb-accordian-card {
  height: 6.1%;
  width: 100%;
  border-radius: 2px;
  background-color: map-get($colors, white);
  box-shadow: 0 4px 7px 0 rgba(0, 0, 0, 0.1);
}

.sb-topic-text {
  &.sb-topic-text {
    padding-top: 5px;
  }

  height: 2.44%;
  width: 80%;
  color: $blue;
  font-size: $font-size-base;
  line-height: 1.25rem;
}

.box-align {
  // margin-right: 18px;
}

// }


.sb-chapter-dd {
  @include clearfix;
  color: $blue;
  padding: $base-block-space;
  background-color: map-get($colors, white);

  .pull-left {
    line-height: 1.88rem;
  }

  ion-icon {
    height: 1.5rem;
    width: 1.5rem;
    border-radius: 12px;
    font-size: 1.75rem;
    color: map-get($colors, light-blue);
  }
}

.sb-topics-container-toc {
  .sb-topic-item {
    color: $primary-color;
    padding: 8px;
  }

  .sb-ftue-design {
    .pull-right {
      display: none;
    }

    .unit-hierachy {
      color: $primary-color;
      padding: 8px;
    }
  }

  .sb-chapter-dd {
    border-bottom: 1px solid $gray-100;
  }

  .sb-collection-child-ftue {
    margin-left: 8px;
  }
}

.drop-arrow{
  border-radius: 50%;
  background-color: map-get($colors, white);
  height: 1.5rem;
  width: 1.5rem;
  padding-top: 8px;
  img{
    height: 0.5rem;
  }
}

.collection-etb-details{
  border-radius: 1rem;
  background-color: var(--app-white);
  margin-bottom: 1rem;
  padding: 0 0 1rem;
  box-shadow: var(--button-style-shadow) !important;
  .title{
    color: var(--app-primary);
    padding: 1rem;
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""