File

src/app/modules/sourcing/components/bulk-approval/bulk-approval.component.ts

Metadata

selector app-bulk-approval
styleUrls bulk-approval.component.scss
templateUrl bulk-approval.component.html

Inputs

originalCollectionData
programContents
programContext
sessionContext
storedCollectionData

Outputs

updateToc $event type: EventEmitter

Constructor

constructor(resourceService: any, bulkJobService: BulkJobService, cacheService: CacheService, userService: any, programsService: any, toasterService: any, helperService: HelperService, actionService: any, programTelemetryService: ProgramTelemetryService, configService: any, learnerService: any)

Methods

getProgramaAprovalPendingContents
getProgramaAprovalPendingContents(contents: any)
Returns: void
approvalPendingContents
approvalPendingContents(hierarchy: any)
Returns: void
checkApprovalPending
checkApprovalPending(content: any)
Returns: void
checkOriginFolderStatus
checkOriginFolderStatus(hierarchy: any)
Returns: void
showApproveBulkModal
showApproveBulkModal()
Returns: void
bulkApproval
bulkApproval()
Returns: void
sendContentForBulkApproval
sendContentForBulkApproval()
Returns: void
createBulkApprovalJob
createBulkApprovalJob()
Returns: void
updateBulkApprovalJob
updateBulkApprovalJob()
Returns: void
updateCollection
updateCollection()
Returns: void
viewBulkApprovalStatus
viewBulkApprovalStatus()
Returns: void
findFolderLevel
findFolderLevel(undefined: { [x: string]: any; children?: undefined[]; }, identifier: any)
Returns: void
tree
tree(ob: any)
Returns: void
prepareTableData
prepareTableData()
Returns: void
downloadFailedContentReport
downloadFailedContentReport()
Returns: void
checkBulkApproveHistory
checkBulkApproveHistory()
Returns: void

Properties

actionService
actionService: any
Public approvalPending
approvalPending: any[]
Public bulkApprovalComfirmation
bulkApprovalComfirmation: boolean
Default value: false
Public bulkApprove
bulkApprove: any
bulkJobService
bulkJobService: BulkJobService
Public buttonDisabled
buttonDisabled: boolean
Default value: false
cacheService
cacheService: CacheService
configService
configService: any
Public dikshaContents
dikshaContents: any[]
Public disableBulkApprove
disableBulkApprove: boolean
Default value: false
Public folderData
folderData: any[]
helperService
helperService: HelperService
Public initialized
initialized: boolean
learnerService
learnerService: any
Public originFolderData
originFolderData: any[]
Public processId
processId: string
programsService
programsService: any
programTelemetryService
programTelemetryService: ProgramTelemetryService
resourceService
resourceService: any
Public showBulkApprovalButton
showBulkApprovalButton: boolean
Default value: false
Public showBulkApproveModal
showBulkApproveModal: boolean
Default value: false
Public successPercentage
successPercentage: number
Public telemetryInteractCdata
telemetryInteractCdata: any
Public telemetryInteractObject
telemetryInteractObject: any
Public telemetryInteractPdata
telemetryInteractPdata: any
Public telemetryPageId
telemetryPageId: string
toasterService
toasterService: any
Public unitGroup
unitGroup: any
Public unitsInLevel
unitsInLevel: any[]
userService
userService: any
import { Component, OnInit, Input, Output, EventEmitter, OnChanges } from '@angular/core';
import { UserService, ActionService, ProgramsService, LearnerService } from '@sunbird/core';
import { ConfigService, ResourceService, ToasterService } from '@sunbird/shared';
import { BulkJobService } from '../../services/bulk-job/bulk-job.service';
import { HelperService } from '../../services/helper.service';
import { ProgramTelemetryService } from '../../../program/services';
import { CacheService } from '../../../shared/services/cache-service/cache.service';
import * as _ from 'lodash-es';
import { map, tap } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { ItemsetService } from '../../services/itemset/itemset.service';

@Component({
  selector: 'app-bulk-approval',
  templateUrl: './bulk-approval.component.html',
  styleUrls: ['./bulk-approval.component.scss']
})
export class BulkApprovalComponent implements OnInit, OnChanges {

  public showBulkApproveModal = false;
  public bulkApprovalComfirmation = false;
  public showBulkApprovalButton = false;
  public approvalPending: Array<any> = [];
  public folderData: Array<any> = [];
  public originFolderData: Array<any> = [];
  public dikshaContents: Array<any>;
  public unitsInLevel: Array<any> = [];
  public unitGroup: any;
  public bulkApprove: any;
  public processId: string;
  public successPercentage: number;
  public initialized: boolean;
  public telemetryInteractCdata: any;
  public telemetryInteractPdata: any;
  public telemetryInteractObject: any;
  public telemetryPageId: string;
  public disableBulkApprove = false;
  public buttonDisabled = false;
  @Input() programContext;
  @Input() sessionContext;
  @Input() storedCollectionData;
  @Input() originalCollectionData;
  @Input() programContents;
  @Output() updateToc = new EventEmitter<any>();

  constructor(public resourceService: ResourceService, public bulkJobService: BulkJobService,
    public cacheService: CacheService, public userService: UserService, public programsService: ProgramsService,
    public toasterService: ToasterService, public helperService: HelperService,
    public actionService: ActionService, public programTelemetryService: ProgramTelemetryService,
    public configService: ConfigService, public learnerService: LearnerService) { }

  ngOnInit() {
    this.checkBulkApproveHistory();
    if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
      this.checkOriginFolderStatus([this.originalCollectionData]);
      this.approvalPendingContents([this.storedCollectionData]);
      this.buttonDisabled = !!(!this.originalCollectionData || this.originalCollectionData && this.originalCollectionData.status !== 'Draft')
    } else {
      this.getProgramaAprovalPendingContents(this.programContents);
    }

    this.initialized = true;
    this.telemetryInteractCdata = _.get(this.sessionContext, 'telemetryPageDetails.telemetryInteractCdata') || [];
    // tslint:disable-next-line:max-line-length
    this.telemetryInteractPdata = this.programTelemetryService.getTelemetryInteractPdata(this.userService.appId, this.configService.appConfig.TELEMETRY.PID );
    // tslint:disable-next-line:max-line-length
    this.telemetryInteractObject = this.programTelemetryService.getTelemetryInteractObject(this.sessionContext.collection, 'Content', '1.0', { l1: this.sessionContext.collection });
    this.telemetryPageId = this.sessionContext.telemetryPageDetails.telemetryPageId;
  }

  ngOnChanges() {
    if (this.initialized) {
      this.approvalPending = [];
      if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
        this.approvalPendingContents([this.storedCollectionData]);
      }
      if (this.approvalPending && this.approvalPending.length) {
        if (!this.bulkApprove || this.bulkApprove && this.bulkApprove.status !== 'processing') {
          this.showBulkApprovalButton = true;
        }
      }
    }
  }

  getProgramaAprovalPendingContents(contents) {
    _.forEach(contents, obj => {
      if (obj.status === 'Live' && this.checkApprovalPending(obj)) {
        const content = _.pick(obj, ['name', 'channel', 'code', 'mimeType', 'framework', 'contentType', 'identifier', 'parent']);
        if (!_.find(this.approvalPending, cont => cont.identifier === content.identifier)) {
          this.approvalPending.push(content);
        }
      }
    });
  }

  approvalPendingContents(hierarchy) {
    _.forEach(hierarchy, obj => {
      const isMainCollection = this.helperService.checkIfMainCollection(obj);
      const isCollectionFolder = this.helperService.checkIfCollectionFolder(obj);
      if (isMainCollection || isCollectionFolder) {
        const unit = _.pick(obj, ['identifier', 'origin']);
        if (isMainCollection) {
          const originUnit = _.find(this.originFolderData, o => o.identifier === unit.origin && o.status === 'Draft');
          if (originUnit) {
            this.folderData.push({identifier: obj.identifier, origin: obj.origin});
          }
        }
        if (isCollectionFolder) {
          const originUnit = _.find(this.originFolderData, o => o.identifier === unit.origin);
          if (originUnit) {
            this.folderData.push({identifier: obj.identifier, origin: obj.origin});
          }
        }
      }

      if (!isMainCollection && !isCollectionFolder && obj.status === 'Live' && this.checkApprovalPending(obj)) {
          const content = _.pick(obj, ['name', 'code', 'mimeType', 'framework', 'contentType', 'identifier', 'parent']);
          const unitData = _.find(this.folderData, data => data.identifier === content.parent);
          if (unitData) {
            content['originUnitId'] = unitData.origin;
            if (!_.find(this.approvalPending, cont => cont.identifier === content.identifier)) {
              this.approvalPending.push(content);
            }
          }
      }
      if (obj.children && obj.children.length) {
        this.approvalPendingContents(obj.children);
      }
    });
  }

  checkApprovalPending(content) {
    let reviewedContents;
    if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
      reviewedContents = [...this.storedCollectionData.acceptedContents || [],
                                      ...this.storedCollectionData.rejectedContents || []];
    } else {
      reviewedContents = [...this.programContext.acceptedcontents || [],
                                      ...this.programContext.rejectedcontents || []];
    }
    if (reviewedContents && reviewedContents.length &&
      _.includes(reviewedContents, content.identifier)) {
         return false;
   } else {
     return true;
   }
  }

  checkOriginFolderStatus(hierarchy) {
    _.forEach(hierarchy, obj => {
      const isMainCollection = this.helperService.checkIfMainCollection(obj);
      const isCollectionFolder = this.helperService.checkIfCollectionFolder(obj);
      if (isMainCollection || isCollectionFolder) {
        this.originFolderData.push({identifier: obj.identifier, status: obj.status});
      }
      if (obj.children && obj.children.length) {
        this.checkOriginFolderStatus(obj.children);
      }
    });
  }
  showApproveBulkModal() {
    if (!this.disableBulkApprove) {
      this.showBulkApproveModal = true;
      this.bulkApprovalComfirmation = true;
    }
  }
  bulkApproval() {
    this.disableBulkApprove = true;
    this.sendContentForBulkApproval();
  }

  sendContentForBulkApproval() {
    const baseUrl = (<HTMLInputElement>document.getElementById('portalBaseUrl'))
    ? (<HTMLInputElement>document.getElementById('portalBaseUrl')).value : window.location.origin;
    const contents = [];
    const questionSets = [];
    const temp = _.compact(_.map(this.approvalPending, item => {
      const reqFormat = {};
      if ((!this.programContext.target_type || this.programContext.target_type === 'collections') && item.originUnitId) {
        const channel =  _.get(this.storedCollectionData.originData, 'channel');
        if (_.isString(channel)) {
          item['createdFor'] = [channel];
        } else if (_.isArray(channel)) {
          item['createdFor'] = channel;
        }
        reqFormat['metadata'] = {..._.pick(this.storedCollectionData, ['framework']),
                        ..._.pick(_.get(this.storedCollectionData, 'originData'), ['channel']),
                          ..._.pick(item, ['name', 'code', 'mimeType', 'contentType', 'createdFor']),
                            ...{lastPublishedBy: this.userService.userProfile.userId}},
        reqFormat['collection'] =  [
          {
            identifier: this.storedCollectionData.origin,
            unitId: item.originUnitId
          }
        ];
      } else if(this.programContext.target_type === 'searchCriteria') {
        if (_.isString(item.channel)) {
          item['createdFor'] = [item.channel];
        } else if (_.isArray(item.channel)) {
          item['createdFor'] = item.channel;
        }
        reqFormat['metadata'] = {
          ..._.pick(item, ['framework', 'channel', 'name', 'code', 'mimeType', 'contentType', 'createdFor']),
          ...{lastPublishedBy: this.userService.userProfile.userId}}
      }
      if (!_.isEmpty(reqFormat)) {
        if (_.get(item, 'mimeType').toLowerCase() === 'application/vnd.sunbird.questionset') {
          reqFormat['source'] = `${baseUrl}/api/questionset/v1/read/${item.identifier}`;
          questionSets.push(reqFormat);
        } else {
          reqFormat['source'] = `${baseUrl}/api/content/v1/read/${item.identifier}`;
          contents.push(reqFormat);
        }
      }
    }));
    if (contents && contents.length) {
      const reqOption = {
        url: this.configService.urlConFig.URLS.BULKJOB.DOCK_IMPORT_V1,
        data: {
          request: {
            content: [
              ...contents
            ]
          }
        }
      };

      this.learnerService.post(reqOption).subscribe((res: any) => {
        if (res && res.result && res.result.processId) {
          this.processId = res.result.processId;
          if (questionSets && questionSets.length) {
            reqOption.url = this.configService.urlConFig.URLS.BULKJOB.DOCK_QS_IMPORT_V1;
            reqOption.data.request['processId'] = this.processId;
            reqOption.data.request['questionset'] = {};
            reqOption.data.request['questionset'] = [...questionSets];
            delete reqOption.data.request.content;

          this.learnerService.post(reqOption).subscribe((res: any) => {
            this.createBulkApprovalJob();
            this.updateCollection();
          });
        } else {
            this.createBulkApprovalJob();
            this.updateCollection();
          }
        }
      }, err => {
        this.disableBulkApprove = false;
        this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
      });
    } else if (questionSets && questionSets.length) {
      const reqOption = {
        url: this.configService.urlConFig.URLS.BULKJOB.DOCK_QS_IMPORT_V1,
        data: {
          request: {
            questionset: [
              ...questionSets
            ]
          }
        }
      };
      this.learnerService.post(reqOption).subscribe((res: any) => {
        this.processId = res.result.processId;
        this.createBulkApprovalJob();
        this.updateCollection();
      });
    } else {
      this.disableBulkApprove = false;
      this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
    }
  }

  createBulkApprovalJob() {
    const reqData = {
      process_id: this.processId,
      program_id: this.programContext.program_id,
      collection_id: this.sessionContext.collection,
      org_id: this.userService.userProfile.rootOrgId || '',
      type: 'bulk_approval',
      status: 'processing',
      overall_stats: {
        approve_success: 0,
        approve_failed: 0,
        approve_pending: this.approvalPending.length,
        total: this.approvalPending.length
      },
      createdby: this.userService.userProfile.userId,
      createdon: new Date()
    };
    if (_.get(this.programContext,'target_type') && this.programContext.target_type === 'searchCriteria') {
      delete(reqData.collection_id);
    }
    this.bulkJobService.createBulkJob(reqData).subscribe(res => {
      this.bulkApprove = reqData;
      this.bulkJobService.setProcess(this.bulkApprove);
      this.showBulkApprovalButton = false;
      this.toasterService.success(this.resourceService.messages.smsg.bulkApprove.create);
    }, err => {
      this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
    });
  }

  updateBulkApprovalJob() {
    if (!_.get(this.bulkApprove, 'overall_stats.approve_pending')) {
      this.bulkApprove.status = 'completed';
      this.bulkApprove['completedon'] = new Date();
    }
    const request = _.pick(this.bulkApprove, ['process_id', 'status', 'overall_stats', 'completedon']);
    request['updatedby'] = this.userService.userProfile.userId;
    this.bulkJobService.updateBulkJob(request).subscribe((res: any) => {
      if (this.bulkApprove.status === 'completed') {
        this.showBulkApprovalButton = true;
      }
      this.bulkJobService.setProcess(this.bulkApprove);
      this.toasterService.success(this.resourceService.messages.smsg.bulkApprove.update);
    }, err => {
      this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
    });
  }

  updateCollection() {
    if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
      const option = {
        url: `${this.configService.urlConFig.URLS.DOCKCONTENT.GET}/${this.sessionContext.collection}`,
        param: { 'mode': 'edit', 'fields': 'acceptedContents,versionKey' }
      };
      this.actionService.get(option).pipe(map((res: any) => res.result.content)).subscribe((data) => {
        const request = {
          content: {
            'versionKey': data.versionKey
          }
        };
        // tslint:disable-next-line:max-line-length
        request.content['acceptedContents'] = _.compact(_.uniq([...this.storedCollectionData.acceptedContents || [],
                                            ..._.map(_.filter(this.approvalPending, content => content.originUnitId), 'identifier')]));
        this.helperService.updateContent(request, this.sessionContext.collection).subscribe(res => {
        this.updateToc.emit('bulkApproval_completed');
        this.showBulkApprovalButton = false;
        }, err => {
          this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.updateToc);
        });
      });
    } else if (this.programContext.target_type === 'searchCriteria') {
        let request = {
          program_id: this.programContext.program_id
        };
          // tslint:disable-next-line:max-line-length
        request['acceptedcontents'] = _.compact(_.uniq([...this.programContext.acceptedcontents || [],
          ..._.map(this.approvalPending, 'identifier')]));
        this.programsService.updateProgram(request).subscribe(() => {
          this.updateToc.emit('bulkApproval_completed');
          this.showBulkApprovalButton = false;
        }, (err) => {
          this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.updateToc);

        });
    }
  }

  viewBulkApprovalStatus() {
    if (this.bulkApprove && this.bulkApprove.status === 'processing') {
      this.bulkJobService.searchContentWithProcessId(this.bulkApprove.process_id, this.bulkApprove.type).subscribe((res: any) => {
        this.successPercentage = 0;
        if (res.result) {
          const contents = _.compact(_.concat(_.get(res.result, 'QuestionSet'), _.get(res.result, 'content')));
          if (contents.length) {
            const overallStats = this.bulkApprove && this.bulkApprove.overall_stats;
            this.dikshaContents = contents;
            overallStats['approve_success'] = _.filter(this.dikshaContents, content => content.status === 'Live').length;
            // tslint:disable-next-line:max-line-length
            overallStats['approve_failed'] = _.filter(this.dikshaContents, content => content.status === 'Failed').length;
            overallStats['approve_pending'] = overallStats.total - (overallStats['approve_success'] + overallStats['approve_failed']);
            this.bulkApprove.overall_stats = overallStats;
            // tslint:disable-next-line:max-line-length
            this.successPercentage = Math.round((this.bulkApprove.overall_stats.approve_success / this.bulkApprove.overall_stats.total) * 100);
            this.updateBulkApprovalJob();
          }
        }
      }, err => {
        this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
      });
    }
  }

  findFolderLevel({ children = [], ...object }, identifier) {
    let result;
    if (object.identifier === identifier) {
      return object;
    }
    return children.some(o => result = this.findFolderLevel(o, identifier)) && Object.assign({}, object, { chi: [result] });
  }

  tree(ob) {
    _.forEach(ob.chi, bb => {
      if (this.helperService.checkIfCollectionFolder(bb)) {
        this.unitGroup.push({name: bb.name, identifier: bb.identifier});
      }
      if (bb.chi) {
        this.tree(bb);
      }
    });
  }

  prepareTableData() {
    const failedContent = _.filter(this.dikshaContents, content => content.status === 'Failed');
    if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
      this.unitsInLevel = _.map(failedContent, content => {
        return this.findFolderLevel(this.storedCollectionData, content.origin);
      });
    }

    try {
      const headers = ['identifier', 'name', 'contentType'];
      if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
        headers.push('Level 1 Textbook Unit');
        headers.push('Level 2 Textbook Unit');
        headers.push('Level 3 Textbook Unit');
        headers.push('Level 4 Textbook Unit');
      }
      const tableData = _.map(failedContent, (con, i) => {
        const result = _.pick(con, ['identifier', 'name', 'primaryCategory']);
        if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
          const folderStructure = this.unitsInLevel[i];
          this.unitGroup = [];
          this.tree(folderStructure);
          if (this.unitGroup && this.unitGroup.length) {
            result['Level 1 Textbook Unit'] = this.unitGroup[0] && this.unitGroup[0].name || '';
            result['Level 2 Textbook Unit'] = this.unitGroup[1] && this.unitGroup[1].name || '';
            result['Level 3 Textbook Unit'] = this.unitGroup[2] && this.unitGroup[2].name || '';
            result['Level 4 Textbook Unit'] = this.unitGroup[3] && this.unitGroup[3].name || '';
          }
        }
        return result;
      });

      const csvDownloadConfig = {
        filename: `Bulk Approval Failed Content Report Of Book - ${this.storedCollectionData.name.trim()}`,
        tableData: tableData,
        headers: headers,
        showTitle: false
      };
        this.programsService.generateCSV(csvDownloadConfig);
      } catch (err) {
        this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
      }
  }

  downloadFailedContentReport() {
    if (!this.dikshaContents) {
      this.bulkJobService.searchContentWithProcessId(this.bulkApprove.process_id, this.bulkApprove.type).subscribe((res: any) => {
        if (res.result && res.result.content && res.result.content.length) {
          this.dikshaContents = _.get(res, 'result.content');
          this.prepareTableData();
        }
      });
    } else {
      this.prepareTableData();
    }
  }

  checkBulkApproveHistory() {
    let bulkApproveParam;
    if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
      bulkApproveParam = 'bulk_approval_' + this.sessionContext.collection;
    } else if (this.programContext.target_type === 'searchCriteria') {
      bulkApproveParam = 'bulk_approval_' + this.sessionContext.programId;
    }
    this.bulkApprove = this.cacheService.get(bulkApproveParam);
    if (this.bulkApprove) {
      if (this.bulkApprove.status === 'processing') {
      } else {
        this.showBulkApprovalButton = true;
      }
    } else {
      const reqData = {
        filters: {
          program_id: this.programContext.program_id        }
      };

      if (!this.programContext.target_type || this.programContext.target_type === 'collections') {
        reqData.filters['collection_id'] = this.sessionContext.collection;
      }

      this.bulkJobService.getBulkOperationStatus(reqData).subscribe(res => {
        if (res.result && res.result.process && res.result.process.length) {
          this.bulkApprove = this.cacheService.get(bulkApproveParam);
        }
        if (!this.bulkApprove || this.bulkApprove && this.bulkApprove.status !== 'processing') {
          this.showBulkApprovalButton = true;
        }
      }, err => {
        this.toasterService.error(this.resourceService.messages.emsg.bulkApprove.something);
      });
    }
  }
}

results matching ""

    No results matching ""