File

src/app/modules/public/module/explore/components/explore-content/explore-content.component.ts

Implements

OnInit OnDestroy AfterViewInit

Metadata

Index

Properties
Methods

Constructor

constructor(searchService: SearchService, router: Router, activatedRoute: ActivatedRoute, paginationService: PaginationService, resourceService: ResourceService, toasterService: ToasterService, configService: ConfigService, utilService: UtilService, orgDetailsService: OrgDetailsService, navigationHelperService: NavigationHelperService, publicPlayerService: PublicPlayerService, userService: UserService, frameworkService: FrameworkService, cacheService: CacheService, navigationhelperService: NavigationHelperService, layoutService: LayoutService, contentManagerService: ContentManagerService, offlineCardService: OfflineCardService, telemetryService: TelemetryService, schemaService: SchemaService)
Parameters :
Name Type Optional
searchService SearchService No
router Router No
activatedRoute ActivatedRoute No
paginationService PaginationService No
resourceService ResourceService No
toasterService ToasterService No
configService ConfigService No
utilService UtilService No
orgDetailsService OrgDetailsService No
navigationHelperService NavigationHelperService No
publicPlayerService PublicPlayerService No
userService UserService No
frameworkService FrameworkService No
cacheService CacheService No
navigationhelperService NavigationHelperService No
layoutService LayoutService No
contentManagerService ContentManagerService No
offlineCardService OfflineCardService No
telemetryService TelemetryService No
schemaService SchemaService No

Methods

addHoverData
addHoverData()
Returns : void
callDownload
callDownload()
Returns : void
checkForBack
checkForBack()
Returns : void
downloadContent
downloadContent(contentId)
Parameters :
Name Optional
contentId No
Returns : void
Private fetchContentOnParamChange
fetchContentOnParamChange()
Returns : void
Private fetchContents
fetchContents()
Returns : void
Public getFilters
getFilters(filters)
Parameters :
Name Optional
filters No
Returns : void
getInteractEdata
getInteractEdata(event)
Parameters :
Name Optional
event No
Returns : void
goback
goback()
Returns : void
hoverActionClicked
hoverActionClicked(event)
Parameters :
Name Optional
event No
Returns : void
initLayout
initLayout()
Returns : void
Public inView
inView(event)
Parameters :
Name Optional
event No
Returns : void
Public isUserLoggedIn
isUserLoggedIn()
Returns : boolean
Private listenLanguageChange
listenLanguageChange()
Returns : void
logTelemetry
logTelemetry(content, actionId)
Parameters :
Name Optional
content No
actionId No
Returns : void
logViewAllTelemetry
logViewAllTelemetry(event)
Parameters :
Name Optional
event No
Returns : void
moveToTop
moveToTop()
Returns : void
Public navigateToPage
navigateToPage(page: number)
Parameters :
Name Type Optional
page number No
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public playContent
playContent(event)
Parameters :
Name Optional
event No
Returns : void
redoLayout
redoLayout()
Returns : void
Private setNoResultMessage
setNoResultMessage()
Returns : void
Private setTelemetryData
setTelemetryData()
Returns : void
updateCardData
updateCardData(downloadListdata)
Parameters :
Name Optional
downloadListdata No
Returns : void
Public viewAll
viewAll(event)
Parameters :
Name Optional
event No
Returns : void

Properties

Public activatedRoute
Type : ActivatedRoute
Public allMimeType
Public allTabData
Public baseUrl
Type : string
Public cacheService
Type : CacheService
Public cardIntractEdata
Type : IInteractEventEdata
Public configService
Type : ConfigService
contentData
contentDownloadStatus
Type : object
Default value : {}
Public contentList
Type : Array<any>
Default value : []
Public contentManagerService
Type : ContentManagerService
contentName
Type : string
Public dataDrivenFilterEvent
Default value : new EventEmitter()
Public dataDrivenFilters
Type : any
Default value : {}
downloadIdentifier
Type : string
Public facets
Type : Array<string>
Public facetsList
Type : any
Public filterType
Type : string
FIRST_PANEL_LAYOUT
Public formData
frameworkId
Public frameworkService
Type : FrameworkService
Public globalSearchFacets
Type : Array<string>
Public hashTagId
Type : string
Public initFilters
Default value : false
Public inViewLogs
Type : []
Default value : []
isDesktopApp
Default value : false
layoutConfiguration
Public layoutService
Type : LayoutService
Public loaderMessage
Type : ILoaderMessage
Public navigationhelperService
Type : NavigationHelperService
Public navigationHelperService
Type : NavigationHelperService
Public noResultMessage
Public numberOfSections
Default value : new Array(this.configService.appConfig.SEARCH.PAGE_LIMIT)
Public orgDetailsService
Type : OrgDetailsService
Public paginationDetails
Type : IPagination
Public paginationService
Type : PaginationService
Public queryParams
Type : any
Public resourceService
Type : ResourceService
Public router
Type : Router
Public searchAll
Public searchService
Type : SearchService
SECOND_PANEL_LAYOUT
Public selectedFilters
showBackButton
Default value : false
showDownloadLoader
Default value : false
showExportLoader
Default value : false
Public showLoader
Default value : true
Public showLoginModal
Default value : false
showModal
Default value : false
Public sortIntractEdata
Type : IInteractEventEdata
Public telemetryImpression
Type : IImpressionEventInput
Public telemetryService
Type : TelemetryService
Public toasterService
Type : ToasterService
Public totalCount
Public unsubscribe$
Default value : new Subject<void>()
Public userService
Type : UserService
Public utilService
Type : UtilService
import {
  PaginationService, ResourceService, ConfigService, ToasterService, OfflineCardService, ILoaderMessage, UtilService, NavigationHelperService, IPagination, LayoutService, COLUMN_TYPE
} from '@sunbird/shared';
import { SearchService, OrgDetailsService, UserService, FrameworkService, SchemaService } from '@sunbird/core';
import { PublicPlayerService } from '../../../../services';
import { combineLatest, Subject, of } from 'rxjs';
import { Component, OnInit, OnDestroy, EventEmitter, AfterViewInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import * as _ from 'lodash-es';
import { IInteractEventEdata, IImpressionEventInput, TelemetryService } from '@sunbird/telemetry';
import { takeUntil, map, mergeMap, first, debounceTime, tap, delay } from 'rxjs/operators';
import { CacheService } from '../../../../../shared/services/cache-service/cache.service';
import { ContentManagerService } from '../../../offline/services';
import {omit, groupBy, get, uniqBy, toLower, find, map as _map, forEach, each} from 'lodash-es';

@Component({
  templateUrl: './explore-content.component.html',
  styleUrls: ['./explore-content.component.scss']
})
export class ExploreContentComponent implements OnInit, OnDestroy, AfterViewInit {

  public showLoader = true;
  public showLoginModal = false;
  public baseUrl: string;
  public noResultMessage;
  public filterType: string;
  public queryParams: any;
  public hashTagId: string;
  public unsubscribe$ = new Subject<void>();
  public telemetryImpression: IImpressionEventInput;
  public inViewLogs = [];
  public sortIntractEdata: IInteractEventEdata;
  public dataDrivenFilters: any = {};
  public dataDrivenFilterEvent = new EventEmitter();
  public initFilters = false;
  public facets: Array<string>;
  public facetsList: any;
  public paginationDetails: IPagination;
  public contentList: Array<any> = [];
  public cardIntractEdata: IInteractEventEdata;
  public loaderMessage: ILoaderMessage;
  public numberOfSections = new Array(this.configService.appConfig.SEARCH.PAGE_LIMIT);
  showExportLoader = false;
  contentName: string;
  showDownloadLoader = false;
  frameworkId;
  public globalSearchFacets: Array<string>;
  public allTabData;
  public selectedFilters;
  public formData;
  layoutConfiguration;
  FIRST_PANEL_LAYOUT;
  SECOND_PANEL_LAYOUT;
  public totalCount;
  public searchAll;
  public allMimeType;
  downloadIdentifier: string;
  contentDownloadStatus = {};
  contentData;
  showModal = false;
  isDesktopApp = false;
  showBackButton = false;

  constructor(public searchService: SearchService, public router: Router,
    public activatedRoute: ActivatedRoute, public paginationService: PaginationService,
    public resourceService: ResourceService, public toasterService: ToasterService,
    public configService: ConfigService, public utilService: UtilService, public orgDetailsService: OrgDetailsService,
    public navigationHelperService: NavigationHelperService, private publicPlayerService: PublicPlayerService,
    public userService: UserService, public frameworkService: FrameworkService,
    public cacheService: CacheService, public navigationhelperService: NavigationHelperService, public layoutService: LayoutService,
    public contentManagerService: ContentManagerService, private offlineCardService: OfflineCardService,
    public telemetryService: TelemetryService, private schemaService: SchemaService) {
    this.paginationDetails = this.paginationService.getPager(0, 1, this.configService.appConfig.SEARCH.PAGE_LIMIT);
    this.filterType = this.configService.appConfig.explore.filterType;
  }
  ngOnInit() {
    this.isDesktopApp = this.utilService.isDesktopApp;
    this.activatedRoute.queryParams.pipe(takeUntil(this.unsubscribe$)).subscribe(queryParams => {
      this.queryParams = { ...queryParams };
    });
    this.searchService.getContentTypes().pipe(takeUntil(this.unsubscribe$)).subscribe(formData => {
      this.allTabData = _.find(formData, (o) => o.title === 'frmelmnts.tab.all');
      this.formData = formData;
      this.globalSearchFacets = (this.queryParams && this.queryParams.searchFilters) ?
      JSON.parse(this.queryParams.searchFilters) : _.get(this.allTabData, 'search.facets');
      this.listenLanguageChange();
      this.initFilters = true;
    }, error => {
      this.toasterService.error(this.resourceService.frmelmnts.lbl.fetchingContentFailed);
      this.navigationhelperService.goBack();
    });

    this.initLayout();
    this.frameworkService.channelData$.pipe(takeUntil(this.unsubscribe$)).subscribe((channelData) => {
      if (!channelData.err) {
        this.frameworkId = _.get(channelData, 'channelData.defaultFramework');
      }
    });
    this.orgDetailsService.getOrgDetails(this.userService.slug).pipe(
      mergeMap((orgDetails: any) => {
        this.hashTagId = orgDetails.hashTagId;
        this.initFilters = true;
        return this.dataDrivenFilterEvent;
      }), first()
    ).subscribe((filters: any) => {
      this.dataDrivenFilters = filters;
      this.fetchContentOnParamChange();
      this.setNoResultMessage();
    },
      error => {
        this.router.navigate(['']);
      }
    );
    this.searchAll = this.resourceService?.frmelmnts?.lbl?.allContent;
    this.contentManagerService.contentDownloadStatus$.subscribe( contentDownloadStatus => {
      this.contentDownloadStatus = contentDownloadStatus;
      this.addHoverData();
    });
    this.checkForBack();
    this.moveToTop();
  }
  goback() {
    if (this.navigationhelperService['_history'].length > 1) {
      this.navigationhelperService.goBack();
    }
  }
  checkForBack() {
    if (_.get(this.activatedRoute, 'snapshot.queryParams["showClose"]') === 'true') {
      this.showBackButton = true;
    }
  }
  initLayout() {
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.redoLayout();
    this.layoutService.switchableLayout().
      pipe(takeUntil(this.unsubscribe$)).subscribe(layoutConfig => {
        if (layoutConfig != null) {
          this.layoutConfiguration = layoutConfig.layout;
        }
        this.redoLayout();
      });
  }
  redoLayout() {
    if (this.layoutConfiguration != null) {
      this.FIRST_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(0, this.layoutConfiguration, COLUMN_TYPE.threeToNine, true);
      this.SECOND_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(1, this.layoutConfiguration, COLUMN_TYPE.threeToNine, true);
    } else {
      this.FIRST_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(0, null, COLUMN_TYPE.fullLayout);
      this.SECOND_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(1, null, COLUMN_TYPE.fullLayout);
    }
  }
  public getFilters(filters) {
    const filterData = filters && filters.filters || {};
    if (filterData.channel && this.facets) {
      const channelIds = [];
      const facetsData = _.find(this.facets, { 'name': 'channel' });
      _.forEach(filterData.channel, (value, index) => {
        const data = _.find(facetsData.values, { 'identifier': value });
        if (data) {
          channelIds.push(data.name);
        }
      });
      if (channelIds && Array.isArray(channelIds) && channelIds.length > 0) {
        filterData.channel = channelIds;
      }
    }
    this.selectedFilters = filterData;
    const defaultFilters = _.reduce(filters, (collector: any, element) => {
      if (element.code === 'board') {
        collector.board = _.get(_.orderBy(element.range, ['index'], ['asc']), '[0].name') || '';
      }
      return collector;
    }, {});
    this.dataDrivenFilterEvent.emit(defaultFilters);
  }
  private fetchContentOnParamChange() {
    combineLatest(this.activatedRoute.params, this.activatedRoute.queryParams, this.schemaService.fetchSchemas())
      .pipe(debounceTime(5),
        tap(data => this.inView({ inview: [] })),
        delay(10),
        tap(data => this.setTelemetryData()),
        map(result => ({ params: { pageNumber: Number(result[0].pageNumber) }, queryParams: result[1] })),
        takeUntil(this.unsubscribe$)
      ).subscribe(({ params, queryParams }) => {
        this.showLoader = true;
        this.paginationDetails.currentPage = params.pageNumber;
        this.queryParams = { ...queryParams };
        this.contentList = [];
        this.fetchContents();
      });
  }
  private fetchContents() {
    const selectedMediaType = _.isArray(_.get(this.queryParams, 'mediaType')) ? _.get(this.queryParams, 'mediaType')[0] :
      _.get(this.queryParams, 'mediaType');
    const mimeType = _.find(_.get(this.allTabData, 'search.filters.mimeType'), (o) => {
      return o.name === (selectedMediaType || 'all');
    });
    const pageType = _.get(this.queryParams, 'pageTitle');
    const filters: any = this.schemaService.schemaValidator({
      inputObj: this.queryParams || {}, properties: _.get(this.schemaService.getSchema('content'), 'properties') || {},
      omitKeys: ['key', 'sort_by', 'sortType', 'appliedFilters', 'softConstraints', 'selectedTab', 'description', 'mediaType', 'contentType', 'searchFilters', 'utm_source']
    });
    if (!filters.channel) {
      filters.channel = this.hashTagId;
    }
    const _filters = _.get(this.allTabData, 'search.filters');
    filters.primaryCategory = filters.primaryCategory || ((_.get(filters, 'primaryCategory.length') && filters.primaryCategory) || _.get(this.allTabData, 'search.filters.primaryCategory'));
    filters.mimeType = filters.mimeType || _.get(mimeType, 'values');
    _.forEach(_filters, (el, key) => {
      if (key !== 'primaryCategory' && key !== 'mimeType' && !_.has(filters, key)) {
        filters[key] = el;
      }
    });
    _.forEach(this.formData, (form, key) => {
      const pageTitle = _.get(this.resourceService, form.title);
      if (pageTitle && pageType && (pageTitle === pageType)) {
        filters.contentType = filters.contentType || _.get(form, 'search.filters.contentType');
      }
    });
    const softConstraints = _.get(this.activatedRoute.snapshot, 'data.softConstraints') || {};
    if (this.queryParams.key) {
      delete softConstraints['board'];
    }
    const option: any = {
      filters: _.omitBy(filters || {}, value => _.isArray(value) ? (!_.get(value, 'length') ? true : false) : false),
      fields: _.get(this.allTabData, 'search.fields'),
      limit: _.get(this.allTabData, 'search.limit') ?  _.get(this.allTabData, 'search.limit')
      : this.configService.appConfig.SEARCH.PAGE_LIMIT,
      pageNumber: this.paginationDetails.currentPage,
      query: this.queryParams.key,
      sort_by: {lastPublishedOn: 'desc'},
      mode: 'soft',
      softConstraints: softConstraints,
      facets: this.globalSearchFacets,
      params: this.configService.appConfig.ExplorePage.contentApiQueryParams || {}
    };
    _.filter(Object.keys(this.queryParams),filterValue => { 
      if(((_.get(this.allTabData , 'search.facets').indexOf(filterValue) !== -1)))
      {
          option.filters[filterValue] = (typeof(this.queryParams[filterValue]) === "string" ) ? this.queryParams[filterValue].split(',') : this.queryParams[filterValue];

      }
  });
    if (this.queryParams.softConstraints) {
      try {
        option.softConstraints = JSON.parse(this.queryParams.softConstraints);
      } catch {

      }
    }
    if (this.frameworkId) {
      option.params.framework = this.frameworkId;
    }
    // Replacing cbse/ncert value with cbse
    const cbseNcertExists = [_.get(filters, 'board[0]'), _.get(filters, 'board'), _.get(filters, 'se_boards[0]'), _.get(filters, 'se_boards')].some(board => _.toLower(board) === 'cbse/ncert');
    if (cbseNcertExists) {
      option.filters.se_boards = ['CBSE'];
    }
    this.searchService.contentSearch(option)
      .pipe(
        mergeMap(data => {
        //   const { subject: selectedSubjects = [] } = (this.selectedFilters || {}) as { subject: [] };
        //   const filteredContents = omit(groupBy(get(data, 'result.content') || get(data, 'result.QuestionSet'), content => {
        //     return ((this.queryParams['primaryCategory'] && this.queryParams['primaryCategory'].length > 0) ? content['subject'] : content['primaryCategory']);
        // }), ['undefined']);
        // for (const [key, value] of Object.entries(filteredContents)) {
        //     const isMultipleSubjects = key && key.split(',').length > 1;
        //     if (isMultipleSubjects) {
        //         const subjects = key && key.split(',');
        //         subjects.forEach((subject) => {
        //             if (filteredContents[subject]) {
        //                 filteredContents[subject] = uniqBy(filteredContents[subject].concat(value), 'identifier');
        //             } else {
        //                 filteredContents[subject] = value;
        //             }
        //         });
        //         delete filteredContents[key];
        //     }
        // }
       // const sections = [];
        // for (const section in filteredContents) {
        //     if (section) {
        //         if (selectedSubjects.length && !(find(selectedSubjects, selectedSub => toLower(selectedSub) === toLower(section)))) {
        //             continue;
        //         }
        //         sections.push({
        //             name: section,
        //             contents: filteredContents[section]
        //         });
        //     }
        // }
        // _map(sections, (section) => {
        //     forEach(section.contents, contents => {
        //         contents.cardImg = contents.appIcon || 'assets/images/book.png';
        //     });
        //     return section;
        // });
        //this.contentList = sections;
        if(get(data, 'result.content') && get(data, 'result.QuestionSet')){
          this.contentList = _.concat(get(data, 'result.content'), get(data, 'result.QuestionSet'));
        } else if(get(data, 'result.content')){
          this.contentList = get(data, 'result.content');
        } else {
          this.contentList = get(data, 'result.QuestionSet');
        }
        this.addHoverData();
          const channelFacet = _.find(_.get(data, 'result.facets') || [], facet => _.get(facet, 'name') === 'channel');
          if (channelFacet) {
            const rootOrgIds = this.orgDetailsService.processOrgData(_.get(channelFacet, 'values'));
            return this.orgDetailsService.searchOrgDetails({
              filters: { isTenant: true, id: rootOrgIds },
              fields: ['slug', 'identifier', 'orgName']
            }).pipe(
              mergeMap(orgDetails => {
                channelFacet.values = _.get(orgDetails, 'content');
                return of(data);
              })
            );
          }
          return of(data);
        })
      )
      .subscribe(data => {
        this.showLoader = false;
        this.facets = this.searchService.updateFacetsData(_.get(data, 'result.facets'));
        this.facetsList = this.searchService.processFilterData(_.get(data, 'result.facets'));
        this.paginationDetails = this.paginationService.getPager(data.result.count, this.paginationDetails.currentPage,
          this.configService.appConfig.SEARCH.PAGE_LIMIT);
        this.totalCount = data.result.count;
        this.setNoResultMessage();
      }, err => {
        this.showLoader = false;
        this.contentList = [];
        this.facetsList = [];
        this.totalCount = 0;
        this.paginationDetails = this.paginationService.getPager(0, this.paginationDetails.currentPage,
          this.configService.appConfig.SEARCH.PAGE_LIMIT);
        this.toasterService.error(this.resourceService.messages.fmsg.m0051);
      });
  }
  addHoverData() {
    this.contentList = this.utilService.addHoverData(this.contentList, true);  
  }
  moveToTop() {
    window.scroll({
      top: 0,
      left: 0,
      behavior: 'smooth'
    });
  }
  public navigateToPage(page: number): void {
    if (page < 1 || page > this.paginationDetails.totalPages) {
      return;
    }
    const url = this.router.url.split('?')[0].replace(/[^\/]+$/, page.toString());
    this.router.navigate([url], { queryParams: this.queryParams });
    this.moveToTop();
  }
  private setTelemetryData() {
    this.inViewLogs = []; // set to empty every time filter or page changes
    this.telemetryImpression = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env
      },
      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: this.activatedRoute.snapshot.data.telemetry.subtype,
        duration: this.navigationhelperService.getPageLoadTime()
      }
    };
    this.cardIntractEdata = {
      id: 'content-card',
      type: 'click',
      pageid: this.activatedRoute.snapshot.data.telemetry.pageid
    };
  }
  public playContent(event) {
    this.publicPlayerService.playContent(event);
  }
  public inView(event) {
    _.forEach(event.inview, (elem, key) => {
      const obj = _.find(this.inViewLogs, { objid: elem.data.identifier });
      if (!obj) {
        this.inViewLogs.push({
          objid: elem.data.identifier,
          objtype: elem.data.contentType || 'content',
          index: elem.id
        });
      }
    });

    if (this.telemetryImpression) {
      this.telemetryImpression.edata.visits = this.inViewLogs;
      this.telemetryImpression.edata.subtype = 'pageexit';
      this.telemetryImpression = Object.assign({}, this.telemetryImpression);
    }
  }
  ngAfterViewInit() {
    setTimeout(() => {
      this.setTelemetryData();
    });
  }
  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  private listenLanguageChange() {
    this.resourceService.languageSelected$.pipe(takeUntil(this.unsubscribe$)).subscribe((languageData) => {
      this.setNoResultMessage();
      if (_.get(this.contentList, 'length') ) {
        if (this.isDesktopApp) {
          this.addHoverData();
        }
        this.facets = this.searchService.updateFacetsData(this.facets);
      }
    });
  }

  private setNoResultMessage() {
    this.resourceService.languageSelected$.subscribe(item => {
    let title = this.utilService.transposeTerms(get(this.resourceService, 'frmelmnts.lbl.noBookfoundTitle'), 'frmelmnts.lbl.noBookfoundTitle', get(item, 'value'));    
    if (this.queryParams.key) {
      const title_part1 = _.replace(this.resourceService.frmelmnts.lbl.desktop.yourSearch, '{key}', this.queryParams.key);
      const title_part2 = this.resourceService.frmelmnts.lbl.desktop.notMatchContent;
      title = title_part1 + ' ' + title_part2;
    }
      this.noResultMessage = {
        'title': title,
        'subTitle': this.utilService.transposeTerms(get(this.resourceService, 'frmelmnts.lbl.noBookfoundSubTitle'), 'frmelmnts.lbl.noBookfoundSubTitle', get(item, 'value')),
        'buttonText': this.utilService.transposeTerms(get(this.resourceService, 'frmelmnts.lbl.noBookfoundButtonText'), 'frmelmnts.lbl.noBookfoundButtonText', get(item, 'value')),
        'showExploreContentButton': false
      };
      
    });
    
  }

  updateCardData(downloadListdata) {
    _.each(this.contentList, (contents) => {
      this.publicPlayerService.updateDownloadStatus(downloadListdata, contents);
    });
  }

  hoverActionClicked(event) {
    event['data'] = event.content;
    this.contentName = event.content.name;
    this.contentData = event.data;
    let telemetryButtonId: any;
    switch (event.hover.type.toUpperCase()) {
      case 'OPEN':
        this.playContent(event);
        this.logTelemetry(this.contentData, 'play-content');
        break;
      case 'DOWNLOAD':
        this.downloadIdentifier = _.get(event, 'content.identifier');
        this.showModal = this.offlineCardService.isYoutubeContent(this.contentData);
        if (!this.showModal) {
          this.showDownloadLoader = true;
          this.downloadContent(this.downloadIdentifier);
        }
        telemetryButtonId = this.contentData.mimeType ===
          'application/vnd.ekstep.content-collection' ? 'download-collection' : 'download-content';
        this.logTelemetry(this.contentData, telemetryButtonId);
        break;
    }
  }

  callDownload() {
    this.showDownloadLoader = true;
    this.downloadContent(this.downloadIdentifier);
  }

  downloadContent(contentId) {
    this.contentManagerService.downloadContentId = contentId;
    this.contentManagerService.downloadContentData = this.contentData;
    this.contentManagerService.failedContentName = this.contentName;
    this.contentManagerService.startDownload({})
      .pipe(takeUntil(this.unsubscribe$))
      .subscribe(data => {
        this.downloadIdentifier = '';
        this.contentManagerService.downloadContentId = '';
        this.contentManagerService.downloadContentData = {};
        this.contentManagerService.failedContentName = '';
        this.showDownloadLoader = false;
      }, error => {
        this.downloadIdentifier = '';
        this.contentManagerService.downloadContentId = '';
        this.contentManagerService.downloadContentData = {};
        this.contentManagerService.failedContentName = '';
        this.showDownloadLoader = false;
        _.each(this.contentList, (content) => {
          content['downloadStatus'] = this.resourceService.messages.stmsg.m0138;
        });
        if (!(error.error.params.err === 'LOW_DISK_SPACE')) {
          this.toasterService.error(this.resourceService.messages.fmsg.m0090);
        }
      });
  }

logTelemetry(content, actionId) {
    const telemetryInteractObject = {
      id: content.identifier,
      type: content.contentType,
      ver: content.pkgVersion ? content.pkgVersion.toString() : '1.0'
    };

    const appTelemetryInteractData: any = {
      context: {
        env: _.get(this.activatedRoute, 'snapshot.root.firstChild.data.telemetry.env') ||
          _.get(this.activatedRoute, 'snapshot.data.telemetry.env') ||
          _.get(this.activatedRoute.snapshot.firstChild, 'children[0].data.telemetry.env')
      },
      edata: {
        id: actionId,
        type: 'click',
        pageid: this.router.url.split('/')[1] || 'explore-page'
      }
    };

    if (telemetryInteractObject) {
      if (telemetryInteractObject.ver) {
        telemetryInteractObject.ver = _.isNumber(telemetryInteractObject.ver) ?
          _.toString(telemetryInteractObject.ver) : telemetryInteractObject.ver;
      }
      appTelemetryInteractData.object = telemetryInteractObject;
    }
    this.telemetryService.interact(appTelemetryInteractData);
  }
  public viewAll(event) {
    this.moveToTop();
    this.logViewAllTelemetry(event);
    const searchQueryParams: any = {};
    searchQueryParams.defaultSortBy = JSON.stringify({ lastPublishedOn: 'desc' });
    searchQueryParams['exists'] = undefined;
    searchQueryParams['primaryCategory'] = (this.queryParams.primaryCategory && this.queryParams.primaryCategory.length) ?
     this.queryParams.primaryCategory : [event.name];
    (this.queryParams.primaryCategory && this.queryParams.primaryCategory.length) ? (searchQueryParams['subject'] = [event.name]) :
    (searchQueryParams['se_subjects'] = this.queryParams.se_subjects);
    searchQueryParams['selectedTab'] = 'all';
    if (this.queryParams.channel) {
      searchQueryParams['channel'] = this.queryParams.channel;
    }
    searchQueryParams['visibility'] = [];
    searchQueryParams['appliedFilters'] = true;
    const sectionUrl = '/explore' + '/view-all/' + event.name.replace(/\s/g, '-');
    this.router.navigate([sectionUrl, 1], { queryParams: searchQueryParams, state: {} });
 }

 public isUserLoggedIn(): boolean {
  return this.userService && (this.userService.loggedIn || false);
}

logViewAllTelemetry(event) {
  const telemetryData = {
      cdata: [{
          type: 'section',
          id: event.name
      }],
      edata: {
          id: 'view-all'
      }
  };
  this.getInteractEdata(telemetryData);
}

getInteractEdata(event) {
  const cardClickInteractData = {
      context: {
          cdata: event.cdata,
          env: this.isUserLoggedIn() ? 'library' : this.activatedRoute.snapshot.data.telemetry.env,
      },
      edata: {
          id: get(event, 'edata.id'),
          type: 'click',
          pageid: this.isUserLoggedIn() ? 'library' : this.activatedRoute.snapshot.data.telemetry.pageid
      },
      object: get(event, 'object')
  };
  this.telemetryService.interact(cardClickInteractData);
}
}

<app-landing-section *ngIf="allTabData" [textToDisplay]="resourceService?.frmelmnts?.tab?.all" [layoutConfiguration]="layoutConfiguration" [svgToDisplay]="allTabData?.theme?.imageName"></app-landing-section>
<div [ngClass]="layoutConfiguration ? 'sbt-fluid-content-bg':''">
  <div [ngClass]="layoutConfiguration ? 'sb-g sbt-container sbt-page-content' : 'sb-g'">
    <div [ngClass]="FIRST_PANEL_LAYOUT">
      <div *ngIf="layoutConfiguration">
        <ng-container *ngIf="isDesktopApp">
          <app-network-status></app-network-status>
          <app-load-offline-content></app-load-offline-content>
          <app-system-warning></app-system-warning>
        </ng-container>
    </div>
        <div [ngClass]="isDesktopApp ? 'sb-desktop-filter-section' : ''">
          <ng-container>
          <app-global-search-filter [layoutConfiguration]="layoutConfiguration" [facets]="facets" [isOpen]='true'
              *ngIf="initFilters && allTabData" (filterChange)="getFilters($event)">
            </app-global-search-filter>
          </ng-container>
        </div>
    </div>
    <div [ngClass]="SECOND_PANEL_LAYOUT" class="w-100">
      <div [ngClass]="layoutConfiguration ? 'sbt-page-content-area' : 'ui container mt-24'">
        <div class="content-grid relative9">
          <div class="sb-pageSection" *ngIf="!showLoader && totalCount > 0 && !showBackButton">
            <div class="sb-pageSection-header mb-10">
              <div class="">
                <h4 class="sb-pageSection-title m-0 mr-5" [innerHTML]="resourceService.frmelmnts?.lbl?.showingResultsFor |
                interpolate:'{searchString}':this.queryParams.key !=null?this.queryParams.key:searchAll "></h4> 
                <span class="badge">{{totalCount}}</span>
              </div>
              <button appTelemetryInteract [telemetryInteractEdata]="closeIntractEdata" *ngIf="showBackButton" class="sb-btn sb-btn-normal sb-btn-error ml-auto sb-cls-btn" type="button" tabindex="0"  (click)= "goback()">
                {{resourceService?.frmelmnts?.btn?.close | translate}} <i class="close icon"></i></button>
            </div>
          </div>
          
          <div [appTelemetryImpression]="telemetryImpression" class="twelve wide column" 
             *ngIf="!showLoader && contentList.length">
           <app-global-search-selected-filter [facets]="facets" [selectedFilters]="selectedFilters"
              *ngIf="initFilters && facets && layoutConfiguration" (filterChange)="getFilters($event)"></app-global-search-selected-filter>
              <ng-container>
                <!-- <ng-container *ngFor="let data of contentList;let i = index;"> -->
                  <div class="sb-grid mb-16">
                    <div *ngFor="let content of contentList;let i = index;"  [id]="i" [data]="content" class="sb-grid--item"
                      [ngClass]="{'last mb-0':last}">
                      <sb-library-card *ngIf="!isDesktopApp;else desktopCard" [indexToDisplay]="i"
                        [layoutConfig]="layoutConfiguration" appTelemetryInteract [telemetryInteractEdata]="cardIntractEdata"
                        [telemetryInteractObject]="{id:content.identifier,type:content.contentType || 'content',ver:content.pkgVersion ? content.pkgVersion.toString():'1.0'}"
                        (cardClick)="playContent($event)" (enterKey)="playContent($event)" [content]="content"
                        [cardImg]="content?.appIcon || 'assets/images/book.png'">
                      </sb-library-card>
                      <ng-template #desktopCard>
                        <div class="sb-desktop-library-card relative9">
                          <sb-library-card [indexToDisplay]="i" [layoutConfig]="layoutConfiguration" appTelemetryInteract
                            [telemetryInteractEdata]="cardIntractEdata"
                            [telemetryInteractObject]="{id:content.identifier,type:content.contentType || 'content',ver:content.pkgVersion ? content.pkgVersion.toString():'1.0'}"
                            [hover-template]="hoverTemplate" [content]="content"
                            [cardImg]="content?.appIcon || 'assets/images/book.png'">
                            <ng-template #hoverTemplate let-hoverData="hoverData" let-content="content">
                              <sb-card-hover class="card-hover" [content]="content" [hoverData]="hoverData"
                                (hoverActionClick)="hoverActionClicked($event)">
                              </sb-card-hover>
                            </ng-template>
                          </sb-library-card>
                        </div>
                      </ng-template>
                    </div>
                  </div>
                <!-- </ng-container> -->
              </ng-container>

              <!-- <ng-container *ngIf =showBackButton>
              <div *ngFor="let section of contentList; let last = last" [ngClass]="{'last mb-0':last}">
                <sb-library-cards-grid *ngIf="!isDesktopApp" [layoutConfig]="layoutConfiguration" [type]="'infinite_card_grid'"
                  [title]="section.name" [contentList]="section.contents" [maxCardCount]="3" [viewMore]="true"
                  (viewMoreClick)="viewAll(section)" (cardClick)="playContent($event, section.name)">
                </sb-library-cards-grid>
                <div class="sb-desktop-library-card relative9">
                  <sb-library-cards-grid *ngIf="isDesktopApp" [layoutConfig]="layoutConfiguration" [type]="'infinite_card_grid_with_hover'" 
                  [title]="section?.name" [contentList]="section.contents" [maxCardCount]="3" [viewMore]="true"
                  (hoverActionClick)="hoverActionClicked($event)" (viewMoreClick)="viewAll(section)">
                  </sb-library-cards-grid>
                </div>
              </div>
            </ng-container> -->
          </div>
          <div [appTelemetryImpression]="telemetryImpression" class="twelve wide column"
            *ngIf="contentList.length === 0 && !showLoader">
            <app-no-result-found [title]="noResultMessage?.title" [subTitle]="noResultMessage?.subTitle" 
            [buttonText]="noResultMessage?.buttonText" [showExploreContentButton]="noResultMessage?.showExploreContentButton"></app-no-result-found>
          </div>
          <div class="twelve wide column" *ngIf="showLoader">
            <div class="sb-grid">
              <div [id]="i" [data]="content" class="sb-grid--item"
                *ngFor="let i of numberOfSections">
                <sb-library-card [layoutConfig]="layoutConfiguration" [isLoading]="true"></sb-library-card>
              </div>
            </div>
          </div>
          <div class="twelve wide column right aligned"
            *ngIf="paginationDetails.totalItems > configService.appConfig.SEARCH.PAGE_LIMIT && !showLoader">
            <div class="sb-pagination-container flex-jc-flex-end mt-16" *ngIf="paginationDetails.pages.length">
              <div class="sb-pagination my-0">
                <a role="button" title="{{resourceService?.frmelmnts?.lbl?.first}}" attr.aria-label="{{resourceService?.frmelmnts?.lbl?.first}}" [ngClass]="{disabled:paginationDetails.currentPage===1 }" class="sb-item "
                  tabindex="0" (click)="navigateToPage(1) ">&laquo;</a>
                <a role="button" title="{{resourceService?.frmelmnts?.lbl?.previous}}" attr.aria-label="{{resourceService?.frmelmnts?.lbl?.previous}}" [ngClass]="{disabled:paginationDetails.currentPage===1 }" class="sb-item "
                  tabindex="0" (click)="navigateToPage(paginationDetails.currentPage - 1)">&lt;</a>
                <a role=“button” aria-current=“page” title="{{page}}" attr.aria-label="{{page}}" *ngFor="let page of paginationDetails.pages" [ngClass]="{active:paginationDetails.currentPage===page}"
                  tabindex="0" (click)="navigateToPage(page)" class="sb-item">{{page}}</a>
                <a role="button" title="{{resourceService?.frmelmnts?.lbl?.next}}" attr.aria-label="{{resourceService?.frmelmnts?.lbl?.next}}" [ngClass]="{disabled:paginationDetails.currentPage=== paginationDetails.totalPages}"
                  tabindex="0" (click)="navigateToPage(paginationDetails.currentPage + 1)" class="sb-item">&gt;</a>
                <a role="button" title="{{resourceService?.frmelmnts?.lbl?.last}}" attr.aria-label="{{resourceService?.frmelmnts?.lbl?.last}}" [ngClass]="{disabled:paginationDetails.currentPage=== paginationDetails.totalPages}"
                  tabindex="0" (click)="navigateToPage(paginationDetails.totalPages)" class="sb-item ">&raquo;</a>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
</div>
</div>
<!-- Show Modal if content has any YouTube data-->
<app-modal-wrapper *ngIf="showModal" [config]="{disableClose: true, size: 'normal'}"
  (dismiss)="showModal = !showModal;showModal = !showModal;" #modal>
  <ng-template sbModalContent>
    <div class="sb-modal">
      <div class="transition ui dimmer page modals active visible">
        <div class="ui modal transition active visible normal">
          <div class="sb-modal-header">
            {{resourceService.frmelmnts?.btn?.download}}
          </div>
          <div class="sb-modal-content">
            <p>{{resourceService?.messages?.stmsg?.m0137 }}</p>
          </div>
          <div class="sb-modal-actions">
            <button class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0"
              (click)="callDownload(); showModal = !showModal; logTelemetry(contentData, 'confirm-download-content');">
              {{resourceService.frmelmnts?.btn?.yes}}
            </button>
            <button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0"
              (click)="showModal = !showModal; logTelemetry(contentData, 'cancel-download-content');">
              {{resourceService.frmelmnts?.btn?.cancel}}
            </button>
          </div>
        </div>
      </div>
    </div>
  </ng-template>
</app-modal-wrapper>

./explore-content.component.scss

.sb-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill,minmax(252px,1fr));
    grid-gap: 1rem;
    grid-row-gap: 1.5rem;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""