src/app/my-groups/add-member-to-group/add-member-to-group.page.ts
selector | app-add-member-to-group |
styleUrls | ./add-member-to-group.page.scss |
templateUrl | ./add-member-to-group.page.html |
Properties |
Methods |
constructor(profileService: ProfileService, groupService: GroupService, systemSettingsService: SystemSettingsService, preferences: SharedPreferences, headerService: AppHeaderService, router: Router, location: Location, platform: Platform, commonUtilService: CommonUtilService, popoverCtrl: PopoverController, telemetryGeneratorService: TelemetryGeneratorService, sbUtility: UtilityService)
|
|||||||||||||||||||||||||||||||||||||||
Parameters :
|
Async getGoogleCaptchaSiteKey |
getGoogleCaptchaSiteKey()
|
Returns :
Promise<literal type>
|
handleBackButton | ||||
handleBackButton(isNavBack)
|
||||
Parameters :
Returns :
void
|
handleDeviceBackButton |
handleDeviceBackButton()
|
Returns :
void
|
handleHeaderEvents | ||||
handleHeaderEvents($event)
|
||||
Parameters :
Returns :
void
|
Async ionViewDidEnter |
ionViewDidEnter()
|
Returns :
any
|
ionViewWillEnter |
ionViewWillEnter()
|
Returns :
void
|
ionViewWillLeave |
ionViewWillLeave()
|
Returns :
void
|
Async onAddToGroupClick |
onAddToGroupClick()
|
Returns :
any
|
onClearUser |
onClearUser()
|
Returns :
void
|
Async onVerifyClick |
onVerifyClick()
|
Returns :
any
|
Async openInfoPopup | ||||||
openInfoPopup(event: MouseEvent)
|
||||||
Parameters :
Returns :
any
|
addMemberInfoPopupRef |
Type : ElementRef<HTMLSpanElement>
|
Decorators :
@ViewChild('addMemberInfoPopupRef', {static: false})
|
appName |
Type : string
|
cap |
Type : RecaptchaComponent
|
Decorators :
@ViewChild('cap', {static: false})
|
corRelationList |
Type : Array<CorrelationData>
|
groupId |
Type : string
|
Public groupService |
Type : GroupService
|
Decorators :
@Inject('GROUP_SERVICE')
|
headerObservable |
Type : any
|
isUserIdVerified |
Default value : false
|
memberList |
Type : GroupMember[]
|
Default value : []
|
showErrorMsg |
Default value : false
|
showLoader |
Type : boolean
|
Private unregisterBackButton |
Type : Subscription
|
userDetails |
username |
Type : string
|
Default value : ''
|
import { Component, Inject, ViewChild, ElementRef } from '@angular/core';
import { Subscription } from 'rxjs';
import {
AddMembersRequest,
CheckUserExistsRequest,
GroupMember,
GroupMemberRole,
GroupService,
ProfileService,
SystemSettingsService,
SharedPreferences,
CorrelationData
} from 'sunbird-sdk';
import { Location } from '@angular/common';
import { Router } from '@angular/router';
import { Platform, PopoverController } from '@ionic/angular';
import {
AppHeaderService,
CommonUtilService,
Environment,
ID,
InteractSubtype,
InteractType,
PageId,
TelemetryGeneratorService,
UtilityService
} from '@app/services';
import { animationShrinkOutTopRight } from '../../animations/animation-shrink-out-top-right';
import { MyGroupsPopoverComponent } from '../../components/popups/sb-my-groups-popover/sb-my-groups-popover.component';
import { animationGrowInFromEvent } from '@app/app/animations/animation-grow-in-from-event';
import { PreferenceKey, GroupErrorCodes } from '@app/app/app.constant';
import { RecaptchaComponent } from 'ng-recaptcha';
@Component({
selector: 'app-add-member-to-group',
templateUrl: './add-member-to-group.page.html',
styleUrls: ['./add-member-to-group.page.scss'],
})
export class AddMemberToGroupPage {
corRelationList: Array<CorrelationData>;
isUserIdVerified = false;
showErrorMsg = false;
headerObservable: any;
showLoader: boolean;
username = '';
groupId: string;
memberList: GroupMember[] = [];
userDetails;
private unregisterBackButton: Subscription;
appName: string;
@ViewChild('cap', { static: false }) cap: RecaptchaComponent;
@ViewChild('addMemberInfoPopupRef', { static: false }) addMemberInfoPopupRef: ElementRef<HTMLSpanElement>;
constructor(
@Inject('PROFILE_SERVICE') private profileService: ProfileService,
@Inject('GROUP_SERVICE') public groupService: GroupService,
@Inject('SYSTEM_SETTINGS_SERVICE') private systemSettingsService: SystemSettingsService,
@Inject('SHARED_PREFERENCES') private preferences: SharedPreferences,
private headerService: AppHeaderService,
private router: Router,
private location: Location,
private platform: Platform,
private commonUtilService: CommonUtilService,
private popoverCtrl: PopoverController,
private telemetryGeneratorService: TelemetryGeneratorService,
private sbUtility: UtilityService
) {
const extras = this.router.getCurrentNavigation().extras.state;
this.groupId = extras.groupId;
this.memberList = extras.memberList;
this.corRelationList = extras.corRelation;
}
async getGoogleCaptchaSiteKey(): Promise<{ isCaptchaEnabled: boolean, captchaKey: string }> {
if (this.commonUtilService.getGoogleCaptchaConfig().size === 0) {
return this.systemSettingsService.getSystemSettings({ id: 'appGoogleReCaptcha' }).toPromise()
.then((res) => {
const captchaConfig = JSON.parse(res.value);
const isCaptchaEnabled = captchaConfig['isEnabled'] || captchaConfig.get('isEnabled');
const captchaKey = captchaConfig['key'] || captchaConfig.get('key');
this.commonUtilService.setGoogleCaptchaConfig(captchaKey, isCaptchaEnabled);
return { isCaptchaEnabled, captchaKey };
});
} else if (Boolean(this.commonUtilService.getGoogleCaptchaConfig())) {
const captchaConfig = this.commonUtilService.getGoogleCaptchaConfig();
const isCaptchaEnabled = captchaConfig['isEnabled'] || captchaConfig.get('isEnabled');
const captchaKey = captchaConfig['key'] || captchaConfig.get('key');
return { isCaptchaEnabled, captchaKey };
}
}
ionViewWillEnter() {
this.headerService.showHeaderWithBackButton();
this.headerObservable = this.headerService.headerEventEmitted$.subscribe(eventName => {
this.handleHeaderEvents(eventName);
});
this.handleDeviceBackButton();
this.commonUtilService.getAppName().then((res) => { this.appName = res; });
}
async ionViewDidEnter() {
try {
const addMemberInfoScreen = await this.preferences.getBoolean(PreferenceKey.ADD_MEMBER_TO_GROUP_INFO_POPUP).toPromise();
if (!addMemberInfoScreen) {
this.addMemberInfoPopupRef.nativeElement.click();
this.preferences.putBoolean(PreferenceKey.ADD_MEMBER_TO_GROUP_INFO_POPUP, true).toPromise().then();
}
} catch (err) {
}
}
ionViewWillLeave() {
this.headerObservable.unsubscribe();
if (this.unregisterBackButton) {
this.unregisterBackButton.unsubscribe();
}
}
handleDeviceBackButton() {
this.unregisterBackButton = this.platform.backButton.subscribeWithPriority(10, () => {
this.handleBackButton(false);
});
}
handleHeaderEvents($event) {
if($event.name === 'back')
{
this.handleBackButton(true);
}
}
handleBackButton(isNavBack) {
if (this.isUserIdVerified) {
this.isUserIdVerified = false;
} else {
this.telemetryGeneratorService.generateBackClickedTelemetry(PageId.ADD_MEMBER,
Environment.GROUP, isNavBack, undefined, this.corRelationList);
this.location.back();
}
}
async onVerifyClick() {
let captchaResponse: string | undefined;
const { isCaptchaEnabled, captchaKey } = await this.getGoogleCaptchaSiteKey();
if (isCaptchaEnabled) {
await this.sbUtility.verifyCaptcha(captchaKey).then((res) => {
captchaResponse = res;
}).catch((error) => {
console.error(error);
});
}
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.VERIFY_USER,
InteractSubtype.VERIFY_CLICKED,
Environment.GROUP,
PageId.ADD_MEMBER,
undefined, undefined, undefined, this.corRelationList, ID.VERIFY_USER);
if (!this.username) {
this.showErrorMsg = true;
return;
}
this.showErrorMsg = false;
const checkUserExistsRequest: CheckUserExistsRequest = {
matching: {
key: 'userName',
value: this.username
},
captchaResponseToken: captchaResponse
};
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.INITIATED,
'',
Environment.GROUP,
PageId.ADD_MEMBER,
undefined,
undefined,
undefined,
this.corRelationList,
ID.VERIFY_MEMBER);
this.showLoader = true;
this.profileService.checkServerProfileExists(checkUserExistsRequest).toPromise()
.then(async (checkUserExistsResponse) => {
this.showLoader = false;
if (checkUserExistsResponse && checkUserExistsResponse.exists) {
this.userDetails = checkUserExistsResponse;
this.isUserIdVerified = true;
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.SUCCESS,
'',
Environment.GROUP,
PageId.ADD_MEMBER,
undefined,
undefined,
undefined,
this.corRelationList,
ID.VERIFY_MEMBER);
} else {
this.showErrorMsg = true;
}
}).catch(async (e) => {
console.error(e);
this.showLoader = false;
this.commonUtilService.showToast('SOMETHING_WENT_WRONG');
});
}
onClearUser() {
this.isUserIdVerified = false;
this.username = '';
}
async onAddToGroupClick() {
if (!this.commonUtilService.networkInfo.isNetworkAvailable) {
this.commonUtilService.presentToastForOffline('YOU_ARE_NOT_CONNECTED_TO_THE_INTERNET');
return;
}
const userExist = this.memberList.find(m => m.userId === this.userDetails.id);
// Check if user already exist in group
if (userExist) {
this.commonUtilService.showToast('MEMBER_ALREADY_EXISTS_IN_GROUP');
return;
}
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.TOUCH,
InteractSubtype.ADD_MEMBER_TO_GROUP_CLICKED,
Environment.GROUP,
PageId.ADD_MEMBER,
undefined, undefined, undefined, this.corRelationList);
const loader = await this.commonUtilService.getLoader();
await loader.present();
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.INITIATED,
'',
Environment.GROUP,
PageId.ADD_MEMBER,
undefined,
undefined,
undefined,
this.corRelationList,
ID.ADD_MEMBER_TO_GROUP);
const addMemberToGroupReq: AddMembersRequest = {
groupId: this.groupId,
addMembersRequest: {
members: [{
userId: this.userDetails.id,
role: GroupMemberRole.MEMBER
}]
}
};
this.groupService.addMembers(addMemberToGroupReq).toPromise()
.then(async (res) => {
await loader.dismiss();
if (res.error && res.error.members && res.error.members.length) {
console.log('in err');
if (res.error.members[0].errorCode === GroupErrorCodes.EXCEEDED_MEMBER_MAX_LIMIT) {
this.commonUtilService.showToast('ERROR_MAXIMUM_MEMBER_COUNT_EXCEEDS');
}
} else {
this.telemetryGeneratorService.generateInteractTelemetry(
InteractType.SUCCESS,
'',
Environment.GROUP,
PageId.ADD_MEMBER,
undefined,
undefined,
undefined,
this.corRelationList,
ID.ADD_MEMBER_TO_GROUP);
this.commonUtilService.showToast('MEMBER_ADDED_TO_GROUP');
this.location.back();
}
}).catch(async (e) => {
console.log(e);
await loader.dismiss();
this.commonUtilService.showToast('SOMETHING_WENT_WRONG');
});
}
async openInfoPopup(event: MouseEvent) {
const popover = await this.popoverCtrl.create({
component: MyGroupsPopoverComponent,
componentProps: {
isFromAddMember: true
},
enterAnimation: animationGrowInFromEvent(event),
leaveAnimation: animationShrinkOutTopRight,
backdropDismiss: false,
showBackdrop: true,
cssClass: 'popover-my-groups'
});
await popover.present();
const { data } = await popover.onDidDismiss();
if (data === undefined) { // Backdrop clicked
} else if (data.closeDeletePopOver) { // Close clicked
} else if (data.canDelete) {
}
}
}
<ion-content overflow-scroll="true">
<div class="au-container" *ngIf="!isUserIdVerified">
<h3 class="au-title">{{'ADD_MEMBER' | translate}}</h3>
<div class="au-ip">
<div class="au-ip-info clearfix">
<span class="pull-left">
{{'MEMBER_ID' | translate: {'app_name': appName} }}<sup>*</sup>
</span>
<span (click)="openInfoPopup($event)" role="button" aria-label="open info popup" class="pull-right" #addMemberInfoPopupRef>
<span>
<ion-icon class="au-info-icon" name="information-circle-outline"></ion-icon>
</span>
</span>
</div>
<input [ngClass]="{'error' : showErrorMsg}" type="text"
placeholder="{{'ENTER_MEMBER_ID' | translate: {'app_name': appName} }}" [(ngModel)]="username">
<p *ngIf="showErrorMsg" class="au-ip-error-msg">
{{'INVALID_MEMBER_ID' | translate: {'app_name': appName} }}
</p>
</div>
</div>
<div class="au-container" *ngIf="isUserIdVerified">
<h3 class="au-title">{{'ADD_MEMBER' | translate}}</h3>
<div class="au-ip">
<div class="au-ip-info clearfix">
<span class="pull-left">{{'MEMBER_ID' | translate: {'app_name': appName} }}</span>
<span (click)="openInfoPopup($event)" class="pull-right">
<ion-icon class="au-info-icon" role="button" aria-label="Open info popup" name="information-circle-outline"></ion-icon>
</span>
</div>
<input type="text" placeholder="{{'ENTER_MEMBER_ID' | translate: {'app_name': appName} }}"
[(ngModel)]="username" disabled>
<ion-icon class="au-clear-icon" name="close" (click)="onClearUser()">
</ion-icon>
</div>
<div class="au-avatar">
<app-profile-avatar [username]="userDetails.name"></app-profile-avatar>
<h3>{{userDetails.name}}</h3>
</div>
<div class="au-desc">{{'ADD_MEMBER_CONFIRMATION' | translate: {'app_name': appName} }}</div>
</div>
<div *ngIf="showLoader" class="ion-padding-start ion-padding-end">
<div class="loader-container">
<div class="loader"></div>
<h6 class="loader-text">{{'VERYFYING_PLEASE_WAIT' | translate}}</h6>
</div>
</div>
</ion-content>
<ion-footer>
<div class="au-btn" *ngIf="!isUserIdVerified">
<button class="sb-btn-large" [class.inactive]="!username" [disabled]="!username" (click)="onVerifyClick()">
{{'VERIFY' | translate}}
</button>
</div>
<div class="au-btn" *ngIf="isUserIdVerified">
<button class="sb-btn-large" (click)="onAddToGroupClick()">
<img src="assets/imgs/ic_person_add_white.svg" alt="">
{{'ADD_TO_GROUP' | translate}}
</button>
</div>
</ion-footer>
./add-member-to-group.page.scss
@import "src/assets/styles/_variables.scss";
.au-container{
padding: 16px;
.au-title{
font-size: 1.125rem;
font-weight: bold;
margin-top: 8px;
}
.au-ip{
margin-bottom: 30px;
position: relative;
.au-ip-info{
margin-bottom: 8px;
font-size: 1rem;
.pull-left{
sup{
color: $red;
}
}
.pull-right{
color: $gray-300;
font-size: $font-size-base;
}
.au-info-icon{
color: $blue;
font-size: 1.25rem;
vertical-align: bottom;
}
}
input{
&.error{
border: 1px solid $red;
}
&:disabled{
background-color: #fff;
}
width: 100%;
height: 2.5rem;
border: 1px solid $gray-800;
padding: 0 16px;
color: $gray-800;
border-radius: 2px;
outline: none;
}
.au-clear-icon{
position: absolute;
bottom: 0.625rem;
right: 0.5rem;
font-size: 1.25rem;
}
.au-ip-error-msg{
color: $red;
font-size: $font-size-base;
margin-top: 8px;
}
}
.au-avatar{
padding: 16px;
background-color: map-get($colors, pale_blue);
text-align: center;
}
.au-desc{
font-size: 1rem;
padding: 16px 0;
span{
font-weight: bold;
}
}
}
.au-btn{
padding: 0px 16px 24px 16px;
.sb-btn-large{
&.inactive{
background-color: $gray-200;
}
img{
margin-right: 8px;
position: relative;
bottom: 0.125rem;
}
}
}
.loader {
border: 4px solid $gray-300;
box-sizing: border-box;
border-radius: 50%;
border-top: 4px solid transparent;
width: 3rem;
float: center;
height: 3rem;
margin-left: 45%;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
/* Safari */
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loader-container {
text-align: center;
padding: 30px;
border-radius: 2px;
background-color: map-get($colors, pale_blue);
}
.loader-text {
font-size: 0.75rem;
color: $gray-300;
}