src/app/modules/learn/components/batch/batch-details/batch-details.component.ts
OnInit
OnDestroy
selector | app-batch-details |
styleUrls | batch-details.component.scss |
templateUrl | ./batch-details.component.html |
constructor(resourceService: ResourceService, permissionService: PermissionService, userService: UserService, courseBatchService: CourseBatchService, toasterService: ToasterService, router: Router, activatedRoute: ActivatedRoute, courseProgressService: CourseProgressService, courseConsumptionService: CourseConsumptionService, telemetryService: TelemetryService, generaliseLabelService: GeneraliseLabelService, connectionService: ConnectionService)
|
|||||||||||||||||||||||||||||||||||||||
Parameters :
|
batchId | |
Type : string
|
|
courseHierarchy | |
Type : any
|
|
courseId | |
Type : string
|
|
courseProgressData | |
Type : any
|
|
enrolledBatchInfo | |
Type : any
|
|
enrolledCourse | |
Type : boolean
|
|
allBatchDetails | |
Type : EventEmitter
|
|
batchUpdate | ||||
batchUpdate(batch)
|
||||
Parameters :
Returns :
void
|
createBatch |
createBatch()
|
Returns :
void
|
enrollBatch | ||||
enrollBatch(batch)
|
||||
Parameters :
Returns :
void
|
fetchUserDetails |
fetchUserDetails()
|
Returns :
void
|
getAllBatchDetails |
getAllBatchDetails()
|
Returns :
void
|
getEnrolledCourseBatchDetails |
getEnrolledCourseBatchDetails()
|
Returns :
void
|
getJoinCourseBatchDetails |
getJoinCourseBatchDetails()
|
Returns :
void
|
getSelectedBatches |
getSelectedBatches()
|
Returns :
void
|
isCertAdded | ||||
isCertAdded(batch)
|
||||
Parameters :
Returns :
boolean
|
isEnrollmentAllowed | ||||
isEnrollmentAllowed(enrollmentEndDate)
|
||||
Parameters :
Returns :
any
|
isUnenrollDisabled |
isUnenrollDisabled()
|
Returns :
void
|
isValidEnrollmentEndDate | ||||
isValidEnrollmentEndDate(enrollmentEndDate)
|
||||
Parameters :
Returns :
boolean
|
logTelemetry | ||||||||||||
logTelemetry(id, content?: literal type, batchId?)
|
||||||||||||
Parameters :
Returns :
void
|
navigateToConfigureCertificate | |||||||||
navigateToConfigureCertificate(mode: string, batchId)
|
|||||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
showBatchDetails |
showBatchDetails()
|
Returns :
void
|
ShowCertDetails | ||||||
ShowCertDetails(isEnrolledBatch?: boolean)
|
||||||
Parameters :
Returns :
void
|
showCreateBatch |
showCreateBatch()
|
Returns :
void
|
unenrollBatch | ||||
unenrollBatch(batch)
|
||||
Parameters :
Returns :
void
|
Public activatedRoute |
Type : ActivatedRoute
|
allBatchList |
Type : []
|
Default value : []
|
allowBatchCreation |
Type : boolean
|
allowCertCreation |
Default value : false
|
batchDetails |
Type : literal type
|
batchList |
Type : []
|
Default value : []
|
batchMessage |
Type : string
|
Default value : ''
|
batchStatus |
Type : Number
|
Public courseBatchService |
Type : CourseBatchService
|
Public courseConsumptionService |
Type : CourseConsumptionService
|
courseCreator |
Default value : false
|
courseMentor |
Default value : false
|
Public courseProgressService |
Type : CourseProgressService
|
Public generaliseLabelService |
Type : GeneraliseLabelService
|
isConnected |
Default value : false
|
isDesktopApp |
Default value : false
|
isExpiredBatchEditable |
Default value : true
|
isOpen |
Default value : true
|
isTrackable |
Default value : false
|
isUnenrollbtnDisabled |
Default value : false
|
meritCertPercent |
Type : number
|
Default value : 0
|
ongoingAndUpcomingBatchList |
Type : []
|
Default value : []
|
Public permissionService |
Type : PermissionService
|
progress |
Type : number
|
Default value : 0
|
Public resourceService |
Type : ResourceService
|
Public router |
Type : Router
|
showAllBatchError |
Default value : false
|
showAllBatchList |
Default value : false
|
showBatchDetailsBeforeJoin |
Default value : false
|
showBatchList |
Default value : false
|
showBatchPopup |
Default value : false
|
showCertificateDetails |
Default value : false
|
showCompletionCertificate |
Default value : false
|
showCreateBatchBtn |
Default value : false
|
showError |
Default value : false
|
showJoinModal |
Default value : false
|
showMeritCertificate |
Default value : false
|
showMessageModal |
Default value : false
|
statusOptions |
Type : []
|
Default value : [
{ name: 'Ongoing', value: 1 },
{ name: 'Upcoming', value: 0 },
{ name: 'Expired', value: 2 }
]
|
telemetryCdata |
Type : Array<literal type>
|
Default value : []
|
Public telemetryService |
Type : TelemetryService
|
Public toasterService |
Type : ToasterService
|
tocId |
Type : string
|
Default value : ''
|
todayDate |
Default value : dayjs(new Date()).format('YYYY-MM-DD')
|
Public unsubscribe |
Default value : new Subject<void>()
|
userList |
Type : []
|
Default value : []
|
userNames |
Type : object
|
Default value : {}
|
Public userService |
Type : UserService
|
viewBatch |
Default value : false
|
import { takeUntil } from 'rxjs/operators';
import { combineLatest } from 'rxjs';
import { CourseBatchService, CourseProgressService, CourseConsumptionService } from './../../../services';
import { Router, ActivatedRoute } from '@angular/router';
import { Component, OnInit, Input, OnDestroy, Output, EventEmitter } from '@angular/core';
import { ResourceService, ServerResponse, ToasterService, ConnectionService } from '@sunbird/shared';
import { PermissionService, UserService, GeneraliseLabelService } from '@sunbird/core';
import * as _ from 'lodash-es';
import { TelemetryService } from '@sunbird/telemetry';
import { Subject } from 'rxjs';
import dayjs from 'dayjs';
@Component({
selector: 'app-batch-details',
templateUrl: './batch-details.component.html',
styleUrls: ['batch-details.component.scss']
})
export class BatchDetailsComponent implements OnInit, OnDestroy {
public unsubscribe = new Subject<void>();
batchStatus: Number;
@Input() courseId: string;
@Input() enrolledCourse: boolean;
@Input() enrolledBatchInfo: any;
@Input() batchId: string;
@Input() courseHierarchy: any;
@Input() courseProgressData: any;
isOpen = true;
courseMentor = false;
batchList = [];
userList = [];
showError = false;
userNames = {};
showBatchList = false;
showBatchPopup = false;
statusOptions = [
{ name: 'Ongoing', value: 1 },
{ name: 'Upcoming', value: 0 },
{ name: 'Expired', value: 2 }
];
todayDate = dayjs(new Date()).format('YYYY-MM-DD');
progress = 0;
isUnenrollbtnDisabled = false;
allBatchList = [];
showAllBatchList = false;
showAllBatchError = false;
showJoinModal = false;
telemetryCdata: Array<{}> = [];
@Output() allBatchDetails = new EventEmitter();
allowBatchCreation: boolean;
isTrackable = false;
courseCreator = false;
viewBatch = false;
showCreateBatchBtn = false;
allowCertCreation = false;
ongoingAndUpcomingBatchList = [];
batchMessage = '';
showMessageModal = false;
tocId = '';
isConnected = false;
isDesktopApp = false;
isExpiredBatchEditable = true;
showBatchDetailsBeforeJoin = false;
batchDetails: {};
showCertificateDetails = false;
showCompletionCertificate = false;
showMeritCertificate = false;
meritCertPercent = 0;
constructor(public resourceService: ResourceService, public permissionService: PermissionService,
public userService: UserService, public courseBatchService: CourseBatchService, public toasterService: ToasterService,
public router: Router, public activatedRoute: ActivatedRoute, public courseProgressService: CourseProgressService,
public courseConsumptionService: CourseConsumptionService, public telemetryService: TelemetryService,
public generaliseLabelService: GeneraliseLabelService, private connectionService: ConnectionService) {
this.batchStatus = this.statusOptions[0].value;
}
isUnenrollDisabled() {
this.isUnenrollbtnDisabled = true;
let progressToDisplay = 0;
if (this.courseProgressData) {
this.progress = _.get(this.courseProgressData , 'progress') ? Math.round(this.courseProgressData.progress) : 0;
progressToDisplay = Math.floor((this.courseProgressData.completedCount / this.courseHierarchy.leafNodesCount) * 100);
} else {
return;
}
if ((!this.enrolledBatchInfo.endDate || (this.enrolledBatchInfo.endDate >= this.todayDate)) &&
this.enrolledBatchInfo.enrollmentType === 'open' && this.progress !== 100 && progressToDisplay !== 100) {
this.isUnenrollbtnDisabled = false;
}
if (!this.isConnected) {
this.isUnenrollbtnDisabled = true;
}
}
isValidEnrollmentEndDate(enrollmentEndDate) {
return !!enrollmentEndDate;
}
isEnrollmentAllowed(enrollmentEndDate) {
return dayjs(enrollmentEndDate).isBefore(this.todayDate);
}
ngOnInit() {
this.isDesktopApp = this.userService.isDesktopApp;
this.connectionService.monitor()
.pipe(takeUntil(this.unsubscribe)).subscribe(isConnected => {
this.isConnected = isConnected;
});
this.tocId = _.get(this.activatedRoute, 'snapshot.queryParams.textbook');
this.showCreateBatch();
this.courseConsumptionService.showJoinCourseModal
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => {
this.getJoinCourseBatchDetails();
});
if (this.enrolledCourse === true) {
this.getEnrolledCourseBatchDetails();
} else {
this.getAllBatchDetails();
}
this.courseBatchService.updateEvent.pipe(
takeUntil(this.unsubscribe))
.subscribe((data) => {
this.getAllBatchDetails();
});
}
getAllBatchDetails() {
this.showCreateBatchBtn = false;
this.showBatchList = false;
this.showError = false;
this.batchList = [];
const searchParams: any = {
filters: {
courseId: this.courseId,
status: ['1']
},
offset: 0,
sort_by: { createdDate: 'desc' }
};
const searchParamsCreator = _.cloneDeep(searchParams);
const searchParamsMentor = _.cloneDeep(searchParams);
if (this.courseConsumptionService.canViewDashboard(this.courseHierarchy)) {
searchParamsCreator.filters.status = ['0', '1', '2'];
searchParamsMentor.filters.status = ['0', '1', '2'];
searchParamsCreator.filters.createdBy = this.userService.userid;
searchParamsMentor.filters.mentors = [this.userService.userid];
combineLatest(
this.courseBatchService.getAllBatchDetails(searchParamsCreator),
this.courseBatchService.getAllBatchDetails(searchParamsMentor),
).pipe(takeUntil(this.unsubscribe))
.subscribe((data) => {
const batchList = _.union(data[0].result.response.content, data[1].result.response.content);
this.courseConsumptionService.emitBatchList(batchList);
this.ongoingAndUpcomingBatchList = _.compact(batchList);
this.getSelectedBatches();
if (this.batchList.length > 0) {
this.fetchUserDetails();
} else {
this.showBatchList = true;
}
}, (err) => {
this.showError = true;
if (!this.isDesktopApp || (this.isDesktopApp && this.isConnected)) {
this.toasterService.error(this.resourceService.messages?.fmsg?.m0004);
}
});
} else {
searchParams.filters.enrollmentType = 'open';
this.courseBatchService.getAllBatchDetails(searchParams).pipe(
takeUntil(this.unsubscribe))
.subscribe((data: ServerResponse) => {
this.allBatchDetails.emit(_.get(data, 'result.response'));
if (data.result.response.content && data.result.response.content.length > 0) {
this.batchList = data.result.response.content;
this.fetchUserDetails();
this.showBatchDetails();
this.ShowCertDetails();
} else {
this.showBatchList = true;
}
},
(err: ServerResponse) => {
this.showError = true;
if (!this.isDesktopApp || (this.isDesktopApp && this.isConnected)) {
this.toasterService.error(this.resourceService.messages.fmsg.m0004);
}
});
}
}
getSelectedBatches () {
this.batchList = _.filter(this.ongoingAndUpcomingBatchList, batch => {
return (_.isEqual(batch.status, this.batchStatus));
});
let showCreateBtn = true;
_.filter(this.ongoingAndUpcomingBatchList, batch => {
if (batch.status === 1 || batch.status === 0) {
showCreateBtn = false;
this.isExpiredBatchEditable = false;
return ;
}
});
this.showCreateBatchBtn = showCreateBtn; // this.ongoingAndUpcomingBatchList.length <= 0;
}
getJoinCourseBatchDetails() {
this.showAllBatchList = false;
this.showAllBatchError = false;
this.allBatchList = [];
const searchParams: any = {
filters: {
courseId: this.courseId,
enrollmentType: 'open',
status: ['1']
},
offset: 0,
sort_by: { createdDate: 'desc' }
};
this.courseBatchService.getAllBatchDetails(searchParams)
.pipe(takeUntil(this.unsubscribe))
.subscribe((data) => {
this.allBatchList = _.filter(_.get(data, 'result.response.content'), (batch) => {
return !this.isEnrollmentAllowed(_.get(batch, 'enrollmentEndDate'));
});
// If batch length is 1, then directly join the batch
if (this.allBatchList && this.allBatchList.length === 1) {
this.enrollBatch(this.allBatchList[0]);
} else if (_.isEmpty(this.allBatchList)) {
this.showAllBatchError = true;
} else {
this.showAllBatchList = true;
this.showJoinModal = !(this.allowBatchCreation || this.permissionService.checkRolesPermissions(['COURSE_MENTOR']));
}
}, (err) => {
this.showAllBatchError = true;
if (!this.isDesktopApp || (this.isDesktopApp && this.isConnected)) {
this.toasterService.error(this.resourceService.messages.fmsg.m0004);
}
});
}
showBatchDetails() {
this.showBatchDetailsBeforeJoin = !this.enrolledBatchInfo;
this.batchDetails = this.batchList[0];
}
ShowCertDetails(isEnrolledBatch?: boolean) {
let batchDetails: any;
if (isEnrolledBatch) {
batchDetails = this.enrolledBatchInfo;
} else {
if (this.batchList && this.batchList[0]) {
batchDetails = this.batchList[0];
}
}
this.showCertificateDetails = !(_.isEmpty(_.get(batchDetails, 'certTemplates'))) ? true : false;
const certDetails = _.get(batchDetails, 'certTemplates');
for (const key in certDetails) {
const certCriteria = certDetails[key]['criteria'];
this.showCompletionCertificate = _.get(certCriteria, 'enrollment.status') === 2 ? true : false;
this.showMeritCertificate = _.get(certCriteria, 'assessment.score') ? true : false;
this.meritCertPercent = _.get(certCriteria, 'assessment.score.>=');
}
}
getEnrolledCourseBatchDetails() {
this.ShowCertDetails(true);
if (_.get(this.enrolledBatchInfo, 'participant')) {
const participant = [];
_.forIn(this.enrolledBatchInfo.participant, (value, key) => {
participant.push(key);
});
this.enrolledBatchInfo.participant = participant;
} else {
this.enrolledBatchInfo.participant = [];
}
this.courseProgressService.courseProgressData.pipe(
takeUntil(this.unsubscribe))
.subscribe(courseProgressData => {
this.courseProgressData = courseProgressData;
this.isUnenrollDisabled();
});
}
fetchUserDetails() {
_.forEach(this.batchList, (val) => {
this.userList.push(val.createdBy);
});
this.userList = _.compact(_.uniq(this.userList));
const request = {
filters: {
identifier: this.userList
}
};
this.courseBatchService.getUserList(request).pipe(
takeUntil(this.unsubscribe))
.subscribe((res) => {
_.forEach(res.result.response.content, (user) => {
this.userNames[user.identifier] = user;
});
this.showBatchList = true;
}, (err) => {
this.showError = true;
});
}
batchUpdate(batch) {
if (batch.enrollmentType === 'open') {
this.courseBatchService.setUpdateBatchDetails(batch);
}
this.router.navigate(['update/batch', batch.identifier],
{
queryParams: { enrollmentType: batch.enrollmentType },
relativeTo: this.activatedRoute
});
}
createBatch() {
this.router.navigate(['create/batch'], { relativeTo: this.activatedRoute });
}
enrollBatch(batch) {
this.showJoinModal = false;
if (batch.status === 0) {
this.showMessageModal = true;
this.batchMessage = (this.resourceService.messages.emsg.m009).replace('{startDate}', batch.startDate);
} else {
this.courseBatchService.setEnrollToBatchDetails(batch);
this.router.navigate(['enroll/batch', batch.identifier], {
relativeTo: this.activatedRoute, queryParams: {
autoEnroll: true,
textbook: this.tocId || undefined
}
});
}
}
unenrollBatch(batch) {
// this.courseBatchService.setEnrollToBatchDetails(batch);
const queryParams = this.tocId ? { textbook: this.tocId } : {};
this.router.navigate(['unenroll/batch', batch.identifier], { relativeTo: this.activatedRoute,
queryParams: {...queryParams, primaryCategory: _.get(this.courseHierarchy, 'primaryCategory')}});
}
navigateToConfigureCertificate(mode: string, batchId) {
this.router.navigate([`/certs/configure/certificate`], {
queryParams: {
type: mode,
courseId: this.courseId,
batchId: batchId
}
});
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
/**
* @since - #SH-58
* @description - This method will decide wheather to show the "Create Batch" butto or not
* @returns - boolean
*/
showCreateBatch() {
this.isTrackable = this.courseConsumptionService.isTrackableCollection(this.courseHierarchy);
this.allowBatchCreation = this.courseConsumptionService.canCreateBatch(this.courseHierarchy);
this.viewBatch = this.courseConsumptionService.canViewDashboard(this.courseHierarchy);
this.allowCertCreation = this.courseConsumptionService.canAddCertificates(this.courseHierarchy);
}
isCertAdded(batch) {
return _.isEmpty(_.get(batch, 'cert_templates')) ? false : true;
}
logTelemetry(id, content?: {}, batchId?) {
if (batchId || this.batchId) {
this.telemetryCdata = [{ id: batchId || this.batchId, type: 'courseBatch' }];
}
let objectRollUp;
if (content) {
objectRollUp = this.courseConsumptionService.getContentRollUp(this.courseHierarchy, _.get(content, 'identifier'));
}
const interactData = {
context: {
env: _.get(this.activatedRoute.snapshot.data.telemetry, 'env') || 'Course',
cdata: this.telemetryCdata || []
},
edata: {
id: id,
type: 'click',
pageid: _.get(this.activatedRoute.snapshot.data.telemetry, 'pageid') || 'course-consumption',
},
object: {
id: content ? _.get(content, 'identifier') : this.courseId,
type: content ? _.get(content, 'primaryCategory') : 'Course',
ver: content ? `${_.get(content, 'pkgVersion')}` : `1.0`,
rollup: objectRollUp ? this.courseConsumptionService.getRollUp(objectRollUp) : {}
}
};
this.telemetryService.interact(interactData);
}
}
<!-- Join Course Table -->
<app-modal-wrapper [config]="{disableClose: true}" (dismiss)="showJoinModal = !showJoinModal;" *ngIf="showJoinModal">
<ng-template sbModalContent let-data>
<div class="sb-modal">
<div class="transition ui dimmer page modals active visible">
<div class="ui modal transition active visible normal">
<button aria-label="close dialog" mat-dialog-close class="mat-close-btn">
<span>×</span>
</button>
<div class="sb-modal-header font-weight-normal">
{{resourceService?.frmelmnts?.lbl?.selectBatch}}
</div>
<div class="sb-modal-content" *ngIf="showAllBatchList">
<div class="join-batch">
<div class="join-batch__heading">
<div>{{resourceService?.frmelmnts?.lbl?.availableBatches}}</div>
<div>{{resourceService?.frmelmnts?.lbl?.courseCreatedBy}}</div>
</div>
<div class="join-batch__body" *ngFor="let batch of allBatchList">
<div>{{batch.startDate | dateFormat}}<span *ngIf="batch.endDate"> - {{batch.endDate | dateFormat}}
</span></div>
<div *ngIf="userNames[batch.createdBy]">{{userNames[batch.createdBy].firstName}}
{{userNames[batch.createdBy].lastName}}</div>
<button class="sb-btn sb-btn-outline-secondary sb-btn-normal" tabindex="0"
(click)="enrollBatch(batch); logTelemetry('enroll-batch', courseHierarchy, batch?.identifier)">{{resourceService?.frmelmnts?.lbl?.join}}</button>
</div>
</div>
</div>
<div *ngIf="showAllBatchError">
<div class="sb-no-batch-found">{{resourceService.messages.stmsg.m0081}}</div>
</div>
</div>
</div>
</div>
</ng-template>
</app-modal-wrapper>
<!-- create batch -->
<mat-accordion class="sb-mat-accordion mb-16" *ngIf="isTrackable && viewBatch">
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header tabindex="0" attr.aria-label="{{resourceService?.frmelmnts?.lbl?.batches}} accordion" aria-controls="batches">
<mat-panel-title class="sb-mat-accordion__title d-flex flex-ai-center flex-jc-space-between">
{{resourceService?.frmelmnts?.lbl?.batches}}
</mat-panel-title>
</mat-expansion-panel-header>
<div class="sb-mat-accordion__content" role="region" id="batches" aria-labelledby="batches">
<div class="batch-details">
<div class="mb-16" *ngIf="showBatchList">
<div class="batch-details__dropdown">
<div>
<mat-form-field appearance="fill" class="sb-mat__dropdown w-100 mb-16">
<mat-label>{{resourceService.frmelmnts?.lbl?.batchStatus}}</mat-label>
<mat-select role="listbox" aria-label="Select Status" [(value)]="selectedLanguage"
class="selection"
[(ngModel)]="batchStatus" (selectionChange)="getSelectedBatches()">
<mat-option role="option" *ngFor="let option of statusOptions" [value]="option.value"
attr.aria-label="{{option.name}}">{{option.name}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngFor="let batch of batchList">
<div class="sb-color-primary fmedium font-weight-bold"><i class="calendar outline icon"></i>
{{batch.startDate | dateFormat}}
<span *ngIf="batch.endDate"> - {{batch.endDate | dateFormat}} </span>
</div>
<div class="batch-details__edit d-flex flex-ai-center py-8">
<div *ngIf="allowBatchCreation && allowCertCreation">
<div *ngIf="!isCertAdded(batch)" class="sb-color-primary fnormal font-weight-bold">
<a href="javascript:void(0)" tabindex="0"
(click)="navigateToConfigureCertificate('add', batch?.identifier); logTelemetry('add-certificate')">{{resourceService?.frmelmnts?.cert?.lbl?.addCert}}</a>
</div>
<div *ngIf="isCertAdded(batch)" class="sb-color-primary fnormal font-weight-bold">
<a href="javascript:void(0)" tabindex="0"
(click)="navigateToConfigureCertificate('edit', batch?.identifier); logTelemetry('edit-certificate')">{{resourceService?.frmelmnts?.cert?.lbl?.editCert}}</a>
</div>
</div>
<button class="sb-btn sb-btn-normal sb-btn-outline-primary ml-auto" tabindex="0"
(click)="batchUpdate(batch); logTelemetry('update-batch', courseHierarchy, batch?.identifier);"
[ngClass]="{'sb-btn-disabled': (!isExpiredBatchEditable && batch.status === 2)}"
[disabled]="(!isExpiredBatchEditable && batch.status === 2)">
{{resourceService?.frmelmnts?.lbl?.edit}}
</button>
</div>
<div class="batch-details__created mt-8 fsmall" *ngIf="userNames[batch.createdBy]">
{{resourceService?.frmelmnts?.lbl?.courseCreatedBy}}
{{userNames[batch.createdBy].firstName}} {{userNames[batch.createdBy].lastName}}
</div>
<div class="batch-details__created mt-8 fsmall" *ngIf="isValidEnrollmentEndDate(batch.enrollmentEndDate)">
<span class="sb-label-12size"
*ngIf="!isEnrollmentAllowed(batch.enrollmentEndDate)">{{resourceService.messages.stmsg.m0136}}
{{batch.enrollmentEndDate | dateFormat}}</span>
<span class="sb-label-status-error"
*ngIf="isEnrollmentAllowed(batch.enrollmentEndDate)">{{resourceService.messages.stmsg.m0134}}</span>
</div>
</div>
</div>
<div class="content my-15" *ngIf="batchList.length <= 0">
<div class="sb-no-batch-found">{{resourceService.messages.stmsg.m0081}}</div>
</div>
</div>
<div *ngIf="showError">
<div class="sb-no-batch-found">{{resourceService.messages.stmsg.m0081}}</div>
</div>
<div class="batch-deatils__button text-right" *ngIf="isTrackable && showCreateBatchBtn">
<button class="sb-btn sb-btn-primary sb-btn-normal width-100" tabindex="0"
(click)="createBatch(); logTelemetry('create-batch', courseHierarchy);"
*ngIf="allowBatchCreation">{{resourceService.frmelmnts.lbl.createbatch}}</button>
</div>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
<!-- batch details -->
<mat-accordion class="sb-mat-accordion mb-16" *ngIf="showBatchDetailsBeforeJoin">
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title class="sb-mat-accordion__title d-flex flex-ai-center flex-jc-space-between">
{{resourceService?.frmelmnts?.lbl?.batchdetails}}
</mat-panel-title>
</mat-expansion-panel-header>
<div class="sb-mat-accordion__content">
<div class="batch-details">
<div class="mb-16">
<div *ngIf="batchDetails?.startDate">
<div class="content-metadeta__title fsmall font-weight-bold mb-8 sb-color-gray-800">
{{resourceService?.frmelmnts?.lbl?.coursebatchstartdate}}</div>
<div class="content-metadeta__text fnormal sb-color-gray-400">{{batchDetails?.startDate | dateFormat}}
</div>
</div>
<hr class="section-hr" *ngIf="batchDetails?.endDate" />
<div *ngIf="batchDetails?.endDate">
<div class="content-metadeta__title fsmall font-weight-bold mb-8 sb-color-gray-800">
{{resourceService?.frmelmnts?.lbl?.coursebatchenddate}}</div>
<div class="content-metadeta__text fnormal sb-color-gray-400">{{batchDetails?.endDate | dateFormat}}</div>
</div>
<hr class="section-hr" *ngIf="isValidEnrollmentEndDate(batchDetails?.enrollmentEndDate)" />
<div *ngIf="isValidEnrollmentEndDate(batchDetails?.enrollmentEndDate)">
<div class="content-metadeta__title fsmall font-weight-bold mb-8 sb-color-gray-800">
{{resourceService?.frmelmnts?.lbl?.enrollmentenddate}}</div>
<div class="content-metadeta__text fnormal sb-color-gray-400"> {{batchDetails?.enrollmentEndDate |
dateFormat}}</div>
<div class="sb-label-status-error fsmall" *ngIf="isEnrollmentAllowed(batchDetails?.enrollmentEndDate)">
{{resourceService?.messages?.emsg?.m008 | interpolate:'{endDate}':batchDetails?.enrollmentEndDate}}</div>
</div>
</div>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
<mat-accordion *ngIf="showCertificateDetails" class="sb-mat-accordion mb-16">
<mat-expansion-panel>
<mat-expansion-panel-header title class="sb-mat-accordion__title d-flex flex-ai-center flex-jc-space-between">
<mat-panel-title>
<span>{{resourceService?.frmelemnts?.scttl?.certques}}</span>
</mat-panel-title>
</mat-expansion-panel-header>
<div class="sb-mat-accordion__content">
<div class="batch-details">
<div class="mb-16">
<ul>
<li *ngIf="showCompletionCertificate" class="fsmall mb-8 sb-color-gray-800">
{{resourceService?.frmelmnts?.bltpt?.earnyourcert}}</li>
<li *ngIf="showMeritCertificate" class="fsmall mb-8 sb-color-gray-800">
{{resourceService?.frmelemnts?.bltpt?.earnmcert |
interpolate:'{percent}': meritCertPercent}}</li>
</ul>
</div>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
<!-- Leave batch card -->
<mat-accordion class="sb-mat-accordion mb-16"
*ngIf="enrolledCourse && enrolledBatchInfo && !viewBatch">
<mat-expansion-panel [expanded]="true">
<mat-expansion-panel-header>
<mat-panel-title class="sb-mat-accordion__title d-flex flex-ai-center flex-jc-space-between">
{{resourceService.frmelmnts.lbl.batchdetails}}
</mat-panel-title>
</mat-expansion-panel-header>
<div class="sb-mat-accordion__content">
<div class="batch-details">
<div class="mb-16">
<div class="batch-details__name sb-color-primary font-weight-bold fmedium">
{{enrolledBatchInfo?.name}}</div>
<div class="batch-details__created mt-8 fsmall">
<span class="date">{{enrolledBatchInfo.startDate | dateFormat}} </span>
<span *ngIf="enrolledBatchInfo.endDate" class="date"> -
{{enrolledBatchInfo?.endDate | dateFormat}}</span>
</div>
</div>
<div class="batch-deatils__button text-right">
<button
[ngClass]="{'sb-btn-disabled': isUnenrollbtnDisabled,'sb-btn-outline-primary': !isUnenrollbtnDisabled}"
class="sb-btn sb-btn-outline-primary sb-btn-normal" tabindex="0"
(click)="unenrollBatch(enrolledBatchInfo); logTelemetry('unenroll-batch', courseHierarchy);"
[disabled]="isUnenrollbtnDisabled">{{generaliseLabelService?.frmelmnts?.btn?.unenroll}}</button>
</div>
<div class="batch-details__created mt-8 fsmall">
<span class="right floated" *ngIf="enrolledBatchInfo?.participantCount>=0">
{{enrolledBatchInfo?.participantCount}} {{resourceService.frmelmnts.lbl.learners}}
</span>
<span>
{{enrolledBatchInfo?.mentors?.length}} {{resourceService.frmelmnts.lbl.mentors}}
</span>
</div>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
<app-modal-wrapper [config]="{disableClose: true, size: 'small'}" (dismiss)="showMessageModal = false;"
*ngIf="showMessageModal">
<ng-template sbModalContent>
<div class="sb-modal">
<div class="transition ui dimmer page modals active visible">
<div class="ui modal transition active visible small">
<button aria-label="close dialog" mat-dialog-close class="mat-close-btn">
<span>×</span>
</button>
<div class="sb-modal-header">
{{generaliseLabelService?.frmelmnts?.btn?.enroll}}
</div>
<!--/Header-->
<!--Content-->
<div class="sb-modal-content">
<div class="ui center aligned segment">
<p>{{batchMessage}}</p>
</div>
</div>
</div>
</div>
</div>
</ng-template>
</app-modal-wrapper>
batch-details.component.scss
@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
.join-batch {
&__heading, &__body {
display: flex;
align-items: center;
div {
flex-basis: 45%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
line-height: normal;
}
button {
flex-basis: auto;
}
}
&__heading {
font-size: calculateRem(12px);
margin-bottom: calculateRem(16px);
font-weight: bold;
padding: 0 calculateRem(16px);
}
&__body {
padding: calculateRem(8px) calculateRem(8px) calculateRem(8px) calculateRem(16px);
border: calculateRem(1px) solid var(--gray-100);
font-size: calculateRem(14px);
margin-bottom: calculateRem(16px);
}
}
::ng-deep {
.ui.accordion .active.title .chevron.down.icon {
margin-top:calculateRem(6px);
}
.ui.accordion .title .chevron.down.icon {
margin-top:calculateRem(-6px);
}
.mat-expansion-panel {
overflow: inherit;
}
}
ul {
list-style-type: none;
padding:0px;margin:0px;
}
li {
display: grid;
grid-template-columns: calculateRem(20px) auto;
justify-content: start;
align-items: center;
margin-bottom:1rem
}
li::before {
content: ">";
font-size: calculateRem(12px);
color: var(--gray-200);
font-weight:bold;
}