File

src/app/modules/workspace/components/content-editors/new-collection-editor/new-collection-editor.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods

Constructor

constructor(userService: UserService, layoutService: LayoutService, telemetryService: TelemetryService, publicDataService: PublicDataService, config: ConfigService, contentService: ContentService, router: Router, editorService: EditorService, workSpaceService: WorkSpaceService, frameworkService: FrameworkService, toasterService: ToasterService, activatedRoute: ActivatedRoute, navigationHelperService: NavigationHelperService, lazzyLoadScriptService: LazzyLoadScriptService, resourceService: ResourceService)
Parameters :
Name Type Optional
userService UserService No
layoutService LayoutService No
telemetryService TelemetryService No
publicDataService PublicDataService No
config ConfigService No
contentService ContentService No
router Router No
editorService EditorService No
workSpaceService WorkSpaceService No
frameworkService FrameworkService No
toasterService ToasterService No
activatedRoute ActivatedRoute No
navigationHelperService NavigationHelperService No
lazzyLoadScriptService LazzyLoadScriptService No
resourceService ResourceService No

Methods

Private disableBrowserBackButton
disableBrowserBackButton()
Returns : void
editorEventListener
editorEventListener(event)
Parameters :
Name Optional
event No
Returns : void
generateInteractEvent
generateInteractEvent(intractEventEdata)
Parameters :
Name Optional
intractEventEdata No
Returns : void
Public getCollectionDetails
getCollectionDetails()
Returns : any
Public getDetails
getDetails()
Returns : any
Private getEditorMode
getEditorMode()
Returns : "edit" | "read" | "review"
getFrameWorkDetails
getFrameWorkDetails()
Returns : void
getPrimaryCategoryData
getPrimaryCategoryData(childrenData)
Parameters :
Name Optional
childrenData No
Returns : any
loadScripts
loadScripts()
Returns : void
lockContent
lockContent()
Returns : any
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
redirectToWorkSpace
redirectToWorkSpace()
Returns : void
retireLock
retireLock()
Returns : void
setEditorConfig
setEditorConfig()
Returns : void
switchLayout
switchLayout()
Returns : void
Public validateRequest
validateRequest()

Validate the request

Returns : boolean

Properties

Public baseUrl
Type : string
Private browserBackEventSubscribe
Public collectionDetails
Type : any
Public deviceId
Type : string
Public editorConfig
Type : any
Public editorService
Type : EditorService
Public frameworkService
Type : FrameworkService
Public hierarchyConfig
Type : any
Public layoutService
Type : LayoutService
Public layoutType
Type : string
Public portalVersion
Type : string
Public publicStorageAccount
Type : any
Public queryParams
Type : object
Public resourceService
Type : ResourceService
Private routeParams
Type : any
Public showLoader
Default value : false
Public showQuestionEditor
Default value : false
Public sunbirdCollectionChildrenLimit
Type : any
Public sunbirdQuestionSetChildrenLimit
Type : any
Public toasterService
Type : ToasterService
Public userProfile
Type : any
Public workSpaceService
Type : WorkSpaceService
import { Component, OnDestroy, OnInit } from '@angular/core';
import { UserService, PublicDataService, ContentService, FrameworkService } from '@sunbird/core';
import { TelemetryService, IInteractEventEdata } from '@sunbird/telemetry';
import { ConfigService, NavigationHelperService, ToasterService, ResourceService, LayoutService, ServerResponse} from '@sunbird/shared';
import { EditorService, WorkSpaceService } from './../../../services';
import { ActivatedRoute, Router } from '@angular/router';
import * as _ from 'lodash-es';
import { combineLatest, of, throwError } from 'rxjs';
import { map, mergeMap, tap, first } from 'rxjs/operators';
import { LazzyLoadScriptService } from 'LazzyLoadScriptService';

@Component({
  selector: 'app-new-collection-editor',
  templateUrl: './new-collection-editor.component.html',
  styleUrls: ['./new-collection-editor.component.scss']
})
export class NewCollectionEditorComponent implements OnInit, OnDestroy {
  public editorConfig: any;
  public deviceId: string;
  public portalVersion: string;
  public userProfile: any;
  public showLoader = false;
  private routeParams: any;
  public queryParams: object;
  public collectionDetails: any;
  public showQuestionEditor = false;
  private browserBackEventSubscribe;
  public hierarchyConfig: any;
  public layoutType: string;
  public baseUrl: string;
  public publicStorageAccount: any;
  public sunbirdQuestionSetChildrenLimit: any;
  public sunbirdCollectionChildrenLimit: any;
  constructor(private userService: UserService, public layoutService: LayoutService,
    private telemetryService: TelemetryService, private publicDataService: PublicDataService,
    private config: ConfigService, private contentService: ContentService, private router: Router,
    public editorService: EditorService, public workSpaceService: WorkSpaceService,
    public frameworkService: FrameworkService, public toasterService: ToasterService,
    private activatedRoute: ActivatedRoute, private navigationHelperService: NavigationHelperService,
    private lazzyLoadScriptService: LazzyLoadScriptService,
    public resourceService: ResourceService) {
    const deviceId = (<HTMLInputElement>document.getElementById('deviceId'));
    this.deviceId = deviceId ? deviceId.value : '';
    const buildNumber = (<HTMLInputElement>document.getElementById('buildNumber'));
    this.portalVersion = buildNumber && buildNumber.value ? buildNumber.value.slice(0, buildNumber.value.lastIndexOf('.')) : '1.0';
    this.layoutType = localStorage.getItem('layoutType') || 'joy';
    this.baseUrl = (<HTMLInputElement>document.getElementById('baseUrl'))
      ? (<HTMLInputElement>document.getElementById('baseUrl')).value : document.location.origin;
      this.publicStorageAccount = (<HTMLInputElement>document.getElementById('publicStorageAccount'))
      ? (<HTMLInputElement>document.getElementById('publicStorageAccount')).value : undefined;
      this.sunbirdQuestionSetChildrenLimit = (<HTMLInputElement>document.getElementById('sunbirdQuestionSetChildrenLimit')) ?
      (<HTMLInputElement>document.getElementById('sunbirdQuestionSetChildrenLimit')).value : 500;
      this.sunbirdCollectionChildrenLimit = (<HTMLInputElement>document.getElementById('sunbirdCollectionChildrenLimit')) ?
      (<HTMLInputElement>document.getElementById('sunbirdCollectionChildrenLimit')).value : 1200;
  }

  ngOnInit() {
    this.routeParams = this.activatedRoute.snapshot.params;
    this.userProfile = this.userService.userProfile;
    this.queryParams = this.activatedRoute.snapshot.queryParams;
    this.disableBrowserBackButton();
    this.getDetails().pipe(
      first(),
      tap(data => {
        this.switchLayout();
      })).subscribe((data) => {
        this.showLoader = true;
        this.showQuestionEditor = this.collectionDetails.mimeType === 'application/vnd.sunbird.questionset' ? true : false;
        this.getFrameWorkDetails();
        this.loadScripts();
      },
      (error) => {
          if (error === 'NO_PERMISSION') {
            this.redirectToWorkSpace();
            this.toasterService.error(this.resourceService.messages.emsg.m0013);
          } else if (['RESOURCE_SELF_LOCKED', 'RESOURCE_LOCKED'].includes(_.get(error, 'error.params.err'))) {
            this.retireLock();
            this.toasterService.error(_.replace(error.error.params.errmsg, 'resource', 'content'));
          } else {
            this.redirectToWorkSpace();
            this.toasterService.error(this.resourceService.messages.emsg.m0004);
          }
      });
  }

  switchLayout() {
    if (this.layoutType === 'joy') {
      localStorage.setItem('collectionEditorLayoutType', this.layoutType);
      this.layoutService.initiateSwitchLayout();
    }
  }

  loadScripts() {
    combineLatest(this.lazzyLoadScriptService.loadScript('semanticTreePicker.js'));
  }

  public getCollectionDetails() {
    const options: any = { params: {} };
    options.params.mode = 'edit';
    if (this.routeParams.type && this.routeParams.type === 'QuestionSet') {
      return this.workSpaceService.getQuestion(this.routeParams.contentId, options).
      pipe(mergeMap((data) => {
        this.collectionDetails = data.result.questionset;
        if (this.validateRequest()) {
          return of(data);
        } else {
          return throwError('NO_PERMISSION');
        }
      }));
    } else {
      return this.editorService.getContent(this.routeParams.contentId, options).
      pipe(mergeMap((data) => {
        this.collectionDetails = data.result.content;
        if (this.validateRequest()) {
          return of(data);
        } else {
          return throwError('NO_PERMISSION');
        }
      }));
    }
  }

  public getDetails() {
    const lockInfo = _.pick(this.queryParams, 'lockKey', 'expiresAt', 'expiresIn');
    const allowedEditState = ['draft', 'allcontent', 'collaborating-on', 'uploaded', 'alltextbooks'].includes(this.routeParams.state);
    const allowedEditStatus = this.routeParams.contentStatus ? ['draft'].includes(this.routeParams.contentStatus.toLowerCase()) : false;
    if (_.isEmpty(lockInfo) && allowedEditState && ( allowedEditStatus || this.userService.userProfile.rootOrgAdmin )) {
      return combineLatest(
        this.getCollectionDetails(),
        this.editorService.getOwnershipType(),
        this.lockContent(),
      ).pipe(map(data => ({ collectionInfo: data[0], ownershipType: data[1]})));
    } else {
      return combineLatest(
        this.getCollectionDetails(),
        this.editorService.getOwnershipType(),
      ).pipe(map(data => ({ collectionInfo: data[0], ownershipType: data[1]})));
    }
  }

  lockContent () {
    const contentInfo = {
      contentType: this.routeParams.type,
      framework: this.routeParams.framework,
      identifier: this.routeParams.contentId,
      mimeType: this.routeParams.type && this.routeParams.type === 'QuestionSet' ? 'application/vnd.sunbird.questionset' : 'application/vnd.ekstep.content-collection'
    };
    const input = {
      resourceId : contentInfo.identifier,
      resourceType : 'Content',
      resourceInfo : JSON.stringify(contentInfo),
      creatorInfo : JSON.stringify({'name': this.userService.userProfile.firstName, 'id': this.userService.userProfile.id}),
      createdBy : this.userService.userProfile.id,
      isRootOrgAdmin: this.userService.userProfile.rootOrgAdmin
    };
    return this.workSpaceService.lockContent(input).pipe(tap((data) => {
      this.queryParams = data.result;
      this.router.navigate([], {relativeTo: this.activatedRoute, queryParams: data.result});
    }));
  }

  retireLock () {
    const inputData = {'resourceId': this.routeParams.contentId, 'resourceType': 'Content'};
    this.workSpaceService.retireLock(inputData).subscribe(
      (data: ServerResponse) => {
        this.redirectToWorkSpace();
      },
      (err: ServerResponse) => {
        this.redirectToWorkSpace();
      }
    );
  }

  /**
   *Validate the request
   */
   public validateRequest() {
    const validStatus = _.indexOf(this.config.editorConfig.COLLECTION_EDITOR.collectionStatus, this.collectionDetails.status) > -1;
    const validState = _.indexOf(this.config.editorConfig.COLLECTION_EDITOR.collectionState, this.routeParams.state) > -1;
    if ((this.collectionDetails.mimeType === this.config.editorConfig.COLLECTION_EDITOR.mimeCollection
    || this.collectionDetails.mimeType === this.config.editorConfig.QUESTIONSET_EDITOR.mimeCollection) && validStatus) {
      if (validState && this.collectionDetails.createdBy !== this.userService.userid) {
        return true; // we need to remove this case or validState should be changed
      } else if (validState && _.includes(this.collectionDetails.collaborators, this.userService.userid)) {
        return true;
      } else if (validState && this.collectionDetails.createdBy === this.userService.userid) {
        return true;
      } else if (this.collectionDetails.createdBy === this.userService.userid) {
        return true;
      }
      return false;
    }
    return false;
  }

  getFrameWorkDetails() {
    const objectType = this.collectionDetails.mimeType === 'application/vnd.sunbird.questionset' ? 'QuestionSet' : 'Collection';
    this.workSpaceService.getCategoryDefinition(objectType, this.collectionDetails.primaryCategory, this.userService.channel)
    .subscribe(data => {
      // tslint:disable-next-line:max-line-length
      if (_.get(data, 'result.objectCategoryDefinition.objectMetadata.config')) {
        this.hierarchyConfig = _.get(data, 'result.objectCategoryDefinition.objectMetadata.config.sourcingSettings.collection');
        if (!_.isEmpty(this.hierarchyConfig.children)) {
          this.hierarchyConfig.children = this.getPrimaryCategoryData(this.hierarchyConfig.children);
        }
        if (!_.isEmpty(this.hierarchyConfig.hierarchy)) {
          _.forEach(this.hierarchyConfig.hierarchy, (hierarchyValue) => {
            if (_.get(hierarchyValue, 'children')) {
              hierarchyValue['children'] = this.getPrimaryCategoryData(_.get(hierarchyValue, 'children'));
            }
          });
        }
      }
      if (!this.showQuestionEditor) {
        this.setEditorConfig();
        this.editorConfig.context['framework'] = _.get(this.collectionDetails, 'framework');
        if (_.get(this.collectionDetails, 'primaryCategory') && _.get(this.collectionDetails, 'primaryCategory') !== 'Curriculum Course') {
          this.editorConfig.context['targetFWIds'] = _.get(this.collectionDetails, 'targetFWIds');
        }
        this.showLoader = false;
      } else {
        this.setEditorConfig();
        this.showLoader = false;
      }
    }, err => {
      this.toasterService.error(this.resourceService.messages.emsg.m0015);
    });
  }

  getPrimaryCategoryData(childrenData) {
    _.forEach(childrenData, (value, key) => {
      if (_.isEmpty(value)) {
        switch (key) {
          case 'Question':
            childrenData[key] = this.frameworkService['_channelData'].questionPrimaryCategories
            || this.config.appConfig.WORKSPACE.questionPrimaryCategories;
            break;
          case 'Content':
            childrenData[key] = this.frameworkService['_channelData'].contentPrimaryCategories || [];
            break;
          case 'Collection':
            childrenData[key] = this.frameworkService['_channelData'].collectionPrimaryCategories || [];
            break;
          case 'QuestionSet':
            childrenData[key] = this.frameworkService['_channelData'].questionsetPrimaryCategories || [];
            break;
        }
      }
    });
    return childrenData;
  }

  editorEventListener(event) {
    const layoutType = localStorage.getItem('layoutType');
    const collectionEditorLayoutType = localStorage.getItem('collectionEditorLayoutType');
    if (layoutType === 'default' && collectionEditorLayoutType) {
      this.layoutService.initiateSwitchLayout();
      localStorage.removeItem('collectionEditorLayoutType');
    }
    const contentStatus = this.routeParams.contentStatus.toLowerCase();
    if (contentStatus === 'draft' || contentStatus === 'live') {
      this.retireLock();
    } else {
      this.redirectToWorkSpace();
    }
  }

  redirectToWorkSpace () {
    if (this.routeParams.state === 'collaborating-on') {
      this.navigationHelperService.navigateToWorkSpace('/workspace/content/collaborating-on/1');
    } else if ( this.routeParams.state === 'upForReview') {
      this.navigationHelperService.navigateToWorkSpace('/workspace/content/upForReview/1');
    } else if ( this.routeParams.state === 'allcontent') {
      this.navigationHelperService.navigateToWorkSpace('/workspace/content/allcontent/1');
    } else {
      this.navigationHelperService.navigateToWorkSpace('/workspace/content/draft/1');
    }
  }

  ngOnDestroy() {
    if (this.browserBackEventSubscribe) {
      this.browserBackEventSubscribe.unsubscribe();
    }
    sessionStorage.setItem('inEditor', 'false');
    this.workSpaceService.newtoggleWarning();
  }

  setEditorConfig() {
    // tslint:disable-next-line:max-line-length
    const additionalCategories = _.merge(this.frameworkService['_channelData'].contentAdditionalCategories, this.frameworkService['_channelData'].collectionAdditionalCategories) || this.config.appConfig.WORKSPACE.primaryCategory;
    this.editorConfig = {
      context: {
        identifier: this.routeParams.contentId,
        channel: this.userService.channel,
        authToken: '',
        sid: this.userService.sessionId,
        did: this.deviceId,
        uid: this.userService.userid,
        additionalCategories: additionalCategories,
        host: this.baseUrl,
        pdata: {
          id: this.userService.appId,
          ver: this.portalVersion,
          pid: 'sunbird-portal'
        },
        actor: {
          id: this.userService.userid || 'anonymous',
          type: 'User'
        },
        contextRollup: this.telemetryService.getRollUpData(this.userProfile.organisationIds),
        tags: this.userService.dims,
        timeDiff: this.userService.getServerTimeDiff,
        defaultLicense: this.frameworkService.getDefaultLicense(),
        endpoint: '/data/v3/telemetry',
        env: this.showQuestionEditor ? 'questionset_editor' : 'collection_editor',
        user: {
          id: this.userService.userid,
          orgIds: this.userProfile.organisationIds,
          organisations: this.userService.orgIdNameMap,
          fullName : !_.isEmpty(this.userProfile.lastName) ? this.userProfile.firstName + ' ' + this.userProfile.lastName :
          this.userProfile.firstName,
          firstName: this.userProfile.firstName,
          lastName : !_.isEmpty(this.userProfile.lastName) ? this.userProfile.lastName : '',
          isRootOrgAdmin: this.userService.userProfile.rootOrgAdmin
        },
        channelData: this.frameworkService['_channelData'],
        cloudStorageUrls : this.userService.cloudStorageUrls,
        cloudStorage: _.get(this.config, 'editorConfig.COLLECTION_EDITOR.cloudStorage', {})
      },
      config: {
        primaryCategory: this.collectionDetails.primaryCategory,
        objectType: _.get(this.collectionDetails, 'objectType') || 'QuestionSet',
        mode: this.getEditorMode(),
        questionSet: {
          maxQuestionsLimit: this.sunbirdQuestionSetChildrenLimit
        },
        collection: {
          maxContentsLimit: this.sunbirdCollectionChildrenLimit
        },
      }
    };
    this.editorConfig.config.showAddCollaborator = true;
    this.editorConfig.config.publicStorageAccount = this.publicStorageAccount;
    if (this.showQuestionEditor) {
      this.editorConfig.config.showAddCollaborator = false;
      this.editorConfig.context.framework = this.collectionDetails.framework || this.frameworkService['_channelData'].defaultFramework;
    }
    this.editorConfig.config = _.assign(this.editorConfig.config, this.hierarchyConfig);
  }

  private disableBrowserBackButton() {
    window.location.hash = 'no';
    sessionStorage.setItem('inEditor', 'true');
    this.workSpaceService.newtoggleWarning(this.routeParams.type);
    this.browserBackEventSubscribe = this.workSpaceService.browserBackEvent.subscribe(() => {
      const intractEventEdata: IInteractEventEdata = {
        id: 'browser-back-button',
        type: 'click',
        pageid: 'collection-editor'
      };
      this.generateInteractEvent(intractEventEdata);
    });
  }

  private getEditorMode() {
    const contentStatus = this.collectionDetails.status.toLowerCase();
    if (contentStatus === 'draft' || contentStatus === 'live' || contentStatus === 'flagdraft'
        || contentStatus === 'unlisted') {
      return 'edit';
    }

    if (contentStatus === 'flagged' || contentStatus === 'flagreview') {
      return 'read';
    }

    if (contentStatus === 'review') {
      if (this.collectionDetails.createdBy === this.userProfile.id) {
        return 'read';
      } else {
        return 'review';
      }
    }
  }

  generateInteractEvent(intractEventEdata) {
    if (intractEventEdata) {
      const telemetryInteractData: any = {
        context: {
          env: 'collection-editor'
        },
        edata: intractEventEdata
      };
      if (this.collectionDetails) {
        telemetryInteractData.object = {
          id: this.collectionDetails.identifier,
          type: this.collectionDetails.contentType || this.collectionDetails.resourceType || 'collection',
          ver: this.collectionDetails.pkgVersion ? this.collectionDetails.pkgVersion.toString() : '1.0',
        };
      }
      this.telemetryService.interact(telemetryInteractData);
    }
  }

}
<ng-container *ngIf="!showLoader && editorConfig">
  <lib-editor [editorConfig]="editorConfig" (editorEmitter)="editorEventListener($event)" ></lib-editor>
</ng-container>

<sui-dimmer class="page" *ngIf="showLoader" [isDimmed]="showLoader">
  <div class="ui text loader"><h2>Loading...</h2></div>
</sui-dimmer>

./new-collection-editor.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""