File

src/app/modules/user-onboarding/components/onboarding-popup/onboarding-popup.component.ts

Implements

OnInit

Metadata

Index

Properties
Methods
Inputs
Outputs
Accessors

Constructor

constructor(sanitizer: DomSanitizer, deviceRegisterService: DeviceRegisterService, formService: FormService, resourceService: ResourceService, userService: UserService)
Parameters :
Name Type Optional
sanitizer DomSanitizer No
deviceRegisterService DeviceRegisterService No
formService FormService No
resourceService ResourceService No
userService UserService No

Inputs

deviceProfile
Type : IDeviceProfile
guestUserDetails
Type : any
isGuestUser
Type : any
OnboardingFormConfig
Type : any

Outputs

close
Type : EventEmitter
isStepperCompleted
Type : EventEmitter

Methods

getLocation
getLocation()
Returns : void
getOnboardingFormConfig
getOnboardingFormConfig(isBMGSkipped, isUserTypeSkipped, isLocationSkipped)

if all are disabled it wont show the popup

Parameters :
Name Optional Description
isBMGSkipped No
  • Flag to indicate BMGS section
isUserTypeSkipped No
  • Flag to indicate userType section
isLocationSkipped No
  • Flag to indicate Location section
Returns : void
getSanitizedURL
getSanitizedURL(url: string)
Parameters :
Name Type Optional Description
url string No
  • Raw url
Returns : any
isAllScreenDisabled
isAllScreenDisabled()

emit a event to parent to disbale the stepepr popup if true preview screen will be disable if only one scrren is enabled in stepper

Returns : void
locationSubmit
locationSubmit(stepper: MatStepper)

navigate to the next stepper when the submit event is emitted from the location screen. call the getLocation function to get the location details to display on preview page

Parameters :
Name Type Optional Description
stepper MatStepper No
  • stepper event
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onClickNext
onClickNext()
Returns : void
onProcessComplete
onProcessComplete()
Returns : void
Public updateFrameWork
updateFrameWork(stepper: MatStepper)
Parameters :
Name Type Optional Description
stepper MatStepper No
  • stepper event
Returns : void
updateGuestUser
updateGuestUser(defaultVal)
Parameters :
Name Optional Description
defaultVal No
  • API request object
Returns : void
userTypeSubmit
userTypeSubmit(stepper: MatStepper)
Parameters :
Name Type Optional Description
stepper MatStepper No
  • stepper event
Returns : void

Properties

Public deviceRegisterService
Type : DeviceRegisterService
Public formService
Type : FormService
guestUserStoredData
isEditable
Type : boolean
Default value : true
isPreview
Default value : true
isSkipped
Type : boolean
Default value : true
onboardingFilterData
Public onBoardingPopup
Type : string
Default value : 'onboarding-popup'
Public resourceService
Type : ResourceService
Public sanitizer
Type : DomSanitizer
stepper
Type : MatStepper
Decorators :
@ViewChild('stepper')
tenantInfo
Type : ITenantData
Public unsubscribe$
Default value : new Subject<void>()
Public userService
Type : UserService
userTypeStoredData

Accessors

onboardingScreenType
getonboardingScreenType()
import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { DeviceRegisterService, FormService, UserService } from '@sunbird/core';
import { ResourceService } from '@sunbird/shared';
import * as _ from 'lodash-es';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ITenantData } from './../../../core/services/tenant/interfaces/tenant';
import { IDeviceProfile } from '../../../shared-feature/interfaces';
import { MatStepper } from '@angular/material/stepper';
import { DomSanitizer } from '@angular/platform-browser';
import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
import { onboardingScreenType } from '../../components/onboarding-popup/onboarding-popup.component.models'

@Component({
  selector: 'app-onboarding-popup',
  templateUrl: './onboarding-popup.component.html',
  styleUrls: ['./onboarding-popup.component.scss'],
  providers: [{
    provide: STEPPER_GLOBAL_OPTIONS, useValue: { displayDefaultIndicatorType: false }
  }]
})
export class OnboardingPopupComponent implements OnInit {
  @Input() deviceProfile: IDeviceProfile;
  @Input() guestUserDetails;
  @Input() isGuestUser;
  @Output() close = new EventEmitter<any>();
  @Output() isStepperCompleted = new EventEmitter<any>();
  @Input() OnboardingFormConfig;
  public unsubscribe$ = new Subject<void>();
  public onBoardingPopup = 'onboarding-popup';
  isEditable: boolean = true;
  guestUserStoredData;
  userTypeStoredData;
  tenantInfo: ITenantData;
  isSkipped: boolean = true;
  onboardingFilterData;
  isPreview = true;
  @ViewChild('stepper') stepper: MatStepper;
  get onboardingScreenType() { return onboardingScreenType; }
  constructor(
    public sanitizer: DomSanitizer,
    public deviceRegisterService: DeviceRegisterService,
    public formService: FormService,
    public resourceService: ResourceService,
    public userService: UserService

  ) { }
  ngOnInit() {
    this.guestUserStoredData = JSON.parse(localStorage.getItem('guestUserDetails'));
    this.getOnboardingFormConfig(false, false, false);
  }
  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  /**
   * @param  {MatStepper} stepper - stepper event 
   * @description -   navigate to the next stepper when the submit event is emitted from  the userType screen.
   */
  userTypeSubmit(stepper: MatStepper) {
    this.userTypeStoredData = localStorage.getItem('guestUserType');
    this.isSkipped = false;
    if (this.onboardingFilterData.length === 1) {
      this.isStepperCompleted.emit(true);
    } else {
      stepper.next();
    }
  }

  /**
   * @param  {MatStepper} stepper - stepper event 
   * @description -  locationSubmit 
   * navigate to the next stepper when the submit event is emitted from  the location screen.
   * call the getLocation function to get the location details to display on preview page
   */
  locationSubmit(stepper: MatStepper) { // location form submit
    this.guestUserStoredData = JSON.parse(localStorage.getItem('guestUserDetails'));
    this.isSkipped = false;
    this.getLocation();
    if (this.onboardingFilterData.length === 1) {
      this.isStepperCompleted.emit(true);
    } else {
      stepper.next();
    }
  }

  /**
  * @description -  to get the device profile details
  */
  getLocation() {
    this.deviceRegisterService.fetchDeviceProfile().pipe(takeUntil(this.unsubscribe$)).subscribe((response) => {
      this.deviceProfile = _.get(response, 'result');
    });
  }

  /**
   * @param  {MatStepper} stepper - stepper event 
   * @description -  navigate to the next stepper when the submit event is emitted from  the BMGS screen.
   */
  public updateFrameWork(stepper: MatStepper) {
    this.guestUserStoredData = JSON.parse(localStorage.getItem('guestUserDetails'));
    this.isSkipped = false;
    if (this.onboardingFilterData.length === 1) {
      this.isStepperCompleted.emit(true);
    } else {
      stepper.next();
    }
  }

  /**
   * @param  {Boolean} isBMGSkipped - Flag to indicate BMGS section
   * @param  {Boolean} isUserTypeSkipped - Flag to indicate userType section
   * @param  {Boolean} isLocationSkipped - Flag to indicate Location section
   * @description -  function to validate form config if disabled & having default value. it will update the api based on default
   * if all are disabled it wont show the popup
   */
  getOnboardingFormConfig(isBMGSkipped, isUserTypeSkipped, isLocationSkipped) { // condition for form config
    _.map(this.OnboardingFormConfig, (formConfigRes) => {
      if (_.get(formConfigRes, 'renderOptions.name') === onboardingScreenType.BMGS && ((_.get(formConfigRes, 'isEnabled') === false && _.get(formConfigRes, 'defaults')) || (isBMGSkipped && _.get(formConfigRes, 'defaults')))) {
        this.updateGuestUser(_.get(formConfigRes, 'defaults'));
      } else if (_.get(formConfigRes, 'renderOptions.name') === onboardingScreenType.USERTYPE && ((_.get(formConfigRes, 'isEnabled') === false && _.get(formConfigRes, 'defaults.role')) || (isUserTypeSkipped && _.get(formConfigRes, 'defaults.role')))) {
        localStorage.setItem('guestUserType', _.get(formConfigRes, 'defaults.role'));
        this.userTypeStoredData = localStorage.getItem('guestUserType')
      } else if (_.get(formConfigRes, 'renderOptions.name') === onboardingScreenType.LOCATION && ((_.get(formConfigRes, 'isEnabled') === false && _.get(formConfigRes, 'defaults')) || (isLocationSkipped && _.get(formConfigRes, 'defaults')))) {
        this.deviceRegisterService.updateDeviceProfile(_.get(formConfigRes, 'defaults')).subscribe();
      }
      this.isAllScreenDisabled();
    });
  }

  /**
   * @param  {object} defaultVal -   API request object
   * @description - update the guestUser Service with default value
   */
  updateGuestUser(defaultVal) {
    const user: any = { name: 'guest', formatedName: 'Guest', framework: defaultVal };
    const userType = localStorage.getItem('userType');
    if (userType) {
      user.role = userType;
    }
    this.userService.createGuestUser(user).subscribe();
  }

  /**
   * @description - function to check weather all the fileds are disabled
   * emit a event to parent to disbale the stepepr popup if true
   * preview screen will be disable if only one scrren is enabled in stepper
   */
  isAllScreenDisabled() {
    this.onboardingFilterData = _.filter(this.OnboardingFormConfig, (res) => res.isEnabled === true);
    if (this.onboardingFilterData.length === 0) {
      this.isPreview = false;
      this.isStepperCompleted.emit(true);
    }
    if (this.onboardingFilterData.length === 1) {
      this.isPreview = false;
    }
  }

  /**
  * @description - close the stepper popup when the user completes the process
  */
  onProcessComplete() {
    const userType = localStorage.getItem('guestUserType');
    if (!this.guestUserStoredData) {
      this.getOnboardingFormConfig(true, false, false);
    }
    if (!userType) {
      this.getOnboardingFormConfig(false, true, false);
    }
    if (!this.deviceProfile) {
      this.getOnboardingFormConfig(false, false, true);
    }
    this.isStepperCompleted.emit(true);
  }

  /**
   * @param  {string} url  - Raw url
   * @description - url to be sanitized to display in iframe
   */
  getSanitizedURL(url: string) {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }

  /**
   * @description - it will return a flag if all the steps are skipped
   */
  onClickNext() {
    if (this.onboardingFilterData.length === 1) {
      this.onProcessComplete();
    }
  }
}
<div *ngIf="OnboardingFormConfig.length">
  <app-modal-wrapper #modal>
      <ng-template sbModalContent>
          <mat-horizontal-stepper style="background: var(--sbt-body-bg);" [linear]="true" #stepper>
              <ng-container *ngFor="let configData of OnboardingFormConfig | sortBy:'sequence':'asc'">
                  <h3>Your preferences</h3>
                  <!-- component -->
                  <mat-step
                      *ngIf="configData?.isEnabled && [onboardingScreenType.HTML, onboardingScreenType.URL,onboardingScreenType.VIDEO,onboardingScreenType.PDF,onboardingScreenType.COMPONENT ].includes(configData?.renderOptions?.type)">
                      <ng-template matStepLabel>{{configData?.stepLabel}}</ng-template>
                      <mat-label *ngIf="configData?.description">{{configData?.description}}</mat-label>

                      <!-- #1 userType -->
                      <app-onboarding-user-selection
                          *ngIf="configData?.renderOptions?.name === onboardingScreenType.USERTYPE"
                          [tenantInfo]="tenantInfo" [isStepper]="true" (userSelect)="userTypeSubmit(stepper)">
                      </app-onboarding-user-selection>

                      <!-- #2 Location -->
                      <app-location-selection
                          *ngIf="configData?.renderOptions?.name === onboardingScreenType.LOCATION"
                          [deviceProfile]="deviceProfile" [isClosable]="false" [isStepper]="true"
                          (close)="locationSubmit(stepper)">
                          <img [src]="tenantInfo?.logo" class="b\rand-logo" height="40"
                              alt="{{resourceService?.frmelmnts?.lbl?.welcomeToInstance | interpolate:'{instance}': tenantInfo?.titleName}}" />
                          <h1 class="mb-0 header-text">{{resourceService?.frmelmnts?.lbl?.welcomeToInstance |
                              interpolate:'{instance}': tenantInfo?.titleName}}</h1>
                      </app-location-selection>

                      <!-- #3 BMGS -->
                      <app-popup *ngIf="configData?.renderOptions?.name === onboardingScreenType.BMGS"
                          [dialogProps]="data" [buttonLabel]="resourceService?.frmelmnts?.btn?.submit"
                          [isGuestUser]="isGuestUser" [isStepper]="true" (submit)="updateFrameWork(stepper)">
                      </app-popup>

                      <!-- html code snippits -->
                      <div *ngIf="configData?.renderOptions?.type === onboardingScreenType.HTML"
                          [innerHTML]="configData?.renderOptions?.content">
                      </div>

                      <!-- url based screen -->
                      <div *ngIf="configData?.renderOptions?.type === onboardingScreenType.URL">
                          <iframe width="580" height="330" frameborder="0" class="dashboard-iframe"
                              [src]="getSanitizedURL(configData?.url)">
                          </iframe>
                      </div>

                      <!-- SunBird video Player -->

                      <div *ngIf="configData?.renderOptions?.type === onboardingScreenType.VIDEO" class="aspectratio"
                          data-ratio="16:9" id="help-video-aspect-ratio" #aspectRatio>
                          <sunbird-video-player [playerConfig]="configData?.renderOptions?.videoPlayerConfig">
                          </sunbird-video-player>
                      </div>

                      <!-- SunBird pdf Player -->
                      <div *ngIf="configData?.renderOptions?.type === onboardingScreenType.PDF" class="aspectratio"
                          data-ratio="16:9" id="help-video-aspect-ratio" #aspectRatio>
                          <sunbird-pdf-player [playerConfig]="configData?.renderOptions?.pdfPlayerConfig">
                          </sunbird-pdf-player>
                      </div>
                      <!-- action button -->
                      <button *ngIf="!configData?.isMandatory" class="sb-btn sb-btn-normal sb-btn-primary"
                          (click)="onClickNext()" matStepperNext>Skip/Next &#8250;</button>
                      <div *ngIf="isPreview">

                          <button *ngIf="configData?.sequence != 1" class="sb-btn sb-btn-normal sb-btn-primary"
                              matStepperPrevious>&#8249; Back</button>
                      </div>
                  </mat-step>
              </ng-container>

              <!-- by default preview screen -->
              <mat-step *ngIf="isPreview">
                  <ng-template matStepLabel>Preview</ng-template>
                  <p *ngIf="!isSkipped">You have selected these below data in previous section !!</p>
                  <p *ngIf="isSkipped">You have skipped all previous sections !!</p>
                  <div *ngIf="!isSkipped" class="user-detail-container p-24 my-16" role="list">
                      <div class="user-detail-list" role="listitem" tabindex="0"
                          attr.aria-label="Name:{{guestUserStoredData?.formatedName}}"
                          *ngIf="guestUserStoredData && guestUserStoredData?.formatedName">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">Name:</label>
                          <label
                              class="label-values fnormal font-weight-bold">{{guestUserStoredData?.formatedName}}</label>
                      </div>
                      <div class="user-detail-list" role="listitem" tabindex="1"
                          attr.aria-label="Role:{{userTypeStoredData}}" *ngIf="userTypeStoredData">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">Role:</label>
                          <label class="label-values fnormal font-weight-bold">{{userTypeStoredData}}</label>
                      </div>
                      <div class="user-detail-list" role="listitem" tabindex="0"
                          attr.aria-label="Board:{{guestUserStoredData?.framework?.board}}"
                          *ngIf="guestUserStoredData && guestUserStoredData?.framework?.board">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">Board:</label>
                          <label
                              class="label-values fnormal font-weight-bold">{{guestUserStoredData?.framework?.board}}</label>
                      </div>
                      <div class="user-detail-list" role="listitem" tabindex="0"
                          attr.aria-label="Medium:{{guestUserStoredData?.framework?.medium}}"
                          *ngIf="guestUserStoredData && guestUserStoredData?.framework?.medium">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">Medium:</label>
                          <label
                              class="label-values fnormal font-weight-bold">{{guestUserStoredData?.framework?.medium}}</label>
                      </div>
                      <div class="user-detail-list" role="listitem" tabindex="0"
                          attr.aria-label="Grade:{{guestUserStoredData?.framework?.gradeLevel}}"
                          *ngIf="guestUserStoredData && guestUserStoredData?.framework?.gradeLevel">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">Grade:</label>
                          <label
                              class="label-values fnormal font-weight-bold">{{guestUserStoredData?.framework?.gradeLevel}}</label>
                      </div>
                      <div class="user-detail-list" role="listitem" tabindex="0"
                          attr.aria-label="District:{{deviceProfile?.userDeclaredLocation?.district}}"
                          *ngIf="deviceProfile && deviceProfile?.userDeclaredLocation?.district">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">District:</label>
                          <label
                              class="label-values fnormal font-weight-bold">{{deviceProfile?.userDeclaredLocation?.district}}</label>
                      </div>
                      <div class="user-detail-list" role="listitem" tabindex="0"
                          attr.aria-label="State:{{deviceProfile?.userDeclaredLocation?.state}}"
                          *ngIf="deviceProfile && deviceProfile?.userDeclaredLocation?.state">
                          <label class="label-names fnormal font-weight-normal pr-8" role="heading">State:</label>
                          <label
                              class="label-values fnormal font-weight-bold">{{deviceProfile?.userDeclaredLocation?.state}}</label>
                      </div>
                  </div>
                  <button class="sb-btn sb-btn-normal sb-btn-primary" (click)="onProcessComplete()">Done</button>
                  <button *ngIf="configData?.sequence != 1" class="sb-btn sb-btn-normal sb-btn-primary"
                      matStepperPrevious>&#8249; Back</button>
              </mat-step>
          </mat-horizontal-stepper>
      </ng-template>
  </app-modal-wrapper>
</div>

./onboarding-popup.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
@use "components/video" as *;

::ng-deep .mat-step-header .mat-step-icon-selected {
    border-color: #024f9d;
    background-color: #024f9d;
}

::ng-deep .mat-step-header .mat-step-icon {
    border-color: #024f9d;
    background-color: #024f9d;
}

button {
    float: right;
}
// to disable the stepper tab
::ng-deep .mat-horizontal-stepper-header{
    pointer-events: none !important;
  }

    // user-details gray box new design css
.user-detail-container{
    border-radius: 1.5rem;
    background: var(--rc-e9e5e5);
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-gap: 0.5rem;
    text-transform: capitalize;
    width: 100%;
    max-width: 36rem;
    margin: 1rem auto;

    .user-detail-list{
        display: flex;
        @include respond-below(sm){
            flex-direction: column;
        }
        .label-values{
            word-break: break-word;
        }
    }

    .user-detail-list:nth-child(1){ order: 1; }
    .user-detail-list:nth-child(2) { order: 2; }
    .user-detail-list:nth-child(3) { order: 3; }
    .user-detail-list:nth-child(4){ order: 4; }
    .user-detail-list:nth-child(5){ order: 1; }
    .user-detail-list:nth-child(6) { order: 2; }
    .user-detail-list:nth-child(7) { order: 3; }
  }
  
  @include respond-below(sm){
    .user-detail-container {
      grid-template-columns: 1fr;
      border-radius:0;

      .user-detail-list:nth-child(1){ order: 1; }
      .user-detail-list:nth-child(2) { order: 2; }
      .user-detail-list:nth-child(3) { order: 3; }
      .user-detail-list:nth-child(4){ order: 4; }
      .user-detail-list:nth-child(5){ order: 5; }
      .user-detail-list:nth-child(6) { order: 6; }
      .user-detail-list:nth-child(7) { order: 7; }
  
   }
  }
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""