File

src/app/resources/relevant-contents/relevant-contents.page.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods

Constructor

constructor(frameworkUtilService: FrameworkUtilService, contentService: ContentService, commonUtilService: CommonUtilService, telemetryGeneratorService: TelemetryGeneratorService, translate: TranslateService, router: Router, navService: NavigationService)
Parameters :
Name Type Optional
frameworkUtilService FrameworkUtilService No
contentService ContentService No
commonUtilService CommonUtilService No
telemetryGeneratorService TelemetryGeneratorService No
translate TranslateService No
router Router No
navService NavigationService No

Methods

Private Async fetchContentResult
fetchContentResult(request: ContentSearchCriteria)
Parameters :
Name Type Optional
request ContentSearchCriteria No
Returns : Promise<any[]>
Private Async getBoardList
getBoardList(board)
Parameters :
Name Optional
board No
Returns : unknown
Private getDefaultBoard
getDefaultBoard()
Returns : void
Private getNavParam
getNavParam()
Returns : void
Private getPrimaryCategoryList
getPrimaryCategoryList()
Returns : {}
Private Async getRelevantContents
getRelevantContents()
Returns : any
Private Async getSimilarContents
getSimilarContents()
Returns : any
Async goToHelp
goToHelp()
Returns : any
navigateToTextBookDetailPage
navigateToTextBookDetailPage(event)
Parameters :
Name Optional
event No
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
Async ngOnInit
ngOnInit()
Returns : any
Private prepareContentRequest
prepareContentRequest()
Returns : void
viewMoreContent
viewMoreContent(type: ContentOrder)
Parameters :
Name Type Optional
type ContentOrder No
Returns : void

Properties

Public commonUtilService
Type : CommonUtilService
contentOrder
Default value : ContentOrder
corRelation
Type : Array<CorrelationData>
Default value : []
Private defaultBoard
Type : []
Default value : []
Private displayCount
Type : number
Default value : 4
Private formInput
Type : any
isLoading
Default value : false
Private paramsData
Type : any
relevantContentCount
Default value : this.displayCount
relevantContentList
Type : Array<any>
Default value : []
Private searchRequest
Type : ContentSearchCriteria
Default value : { searchType: SearchType.SEARCH, facets: Search.FACETS_ETB, fields: ExploreConstants.REQUIRED_FIELDS }
Private selectedFramework
Type : object
Default value : { board: [], medium: [], grade: [], subject: [], primaryCategory: [], }
similarContentCount
Default value : this.displayCount
similarContentList
Type : Array<any>[]
import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
import { CommonUtilService } from '@app/services/common-util.service';
import { TelemetryGeneratorService } from '@app/services/telemetry-generator.service';
import { CorReleationDataType, Environment, InteractSubtype, InteractType, PageId, ImpressionType } from '@app/services';
import {
  ContentSearchCriteria,
  ContentSearchResult,
  ContentService,
  SearchType,
  GetSuggestedFrameworksRequest,
  CachedItemRequestSourceFrom,
  FrameworkCategoryCodesGroup,
  FrameworkUtilService,
  CorrelationData
} from 'sunbird-sdk';
import { ExploreConstants, RouterLinks, Search } from '@app/app/app.constant';
import { Router } from '@angular/router';
import { ContentUtil } from '@app/util/content-util';
import { TranslateService } from '@ngx-translate/core';
import { NavigationService } from '@app/services/navigation-handler.service';

enum ContentOrder {
  RELEVANT = 'RELEVANT',
  SIMILAR = 'SIMILAR',
}
@Component({
  selector: 'app-relevant-contents',
  templateUrl: './relevant-contents.page.html',
  styleUrls: ['./relevant-contents.page.scss'],
})
export class RelevantContentsPage implements OnInit, OnDestroy {
  private displayCount = 4;
  private formInput: any;
  private searchRequest: ContentSearchCriteria = {
    searchType: SearchType.SEARCH,
    facets: Search.FACETS_ETB,
    fields: ExploreConstants.REQUIRED_FIELDS
  };
  private selectedFramework = {
    board: [],
    medium: [],
    grade: [],
    subject: [],
    primaryCategory: [],
  };
  private paramsData: any;
  private defaultBoard = [];

  relevantContentList: Array<any> = [];
  similarContentList: Array<any>[];
  contentOrder = ContentOrder;
  relevantContentCount = this.displayCount;
  similarContentCount = this.displayCount;
  isLoading = false;
  corRelation: Array<CorrelationData> = [];

  constructor(
    @Inject('FRAMEWORK_UTIL_SERVICE') private frameworkUtilService: FrameworkUtilService,
    @Inject('CONTENT_SERVICE') private contentService: ContentService,
    public commonUtilService: CommonUtilService,
    private telemetryGeneratorService: TelemetryGeneratorService,
    private translate: TranslateService,
    private router: Router,
    private navService: NavigationService
  ) {
    this.getNavParam();
  }
  async ngOnInit() {
    this.telemetryGeneratorService.generateImpressionTelemetry(
      ImpressionType.VIEW,
      '',
      PageId.RELEVANT_CONTENTS,
      Environment.USER,
      undefined,
      undefined,
      undefined,
      undefined,
      this.corRelation);
  }

  private getNavParam() {
    this.isLoading = true;
    const navExtras = this.router.getCurrentNavigation().extras && this.router.getCurrentNavigation().extras.state;
    if (navExtras) {
      this.formInput = navExtras.formInput;
      this.corRelation = navExtras.corRelation;
      this.paramsData = navExtras.formOutput;
      this.selectedFramework.board = this.paramsData.board && this.paramsData.board.name ? [this.paramsData.board.name] : [];
      this.selectedFramework.medium = this.paramsData.medium && this.paramsData.medium.name ? [this.paramsData.medium.name] : [];
      this.selectedFramework.grade = this.paramsData.grade && this.paramsData.grade.name ? [this.paramsData.grade.name] : [];
      this.selectedFramework.subject = this.paramsData.subject && this.paramsData.subject.name ? [this.paramsData.subject.name] : [];
      this.selectedFramework.primaryCategory = [this.paramsData.primaryCategory];
    }
    this.getDefaultBoard();
    this.prepareContentRequest();
    this.getRelevantContents();
    this.getSimilarContents();
    this.corRelation.push({ id: PageId.RELEVANT_CONTENTS, type: CorReleationDataType.FROM_PAGE });
  }

  private prepareContentRequest() {
    this.searchRequest.board = this.selectedFramework.board;
    this.searchRequest.medium = this.selectedFramework.medium;
    this.searchRequest.grade = this.selectedFramework.grade;
    this.searchRequest.subject = this.selectedFramework.subject;
    this.searchRequest.primaryCategories = this.selectedFramework.primaryCategory;
    this.searchRequest.mode = 'hard';
  }

  private async getRelevantContents() {
    this.relevantContentList = await this.fetchContentResult(this.searchRequest);
  }

  private async getSimilarContents() {
    try {
      const similarContentRequest: ContentSearchCriteria = { ...this.searchRequest };

      if (this.selectedFramework.board && this.defaultBoard.length && this.selectedFramework.board.find(e => e === this.defaultBoard[0])) {
        similarContentRequest.board = await this.getBoardList(this.searchRequest.board && this.searchRequest.board[0]);
      } else {
        similarContentRequest.board = this.defaultBoard[0];
      }
      similarContentRequest.mode = 'soft';

      similarContentRequest.primaryCategories = this.getPrimaryCategoryList();
      const contentList = await this.fetchContentResult(similarContentRequest);
      contentList.sort((a) => {
        const val = (a['primaryCategory'] !== this.searchRequest.primaryCategories[0]) ? 1 : -1;
        return val;
      });
      this.similarContentList = contentList;
      this.isLoading = false;
    } catch (e) {
      this.isLoading = false;
    }

  }

  private async fetchContentResult(request: ContentSearchCriteria): Promise<any[]> {
    try {
      const result: ContentSearchResult = await this.contentService.searchContent(request).toPromise();
      const contentList = result.contentDataList;
      if (contentList && contentList.length) {
        for (let i = 0; i < contentList.length; i++) {
          contentList[i]['cardImg'] = ContentUtil.getAppIcon(contentList[i].appIcon,
            contentList[i]['basePath'], this.commonUtilService.networkInfo.isNetworkAvailable);
        }
      }
      return contentList || [];
    } catch (e) {
      console.log(e);
      return [];
    }
  }

  ngOnDestroy(): void {

  }

  navigateToTextBookDetailPage(event) {
    const item = event.data;
    const index = event.index;
    const identifier = item.contentId || item.identifier;
    const corRelationList = [{ id: item.name, type: CorReleationDataType.SUBJECT }];
    const values = {};
    values['sectionName'] = item.subject;
    values['positionClicked'] = index;
    this.telemetryGeneratorService.generateInteractTelemetry(InteractType.TOUCH,
      InteractSubtype.CONTENT_CLICKED,
      Environment.HOME,
      PageId.EXPLORE_MORE_CONTENT,
      ContentUtil.getTelemetryObject(item),
      values,
      ContentUtil.generateRollUp(undefined, identifier),
      corRelationList);
    if (this.commonUtilService.networkInfo.isNetworkAvailable || item.isAvailableLocally) {
      this.navService.navigateToDetailPage(
        item,
        { content: item, corRelation: corRelationList }
      );
    } else {
      this.commonUtilService.presentToastForOffline('OFFLINE_WARNING_ETBUI');
    }
  }

  viewMoreContent(type: ContentOrder) {
    if (type === this.contentOrder.RELEVANT) {
      this.relevantContentCount += this.displayCount;
    } else {
      this.similarContentCount += this.displayCount;
    }
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.VIEW_MORE_CLICKED,
      Environment.HOME,
      PageId.RELEVANT_CONTENTS)
  }

  async goToHelp() {
    this.telemetryGeneratorService.generateInteractTelemetry(
      InteractType.TOUCH,
      InteractSubtype.HELP_CLICKED,
      Environment.HOME,
      PageId.RELEVANT_CONTENTS);

    this.router.navigate([`/${RouterLinks.FAQ_HELP}`], {
      state: {
        corRelation: this.corRelation
      }
    });
  }

  private getPrimaryCategoryList() {
    const primaryCategoryConfig: any = this.formInput.find(e => e.code === 'primaryCategory');
    const primaryCategoryList = [];
    const list = (primaryCategoryConfig && primaryCategoryConfig.templateOptions && primaryCategoryConfig.templateOptions.options) || [];
    list.forEach(element => {
      primaryCategoryList.push(element.value);
    });
    return primaryCategoryList;
  }

  private getDefaultBoard() {
    const boardConfig = this.formInput.find(e => e.code === 'board');
    this.defaultBoard = boardConfig && boardConfig.templateOptions && boardConfig.templateOptions.dataSrc &&
      boardConfig.templateOptions.dataSrc.params && boardConfig.templateOptions.dataSrc.params.relevantTerms ?
      boardConfig.templateOptions.dataSrc.params.relevantTerms : [];
  }

  private async getBoardList(board) {
    const getSuggestedFrameworksRequest: GetSuggestedFrameworksRequest = {
      from: CachedItemRequestSourceFrom.CACHE,
      language: this.translate.currentLang,
      requiredCategories: FrameworkCategoryCodesGroup.DEFAULT_FRAMEWORK_CATEGORIES
    };

    try {
      const list = await this.frameworkUtilService.getActiveChannelSuggestedFrameworkList(getSuggestedFrameworksRequest).toPromise();
      const boardList = [];
      list.forEach(element => {
        if (element.name !== board) {
          boardList.push(element.name);
        }
      });

      return boardList || [];
    } catch (e) {
      return [];
    }
  }

}
<ion-content>

    <div class="p-16 rc-bg-color" *ngIf="isLoading">
        <div class="sb-textbook-container">
            <sb-library-cards-stack 
                [contentList]="[1,2,3,4,5,6,7,8]"
                [maxCardCount]="8"
                [isLoading]="isLoading">
            </sb-library-cards-stack>
        </div>
    </div>

    <div class="p-16 rc-bg-color" *ngIf="relevantContentList?.length">
        <p class="rc-title" role="heading" aria-level="1">{{'FRMELEMNTS_LBL_CONTENT_FOUND' | translate }}</p>
        <div class="sb-textbook-container">
            <sb-library-cards-stack 
                [contentList]="relevantContentList"
                [isOffline]="!commonUtilService.networkInfo.isNetworkAvailable" 
                [maxCardCount]="relevantContentCount"
                [viewMoreButtonText]="'SEE_MORE_CONTENT' | translate"
                (viewMoreClick)="viewMoreContent(contentOrder.RELEVANT)"
                (cardClick)="navigateToTextBookDetailPage($event)">
            </sb-library-cards-stack>
        </div>
    </div>

    <div class="p-16 mt-8" *ngIf="similarContentList?.length">
        <p class="rc-title" role="heading" aria-level="2">{{'FRMELEMNTS_LBL_CONTENT_AVAIALABLE_IN_OTHER_BOARD' | translate }}</p>
        <div class="sb-textbook-container">
            <sb-library-cards-stack 
                [contentList]="similarContentList"
                [isOffline]="!commonUtilService.networkInfo.isNetworkAvailable" 
                [maxCardCount]="similarContentCount"
                [viewMoreButtonText]="'SEE_MORE_CONTENT' | translate"
                (viewMoreClick)="viewMoreContent(contentOrder.SIMILAR)"
                (cardClick)="navigateToTextBookDetailPage($event)">
            </sb-library-cards-stack>
        </div>
    </div>

    <div class="no-content-msg" *ngIf="!isLoading && !similarContentList?.length && !relevantContentList?.length">
        <div>
            <img src="assets/imgs/group.svg" alt="no data found">
        </div>
        <strong>{{'FRMELEMNTS_LBL_NO_MATCHING_CONTENT' | translate}}</strong>

        <p class="mb-0">{{'FRMELEMNTS_LBL_CONTENT_TO_BE_ADDED' | translate}}</p>
        <p [innerHTML]="'FRMELEMNTS_LBL_CLICK_HELP' | translate"></p>
    </div>

    <div *ngIf="similarContentList?.length || relevantContentList?.length">
        <div class="text-center mt-32">
            <p class="mb-0">{{ "FRMELEMNTS_LBL_COULD_NOT_FIND_CONTENT_YET" | translate}}</p>
        </div>
        
        <ion-button expand="block" class="M16 MB30" (click)="goToHelp()">
            {{'FRMELEMNTS_BTN_SEEK_HELP' | translate}}
        </ion-button>
    </div>
        
</ion-content>

<ion-footer *ngIf="!similarContentList?.length && !relevantContentList?.length">
    <ion-button expand="block" class="M16 MB30" (click)="goToHelp()">
        {{'FRMELEMNTS_BTN_SEEK_HELP' | translate}}
    </ion-button>
</ion-footer>

./relevant-contents.page.scss

@import "src/assets/styles/variables";
@import "src/assets/styles/_custom-mixins";
@import "src/assets/styles/fonts";

.rc-title {
  margin: 8px;
  font-weight: bold;
}

.rc-bg-color {
  background-color: map-get($colors, white_f2)
}

ion-button {
  --background: #{$blue} !important;
  height: 2.5rem !important;
}

.no-content-msg {
  text-align: center;
  padding-top: 30%;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""