File

src/app/modules/public/module/offline/components/library/library.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods
HostListeners

Constructor

constructor(activatedRoute: ActivatedRoute, router: Router, utilService: UtilService, toasterService: ToasterService, configService: ConfigService, resourceService: ResourceService, publicPlayerService: PublicPlayerService, searchService: SearchService, connectionService: ConnectionService, navigationHelperService: NavigationHelperService, telemetryService: TelemetryService, contentManagerService: ContentManagerService, offlineCardService: OfflineCardService, systemInfoService: SystemInfoService, layoutService: LayoutService, userService: UserService, orgDetailsService: OrgDetailsService)
Parameters :
Name Type Optional
activatedRoute ActivatedRoute No
router Router No
utilService UtilService No
toasterService ToasterService No
configService ConfigService No
resourceService ResourceService No
publicPlayerService PublicPlayerService No
searchService SearchService No
connectionService ConnectionService No
navigationHelperService NavigationHelperService No
telemetryService TelemetryService No
contentManagerService ContentManagerService No
offlineCardService OfflineCardService No
systemInfoService SystemInfoService No
layoutService LayoutService No
userService UserService No
orgDetailsService OrgDetailsService No

HostListeners

window:scroll
window:scroll()

Methods

addHoverData
addHoverData()
Returns : void
constructSearchRequest
constructSearchRequest()
Returns : any
downloadContent
downloadContent(contentId)
Parameters :
Name Optional
contentId No
Returns : void
exportContent
exportContent(contentId)
Parameters :
Name Optional
contentId No
Returns : void
fetchContentOnParamChange
fetchContentOnParamChange()
Returns : void
fetchContents
fetchContents(isFilterChange?: boolean)
Parameters :
Name Type Optional
isFilterChange boolean Yes
Returns : void
fetchCurrentPageData
fetchCurrentPageData()
Returns : void
Public getFilters
getFilters(filters)
Parameters :
Name Optional
filters No
Returns : void
getOrgDetails
getOrgDetails()
Returns : void
hideLoader
hideLoader()
Returns : void
hoverActionClicked
hoverActionClicked(event)
Parameters :
Name Optional
event No
Returns : void
initLayout
initLayout()
Returns : void
logTelemetry
logTelemetry(content, actionId)
Parameters :
Name Optional
content No
actionId No
Returns : void
navigateToMyDownloads
navigateToMyDownloads()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onScroll
onScroll()
Decorators :
@HostListener('window:scroll', undefined)
Returns : void
playContent
playContent(event: any)
Parameters :
Name Type Optional
event any No
Returns : void
Private prepareCarouselData
prepareCarouselData(sections: [])
Parameters :
Name Type Optional Default value
sections [] No []
Returns : any
prepareVisits
prepareVisits()
Returns : void
redoLayout
redoLayout()
Returns : void
setTelemetryData
setTelemetryData()
Returns : void
updateCardData
updateCardData()
Returns : void

Properties

Public cardInteractCdata
Type : any
Public cardInteractObject
Type : any
Public carouselMasterData
Type : Array<ICaraouselData>
Default value : []
Public channelId
Type : string
Public contentData
Type : any
contentDownloadStatus
Type : object
Default value : {}
Public contentManagerService
Type : ContentManagerService
contentName
Type : string
currentPageData
Public custodianOrg
Default value : true
Public dataDrivenFilterEvent
Default value : new EventEmitter()
Public dataDrivenFilters
Type : any
Default value : {}
Public defaultFilters
downloadIdentifier
Type : string
facets
FIRST_PANEL_LAYOUT
Public formData
Public globalSearchFacets
Type : Array<string>
Public hashTagId
Type : string
infoData
Public initFilters
Default value : false
isConnected
Default value : navigator.onLine
isDesktopApp
Default value : false
isFilterChanged
Default value : false
languageDirection
Type : string
Default value : 'ltr'
layoutConfiguration
Type : any
Public layoutService
Type : LayoutService
Readonly MAXIMUM_CPU_LOAD
Type : number
Default value : 90
Readonly MINIMUM_REQUIRED_RAM
Type : number
Default value : 100
Public modifiedFilters
Type : any
Public navigationHelperService
Type : NavigationHelperService
organisationId
Type : string
Public pageSections
Type : Array<ICaraouselData>
Default value : []
pageTitle
pageTitleSrc
Public queryParams
Type : any
Public resourceService
Type : ResourceService
Public router
Type : Router
Public searchService
Type : SearchService
SECOND_PANEL_LAYOUT
Public sections
Type : Array<any>
Default value : []
Public selectedFilters
Type : any
showCpuLoadWarning
Default value : false
showDownloadLoader
Default value : false
showExportLoader
Default value : false
showLoadContentModal
Default value : false
Public showLoader
Default value : true
showMinimumRAMWarning
Default value : false
showModal
Default value : false
Public showSectionLoader
Default value : false
slideConfig
Default value : this.configService.appConfig.AllDownloadsSection.slideConfig
Public slug
Type : string
svgToDisplay
Public telemetryImpression
Type : IImpressionEventInput
Public telemetryService
Type : TelemetryService
Public unsubscribe$
Default value : new Subject<void>()
Public userDetails
Type : any
Default value : {}
Public userService
Type : UserService
Public viewAllInteractEdata
Type : IInteractEventEdata
import { Component, OnInit, EventEmitter, HostListener, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute, NavigationStart } from '@angular/router';
import { combineLatest, Subject } from 'rxjs';
import { tap, filter, takeUntil, first, debounceTime, delay } from 'rxjs/operators';
import * as _ from 'lodash-es';
import {
    OfflineCardService, ResourceService, ToasterService, ConfigService, UtilService, ICaraouselData,
    NavigationHelperService, ILanguage,  LayoutService, COLUMN_TYPE, ConnectionService
} from '@sunbird/shared';
import { SearchService, UserService, OrgDetailsService } from '@sunbird/core';
import { PublicPlayerService } from '@sunbird/public';
import { IInteractEventEdata, IImpressionEventInput, TelemetryService } from '@sunbird/telemetry';
import { ContentManagerService, SystemInfoService } from '../../services';
@Component({
    selector: 'app-library',
    templateUrl: './library.component.html',
    styleUrls: ['./library.component.scss']
})
export class LibraryComponent implements OnInit, OnDestroy {

    public showLoader = true;
    public showSectionLoader = false;
    public queryParams: any;
    public hashTagId: string;
    public dataDrivenFilters: any = {};
    public slug: string;
    organisationId: string;
    public carouselMasterData: Array<ICaraouselData> = [];
    public pageSections: Array<ICaraouselData> = [];

    public sections: Array<any> = [];
    public initFilters = false;
    public userDetails: any = {};
    public selectedFilters: any;

    public dataDrivenFilterEvent = new EventEmitter();
    public unsubscribe$ = new Subject<void>();

    public modifiedFilters: any;

    isConnected = navigator.onLine;
    slideConfig = this.configService.appConfig.AllDownloadsSection.slideConfig;
    showExportLoader = false;
    showDownloadLoader = false;
    contentName: string;
    infoData;
    languageDirection = 'ltr';
    isFilterChanged = false;
    showModal = false;
    showLoadContentModal = false;
    downloadIdentifier: string;
    readonly MINIMUM_REQUIRED_RAM = 100;
    readonly MAXIMUM_CPU_LOAD = 90;
    showMinimumRAMWarning = false;
    showCpuLoadWarning = false;
    isDesktopApp = false;
    contentDownloadStatus = {};
    /* Telemetry */
    public viewAllInteractEdata: IInteractEventEdata;
    public telemetryImpression: IImpressionEventInput;
    public cardInteractObject: any;
    public cardInteractCdata: any;
    public contentData: any;

    layoutConfiguration: any;
    FIRST_PANEL_LAYOUT;
    SECOND_PANEL_LAYOUT;
    pageTitle;
    svgToDisplay;
    pageTitleSrc;
    facets;
    currentPageData;
    public channelId: string;
    public custodianOrg = true;
    public defaultFilters;
    public formData;
    public globalSearchFacets: Array<string>;

    @HostListener('window:scroll', []) onScroll(): void {
        if ((window.innerHeight + window.scrollY) >= (document.body.offsetHeight * 2 / 3)
            && this.pageSections.length < this.carouselMasterData.length) {
            this.pageSections.push(this.carouselMasterData[this.pageSections.length]);
            this.addHoverData();
        }
    }
    constructor(
        private activatedRoute: ActivatedRoute,
        public router: Router,
        private utilService: UtilService,
        private toasterService: ToasterService,
        private configService: ConfigService,
        public resourceService: ResourceService,
        private publicPlayerService: PublicPlayerService,
        public searchService: SearchService,
        private connectionService: ConnectionService,
        public navigationHelperService: NavigationHelperService,
        public telemetryService: TelemetryService,
        public contentManagerService: ContentManagerService,
        private offlineCardService: OfflineCardService,
        private systemInfoService: SystemInfoService,
        public layoutService: LayoutService,
        public userService: UserService,
        private orgDetailsService: OrgDetailsService
    ) {
     }

    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);
        }
    }

    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();
        });
    }

    fetchCurrentPageData() {
        this.searchService.getContentTypes(true).pipe(takeUntil(this.unsubscribe$)).subscribe(formData => {
            this.currentPageData = _.find(formData, (o) => o.title === 'frmelmnts.lbl.desktop.mylibrary');
            const { contentType, title, theme: { imageName = null } = {} } = this.currentPageData;
            this.pageTitle = _.get(this.resourceService, title);
            this.pageTitleSrc = _.get(this.resourceService, 'RESOURCE_CONSUMPTION_ROOT') + title;
            this.formData = formData;
            this.svgToDisplay = imageName;
            this.globalSearchFacets = _.get(this.currentPageData, 'search.facets');
            this.globalSearchFacets = [
                'se_boards',
                'se_gradeLevels',
                'se_subjects',
                'se_mediums',
                'primaryCategory',
                'mimeType'
              ];
            this.getOrgDetails();
        }, error => {
            this.toasterService.error(this.resourceService.frmelmnts.lbl.fetchingContentFailed);
            this.navigationHelperService.goBack();
        });
    }

    getOrgDetails() {
        this.orgDetailsService.getOrgDetails(this.userService.slug).pipe(
            tap((orgDetails: any) => {
                this.hashTagId = orgDetails.hashTagId;
                this.initFilters = true;
                return this.dataDrivenFilterEvent;
            }), first()
            ).subscribe((filters: any) => {
                this.dataDrivenFilters = filters;
                this.fetchContentOnParamChange();
            },
            error => {
                this.router.navigate(['']);
            }
        );
    }

    ngOnInit() {
        this.isDesktopApp = this.utilService.isDesktopApp;
        this.activatedRoute.queryParams.pipe(takeUntil(this.unsubscribe$)).subscribe(queryParams => {
            this.queryParams = { ...queryParams };
        });
        this.fetchCurrentPageData();
        this.initLayout();
        this.setTelemetryData();
        this.contentManagerService.contentDownloadStatus$.subscribe( contentDownloadStatus => {
            this.contentDownloadStatus = contentDownloadStatus;
            this.updateCardData();
        });
        this.systemInfoService.getSystemInfo().pipe(takeUntil(this.unsubscribe$)).subscribe(data => {
            let { availableMemory } = data.result;
            availableMemory = Math.floor(availableMemory / (1024 * 1024));
            const availableCpuLoad =  _.get(data.result, 'cpuLoad');
            this.showCpuLoadWarning = availableCpuLoad ? Boolean(availableCpuLoad > this.MAXIMUM_CPU_LOAD) : false;

            this.showMinimumRAMWarning = availableMemory ? Boolean(availableMemory < this.MINIMUM_REQUIRED_RAM) : false;
        }, error => {
            this.showCpuLoadWarning = false;
            this.showMinimumRAMWarning = false;
        });

        this.connectionService.monitor()
            .pipe(takeUntil(this.unsubscribe$))
            .subscribe(isConnected => {
                this.isConnected = isConnected;
            });

        this.contentManagerService.completeEvent
            .pipe(takeUntil(this.unsubscribe$))
            .subscribe((data) => {
                const url = this.router.url.split('?');
                if (url[0] === '/mydownloads') {
                    this.fetchContents(false);
                }
            });

        this.router.events
            .pipe(filter((event) => event instanceof NavigationStart), takeUntil(this.unsubscribe$))
            .subscribe(x => { this.prepareVisits(); });

        this.utilService.languageChange
            .pipe(takeUntil(this.unsubscribe$))
            .subscribe((language: ILanguage) => {
                this.languageDirection = language.dir;
            });

        this.utilService.clearSearchQuery();
    }

    fetchContentOnParamChange() {
        combineLatest(this.activatedRoute.params, this.activatedRoute.queryParams)
          .pipe(debounceTime(5),
            delay(10),
            tap(data => this.setTelemetryData()),
            takeUntil(this.unsubscribe$)
          ).subscribe(() => {
            this.showLoader = true;
            this.fetchContents();
        });
    }

    ngOnDestroy() {
        this.unsubscribe$.next();
        this.unsubscribe$.complete();
    }
    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);
        this.carouselMasterData = [];
    }

    constructSearchRequest() {

        const selectedMediaType = _.isArray(_.get(this.queryParams, 'mediaType')) ? _.get(this.queryParams, 'mediaType')[0] :
        _.get(this.queryParams, 'mediaType');
        const mimeType = _.find(_.get(this.currentPageData, 'search.filters.mimeType'), (o) => {
        return o.name === (selectedMediaType || 'all');
        });
        const pageType = _.get(this.queryParams, 'pageTitle');
        const filters: any = _.omit(this.queryParams, ['key', 'sort_by', 'sortType', 'appliedFilters', 'softConstraints', 'selectedTab', 'mediaType', 'contentType', 'board', 'medium', 'gradeLevel', 'subject']);
        if (!filters.channel) {
            filters.channel = this.hashTagId;
        }
        filters.mimeType = _.get(mimeType, 'values');
        
        _.forEach(this.formData, (form, key) => {
        const pageTitle = _.get(this.resourceService, form.title);
        if (pageTitle && pageType && (pageTitle === pageType)) {
            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.currentPageData, 'search.fields'),
            query: this.queryParams.key,
            softConstraints: softConstraints,
            facets: this.globalSearchFacets,
            params: this.configService.appConfig.ExplorePage.contentApiQueryParams || {}
        };
        if (this.queryParams.softConstraints) {
            try {
                option.softConstraints = JSON.parse(this.queryParams.softConstraints);
            } catch {

            }
        }
        return option;
    }

    fetchContents(isFilterChange?: boolean) {
        const shouldGetAllDownloads = !(isFilterChange);
        const option = this.constructSearchRequest();
        this.searchService.contentSearch(option).subscribe(searchRes => {
            if (searchRes) {
                const facets = this.searchService.updateFacetsData(_.get(searchRes, 'result.facets'));
                this.facets = facets.filter(facet => facet.values.length > 0);
                const filteredContents = _.omit(_.groupBy(searchRes['result'].content, 'subject'), ['undefined']);
                const otherContents = _.filter(searchRes['result'].content, (content) => !content.subject );
                // Check for multiple subjects
                for (const [key, value] of Object.entries(filteredContents)) {
                    const isMultipleSubjects = key.split(',').length > 1;
                    if (isMultipleSubjects) {
                        const subjects = key.split(',');
                        subjects.forEach((subject) => {
                            if (filteredContents[subject]) {
                                filteredContents[subject] = _.uniqBy(filteredContents[subject].concat(value), 'identifier');
                            } else {
                                filteredContents[subject] = value;
                            }
                        });
                        delete filteredContents[key];
                    }
                }

                if (!shouldGetAllDownloads && this.sections[0]) {
                    this.sections.splice(1, this.sections.length);
                } else {
                    this.sections = [];
                }
                const contents = []; // to sort the contents/textbooks other than downloads
                for (const section in filteredContents) {
                    if (section) {
                        contents.push({
                            name: section,
                            contents: filteredContents[section].sort((a, b) => a.name.localeCompare(b.name))
                        });
                    }
                }
                // should not affect the download contents order(should be top)
                contents.sort((a, b) => a.name.localeCompare(b.name));
                contents.push({
                    name: this.resourceService.frmelmnts.lbl.other,
                    contents: otherContents.sort((a, b) => a.name.localeCompare(b.name))
                });
                this.sections.push(...contents);

                this.carouselMasterData = this.prepareCarouselData(this.sections);
                this.hideLoader();
                if (!this.carouselMasterData.length) {
                    return; // no page section
                }
                this.pageSections = _.cloneDeep(this.carouselMasterData);
                this.resourceService.languageSelected$.pipe(takeUntil(this.unsubscribe$)).subscribe(item => {
                    this.addHoverData();
                    this.facets = this.searchService.updateFacetsData(this.facets);
                });
            } else {
                this.hideLoader();
                this.carouselMasterData = [];
                this.pageSections = [];
                this.toasterService.error(this.resourceService.messages.fmsg.m0004);
            }
        });
    }

    hideLoader() {
        this.showLoader = false;
        this.showSectionLoader = false;
    }

    addHoverData() {
        _.each(this.pageSections, (pageSection) => {
            _.forEach(pageSection.contents, contents => {
               if (this.contentDownloadStatus[contents.identifier]) {
                   contents['downloadStatus'] = this.contentDownloadStatus[contents.identifier];
               }
            });
            this.pageSections[pageSection] = this.utilService.addHoverData(pageSection.contents, false);
        });
    }

    private prepareCarouselData(sections = []) {
        const { constantData, metaData, dynamicFields } = this.configService.appConfig.ExplorePage;
        const carouselData = _.reduce(sections, (collector, element) => {
            const contents = _.get(element, 'contents') || [];
            element.contents = this.utilService.getDataForCard(contents, constantData, dynamicFields, metaData);
            if (element.contents && element.contents.length) {
                element.contents.forEach((item) => {
                    item.cardImg = item.cardImg || item.courseLogoUrl || 'assets/images/book.png';
                });
                collector.push(element);
            }
            return collector;
        }, []);
        return carouselData;
    }

    setTelemetryData() {
        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.router.url,
                subtype: this.activatedRoute.snapshot.data.telemetry.subtype,
                duration: this.navigationHelperService.getPageLoadTime()
            }
        };
        this.viewAllInteractEdata = {
            id: `view-all-button`,
            type: 'click',
            pageid: 'library'
        };
    }

    prepareVisits() {
        const visits = [];
        _.map(this.sections, section => {
            _.forEach(section.contents, (content, index) => {
                visits.push({
                    objid: content.metaData.identifier,
                    objtype: content.metaData.contentType,
                    index: index,
                    section: section.name,
                });
            });
        });

        this.telemetryImpression.edata.visits = visits;
        this.telemetryImpression.edata.subtype = 'pageexit';
        this.telemetryImpression = Object.assign({}, this.telemetryImpression);
    }

    logTelemetry(content, actionId) {
        const telemetryInteractObject = {
            id: content.metaData.identifier || content.metaData.courseId,
            type: content.metaData.contentType || 'TextBook',
            ver: content.metaData.pkgVersion ? content.metaData.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] || 'library'
            }
        };

        if (telemetryInteractObject) {
            if (telemetryInteractObject.ver) {
                telemetryInteractObject.ver = _.isNumber(telemetryInteractObject.ver) ?
                    _.toString(telemetryInteractObject.ver) : telemetryInteractObject.ver;
            }
            appTelemetryInteractData.object = telemetryInteractObject;
        }
        this.telemetryService.interact(appTelemetryInteractData);
    }

    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.metaData.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;
            case 'SAVE':
                this.showExportLoader = true;
                this.exportContent(_.get(event, 'content.metaData.identifier'));
                telemetryButtonId = this.contentData.mimeType ===
                    'application/vnd.ekstep.content-collection' ? 'export-collection' : 'export-content';
                this.logTelemetry(this.contentData, telemetryButtonId);
                break;
        }
    }

    playContent(event: any) {
        this.publicPlayerService.playContent(event);
    }

    exportContent(contentId) {
        this.contentManagerService.exportContent(contentId)
            .pipe(takeUntil(this.unsubscribe$))
            .subscribe(data => {
                this.showExportLoader = false;
                this.toasterService.success(this.resourceService.messages.smsg.m0059);
            }, error => {
                this.showExportLoader = false;
                if (_.get(error, 'error.responseCode') !== 'NO_DEST_FOLDER') {
                    this.toasterService.error(this.resourceService.messages.fmsg.m0091);
                }
            });
    }

    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.pageSections, (pageSection) => {
                    _.each(pageSection.contents, (pageData) => {
                        pageData['downloadStatus'] = this.resourceService.messages.stmsg.m0138;
                    });
                });
                if (!(error.error.params.err === 'LOW_DISK_SPACE')) {
                this.toasterService.error(this.resourceService.messages.fmsg.m0090);
                  }
            });
    }

    updateCardData() {
        _.each(this.pageSections, (pageSection) => {
            _.each(pageSection.contents, (pageData) => {
                this.publicPlayerService.updateDownloadStatus(this.contentDownloadStatus, pageData);
            });
        });
        this.addHoverData();
    }

    navigateToMyDownloads() {
        this.router.navigate(['/']);
    }
}
<app-landing-section [textToDisplay]="pageTitleSrc" [svgToDisplay]="svgToDisplay"
  [layoutConfiguration]="layoutConfiguration"></app-landing-section>
<div [ngClass]="layoutConfiguration ? 'sbt-fluid-content-bg':''">
  <div class="sb-g" [ngClass]="layoutConfiguration ? 'sb-g sbt-container sbt-page-content' : 'sb-g'"
    [appTelemetryImpression]="telemetryImpression">
    <div [ngClass]="FIRST_PANEL_LAYOUT">
      <div class="sb-desktop-filter-section">
        <div *ngIf="layoutConfiguration">
          <div *ngIf="isDesktopApp">
            <app-network-status></app-network-status>
            <app-load-offline-content></app-load-offline-content>
            <app-system-warning></app-system-warning>
          </div>
        </div>
        <app-global-search-filter [layoutConfiguration]="layoutConfiguration" [facets]="facets" [isOpen]='true'
          *ngIf="initFilters" (filterChange)="getFilters($event)">
        </app-global-search-filter>
      </div>
    </div>
    <div [ngClass]="SECOND_PANEL_LAYOUT">
      <div [appTelemetryImpression]="telemetryImpression"
        [ngClass]="layoutConfiguration ? 'sbt-page-content-area' : 'ui container mt-24'">
        <div>
          <div class="ui container relative9">
            <div class="ui stackable grid m-0">
              <div class="twele wide column p-0">
                <div *ngIf="showLoader">
                  <app-loader [data]='loaderMessage'></app-loader>
                </div>
                <app-global-search-selected-filter [facets]="facets" [selectedFilters]="selectedFilters"
                  *ngIf="initFilters && facets && layoutConfiguration" (filterChange)="getFilters($event)">
                </app-global-search-selected-filter>
                <section *ngFor="let section of pageSections; let index=index;">
                  <div class="sb-desktop-library-card relative9">
                    <sb-library-cards-grid *ngIf="section?.name !== 'Recently Added'" [layoutConfig]="layoutConfiguration"
                      [type]="'infinite_card_grid_with_hover'" [title]="section?.name" [contentList]="section?.contents"
                      [maxCardCount]="3" (hoverActionClick)="hoverActionClicked($event)">
                    </sb-library-cards-grid>
                  </div>
                </section>
                <div class="twelve wide column" *ngIf="!pageSections?.length">
                    <app-no-result-found [title]="resourceService?.messages?.stmsg?.m0030"></app-no-result-found>
                </div>

                <div *ngIf="showSectionLoader">
                  <app-loader [data]='loaderMessage'></app-loader>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<app-load-content *ngIf="showLoadContentModal" (close)="showLoadContentModal = false"></app-load-content>

<!-- Show Modal if content has any YouTube data-->
<app-modal-wrapper *ngIf="showModal" [config]="{disableClose: true, size: 'normal'}" (dismiss)="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>

<app-loader *ngIf="showExportLoader" [data]="{loaderMessage: resourceService.frmelmnts?.lbl?.exportingContent | interpolate:'{contentName}':contentName}"> </app-loader>
<app-loader *ngIf="showDownloadLoader" [data]="{loaderMessage: resourceService.frmelmnts?.lbl?.downloadingContent | interpolate:'{contentName}':contentName}"> </app-loader>

./library.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
:host {
  .page {
    background: rgba(var(--rc-rgba-black), 0.6);
    h6 {
      color: var(--gray-0);
      font-weight: normal;
    }
  }
  .page-container {
    margin: calculateRem(16px) calculateRem(32px);
  }

  .header {
    display: flex;
    flex-direction: row;
    margin: calculateRem(24px) 0 calculateRem(16px) 0;
    align-items: center;
    .title {
      text-overflow: ellipsis;
      overflow: hidden;
      flex: 1;
      height: calculateRem(24px);
      color: var(--primary-color);
      font-size: calculateRem(16px);
      font-weight: bold;
      text-transform: capitalize;
      line-height: calculateRem(24px);
      display: flex;
      align-items: center;
    }
  }

  .sbcardwidth {
    width: calculateRem(292px) !important;
    padding: 0px 0px calculateRem(4px) 0px;
  }
  [dir="rtl"] .sbcardwidth:first-child {
    margin-right: 0px !important;
  }
}

.ui.dimmer .ui.loader:before {
  border-color: rgba(var(--rc-rgba-white), 0.01);
}
.ui.dimmer .ui.loader:after {
  border-color: var(--primary-200) transparent transparent;
}

// sb grid template css
.sbgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(291.98px, 1fr));
  grid-gap: 1rem;
  grid-row-gap: 1.5rem;
}

/* sb-card styles getting overriden by _cards.scss */
:host ::ng-deep {
  .slick-slider .slick-track {
    // width: auto !important;
    padding-top: 0px;
  }
  [dir="ltr"].slick-slider .slick-prev,
  [dir="rtl"].slick-slider .slick-next {
    left: calculateRem(-16px) !important;
    right: auto !important;
  }
  [dir="rtl"].slick-slider .slick-prev,
  [dir="ltr"].slick-slider .slick-next {
    right: calculateRem(-8px) !important;
    left: auto !important;
  }
}
.sb--card:hover {
  transform: none !important;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""