File

src/app/manage-learn/project/project-details/project-details.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods

Constructor

constructor(params: ActivatedRoute, headerService: AppHeaderService, translate: TranslateService, db: DbService, network: NetworkService, toast: ToastService, commonUtilService: CommonUtilService, router: Router, alert: AlertController, ref: ChangeDetectorRef, unnatiService: UnnatiDataService, location: Location, projectServ: ProjectService, modal: ModalController, utils: UtilsService, ngZone: NgZone, share: SharingFeatureService)
Parameters :
Name Type Optional
params ActivatedRoute No
headerService AppHeaderService No
translate TranslateService No
db DbService No
network NetworkService No
toast ToastService No
commonUtilService CommonUtilService No
router Router No
alert AlertController No
ref ChangeDetectorRef No
unnatiService UnnatiDataService No
location Location No
projectServ ProjectService No
modal ModalController No
utils UtilsService No
ngZone NgZone No
share SharingFeatureService No

Methods

Async addNewTask
addNewTask()
Returns : unknown
doSyncAction
doSyncAction()
Returns : void
getAllActiveTasks
getAllActiveTasks()
Returns : void
getAssessmentTypeTaskId
getAssessmentTypeTaskId()
Returns : {}
getProject
getProject()
Returns : void
getProjectsApi
getProjectsApi(certificate?)
Parameters :
Name Optional
certificate Yes
Returns : void
getProjectTaskStatus
getProjectTaskStatus()
Returns : void
ionViewWillEnter
ionViewWillEnter()
Returns : void
ionViewWillLeave
ionViewWillLeave()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onAction
onAction(event)
Parameters :
Name Optional
event No
Returns : void
onTaskAction
onTaskAction(event)
Parameters :
Name Optional
event No
Returns : void
openResource
openResource(resource)
Parameters :
Name Optional
resource No
Returns : void
refreshTheActions
refreshTheActions()
Returns : void
segmentChanged
segmentChanged(event)
Parameters :
Name Optional
event No
Returns : void
setActionButtons
setActionButtons()
Returns : void
setCardMetaData
setCardMetaData()
Returns : void
setHeaderConfig
setHeaderConfig()
Returns : void
submitImprovment
submitImprovment()
Returns : void
updateAssessmentStatus
updateAssessmentStatus(data)
Parameters :
Name Optional
data No
Returns : void
updateLocalDb
updateLocalDb(setIsEditTrue)
Parameters :
Name Optional Default value
setIsEditTrue No false
Returns : void

Properties

_appHeaderSubscription
Type : Subscription
_headerConfig
Private _networkSubscription
Type : Subscription
allStatusTypes
Default value : statusType
allStrings
cardMetaData
categories
Type : []
Default value : []
certificateCriteria
Type : any
Default value : []
isNotSynced
Type : boolean
networkFlag
Type : boolean
Public params
Type : ActivatedRoute
programId
projectActions
projectCompletionPercent
projectDetails
projectDetailsCopy
projectId
projectType
segmentType
Type : string
Default value : "details"
shareTaskId
solutionId
taskCount
Type : number
Default value : 0
taskNoDataFound
Type : string
Default value : "FRMELEMNTS_LBL_PLEASE_CREATE_AND_COMPLETE_TASKS"
templateId
import { ChangeDetectorRef, Component, NgZone, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppHeaderService, CommonUtilService } from '@app/services';
import { TranslateService } from '@ngx-translate/core';
import { actions } from '../../core/constants/actions.constants';
import { DbService } from '../../core/services/db.service';
import { ToastService, NetworkService, ProjectService, statusType, UtilsService } from '../../core';
import { Subscription } from 'rxjs';
import { RouterLinks } from '@app/app/app.constant';
import { urlConstants } from '../../core/constants/urlConstants';
import { SharingFeatureService } from '../../core/services/sharing-feature.service';
import { AlertController, ModalController } from '@ionic/angular';
import { UnnatiDataService } from '../../core/services/unnati-data.service';
import { Location } from '@angular/common';
import * as _ from 'underscore';
import { CreateTaskFormComponent } from '../../shared';

@Component({
  selector: 'app-project-details',
  templateUrl: './project-details.component.html',
  styleUrls: ['./project-details.component.scss'],
})
export class ProjectDetailsComponent implements OnInit {
  projectId;
  solutionId;
  programId
  templateId;
  projectType;
  _headerConfig;
  allStrings;
  projectDetails;
  categories = [];
  isNotSynced: boolean;
  cardMetaData;
  projectActions;
  segmentType = "details";
  networkFlag: boolean;
  private _networkSubscription: Subscription;
  shareTaskId
  _appHeaderSubscription: Subscription;
  projectCompletionPercent;
  allStatusTypes = statusType;
  taskCount = 0;
  projectDetailsCopy;
  taskNoDataFound="FRMELEMNTS_LBL_PLEASE_CREATE_AND_COMPLETE_TASKS"
  certificateCriteria:any =[];
  constructor(
    public params: ActivatedRoute,
    private headerService: AppHeaderService,
    private translate: TranslateService,
    private db: DbService,
    private network: NetworkService,
    private toast: ToastService,
    private commonUtilService: CommonUtilService,
    private router: Router,
    private alert: AlertController,
    private ref: ChangeDetectorRef,
    private unnatiService: UnnatiDataService,
    private location: Location,
    private projectServ: ProjectService,
    private modal: ModalController,
    private utils: UtilsService,
    private ngZone: NgZone,
    private share: SharingFeatureService
  ) {
    params.queryParams.subscribe((parameters) => {
      this.networkFlag = this.commonUtilService.networkInfo.isNetworkAvailable;
      this._networkSubscription = this.commonUtilService.networkAvailability$.subscribe(async (available: boolean) => {
        this.networkFlag = available;
      })
      this.setHeaderConfig();
      this.projectId = parameters.projectId;
      this.solutionId = parameters.solutionId;
      this.programId = parameters.programId;
      this.projectType = parameters.type ? parameters.type : '';
      this.templateId = parameters.templateId;
      this.getProject()
    });
  }

  ngOnInit() {
    this.translate
      .get([
        "FRMELEMNTS_MSG_SOMETHING_WENT_WRONG",
        "FRMELEMNTS_MSG_NO_ENTITY_MAPPED",
        "FRMELEMNTS_MSG_CANNOT_GET_PROJECT_DETAILS",
        "FRMELEMNTS_LBL_IMPORT_PROJECT_MESSAGE",
        "YES",
        "NO"
      ])
      .subscribe((texts) => {
        this.allStrings = texts;
      });
  }
  ionViewWillEnter() {
    this._appHeaderSubscription = this.headerService.headerEventEmitted$.subscribe(eventName => {
      this.location.back();
    });
  }
  ionViewWillLeave() {
    if (this._appHeaderSubscription) {
      this._appHeaderSubscription.unsubscribe();
    }
  }

  setHeaderConfig() {
    this._headerConfig = {
      showHeader: true,
      showBurgerMenu: false,
      pageTitle: '',
      actionButtons: [],
    };
    this.headerService.updatePageConfig(this._headerConfig);
  }

  refreshTheActions() {
    this.setActionButtons();
    this.projectCompletionPercent = this.projectServ.getProjectCompletionPercentage(this.projectDetails);
    this.getAllActiveTasks();
  }

  getProject() {
    if (this.projectId) {
      this.db.query({ _id: this.projectId }).then(
        (success) => {
          if (success.docs.length) {
            this.categories = [];
            this.projectDetails = success.docs.length ? success.docs[0] : {};
            if(this.projectDetails.certificate){
              this.certificateCriteria =[];
              let criteria = Object.keys(this.projectDetails?.certificate?.criteria?.conditions);
              criteria.forEach(element => {
                let config ={
                  name:this.projectDetails?.certificate?.criteria?.conditions[element].validationText
                }
                this.certificateCriteria.push(config);
              })
            }
            this.setActionButtons();
            this.isNotSynced = this.projectDetails ? (this.projectDetails.isNew || this.projectDetails.isEdit) : false;
            this.projectDetails.categories.forEach((category: any) => {
              category.label ? this.categories.push(category.label) : this.categories.push(category.name);
            });
            this.setCardMetaData();
            this.projectCompletionPercent = this.projectServ.getProjectCompletionPercentage(this.projectDetails);
            this.getProjectTaskStatus();
            this.taskCount = this.utils.getTaskCount(this.projectDetails);
            this.getAllActiveTasks();
          } else {
            this.getProjectsApi();
          }

        },
        (error) => {
          this.getProjectsApi();
        }
      );
    } else {
      this.getProjectsApi();
    }

  }

  getAllActiveTasks() {
    const profileDetailsCopy = { ...this.projectDetails }
    let activeTask =    _.filter(this.projectDetails.tasks, function(el) {
      return !el.isDeleted;
   });
   profileDetailsCopy.tasks = activeTask;
   this.ngZone.run(() => {
    this.projectDetailsCopy = profileDetailsCopy;
   })
  }

  setCardMetaData() {
    this.cardMetaData = {
      title: this.projectDetails.title,
      subTitle: this.projectDetails.programName || null
    }
  }

  segmentChanged(event) {
    this.segmentType = event.detail.value;
  }

  setActionButtons() {
    let defaultOptions = actions.PROJECT_ACTIONS;
    if (this.projectDetails.isNew || this.projectDetails.isEdit) {
      const indexOfSync = defaultOptions.length - 1;
      defaultOptions[indexOfSync] = actions.SYNC_ACTION;
    } else {
      const indexOfSync = defaultOptions.length - 1;
      defaultOptions[indexOfSync] = actions.SYNCED_ACTION;
    }
    if (this.projectDetails.downloaded) {
      defaultOptions[0] = actions.DOWNLOADED_ACTION
    } else {
      defaultOptions[0] = actions.NOT_DOWNLOADED;
    }
    if (this.projectDetails.status === statusType.submitted) {
      if(this.projectDetails.certificate){
        defaultOptions = actions.SUBMITTED_PROJECT_ACTIONS.concat(actions.CERTIFICATE_ACTION);
      }else{
        defaultOptions = actions.SUBMITTED_PROJECT_ACTIONS
      }
    }
    this.projectActions = defaultOptions;
  }

  doSyncAction() {
    if (this.network.isNetworkAvailable) {
      this.projectDetails.isNew
        ? this.projectServ.createNewProject(this.projectDetails)
        : this.router.navigate([`${RouterLinks.PROJECT}/${RouterLinks.SYNC}`], { queryParams: { projectId: this.projectId } });
    } else {
      this.toast.showMessage('FRMELEMNTS_MSG_PLEASE_GO_ONLINE', 'danger');
    }
  }

  onAction(event) {
    switch (event) {
      case 'download':
        if (this.network.isNetworkAvailable) {
          this.projectDetails.downloaded = true;
          this.updateLocalDb();
          this.toast.showMessage('FRMELEMNTS_MSG_DOWNLOADED_SUCCESSFULLY', 'success');
          this.setActionButtons();
        } else {
          this.toast.showMessage('FRMELEMNTS_LBL_PROJECT_DOWNLOAD_OFFLINE', 'danger');
        }
        break;
      case 'downloaded':
        break;
      case 'sync':
        this.doSyncAction();
        break;
      case 'synced':
        break;
      case 'share':
        this.network.isNetworkAvailable
          ? this.projectServ.openSyncSharePopup('shareProject', this.projectDetails.title, this.projectDetails)
          : this.toast.showMessage('FRMELEMNTS_MSG_PLEASE_GO_ONLINE', 'danger');
        break;
      case 'files':
        this.router.navigate([`${RouterLinks.ATTACHMENTS_LIST}`, this.projectDetails._id]);
        break
      case 'edit':
        this.router.navigate([`/${RouterLinks.PROJECT}/${RouterLinks.PROJECT_EDIT}`, this.projectDetails._id]);
        break;
      case 'certificate':
       this.getProjectsApi(true);
        break
    }
  }

  onTaskAction(event) {
    switch (event.type) {
      case 'deleteTask':
        let index = 0;
        for (const task of this.projectDetails.tasks) {
          if(event.taskId === task._id){
            break;
          }
          index++
        }
        this.projectDetails.tasks[index].isDeleted = true;
        this.projectDetails.tasks[index].isEdit = true;
        this.refreshTheActions();
        this.updateLocalDb(true);
        this.taskCount = this.utils.getTaskCount(this.projectDetails);
        break
    }
  }

  openResource(resource) {
    this.projectServ.openResources(resource);
  }

  updateLocalDb(setIsEditTrue = false) {
    this.projectDetails.isEdit = setIsEditTrue ? true : this.projectDetails.isEdit;
    this.db.update(this.projectDetails).then(success => {
      this.projectDetails._rev = success.rev;
      this.taskCount = this.utils.getTaskCount(this.projectDetails);
    })
  }

  getProjectsApi(certificate?) {
    const payload = {
      projectId: this.projectId,
      solutionId: this.solutionId,
      isProfileInfoRequired: false,
      programId: this.programId,
      templateId: this.templateId,
      certificate : certificate
    };
    this.projectServ.getProjectDetails(payload);
  }

  getProjectTaskStatus() {
    if (!this.projectDetails.tasks && !this.projectDetails.tasks.length) {
      return
    }
    let taskIdArr = this.getAssessmentTypeTaskId()

    if (!taskIdArr.length) {
      return
    }
    if (!this.networkFlag) {
      return;
    }
    const config = {
      url: urlConstants.API_URLS.PROJCET_TASK_STATUS + `${this.projectDetails._id}`,
      payload: {
        taskIds: taskIdArr,
      },
    };
    this.unnatiService.post(config).subscribe(
      (success) => {
        if (!success.result) {
          return;
        }
        this.updateAssessmentStatus(success.result);
      },
      (error) => {
      }
    );
  }

  updateAssessmentStatus(data) {
    // if task type is assessment or observation then check if it is submitted and change the status and update in db
    let isChnaged = false
    this.projectDetails.tasks.map((t) => {
      data.map((d) => {
        if (d.type == 'assessment' || d.type == 'observation') {//check if type is observation or assessment 
          if (d._id == t._id && d.submissionDetails.status) {
            // check id matches and task details has submissionDetails
            if (!t.submissionDetails || JSON.stringify(t.submissionDetails)  != JSON.stringify(d.submissionDetails) ) {
              t.submissionDetails = d.submissionDetails;
              t.status = d.submissionDetails.status;
              t.isEdit = true
              isChnaged = true;
              t.isEdit = true
              this.projectDetails.isEdit = true
              this.refreshTheActions();
            }
          }
        }

      });
    });
    isChnaged ? this.updateLocalDb(true) : null// if any assessment/observatiom task status is changed then only update 
    this.ref.detectChanges();
  }

  getAssessmentTypeTaskId() {
    const assessmentTypeTaskIds = [];
    for (const task of this.projectDetails.tasks) {
      task.type === "assessment" || task.type === "observation" ? assessmentTypeTaskIds.push(task._id) : null;
    }
    return assessmentTypeTaskIds;
  }

  submitImprovment() {
    if (!this.network.isNetworkAvailable) {
      this.toast.showMessage('FRMELEMNTS_MSG_YOU_ARE_WORKING_OFFLINE_TRY_AGAIN', 'danger')
    }
    this.router.navigate([`${RouterLinks.PROJECT}/${RouterLinks.ADD_FILE}`, this.projectDetails._id])
  }

  async addNewTask() {
    const modal = await this.modal.create({
      component: CreateTaskFormComponent,
      cssClass: "create-task-modal",
    });
    modal.onDidDismiss().then((data) => {
      if (data.data) {
        !this.projectDetails.tasks ? (this.projectDetails.tasks = []) : "";
        this.projectDetails.status = this.projectDetails.status ? this.projectDetails.status : statusType.notStarted;
        this.projectDetails.status = this.projectDetails.status == statusType.notStarted ? statusType.inProgress : this.projectDetails.status;
        this.projectDetails.tasks.push(data.data);
        this.toast.showMessage("FRMELEMNTS_MSG_NEW_TASK_ADDED_SUCCESSFUL", 'success');
        this.updateLocalDb(true);
        this.refreshTheActions();
      }
    });
    return await modal.present();
  }

}
<ion-content class="ion-padding">

  <app-metadata-details translucent="true" [data]="cardMetaData" id="projectMetaDataCard">
    <div class="certificate-tag" certificate *ngIf="projectDetails?.certificate">
      {{'CERTIFICATE' | translate}}
    </div>
    <div class="sb-dt-card-actions">
      <div class="wrapper">
        <app-metadata-actions (actionEvent)="onAction($event)" [actionItems]="projectActions" id="projectActions"></app-metadata-actions>
      </div>

      <div class="sb-course-progress-container"
        *ngIf="projectDetails?.status?.length &&  projectDetails?.status !== allStatusTypes.submitted" id="projectStatus">
        <p><strong>{{'YOUR_PROGRESS_LABEL' | translate}}</strong>
        </p>
        <p>{{projectCompletionPercent?.completedTasks}} / {{projectCompletionPercent?.totalTasks}} {{'COMPLETED' |
          translate}}
        </p>
        <ion-progress-bar
          [value]="projectCompletionPercent?.completedTasks/projectCompletionPercent?.totalTasks"
          [ngClass]="{'completed':projectCompletionPercent?.completedTasks===projectCompletionPercent?.totalTasks && projectCompletionPercent?.totalTasks !==0, 'in-progress': projectCompletionPercent?.completedTasks !== projectCompletionPercent?.totalTasks && projectCompletionPercent?.totalTasks !==0, 'zeroTask': projectCompletionPercent?.totalTasks == 0}"
          class="progress-bar-style"></ion-progress-bar>
      </div>

    </div>
    <div class="submit-text" *ngIf="(taskCount && projectCompletionPercent?.completedTasks == projectCompletionPercent?.totalTasks) && projectDetails?.status != allStatusTypes.submitted"> {{'FRMELEMNTS_LBL_TO_SUBMIT_PROJECT' | translate}} <ion-icon name="arrow-down"></ion-icon>
    </div>
    <ion-button (click)="submitImprovment()" id="submitImprovement"
      *ngIf="projectDetails?.status && projectDetails?.status !== allStatusTypes.submitted" expand="block"
      class="ion-text-none ion-margin-top custom-btn-txt-transform-none"
      [ngClass]="{'button-disabled':projectCompletionPercent?.completedTasks !== projectCompletionPercent?.totalTasks || !taskCount}"
      [disabled]="!taskCount || (projectCompletionPercent?.completedTasks !== projectCompletionPercent?.totalTasks)">
      {{'FRMELEMNTS_LBL_SUBMIT_IMPROVEMENT' | translate}}
    </ion-button>
    <div class="sb-course-complete-container ion-padding" *ngIf="projectDetails?.status === allStatusTypes.submitted">
      <div class="img-container">
        <img class="success-badge" src='assets/imgs/Badge green.svg' alt="completed">
      </div>
      <div class="text-container">
        <p><strong>{{'FRMELEMNTS_LBL_SUBMIT_IMPROVEMENT_SUCCESS_MESSAGE' | translate }}</strong></p>
      </div>
    </div>
  </app-metadata-details>

  <div class="project-segments">
    <ion-segment [(ngModel)]="segmentType" (ionChange)="segmentChanged($event)" class="segment-card">
      <ion-segment-button value="details" class="flex-5">
        <ion-label class="font-12 text-transform-none">{{'FRMELEMNTS_LBL_PROJECT_DETAILS' | translate }}</ion-label>
      </ion-segment-button>
      <div class="hr-div">
        <hr class="hr-height">
      </div>
      <ion-segment-button value="tasks" class="flex-5">
        <ion-label class="font-12 text-transform-none">{{'FRMELEMNTS_LBL_TASK_DETAILS' | translate }}
        </ion-label>
      </ion-segment-button>
    </ion-segment>
  </div>
  <div *ngIf="segmentType == 'details'">
    <app-project-details-card [data]="projectDetails" [categories]="categories">
    </app-project-details-card>
    <app-accordion-list [data]="projectDetails?.learningResources" (actionEvent)="openResource($event)"
      [title]="'FRMELEMNTS_LBL_LEARNING_RESOURCES'" *ngIf="projectDetails?.learningResources?.length">
    </app-accordion-list>
    <app-accordion-list *ngIf="certificateCriteria.length" [data]="certificateCriteria" [showCard]="false"
    [title]="'FRMELEMNTS_LBL_CERTIFICATION_CRITERIA'"> </app-accordion-list>
  </div>

  <app-task-card *ngIf="segmentType == 'tasks'" [data]="projectDetailsCopy" (actionEvent)="onTaskAction($event)"
    [viewOnly]="projectDetailsCopy?.status === allStatusTypes.submitted"></app-task-card>

    <app-no-data class="ion-padding" *ngIf="segmentType == 'tasks' && taskCount==0 && (projectDetails?.status && projectDetails?.status !== allStatusTypes.submitted)" [message]="taskNoDataFound" [color]="'text-primary'"></app-no-data>

    <ion-card class="add-task" (click)="addNewTask()" *ngIf="segmentType == 'tasks' &&  projectDetails?.status && projectDetails?.status !== allStatusTypes.submitted">
      <ion-card-content>
        <ion-grid>
          <ion-row class="flex-box">
              <ion-icon name="add-circle" class="icon"></ion-icon>
              <ion-label class="label ion-margin-start">{{'FRMELEMNTS_LBL_ADD_YOUR_TASK' | translate}}</ion-label>
          </ion-row>
        </ion-grid>
      </ion-card-content>
      
    </ion-card>
</ion-content>

./project-details.component.scss

@import 'src/assets/styles/_custom-mixins';
@import "src/assets/styles/variables";
@import "src/assets/styles/_variables.scss";

.button-disabled {
    --background: #707070 !important;
}
.completed {
    --progress-background: var(--app-green) !important;
}
.zeroTask{
  --progress-background: var(--app-lighter-gray) !important;
}
.in-progress {
    --progress-background: var(--app-quaternary-medium) !important;
}
.sb-course-complete-container {
    white-space: nowrap;
    width: 100%;
    background-color: map-get($colors, light_grayish_green);
    @include padding(8px);
    .img-container{
      width: 20%;
      vertical-align: middle;
      display: inline-block;
    }
    .text-container{
      color: map-get($colors, office_green);
      font-family: "Noto Sans", sans-serif;
      font-size: 0.875rem !important;
      font-weight: bold;
      width: 80%;
      vertical-align: middle;
      display: inline-block;
      padding-left: 10px;
      @include padding(0px 0px 0px 11px);
      white-space: normal;
    }
  }

  .add-task {
    --background: var(--app-primary-light) !important;
    background-color: var(--app-primary-light);
    .flex-box {
      display: flex;
      align-items: center;
      .icon {
        color: var(--app-primary) !important;
        font-size: 1.875rem;
      }
      .label {
        flex: 1;
        font-size: 0.875rem;
      }
    }
  }
  .submit-text{
    color: red;
    font-weight: 600;
    padding: 10px 5px;
    padding-bottom: 0px !important;
    ion-icon{
      background: red;
      color: #fff;
      border-radius: 50%;
      padding: 2px;
      vertical-align: middle;
      margin-left: 3px;
    }
  }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""