src/app/modules/shared-feature/components/global-consent-pii/global-consent-pii.component.ts
OnInit
selector | app-global-consent-pii |
styleUrls | ./global-consent-pii.component.scss |
templateUrl | ./global-consent-pii.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
constructor(csUserService: CsUserService, toasterService: ToasterService, userService: UserService, resourceService: ResourceService, tncService: TncService, utilService: UtilService, popupControlService: PopupControlService, activatedRoute: ActivatedRoute, coursesService: CoursesService, router: Router, generaliseLabelService: GeneraliseLabelService)
|
||||||||||||||||||||||||||||||||||||
Parameters :
|
collection | |
Type : any
|
|
consentConfig | |
Type : any
|
|
isglobalConsent | |
Type : any
|
|
profileInfo | |
Type : any
|
|
showConsentPopup | |
Type : any
|
|
type | |
Type : any
|
|
close | |
Type : EventEmitter
|
|
consentShare | |
Type : EventEmitter
|
|
checkQueryParams |
checkQueryParams()
|
Returns :
void
|
fetchTncData |
fetchTncData()
|
Returns :
void
|
getDeclarationReqObject | ||||
getDeclarationReqObject(usersProfile)
|
||||
Parameters :
Returns :
{ operation: string; userId: any; orgId: any; info: any; }
|
getUserConsent |
getUserConsent()
|
Returns :
void
|
getUserInformation |
getUserInformation()
|
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
removeQueryParam |
removeQueryParam()
|
Returns :
void
|
saveConsent |
saveConsent()
|
Returns :
void
|
showAndHidePopup | ||||||
showAndHidePopup(mode: boolean)
|
||||||
Parameters :
Returns :
void
|
toggleEditSetting |
toggleEditSetting()
|
Returns :
void
|
updateUserConsent | ||||||
updateUserConsent(isActive: boolean)
|
||||||
Parameters :
Returns :
void
|
updateUserDeclaration | ||||
updateUserDeclaration(request)
|
||||
Parameters :
Returns :
void
|
consentPii |
Type : string
|
Default value : 'Yes'
|
editSetting |
Default value : false
|
Public generaliseLabelService |
Type : GeneraliseLabelService
|
instance |
Type : string
|
isDataShareOn |
Default value : false
|
isOpen |
Default value : false
|
isTncAgreed |
Default value : false
|
lastUpdatedOn |
Type : string
|
Default value : ''
|
Public popupControlService |
Type : PopupControlService
|
profileDetailsModal |
Decorators :
@ViewChild('profileDetailsModal')
|
Public resourceService |
Type : ResourceService
|
showSettingsPage |
Type : boolean
|
showTncPopup |
Default value : false
|
termsAndConditionLink |
Type : string
|
Public tncService |
Type : TncService
|
unsubscribe |
Default value : new Subject<void>()
|
userInformation |
Type : []
|
Default value : []
|
Public userService |
Type : UserService
|
Private usersProfile |
Type : any
|
Public utilService |
Type : UtilService
|
import { Component, Inject, Input, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
import { Consent, ConsentStatus } from '@project-sunbird/client-services/models';
import { CsUserService } from '@project-sunbird/client-services/services/user/interface';
import { TncService, UserService, CoursesService, GeneraliseLabelService } from '@sunbird/core';
import { ResourceService, ServerResponse, ToasterService, UtilService } from '@sunbird/shared';
import * as _ from 'lodash-es';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { PopupControlService } from '../../../../service/popup-control.service';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'app-global-consent-pii',
templateUrl: './global-consent-pii.component.html',
styleUrls: ['./global-consent-pii.component.scss']
})
export class GlobalConsentPiiComponent implements OnInit {
@Input() collection;
@Input() type;
@Input() showConsentPopup;
@Input() consentConfig;
@Input() isglobalConsent;
@Input() profileInfo;
@ViewChild('profileDetailsModal') profileDetailsModal;
@Output() close = new EventEmitter<any>();
@Output() consentShare = new EventEmitter<any>();
isOpen = false;
instance: string;
consentPii = 'Yes';
isDataShareOn = false;
lastUpdatedOn = '';
userInformation = [];
editSetting = false;
isTncAgreed = false;
// showConsentPopup = false;
showTncPopup = false;
termsAndConditionLink: string;
unsubscribe = new Subject<void>();
private usersProfile: any;
showSettingsPage: boolean;
constructor(
@Inject('CS_USER_SERVICE') private csUserService: CsUserService,
private toasterService: ToasterService,
public userService: UserService,
public resourceService: ResourceService,
public tncService: TncService,
public utilService: UtilService,
public popupControlService: PopupControlService,
private activatedRoute: ActivatedRoute,
private coursesService: CoursesService,
private router: Router,
public generaliseLabelService: GeneraliseLabelService
) {
this.instance = (<HTMLInputElement>document.getElementById('instance'))
? (<HTMLInputElement>document.getElementById('instance')).value.toUpperCase() : 'SUNBIRD';
}
ngOnInit() {
this.usersProfile = _.cloneDeep(this.userService.userProfile);
this.getUserInformation();
this.getUserConsent();
if (this.isglobalConsent || this.type === 'program-consent') {
this.showSettingsPage = false;
} else {
this.showSettingsPage = true;
}
this.checkQueryParams();
this.coursesService.revokeConsent
.pipe(takeUntil(this.unsubscribe))
.subscribe((res) => {
this.updateUserConsent(false);
});
}
checkQueryParams() {
this.activatedRoute.queryParams
.pipe(takeUntil(this.unsubscribe))
.subscribe(response => {
if (response.consent) {
if (this.type === 'course-consent' || this.type === 'global-consent') {
this.showConsentPopup = true;
}
this.removeQueryParam();
}
});
}
getUserInformation() {
this.userInformation['name'] = this.usersProfile.lastName ?
`${this.usersProfile.firstName} ${this.usersProfile.lastName}` : this.usersProfile.firstName;
this.userInformation['userid'] = this.usersProfile.userId;
this.userInformation['emailId'] = this.usersProfile.email;
this.userInformation['phone'] = this.usersProfile.phone;
if (this.usersProfile && this.usersProfile.externalIds) {
_.forEach(this.usersProfile.externalIds, (externaleId) => {
if (externaleId.provider === this.usersProfile.channel) {
this.userInformation['externalId'] = externaleId.id;
}
});
}
if (_.get(this.usersProfile, 'userLocations.length')) {
this.usersProfile.userLocations.forEach(locDetail => {
switch (locDetail.type) {
case 'state':
this.userInformation['state'] = locDetail.name;
break;
case 'district':
this.userInformation['district'] = locDetail.name;
break;
case 'block':
this.userInformation['block'] = locDetail.name;
break;
case 'school':
this.userInformation['schoolName'] = locDetail.name;
this.userInformation['schoolId'] = locDetail.code;
break;
}
});
}
if (_.get(this.usersProfile, 'declarations.length')) {
for (const [key, value] of Object.entries(this.usersProfile.declarations[0].info)) {
switch (key) {
case 'declared-email':
this.userInformation['emailId'] = value;
break;
case 'declared-phone':
this.userInformation['phone'] = value;
break;
case 'declared-school-udise-code':
this.userInformation['schoolId'] = this.userInformation['schoolId'] || value;
break;
case 'declared-school-name':
this.userInformation['schoolName'] = this.userInformation['schoolName'] || value;
break;
}
}
}
if (this.profileInfo) {
this.userInformation = _.assign(this.userInformation, this.profileInfo);
}
}
fetchTncData() {
this.tncService.getTncConfig().pipe(takeUntil(this.unsubscribe)).subscribe((data: ServerResponse) => {
const response = _.get(data, 'result.response.value');
if (response) {
try {
const tncConfig = this.utilService.parseJson(response);
const version = _.get(tncConfig, 'latestVersion') || {};
this.termsAndConditionLink = tncConfig[version].url;
} catch (e) {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
}
}
}, () => {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
}
);
}
saveConsent() {
const isActive = _.upperCase(this.consentPii) === 'YES';
if (isActive) {
this.showConsentPopup = true;
} else {
this.updateUserConsent(isActive);
}
this.toggleEditSetting();
}
toggleEditSetting() {
this.editSetting = !this.editSetting;
}
showAndHidePopup(mode: boolean) {
this.showTncPopup = mode;
this.popupControlService.changePopupStatus(true);
}
getUserConsent() {
const request = {
userId: this.userService.userid,
consumerId: '',
objectId: ''
};
if (this.type === 'course-consent') {
request.consumerId = this.collection ? this.collection.channel : '';
request.objectId = this.collection ? this.collection.identifier : '';
} else if ( this.type === 'global-consent') {
request.consumerId = this.userService.channel;
request.objectId = this.userService.channel;
const declReq = [];
if (this.getDeclarationReqObject(this.usersProfile)) {
declReq.push(this.getDeclarationReqObject(this.usersProfile));
this.updateUserDeclaration(declReq);
}
} else if(this.type === 'program-consent'){
request.consumerId = this.collection.rootOrganisations;
request.objectId = this.collection.programId
}
this.csUserService.getConsent(request, { apiPath: '/learner/user/v1' })
.pipe(takeUntil(this.unsubscribe))
.subscribe(res => {
if (this.type === 'global-consent') {
this.showConsentPopup = false;
this.type = '';
this.isglobalConsent = false;
}
this.isDataShareOn = _.get(res, 'consents[0].status') === ConsentStatus.ACTIVE;
this.consentPii = this.isDataShareOn ? 'No' : 'Yes';
this.lastUpdatedOn = _.get(res, 'consents[0].lastUpdatedOn') || '';
}, error => {
console.error('error', error);
if (error.code === 'HTTP_CLIENT_ERROR' && _.get(error, 'response.responseCode') === 404) {
this.showConsentPopup = true;
} else {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
}
});
}
updateUserConsent(isActive: boolean) {
this.showConsentPopup = false;
const request: Consent = {
status: isActive ? ConsentStatus.ACTIVE : ConsentStatus.REVOKED,
userId: this.userService.userid,
consumerId: '',
objectId: '',
objectType: ''
};
if (this.type === 'course-consent') {
request.consumerId = this.collection ? this.collection.channel : '';
request.objectId = this.collection ? this.collection.identifier : '';
request.objectType = 'Collection';
} else if ( this.type === 'global-consent') {
request.consumerId = this.userService.channel;
request.objectId = this.userService.channel;
request.objectType = 'Organisation';
} else if(this.type === 'program-consent'){
request.consumerId = this.collection.rootOrganisations;
request.objectId = this.collection.programId;
request.objectType = 'Program'
}
this.csUserService.updateConsent(request, { apiPath: '/learner/user/v1' })
.pipe(takeUntil(this.unsubscribe))
.subscribe(() => {
if(this.type === 'program-consent'){
this.consentShare.emit({consent:true})
}
this.type !== 'program-consent' && this.toasterService.success(_.get(this.resourceService, 'messages.smsg.dataSettingSubmitted'));
this.getUserConsent();
this.close.emit();
this.popupControlService.changePopupStatus(true);
}, error => {
this.isTncAgreed = false;
this.toasterService.error(_.get(this.resourceService, 'messages.emsg.m0005'));
console.error('Error while updating user consent', error);
if(this.type === 'program-consent'){
this.consentShare.emit({consent:false})
}
});
}
removeQueryParam() {
this.router.navigate([], {
queryParams: { 'consent': null },
queryParamsHandling: 'merge',
replaceUrl: true
});
}
updateUserDeclaration(request) {
this.csUserService.updateUserDeclarations(request, { apiPath: '/learner/user/v1' })
.pipe(takeUntil(this.unsubscribe))
.subscribe(() => {
this.toasterService.success(_.get(this.resourceService, 'messages.smsg.m0037'));
}, err => {
this.toasterService.error(this.resourceService.messages.emsg.m0052);
});
}
getDeclarationReqObject(usersProfile) {
let userExternalId = null;
if (usersProfile && usersProfile.externalIds) {
_.forEach(usersProfile.externalIds, (externaleId) => {
if (externaleId.provider === usersProfile.channel) {
userExternalId = externaleId.id;
}
});
}
const info: any = {
'declared-ext-id': userExternalId,
'declared-phone': '',
'declared-email': ''
};
const declarationObj = {
operation: 'add',
userId : usersProfile.userId,
orgId: usersProfile.rootOrgId,
info: info
};
if (userExternalId) {
return declarationObj;
} else {
return null;
}
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
if (_.get(this.profileDetailsModal, 'deny')) {
this.profileDetailsModal.deny();
}
}
}
<mat-accordion class="sb-mat-accordion mb-16" *ngIf="showSettingsPage">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title class="sb-mat-accordion__title">
{{resourceService?.frmelmnts?.lbl?.dataSetting}}
</mat-panel-title>
</mat-expansion-panel-header>
<div class="sb-mat-accordion__content" role="region" id="dataSetting"
aria-labelledby="dataSetting">
<label class="fnormal font-weight-normal text-uppercase">{{resourceService?.frmelmnts?.lbl?.dataSharingIs}}
<span>{{ isDataShareOn ? resourceService?.frmelmnts?.lbl?.on : resourceService?.frmelmnts?.lbl?.off }}</span>
</label>
<p class="fsmall mb-0" *ngIf="isDataShareOn">{{resourceService?.frmelmnts?.lbl?.dataShareOnNote}}</p>
<p class="fsmall mb-0" *ngIf="!isDataShareOn">{{resourceService?.frmelmnts?.lbl?.dataShareOffNote}}</p>
<label class="fsmall font-weight-normal data-labels"
*ngIf="lastUpdatedOn">{{resourceService?.frmelmnts?.lbl?.lastUpdatedOn}} {{lastUpdatedOn | date
:'dd/MM/yyyy'}}</label>
<div class="d-flex flex-ai-end flex-jc-flex-end">
<button class="sb-btn sb-btn-normal sb-btn-link sb-btn-link-primary font-weight-bold"
(click)="toggleEditSetting()" tabindex="0">
{{ editSetting ? resourceService?.frmelmnts?.btn?.close : resourceService?.frmelmnts?.lbl?.editSetting }}
</button>
</div>
<div *ngIf="editSetting" class="sb-update-data-settings">
<hr>
<label
class="fsmall mb-0 font-weight-bold data-labels">{{resourceService?.frmelmnts?.lbl?.updateSetting}}</label>
<div class="d-flex py-8 flex-w-wrap">
<div class="sb-radio-btn-checkbox sb-radio-btn-primary">
<input [value]="'Yes'" id="shareConsent" type="radio" [(ngModel)]="consentPii">
<label for="shareConsent" class="fsmall">{{resourceService?.frmelmnts?.lbl?.shareProfileDetails}}</label>
</div>
<div class="sb-radio-btn-checkbox sb-radio-btn-primary">
<input [value]="'No'" id="noShareContent" type="radio" [(ngModel)]="consentPii">
<label for="noShareContent"
class="fsmall">{{resourceService?.frmelmnts?.lbl?.notShareProfileDetails}}</label>
</div>
</div>
<button class="sb-btn sb-btn-normal sb-btn-outline-primary w-100 text-uppercase" tabindex="0"
(click)="saveConsent()">{{resourceService?.frmelmnts?.btn?.save}}</button>
</div>
</div>
</mat-expansion-panel>
</mat-accordion>
<app-modal-wrapper *ngIf="showConsentPopup" [config]="{disableClose: true, size: 'normal', panelClass: ['overflow-visible', 'material-modal']}"
(dismiss)="showConsentPopup = false;" #profileDetailsModal>
<ng-template sbModalContent>
<div class="sb-mat__modal">
<!--Header-->
<div mat-dialog-title class="mb-0 px-16">
<div class="title">{{resourceService?.frmelmnts?.lbl?.consentsharedetail}}</div>
</div>
<!--/Header-->
<!--Content-->
<div class="sb-mat__modal__content d-flex flex-dc o-y-visible lineHeight-normal">
<div class="profile-fields">
<div class="d-flex mb-16 fnormal">
<label
class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.dashboardsortbyusername}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.name || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.state}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.state || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.userId}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.userid || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.externalId}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.externalId || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.district}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.district || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.block}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.block || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.schoolId}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.schoolId || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.schoolName}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.schoolName || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label
class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.mobileNumber}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.phone || '-'}}</div>
</div>
<div class="d-flex mb-16 fnormal">
<label class="font-weight-bold profile-field-label">{{resourceService?.frmelmnts?.lbl?.emailId}}<span
class="mx-8">:</span></label>
<div class="font-weight-normal">{{userInformation.emailId || '-'}}</div>
</div>
</div>
<div class="mb-16 fnormal font-weight-normal" *ngIf="type === 'course-consent' || type === 'program-consent'">
<img src="../../../../../../assets/images/info-icon.svg" width="14px" height="14px" class="mr-8"
alt="info">{{resourceService?.frmelmnts?.lbl?.canEditProfileDetails}}
</div>
<p class="mb-0fnormal font-weight-normal">
<input type="checkbox" [(ngModel)]="isTncAgreed" class="mr-8" aria-label="term and condition checkbox">
{{consentConfig.tncText | interpolate:'{instance}': instance}}
<a class="sb-color-primary" href="javascript:void(0)" tabindex="0"
(click)="showTncPopup=true">{{consentConfig.tncLink | interpolate:'{instance}':
resourceService?.instance}}</a>
</p>
</div>
<!--/Content-->
<!--Actions-->
<div class="sb-mat__modal__actions">
<button class="sb-btn sb-btn-normal sb-btn-outline-primary text-uppercase" tabindex="0"
(click)="updateUserConsent(false)"
*ngIf="type === 'course-consent' || type === 'program-consent'">{{resourceService?.frmelmnts?.lbl?.dontShare}}</button>
<button type="button" tabindex="0" [ngClass]="{'sb-btn-disabled': !isTncAgreed}" [disabled]="!isTncAgreed"
class="sb-btn sb-btn-normal sb-btn-primary text-uppercase ml-8" (click)="updateUserConsent(true)"
*ngIf="type === 'global-consent'">{{resourceService?.frmelmnts?.lbl?.continue}}</button>
<button type="button" tabindex="0" [ngClass]="{'sb-btn-disabled': !isTncAgreed}" [disabled]="!isTncAgreed"
class="sb-btn sb-btn-normal sb-btn-primary text-uppercase ml-8" (click)="updateUserConsent(true)"
*ngIf="type === 'course-consent' || type === 'program-consent'">{{resourceService?.frmelmnts?.lbl?.share}}</button>
</div>
<!--/Actions-->
</div>
</ng-template>
</app-modal-wrapper>
<app-tnc-popup (close)="showAndHidePopup(false)" [tncUrl]="termsAndConditionLink" *ngIf="showTncPopup">
</app-tnc-popup>
./global-consent-pii.component.scss
@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
.sb-modal-profile-details {
input[type="checkbox"] {
width: calculateRem(16px);
height: calculateRem(16px);
position: relative;
top: calculateRem(2px);
}
}
.profile-fields{
word-break: break-all;
.profile-field-label{
width: calculateRem(150px);
@media screen and (max-width:768px) {
width: auto;
}
}
}