File

src/app/modules/shared-feature/components/user-location/user-location.component.ts

Implements

OnInit OnDestroy AfterViewInit

Metadata

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(resourceService: ResourceService, toasterService: ToasterService, formBuilder: UntypedFormBuilder, profileService: ProfileService, activatedRoute: ActivatedRoute, router: Router, userService: UserService, deviceRegisterService: DeviceRegisterService, navigationhelperService: NavigationHelperService, telemetryService: TelemetryService, popupControlService: PopupControlService)
Parameters :
Name Type Optional
resourceService ResourceService No
toasterService ToasterService No
formBuilder UntypedFormBuilder No
profileService ProfileService No
activatedRoute ActivatedRoute No
router Router No
userService UserService No
deviceRegisterService DeviceRegisterService No
navigationhelperService NavigationHelperService No
telemetryService TelemetryService No
popupControlService PopupControlService No

Inputs

deviceProfile
Type : any
isCustodianOrgUser
Type : any
userLocationDetails
Type : any
userProfile
Type : any

Outputs

close
Type : EventEmitter

Methods

closeModal
closeModal()
Returns : void
enableSubmitButton
enableSubmitButton()
Returns : void
Private generateInteractEvent
generateInteractEvent(telemetryData)
Parameters :
Name Optional
telemetryData No
Returns : void
getDistrict
getDistrict(stateId)
Parameters :
Name Optional
stateId No
Returns : any
getLocationCodes
getLocationCodes(locationToProcess)
Parameters :
Name Optional
locationToProcess No
Returns : any
getSelectionStrategy
getSelectionStrategy()
Returns : void
getState
getState()
Returns : void
getTelemetryData
getTelemetryData(changeType)
Parameters :
Name Optional
changeType No
Returns : { locationIntractEdata: { id: string; type: string; subtype: any; }; telemetryCdata: {}; }
initializeFormFields
initializeFormFields()
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
onStateChange
onStateChange()
Returns : void
processDistrictLocation
processDistrictLocation(district, stateData)
Parameters :
Name Optional
district No
stateData No
Returns : any
processStateLocation
processStateLocation(state)
Parameters :
Name Optional
state No
Returns : any
setData
setData(location)
Parameters :
Name Optional
location No
Returns : void
setDistrict
setDistrict(district)
Parameters :
Name Optional
district No
Returns : void
setSelectedLocation
setSelectedLocation(location, updateUserProFile, updateDeviceProfile)
Parameters :
Name Optional
location No
updateUserProFile No
updateDeviceProfile No
Returns : void
setState
setState(state)
Parameters :
Name Optional
state No
Returns : void
setStateDistrict
setStateDistrict(location)
Parameters :
Name Optional
location No
Returns : void
telemetryLogEvents
telemetryLogEvents(locationType: any, status: boolean)
Parameters :
Name Type Optional
locationType any No
status boolean No
Returns : void
updateDeviceProfileData
updateDeviceProfileData(data, locationDetails)
Parameters :
Name Optional
data No
locationDetails No
Returns : any
updateLocation
updateLocation(data, locationDetails)
Parameters :
Name Optional
data No
locationDetails No
Returns : void
updateUserLocation
updateUserLocation()
Returns : void
updateUserProfileData
updateUserProfileData(data)
Parameters :
Name Optional
data No
Returns : any

Properties

allDistricts
Type : any
allStates
Type : any
Public deviceRegisterService
Type : DeviceRegisterService
districtDiv
Decorators :
@ViewChild('districtDiv')
enableSubmitBtn
Default value : false
isDeviceProfileUpdateAllowed
Default value : false
isUserProfileUpdateAllowed
Default value : false
Public navigationhelperService
Type : NavigationHelperService
Public popupControlService
Type : PopupControlService
Public processedDeviceLocation
Type : any
Default value : {}
Public profileService
Type : ProfileService
Public resourceService
Type : ResourceService
Public router
Type : Router
sbFormBuilder
Type : UntypedFormBuilder
selectedDistrict
selectedState
showDistrictDivLoader
Default value : false
stateDiv
Decorators :
@ViewChild('stateDiv')
Private suggestedLocation
Public suggestionType
Type : any
telemetryImpression
Type : IImpressionEventInput
Public toasterService
Type : ToasterService
userDetailsForm
Type : UntypedFormGroup
userLocationModal
Decorators :
@ViewChild('userLocationModal')
Public userService
Type : UserService
import {Component, EventEmitter, Input, OnInit, Output, ViewChild, OnDestroy, AfterViewInit} from '@angular/core';
import {ResourceService, ToasterService, NavigationHelperService} from '@sunbird/shared';
import {UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators} from '@angular/forms';
import {DeviceRegisterService, UserService} from '@sunbird/core';
import {ActivatedRoute, Router} from '@angular/router';
import {ProfileService} from '@sunbird/profile';
import * as _ from 'lodash-es';
import {IImpressionEventInput, IInteractEventInput, TelemetryService} from '@sunbird/telemetry';
import {map} from 'rxjs/operators';
import {forkJoin, of} from 'rxjs';
import { PopupControlService } from '../../../../service/popup-control.service';

@Component({
  selector: 'app-user-location',
  templateUrl: './user-location.component.html',
  styleUrls: ['./user-location.component.scss']
})
export class UserLocationComponent implements OnInit, OnDestroy, AfterViewInit {

  @Output() close = new EventEmitter<any>();
  @Input() userLocationDetails: any;
  @Input() deviceProfile: any;
  @Input() isCustodianOrgUser: any;
  @Input() userProfile: any;
  @ViewChild('userLocationModal') userLocationModal;
  @ViewChild('stateDiv') stateDiv;
  @ViewChild('districtDiv') districtDiv;
  userDetailsForm: UntypedFormGroup;
  public processedDeviceLocation: any = {};
  selectedState;
  selectedDistrict;
  allStates: any;
  allDistricts: any;
  showDistrictDivLoader = false;
  sbFormBuilder: UntypedFormBuilder;
  enableSubmitBtn = false;
  isDeviceProfileUpdateAllowed = false;
  isUserProfileUpdateAllowed = false;
  telemetryImpression: IImpressionEventInput;
  public suggestionType: any;
  private suggestedLocation;

  constructor(public resourceService: ResourceService, public toasterService: ToasterService,
              formBuilder: UntypedFormBuilder, public profileService: ProfileService, private activatedRoute: ActivatedRoute,
              public router: Router, public userService: UserService, public deviceRegisterService: DeviceRegisterService,
              public navigationhelperService: NavigationHelperService, private telemetryService: TelemetryService,
              public popupControlService: PopupControlService) {
    this.sbFormBuilder = formBuilder;
  }

  ngOnInit() {
    this.popupControlService.changePopupStatus(false);
    this.initializeFormFields();
    this.getState();
  }

  ngAfterViewInit () {
    setTimeout(() => {
      this.telemetryImpression = {
        context: {
          env: 'user-location',
          cdata: [{id: 'user:state:districtConfimation', type: 'Feature'},
            {id: 'SC-1373', type: 'Task'}
          ]
        },
        edata: {
          type: 'view',
          pageid: 'location-popup',
          uri: this.router.url,
          duration: this.navigationhelperService.getPageLoadTime()
        }
      };
    });
  }

  initializeFormFields() {
    this.userDetailsForm = this.sbFormBuilder.group({
      state: new UntypedFormControl(null, [Validators.required]),
      district: new UntypedFormControl(null, [Validators.required])
    });
    this.enableSubmitBtn = (this.userDetailsForm.status === 'VALID');
    this.enableSubmitButton();
  }

  enableSubmitButton() {
    this.userDetailsForm.valueChanges.subscribe(val => {
      this.enableSubmitBtn = (this.userDetailsForm.status === 'VALID');
    });
  }

  processStateLocation(state) {
    let locationExist: any = {};
    if (state) {
      locationExist = _.find(this.allStates, (locations) => {
        return locations.name.toLowerCase() === state.toLowerCase() && locations.type === 'state';
      });
    }
    return locationExist;
  }

  processDistrictLocation(district, stateData) {
    const requestData = {'filters': {'type': 'district', parentId: stateData && stateData.id || ''}};
    return this.profileService.getUserLocation(requestData).pipe(map((res: any) => {
      this.allDistricts = res.result.response;
      let locationExist: any = {};
      if (district) {
        locationExist = _.find(this.allDistricts, (locations) => {
          return locations.name.toLowerCase() === district.toLowerCase() && locations.type === 'district';
        });
      }
      return locationExist;
    }, err => {
      this.closeModal();
      this.toasterService.error(this.resourceService.messages.emsg.m0017);
    }));
  }

  setState(state) {
    let locationExist: any;
    if (state) {
      locationExist = _.find(this.allStates, (locations) => {
        return locations.code === state.code && locations.type === 'state';
      });
    }
    this.selectedState = locationExist;
    locationExist ? this.userDetailsForm.controls['state'].setValue(locationExist.code) :
      this.userDetailsForm.controls['state'].setValue('');
  }

  setDistrict(district) {
    let locationExist: any;
    if (district) {
      locationExist = _.find(this.allDistricts, (locations) => {
        return locations.code === district.code && locations.type === 'district';
      });
    }
    this.selectedDistrict = locationExist;
    locationExist ? this.userDetailsForm.controls['district'].setValue(locationExist.code) :
      this.userDetailsForm.controls['district'].setValue('');
  }

  getSelectionStrategy() {
    if (this.userService.loggedIn) {
      const userProfileData = this.userService.userProfile;
      const isUserLocationConfirmed = userProfileData && userProfileData.userLocations &&
        Array.isArray(userProfileData.userLocations) && userProfileData.userLocations.length >= 1;

      if (!isUserLocationConfirmed && this.deviceProfile.userDeclaredLocation) {
        // render using userDeclaredLocation
        // update user profile only
        this.suggestionType = 'userDeclared';
        this.setSelectedLocation(this.deviceProfile.userDeclaredLocation, true, false);
      }
      if (!(this.deviceProfile && this.deviceProfile.userDeclaredLocation)) {
        if (isUserLocationConfirmed) {
          const userLocation = {
            district: _.find(userProfileData.userLocations, (location) => {
              return location.type === 'district';
            }),
            state: _.find(userProfileData.userLocations, (location) => {
              return location.type === 'state';
            })
          };
          this.isUserProfileUpdateAllowed = false;
          this.isDeviceProfileUpdateAllowed = true;
          this.setData(userLocation);
          // render using user location
          // update only device profile
          this.suggestionType = 'userLocation';
        } else if (!isUserLocationConfirmed) {
          this.setSelectedLocation(this.deviceProfile.ipLocation, true, true);
          // render using ip
          // update device location and user location
          this.suggestionType = 'ipLocation';
        }
      }
    } else {
      if (!(this.deviceProfile && this.deviceProfile.userDeclaredLocation)) {
        this.setSelectedLocation(this.deviceProfile.ipLocation, false, true);
        // render using ip
        // update device profile only
        this.suggestionType = 'ipLocation';
      }
    }
  }

  setSelectedLocation(location, updateUserProFile, updateDeviceProfile) {
    location = location ? location : {'state': '', 'district': ''};
    const mappedStateDetails = this.processStateLocation(location.state);
    this.getLocationCodes(location).subscribe((mappedDistrictDetails) => {
      this.processedDeviceLocation = {
        district: mappedDistrictDetails,
        state: mappedStateDetails
      };
      this.setStateDistrict(this.processedDeviceLocation);
      this.isUserProfileUpdateAllowed = updateUserProFile;
      this.isDeviceProfileUpdateAllowed = updateDeviceProfile;
    });
  }

  setData(location) {
    this.getDistrict(location.state.id).subscribe((districts) => {
      this.setStateDistrict(location);
    });
  }

  setStateDistrict(location) {
    if (location) {
      this.suggestedLocation = location;
      if (location.state) {
        this.setState(location.state);
      }
      if (location.district) {
        this.setDistrict(location.district);
      }
    }
    this.onStateChange();
  }

  getLocationCodes(locationToProcess) {
    const mappedStateDetails = this.processStateLocation(locationToProcess.state);
    return this.processDistrictLocation(locationToProcess.district, mappedStateDetails);
  }

  getState() {
    const requestData = {'filters': {'type': 'state'}};
    this.profileService.getUserLocation(requestData).subscribe((res) => {
      this.allStates = res.result.response;
      this.getSelectionStrategy();
    }, err => {
      this.closeModal();
      this.toasterService.error(this.resourceService.messages.emsg.m0016);
    });
  }

  onStateChange() {
    const stateControl = this.userDetailsForm.get('state');
    let stateValue = '';
    stateControl.valueChanges.subscribe(
      (data: string) => {
        if (stateControl.status === 'VALID' && stateValue !== stateControl.value) {
          this.allDistricts = null;
          this.userDetailsForm.get('district').reset();
          const state = _.find(this.allStates, (states) => {
            return states.code === stateControl.value;
          });
          this.showDistrictDivLoader = true;
          this.getDistrict(state.id).subscribe((districts) => {
            stateValue = stateControl.value;
          });
        }
      });
  }

  getDistrict(stateId) {
    const requestData = {'filters': {'type': 'district', parentId: stateId}};
    return this.profileService.getUserLocation(requestData).pipe(map((res: any) => {
      this.showDistrictDivLoader = false;
      this.allDistricts = res.result.response;
      return res.result.response;
    }));
  }

  closeModal() {
    this.popupControlService.changePopupStatus(true);
    this.userLocationModal.deny();
    this.close.emit();
  }

  updateUserLocation() {
    const locationCodes = [];
    const locationDetails: any = {};
    if (this.userDetailsForm.value.state) {
      locationCodes.push(this.userDetailsForm.value.state);
      locationDetails.stateCode = this.userDetailsForm.value.state;
    }
    if (this.userDetailsForm.value.district) {
      locationCodes.push(this.userDetailsForm.value.district);
      locationDetails.districtCode = this.userDetailsForm.value.district;
    }
    const data = {profileLocation: locationCodes};
    let districtData, stateData, changeType = '';
    if (locationDetails.stateCode) {
      stateData = _.find(this.allStates, (states) => {
        return states.code === locationDetails.stateCode;
      });
    }
    if (locationDetails.districtCode) {
      districtData = _.find(this.allDistricts, (districts) => {
        return districts.code === locationDetails.districtCode;
      });
    }
    if (stateData.name !== _.get(this.suggestedLocation, 'state.name')) {
      changeType = changeType + 'state-changed';
    }
    if (districtData.name !== _.get(this.suggestedLocation, 'district.name')) {
      if (_.includes(changeType, 'state-changed')) {
        changeType = 'state-dist-changed';
      } else {
        changeType = changeType + 'dist-changed';
      }
    }
    const telemetryData = this.getTelemetryData(changeType);
    this.generateInteractEvent(telemetryData);
    this.updateLocation(data, {state: stateData, district: districtData});
  }

  getTelemetryData(changeType) {
    return {
      locationIntractEdata: {
        id: 'submit-clicked',
        type: changeType ? 'location-changed' : 'location-unchanged',
        subtype: changeType
      },
      telemetryCdata: [
        {id: 'user:state:districtConfimation', type: 'Feature'},
        {id: 'SC-1373', type: 'Task'}
      ]
    };
  }

  private generateInteractEvent(telemetryData) {
    const intractEdata = telemetryData.locationIntractEdata;
    const telemetryInteractCdata = telemetryData.telemetryCdata;
    if (intractEdata) {
      const appTelemetryInteractData: IInteractEventInput = {
        context: {
          env: 'user-location',
          cdata: [
            {id: 'user:state:districtConfimation', type: 'Feature'},
            {id: 'SC-1373', type: 'Task'}
          ],
        },
        edata: intractEdata
      };
      if (telemetryInteractCdata) {
        appTelemetryInteractData.object = telemetryInteractCdata;
      }
      this.telemetryService.interact(appTelemetryInteractData);
    }
  }

  updateLocation(data, locationDetails) {
    this.enableSubmitBtn = false;
    let response1: any;
    response1 = this.updateDeviceProfileData(data, locationDetails);
    const response2 = this.updateUserProfileData(data);
    forkJoin([response1, response2]).subscribe((res) => {
      if (!_.isEmpty(res[0])) {
        this.telemetryLogEvents('Device Profile', true);
      }
      if (!_.isEmpty(res[1])) {
        this.telemetryLogEvents('User Profile', true);
      }
      this.closeModal();
    }, (err) => {
      if (!_.isEmpty(err[0])) {
        this.telemetryLogEvents('Device Profile', false);
      }
      if (!_.isEmpty(err[1])) {
        this.telemetryLogEvents('User Profile', false);
      }
      this.closeModal();
    });
  }

  updateDeviceProfileData(data, locationDetails) {
    if (!this.isDeviceProfileUpdateAllowed) {
      return of({});
    }
    return this.deviceRegisterService.updateDeviceProfile({
      state: _.get(locationDetails, 'state.name'),
      district: _.get(locationDetails, 'district.name')
    });
  }

  updateUserProfileData(data) {
    if (!this.isUserProfileUpdateAllowed || !this.isCustodianOrgUser) {
      return of({});
    }
    return this.profileService.updateProfile(data);
  }

  telemetryLogEvents(locationType: any, status: boolean) {
    let level = 'ERROR';
    let msg = 'Updation of ' + locationType + ' failed';
    if (status) {
      level = 'SUCCESS';
      msg = 'Updation of ' + locationType + ' success';
    }
    const event = {
      context: {
        env: 'portal'
      },
      edata: {
        type: 'update-location',
        level: level,
        message: msg
      }
    };
    this.telemetryService.log(event);
  }

  ngOnDestroy(): void {
    this.popupControlService.changePopupStatus(true);
  }

}
<app-modal-wrapper [config]="{disableClose: true, size: 'normal'}" (dismiss)="closeModal();"
  [appTelemetryImpression]="telemetryImpression" #userLocationModal>
  <ng-template sbModalContent>
    <div class="sb-modal">
      <div class="transition ui dimmer page modals active visible">
        <div class="ui modal transition active visible normal">
          <!--Header-->
          <div class="sb-modal-header">
            Your Location
          </div>
          <!--/Header-->

          <!--Content-->
          <div class="sb-modal-content o-y-visible" [appTelemetryImpression]="telemetryImpression">
            <form class="sb-form" [formGroup]="userDetailsForm">
              <p class="mb-8">{{resourceService?.messages?.imsg?.m0074}}</p>
              <div class="sb-field">
                <label>{{resourceService?.frmelmnts?.lbl?.state}}:</label>
                <sui-select class="selection" formControlName="state" [options]="allStates" labelField="name"
                  id="states" valueField="code" name="state"
                  placeholder="{{resourceService?.frmelmnts?.lbl?.selectState}}" #stateDiv>
                  <sui-select-option *ngFor="let state of stateDiv.filteredOptions | slice:0:100" [value]="state">
                  </sui-select-option>
                </sui-select>
              </div>
              <div class="sb-fielgroup">
                <label>{{resourceService?.frmelmnts?.lbl?.district}}:</label>
                <div class="sb-field">
                  <div class="ui segment" *ngIf="showDistrictDivLoader">
                    <div class="ui active inverted dimmer">
                      <div class="ui mini text loader">{{resourceService?.messages?.stmsg?.m0130}}</div>
                    </div>
                  </div>
                  <sui-select *ngIf="!showDistrictDivLoader" class="selection" formControlName="district"
                    [options]="allDistricts" id="districts" labelField="name" valueField="code" name="district"
                    placeholder="{{resourceService?.frmelmnts?.lbl?.selectDistrict}}" #districtDiv>
                    <sui-select-option *ngFor="let district of districtDiv.filteredOptions | slice:0:100"
                      [value]="district"></sui-select-option>
                  </sui-select>
                </div>
              </div>
            </form>
          </div>
          <!--/Content-->

          <!--Actions-->
          <div class="sb-modal-actions">
            <button class="sb-btn sb-btn-normal sb-btn-primary" [ngClass]="{'sb-btn-disabled': !enableSubmitBtn}"
              [disabled]="!enableSubmitBtn" tabindex="0" (click)="updateUserLocation()">
              {{resourceService?.frmelmnts?.btn?.submit}}
            </button>
          </div>
          <!--/Actions-->

        </div>
      </div>
    </div>
  </ng-template>
</app-modal-wrapper>

./user-location.component.scss

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""