File

src/app/modules/public/module/course/components/course-consumption/public-course-consumption-page/public-course-consumption-page.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods

Constructor

constructor(navigationHelperService: NavigationHelperService, activatedRoute: ActivatedRoute, courseConsumptionService: CourseConsumptionService, toasterService: ToasterService, resourceService: ResourceService, router: Router, contentUtilsServiceService: ContentUtilsServiceService, configService: ConfigService, telemetryService: TelemetryService, generaliseLabelService: GeneraliseLabelService, layoutService: LayoutService, utilService: UtilService, connectionService: ConnectionService, contentManagerService: ContentManagerService, offlineCardService: OfflineCardService, courseBatchService: CourseBatchService)
Parameters :
Name Type Optional
navigationHelperService NavigationHelperService No
activatedRoute ActivatedRoute No
courseConsumptionService CourseConsumptionService No
toasterService ToasterService No
resourceService ResourceService No
router Router No
contentUtilsServiceService ContentUtilsServiceService No
configService ConfigService No
telemetryService TelemetryService No
generaliseLabelService GeneraliseLabelService No
layoutService LayoutService No
utilService UtilService No
connectionService ConnectionService No
contentManagerService ContentManagerService No
offlineCardService OfflineCardService No
courseBatchService CourseBatchService No

Methods

checkDownloadStatus
checkDownloadStatus()
Returns : void
checkStatus
checkStatus(status)
Parameters :
Name Optional
status No
Returns : any
closeSharePopup
closeSharePopup(id)
Parameters :
Name Optional
id No
Returns : void
deleteCollection
deleteCollection(collectionData)
Parameters :
Name Optional
collectionData No
Returns : void
downloadCollection
downloadCollection(collection)
Parameters :
Name Optional
collection No
Returns : void
exportCollection
exportCollection(collection)
Parameters :
Name Optional
collection No
Returns : void
getAllBatchDetails
getAllBatchDetails()
Returns : void
isEnrollmentAllowed
isEnrollmentAllowed(enrollmentEndDate)
Parameters :
Name Optional
enrollmentEndDate No
Returns : any
isValidEnrollmentEndDate
isValidEnrollmentEndDate(enrollmentEndDate)
Parameters :
Name Optional
enrollmentEndDate No
Returns : boolean
isYoutubeContentPresent
isYoutubeContentPresent(collection)
Parameters :
Name Optional
collection No
Returns : void
logTelemetry
logTelemetry(id, content?: literal type)
Parameters :
Name Type Optional
id No
content literal type Yes
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onShareLink
onShareLink()
Returns : void
redirectToExplore
redirectToExplore()
Returns : void
setTelemetryShareData
setTelemetryShareData(param)
Parameters :
Name Optional
param No
Returns : void
showJoinModal
showJoinModal(event)
Parameters :
Name Optional
event No
Returns : void
updateCollection
updateCollection(collection)
Parameters :
Name Optional
collection No
Returns : void

Properties

batchList
Type : []
Default value : []
contentDownloadStatus
Type : object
Default value : {}
Public contentUtilsServiceService
Type : ContentUtilsServiceService
Public courseBatchService
Type : CourseBatchService
Public courseHierarchy
Type : any
Public courseId
Type : string
disableDelete
Default value : false
enrollmentEndDate
Type : string
Public generaliseLabelService
Type : GeneraliseLabelService
isAvailableLocally
Default value : false
isConnected
Default value : false
isDesktopApp
Default value : false
layoutConfiguration
Type : any
Public layoutService
Type : LayoutService
Public navigationHelperService
Type : NavigationHelperService
Public resourceService
Type : ResourceService
Public router
Type : Router
shareLink
Type : string
sharelinkModal
Type : boolean
showDeleteModal
Default value : false
showDownloadLoader
Default value : false
Public showError
Default value : false
showExportLoader
Default value : false
Public showLoader
Default value : true
showModal
Default value : false
showUpdate
Default value : false
Public telemetryCourseImpression
Type : IImpressionEventInput
telemetryShareData
Type : Array<ITelemetryShare>

telemetryShareData

Public toasterService
Type : ToasterService
todayDate
Default value : dayjs(new Date()).format('YYYY-MM-DD')
Public unsubscribe
Default value : new Subject<void>()
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ResourceService, ToasterService, ConfigService, ContentUtilsServiceService, ITelemetryShare,
  LayoutService, UtilService } from '@sunbird/shared';
import { CourseBatchService, CourseConsumptionService } from '@sunbird/learn';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import * as _ from 'lodash-es';
import { IImpressionEventInput, TelemetryService } from '@sunbird/telemetry';
import { NavigationHelperService, ConnectionService, OfflineCardService, ServerResponse } from '@sunbird/shared';
import { GeneraliseLabelService } from '@sunbird/core';
import { ContentManagerService } from '../../../../offline/services/content-manager/content-manager.service';
import dayjs from 'dayjs';

@Component({
  templateUrl: './public-course-consumption-page.component.html',
  styleUrls: ['./public-course-consumption-page.component.scss']
})
export class PublicCourseConsumptionPageComponent implements OnInit, OnDestroy {
  public courseId: string;
  public showLoader = true;
  public showError = false;
  public courseHierarchy: any;
  layoutConfiguration: any;
  sharelinkModal: boolean;
  shareLink: string;
  public telemetryCourseImpression: IImpressionEventInput;
  batchList = [];
  enrollmentEndDate: string;
  todayDate = dayjs(new Date()).format('YYYY-MM-DD');

  // Desktop App
  isDesktopApp = false;
  isConnected = false;
  contentDownloadStatus = {};
  showUpdate = false;
  showExportLoader = false;
  showModal = false;
  showDownloadLoader = false;
  disableDelete = false;
  isAvailableLocally = false;
  showDeleteModal = false;

  /**
   * telemetryShareData
  */
  telemetryShareData: Array<ITelemetryShare>;

  public unsubscribe = new Subject<void>();
  constructor(public navigationHelperService: NavigationHelperService, private activatedRoute: ActivatedRoute,
    private courseConsumptionService: CourseConsumptionService, public toasterService: ToasterService,
    public resourceService: ResourceService, public router: Router, public contentUtilsServiceService: ContentUtilsServiceService,
    private configService: ConfigService, private telemetryService: TelemetryService,
    public generaliseLabelService: GeneraliseLabelService, public layoutService: LayoutService,
    private utilService: UtilService,
    private connectionService: ConnectionService,
    private contentManagerService: ContentManagerService,
    private offlineCardService: OfflineCardService,
    public courseBatchService: CourseBatchService
    ) {
  }

  showJoinModal(event) {
    this.courseConsumptionService.showJoinCourseModal.emit(event);
  }

  ngOnInit() {
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.layoutService.switchableLayout().
      pipe(takeUntil(this.unsubscribe)).subscribe(layoutConfig => {
        if (layoutConfig != null) {
          this.layoutConfiguration = layoutConfig.layout;
        }
      });
    this.isDesktopApp = this.utilService.isDesktopApp;
    if (this.isDesktopApp) {
      this.connectionService.monitor().pipe(takeUntil(this.unsubscribe)).subscribe(isConnected => {
        this.isConnected = isConnected;
      });
      this.contentManagerService.contentDownloadStatus$.pipe(takeUntil(this.unsubscribe)).subscribe( contentDownloadStatus => {
        this.contentDownloadStatus = contentDownloadStatus;
        this.checkDownloadStatus();
      });
    }
    this.showLoader = true;
    const routeParams: any = {...this.activatedRoute.snapshot.firstChild.params };
    this.courseId = routeParams.courseId;
    this.getAllBatchDetails();
    if (!this.courseId) {
      return this.redirectToExplore();
    }
    const inputParams = {params: this.configService.appConfig.CourseConsumption.contentApiQueryParams};
    this.courseConsumptionService.getCourseHierarchy(this.courseId, inputParams).pipe(takeUntil(this.unsubscribe))
    .subscribe((courseHierarchy: any) => {
      this.courseHierarchy = courseHierarchy;
      this.layoutService.updateSelectedContentType.emit(this.courseHierarchy.contentType);
      this.showLoader = false;
    }, (error) => {
      if (_.isEqual(_.get(error, 'error.responseCode'), 'RESOURCE_NOT_FOUND')) {
        this.toasterService.error(this.generaliseLabelService.messages.emsg.m0002);
      } else {
        this.toasterService.error(this.resourceService.messages.emsg.m0005);
      }
      this.redirectToExplore();
    });
  }

  getAllBatchDetails() {
    this.batchList = [];
    const searchParams: any = {
      filters: {
        status: '1',
        courseId: this.courseId
      },
      offset: 0,
      sort_by: { createdDate: 'desc' }
    };
    searchParams.filters.enrollmentType = 'open';
    this.courseBatchService.getAllBatchDetails(searchParams).pipe(
      takeUntil(this.unsubscribe))
      .subscribe((data: ServerResponse) => {
        if (data.result.response.content && data.result.response.content.length > 0) {
          this.batchList = data.result.response.content;
          this.enrollmentEndDate = _.get(this.batchList[0], 'enrollmentEndDate');
        }
      },
      (err: ServerResponse) => {
        this.showError = true;
        this.toasterService.error(this.resourceService.messages.fmsg.m0004);
      });
  }

  isEnrollmentAllowed(enrollmentEndDate) {
    return dayjs(enrollmentEndDate).isBefore(this.todayDate);
  }

  isValidEnrollmentEndDate(enrollmentEndDate) {
    return !!enrollmentEndDate;
  }

  onShareLink() {
    this.sharelinkModal = true;
    this.shareLink = this.contentUtilsServiceService.getCoursePublicShareUrl(this.courseHierarchy.identifier);
    this.setTelemetryShareData(this.courseHierarchy);
  }
  setTelemetryShareData(param) {
    this.telemetryShareData = [{
      id: param.identifier,
      type: param.contentType,
      ver: param.pkgVersion ? param.pkgVersion.toString() : '1.0'
    }];
  }

  redirectToExplore() {
    this.navigationHelperService.navigateToResource('explore?selectedTab=course');
  }

  closeSharePopup(id) {
    this.sharelinkModal = false;
    const interactData = {
      context: {
        env: _.get(this.activatedRoute.snapshot.data.telemetry, 'env') || 'explore',
        cdata: []
      },
      edata: {
        id: id,
        type: 'click',
        pageid: _.get(this.activatedRoute.snapshot.data.telemetry, 'pageid') || 'explore-course-toc',
      },
      object: {
        id: _.get(this.courseHierarchy, 'identifier'),
        type: _.get(this.courseHierarchy, 'contentType') || 'Course',
        ver: `${_.get(this.courseHierarchy, 'pkgVersion')}` || `1.0`,
        rollup: { l1: this.courseId }
      }
    };
    this.telemetryService.interact(interactData);
  }

  logTelemetry(id, content?: {}) {
    let objectRollUp;
    if (content) {
      objectRollUp = this.courseConsumptionService.getContentRollUp(this.courseHierarchy, _.get(content, 'identifier'));
    }
    const interactData = {
      context: {
        env: _.get(this.activatedRoute.snapshot.data.telemetry, 'env') || 'content',
        cdata: []
      },
      edata: {
        id: id,
        type: 'click',
        pageid: _.get(this.activatedRoute.snapshot.data.telemetry, 'pageid') || 'explore-course',
      },
      object: {
        id: content ? _.get(content, 'identifier') : this.activatedRoute.snapshot.params.courseId,
        type: content ? _.get(content, 'contentType') : 'Course',
        ver: content ? `${_.get(content, 'pkgVersion')}` : `1.0`,
        rollup: objectRollUp ? this.courseConsumptionService.getRollUp(objectRollUp) : {}
      }
    };
    this.telemetryService.interact(interactData);
  }

  checkStatus(status) {
    this.checkDownloadStatus();
    return this.utilService.getPlayerDownloadStatus(status, this.courseHierarchy);
  }

  checkDownloadStatus() {
    if (this.courseHierarchy) {
      const downloadStatus = ['CANCELED', 'CANCEL', 'FAILED', 'DOWNLOAD'];
      const status = this.contentDownloadStatus[this.courseHierarchy.identifier];
      this.courseHierarchy['downloadStatus'] = _.isEqual(downloadStatus, status) ? 'DOWNLOAD' :
      (_.includes(['INPROGRESS', 'RESUME', 'INQUEUE'], status) ? 'DOWNLOADING' : _.isEqual(status, 'COMPLETED') ? 'DOWNLOADED' : status);
    }
  }
  updateCollection(collection) {
    collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
    this.logTelemetry('update-collection');
    const request = {
      contentId: collection.identifier
    };
    this.contentManagerService.updateContent(request).pipe(takeUntil(this.unsubscribe)).subscribe(data => {
      collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
      this.showUpdate = false;
    }, (err) => {
      this.showUpdate = true;
      const errorMessage = !this.isConnected ? _.replace(this.resourceService.messages.smsg.m0056, '{contentName}', collection.name) :
        this.resourceService.messages.fmsg.m0096;
      this.toasterService.error(errorMessage);
    });
  }

  exportCollection(collection) {
    this.logTelemetry('export-collection');
    this.showExportLoader = true;
    this.contentManagerService.exportContent(collection.identifier)
      .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);
        }
      });
  }

  isYoutubeContentPresent(collection) {
    this.logTelemetry('is-youtube-in-collection');
    this.showModal = this.offlineCardService.isYoutubeContent(collection);
    if (!this.showModal) {
      this.downloadCollection(collection);
    }
  }

  downloadCollection(collection) {
    this.showDownloadLoader = true;
    this.disableDelete = false;
    collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
    this.logTelemetry('download-collection');
    this.contentManagerService.downloadContentId = collection.identifier;
    this.contentManagerService.downloadContentData = collection;
    this.contentManagerService.failedContentName = collection.name;
    this.contentManagerService.startDownload({}).pipe(takeUntil(this.unsubscribe)).subscribe(data => {
      this.contentManagerService.downloadContentId = '';
      this.contentManagerService.downloadContentData = {};
      this.showDownloadLoader = false;
      collection['downloadStatus'] = this.resourceService.messages.stmsg.m0140;
    }, error => {
      this.disableDelete = true;
      this.showDownloadLoader = false;
      this.contentManagerService.downloadContentId = '';
      this.contentManagerService.downloadContentData = {};
      this.contentManagerService.failedContentName = '';
      collection['downloadStatus'] = this.resourceService.messages.stmsg.m0138;
      if (!(error.error.params.err === 'LOW_DISK_SPACE')) {
        this.toasterService.error(this.resourceService.messages.fmsg.m0090);
          }
    });
  }

  deleteCollection(collectionData) {
    this.disableDelete = true;
    this.logTelemetry('delete-collection');
    const request = {request: {contents: [collectionData.identifier]}};
    this.contentManagerService.deleteContent(request).pipe(takeUntil(this.unsubscribe)).subscribe(data => {
      this.toasterService.success(this.resourceService.messages.stmsg.desktop.deleteCourseSuccessMessage);
      collectionData['downloadStatus'] = 'DOWNLOAD';
      collectionData['desktopAppMetadata.isAvailable'] = false;
      this.redirectToExplore();
    }, err => {
      this.disableDelete = false;
      this.toasterService.error(this.resourceService.messages.etmsg.desktop.deleteCourseErrorMessage);
    });
  }
  ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }
}
<!-- Back Button Previous Module & Next Module button -->
<div
  [ngClass]="layoutConfiguration ? 'sb-back-actionbar' : 'sb-bg-color-white back-btn-container cc-player__btn-back relative9'"
  class="relative position mt-0">
  <div class="ui container py-0 px-0 d-flex flex-ai-center">
    <div class="py-0 d-flex flex-ai-center w-100">
      <!-- /* Back button */ -->
      <button type="button" [ngClass]="layoutConfiguration ? 'sb-btn-primary sb-btn-round' : 'sb-btn-link sb-btn-link-primary sb-left-icon-btn px-0'" class="sb-btn sb-btn-normal" tabindex="0" (click)="redirectToExplore()" attr.aria-label="{{resourceService?.frmelmnts?.btn?.back}}">
        <i class="icon-svg icon-svg--xxs icon-back mr-4"><svg class="icon icon-svg--primary">
            <use xlink:href="assets/images/sprite.svg#arrow-long-left"></use>
          </svg></i>
        <span>{{resourceService?.frmelmnts?.btn?.back}}</span>
      </button>
      <!-- Textbook details with continue playing and join course button -->
      <div class="textbook d-flex flex-ai-center w-100 ml-16" *ngIf="!showLoader && !showError">
        <!-- Textbook details -->
        <div class="textbook__details d-flex flex-ai-center">
          <!-- Textbook image -->
          <div class="textbook__bookimg">
            <img src="{{courseHierarchy?.appIcon || 'assets/images/book.png'}}" alt="{{courseHierarchy?.name}}">
          </div>
          <div class="ml-8 textbook__heading">
            <!-- Textbook title -->
            <h5 class="textbook__title sb-color-primary font-weight-bold mb-0" tabindex="0">{{courseHierarchy?.name}}
            </h5>
            <!-- Textbook Rating with share icon -->
            <div class="textbook__rating d-flex flex-ai-center">
              <sui-rating class="ui star rating" [isReadonly]="true" [ngModel]="courseHierarchy.me_averageRating || 0"
                [maximum]="5"></sui-rating>

              <button tabindex="0" (click)="onShareLink()"
                class="sb-btn sb-btn-normal sb-btn-link sb-btn-link-primary sb-left-icon-btn ml-8 sb-btn-icon-fix">
                <i class="icon-svg icon-svg--xs icon-share mr-8"><svg class="icon icon-svg--primary">
                    <use xlink:href="assets/images/sprite.svg#share"></use>
                  </svg></i>
                {{resourceService?.frmelmnts?.lbl?.share}}
              </button>
            </div>
          </div>
        </div>
        <div class="batch-details__created mt-8 fsmall mx-8" *ngIf="isValidEnrollmentEndDate(enrollmentEndDate)">
          <span class="sb-label-12size"
            *ngIf="!isEnrollmentAllowed(enrollmentEndDate)">{{resourceService?.messages?.stmsg?.m0136}}
            {{enrollmentEndDate | dateFormat}}</span>
          <span class="sb-label-status-error"
            *ngIf="isEnrollmentAllowed(enrollmentEndDate)">{{resourceService?.messages?.emsg?.m008 | interpolate:'{endDate}':enrollmentEndDate}}</span>
        </div>
        <div class="certified-course mx-8" [ngClass]="{'d-flex': isDesktopApp}">
          <div class="certified-course__btn" *ngIf="!enrolledCourse && !courseMentor">
            <button class="sb-btn sb-btn-secondary sb-btn-normal ml-auto textbook__addbtn" tabindex="0"
            [disabled]="isEnrollmentAllowed(enrollmentEndDate)"
            [ngClass]="{'sb-btn-disabled': isEnrollmentAllowed(enrollmentEndDate)}"
              (click)="showJoinModal(true); logTelemetry(courseHierarchy?.primaryCategory.toLowerCase() === 'course' ? 'join-course' : 'join', courseHierarchy);">{{generaliseLabelService?.frmelmnts?.btn?.enroll}}</button>
          </div>
          <div *ngIf="isDesktopApp && !enrolledCourse && !courseMentor" class="d-flex">
            <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
              *ngIf="isConnected && (checkStatus('DOWNLOADED')) && showUpdate" tabindex="0"
              (click)="updateCollection(courseHierarchy)">{{resourceService?.frmelmnts?.btn?.update}}</button>
            <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
              *ngIf="checkStatus('DOWNLOADED')" [disabled]="disableDelete" tabindex="0"
              (click)="logTelemetry('confirm-delete-collection'); showDeleteModal = !showDeleteModal;">{{resourceService?.frmelmnts?.btn?.delete}}</button>
            <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
              *ngIf="checkStatus('DOWNLOADED')" tabindex="0"
              (click)="exportCollection(courseHierarchy)">{{resourceService?.frmelmnts?.lbl?.saveToPenDrive}}</button>
            <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
              *ngIf="checkStatus('DOWNLOAD')" appOnlineOnly tabindex="0"
              (click)="isYoutubeContentPresent(courseHierarchy)">{{resourceService?.frmelmnts?.btn?.download}}</button>
            <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
              *ngIf="checkStatus('DOWNLOADING')">{{resourceService?.frmelmnts?.lbl?.downloading}}</button>
            <button type="button" class="sb-btn sb-btn-outline-primary sb-btn-normal mr-8"
              *ngIf="checkStatus('PAUSED')">{{resourceService.frmelmnts?.lbl?.downloadingPaused}}</button>
          </div>
        </div>
      </div>

    </div>
  </div>
</div>

<div [ngClass]="layoutConfiguration ? 'sbt-inside-page-container' : 'pt-16'">

  <router-outlet *ngIf="!showLoader && !showError"></router-outlet>
  <div *ngIf="showLoader" class="ui container">
    <app-loader></app-loader>
  </div>
</div>

<app-modal-wrapper *ngIf="sharelinkModal" [config]="{disableClose: false, panelClass: 'material-modal'}"
  (dismiss)="closeSharePopup('close-share-link-popup')">
  <ng-template sbModalContent>
    <app-share-link [shareLink]="shareLink" [telemetryShareData]="telemetryShareData">
    </app-share-link>
  </ng-template>
</app-modal-wrapper>

<div *ngIf="isDesktopApp">
  
    <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)="downloadCollection(courseHierarchy); showModal = !showModal;">
                  {{resourceService.frmelmnts?.btn?.download}}
                </button>
                <button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0"
                  (click)="logTelemetry('cancel-download-collection'); showModal = !showModal;">
                  {{resourceService.frmelmnts?.btn?.cancel}}
                </button>
              </div>
            </div>
          </div>
        </div>
      </ng-template>
    </app-modal-wrapper>
    
    
    <app-modal-wrapper *ngIf="showDeleteModal" [config]="{disableClose: true, size: 'normal'}"
      (dismiss)="showDeleteModal = !showDeleteModal;" #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?.lbl?.delete}}
              </div>
              <div class="sb-modal-content">
                <p>{{resourceService?.frmelmnts?.lbl?.desktop?.deleteCourse | interpolate:'{name}': courseHierarchy?.name}}
                </p>
              </div>
              <div class="sb-modal-actions">
                <button class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0"
                  (click)="deleteCollection(courseHierarchy); showDeleteModal = !showDeleteModal;">
                  {{resourceService?.frmelmnts?.lbl?.delete}}
                </button>
                <button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0"
                  (click)="logTelemetry('cancel-delete-collection'); showDeleteModal = !showDeleteModal;">
                  {{resourceService.frmelmnts?.btn?.cancel}}
                </button>
              </div>
            </div>
          </div>
        </div>
      </ng-template>
    </app-modal-wrapper>
</div>

./public-course-consumption-page.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;

::ng-deep {
    .ui.tiny.progress .bar {
        min-width: 0
    }

}

.back-btn-container {
    z-index: 1;

    .modulebtn-divider {
        width: calculateRem(1px);
        height: calculateRem(24px);
        background: var(--gray-200);
        display: inline-block;
        margin: 0 calculateRem(8px);
    }
}

.certified-course {
    justify-self: end;
    align-self: center;
}

.textbook {
    &-container {
        box-shadow: 0 0 calculateRem(10px) 0 rgba(0, 0, 0, 0.25);
        position: relative;
        background-color: var(--gray-0);
    }

    &__details {
        flex: 1;
        min-width: 0;
    }

    &__bookimg {
        width: calculateRem(48px);
        height: calculateRem(48px);
        img {
            width: calculateRem(48px);
            height: calculateRem(48px);
        }
    }

    &__heading {
        min-width: 0;

        .textbook__title {
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
    }

    &__addbtn {
        white-space: nowrap;
    }
}

@include respond-below(sm) {
    .certified-course {
        justify-self: start;
    }

    .certified-course__btn {
        margin-top: calculateRem(8px);
    }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""