File

src/app/modules/certificate/components/certificate-configuration/certificate-configuration.component.ts

Index

Properties

Properties

label
label: string
Type : string
name
name: string
Type : string
show
show: boolean
Type : boolean
import { UploadCertificateService } from './../../services/upload-certificate/upload-certificate.service';
import { CertConfigModel } from './../../models/cert-config-model/cert-config-model';
import { Component, OnInit, OnDestroy, ViewChild, HostListener } from '@angular/core';
import { CertificateService, UserService, PlayerService, CertRegService, FormService } from '@sunbird/core';
import * as _ from 'lodash-es';
import { UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms';
import { ResourceService, NavigationHelperService, ToasterService, LayoutService, COLUMN_TYPE } from '@sunbird/shared';
import { Router, ActivatedRoute } from '@angular/router';
import { combineLatest, of, Subject } from 'rxjs';
import { catchError, tap, map } from 'rxjs/operators';
import { TelemetryService, IImpressionEventInput } from '@sunbird/telemetry';
import { DomSanitizer } from '@angular/platform-browser';

export interface IConfigLabels {
  label: string;
  name: string;
  show: boolean;
}

@Component({
  selector: 'app-certificate-configuration',
  templateUrl: './certificate-configuration.component.html',
  styleUrls: ['./certificate-configuration.component.scss']
})
export class CertificateConfigurationComponent implements OnInit, OnDestroy {
  @ViewChild('selectCertType') selectCertType;
  @ViewChild('selectRecipient') selectRecipient;
  @ViewChild('templateChangeModal') templateChangeModal;
  @ViewChild('selectScoreRange') selectScoreRange;

  public unsubscribe$ = new Subject<void>();
  showPreviewModal;
  showTemplateDetectModal;
  certTypes: any;
  issueTo: any;
  telemetryImpression: IImpressionEventInput;
  userPreference: UntypedFormGroup;
  disableAddCertificate = true;
  queryParams: any;
  courseDetails: any;
  showLoader = true;
  certTemplateList: Array<{}> = [];
  batchDetails: any;
  currentState: any;
  screenStates: any = { 'default': 'default', 'certRules': 'certRules' };
  selectedTemplate: any;
  previewTemplate: any;
  configurationMode: string;
  certConfigModalInstance = new CertConfigModel();
  previewUrl: string;
  templateIdentifier: string;
  isTemplateChanged = false;
  certEditable = true;
  config: { select: IConfigLabels, preview: IConfigLabels, remove: IConfigLabels };
  certificate: any;
  newTemplateIdentifier: any;
  showAlertModal = false;
  addScoreRule = false;
  arrayValue = {};
  scoreRange: any;
  isSingleAssessment = false;
  isStateCertificate = false;
  instance: string;
  layoutConfiguration: any;
  FIRST_PANEL_LAYOUT;
  SECOND_PANEL_LAYOUT;
  certificateFormConfig: any;

  constructor(
    private certificateService: CertificateService,
    private userService: UserService,
    private playerService: PlayerService,
    private sanitizer: DomSanitizer,
    private resourceService: ResourceService,
    private certRegService: CertRegService,
    public uploadCertificateService: UploadCertificateService,
    public navigationHelperService: NavigationHelperService,
    private activatedRoute: ActivatedRoute,
    private toasterService: ToasterService,
    private router: Router,
    private telemetryService: TelemetryService,
    public layoutService: LayoutService,
    private formService: FormService) {
      this.instance = (<HTMLInputElement>document.getElementById('instance'))
      ? (<HTMLInputElement>document.getElementById('instance')).value : 'sunbird';
    }
  /**
   * @description - It will handle back button click.
   */
  @HostListener('window:popstate', ['$event'])
  onPopState(event) {
    if (this.isTemplateChanged) {
      this.isTemplateChanged = false;
    }
  }

  /**
   * @since - release-3.2.10
   * @description - It will prepare all the necessary data along with the apis.
   */
  ngOnInit() {
    this.initializeLabels();
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.redoLayout();
    this.currentState = this.screenStates.default;
    this.uploadCertificateService.certificate.subscribe(res => {
      if (res && !_.isEmpty(res)) {
        this.showAlertModal = true;
        this.currentState = 'certRules';
        this.showPreviewModal = false;
        this.newTemplateIdentifier = _.get(res , 'identifier');
      }
    });
    this.navigationHelperService.setNavigationUrl();
    this.initializeFormFields();
    this.activatedRoute.queryParams.subscribe((params) => {
      this.queryParams = params;
      this.configurationMode = _.get(this.queryParams, 'type');
    });
    combineLatest(
      this.getCourseDetails(_.get(this.queryParams, 'courseId')),
      this.getBatchDetails(_.get(this.queryParams, 'batchId')),
      this.getTemplateList(),
      this.getCertificateFormData()
    ).subscribe((data) => {
      this.showLoader = false;
      this.checkMultipleAssessment();
    }, (error) => {
      this.showLoader = false;
      this.toasterService.error(this.resourceService.messages.emsg.m0005);
    });
  }
  checkMultipleAssessment() {
    try {
      const contentTypes = JSON.parse(_.get(this.courseDetails, 'contentTypesCount'));
    const selfAssessCount = _.get(contentTypes, 'SelfAssess');
    if (selfAssessCount && selfAssessCount > 1) {
      this.isSingleAssessment = false;
    } else if (selfAssessCount && selfAssessCount == 1) {
      this.isSingleAssessment = true;
    } else {
      this.isSingleAssessment = false;
    }
    } catch (error) {
      console.log(error)
    }
    
  }
  certificateCreation() {
    this.currentState = this.screenStates.certRules;
  }

  /**
   * @description - It will trigger impression telemetry event once the view is ready.
   */
  ngAfterViewInit() {
    this.setTelemetryImpressionData();
  }

  /**
   * @description - It will prepare the config data for the hover activity of the cert-list cards.
   */
  initializeLabels() {
    this.config = {
      select: {
        label: _.get(this.resourceService, 'frmelmnts.lbl.Select'),
        name: 'Select',
        show: true
      },
      preview: {
        label: _.get(this.resourceService, 'frmelmnts.cert.lbl.preview'),
        name: 'Preview',
        show: true
      },
      remove: {
        label: _.get(this.resourceService, 'frmelmnts.cert.lbl.unselect'),
        name: 'Remove',
        show: false
      }
    };
  }

  /**
   * @description - It will fetch the drop-down values by calling the preference api with proper request payload.
   */
  getCertConfigFields() {
    const request = {
      request: {
        orgId: _.get(this.userService, 'userProfile.rootOrgId'),
        key: 'certRules'
      }
    };
    this.certificateService.fetchCertificatePreferences(request).subscribe(certRulesData => {
      const dropDownValues = this.certConfigModalInstance.getDropDownValues(_.get(certRulesData, 'result.response.data.fields'));
      this.certTypes = _.get(dropDownValues, 'certTypes');
      this.issueTo = _.get(dropDownValues, 'issueTo');
      this.scoreRange = _.get(dropDownValues, 'scoreRange');
    }, error => {
      this.toasterService.error(this.resourceService.messages.emsg.m0005);
    });
  }

  /**
   * @description - It will fetch list of certificate templates from preference api.
   */
  getTemplateList() {
    const request = {
      'request': {
          'filters': {
              'certType': 'cert template',
              'channel': this.userService.channel,
              'mediaType': 'image'
          },
          'sort_by': {
            'lastUpdatedOn': 'desc'
          },
          'fields': ['indentifier', 'name', 'code', 'certType', 'data', 'issuer', 'signatoryList', 'artifactUrl', 'primaryCategory', 'channel'],
          'limit': 100
      }
  };
  return this.uploadCertificateService.getCertificates(request).pipe(
      tap((certTemplateData) => {
        const templatList = _.get(certTemplateData, 'result.content');
        this.certTemplateList = templatList;
        // To select the newly created certificate
        let tempIdToSelect;
        if (this.newTemplateIdentifier) {
          tempIdToSelect = this.newTemplateIdentifier;
        } else {
          tempIdToSelect = this.templateIdentifier;
        }
        const templateData = templatList.find(templat => tempIdToSelect && (templat.identifier === tempIdToSelect));
        if (templateData) {
          _.remove(this.certTemplateList, (cert) => _.get(cert, 'identifier') === _.get(templateData , 'identifier'));
          this.certTemplateList.unshift(templateData);
          this.selectedTemplate = templateData;
        }
      }), catchError(error => {
          return of({});
        })
    );
  }

  refreshData() {
    this.getTemplateList().subscribe(response => {
    }, (error) => {
      this.toasterService.error(this.resourceService.messages.emsg.m0005);
    });
  }
  /**
   * @param  {string} batchId
   * @description - It will fetch the batch details.
   */
  getBatchDetails(batchId) {
    return this.certificateService.getBatchDetails(batchId).pipe(
      tap(batchDetails => {
        this.batchDetails = _.get(batchDetails, 'result.response');
        const cert_templates = _.get(this.batchDetails, 'cert_templates');
        if (_.isEmpty(cert_templates)) {
          this.getCertConfigFields();
        } else {
          // Certifciate has attached to a batch
          if (_.isArray(cert_templates)) {
            this.batchDetails.cert_templates = cert_templates[0];
          }
          this.processCertificateDetails(cert_templates);
        }
      })
    );
  }


  initializeFormFields() {
    this.userPreference = new UntypedFormGroup({
      scoreRange: new UntypedFormControl(''),
      issueTo: new UntypedFormControl('', [Validators.required]),
      allowPermission: new UntypedFormControl('', [Validators.required])
    });
    this.userPreference.valueChanges.subscribe(val => {
      this.validateForm();
    });
  }


  validateForm() {
    if (this.userPreference.status === 'VALID'
      && _.get(this.userPreference, 'value.allowPermission') && !_.isEmpty(this.selectedTemplate)) {
      this.disableAddCertificate = false;
    } else {
      this.disableAddCertificate = true;
    }
  }

  /**
   * @param  {string} courseId
   * @description - It will fetch the course details.
   */
  getCourseDetails(courseId: string) {
    return this.playerService.getCollectionHierarchy(courseId).pipe(
      tap(courseData => {
        this.courseDetails = _.get(courseData, 'result.content');
      }, catchError(error => {
        return of({});
      }))
    );
  }

  /**
   * @description - It will check for the template change or update the certificate.
   */
  updateCertificate() {
    if (this.templateIdentifier !== _.get(this.selectedTemplate, 'name')) {
      this.isTemplateChanged = true;
    } else {
      this.attachCertificateToBatch();
    }
  }

  attachCertificateToBatch() {
    this.sendInteractData({ id: this.configurationMode === 'add' ? 'attach-certificate' : 'confirm-template-change' });
    if (this.addScoreRule === false) {
      this.userPreference.value['scoreRange'] = null;
    }
    const request = {
      'request': {
        'batch': {
          'courseId': _.get(this.queryParams, 'courseId'),
          'batchId': _.get(this.queryParams, 'batchId'),
          'template': {
            'identifier': _.get(this.selectedTemplate, 'identifier'),
            'criteria': this.getCriteria(this.userPreference.value),
            'name': _.get(this.selectedTemplate, 'name'),
            'issuer': JSON.parse(_.get(this.selectedTemplate, 'issuer')),
            'data': JSON.stringify(_.get(this.selectedTemplate, 'data')),
            'previewUrl': _.get(this.selectedTemplate, 'artifactUrl'),
            'signatoryList': JSON.parse(_.get(this.selectedTemplate, 'signatoryList'))
          }
        }
      }
    };

    if (this.isTemplateChanged) {
      request['request']['oldTemplateId'] = this.templateIdentifier;
    }
    this.certRegService.addCertificateTemplate(request).subscribe(data => {
      this.isTemplateChanged = false;
      if (this.configurationMode === 'add') {
        this.toasterService.success(_.get(this.resourceService, 'frmelmnts.cert.lbl.certAddSuccess'));
      } else {
        this.toasterService.success(_.get(this.resourceService, 'frmelmnts.cert.lbl.certUpdateSuccess'));
      }
      this.certificateService.getBatchDetails(_.get(this.queryParams, 'batchId')).subscribe(batchDetails => {
        this.batchDetails = _.get(batchDetails, 'result.response');
        this.processCertificateDetails(_.get(this.batchDetails, 'cert_templates'));
        this.goBack();
      }, error => {
        this.toasterService.error(this.resourceService.messages.emsg.m0005);
      });
    }, error => {
      if (this.configurationMode === 'add') {
        this.toasterService.error(_.get(this.resourceService, 'frmelmnts.cert.lbl.certAddError'));
      } else {
        this.toasterService.error(_.get(this.resourceService, 'frmelmnts.cert.lbl.certEditError'));
      }
    });
  }

  processCertificateDetails(certTemplateDetails) {
    const templateData = _.pick(_.get(certTemplateDetails, Object.keys(certTemplateDetails)), ['criteria', 'previewUrl', 'artifactUrl', 'identifier', 'data', 'issuer', 'signatoryList', 'name', 'url']);
    this.templateIdentifier = _.get(templateData, 'identifier');
    this.selectedTemplate = {
      'name': _.get(templateData, 'name'),
      'identifier': _.get(templateData, 'identifier'),
      'previewUrl': _.get(templateData, 'previewUrl'),
      'issuer': JSON.stringify(_.get(templateData, 'issuer')),
      'data': JSON.stringify(_.get(templateData, 'data')),
      'signatoryList': JSON.stringify(_.get(templateData, 'signatoryList')),
      'artifactUrl': _.get(templateData, 'artifactUrl')
     };
     if (!_.get(templateData, 'previewUrl') && _.get(templateData, 'url')) {
      this.selectedTemplate['previewUrl'] = _.get(templateData, 'url');
      templateData['previewUrl'] = _.get(templateData, 'url');
     }
    // if (!_.isEmpty(this.newTemplateIdentifier)) {
    //   this.templateIdentifier = this.newTemplateIdentifier;
    //   this.selectedTemplate = null;
    // }
    this.previewUrl = _.get(templateData, 'previewUrl');
    this.setCertEditable();
    this.processCriteria(_.get(templateData, 'criteria'));
  }

  setCertEditable() {
    this.certEditable = this.previewUrl ? true : false;
  }

  editCertificate() {
    this.configurationMode = 'edit';
    this.currentState = this.screenStates.certRules;
    this.sendInteractData({ id: 'edit-certificate' });
  }

  getCriteria(rawDropdownValues) {
    const processedData = this.certConfigModalInstance.processDropDownValues(rawDropdownValues, _.get(this.userService, 'userProfile.rootOrgId'));
    return processedData;
  }

  processCriteria(criteria) {
    const data = this.certConfigModalInstance.processCriteria(criteria);
    this.issueTo = _.get(data, 'issueTo');
    const scoreRange = _.get(data, 'scoreRange');
    if (scoreRange) {
      this.addRule();
    }
    const scoreRangeFormEle = this.userPreference.controls['scoreRange'];
    const issueToFormEle = this.userPreference.controls['issueTo'];
    this.issueTo && this.issueTo.length > 0 ? issueToFormEle.setValue(this.issueTo[0].name) : issueToFormEle.setValue('');
    scoreRange ? scoreRangeFormEle.setValue(scoreRange) : scoreRangeFormEle.setValue('');
  }

  handleCertificateEvent(event, template: {}) {
    const show = _.get(this.selectedTemplate, 'name') === _.get(template, 'name');
    switch (_.lowerCase(_.get(event, 'name'))) {
      case 'select':
        this.selectedTemplate = template;
        this.config.remove.show = show;
        this.config.select.show = !show;
        this.validateForm();
        this.sendInteractData({ id: 'select-template' });
        break;
      case 'remove':
        this.selectedTemplate = {};
        this.config.select.show = show;
        this.config.remove.show = !show;
        this.validateForm();
        this.sendInteractData({ id: 'unselect-template' });
        break;
      case 'preview':
        this.previewTemplate = template;
        this.showPreviewModal = true;
        this.sendInteractData({ id: 'preview-template' });
        break;
    }
  }

  getConfig(config: { show: boolean, label: string, name: string }, template) {
    const show = _.get(this.selectedTemplate, 'name') === _.get(template, 'name');
    if (_.lowerCase(_.get(config, 'label')) === 'select') {
      return ({ show: !show, label: config.label, name: config.name });
    } else {
      return ({ show: show, label: config.label, name: config.name });
    }
  }

  closeModal(event) {
    _.remove(this.certTemplateList, (template) => _.get(template, 'identifier') === _.get(event, 'template.identifier'));
    this.certTemplateList.unshift(_.get(event, 'template'));
    this.showPreviewModal = false;
    this.selectedTemplate = _.get(event, 'name') ? _.get(event, 'template') : this.selectedTemplate;
    this.validateForm();
    if (_.get(event, 'name')) {
      this.sendInteractData({ id: 'select-template' });
    } else {
      this.sendInteractData({ id: 'close-preview' });
    }
  }

  closeTemplateDetectModal() {
    this.isTemplateChanged = false;
    this.sendInteractData({ id: 'cancel-template-change' });
  }

  navigateToCertRules() {
    this.currentState = this.screenStates.certRules;
    this.sendInteractData({ id: 'add-certificate' });
  }

  goBack() {
    if (this.currentState === this.screenStates.certRules) {
      // Goback to cert list screen
      this.currentState = this.screenStates.default;
    } else {
      this.router.navigate([`/learn/course/${_.get(this.queryParams, 'courseId')}`]);
    }
  }

  cancelSelection() {
    this.currentState = this.screenStates.default;
    this.userPreference.controls['allowPermission'].reset();
    this.sendInteractData({ id: this.configurationMode === 'add' ? 'cancel-add-certificate' : 'cancel-update-certificate' });
    if (this.configurationMode === 'add') {
      this.userPreference.reset();
      this.selectedTemplate = {};
    } else {
      const cert_templates = _.get(this.batchDetails, 'cert_templates');
      this.processCertificateDetails(cert_templates);
    }
  }

  setTelemetryImpressionData() {
    this.telemetryImpression = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: [{
          type: 'Batch',
          id: _.get(this.queryParams, 'batchId')
        },
        {
          type: 'Course',
          id: _.get(this.queryParams, 'courseId')
        }]
      },
      edata: {
        type: this.activatedRoute.snapshot.data.telemetry.type,
        subtype: this.activatedRoute.snapshot.data.telemetry.subtype,
        pageid: this.activatedRoute.snapshot.data.telemetry.pageid,
        uri: this.router.url,
        duration: this.navigationHelperService.getPageLoadTime()
      }
    };
    this.telemetryService.impression(this.telemetryImpression);
  }

  sendInteractData(interactData) {
    const data = {
      context: {
        env: this.activatedRoute.snapshot.data.telemetry.env,
        cdata: [{
          type: 'Batch',
          id: _.get(this.queryParams, 'batchId')
        },
        {
          type: 'Course',
          id: _.get(this.queryParams, 'courseId')
        }]
      },
      edata: {
        id: _.get(interactData, 'id'),
        type: 'CLICK',
        pageid: this.activatedRoute.snapshot.data.telemetry.pageid
      }
    };

    if (this.configurationMode === 'edit') {
      data['object'] = {
        id: _.get(this.selectedTemplate, 'name'),
        type: 'Certificate',
        ver: '1.0',
        rollup: { l1: _.get(this.queryParams, 'courseId') }
      };
    }

    this.telemetryService.interact(data);
  }

  navigateToCreateTemplate() {
    if(_.get(this.certificateFormConfig, 'enableSVGEditor')) {
      this.router.navigate([`/certs/configure/create-certificate-template`], {
        queryParams: {
          type: this.configurationMode,
          courseId: _.get(this.queryParams, 'courseId'),
          batchId: _.get(this.queryParams, 'batchId')
        }
      });
    } else {
      this.router.navigate([`/certs/configure/create-template`], {
        queryParams: {
          type: this.configurationMode,
          courseId: _.get(this.queryParams, 'courseId'),
          batchId: _.get(this.queryParams, 'batchId')
        }
      });
    }
  }
  removeSelectedCertificate() {
    this.selectedTemplate = null;
  }
  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
    this.uploadCertificateService.certificate.next(null);
  }
  public addRule() {
    this.addScoreRule = true;
    let range = 100;
    const step = 10;
    const arr = [];
    while (range > 0) {
      arr.push(range);
      range = range - step;
    }
    this.arrayValue['range'] = arr;
  }
  removeRule() {
    setTimeout(() => {
      this.userPreference.value['scoreRange'] = null;
    }, 500);
    this.addScoreRule = false;
  }
  redoLayout() {
    if (this.layoutConfiguration != null) {
      this.FIRST_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(0, this.layoutConfiguration, COLUMN_TYPE.threeToNine);
      this.SECOND_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(1, this.layoutConfiguration, COLUMN_TYPE.threeToNine);
    } 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);
    }
  }
  handleParameterChange(event) {
    if (_.get(event, 'value') === 'My state teacher') {
      this.isStateCertificate = true;
    } else {
      this.isStateCertificate = false;
    }
  }

  getCertificateFormData() {
    const formServiceInputParams = {
      formType: 'certificate',
      contentType: 'course',
      formAction: 'certificateCreate',
      component: 'portal'
    };
    return this.formService.getFormConfig(formServiceInputParams, null, 'data').pipe(
      map((data) => {
        this.certificateFormConfig = data;
        return data;
      }),tap(mapping => {
      }),
        catchError((err) => {
          return of([])
        })
      );
  }
}

results matching ""

    No results matching ""