src/app/modules/public/module/course/components/explore-course/explore-course.component.ts
OnInit
OnDestroy
AfterViewInit
templateUrl | ./explore-course.component.html |
constructor(searchService: SearchService, router: Router, activatedRoute: ActivatedRoute, paginationService: PaginationService, resourceService: ResourceService, toasterService: ToasterService, configService: ConfigService, utilService: UtilService, orgDetailsService: OrgDetailsService, publicPlayerService: PublicPlayerService, userService: UserService, cacheService: CacheService, formService: FormService, browserCacheTtlService: BrowserCacheTtlService, navigationhelperService: NavigationHelperService, layoutService: LayoutService)
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
Parameters :
|
closeModal |
closeModal()
|
Returns :
void
|
Private fetchContentOnParamChange |
fetchContentOnParamChange()
|
Returns :
void
|
Private fetchContents |
fetchContents()
|
Returns :
void
|
Public getFilters | ||||
getFilters(filters)
|
||||
Parameters :
Returns :
void
|
Private getFrameWork |
getFrameWork()
|
Returns :
any
|
initLayout |
initLayout()
|
Returns :
void
|
Public inView | ||||
inView(event)
|
||||
Parameters :
Returns :
void
|
Public navigateToPage | ||||||
navigateToPage(page: number)
|
||||||
Parameters :
Returns :
void
|
ngAfterViewInit |
ngAfterViewInit()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
Public playContent | ||||
playContent(event)
|
||||
Parameters :
Returns :
void
|
redoLayout |
redoLayout()
|
Returns :
void
|
Private setNoResultMessage |
setNoResultMessage()
|
Returns :
void
|
Private setTelemetryData |
setTelemetryData()
|
Returns :
void
|
Public activatedRoute |
Type : ActivatedRoute
|
Public allMimeType |
Public allTabData |
Public baseUrl |
Type : string
|
Public browserCacheTtlService |
Type : BrowserCacheTtlService
|
Public cacheService |
Type : CacheService
|
Public cardIntractEdata |
Type : IInteractEventEdata
|
Public configService |
Type : ConfigService
|
Public contentList |
Type : Array<ICard>
|
Default value : []
|
Public dataDrivenFilterEvent |
Default value : new EventEmitter()
|
Public dataDrivenFilters |
Type : any
|
Default value : {}
|
Public facets |
Type : Array<string>
|
Public facetsList |
Type : any
|
Public filterType |
Type : string
|
FIRST_PANEL_LAYOUT |
Type : string
|
Public formService |
Type : FormService
|
Public frameWorkName |
Type : string
|
Public globalSearchFacets |
Type : Array<string>
|
Public hashTagId |
Type : string
|
Public initFilters |
Default value : false
|
Public inViewLogs |
Type : []
|
Default value : []
|
layoutConfiguration |
Type : any
|
Public layoutService |
Type : LayoutService
|
Public loaderMessage |
Type : ILoaderMessage
|
Public navigationhelperService |
Type : NavigationHelperService
|
Public noResultMessage |
Type : INoResultMessage
|
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 |
Type : string
|
Public selectedFilters |
Public showLoader |
Default value : true
|
Public showLoginModal |
Default value : false
|
Public sortIntractEdata |
Type : IInteractEventEdata
|
Public telemetryImpression |
Type : IImpressionEventInput
|
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, INoResultMessage,
ICard, ILoaderMessage, UtilService, BrowserCacheTtlService, NavigationHelperService, IPagination,
LayoutService, COLUMN_TYPE
} from '@sunbird/shared';
import { SearchService, OrgDetailsService, UserService, FormService } 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 } from '@sunbird/telemetry';
import { takeUntil, map, mergeMap, first, debounceTime, catchError, tap, delay } from 'rxjs/operators';
import { CacheService } from '../../../../../shared/services/cache-service/cache.service';
@Component({
templateUrl: './explore-course.component.html'
})
export class ExploreCourseComponent implements OnInit, OnDestroy, AfterViewInit {
public showLoader = true;
public showLoginModal = false;
public baseUrl: string;
public noResultMessage: INoResultMessage;
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<ICard> = [];
public cardIntractEdata: IInteractEventEdata;
public loaderMessage: ILoaderMessage;
public frameWorkName: string;
layoutConfiguration: any;
FIRST_PANEL_LAYOUT: string;
SECOND_PANEL_LAYOUT: string;
public globalSearchFacets: Array<string>;
public allTabData;
public selectedFilters;
public totalCount;
public searchAll;
public allMimeType;
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,
private publicPlayerService: PublicPlayerService, public userService: UserService, public cacheService: CacheService,
public formService: FormService, public browserCacheTtlService: BrowserCacheTtlService,
public navigationhelperService: NavigationHelperService, public layoutService: LayoutService) {
this.paginationDetails = this.paginationService.getPager(0, 1, this.configService.appConfig.SEARCH.PAGE_LIMIT);
this.filterType = this.configService.appConfig.exploreCourse.filterType;
}
ngOnInit() {
this.searchService.getContentTypes().pipe(takeUntil(this.unsubscribe$)).subscribe(formData => {
this.allTabData = _.find(formData, (o) => o.title === 'frmelmnts.tab.all');
this.globalSearchFacets = _.get(this.allTabData, 'search.facets');
this.setNoResultMessage();
this.initFilters = true;
}, error => {
this.toasterService.error(this.resourceService.frmelmnts.lbl.fetchingContentFailed);
this.navigationhelperService.goBack();
});
this.layoutConfiguration = this.layoutService.initlayoutConfig();
this.initLayout();
combineLatest(
this.orgDetailsService.getOrgDetails(this.userService.slug),
this.getFrameWork()
).pipe(
mergeMap((data: any) => {
this.hashTagId = data[0].hashTagId;
if (data[1]) {
this.initFilters = true;
this.frameWorkName = data[1];
return of({});
// return this.dataDrivenFilterEvent;
} else {
return of({});
}
}), first()
).subscribe((filters: any) => {
this.dataDrivenFilters = filters;
this.fetchContentOnParamChange();
this.setNoResultMessage();
},
error => {
this.router.navigate(['']);
}
);
this.searchAll = this.resourceService?.frmelmnts?.lbl?.allContent;
}
initLayout() {
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 getFrameWork() {
const formServiceInputParams = {
formType: 'framework',
formAction: 'search',
contentType: 'framework-code',
};
return this.formService.getFormConfig(formServiceInputParams, this.hashTagId)
.pipe(map((data) => {
const frameWork = _.find(data, 'framework').framework;
return frameWork;
}), catchError((error) => {
return of(false);
}));
}
private fetchContentOnParamChange() {
combineLatest(this.activatedRoute.params, this.activatedRoute.queryParams)
.pipe(debounceTime(5), // wait for both params and queryParams event to change
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 filters: any = _.omit(this.queryParams, ['key', 'sort_by', 'sortType', 'appliedFilters', 'softConstraints', 'selectedTab', 'mediaType']);
if (!filters.channel) {
filters.channel = this.hashTagId;
}
filters.primaryCategory = filters.primaryCategory || _.get(this.allTabData, 'search.filters.primaryCategory');
filters.mimeType = _.get(mimeType, 'values');
const softConstraints = _.get(this.activatedRoute.snapshot, 'data.softConstraints') || {};
if (this.queryParams.key) {
delete softConstraints['board'];
}
const option: any = {
filters: filters,
fields: _.get(this.allTabData, 'search.fields'),
limit: _.get(this.allTabData, 'search.limit'),
pageNumber: this.paginationDetails.currentPage,
query: this.queryParams.key,
mode: 'soft',
softConstraints: softConstraints,
facets: this.globalSearchFacets,
params: this.configService.appConfig.ExplorePage.contentApiQueryParams || {}
};
if (this.queryParams.softConstraints) {
try {
option.softConstraints = JSON.parse(this.queryParams.softConstraints);
} catch {
}
}
this.searchService.contentSearch(option)
.pipe(
mergeMap(data => {
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.contentList = data.result.content || [];
this.totalCount = data.result.count;
}, 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);
});
}
private setTelemetryData() {
this.inViewLogs = [];
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.metaData.identifier });
if (!obj) {
this.inViewLogs.push({
objid: elem.data.metaData.identifier,
objtype: elem.data.metaData.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);
}
}
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 });
window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});
}
ngAfterViewInit() {
setTimeout(() => {
this.setTelemetryData();
});
}
ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
closeModal() {
this.showLoginModal = false;
}
private setNoResultMessage() {
this.noResultMessage = {
'message': 'messages.stmsg.m0007',
'messageText': 'messages.stmsg.m0006'
};
}
}
<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">
<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 [ngClass]="SECOND_PANEL_LAYOUT" class="w-100">
<div [appTelemetryImpression]="telemetryImpression" [ngClass]="layoutConfiguration ? 'sbt-page-content-area' : 'ui container mt-24'">
<div class="content-grid relative9">
<div class="sb-pageSection" *ngIf="!showLoader && totalCount > 0">
<div class="sb-pageSection-header">
<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>
<button appTelemetryInteract [telemetryInteractEdata]="closeIntractEdata" class="sb-btn sb-btn-normal sb-btn-error ml-auto sb-cls-btn" type="button" [routerLink]="['/explore-course']">{{resourceService?.frmelmnts?.btn?.close}} <i class="close icon"></i></button>
</div>
</div>
<div class="twelve wide column" [appTelemetryImpression]="telemetryImpression"
*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>
<div class="sb-grid dynamic-section-card ">
<div [id]="i" [data]="content" class=""
*ngFor="let content of contentList;let i = index;">
<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'}"
(cardClick)="playContent($event)" (enterKey)="playContent($event)" [content]="content"
[cardImg]="content?.appIcon || 'assets/images/book.png'">
</sb-library-card>
</div>
</div>
</div>
<div [appTelemetryImpression]="telemetryImpression" class="twelve wide column" *ngIf="contentList.length === 0 && !showLoader">
<app-no-result [data]="noResultMessage"></app-no-result>
</div>
<div class="twelve wide column" *ngIf="showLoader">
<app-loader [data]='loaderMessage'></app-loader>
</div>
<div class="twelve wide column right aligned py-0" *ngIf="paginationDetails.totalItems > configService.appConfig.SEARCH.PAGE_LIMIT && !showLoader">
<div class="sb-pagination-container flex-jc-flex-end" *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) ">«</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)"><</a>
<a href=“javascript:void(0);” 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">></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 ">»</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>