application skeleton
parent
62f2cfcda3
commit
48a4360ac1
@ -1,3 +1,83 @@
|
|||||||
<ion-app>
|
|
||||||
<ion-router-outlet></ion-router-outlet>
|
<!-- <ion-nav [root]="rootPage" #mycontent swipeBackEnabled="false"></ion-nav> -->
|
||||||
|
<ion-app [dir]="direction">
|
||||||
|
<ion-split-pane>
|
||||||
|
<!-- <ion-menu persistent="true" id="leftMenu" class="menu"
|
||||||
|
side="left" *ngIf="direction==='ltr'" >
|
||||||
|
<ion-content class="sidebar-menu">
|
||||||
|
<div class="header-div">
|
||||||
|
<div class="centerDiv">
|
||||||
|
<p class="TxtPlace">{{"home.hello" | translate}}, {{User_name_Emp}}</p>
|
||||||
|
<div> <img src="{{user_image}}" class="profileImg" ></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ion-list>
|
||||||
|
<button class="menu-item" ion-item menuClose ion-item (click)="goToWorkListPage()" >
|
||||||
|
<img width="30" src="../assets/imgs/bell.png" item-left >
|
||||||
|
{{"home.worklist" | translate }}
|
||||||
|
<ion-badge item-end>{{notBadge}}</ion-badge>
|
||||||
|
</button>
|
||||||
|
<button class="menu-item" ion-item menuClose ion-item (click)="goToProfile()" >
|
||||||
|
<img width="30" src="../assets/imgs/username.png" item-left >
|
||||||
|
{{"userProfile.title" | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="menu-item" ion-item menuClose ion-item (click)="logout()" >
|
||||||
|
<img width="30" src="../assets/imgs/signout.png" item-left >
|
||||||
|
{{"home.logout" | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="menuFooter">
|
||||||
|
<div> <img src="{{companyUrl}}" class="CompanyImg" ></div>
|
||||||
|
<p class="companyTxt">{{companyDesc}}</p>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
</ion-menu>
|
||||||
|
<ion-menu persistent="true" id="rightMenu" class="menu"
|
||||||
|
side="right" *ngIf="direction==='rtl'" >
|
||||||
|
<ion-content class="sidebar-menu">
|
||||||
|
<div class="header-div">
|
||||||
|
<div class="centerDiv">
|
||||||
|
<p class="TxtPlace">{{"home.hello" | translate}}, {{User_name_Emp}}</p>
|
||||||
|
<div> <img src="{{user_image}}" class="profileImg" ></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ion-list>
|
||||||
|
<button class="menu-item" ion-item menuClose ion-item (click)="goToWorkListPage()" >
|
||||||
|
<img width="30" src="../assets/imgs/bell.png" item-left >
|
||||||
|
{{"home.worklist" | translate }}
|
||||||
|
<ion-badge item-end>{{notBadge}}</ion-badge>
|
||||||
|
</button>
|
||||||
|
<button class="menu-item" ion-item menuClose ion-item (click)="goToProfile()" >
|
||||||
|
<img width="30" src="../assets/imgs/username.png" item-left >
|
||||||
|
{{"userProfile.title" | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button class="menu-item" ion-item menuClose ion-item (click)="logout()" >
|
||||||
|
<img width="30" src="../assets/imgs/signout.png" item-left >
|
||||||
|
{{"home.logout" | translate }}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="menuFooter">
|
||||||
|
<div> <img src="{{companyUrl}}" class="CompanyImg" ></div>
|
||||||
|
<p class="companyTxt">{{companyDesc}}</p>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
</ion-menu> -->
|
||||||
|
|
||||||
|
<ion-router-outlet main></ion-router-outlet>
|
||||||
|
|
||||||
|
</ion-split-pane>
|
||||||
|
|
||||||
</ion-app>
|
</ion-app>
|
||||||
@ -1,26 +1,36 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||||
|
import { Platform, Events, MenuController } from '@ionic/angular';
|
||||||
import { Platform } from '@ionic/angular';
|
|
||||||
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
|
|
||||||
import { StatusBar } from '@ionic-native/status-bar/ngx';
|
import { StatusBar } from '@ionic-native/status-bar/ngx';
|
||||||
|
import { TranslatorService } from './hmg-common/services/translator/translator.service';
|
||||||
|
import { CommonService } from './hmg-common/services/common/common.service';
|
||||||
|
import { AuthenticationService } from './hmg-common/services/authentication/authentication.service';
|
||||||
|
import { AuthenticatedUser } from './hmg-common/services/authentication/models/authenticated-user';
|
||||||
|
import { TabsBarComponent } from './hmg-common/ui/tabs-bar/tabs-bar.component';
|
||||||
|
import { KeyboardService } from './hmg-common/services/keyboard/keyboard.service';
|
||||||
|
import { Router, RouteConfigLoadStart, RouteConfigLoadEnd, NavigationStart, NavigationEnd, NavigationCancel } from '@angular/router';
|
||||||
|
import { LazyLoadingService } from './hmg-common/services/lazy-loading/lazy-loading.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
|
styleUrls: ['./app.component.scss'],
|
||||||
templateUrl: 'app.component.html'
|
templateUrl: 'app.component.html'
|
||||||
})
|
})
|
||||||
export class AppComponent {
|
export class AppComponent implements OnInit, AfterViewInit {
|
||||||
constructor(
|
// rootPage:any = LoginPage;
|
||||||
private platform: Platform,
|
// @ViewChild(Nav) nav: Nav;
|
||||||
private splashScreen: SplashScreen,
|
|
||||||
private statusBar: StatusBar
|
menuList:any=[];
|
||||||
) {
|
User_name_Emp:string="";
|
||||||
this.initializeApp();
|
user_image:string="";
|
||||||
|
menuSide:string="left";
|
||||||
|
notBadge:number;
|
||||||
|
companyUrl:string="../assets/imgs/CS.png";
|
||||||
|
companyDesc:string="Powered By Cloud Solutions";
|
||||||
|
public direction = 'ltr';
|
||||||
|
ngOnInit(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ngAfterViewInit(){
|
||||||
|
|
||||||
initializeApp() {
|
|
||||||
this.platform.ready().then(() => {
|
|
||||||
this.statusBar.styleDefault();
|
|
||||||
this.splashScreen.hide();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,28 @@
|
|||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<nav-buttons [navigate]="false" (backClick)="onRejectClicked()" ></nav-buttons>
|
||||||
|
<ion-title>{{ 'general,usage-agreement' | translate}}</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content padding>
|
||||||
|
<scroll-content>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row *ngIf="agreementContent" class="ion-justify-content-center">
|
||||||
|
<ion-col [size]="11">
|
||||||
|
<div class="html-container" [innerHTML]="agreementContent | safeHtml"> </div>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
<page-trailer [small]="true"></page-trailer>
|
||||||
|
</scroll-content>
|
||||||
|
<footer>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row class="ion-justify-content-center">
|
||||||
|
<ion-col [size]="10" [sizeLg]="8" [sizeXl]="6" no-padding>
|
||||||
|
<ion-button (click)="onAcceptClicked()" expand="block">{{ 'general,accept' | translate}}</ion-button>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
</footer>
|
||||||
|
</ion-content>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
.agreement_area{
|
||||||
|
width: 100%;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.html-container {
|
||||||
|
width: 96%;
|
||||||
|
padding: 2%;
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AgreementComponent } from './agreement.component';
|
||||||
|
|
||||||
|
describe('AgreementComponent', () => {
|
||||||
|
let component: AgreementComponent;
|
||||||
|
let fixture: ComponentFixture<AgreementComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AgreementComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AgreementComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
||||||
|
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
||||||
|
import { AgreementService } from './service/agreement.service';
|
||||||
|
import { CheckUserAgreementResponse } from './service/models/check-user-agreement.response';
|
||||||
|
import { GetUserAgreementResponse } from './service/models/get-user-agreement.response';
|
||||||
|
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-agreement',
|
||||||
|
templateUrl: './agreement.component.html',
|
||||||
|
styleUrls: ['./agreement.component.scss']
|
||||||
|
})
|
||||||
|
export class AgreementComponent implements OnInit {
|
||||||
|
|
||||||
|
public agreementContent: string;
|
||||||
|
constructor(
|
||||||
|
public ts: TranslatorService,
|
||||||
|
public cs: CommonService,
|
||||||
|
public agreementService: AgreementService,
|
||||||
|
public auth: AuthenticationService
|
||||||
|
|
||||||
|
) { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.checkUserAgreement();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkUserAgreement() {
|
||||||
|
this.agreementService.checkUserAgreement(
|
||||||
|
() => {
|
||||||
|
this.checkUserAgreement();
|
||||||
|
}, this.ts.trPK('general', 'retry')).subscribe((result: CheckUserAgreementResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
if (result.IsPatientAlreadyAgreed) {
|
||||||
|
this.auth.setUserAgreed(true);
|
||||||
|
this.cs.openHome();
|
||||||
|
} else {
|
||||||
|
this.getUserAgreement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getUserAgreement() {
|
||||||
|
this.agreementService.getAgreement(
|
||||||
|
() => {
|
||||||
|
this.getUserAgreement();
|
||||||
|
}, this.ts.trPK('general', 'retry')).subscribe((result: GetUserAgreementResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
this.agreementContent = result.UserAgreementContent;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onAcceptClicked() {
|
||||||
|
this.agreementService.addUserAgreement(
|
||||||
|
() => {
|
||||||
|
this.onAcceptClicked();
|
||||||
|
}, this.ts.trPK('general', 'retry')).subscribe((result: GetUserAgreementResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
this.auth.setUserAgreed(true);
|
||||||
|
this.cs.openHome();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onRejectClicked() {
|
||||||
|
this.auth.clearUser().subscribe(success => {
|
||||||
|
this.cs.openHome();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AgreementService } from './agreement.service';
|
||||||
|
|
||||||
|
describe('AgreementService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: AgreementService = TestBed.get(AgreementService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,53 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ConnectorService } from 'src/app/hmg-common/services/connector/connector.service';
|
||||||
|
import { CheckUserAgreementRequest } from './models/check-user-agreement.request';
|
||||||
|
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { CheckUserAgreementResponse } from './models/check-user-agreement.response';
|
||||||
|
import { Request } from 'src/app/hmg-common/services/models/request';
|
||||||
|
import { GetUserAgreementResponse } from './models/get-user-agreement.response';
|
||||||
|
import { AddUserAgreementRequest } from './models/add-user-agreement.request';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AgreementService {
|
||||||
|
|
||||||
|
public static checkAgreementURL = 'Services/Patients.svc/REST/CheckForUsageAgreement';
|
||||||
|
public static getAgreementURL = 'Services/Patients.svc/REST/GetUsageAgreementText';
|
||||||
|
public static addAgreementURL = 'Services/Patients.svc/REST/AddUsageAgreement';
|
||||||
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public con: ConnectorService,
|
||||||
|
public auth: AuthenticationService
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public checkUserAgreement(onError: any, errorLabel: string): Observable<CheckUserAgreementResponse> {
|
||||||
|
const request = new CheckUserAgreementRequest();
|
||||||
|
request.Region = 1;
|
||||||
|
this.auth.authenticateRequest(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
return this.con.post(AgreementService.checkAgreementURL, request, onError, errorLabel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAgreement(onError: any, errorLabel: string): Observable<GetUserAgreementResponse> {
|
||||||
|
const request = new Request();
|
||||||
|
this.auth.setPublicFields(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
return this.con.post(AgreementService.getAgreementURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public addUserAgreement(onError: any, errorLabel: string): Observable<GetUserAgreementResponse> {
|
||||||
|
const request = new AddUserAgreementRequest();
|
||||||
|
request.Region = 1;
|
||||||
|
this.auth.authenticateRequest(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
return this.con.post(AgreementService.addAgreementURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { Request } from 'src/app/hmg-common/services/models/request';
|
||||||
|
|
||||||
|
export class AddUserAgreementRequest extends Request {
|
||||||
|
Region: number; // 1
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { Request } from 'src/app/hmg-common/services/models/request';
|
||||||
|
|
||||||
|
export class CheckUserAgreementRequest extends Request {
|
||||||
|
Region: number; // 1
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { Response } from 'src/app/hmg-common/services/models/response';
|
||||||
|
|
||||||
|
export class CheckUserAgreementResponse extends Response {
|
||||||
|
IsPatientAlreadyAgreed: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { Response } from 'src/app/hmg-common/services/models/response';
|
||||||
|
|
||||||
|
export class GetUserAgreementResponse extends Response {
|
||||||
|
UserAgreementContent: string;
|
||||||
|
}
|
||||||
@ -0,0 +1,72 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
import { IonicModule } from '@ionic/angular';
|
||||||
|
import { AuthenticationPage } from './authentication.page';
|
||||||
|
import { LoginComponent } from './login/login.component';
|
||||||
|
import { ForgotComponent } from './forgot/forgot.component';
|
||||||
|
import { HmgCommonModule } from '../hmg-common/hmg-common.module';
|
||||||
|
import { SelectButtonModule } from 'primeng/selectbutton';
|
||||||
|
import { AgreementComponent } from './agreement/agreement.component';
|
||||||
|
import { FingerprintAIO } from '@ionic-native/fingerprint-aio/ngx';
|
||||||
|
import { Device } from '@ionic-native/device/ngx';
|
||||||
|
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
|
||||||
|
|
||||||
|
import { SearchableOptionsModule } from '../hmg-common/ui/searchable-select/searchable-options.module';
|
||||||
|
import { MobileNumberModule } from 'src/app/hmg-common/ui/mobile-number/mobile-number.module';
|
||||||
|
import { SmsdialogPageModule } from 'src/app/hmg-common/ui/smsdialog/smsdialog.module';
|
||||||
|
import { SmsPageModule } from 'src/app/hmg-common/ui/sms/sms.module';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: AuthenticationPage,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'login',
|
||||||
|
component: LoginComponent
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
path: 'forgot',
|
||||||
|
component: ForgotComponent
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'agreement',
|
||||||
|
component: AgreementComponent
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
SmsdialogPageModule,
|
||||||
|
SmsPageModule,
|
||||||
|
IonicModule,
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
HmgCommonModule,
|
||||||
|
SearchableOptionsModule,
|
||||||
|
SelectButtonModule,
|
||||||
|
MobileNumberModule
|
||||||
|
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AuthenticationPage,
|
||||||
|
LoginComponent,
|
||||||
|
ForgotComponent,
|
||||||
|
AgreementComponent,
|
||||||
|
],
|
||||||
|
providers:[
|
||||||
|
FingerprintAIO,
|
||||||
|
Device,
|
||||||
|
SplashScreen
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AuthenticationPageModule { }
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<!--
|
||||||
|
<ion-content>
|
||||||
|
<ion-router-outlet></ion-router-outlet>
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
<div class="hub">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<ion-content>
|
||||||
|
<ion-router-outlet></ion-router-outlet>
|
||||||
|
</ion-content>
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthenticationPage } from './authentication.page';
|
||||||
|
|
||||||
|
describe('AuthenticationPage', () => {
|
||||||
|
let component: AuthenticationPage;
|
||||||
|
let fixture: ComponentFixture<AuthenticationPage>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AuthenticationPage ],
|
||||||
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(AuthenticationPage);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-authentication',
|
||||||
|
templateUrl: './authentication.page.html',
|
||||||
|
styleUrls: ['./authentication.page.scss'],
|
||||||
|
})
|
||||||
|
export class AuthenticationPage implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<nav-buttons ></nav-buttons>
|
||||||
|
<ion-title>{{'login,forgot-id' | translate}}</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content padding>
|
||||||
|
<scroll-content>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row class="ion-justify-content-center">
|
||||||
|
<ion-col center [size]="11">
|
||||||
|
<p> {{ 'login,forgot-desc'| translate}}</p>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<!-- international mobile number-->
|
||||||
|
<ion-row class="ion-justify-content-center">
|
||||||
|
<ion-col [size]="11">
|
||||||
|
<international-mobile (changed)="countryCodeChanged($event)"></international-mobile>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
|
||||||
|
|
||||||
|
</ion-grid>
|
||||||
|
<page-trailer [small]="true"></page-trailer>
|
||||||
|
</scroll-content>
|
||||||
|
<footer>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row class="ion-justify-content-center">
|
||||||
|
<ion-col [size]="10" [sizeLg]="8" [sizeXl]="6" no-padding>
|
||||||
|
<ion-button (click)="onForgot()" [disabled]="!isValidForm()" expand="block">
|
||||||
|
{{'general,submit' | translate}} </ion-button>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
</footer>
|
||||||
|
</ion-content>
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ForgotComponent } from './forgot.component';
|
||||||
|
|
||||||
|
describe('ForgotComponent', () => {
|
||||||
|
let component: ForgotComponent;
|
||||||
|
let fixture: ComponentFixture<ForgotComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ForgotComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ForgotComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,115 @@
|
|||||||
|
import { Component, OnInit, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core';
|
||||||
|
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
||||||
|
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { AlertController } from '@ionic/angular';
|
||||||
|
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
||||||
|
import { CheckUserAuthenticationRequest } from 'src/app/hmg-common/services/authentication/models/check-user-auth.request';
|
||||||
|
import { CheckUserAuthenticationResponse } from 'src/app/hmg-common/services/authentication/models/check-user-auth.response';
|
||||||
|
import { CheckActivationCodeRequest } from 'src/app/hmg-common/services/authentication/models/check-activation-code.request';
|
||||||
|
import { SmsReaderService } from 'src/app/hmg-common/services/sms/sms-reader.service';
|
||||||
|
import { ForgotFileIDResponse } from '../../hmg-common/services/authentication/models/forgot-File-ID.response';
|
||||||
|
import { InternationalMobileComponent } from 'src/app/hmg-common/ui/mobile-number/international-mobile/international-mobile.component';
|
||||||
|
import { CountryCode } from 'src/app/hmg-common/ui/mobile-number/international-mobile/models/country-code.model';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-forgot',
|
||||||
|
templateUrl: './forgot.component.html',
|
||||||
|
styleUrls: ['./forgot.component.scss']
|
||||||
|
})
|
||||||
|
export class ForgotComponent implements OnInit,OnDestroy {
|
||||||
|
|
||||||
|
public countryCode: CountryCode;
|
||||||
|
@ViewChild(InternationalMobileComponent) internationlMobile: InternationalMobileComponent;
|
||||||
|
constructor(
|
||||||
|
public cs: CommonService,
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
public router: Router,
|
||||||
|
public alertController: AlertController,
|
||||||
|
public ts: TranslatorService,
|
||||||
|
public smsService: SmsReaderService,
|
||||||
|
public changeDetector: ChangeDetectorRef
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.smsService.stopSMSMonitoring();
|
||||||
|
}
|
||||||
|
public onForgot() {
|
||||||
|
this.sendSMSForForgotPassword();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public countryCodeChanged(countryCode: CountryCode) {
|
||||||
|
this.countryCode = countryCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isValidForm() {
|
||||||
|
return (this.countryCode && this.countryCode.isValid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private checkUserResult: CheckUserAuthenticationResponse;
|
||||||
|
|
||||||
|
private sendSMSForForgotPassword() {
|
||||||
|
const request = new CheckUserAuthenticationRequest();
|
||||||
|
request.PatientMobileNumber = this.countryCode.number;
|
||||||
|
request.ZipCode = CountryCode.localCode(this.countryCode.code);
|
||||||
|
|
||||||
|
this.authService.sendSMSForForgotFileNumber(
|
||||||
|
request,
|
||||||
|
() => {
|
||||||
|
this.sendSMSForForgotPassword();
|
||||||
|
}, this.ts.trPK('general', 'ok')).subscribe((result: CheckUserAuthenticationResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
this.checkUserResult = result;
|
||||||
|
if (result.isSMSSent) {
|
||||||
|
this.startReceivingSMS();
|
||||||
|
this.presentSMSPasswordDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private startReceivingSMS() {
|
||||||
|
this.smsService.startSMSMonitoring((code) => {
|
||||||
|
this.cs.dismissSMSDialog().subscribe(cleared => {
|
||||||
|
this.checkActivationCode(code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public presentSMSPasswordDialog() {
|
||||||
|
this.cs.presentSMSPasswordDialog(
|
||||||
|
(code: string) => {
|
||||||
|
this.checkActivationCode(code);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkActivationCode(readedCode?) {
|
||||||
|
const request = new CheckActivationCodeRequest();
|
||||||
|
request.LogInTokenID = this.checkUserResult.LogInTokenID;
|
||||||
|
request.PatientOutSA = this.checkUserResult.PatientOutSA ? 1 : 0;
|
||||||
|
request.PatientMobileNumber = this.countryCode.number;
|
||||||
|
request.ZipCode = CountryCode.localCode(this.countryCode.code);
|
||||||
|
request.activationCode = readedCode;
|
||||||
|
|
||||||
|
this.authService.forgotFileIdActivation(request,
|
||||||
|
() => {
|
||||||
|
this.presentSMSPasswordDialog();
|
||||||
|
}, this.ts.trPK('general', 'retry')).subscribe((result: ForgotFileIDResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
this.smsService.stopSMSMonitoring();
|
||||||
|
this.cs.presentAlert(result.ReturnMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
<ion-content padding>
|
||||||
|
<ion-grid class="customGrid">
|
||||||
|
<ion-row>
|
||||||
|
<ion-col class="colPad">
|
||||||
|
<ion-img class="centerDiv" src="../assets/imgs/CS.png"></ion-img>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<P class="pageTitle text-caps">{{'login,title' | translate}}</P>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<img class="item-icon" src="assets/imgs/username.png" item-start />
|
||||||
|
<ion-label>{{'login,userName' | translate}}</ion-label>
|
||||||
|
<ion-input required type="text" [(ngModel)]="memberLogin.P_USER_NAME">
|
||||||
|
</ion-input>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<ion-item>
|
||||||
|
<img class="item-icon" src="assets/imgs/password.png" item-start />
|
||||||
|
<ion-label>{{'login,password' | translate}}</ion-label>
|
||||||
|
<ion-input required type="password" [(ngModel)]="memberLogin.P_PASSWORD">
|
||||||
|
</ion-input>
|
||||||
|
</ion-item>
|
||||||
|
|
||||||
|
<div class="centerDiv signupDiv" *ngIf="isAppleStore==true">
|
||||||
|
<a (click)="signUp()">{{ts.trPK('login','signup')}}</a>
|
||||||
|
</div>
|
||||||
|
<div class="gridDiv">
|
||||||
|
<button class="gridBtn" ion-button (click)="changeLanguage(2)">English</button>
|
||||||
|
<button class="gridBtn arTxt" ion-button (click)="changeLanguage(1)">عربي</button>
|
||||||
|
</div>
|
||||||
|
<ion-footer>
|
||||||
|
<div class="centerDiv">
|
||||||
|
<button ion-button (click)="http_call()">{{ts.trPK('login','login')}}</button>
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div class="centerDiv">
|
||||||
|
<a (click)="forgetPasswordPage()">{{ts.trPK('login','forgot-password')}}</a>
|
||||||
|
</div>
|
||||||
|
</ion-footer>
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
|
||||||
|
.signupDiv{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.customGrid{
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
ion-item.item.item-block.item-md.item-input,
|
||||||
|
ion-item.item.item-block.item-ios.item-input{
|
||||||
|
padding: 0px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
ion-col.colPad.col {
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
ion-img{
|
||||||
|
width: 170px;
|
||||||
|
height: 170px;
|
||||||
|
background:var(--light);
|
||||||
|
}
|
||||||
|
.gridDiv{
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
margin-top: 20px;
|
||||||
|
// margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
// @include ltr(){
|
||||||
|
// padding-left: 16px;
|
||||||
|
// padding-right: 0;
|
||||||
|
// }
|
||||||
|
// @include rtl(){
|
||||||
|
// padding-right: 16px;
|
||||||
|
// padding-left: 0;
|
||||||
|
// // margin-bottom: 5px;
|
||||||
|
// }
|
||||||
|
button.gridBtn.button.button-md, button.gridBtn.button.button-ios, button.gridBtn.button.button{
|
||||||
|
font-family: var(--fontFamilyLightEN) !important;
|
||||||
|
min-width: auto;
|
||||||
|
// @include ltr(){
|
||||||
|
// float: left;
|
||||||
|
// border-radius: 2px 0px 0px 2px;
|
||||||
|
// font-family:$fontFamilyBoldEN !important;
|
||||||
|
// color:$customnavy;
|
||||||
|
// }
|
||||||
|
// @include rtl(){
|
||||||
|
// float: right;
|
||||||
|
// border-radius: 0px 2px 2px 0px ;
|
||||||
|
// color:$darkgray;
|
||||||
|
// }
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
border: 1px solid var(--cusgray);
|
||||||
|
box-shadow: none;
|
||||||
|
-webkit-box-shadow:none;
|
||||||
|
-moz-box-shadow: none;
|
||||||
|
background: var(--light);
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
button.arTxt.button.button-md, button.arTxt.button.button-ios, button.arTxt.button.button{
|
||||||
|
// @include rtl(){
|
||||||
|
// float: right;
|
||||||
|
// color:$customnavy !important;
|
||||||
|
// font-family:$fontFamilyIOSAR !important;
|
||||||
|
// font-weight: bold;
|
||||||
|
// border-radius: 2px 0px 0px 2px !important;
|
||||||
|
// }
|
||||||
|
// @include ltr(){
|
||||||
|
// float: left;
|
||||||
|
// color:$darkgray !important;
|
||||||
|
// font-family: $fontFamilyIOSAR !important;
|
||||||
|
// border-radius: 0px 2px 2px 0px !important;
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoginComponent } from './login.component';
|
||||||
|
|
||||||
|
describe('LoginComponent', () => {
|
||||||
|
let component: LoginComponent;
|
||||||
|
let fixture: ComponentFixture<LoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ LoginComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,476 @@
|
|||||||
|
import { Component, OnInit, ViewChild, ChangeDetectorRef, NgZone, OnDestroy } from '@angular/core';
|
||||||
|
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
||||||
|
import { AuthenticationService } from 'src/app/hmg-common/services/authentication/authentication.service';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { AlertController } from '@ionic/angular';
|
||||||
|
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
||||||
|
import { CheckUserAuthenticationRequest } from 'src/app/hmg-common/services/authentication/models/check-user-auth.request';
|
||||||
|
import { CheckUserAuthenticationResponse } from 'src/app/hmg-common/services/authentication/models/check-user-auth.response';
|
||||||
|
import { CheckActivationCodeRequest } from 'src/app/hmg-common/services/authentication/models/check-activation-code.request';
|
||||||
|
import { CheckActivationCodeResponse } from 'src/app/hmg-common/services/authentication/models/check-activation-code.response';
|
||||||
|
import { SmsReaderService } from 'src/app/hmg-common/services/sms/sms-reader.service';
|
||||||
|
import { AuthenticatedUser } from 'src/app/hmg-common/services/authentication/models/authenticated-user';
|
||||||
|
import { PATIENT_TYPE } from 'src/app/hmg-common/services/models/patient.type';
|
||||||
|
import { FingerprintAIO } from '@ionic-native/fingerprint-aio/ngx';
|
||||||
|
import { GetLoginInfoRequest } from 'src/app/hmg-common/services/authentication/models/get-login-info.request';
|
||||||
|
import { GetLoginInfoResponse } from 'src/app/hmg-common/services/authentication/models/get-login-info.response';
|
||||||
|
import { Device } from '@ionic-native/device/ngx';
|
||||||
|
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
|
||||||
|
import { CountryCode } from 'src/app/hmg-common/ui/mobile-number/international-mobile/models/country-code.model';
|
||||||
|
import { SMSService } from 'src/app/hmg-common/ui/sms/service/smsservice';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'login',
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrls: ['./login.component.scss']
|
||||||
|
})
|
||||||
|
|
||||||
|
export class LoginComponent implements OnInit, OnDestroy {
|
||||||
|
appLang:number=1;
|
||||||
|
isExpired:boolean =false;
|
||||||
|
isSupportAr:boolean=false;
|
||||||
|
isAppleStore:boolean=false;
|
||||||
|
memberLogin: any = {};
|
||||||
|
constructor(
|
||||||
|
public cs: CommonService,
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
public router: Router,
|
||||||
|
public alertController: AlertController,
|
||||||
|
public ts: TranslatorService,
|
||||||
|
public smsService: SmsReaderService,
|
||||||
|
private faio: FingerprintAIO,
|
||||||
|
public ngZone: NgZone,
|
||||||
|
public device: Device,
|
||||||
|
public splash: SplashScreen
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
//this.setIdPattern();
|
||||||
|
setTimeout(() => {
|
||||||
|
this.checkIfLoggedInBefore();
|
||||||
|
// this.splash.hide();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.backClicked();
|
||||||
|
}
|
||||||
|
private checkIfLoggedInBefore() {
|
||||||
|
this.cs.startLoading();
|
||||||
|
// check if user logged in before
|
||||||
|
this.authService.loadAuthenticatedUser().subscribe((user: AuthenticatedUser) => {
|
||||||
|
if (user) {
|
||||||
|
this.startBiometricLogin(user);
|
||||||
|
} else {
|
||||||
|
this.hideSplashScreen(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private hideSplashScreen(stopLoading = false) {
|
||||||
|
// this.splash.hide();
|
||||||
|
if (stopLoading) {
|
||||||
|
this.cs.stopLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private startBiometricLogin(user: AuthenticatedUser) {
|
||||||
|
this.faio.isAvailable().then((options) => {
|
||||||
|
this.hideSplashScreen(true);
|
||||||
|
if (user.biometricEnabled) {
|
||||||
|
// ask if login with face or finger
|
||||||
|
this.cs.presentConfirmDialog(
|
||||||
|
this.ts.trPK('login', options),
|
||||||
|
() => this.presentBiometricDialog(user),
|
||||||
|
() => { }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// ask to enable biometric
|
||||||
|
this.getPermissionToActivateBiometric(user);
|
||||||
|
}
|
||||||
|
}, () => {
|
||||||
|
this.hideSplashScreen(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getPermissionToActivateBiometric(user: AuthenticatedUser) {
|
||||||
|
this.cs.presentConfirmDialog(
|
||||||
|
this.ts.trPK('login', 'enable-biometric'),
|
||||||
|
() => {
|
||||||
|
user['biometricEnabled'] = true;
|
||||||
|
this.authService.updateLoggedInUser(user).subscribe((success: boolean) => {
|
||||||
|
this.presentBiometricDialog(user);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
() => { }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
activate biometric login for this user
|
||||||
|
*/
|
||||||
|
private getMobileInfo(user: AuthenticatedUser) {
|
||||||
|
this.authService.getLoginInfo(new GetLoginInfoRequest(user), () => {
|
||||||
|
|
||||||
|
}, this.ts.trPK('general', 'ok')).subscribe((result: GetLoginInfoResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
if (!result.SMSLoginRequired) {
|
||||||
|
this.loginTokenID = result.LogInTokenID;
|
||||||
|
this.patientOutSA = result.PatientOutSA;
|
||||||
|
this.initializeForAuthentictedUser(user);
|
||||||
|
// sms for register the biometric
|
||||||
|
if (result.isSMSSent) {
|
||||||
|
this.startListeneingForSMS(this.ts.trPK('general', 'enter-sms-enable-biometric'));
|
||||||
|
} else {
|
||||||
|
this.checkActivationCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private initializeForAuthentictedUser(user: AuthenticatedUser) {
|
||||||
|
this.ngZone.run(() => {
|
||||||
|
this.isMobileFingerPrint = true;
|
||||||
|
this.FingerPrintPatientIdentificationID = user.IdentificationNo;
|
||||||
|
this.mobileNumber = user.MobileNumber;
|
||||||
|
this.zipCode = CountryCode.localCode(user.ZipCode);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private presentBiometricDialog(user) {
|
||||||
|
this.faio.show({
|
||||||
|
clientId: 'Fingerprint Authetnciation',
|
||||||
|
clientSecret: 'Ate343_9347lajF', // Only necessary for Android
|
||||||
|
disableBackup: true, // Only for Android(optional)
|
||||||
|
localizedFallbackTitle: this.ts.trPK('login', 'use-pin'), // Only for iOS
|
||||||
|
localizedReason: this.ts.trPK('login', 'auth-please') // Only for iOS
|
||||||
|
}).then((result: any) => {
|
||||||
|
// this.checkActivationCode();
|
||||||
|
this.getMobileInfo(user);
|
||||||
|
|
||||||
|
}).catch((error: any) => console.log(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
we need holders here since the country code maybe is not loaded yet for automatic login
|
||||||
|
*/
|
||||||
|
private mobileNumber: string;
|
||||||
|
private zipCode: string;
|
||||||
|
|
||||||
|
public onLogin() {
|
||||||
|
|
||||||
|
|
||||||
|
this.checkUserAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public loginWithMyAccount() {
|
||||||
|
// this.loginWithTamer();
|
||||||
|
this.loginWithTamer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO to be removed later
|
||||||
|
*/
|
||||||
|
public loginWithEnas() {
|
||||||
|
alert('you are doing slient login width enas account ');
|
||||||
|
const user = new AuthenticatedUser();
|
||||||
|
user.PatientID = 862616;
|
||||||
|
|
||||||
|
user.PatientTypeID = PATIENT_TYPE.PERMANENT;
|
||||||
|
user.PatientOutSA = false;
|
||||||
|
user.TokenID = '@dm!n';
|
||||||
|
user.ProjectID = 0;
|
||||||
|
user.NationalityID = '2300948375';
|
||||||
|
user.MobileNo = user.MobileNumber = '554355126';
|
||||||
|
user.ZipCode = '+966';
|
||||||
|
user.Address = 'riyadh';
|
||||||
|
user.FirstName = 'MOHAMED';
|
||||||
|
user.MiddleName = 'yaghi';
|
||||||
|
user.LastName = 'mohammed';
|
||||||
|
user.Age = 30;
|
||||||
|
user.agreed = true;
|
||||||
|
const birthDate = new Date();
|
||||||
|
birthDate.setFullYear(birthDate.getFullYear() - 29);
|
||||||
|
user.DateofBirth = this.cs.convertISODateToJsonDate(this.cs.getDateISO(birthDate));
|
||||||
|
user.Email = 'Mohamed.Afifi@cloudsolution-sa.com';
|
||||||
|
user.PatientName = 'enas yaghi';
|
||||||
|
this.authService.updateLoggedInUser(user).subscribe(done => {
|
||||||
|
this.authService.startIdleMonitoring();
|
||||||
|
this.cs.openHome();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public loginWithVaccineUser() {
|
||||||
|
alert('you are doing slient login width vaccine account ');
|
||||||
|
const user = new AuthenticatedUser();
|
||||||
|
user.PatientID = 862616; // user with vaccines in dev
|
||||||
|
|
||||||
|
user.PatientTypeID = PATIENT_TYPE.PERMANENT;
|
||||||
|
user.PatientOutSA = false;
|
||||||
|
user.TokenID = '@dm!n';
|
||||||
|
user.NationalityID = '2300948375';
|
||||||
|
user.MobileNo = user.MobileNumber = '554355126';
|
||||||
|
user.ProjectID = 0;
|
||||||
|
user.ZipCode = '+966';
|
||||||
|
user.Address = 'riyadh';
|
||||||
|
user.FirstName = 'MOHAMED';
|
||||||
|
user.MiddleName = 'yaghi';
|
||||||
|
user.LastName = 'mohammed';
|
||||||
|
user.Age = 30;
|
||||||
|
user.agreed = true;
|
||||||
|
const birthDate = new Date();
|
||||||
|
birthDate.setFullYear(birthDate.getFullYear() - 29);
|
||||||
|
user.DateofBirth = this.cs.convertISODateToJsonDate(this.cs.getDateISO(birthDate));
|
||||||
|
user.Email = 'minna.barry@cloudsolution-sa.com';
|
||||||
|
user.PatientName = 'enas yaghi';
|
||||||
|
this.authService.updateLoggedInUser(user).subscribe(done => {
|
||||||
|
this.authService.startIdleMonitoring();
|
||||||
|
this.cs.openHome();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public loginWithEyeMeasureUser() {
|
||||||
|
alert('you are doing slient login width eye measurements user account ');
|
||||||
|
const user = new AuthenticatedUser();
|
||||||
|
user.PatientID = 873010;
|
||||||
|
|
||||||
|
user.PatientTypeID = PATIENT_TYPE.PERMANENT;
|
||||||
|
user.PatientOutSA = false;
|
||||||
|
user.TokenID = '@dm!n';
|
||||||
|
user.NationalityID = '2302581828';
|
||||||
|
user.ProjectID = 0;
|
||||||
|
user.MobileNo = user.MobileNumber = '555333541';
|
||||||
|
user.ZipCode = '+966';
|
||||||
|
user.Address = 'riyadh';
|
||||||
|
user.FirstName = 'eye';
|
||||||
|
user.MiddleName = 'user';
|
||||||
|
user.LastName = 'measurment';
|
||||||
|
user.Age = 30;
|
||||||
|
user.agreed = true;
|
||||||
|
const birthDate = new Date();
|
||||||
|
birthDate.setFullYear(birthDate.getFullYear() - 29);
|
||||||
|
user.DateofBirth = this.cs.convertISODateToJsonDate(this.cs.getDateISO(birthDate));
|
||||||
|
user.Email = 'sultan.khan@hmg.local';
|
||||||
|
user.PatientName = 'eye user';
|
||||||
|
this.authService.updateLoggedInUser(user).subscribe(done => {
|
||||||
|
this.authService.startIdleMonitoring();
|
||||||
|
this.cs.openHome();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO login with mr rwaid
|
||||||
|
*/
|
||||||
|
public loginWithRwaid() {
|
||||||
|
alert('you are doing slient login width mr: rwaid account');
|
||||||
|
|
||||||
|
const user = new AuthenticatedUser();
|
||||||
|
// tamer with eye measurments 1231755
|
||||||
|
user.PatientID = 1018977;
|
||||||
|
user.PatientTypeID = PATIENT_TYPE.PERMANENT;
|
||||||
|
user.ProjectID = 0;
|
||||||
|
user.PatientOutSA = false;
|
||||||
|
user.TokenID = '@dm!n';
|
||||||
|
user.NationalityID = '1001242559';
|
||||||
|
user.MobileNo = user.MobileNumber = '545156035';
|
||||||
|
user.ZipCode = '+966';
|
||||||
|
user.Address = 'riyadh';
|
||||||
|
user.FirstName = 'rwaid';
|
||||||
|
user.MiddleName = 'el mallah';
|
||||||
|
user.LastName = 'mohammed';
|
||||||
|
user.Age = 30;
|
||||||
|
user.agreed = true;
|
||||||
|
const birthDate = new Date();
|
||||||
|
birthDate.setFullYear(birthDate.getFullYear() - 29);
|
||||||
|
user.DateofBirth = this.cs.convertISODateToJsonDate(this.cs.getDateISO(birthDate));
|
||||||
|
user.Email = 'mohamed.afifi@cloudsolution-sa.com';
|
||||||
|
user.PatientName = 'rwaid al mallah';
|
||||||
|
this.authService.updateLoggedInUser(user).subscribe(done => {
|
||||||
|
this.authService.startIdleMonitoring();
|
||||||
|
this.cs.openHome();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public loginWithTamer() {
|
||||||
|
alert('you are doing slient login width tamer account');
|
||||||
|
|
||||||
|
const user = new AuthenticatedUser();
|
||||||
|
user.PatientID = 1231755;
|
||||||
|
user.PatientTypeID = PATIENT_TYPE.PERMANENT;
|
||||||
|
user.ProjectID = 0;
|
||||||
|
user.PatientOutSA = false;
|
||||||
|
user.TokenID = '@dm!n';
|
||||||
|
user.NationalityID = '1001242559';
|
||||||
|
user.MobileNo = user.MobileNumber = '537503378';
|
||||||
|
user.ZipCode = '+966';
|
||||||
|
user.Address = 'riyadh';
|
||||||
|
user.FirstName = 'tamer';
|
||||||
|
user.MiddleName = 'faneshah';
|
||||||
|
user.LastName = 'faneshah';
|
||||||
|
user.Age = 30;
|
||||||
|
user.agreed = true;
|
||||||
|
const birthDate = new Date();
|
||||||
|
birthDate.setFullYear(birthDate.getFullYear() - 29);
|
||||||
|
user.DateofBirth = this.cs.convertISODateToJsonDate(this.cs.getDateISO(birthDate));
|
||||||
|
user.Email = 'mohamed.afifi@cloudsolution-sa.com';
|
||||||
|
user.PatientName = 'tamer fneshah';
|
||||||
|
this.authService.updateLoggedInUser(user).subscribe(done => {
|
||||||
|
this.authService.startIdleMonitoring();
|
||||||
|
this.cs.openHome();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private startListeneingForSMS(title?: string) {
|
||||||
|
this.startReceivingSMS();
|
||||||
|
//this.presentSMSPasswordDialog(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkUserAuthentication() {
|
||||||
|
const request = new CheckUserAuthenticationRequest();
|
||||||
|
request.PatientMobileNumber = this.mobileNumber;
|
||||||
|
request.ZipCode = this.zipCode;
|
||||||
|
request.isRegister = false;
|
||||||
|
request.TokenID = '';
|
||||||
|
|
||||||
|
this.authService.checkUserAuthentication(
|
||||||
|
request,
|
||||||
|
() => {
|
||||||
|
|
||||||
|
}, this.ts.trPK('general', 'ok')).subscribe((result: CheckUserAuthenticationResponse) => {
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
this.loginTokenID = result.LogInTokenID;
|
||||||
|
this.patientOutSA = result.PatientOutSA;
|
||||||
|
this.isMobileFingerPrint = false;
|
||||||
|
this.FingerPrintPatientIdentificationID = '';
|
||||||
|
if (result.isSMSSent) {
|
||||||
|
this.startListeneingForSMS();
|
||||||
|
} else {
|
||||||
|
this.smsService.stopSMSMonitoring();
|
||||||
|
this.checkActivationCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public backClicked() {
|
||||||
|
this.smsService.stopSMSMonitoring();
|
||||||
|
}
|
||||||
|
|
||||||
|
private startReceivingSMS() {
|
||||||
|
|
||||||
|
// this.smsModal.presentModal();
|
||||||
|
// this.smsService.startSMSMonitoring((code) => {
|
||||||
|
// this.smsModal.dismiss;
|
||||||
|
// this.global_code = code;
|
||||||
|
// SMSService.code = this.global_code;
|
||||||
|
// this.checkActivationCode(code);
|
||||||
|
// this.cs.dismissSMSDialog().subscribe(cleared => {
|
||||||
|
// this.checkActivationCode(code);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
public presentSMSPasswordDialog(title?: string) {
|
||||||
|
this.cs.presentSMSPasswordDialog(
|
||||||
|
(code: string) => {
|
||||||
|
this.checkActivationCode(code);
|
||||||
|
}, null, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
private patientOutSA: boolean;
|
||||||
|
private loginTokenID: string;
|
||||||
|
private isMobileFingerPrint: boolean;
|
||||||
|
private FingerPrintPatientIdentificationID: string;
|
||||||
|
|
||||||
|
private checkActivationCode(readedCode?) {
|
||||||
|
const request = new CheckActivationCodeRequest();
|
||||||
|
request.IsMobileFingerPrint = this.isMobileFingerPrint;
|
||||||
|
request.FingerPrintPatientIdentificationID = this.FingerPrintPatientIdentificationID;
|
||||||
|
request.LogInTokenID = this.loginTokenID;
|
||||||
|
request.PatientOutSA = this.patientOutSA ? 1 : 0;
|
||||||
|
request.activationCode = readedCode || '0000';
|
||||||
|
request.IsSilentLogin = !readedCode;
|
||||||
|
request.PatientMobileNumber = this.mobileNumber;
|
||||||
|
request.ZipCode = this.zipCode;
|
||||||
|
// request.SearchType = this.loginType;
|
||||||
|
// if (this.loginType === LoginComponent.IDENTIFCIATION_LOGIN_TYPE) {
|
||||||
|
// request.PatientIdentificationID = this.id;
|
||||||
|
// request.PatientID = 0;
|
||||||
|
// } else {
|
||||||
|
// request.PatientID = Number(this.id);
|
||||||
|
// request.PatientIdentificationID = '';
|
||||||
|
// }
|
||||||
|
request.isRegister = false;
|
||||||
|
// this.authService.checkActivationCode(
|
||||||
|
// request,
|
||||||
|
// () => {
|
||||||
|
// //this.presentSMSPasswordDialog();
|
||||||
|
// this.smsModal.presentModal();
|
||||||
|
// }, this.ts.trPK('general', 'retry')).subscribe((result: CheckActivationCodeResponse) => {
|
||||||
|
// if (this.cs.validResponse(result)) {
|
||||||
|
// if (this.cs.hasData(result.List)) {
|
||||||
|
// this.smsService.stopSMSMonitoring();
|
||||||
|
// this.checkIfUserAgreedBefore(result);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private checkIfUserAgreedBefore(result: CheckActivationCodeResponse) {
|
||||||
|
|
||||||
|
this.authService.setAuthenticatedUser(result).subscribe(() => {
|
||||||
|
if (this.authService.isAgreedBefore()) {
|
||||||
|
this.cs.openHome();
|
||||||
|
} else {
|
||||||
|
this.cs.openAgreement();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkUserAgreement() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public signOut() {
|
||||||
|
// this.cs.presentConfirmDialog(this.ts.trPK('login', 'sign-out'),
|
||||||
|
// () => {
|
||||||
|
// this.authService.clearUser().subscribe(success => {
|
||||||
|
// this.id = null;
|
||||||
|
// if (this.countryCode) {
|
||||||
|
// this.internationlMobile.setMobileNumber(this.countryCode.code, null);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public openForgotID() {
|
||||||
|
this.cs.openUserForgot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public onDismiss()
|
||||||
|
{
|
||||||
|
// this.global_code = SMSService.code;
|
||||||
|
//this.checkActivationCode(this.global_code);
|
||||||
|
}
|
||||||
|
public onCancelled()
|
||||||
|
{
|
||||||
|
console.log("Modal pop up cancelled");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';
|
||||||
|
|
||||||
|
/*
|
||||||
|
default is to resuse except for one with destroy
|
||||||
|
*/
|
||||||
|
export class CustomReuseStrategy implements RouteReuseStrategy {
|
||||||
|
|
||||||
|
handlers: { [key: string]: DetachedRouteHandle } = {};
|
||||||
|
|
||||||
|
shouldDetach(route: ActivatedRouteSnapshot): boolean {
|
||||||
|
console.log('CustomReuseStrategy:shouldDetach', route);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
|
||||||
|
console.log('CustomReuseStrategy:store', route, handle);
|
||||||
|
this.handlers[route.routeConfig.path] = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldAttach(route: ActivatedRouteSnapshot): boolean {
|
||||||
|
console.log('CustomReuseStrategy:shouldAttach', route);
|
||||||
|
return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
|
||||||
|
}
|
||||||
|
|
||||||
|
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
|
||||||
|
console.log('CustomReuseStrategy:retrieve', route);
|
||||||
|
if (!route.routeConfig) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.handlers[route.routeConfig.path];
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
|
||||||
|
console.log('CustomReuseStrategy:shouldReuseRoute', future, curr);
|
||||||
|
return future.routeConfig === curr.routeConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { HmgCommonModule } from './hmg-common.module';
|
||||||
|
|
||||||
|
describe('HmgCommonModule', () => {
|
||||||
|
let hmgCommonModule: HmgCommonModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
hmgCommonModule = new HmgCommonModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(hmgCommonModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,248 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
import { Globalization } from '@ionic-native/globalization/ngx';
|
||||||
|
import { NumberRangeComponent } from './ui/number-range/number-range.component';
|
||||||
|
import { IonicModule } from '@ionic/angular';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { SSpacerComponent } from './ui/spacer/s-spacer/s-spacer.component';
|
||||||
|
import { MSpacerComponent } from './ui/spacer/m-spacer/m-spacer.component';
|
||||||
|
import { LSpacerComponent } from './ui/spacer/l-spacer/l-spacer.component';
|
||||||
|
import { ImagesSliderComponent } from './ui/images-slider/images-slider.component';
|
||||||
|
import { InfoDialogComponent } from './ui/info-dialog/info-dialog.component';
|
||||||
|
import { SelectComponent } from './ui/select/select.component';
|
||||||
|
import { ConnectorService } from './services/connector/connector.service';
|
||||||
|
import { TranslatorService } from './services/translator/translator.service';
|
||||||
|
import { FaceAvatarComponent } from './ui/face-avatar/face-avatar.component';
|
||||||
|
import { DividerComponent } from './ui/divider/divider.component';
|
||||||
|
import { NavButtonsComponent } from './ui/nav-buttons/nav-buttons.component';
|
||||||
|
import { SharedDataService } from './services/shared-data-service/shared-data.service';
|
||||||
|
import { TranslatePipe } from './pipes/translate/translate.pipe';
|
||||||
|
import { DatePipeTransform } from './pipes/date/date.pipe';
|
||||||
|
import { AlertControllerService } from './ui/alert/alert-controller.service';
|
||||||
|
import { DateTimePipe } from './pipes/date-time/date-time.pipe';
|
||||||
|
import { ThemeableBrowser } from '@ionic-native/themeable-browser/ngx';
|
||||||
|
import { LaunchNavigator } from '@ionic-native/launch-navigator/ngx';
|
||||||
|
import { SafeHtmlPipe } from './pipes/safe-html/safe-html.pipe';
|
||||||
|
import { BackButtonComponent } from './ui/back-button/back-button.component';
|
||||||
|
import { IfDatePipe } from './pipes/date/if-date.pipe';
|
||||||
|
import { DynamicTableComponent } from './ui/dynamic-table/dynamic-table.component';
|
||||||
|
import { EmptyFieldPipe } from './pipes/empty-field/empty-field.pipe';
|
||||||
|
import { TimePipe } from './pipes/time/time.pipe';
|
||||||
|
import { KeysPipe } from './pipes/keys/keys.pipe';
|
||||||
|
import { SegmentContentComponent } from './ui/segment-content/segment-content.component';
|
||||||
|
import { GraphComponent } from './ui/graph/graph.component';
|
||||||
|
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
||||||
|
import { ExpandableComponent } from './ui/expandable/expandable.component';
|
||||||
|
import { ProjectsService } from './services/projects/projects.service';
|
||||||
|
import { NationalityService } from './services/nationality/nationality.service';
|
||||||
|
import { FileUploaderComponent } from './ui/file-uploader/file-uploader.component';
|
||||||
|
import { Device } from '@ionic-native/device/ngx';
|
||||||
|
import { NativeStorage } from '@ionic-native/native-storage/ngx';
|
||||||
|
import { ProgressLoadingService } from './ui/progressLoading/progress-loading.service';
|
||||||
|
import { BarChartComponent } from './ui/bar-chart/bar-chart.component';
|
||||||
|
import { DonutChartComponent } from './ui/donut-chart/donut-chart.component';
|
||||||
|
import { UserLocalNotificationService } from './services/user-local-notification/user-local-notification.service';
|
||||||
|
import { LocalNotifications } from '@ionic-native/local-notifications/ngx';
|
||||||
|
import { EmailComponent } from './ui/email/email.component';
|
||||||
|
import { Badge } from '@ionic-native/badge/ngx';
|
||||||
|
import { Push } from '@ionic-native/push/ngx';
|
||||||
|
import { PushService } from './services/push/push.service';
|
||||||
|
import { LifeCycleService } from './services/life-cycle/life-cycle.service';
|
||||||
|
import { HmgBrowserService } from './services/hmg-browser/hmg-browser.service';
|
||||||
|
import { GuidService } from './services/guid/guid.service';
|
||||||
|
import { TabsBarComponent } from './ui/tabs-bar/tabs-bar.component';
|
||||||
|
import { PageTrailerComponent } from './ui/spacer/page-trailer/page-trailer.component';
|
||||||
|
import { GeofencingService } from './services/geofencing/geofencing.service';
|
||||||
|
import { BackgroundGeolocation } from '@ionic-native/background-geolocation/ngx';
|
||||||
|
import { ButtonComponent } from './ui/button/button.component';
|
||||||
|
import { ToolbarButtonComponent } from './ui/toolbar-button/toolbar-button.component';
|
||||||
|
import { ListboxModule } from 'primeng/listbox';
|
||||||
|
import { GenderSelectComponent } from './ui/gender-select/gender-select.component';
|
||||||
|
import { DateSelectComponent } from './ui/date-select/date-select.component';
|
||||||
|
import { ToggleButtonComponent } from './ui/toggle-button/toggle-button.component';
|
||||||
|
import { Footer } from 'primeng/components/common/shared';
|
||||||
|
import { FooterComponent } from './ui/footer/footer.component';
|
||||||
|
import { ScrollContentComponent } from './ui/scroll-content/scroll-content.component';
|
||||||
|
import { ScrollSegmentContentComponent } from './ui/scroll-segment-content/scroll-segment-content.component';
|
||||||
|
import { Keyboard } from '@ionic-native/keyboard/ngx';
|
||||||
|
import { KeyboardService } from './services/keyboard/keyboard.service';
|
||||||
|
import { DevicePermissionsService } from './services/device-permissions/device-permissions.service';
|
||||||
|
import { SegmentsComponent } from './ui/segments/segments.component';
|
||||||
|
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
|
||||||
|
import { AccordionComponent } from './ui/accordion/accordion.component';
|
||||||
|
import { AccordionTabComponent } from './ui/accordion/accordion-tab/accordion-tab.component';
|
||||||
|
import { TwoOptionSelectComponent } from './ui/two-option-select/two-option-select.component';
|
||||||
|
import { HMGPreloadingStrategyLoading } from './services/preloading-strategy/hmg-preloading-strategy-loading';
|
||||||
|
import { HMGPreloadingStrategy } from './services/preloading-strategy/hmg-preloading-strategy.1';
|
||||||
|
import { LazyLoadingService } from './services/lazy-loading/lazy-loading.service';
|
||||||
|
import { RefresherComponent } from './ui/refresher/refresher.component';
|
||||||
|
import { SendEmailComponent } from './ui/send-email/send-email.component';
|
||||||
|
import { EmptyDataComponent } from './ui/empty-data/empty-data.component';
|
||||||
|
import { Diagnostic } from '@ionic-native/diagnostic/ngx';
|
||||||
|
import { DetailButtonComponent } from './ui/detail-button/detail-button.component';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { HeaderButtonComponent } from './ui/header-button/header-button.component';
|
||||||
|
import { CallNumber } from '@ionic-native/call-number/ngx';
|
||||||
|
import { AppRate } from '@ionic-native/app-rate/ngx';
|
||||||
|
import { RatingService } from './services/rating/rating.service';
|
||||||
|
import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';
|
||||||
|
import { RateService } from './services/rate/rate.service';
|
||||||
|
import { PaymentComponent } from './ui/payment/payment.component';
|
||||||
|
import { PaymentService } from './ui/payment/service/payment.service';
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
FormsModule,
|
||||||
|
RouterModule,
|
||||||
|
IonicModule,
|
||||||
|
HttpClientModule,
|
||||||
|
NgxChartsModule,
|
||||||
|
ListboxModule
|
||||||
|
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
NumberRangeComponent,
|
||||||
|
SSpacerComponent,
|
||||||
|
MSpacerComponent,
|
||||||
|
LSpacerComponent,
|
||||||
|
ImagesSliderComponent,
|
||||||
|
InfoDialogComponent,
|
||||||
|
SelectComponent,
|
||||||
|
FaceAvatarComponent,
|
||||||
|
DividerComponent,
|
||||||
|
NavButtonsComponent,
|
||||||
|
TranslatePipe,
|
||||||
|
DatePipeTransform,
|
||||||
|
DateTimePipe,
|
||||||
|
SafeHtmlPipe,
|
||||||
|
BackButtonComponent,
|
||||||
|
IfDatePipe,
|
||||||
|
DynamicTableComponent,
|
||||||
|
EmptyFieldPipe,
|
||||||
|
TimePipe,
|
||||||
|
KeysPipe,
|
||||||
|
SegmentContentComponent,
|
||||||
|
GraphComponent,
|
||||||
|
ExpandableComponent,
|
||||||
|
FileUploaderComponent,
|
||||||
|
BarChartComponent,
|
||||||
|
DonutChartComponent,
|
||||||
|
EmailComponent,
|
||||||
|
TabsBarComponent,
|
||||||
|
PageTrailerComponent,
|
||||||
|
ButtonComponent,
|
||||||
|
ToolbarButtonComponent,
|
||||||
|
GenderSelectComponent,
|
||||||
|
DateSelectComponent,
|
||||||
|
ToggleButtonComponent,
|
||||||
|
ScrollContentComponent,
|
||||||
|
FooterComponent,
|
||||||
|
ScrollSegmentContentComponent,
|
||||||
|
SegmentsComponent,
|
||||||
|
SegmentsComponent,
|
||||||
|
AccordionComponent,
|
||||||
|
AccordionTabComponent,
|
||||||
|
TwoOptionSelectComponent,
|
||||||
|
RefresherComponent,
|
||||||
|
SendEmailComponent,
|
||||||
|
EmptyDataComponent,
|
||||||
|
DetailButtonComponent,
|
||||||
|
HeaderButtonComponent,
|
||||||
|
PaymentComponent
|
||||||
|
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
NumberRangeComponent,
|
||||||
|
SSpacerComponent,
|
||||||
|
MSpacerComponent,
|
||||||
|
LSpacerComponent,
|
||||||
|
ImagesSliderComponent,
|
||||||
|
InfoDialogComponent,
|
||||||
|
SelectComponent,
|
||||||
|
FaceAvatarComponent,
|
||||||
|
DividerComponent,
|
||||||
|
NavButtonsComponent,
|
||||||
|
DatePipeTransform,
|
||||||
|
TranslatePipe,
|
||||||
|
DateTimePipe,
|
||||||
|
SafeHtmlPipe,
|
||||||
|
IfDatePipe,
|
||||||
|
DynamicTableComponent,
|
||||||
|
EmptyFieldPipe,
|
||||||
|
TimePipe,
|
||||||
|
KeysPipe,
|
||||||
|
SegmentContentComponent,
|
||||||
|
GraphComponent,
|
||||||
|
FileUploaderComponent,
|
||||||
|
BarChartComponent,
|
||||||
|
DonutChartComponent,
|
||||||
|
EmailComponent,
|
||||||
|
TabsBarComponent,
|
||||||
|
PageTrailerComponent,
|
||||||
|
ButtonComponent,
|
||||||
|
ToolbarButtonComponent,
|
||||||
|
GenderSelectComponent,
|
||||||
|
DateSelectComponent,
|
||||||
|
ToggleButtonComponent,
|
||||||
|
ScrollContentComponent,
|
||||||
|
FooterComponent,
|
||||||
|
ScrollSegmentContentComponent,
|
||||||
|
SegmentsComponent,
|
||||||
|
AccordionComponent,
|
||||||
|
AccordionTabComponent,
|
||||||
|
TwoOptionSelectComponent,
|
||||||
|
RefresherComponent,
|
||||||
|
SendEmailComponent,
|
||||||
|
EmptyDataComponent,
|
||||||
|
DetailButtonComponent,
|
||||||
|
HeaderButtonComponent,
|
||||||
|
PaymentComponent
|
||||||
|
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
ConnectorService,
|
||||||
|
TranslatorService,
|
||||||
|
Globalization,
|
||||||
|
SharedDataService,
|
||||||
|
AlertControllerService,
|
||||||
|
ThemeableBrowser,
|
||||||
|
LaunchNavigator,
|
||||||
|
ProjectsService,
|
||||||
|
NationalityService,
|
||||||
|
Device,
|
||||||
|
NativeStorage,
|
||||||
|
ProgressLoadingService,
|
||||||
|
PushService,
|
||||||
|
UserLocalNotificationService,
|
||||||
|
LocalNotifications,
|
||||||
|
Badge,
|
||||||
|
Push,
|
||||||
|
LifeCycleService,
|
||||||
|
HmgBrowserService,
|
||||||
|
GuidService,
|
||||||
|
BackgroundGeolocation,
|
||||||
|
GeofencingService,
|
||||||
|
Keyboard,
|
||||||
|
KeyboardService,
|
||||||
|
Diagnostic,
|
||||||
|
DevicePermissionsService,
|
||||||
|
BarcodeScanner,
|
||||||
|
LazyLoadingService,
|
||||||
|
HMGPreloadingStrategy,
|
||||||
|
HMGPreloadingStrategyLoading,
|
||||||
|
Diagnostic,
|
||||||
|
CallNumber,
|
||||||
|
AppRate,
|
||||||
|
RatingService,
|
||||||
|
InAppBrowser,
|
||||||
|
RateService,
|
||||||
|
PaymentService
|
||||||
|
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class HmgCommonModule { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { DateTimePipe } from './date-time.pipe';
|
||||||
|
|
||||||
|
describe('DateTimePipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new DateTimePipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { CommonService } from '../../services/common/common.service';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'dateTime'
|
||||||
|
})
|
||||||
|
export class DateTimePipe implements PipeTransform {
|
||||||
|
constructor(
|
||||||
|
public cs: CommonService
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
transform(value: any, args?: any): any {
|
||||||
|
if (value) {
|
||||||
|
return this.cs.evaluteDate(value, true);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public evaluteDate(dateStr: string): string {
|
||||||
|
const utc = parseInt(dateStr.substring(6, dateStr.length - 2), 10);
|
||||||
|
const appoDate = new Date(utc);
|
||||||
|
return appoDate.toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { DatePipe } from './date.pipe';
|
||||||
|
|
||||||
|
describe('DatePipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new DatePipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { CommonService } from '../../services/common/common.service';
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'date'
|
||||||
|
})
|
||||||
|
|
||||||
|
export class DatePipeTransform implements PipeTransform {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public cs: CommonService
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
transform(value: any, args?: any): any {
|
||||||
|
if (value) {
|
||||||
|
return this.cs.evaluteDate(value);
|
||||||
|
// return super.transform(value, 'dd/MMM/yyyy');
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { IfDatePipe } from './if-date.pipe';
|
||||||
|
|
||||||
|
describe('IfDatePipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new IfDatePipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'ifDate'
|
||||||
|
})
|
||||||
|
export class IfDatePipe implements PipeTransform {
|
||||||
|
|
||||||
|
transform(value: any, args?: any): any {
|
||||||
|
if (value) {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
return this.evaluteDate(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public evaluteDate(str: string): string {
|
||||||
|
const isDate = str.substring(1, 5);
|
||||||
|
if (isDate && (isDate.toLocaleLowerCase() === 'date')) {
|
||||||
|
const utc = parseInt(str.substring(6, str.length - 2), 10);
|
||||||
|
const appoDate = new Date(utc);
|
||||||
|
return appoDate.toLocaleDateString();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { EmptyFieldPipe } from './empty-field.pipe';
|
||||||
|
|
||||||
|
describe('EmptyFieldPipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new EmptyFieldPipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'emptyField'
|
||||||
|
})
|
||||||
|
export class EmptyFieldPipe implements PipeTransform {
|
||||||
|
|
||||||
|
transform(value: any, args?: any): any {
|
||||||
|
return value ? value : '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { KeysPipe } from './keys.pipe';
|
||||||
|
|
||||||
|
describe('KeysPipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new KeysPipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { CommonService } from '../../services/common/common.service';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'keys'
|
||||||
|
})
|
||||||
|
export class KeysPipe implements PipeTransform {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public cs: CommonService
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
transform(obj: any, args?: any): any[] {
|
||||||
|
return this.cs.keysInObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { SafeHtmlPipe } from './safe-html.pipe';
|
||||||
|
|
||||||
|
describe('SafeHtmlPipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new SafeHtmlPipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { DomSanitizer } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'safeHtml'
|
||||||
|
})
|
||||||
|
export class SafeHtmlPipe implements PipeTransform {
|
||||||
|
|
||||||
|
constructor(private sanitizer: DomSanitizer) { }
|
||||||
|
|
||||||
|
transform(html, sanitize: any = true) {
|
||||||
|
if (sanitize) {
|
||||||
|
html = html.replace(new RegExp('\n', 'g'), '<br>');
|
||||||
|
return this.sanitizer.bypassSecurityTrustHtml(html);
|
||||||
|
} else {
|
||||||
|
return html.replace(new RegExp('\n', 'g'), '<br>');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { TimePipe } from './time.pipe';
|
||||||
|
|
||||||
|
describe('TimePipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new TimePipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import { Pipe, PipeTransform } from "@angular/core";
|
||||||
|
import { CommonService } from "../../services/common/common.service";
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: "time"
|
||||||
|
})
|
||||||
|
export class TimePipe implements PipeTransform {
|
||||||
|
constructor(public cs: CommonService) { }
|
||||||
|
|
||||||
|
transform(value: any): any {
|
||||||
|
if (value) {
|
||||||
|
const dateTime = this.cs.evaluteDateAsObject(value);
|
||||||
|
return this.cs.localizeTime(dateTime);
|
||||||
|
// return this.evaluteTime(value);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public evaluteTime(dateStr: string): string {
|
||||||
|
const utc = parseInt(dateStr.substring(6, dateStr.length - 2), 10);
|
||||||
|
const appoDate = new Date(utc);
|
||||||
|
return appoDate.toLocaleTimeString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { TranslatePipe } from './translate.pipe';
|
||||||
|
|
||||||
|
describe('TranslatePipe', () => {
|
||||||
|
it('create an instance', () => {
|
||||||
|
const pipe = new TranslatePipe();
|
||||||
|
expect(pipe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
import { TranslatorService } from '../../services/translator/translator.service';
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: 'translate'
|
||||||
|
})
|
||||||
|
export class TranslatePipe implements PipeTransform {
|
||||||
|
|
||||||
|
constructor(public translator: TranslatorService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
transform(value: string, arg1?: any): any {
|
||||||
|
if (value) {
|
||||||
|
return this.translator.trInline(value);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthenticationService } from './authentication.service';
|
||||||
|
|
||||||
|
describe('AuthenticationService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: AuthenticationService = TestBed.get(AuthenticationService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,614 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Request } from '../models/request';
|
||||||
|
import { TranslatorService } from '../translator/translator.service';
|
||||||
|
import { ConnectorService } from '../connector/connector.service';
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { CheckPatientRegisterationRequest } from './models/check-patient-registeration.request';
|
||||||
|
import { LoginRequest } from './models/login.request';
|
||||||
|
import { Response } from '../models/response';
|
||||||
|
import { AuthenticatedUser } from './models/authenticated-user';
|
||||||
|
import { CommonService } from '../common/common.service';
|
||||||
|
import { CheckUserAuthenticationRequest } from './models/check-user-auth.request';
|
||||||
|
import { CheckActivationCodeRequest } from './models/check-activation-code.request';
|
||||||
|
import { CheckUserAuthenticationResponse } from './models/check-user-auth.response';
|
||||||
|
import { CheckActivationCodeResponse } from './models/check-activation-code.response';
|
||||||
|
import { NativeStorage } from '@ionic-native/native-storage/ngx';
|
||||||
|
import { CheckRegisterationCodeRequest } from './models/check-registeration-code.request';
|
||||||
|
import { RegisterInformationRequest } from './models/register-information.request';
|
||||||
|
import { ForgotFileIDResponse } from './models/forgot-File-ID.response';
|
||||||
|
import { EmailRequest } from '../models/email-request';
|
||||||
|
import { EmailInput } from '../../ui/email/models/email-input';
|
||||||
|
import { UserLocalNotificationService } from '../user-local-notification/user-local-notification.service';
|
||||||
|
import { GetLoginInfoRequest } from './models/get-login-info.request';
|
||||||
|
import { GetLoginInfoResponse } from './models/get-login-info.response';
|
||||||
|
import { analyzeAndValidateNgModules } from '@angular/compiler';
|
||||||
|
import { Events } from '@ionic/angular';
|
||||||
|
import { InternationalMobileComponent } from '../../ui/mobile-number/international-mobile/international-mobile.component';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class AuthenticationService {
|
||||||
|
|
||||||
|
|
||||||
|
public static MOBILE_USER = 102;
|
||||||
|
|
||||||
|
/* login methods */
|
||||||
|
public static loginURL = 'Services/Authentication.svc/REST/CheckPatientAuthentication';
|
||||||
|
public static checkUserAuthURL = 'Services/Authentication.svc/REST/CheckPatientAuthentication';
|
||||||
|
public static activationCodeURL = 'Services/Authentication.svc/REST/CheckActivationCode';
|
||||||
|
public static getLoginInfoURL = 'Services/Authentication.svc/REST/GetMobileLoginInfo';
|
||||||
|
|
||||||
|
/* register methods */
|
||||||
|
|
||||||
|
public static checkPatientForRegisterationURL = 'Services/Authentication.svc/REST/CheckPatientForRegisteration';
|
||||||
|
public static sendSmsForRegisterURL = 'Services/Authentication.svc/REST/SendSMSForPatientRegisteration';
|
||||||
|
public static registerTempUserURL = 'Services/Authentication.svc/REST/RegisterTempPatientWithoutSMS';
|
||||||
|
|
||||||
|
public static sendSMSForgotFileNoURL = 'Services/Authentication.svc/REST/SendPatientIDSMSByMobileNumber';
|
||||||
|
public static forgotFileIDURL = 'Services/Authentication.svc/REST/CheckActivationCodeForSendFileNo';
|
||||||
|
public static user: AuthenticatedUser;
|
||||||
|
|
||||||
|
public static LOGIN_EVENT = 'user-login-event';
|
||||||
|
public static FAMILY_LOGIN_EVENT = 'family-login-event';
|
||||||
|
public static AUTHENTICATED_USER_KEY = 'save-authenticated-user';
|
||||||
|
|
||||||
|
// private static user: AuthenticatedUser;
|
||||||
|
constructor(
|
||||||
|
public con: ConnectorService,
|
||||||
|
public cs: CommonService,
|
||||||
|
public ts: TranslatorService,
|
||||||
|
public nativeStorage: NativeStorage,
|
||||||
|
public localNotifications: UserLocalNotificationService,
|
||||||
|
private events: Events
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public authenticateRequest(request: Request, automaticLogin = true): Request {
|
||||||
|
|
||||||
|
this.setPublicFields(request);
|
||||||
|
const user = this.getAuthenticatedUser();
|
||||||
|
if (user) {
|
||||||
|
/*user with eye prescriptions*/
|
||||||
|
request.PatientID = user.PatientID;
|
||||||
|
request.TokenID = user.TokenID;
|
||||||
|
request.PatientOutSA = user.PatientOutSA ? 1 : 0;
|
||||||
|
request.PatientTypeID = user.PatientTypeID;
|
||||||
|
if (AuthenticationService.requireRelogin) {
|
||||||
|
this.sessionTimeOutDialog();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.cs.userNeedToReLogin();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else {
|
||||||
|
if (automaticLogin) {
|
||||||
|
this.cs.openUserLogin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPublicFields(request: Request): Request {
|
||||||
|
request.VersionID = 3.6;
|
||||||
|
request.Channel = 3;
|
||||||
|
request.LanguageID = TranslatorService.getCurrentLanguageCode();
|
||||||
|
request.IPAdress = '10.10.10.10';
|
||||||
|
request.SessionID = 'any thing'; // ??? required for not authorized login funny
|
||||||
|
request.isDentalAllowedBackend = false;
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
public authenticateAndSetPersonalInformation(request: EmailRequest, examinationInfo?: any): EmailRequest {
|
||||||
|
// if not authenticated will be redirected to login
|
||||||
|
this.authenticateRequest(request);
|
||||||
|
const user = this.getAuthenticatedUser();
|
||||||
|
if (user) {
|
||||||
|
request.To = user.Email;
|
||||||
|
request.DateofBirth = user.DateofBirth;
|
||||||
|
request.PatientIditificationNum = user.PatientIdentificationNo;
|
||||||
|
request.PatientMobileNumber = user.MobileNo;
|
||||||
|
request.PatientName = user.PatientName;
|
||||||
|
request.PatientOutSA = user.PatientOutSA ? 1 : 0;
|
||||||
|
request.PatientTypeID = user.PatientTypeID;
|
||||||
|
|
||||||
|
if (examinationInfo) {
|
||||||
|
if (examinationInfo.SetupID) { request.SetupID = examinationInfo.SetupID; }
|
||||||
|
if (examinationInfo.ProjectName) { request.ProjectName = examinationInfo.ProjectName; }
|
||||||
|
if (examinationInfo.ClinicName) { request.ClinicName = examinationInfo.ClinicDescription; }
|
||||||
|
if (examinationInfo.DoctorName) { request.DoctorName = examinationInfo.DoctorName; }
|
||||||
|
if (examinationInfo.ProjectID) { request.ProjectID = examinationInfo.ProjectID; }
|
||||||
|
if (examinationInfo.InvoiceNo) { request.InvoiceNo = examinationInfo.InvoiceNo; }
|
||||||
|
if (examinationInfo.OrderDate) {
|
||||||
|
request.OrderDate = this.cs.getDateISO(this.cs.evaluteDateAsObject(examinationInfo.OrderDate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public getAuthenticatedRequest(login = true): Request {
|
||||||
|
const request = new Request();
|
||||||
|
this.authenticateRequest(request, login);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public getPublicRequest(): Request {
|
||||||
|
const request = new Request();
|
||||||
|
this.setPublicFields(request);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public login(request: LoginRequest, onError: any, errorLabel: string): Observable<Response> {
|
||||||
|
request.PatientID = 0;
|
||||||
|
request.TokenID = '';
|
||||||
|
request.isDentalAllowedBackend = false;
|
||||||
|
request.isRegister = false;
|
||||||
|
return this.con.post(AuthenticationService.loginURL, request, onError, errorLabel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public isAuthenticated(): boolean {
|
||||||
|
return AuthenticationService.user != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isAuthenticatedFamilyMember(): boolean {
|
||||||
|
if ( AuthenticationService.user != null ) {
|
||||||
|
return AuthenticationService.user.familyMember;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this fucntion load from user information if he logged in before
|
||||||
|
* and save user into memory and local storage
|
||||||
|
* disable notifications for previous user if new user logged in with different user
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* info:
|
||||||
|
* 1- user stored in local storage without token
|
||||||
|
* @param result check activation code result
|
||||||
|
*/
|
||||||
|
public setAuthenticatedUser(result: CheckActivationCodeResponse): Observable<boolean> {
|
||||||
|
|
||||||
|
return Observable.create(observer => {
|
||||||
|
this.loadAuthenticatedUser().subscribe((loadedUser: AuthenticatedUser) => {
|
||||||
|
AuthenticationService.requireRelogin = false;
|
||||||
|
this.startIdleMonitoring();
|
||||||
|
const user = this.updateAuthenticatedUser(result, loadedUser);
|
||||||
|
/* we store in hd without token but with token in memory*/
|
||||||
|
this.saveUserInStorage(user).subscribe((success: boolean) => {
|
||||||
|
AuthenticationService.user = user;
|
||||||
|
this.publishUserChangeEvent();
|
||||||
|
observer.next(true);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetAuthenticatedUser(user: AuthenticatedUser ) {
|
||||||
|
AuthenticationService.user = user;
|
||||||
|
AuthenticationService.requireRelogin = false;
|
||||||
|
this.startIdleMonitoring();
|
||||||
|
this.publishUserChangeEvent();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public setAuthenticatedMemberFamilyUser(result: CheckActivationCodeResponse) {
|
||||||
|
|
||||||
|
const authUser = new AuthenticatedUser();
|
||||||
|
AuthenticationService.requireRelogin = false;
|
||||||
|
this.startIdleMonitoring();
|
||||||
|
const user = this.updateAuthenticatedUser(result, authUser);
|
||||||
|
user["familyMember"] = true;
|
||||||
|
user.familyMember = true;
|
||||||
|
// user["hello"]= "ok";
|
||||||
|
/* we store in hd without token but with token in memory*/
|
||||||
|
AuthenticationService.user = user;
|
||||||
|
this.publishFamilyMemeberUserChangeEvent();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public updateLoggedInUser(newUser: AuthenticatedUser): Observable<boolean> {
|
||||||
|
return Observable.create(observer => {
|
||||||
|
/* we store in hd without token but with token in memory*/
|
||||||
|
this.saveUserInStorage(newUser).subscribe((success: boolean) => {
|
||||||
|
AuthenticationService.requireRelogin = false;
|
||||||
|
AuthenticationService.user = newUser;
|
||||||
|
this.publishUserChangeEvent();
|
||||||
|
observer.next(success);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public setDeviceToken(token: string) {
|
||||||
|
const user = this.getAuthenticatedUser();
|
||||||
|
if (user) {
|
||||||
|
user.deviceToken = token;
|
||||||
|
this.updateLoggedInUser(user).subscribe((success: boolean) => {
|
||||||
|
// console.log('token stored:' + token);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public registerTempUser(request: RegisterInformationRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<CheckActivationCodeResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
return this.con.post(AuthenticationService.registerTempUserURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getLoginInfo(request: GetLoginInfoRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<GetLoginInfoResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
return this.con.post(AuthenticationService.getLoginInfoURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*update new authenticated user from previously stored and loaded user
|
||||||
|
*/
|
||||||
|
private updateAuthenticatedUser(result: CheckActivationCodeResponse, loadedUser: AuthenticatedUser): AuthenticatedUser {
|
||||||
|
const user = result.List[0];
|
||||||
|
if (loadedUser) {
|
||||||
|
// only if same user we fetch previous settings
|
||||||
|
if (loadedUser.PatientID === user.PatientID) {
|
||||||
|
user.agreed = loadedUser.agreed;
|
||||||
|
user.biometricEnabled = loadedUser.biometricEnabled;
|
||||||
|
} else {
|
||||||
|
this.localNotifications.deleteAllNotifications();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (user.FirstName && user.LastName) {
|
||||||
|
user.PatientName = user.FirstName + ' ' + user.LastName;
|
||||||
|
}
|
||||||
|
user.IdentificationNo = user.PatientIdentificationNo;
|
||||||
|
/*
|
||||||
|
since suliman al habib has no support now for international phone number we do this woraround
|
||||||
|
*/
|
||||||
|
if (user.PatientOutSA) {
|
||||||
|
user.ZipCode = InternationalMobileComponent.EMIRATE_DIAL_CODE;
|
||||||
|
} else {
|
||||||
|
user.ZipCode = InternationalMobileComponent.SAUDI_DIAL_CODE;
|
||||||
|
}
|
||||||
|
user.Email = this.isRealEmail(user.EmailAddress) ? user.EmailAddress : null;
|
||||||
|
|
||||||
|
user.MobileNumber = user.MobileNumber.substr(1, user.MobileNumber.length - 1);
|
||||||
|
user.MobileNo = user.MobileNumber;
|
||||||
|
user.PatientOutSA = result.PatientOutSA;
|
||||||
|
user.PatientTypeID = result.PatientType;
|
||||||
|
user.TokenID = result.AuthenticationTokenID;
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isRealEmail(email: string): boolean {
|
||||||
|
return EmailInput.isValidEmail(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
public isAuthenticatedUserHasRealEmail(): boolean {
|
||||||
|
const user = this.getAuthenticatedUser();
|
||||||
|
return user ? this.isRealEmail(user.Email) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setUserAgreed(agreed: boolean) {
|
||||||
|
const user = this.getAuthenticatedUser();
|
||||||
|
if (user) {
|
||||||
|
user.agreed = agreed;
|
||||||
|
// user['agreed'] = agreed;
|
||||||
|
this.saveUserInStorage(user).subscribe(result => {
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public isAgreedBefore(): boolean {
|
||||||
|
const user = this.getAuthenticatedUser();
|
||||||
|
if (user) {
|
||||||
|
return (user.agreed != null) ? user.agreed : false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* we store in localstorage without token but we keep it in the static member
|
||||||
|
*/
|
||||||
|
private saveUserInStorage(user: AuthenticatedUser): Observable<boolean> {
|
||||||
|
|
||||||
|
return Observable.create(observer => {
|
||||||
|
if (user) {
|
||||||
|
const TokenID = user.TokenID;
|
||||||
|
user.TokenID = null;
|
||||||
|
this.nativeStorage.setItem(AuthenticationService.AUTHENTICATED_USER_KEY, user)
|
||||||
|
.then(
|
||||||
|
() => {
|
||||||
|
user.TokenID = TokenID;
|
||||||
|
observer.next(true);
|
||||||
|
observer.complete();
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
user.TokenID = TokenID;
|
||||||
|
|
||||||
|
observer.next(false);
|
||||||
|
observer.complete();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
observer.next(false);
|
||||||
|
observer.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* signout
|
||||||
|
*clear user session and storage information
|
||||||
|
*/
|
||||||
|
public clearUser(): Observable<boolean> {
|
||||||
|
this.clearUserSession();
|
||||||
|
return Observable.create(observer => {
|
||||||
|
this.publishUserChangeEvent();
|
||||||
|
this.nativeStorage.remove(AuthenticationService.AUTHENTICATED_USER_KEY).then(
|
||||||
|
() => {
|
||||||
|
observer.next(true);
|
||||||
|
observer.complete();
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
observer.next(false);
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private publishUserChangeEvent() {
|
||||||
|
this.events.publish(AuthenticationService.LOGIN_EVENT, this.getAuthenticatedUser(), Date.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
private publishFamilyMemeberUserChangeEvent() {
|
||||||
|
this.events.publish(AuthenticationService.FAMILY_LOGIN_EVENT, this.getAuthenticatedUser(), Date.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
public clearUserSession() {
|
||||||
|
AuthenticationService.user = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadAuthenticatedUser(): Observable<AuthenticatedUser> {
|
||||||
|
return Observable.create(observer => {
|
||||||
|
|
||||||
|
this.nativeStorage.getItem(AuthenticationService.AUTHENTICATED_USER_KEY)
|
||||||
|
.then(
|
||||||
|
(user) => {
|
||||||
|
observer.next(user);
|
||||||
|
observer.complete();
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
observer.next(null);
|
||||||
|
observer.complete();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// TODO you should read from local storage and update static member
|
||||||
|
public getAuthenticatedUser(): AuthenticatedUser {
|
||||||
|
/*
|
||||||
|
if (AuthenticationService.requireRelogin) {
|
||||||
|
this.sessionTimeOutDialog();
|
||||||
|
return new AuthenticatedUser();
|
||||||
|
} else {
|
||||||
|
return AuthenticationService.user;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return AuthenticationService.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public checkUserAuthentication(request: CheckUserAuthenticationRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<CheckUserAuthenticationResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
return this.con.post(AuthenticationService.checkUserAuthURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkActivationCode(request: CheckActivationCodeRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<CheckActivationCodeResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
return this.con.post(AuthenticationService.activationCodeURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
client side:
|
||||||
|
id no , mobile no , zip code
|
||||||
|
*/
|
||||||
|
public checkPatientForRegisteration(request: CheckPatientRegisterationRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<Response> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
request.PatientID = 0;
|
||||||
|
request.isRegister = false;
|
||||||
|
return this.con.post(AuthenticationService.checkPatientForRegisterationURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
client side:
|
||||||
|
id no , mobile no , zip code
|
||||||
|
*/
|
||||||
|
public sendSmsForPatientRegisteration(request: CheckPatientRegisterationRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<CheckUserAuthenticationResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
request.PatientID = 0;
|
||||||
|
request.isRegister = false;
|
||||||
|
return this.con.post(AuthenticationService.sendSmsForRegisterURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public checkRegisterationActivationCode(request: CheckRegisterationCodeRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<Response> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
return this.con.post(AuthenticationService.activationCodeURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sendSMSForForgotFileNumber(request: CheckUserAuthenticationRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<CheckUserAuthenticationResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
request.PatientIdentificationID = '';
|
||||||
|
request.PatientID = 0;
|
||||||
|
request.SearchType = 2;
|
||||||
|
request.isRegister = false;
|
||||||
|
return this.con.post(AuthenticationService.sendSMSForgotFileNoURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public forgotFileIdActivation(request: CheckActivationCodeRequest, onError: any, errorLabel: string)
|
||||||
|
: Observable<ForgotFileIDResponse> {
|
||||||
|
this.setPublicFields(request);
|
||||||
|
request.TokenID = '';
|
||||||
|
request.PatientIdentificationID = '';
|
||||||
|
request.PatientID = 0;
|
||||||
|
request.SearchType = 2;
|
||||||
|
request.isRegister = false;
|
||||||
|
return this.con.post(AuthenticationService.forgotFileIDURL, request, onError, errorLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public isSAUDIIDValid(id: string): boolean {
|
||||||
|
if (!id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
id = id.toString();
|
||||||
|
id = id.trim();
|
||||||
|
const returnValue = Number(id);
|
||||||
|
let sum = 0;
|
||||||
|
if (returnValue > 0) {
|
||||||
|
const type = Number(id.charAt(0));
|
||||||
|
|
||||||
|
if (id.length !== 10) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type !== 2 && type !== 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
if ((i % 2) === 0) {
|
||||||
|
const a = id.charAt(i);
|
||||||
|
const x = Number(a) * 2;
|
||||||
|
let b = x.toString();
|
||||||
|
if (b.length === 1) {
|
||||||
|
b = '0' + b;
|
||||||
|
}
|
||||||
|
sum += Number(b.charAt(0)) + Number(b.charAt(1));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sum += Number(id.charAt(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ((sum % 10) === 0);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public checkUserHasEmailDialog(): Observable<void> {
|
||||||
|
|
||||||
|
return Observable.create(observer => {
|
||||||
|
if (this.isAuthenticatedUserHasRealEmail()) {
|
||||||
|
const message = this.ts.trPK('general', 'send-email')
|
||||||
|
.replace('[0]', this.getAuthenticatedUser().EmailAddress || this.getAuthenticatedUser().Email);
|
||||||
|
this.cs.presentConfirmDialog(message,
|
||||||
|
() => {
|
||||||
|
observer.next();
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.cs.presentConfirmDialog(this.ts.trPK('login', 'enter-email'),
|
||||||
|
() => {
|
||||||
|
this.cs.openPatientProfile();
|
||||||
|
observer.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
user session timeout after idle for 20 Minute
|
||||||
|
*/
|
||||||
|
private static requireRelogin = false;
|
||||||
|
public static monitorInterval_M = 20 * 60 * 1000;
|
||||||
|
// public static monitorInterval_M = 15 * 1000;
|
||||||
|
private static timerID;
|
||||||
|
|
||||||
|
private stopIdleTimer() {
|
||||||
|
if (AuthenticationService.timerID) {
|
||||||
|
clearTimeout(AuthenticationService.timerID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sessionTimeOutDialog() {
|
||||||
|
this.cs.presentConfirmDialog(this.ts.trPK('general', 'idle-relogin'), () => {
|
||||||
|
this.cs.openUserLogin();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
reset and start idling interval
|
||||||
|
*/
|
||||||
|
private detectIdle() {
|
||||||
|
this.stopIdleTimer();
|
||||||
|
AuthenticationService.timerID = setTimeout(() => {
|
||||||
|
if (AuthenticationService.user) {
|
||||||
|
AuthenticationService.requireRelogin = true;
|
||||||
|
this.clearUserSession();
|
||||||
|
this.publishUserChangeEvent();
|
||||||
|
this.sessionTimeOutDialog();
|
||||||
|
this.cs.openHome();
|
||||||
|
}
|
||||||
|
}, AuthenticationService.monitorInterval_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerDocumentEvents(events: string[], handler: any) {
|
||||||
|
for (const event of events) {
|
||||||
|
document.addEventListener(event, handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static eventsRegistered = false;
|
||||||
|
public startIdleMonitoring() {
|
||||||
|
if (!AuthenticationService.eventsRegistered) {
|
||||||
|
AuthenticationService.eventsRegistered = true;
|
||||||
|
// every time we have and event
|
||||||
|
this.registerDocumentEvents(['mousedown', 'touchstart', 'click', 'keyup'], () => {
|
||||||
|
// if user still logged in and session not expired
|
||||||
|
if (AuthenticationService.user && !AuthenticationService.requireRelogin) {
|
||||||
|
// reset and start idling timer
|
||||||
|
this.detectIdle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
export class PatientUserModel {
|
||||||
|
Address: string;
|
||||||
|
Age: number;
|
||||||
|
BloodGroup: string;
|
||||||
|
CreatedBy: number;
|
||||||
|
DHCCPatientRefID: string;
|
||||||
|
DateofBirth: string;
|
||||||
|
EmailAddress: string;
|
||||||
|
EmergencyContactName: string;
|
||||||
|
EmergencyContactNo: string;
|
||||||
|
EmployeeID: string;
|
||||||
|
ExpiryDate: string;
|
||||||
|
FaxNumber: string;
|
||||||
|
FirstName: string;
|
||||||
|
FirstNameN: string;
|
||||||
|
Gender: number;
|
||||||
|
GenderDescription: string;
|
||||||
|
IsEmailAlertRequired: boolean;
|
||||||
|
IsHmgEmployee: boolean;
|
||||||
|
IsSMSAlertRequired: boolean;
|
||||||
|
LastName: string;
|
||||||
|
LastNameN: string;
|
||||||
|
MemberID: string;
|
||||||
|
MiddleName: string;
|
||||||
|
MiddleNameN: string;
|
||||||
|
MobileNumber: string;
|
||||||
|
NationalityID: string;
|
||||||
|
OutSA: number;
|
||||||
|
POBox: string;
|
||||||
|
PatientID: number;
|
||||||
|
PatientIdentificationNo: string;
|
||||||
|
PatientIdentificationType: number;
|
||||||
|
PatientPayType: number;
|
||||||
|
PatientType: number;
|
||||||
|
PhoneOffice: string;
|
||||||
|
PhoneResi: string;
|
||||||
|
PreferredLanguage: string;
|
||||||
|
ProjectID: number;
|
||||||
|
RHFactor: any;
|
||||||
|
ReceiveHealthSummaryReport: boolean;
|
||||||
|
RelationshipID: number;
|
||||||
|
SetupID: string;
|
||||||
|
Status: number;
|
||||||
|
ZipCode: string;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { PatientUserModel } from './PatientUserModel';
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
export class AuthenticatedUser extends PatientUserModel {
|
||||||
|
PatientName: string;
|
||||||
|
TokenID: string;
|
||||||
|
MobileNo: string;
|
||||||
|
Email: string;
|
||||||
|
PatientOutSA: boolean;
|
||||||
|
PatientTypeID: number;
|
||||||
|
agreed: boolean;
|
||||||
|
IdentificationNo: string;
|
||||||
|
deviceToken: string;
|
||||||
|
biometricEnabled: boolean;
|
||||||
|
ProjectID: number;
|
||||||
|
familyMember: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
|
||||||
|
export class CheckActivationCodeRequest extends Request {
|
||||||
|
FingerPrintPatientIdentificationID?: string ; // ""
|
||||||
|
IsMobileFingerPrint?: boolean; // false
|
||||||
|
ForRegisteration?: boolean;
|
||||||
|
LogInTokenID: string ; // null if not exist
|
||||||
|
PatientIdentificationID: string ;
|
||||||
|
PatientMobileNumber: string;
|
||||||
|
SearchType?: number ; // 1 for id , 2 for file no
|
||||||
|
activationCode: string ; // "0000" if sms activation is not required
|
||||||
|
isRegister: boolean;
|
||||||
|
ZipCode: string;
|
||||||
|
IsSilentLogin: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { Response } from '../../models/response';
|
||||||
|
import { PatientUserModel } from './PatientUserModel';
|
||||||
|
import { AuthenticatedUser } from './authenticated-user';
|
||||||
|
|
||||||
|
export class CheckActivationCodeResponse extends Response {
|
||||||
|
List: AuthenticatedUser[];
|
||||||
|
AuthenticationTokenID: string;
|
||||||
|
PatientOutSA: boolean;
|
||||||
|
PatientType: number;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
|
||||||
|
export class CheckPatientRegisterationRequest extends Request {
|
||||||
|
PatientIdentificationID: string; // "iqama"
|
||||||
|
PatientMobileNumber: string; // "phone without start 0"
|
||||||
|
TokenID: string; // should be empty ""
|
||||||
|
ZipCode: string; // "966 or 971"
|
||||||
|
isRegister: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
|
||||||
|
export class CheckRegisterationCodeRequest extends Request {
|
||||||
|
ForRegisteration: boolean;
|
||||||
|
LogInTokenID: string; // null if not exist
|
||||||
|
PatientIdentificationID: string;
|
||||||
|
PatientMobileNumber: string;
|
||||||
|
SearchType: number; // 1 for id , 2 for file no
|
||||||
|
activationCode: string; // "0000" if sms activation is not required
|
||||||
|
isRegister: boolean;
|
||||||
|
ZipCode: string;
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
|
||||||
|
export class CheckUserAuthenticationRequest extends Request {
|
||||||
|
PatientIdentificationID: string; // id
|
||||||
|
PatientMobileNumber: string; // phone number
|
||||||
|
ZipCode: string;
|
||||||
|
SearchType: number; // 1 for id , 2 for file no
|
||||||
|
isRegister: boolean; // false
|
||||||
|
LogInTokenID?: string;
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
import { Response } from '../../models/response';
|
||||||
|
|
||||||
|
export class CheckUserAuthenticationResponse extends Response {
|
||||||
|
PatientHasFile: boolean;
|
||||||
|
PatientOutSA: boolean;
|
||||||
|
PatientType: number;
|
||||||
|
ProjectIDOut: number;
|
||||||
|
SMSLoginRequired: boolean;
|
||||||
|
VerificationCode: string;
|
||||||
|
hasFile: boolean;
|
||||||
|
isSMSSent: boolean;
|
||||||
|
LogInTokenID: string;
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
import { Response } from '../../models/response';
|
||||||
|
|
||||||
|
export class ForgotFileIDResponse extends Response {
|
||||||
|
ReturnMessage: string;
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
import { AuthenticatedUser } from './authenticated-user';
|
||||||
|
import { CountryCode } from 'src/app/hmg-common/ui/mobile-number/international-mobile/models/country-code.model';
|
||||||
|
|
||||||
|
export class GetLoginInfoRequest extends Request {
|
||||||
|
NationalID: string;
|
||||||
|
MobileNo: string;
|
||||||
|
DeviceToken: string;
|
||||||
|
PatientID: number;
|
||||||
|
ProjectOutSA: boolean;
|
||||||
|
LoginType: number; // 2 by patient id , 1 by identification number
|
||||||
|
ZipCode: string;
|
||||||
|
PatientMobileNumber: string; // same as mobileNO,
|
||||||
|
SearchType: number; // 2
|
||||||
|
PatientIdentificationID: string // ""
|
||||||
|
isRegister: boolean; // false
|
||||||
|
constructor(user: AuthenticatedUser) {
|
||||||
|
super();
|
||||||
|
this.NationalID = user.IdentificationNo;
|
||||||
|
this.MobileNo = this.PatientMobileNumber = user.MobileNo;
|
||||||
|
this.DeviceToken = user.deviceToken;
|
||||||
|
this.PatientID = user.PatientID;
|
||||||
|
this.ProjectOutSA = user.PatientOutSA ;
|
||||||
|
this.LoginType = 2;
|
||||||
|
this.ZipCode = CountryCode.localCode( user.ZipCode);
|
||||||
|
this.SearchType = 2;
|
||||||
|
this.PatientIdentificationID = '';
|
||||||
|
this.isRegister = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
import { Response } from '../../models/response';
|
||||||
|
|
||||||
|
export class GetLoginInfoResponse extends Response {
|
||||||
|
SMSLoginRequired: boolean;
|
||||||
|
isSMSSent: boolean;
|
||||||
|
LogInTokenID: string;
|
||||||
|
PatientOutSA: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
|
||||||
|
export class LoginRequest extends Request {
|
||||||
|
PatientID: number; // 0
|
||||||
|
PatientIdentificationID: string; // "2401412511"
|
||||||
|
PatientMobileNumber: string; // "537753536"
|
||||||
|
SearchType: number; // 1 for iqama 2 for file number
|
||||||
|
TokenID: string; // ""
|
||||||
|
ZipCode: string; // "966"
|
||||||
|
// isDentalAllowedBackend: false
|
||||||
|
isRegister: boolean; // false
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
export class RegisterInformationPatientModel {
|
||||||
|
FirstName: string;
|
||||||
|
MiddleName: string;
|
||||||
|
LastName: string;
|
||||||
|
StrDateofBirth: string; // ison date
|
||||||
|
TempValue: true;
|
||||||
|
DateofBirth: string; // backend format
|
||||||
|
Gender: number;
|
||||||
|
NationalityID: string;
|
||||||
|
ProjectID: number;
|
||||||
|
MobileNumber: string;
|
||||||
|
PatientIdentificationType: number;
|
||||||
|
PatientIdentificationNo: string;
|
||||||
|
PatientOutSA: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
import { Request } from '../../models/request';
|
||||||
|
import { RegisterInformationPatientModel } from './register-information-patient.model';
|
||||||
|
|
||||||
|
export class RegisterInformationRequest extends Request {
|
||||||
|
activationCode: string;
|
||||||
|
LogInTokenID: string;
|
||||||
|
PatientIdentificationID: string;
|
||||||
|
PatientMobileNumber: string;
|
||||||
|
ProjectID: number;
|
||||||
|
Patientobject = new RegisterInformationPatientModel();
|
||||||
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.Patientobject.TempValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public setName(first: string, middle: string, last: string) {
|
||||||
|
this.Patientobject.FirstName = first;
|
||||||
|
this.Patientobject.MiddleName = middle;
|
||||||
|
this.Patientobject.LastName = last;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setBirthDate(birthDateISO: string, birthDateJSON: string) {
|
||||||
|
this.Patientobject.StrDateofBirth = birthDateISO;
|
||||||
|
this.Patientobject.DateofBirth = birthDateJSON;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setGender(gender: number) {
|
||||||
|
this.Patientobject.Gender = gender;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AutoConnectService } from './auto-connect.service';
|
||||||
|
|
||||||
|
describe('AutoConnectService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: AutoConnectService = TestBed.get(AutoConnectService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,204 @@
|
|||||||
|
|
||||||
|
import { ConnectorService } from '../connector/connector.service'
|
||||||
|
import { AuthenticationService } from '../authentication/authentication.service'
|
||||||
|
import { CredentialWifiRequest } from './models/credential-wifi.request'
|
||||||
|
import { CredentialWifiResponse } from './models/credential-wifi.response'
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Platform } from '@ionic/angular';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { CommonService } from '../common/common.service';
|
||||||
|
import { AuthenticatedUser } from '../authentication/models/authenticated-user'
|
||||||
|
import { AlertControllerService } from 'src/app/hmg-common/ui/alert/alert-controller.service';
|
||||||
|
import { TranslatorService } from 'src/app/hmg-common/services/translator/translator.service';
|
||||||
|
|
||||||
|
|
||||||
|
declare var WifiWizard2: any;
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export class AutoConnectService {
|
||||||
|
passWord: any;
|
||||||
|
userName: any;
|
||||||
|
public buttons: any[]
|
||||||
|
|
||||||
|
public static credentialInfoWifi = 'Services/Patients.svc/REST/Hmg_SMS_Get_By_ProjectID_And_PatientID';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public con: ConnectorService,
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
public cs: CommonService,
|
||||||
|
public platform: Platform,
|
||||||
|
public ts: TranslatorService
|
||||||
|
) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public getCredentialWifiService(patientID: any, projectID: any, onError: any): Observable<CredentialWifiResponse> {
|
||||||
|
//const request = this.authService.getAuthenticatedRequest();
|
||||||
|
const request = new CredentialWifiRequest();
|
||||||
|
request.PatientID = patientID;
|
||||||
|
request.ProjectID = projectID;
|
||||||
|
// request.SetupID= '91877';
|
||||||
|
return this.con.post(AutoConnectService.credentialInfoWifi, request, onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
call service to get Password and Name
|
||||||
|
call plugin to connected
|
||||||
|
if connected then open url
|
||||||
|
*/
|
||||||
|
public getCredentialWifi(buttons) {
|
||||||
|
this.buttons = buttons;
|
||||||
|
|
||||||
|
const authUser = this.authService.getAuthenticatedUser();
|
||||||
|
this.getCredentialWifiService(authUser.PatientID, authUser.ProjectID, () => { }).subscribe((result: any) => {
|
||||||
|
|
||||||
|
if (this.cs.validResponse(result)) {
|
||||||
|
|
||||||
|
if (this.cs.hasData(result.Hmg_SMS_Get_By_ProjectID_And_PatientIDList)) {
|
||||||
|
//get the password and userNmae
|
||||||
|
// send it to url
|
||||||
|
this.passWord = result.Hmg_SMS_Get_By_ProjectID_And_PatientIDList[0].Password;
|
||||||
|
this.userName = result.Hmg_SMS_Get_By_ProjectID_And_PatientIDList[0].UserName;
|
||||||
|
this.scanWifi();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async scanWifi() {
|
||||||
|
|
||||||
|
// this.platform.ready().then(() => {
|
||||||
|
if (this.platform.is("ios")) {
|
||||||
|
//check avaliable ssid
|
||||||
|
this.checkConnected();
|
||||||
|
} //end if iOS
|
||||||
|
else if (this.platform.is("android")) {
|
||||||
|
|
||||||
|
// alert("Android");
|
||||||
|
try {
|
||||||
|
let result = await WifiWizard2.scan()
|
||||||
|
let resultList = result;
|
||||||
|
for (let i = 0; i < resultList.length; i++) {
|
||||||
|
let ssid = resultList[i].SSID;
|
||||||
|
if (ssid == "CS-Guest") {
|
||||||
|
// alert("ssid " + ssid);
|
||||||
|
i = resultList.length; // to stop the loop
|
||||||
|
} // if ssid == cs-guest
|
||||||
|
} // for loop
|
||||||
|
|
||||||
|
this.checkConnected();
|
||||||
|
} catch (e) {
|
||||||
|
//alert( 'Error to Scan: '+ e );
|
||||||
|
// this.alertService.presentConfirm(
|
||||||
|
// this.ts.trPK('general', 'info'),
|
||||||
|
// this.ts.trPK('error', 'scan-wifi'),
|
||||||
|
// this.ts.trPK('general', 'ok'), () => {
|
||||||
|
// this.alertService.dismiss();
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
this.cs.presentAcceptDialog(this.ts.trPK('error', 'scan-wifi'), () => { })
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
} //end if Android
|
||||||
|
//});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async checkConnected() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
let result = await WifiWizard2.getConnectedSSID()
|
||||||
|
if (result == "CS-Guest") {
|
||||||
|
// alert('WIFI SSID '+ result);
|
||||||
|
this.disconnectNetwork();
|
||||||
|
} else {
|
||||||
|
this.startConnected();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert('Error to display WIFI SSID: ' + e);
|
||||||
|
// conneted to local HMG
|
||||||
|
this.startConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async startConnected() {
|
||||||
|
alert(" startConnected ");
|
||||||
|
|
||||||
|
try {
|
||||||
|
let result;
|
||||||
|
if (this.platform.is("ios")) {
|
||||||
|
result = await WifiWizard2.iOSConnectNetwork("CS-Guest")
|
||||||
|
} else if (this.platform.is("android")) {
|
||||||
|
|
||||||
|
result = await WifiWizard2.connect("CS-Guest", false, false)
|
||||||
|
}
|
||||||
|
alert('conected: ' + result);
|
||||||
|
this.buttons[5][5].title = 'home,auto-connected-wifi';
|
||||||
|
|
||||||
|
//let url="http://192.168.104.251/guest/HMG-Guest.php?_browser=1&cmd=login&essid=CS-Guest&apname=CS_AP_9&apgroup=CloudSolutons%20AP%20Group&url=http%3A%2F%2Fwww%2Emsftconnecttest%2Ecom%252Fredirect&Name=6200&Pass=7809";
|
||||||
|
|
||||||
|
let url = "http://192.168.104.251/guest/HMG-Guest.php?_browser=1&cmd=login&essid=CS-Guest&apname=CS_AP_9&apgroup=CloudSolutons%20AP%20Group&url=http%3A%2F%2Fwww%2Emsftconnecttest%2Ecom%252Fredirect&Name=" + this.userName + "&Pass=" + this.passWord + "";
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.cs.openBrowser(url);
|
||||||
|
}, 2 * 1000);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
//display error for check the avaliable Wifi
|
||||||
|
// alert( 'Error to connected: '+ e );
|
||||||
|
// this.alertService.presentConfirm(
|
||||||
|
// this.ts.trPK('general', 'info'),
|
||||||
|
// this.ts.trPK('error', 'connect-Wifi'),
|
||||||
|
// this.ts.trPK('general', 'ok'), () => {
|
||||||
|
// this.alertService.dismiss();
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
this.cs.presentAcceptDialog(this.ts.trPK('error', 'connect-Wifi'), () => { });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public async disconnectNetwork() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
let result;
|
||||||
|
if (this.platform.is("ios")) {
|
||||||
|
result = await WifiWizard2.iOSDisconnectNetwork("CS-Guest")
|
||||||
|
} else if (this.platform.is("android")) {
|
||||||
|
|
||||||
|
result = await WifiWizard2.disconnect("CS-Guest")
|
||||||
|
}
|
||||||
|
this.buttons[5][5].title = 'home,auto-wifi';
|
||||||
|
alert('Succssful Disconected ' + result);
|
||||||
|
} catch (e) {
|
||||||
|
//display error for check the avaliable Wifi
|
||||||
|
// alert( 'Error to connected: '+ e );
|
||||||
|
// this.alertService.presentConfirm(
|
||||||
|
// this.ts.trPK('general', 'info'),
|
||||||
|
// this.ts.trPK('error', 'disconnect-Wifi'),
|
||||||
|
// this.ts.trPK('general', 'ok'), () => {
|
||||||
|
// this.alertService.dismiss();
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
|
this.cs.presentAcceptDialog(this.ts.trPK('error', 'disconnect-Wifi'), () => { })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
export class CredentialWifiModel{
|
||||||
|
|
||||||
|
UserName:number;
|
||||||
|
Password:number;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { Request } from 'src/app/hmg-common/services/models/request';
|
||||||
|
|
||||||
|
export class CredentialWifiRequest extends Request {
|
||||||
|
PatientID: number;
|
||||||
|
ProjectID:number;
|
||||||
|
SetupID:String;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { Response } from 'src/app/hmg-common/services/models/response';
|
||||||
|
import { CredentialWifiModel } from './credential-wifi.modal';
|
||||||
|
|
||||||
|
export class CredentialWifiResponse extends Response {
|
||||||
|
List_PatientCredentialWifi: CredentialWifiModel[];
|
||||||
|
}
|
||||||
@ -0,0 +1,638 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { NavController, ToastController, LoadingController, AlertController, Platform } from '@ionic/angular';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { TranslatorService } from '../translator/translator.service';
|
||||||
|
import { AlertControllerService } from '../../ui/alert/alert-controller.service';
|
||||||
|
import { Response } from '../models/response';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { ThemeableBrowser } from '@ionic-native/themeable-browser/ngx';
|
||||||
|
import { BrowserConfig } from './models/browser-config';
|
||||||
|
import { LaunchNavigator, LaunchNavigatorOptions } from '@ionic-native/launch-navigator/ngx';
|
||||||
|
import { Device } from '@ionic-native/device/ngx';
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class CommonService {
|
||||||
|
private progressLoaders: any[] = [];
|
||||||
|
private loadingProgress: any;
|
||||||
|
constructor(
|
||||||
|
public nav: NavController,
|
||||||
|
public router: Router,
|
||||||
|
public location: Location,
|
||||||
|
public ts: TranslatorService,
|
||||||
|
public loadingController: LoadingController,
|
||||||
|
public toastController: ToastController,
|
||||||
|
public alertController: AlertControllerService,
|
||||||
|
public alertControllerIonic: AlertController,
|
||||||
|
public themeableBrowser: ThemeableBrowser,
|
||||||
|
public launchNavigation: LaunchNavigator,
|
||||||
|
public platform: Platform,
|
||||||
|
public device: Device
|
||||||
|
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public back() {
|
||||||
|
// this.location.back();
|
||||||
|
this.nav.goBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public round(value: number, decimal: number): string {
|
||||||
|
const valueStr = value.toString();
|
||||||
|
const dotIndex = valueStr.indexOf('.');
|
||||||
|
|
||||||
|
if (dotIndex >= 0) {
|
||||||
|
return valueStr.toString().substr(0, dotIndex + decimal);
|
||||||
|
} else {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public toastPK(page: string, key: string) {
|
||||||
|
this.toast(this.ts.trPK(page, key));
|
||||||
|
}
|
||||||
|
async toast(message: string) {
|
||||||
|
const toast = await this.toastController.create({
|
||||||
|
message: message,
|
||||||
|
showCloseButton: true,
|
||||||
|
position: 'middle',
|
||||||
|
duration: 2000,
|
||||||
|
closeButtonText: this.ts.trPK('general', 'done')
|
||||||
|
});
|
||||||
|
toast.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
async startLoading() {
|
||||||
|
this.stopLoading();
|
||||||
|
const loader = await this.loadingController.create({
|
||||||
|
spinner: 'bubbles',
|
||||||
|
duration: 30000,
|
||||||
|
message: this.ts.trPK('error', 'wait'),
|
||||||
|
translucent: true
|
||||||
|
});
|
||||||
|
|
||||||
|
this.progressLoaders.push(loader);
|
||||||
|
return await loader.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public mobileNumber(number: string) {
|
||||||
|
return number.substr(1, number.length - 1);
|
||||||
|
}
|
||||||
|
public testFunction() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public stopLoading() {
|
||||||
|
|
||||||
|
/*
|
||||||
|
loading progress must be implemented
|
||||||
|
as synchronous
|
||||||
|
*/
|
||||||
|
setTimeout(() => {
|
||||||
|
for (const loader of this.progressLoaders) {
|
||||||
|
loader.dismiss();
|
||||||
|
}
|
||||||
|
this.progressLoaders = [];
|
||||||
|
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
public presentAlert(message: string) {
|
||||||
|
this.alertDialog(null, this.ts.trPK('general', 'ok'), this.ts.trPK('general', 'alert'), message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public presentConfirmDialog(message: string, onAccept: any, onCancel: any) {
|
||||||
|
|
||||||
|
this.confirmAlertDialog(onAccept, this.ts.trPK('general', 'ok'),
|
||||||
|
null, this.ts.trPK('general', 'cancel'),
|
||||||
|
this.ts.trPK('general', 'confirm'), message);
|
||||||
|
}
|
||||||
|
|
||||||
|
async presentConfirmDialogOld(message: string, onAccept: any, onCancel: any) {
|
||||||
|
|
||||||
|
this.alertController.presentConfirm(
|
||||||
|
this.ts.trPK('general', 'confirm'),
|
||||||
|
message,
|
||||||
|
this.ts.trPK('general', 'ok'),
|
||||||
|
() => {
|
||||||
|
this.alertController.dismiss();
|
||||||
|
onAccept();
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.alertController.dismiss();
|
||||||
|
onCancel();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public presentAcceptDialog(message: string, onAccept: any) {
|
||||||
|
|
||||||
|
this.alertDialog(onAccept, this.ts.trPK('general', 'ok'), this.ts.trPK('general', 'confirm'), message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async presentAcceptDialogOld(message: string, onAccept: any) {
|
||||||
|
this.alertController.presentConfirm(
|
||||||
|
this.ts.trPK('general', 'confirm'),
|
||||||
|
message,
|
||||||
|
this.ts.trPK('general', 'ok'),
|
||||||
|
() => {
|
||||||
|
this.alertController.dismiss();
|
||||||
|
onAccept();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public confirmBackDialogOld(message: string) {
|
||||||
|
this.alertController.presentConfirm(
|
||||||
|
this.ts.trPK('general', 'info'),
|
||||||
|
message,
|
||||||
|
this.ts.trPK('general', 'ok'),
|
||||||
|
() => {
|
||||||
|
this.back();
|
||||||
|
this.alertController.dismiss();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public confirmBackDialog(message: string) {
|
||||||
|
|
||||||
|
this.alertDialog(
|
||||||
|
() => {
|
||||||
|
this.back();
|
||||||
|
},
|
||||||
|
this.ts.trPK('general', 'ok'), this.ts.trPK('general', 'info'), message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public showErrorMessageDialogOld(onClick: any, okLabel: string, message: string) {
|
||||||
|
this.alertController.presentConfirm(
|
||||||
|
this.ts.trPK('general', 'alert'),
|
||||||
|
message, okLabel, () => {
|
||||||
|
if (onClick) {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
this.alertController.dismiss();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public showErrorMessageDialog(onClick: any, okLabel: string, message: string) {
|
||||||
|
this.alertDialog(onClick, okLabel, this.ts.trPK('general', 'alert'), message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public showConnectionErrorDialogOld(onClick: any, okLabel: string) {
|
||||||
|
|
||||||
|
this.alertController.presentConfirm(
|
||||||
|
this.ts.trPK('general', 'alert'),
|
||||||
|
this.ts.trPK('error', 'conn'),
|
||||||
|
okLabel, () => {
|
||||||
|
if (onClick) {
|
||||||
|
onClick();
|
||||||
|
}
|
||||||
|
this.alertController.dismiss();
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public showConnectionErrorDialog(onClick: any, okLabel: string) {
|
||||||
|
this.alertDialog(onClick, okLabel, this.ts.trPK('general', 'alert'), this.ts.trPK('error', 'conn'));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async confirmAlertDialog(onAccept: any, acceptLabel: string, onCancel: any, cancelLabel: string, title: string, message: string) {
|
||||||
|
this.clearAllAlerts();
|
||||||
|
const alert = await this.alertControllerIonic.create({
|
||||||
|
header: this.ts.trPK('general', 'confirm'),
|
||||||
|
message: message,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: cancelLabel,
|
||||||
|
role: 'cancel',
|
||||||
|
handler: () => {
|
||||||
|
if (onCancel) {
|
||||||
|
onCancel();
|
||||||
|
}
|
||||||
|
this.alertControllerIonic.dismiss();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
text: acceptLabel,
|
||||||
|
handler: () => {
|
||||||
|
if (onAccept) {
|
||||||
|
onAccept();
|
||||||
|
}
|
||||||
|
this.alertControllerIonic.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
// this.alerts.push(alert);
|
||||||
|
await alert.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
async alertDialog(onAccept: any, acceptLabel: string, title: string, message: string) {
|
||||||
|
this.clearAllAlerts();
|
||||||
|
const alert = await this.alertControllerIonic.create({
|
||||||
|
header: title,
|
||||||
|
message: message,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
text: acceptLabel,
|
||||||
|
handler: () => {
|
||||||
|
if (onAccept) {
|
||||||
|
onAccept();
|
||||||
|
}
|
||||||
|
this.alertControllerIonic.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
// this.alerts.push(alert);
|
||||||
|
await alert.present();
|
||||||
|
}
|
||||||
|
|
||||||
|
private alerts: any[] = [];
|
||||||
|
public clearAllAlerts() {
|
||||||
|
/*
|
||||||
|
for (const alert of this.alerts) {
|
||||||
|
this.alertControllerIonic.dismiss(alert);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
this.alerts = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public getDeviceInfo(): string {
|
||||||
|
|
||||||
|
if (this.platform.is('mobile')) {
|
||||||
|
const os = this.platform.is('ios') ? 'Iphone' : 'android';
|
||||||
|
return os + ' - ' + this.device.platform + ' - ' + this.device.version + ' , ' + this.device.manufacturer;
|
||||||
|
} else {
|
||||||
|
return navigator.userAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDeviceType(): string {
|
||||||
|
if (this.platform.is('mobile')) {
|
||||||
|
return 'Mobile ' + (this.platform.is('ios') ? 'Iphone' : 'android');
|
||||||
|
} else {
|
||||||
|
return 'Desktop';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public validResponse(result: Response): boolean {
|
||||||
|
if (result.MessageStatus === 1) {
|
||||||
|
return true;
|
||||||
|
} else if (result.MessageStatus === 2) {
|
||||||
|
return this.hasData(result['SameClinicApptList']);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBrowser(url: string) {
|
||||||
|
// const browser: ThemeableBrowserObject =
|
||||||
|
this.themeableBrowser.create(url, '_blank', BrowserConfig.OPTIONS);
|
||||||
|
|
||||||
|
}
|
||||||
|
public imageFromBase64(base64: string) {
|
||||||
|
return 'data:image/jpeg;base64,' + base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
public openLocation(lat: number, lng: number) {
|
||||||
|
this.launchNavigation.navigate([lat, lng]).then(
|
||||||
|
() => { },
|
||||||
|
() => { this.failedToOpenMap(); }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
private failedToOpenMap() {
|
||||||
|
this.alertController.presentConfirm(
|
||||||
|
this.ts.trPK('general', 'alert'),
|
||||||
|
this.ts.trPK('error', 'map'),
|
||||||
|
this.ts.trPK('general', 'ok'),
|
||||||
|
() => {
|
||||||
|
this.alertController.dismiss();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public evaluteDate(dateStr: string): string {
|
||||||
|
if (dateStr) {
|
||||||
|
const utc = parseInt(dateStr.substring(6, dateStr.length - 2), 10);
|
||||||
|
if (utc) {
|
||||||
|
const appoDate = new Date(utc);
|
||||||
|
if ((appoDate instanceof Date) && !isNaN(appoDate.getTime())) {
|
||||||
|
return appoDate.toLocaleDateString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dateStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public evaluteDateAsObject(dateStr: string): Date {
|
||||||
|
if (dateStr) {
|
||||||
|
const utc = parseInt(dateStr.substring(6, dateStr.length - 2), 10);
|
||||||
|
return new Date(utc);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDateISO(date: Date): string {
|
||||||
|
return date.getFullYear().toString() + '-' +
|
||||||
|
this.trailerZero(date.getMonth() + 1) + '-' +
|
||||||
|
this.trailerZero(date.getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTodayISO(): string {
|
||||||
|
return this.getDateISO(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public getTimeISO(date: Date): string {
|
||||||
|
return this.trailerZero(date.getHours()) + ':' +
|
||||||
|
this.trailerZero(date.getMinutes()) + ':00';
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDateTimeISO(date: Date): string {
|
||||||
|
return this.getDateISO(date) + ' ' + this.getTimeISO(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDateTimeISOFromString(dateStr: string): string {
|
||||||
|
const date = this.evaluteDateAsObject(dateStr);
|
||||||
|
return this.getDateTimeISO(date) + ' ' + this.getTimeISO(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCurrentTimeISO(): string {
|
||||||
|
return this.getTimeISO(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
private trailerZero(value: number): string {
|
||||||
|
const str = value.toString();
|
||||||
|
return (str.length > 1) ? str : ('0' + str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public hasData(array: any[]): boolean {
|
||||||
|
return array != null && array.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public extractNumber(message: string): string {
|
||||||
|
if (message != null && message.length > 0) {
|
||||||
|
let startIndex = null;
|
||||||
|
let endIndex = message.length - 1;
|
||||||
|
for (let i = 0; i < message.length; i++) {
|
||||||
|
const code = message.charCodeAt(i);
|
||||||
|
if (this.inNumberRange(code)) {
|
||||||
|
if (!startIndex) {
|
||||||
|
startIndex = i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (startIndex) {
|
||||||
|
endIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return startIndex ? message.substring(startIndex, endIndex) : '';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public inNumberRange(targetCode: number): boolean {
|
||||||
|
const minDigit = '0'.charCodeAt(0);
|
||||||
|
const maxDigit = '9'.charCodeAt(0);
|
||||||
|
return (targetCode >= minDigit && targetCode <= maxDigit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enterPage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
open calls
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public openAppointments() {
|
||||||
|
this.nav.navigateForward(['/eservices/appointments/home']);
|
||||||
|
// this.router.navigateByUrl('/eservices/appointments/home');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public openHome() {
|
||||||
|
this.nav.navigateRoot(['/home']);
|
||||||
|
// this.nav.navigateByUrl('/home');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public reload(url: string, from: string) {
|
||||||
|
console.log('force reload called from:' + from);
|
||||||
|
// window.location.reload();
|
||||||
|
location.href = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public navigateRoot(url: string) {
|
||||||
|
this.nav.navigateRoot([url]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public navigateForward(url: string) {
|
||||||
|
this.nav.navigateForward([url]);
|
||||||
|
}
|
||||||
|
public navigateBack(url: string) {
|
||||||
|
this.nav.navigateBack([url]);
|
||||||
|
}
|
||||||
|
public openEservices() {
|
||||||
|
this.nav.navigateForward(['/eservices/home']);
|
||||||
|
// this.router.navigateByUrl('/eservices/home');
|
||||||
|
|
||||||
|
}
|
||||||
|
public openBookings() {
|
||||||
|
this.nav.navigateForward(['/eservices/booking/home']);
|
||||||
|
// this.router.navigateByUrl('/eservices/bookings');
|
||||||
|
}
|
||||||
|
public openAppointmentDetails() {
|
||||||
|
this.nav.navigateForward(['/eservices/appointments/detials']);
|
||||||
|
// this.router.navigateByUrl('/eservices/appointments/detials');
|
||||||
|
}
|
||||||
|
|
||||||
|
public openApprovals() {
|
||||||
|
this.nav.navigateForward(['/eservices/approvals']);
|
||||||
|
// this.router.navigateByUrl('/eservices/approvals');
|
||||||
|
|
||||||
|
}
|
||||||
|
public openPrescriptions() {
|
||||||
|
this.nav.navigateForward(['/eservices/prescriptions']);
|
||||||
|
// this.router.navigateByUrl('/eservices/prescriptions');
|
||||||
|
|
||||||
|
}
|
||||||
|
public openPrescriptionReports() {
|
||||||
|
this.nav.navigateForward(['/eservices/prescriptions/reports']);
|
||||||
|
// this.router.navigateByUrl('/eservices/prescriptions/reports');
|
||||||
|
|
||||||
|
}
|
||||||
|
public openPrescriptionPharmaciesList() {
|
||||||
|
this.nav.navigateForward(['/eservices/prescriptions/reports/pharmacies']);
|
||||||
|
// this.router.navigateByUrl('/eservices/prescriptions/reports/pharmacies');
|
||||||
|
|
||||||
|
}
|
||||||
|
public openDoctorSchedule() {
|
||||||
|
this.nav.navigateForward(['/eservices/doctors/schedule']);
|
||||||
|
// this.router.navigateByUrl('/eservices/appointments/doctor-schedule');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public openRadiology() {
|
||||||
|
this.nav.navigateForward(['/eservices/radiology']);
|
||||||
|
// this.router.navigateByUrl('/eservices/radiology');
|
||||||
|
}
|
||||||
|
public openRadiologyReport() {
|
||||||
|
this.nav.navigateForward(['/eservices/radiology/report']);
|
||||||
|
// this.router.navigateByUrl('/eservices/radiology/report');
|
||||||
|
}
|
||||||
|
public openMyDoctors() {
|
||||||
|
this.nav.navigateForward(['/eservices/doctors']);
|
||||||
|
}
|
||||||
|
public openDoctorProfile() {
|
||||||
|
this.nav.navigateForward(['/eservices/doctors/profile']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBookingCalendar() {
|
||||||
|
this.nav.navigateForward(['/eservices/doctors/calendar']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openLabOrders() {
|
||||||
|
this.nav.navigateForward(['/eservices/lab']);
|
||||||
|
// this.router.navigateByUrl('/eservices/lab');
|
||||||
|
}
|
||||||
|
public openLabResult() {
|
||||||
|
this.nav.navigateForward(['/eservices/lab/result']);
|
||||||
|
// this.router.navigateByUrl('/eservices/lab/result');
|
||||||
|
}
|
||||||
|
|
||||||
|
public openEyePrescriptions() {
|
||||||
|
this.nav.navigateForward(['/eservices/eye']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openEyeMeasurments() {
|
||||||
|
this.nav.navigateForward(['/eservices/eye/measurments']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBloodSugarGraph() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-sugar/graph']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBloodSugarAdd() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-sugar/add']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBloodPressureAdd() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-pressure/add']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBloodSugarRHMD() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-sugar/rhmd']);
|
||||||
|
}
|
||||||
|
public openBloodSugarRHMDBL() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-sugar/rhmd-bl']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBloodSugarRHMDBLE() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-sugar/rhmd-ble']);
|
||||||
|
}
|
||||||
|
public openBloodPressureGraph() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/blood-pressure/graph']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openWeightAdd() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/weight/add']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openWeightGraph() {
|
||||||
|
this.nav.navigateForward(['/eservices/tracker/weight/graph']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openBookingDoctorsList() {
|
||||||
|
this.nav.navigateForward(['/eservices/booking/doctors-list']);
|
||||||
|
}
|
||||||
|
public openBookingDentalComplains() {
|
||||||
|
this.nav.navigateForward(['/eservices/booking/dental-complains']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openDocResponseDetail() {
|
||||||
|
this.nav.navigateForward(['/eservices/doc-response/response-detail']);
|
||||||
|
}
|
||||||
|
public openInsurCardDetail() {
|
||||||
|
this.nav.navigateForward(['/eservices/insur-cards/card-detail']);
|
||||||
|
}
|
||||||
|
public openUserAgreement() {
|
||||||
|
this.nav.navigateForward(['/eservices/month-report/user-agreement']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openChildVaccineHome() {
|
||||||
|
this.nav.navigateForward(['/eservices/child-vaccine/home']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openChildVaccineVaccineList() {
|
||||||
|
this.nav.navigateForward(['/eservices/child-vaccine/vaccine-list']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openChildVaccineAddChild() {
|
||||||
|
this.nav.navigateForward(['/eservices/child-vaccine/add-child']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openChildVaccineChildList() {
|
||||||
|
this.nav.navigateForward(['/eservices/child-vaccine/child-list']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openAskDocRequest() {
|
||||||
|
this.nav.navigateForward(['/eservices/ask-doc/ask-doc-request']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openNewMedReport() {
|
||||||
|
this.nav.navigateForward(['/eservices/med-report/new-med-report']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openUserLogin() {
|
||||||
|
console.log('now open login');
|
||||||
|
this.nav.navigateForward(['/authentication/login']);
|
||||||
|
}
|
||||||
|
public openAgreement() {
|
||||||
|
this.nav.navigateForward(['/authentication/agreement']);
|
||||||
|
}
|
||||||
|
public openUserRegister() {
|
||||||
|
this.nav.navigateForward(['/authentication/register']);
|
||||||
|
}
|
||||||
|
public openUserForgot() {
|
||||||
|
this.nav.navigateForward(['/authentication/forgot']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public openFeedback() {
|
||||||
|
this.nav.navigateForward(['/feedback/home']);
|
||||||
|
}
|
||||||
|
public openFeedbackStatusDetails() {
|
||||||
|
this.nav.navigateForward(['/feedback/status-details']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public navigateTo(url: string) {
|
||||||
|
this.nav.navigateForward([url]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CommonService } from './common.service';
|
||||||
|
|
||||||
|
describe('CommonService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: CommonService = TestBed.get(CommonService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,64 @@
|
|||||||
|
import { ThemeableBrowserOptions } from '@ionic-native/themeable-browser/ngx';
|
||||||
|
|
||||||
|
export class BrowserConfig {
|
||||||
|
public static OPTIONS: ThemeableBrowserOptions = {
|
||||||
|
statusbar: {
|
||||||
|
color: '#ffffffff'
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
height: 44,
|
||||||
|
color: '#f0f0f0ff'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
color: '#003264ff',
|
||||||
|
showPageTitle: true
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
image: 'back',
|
||||||
|
imagePressed: 'back_pressed',
|
||||||
|
align: 'left',
|
||||||
|
event: 'backPressed'
|
||||||
|
},
|
||||||
|
forwardButton: {
|
||||||
|
image: 'forward',
|
||||||
|
imagePressed: 'forward_pressed',
|
||||||
|
align: 'left',
|
||||||
|
event: 'forwardPressed'
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
image: 'close',
|
||||||
|
imagePressed: 'close_pressed',
|
||||||
|
align: 'left',
|
||||||
|
event: 'closePressed'
|
||||||
|
},
|
||||||
|
customButtons: [
|
||||||
|
{
|
||||||
|
image: 'share',
|
||||||
|
imagePressed: 'share_pressed',
|
||||||
|
align: 'right',
|
||||||
|
event: 'sharePressed'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
menu: {
|
||||||
|
image: 'menu',
|
||||||
|
imagePressed: 'menu_pressed',
|
||||||
|
title: 'Test',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
align: 'right',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
event: 'helloPressed',
|
||||||
|
label: 'Hello World!'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event: 'testPressed',
|
||||||
|
label: 'Test!'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
backButtonCanClose: true,
|
||||||
|
clearcache: true,
|
||||||
|
clearsessioncache: true,
|
||||||
|
disallowoverscroll: 'yes'
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
|
export class InputData {
|
||||||
|
value: any;
|
||||||
|
values: any [];
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ConnectorService } from './connector.service';
|
||||||
|
|
||||||
|
describe('ConnectorService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: ConnectorService = TestBed.get(ConnectorService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,148 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { Observable, throwError, TimeoutError } from 'rxjs';
|
||||||
|
import { catchError, retry, tap, timeout } from 'rxjs/operators';
|
||||||
|
import { CommonService } from '../common/common.service';
|
||||||
|
import { Response } from '../models/response';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ConnectorService {
|
||||||
|
/*
|
||||||
|
connection configuration settings
|
||||||
|
*/
|
||||||
|
static httpOptions = {
|
||||||
|
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
|
||||||
|
};
|
||||||
|
public static retryTimes = 0;
|
||||||
|
public static timeOut = 30 * 1000;
|
||||||
|
// public static host = 'http://10.50.100.113:6060/'; // development service
|
||||||
|
|
||||||
|
|
||||||
|
// public static host = 'https://hmgwebservices.com/';
|
||||||
|
public static host = 'http://10.50.100.198:6060/'; // development service
|
||||||
|
/* public static host = 'http://10.200.204.101:6060/'; // video conference development
|
||||||
|
public static host = 'http://10.50.100.198:6060/';
|
||||||
|
public static host = 'http://10.50.100.198:6060/'; // development service
|
||||||
|
public static host = 'http://10.50.100.198:4040/'; // UAT service
|
||||||
|
public static host = 'http://10.50.100.198:4444/'; // production service
|
||||||
|
public static host = 'http://10.50.100.113:4040/'; // UAT service
|
||||||
|
public static host = 'http://10.50.100.113:4444/'; // production service
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
end of connection configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public httpClient: HttpClient,
|
||||||
|
public cs: CommonService
|
||||||
|
|
||||||
|
) { }
|
||||||
|
|
||||||
|
|
||||||
|
public post(service: string, data: any, onError: any, errorLabel?: string): Observable<any> {
|
||||||
|
|
||||||
|
this.cs.startLoading();
|
||||||
|
return this.httpClient.post<any>(ConnectorService.host + service, data, ConnectorService.httpOptions)
|
||||||
|
.pipe(
|
||||||
|
timeout(ConnectorService.timeOut),
|
||||||
|
retry(ConnectorService.retryTimes),
|
||||||
|
tap(
|
||||||
|
res => this.handleResponse(res, onError, errorLabel),
|
||||||
|
error => this.handleError(error, onError, errorLabel)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public postNoLoad(service: string, data: any, onError: any): Observable<any> {
|
||||||
|
return this.httpClient.post<any>(ConnectorService.host + service, data, ConnectorService.httpOptions)
|
||||||
|
.pipe(
|
||||||
|
retry(ConnectorService.retryTimes),
|
||||||
|
tap(() => { }, () => { })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// absolute url connection
|
||||||
|
public postToken(service: string, data: any, onError: any, errorLabel?: string): Observable<any> {
|
||||||
|
this.cs.startLoading();
|
||||||
|
return this.httpClient.post<any>(service, data, ConnectorService.httpOptions)
|
||||||
|
.pipe(
|
||||||
|
timeout(ConnectorService.timeOut),
|
||||||
|
retry(ConnectorService.retryTimes),
|
||||||
|
tap(res => this.handleResponse(res, onError, errorLabel),
|
||||||
|
error => this.handleError(error, onError, errorLabel)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(service: string, data: any, onError: any, errorLabel?: string): Observable<any> {
|
||||||
|
this.cs.startLoading();
|
||||||
|
return this.httpClient.get(service, ConnectorService.httpOptions)
|
||||||
|
.pipe(
|
||||||
|
timeout(ConnectorService.timeOut),
|
||||||
|
retry(ConnectorService.retryTimes),
|
||||||
|
tap(res => this.handleResponse(res, onError, errorLabel),
|
||||||
|
error => this.handleError(error, onError, errorLabel)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
load local json data and convert it to corresponding model
|
||||||
|
resourceURL such as 'assets/config.json'
|
||||||
|
*/
|
||||||
|
public getLocalResrouce(resourceURL: string): Observable<any> {
|
||||||
|
return this.httpClient.get(resourceURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public validResponse(result: Response): boolean {
|
||||||
|
// error type == 2 means you have error
|
||||||
|
if (result.MessageStatus === 1) {
|
||||||
|
return true;
|
||||||
|
} else if (result.MessageStatus === 2) {
|
||||||
|
return this.cs.hasData(result['SameClinicApptList']);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public handleError(error: any, onError: any, errorLabel: string) {
|
||||||
|
this.cs.stopLoading();
|
||||||
|
if (error instanceof TimeoutError) {
|
||||||
|
this.cs.showConnectionTimeout(onError, errorLabel);
|
||||||
|
} else {
|
||||||
|
this.cs.showConnectionErrorDialog(onError, errorLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleResponse(result: Response, onError: any, errorLabel: string) {
|
||||||
|
this.cs.stopLoading();
|
||||||
|
if (!this.cs.validResponse(result)) {
|
||||||
|
// not authorized
|
||||||
|
if (result.ErrorType === 2) {
|
||||||
|
// this.cs.userNeedToReLogin();
|
||||||
|
} else {
|
||||||
|
this.cs.showErrorMessageDialog(onError, errorLabel, result.ErrorEndUserMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public getURLText(url: string, onError: any, errorLabel?: string): Observable<any> {
|
||||||
|
this.cs.startLoading();
|
||||||
|
return this.httpClient.get(url)
|
||||||
|
.pipe(
|
||||||
|
timeout(ConnectorService.timeOut),
|
||||||
|
retry(ConnectorService.retryTimes),
|
||||||
|
tap(res => {
|
||||||
|
this.cs.stopLoading();
|
||||||
|
if (!res) {
|
||||||
|
this.cs.showConnectionErrorDialog(onError, errorLabel);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error => this.handleError(error, onError, errorLabel)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DevicePermissionsService } from './device-permissions.service';
|
||||||
|
|
||||||
|
describe('DevicePermissionsService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: DevicePermissionsService = TestBed.get(DevicePermissionsService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Diagnostic } from '@ionic-native/diagnostic/ngx';
|
||||||
|
import { CommonService } from 'src/app/hmg-common/services/common/common.service';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { SubjectSubscriber } from 'rxjs/internal/Subject';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class DevicePermissionsService {
|
||||||
|
public static granted = 'granted';
|
||||||
|
public camera;
|
||||||
|
public mic;
|
||||||
|
public storage;
|
||||||
|
public onSucess;
|
||||||
|
public onerror;
|
||||||
|
|
||||||
|
constructor(public diagnostic: Diagnostic,
|
||||||
|
public cs: CommonService) { }
|
||||||
|
|
||||||
|
public requestCameraPermission(camera: boolean, mic: boolean, storage: boolean): Observable<boolean> {
|
||||||
|
this.camera = camera;
|
||||||
|
this.mic = mic;
|
||||||
|
this.storage = storage;
|
||||||
|
return Observable.create( observer => {
|
||||||
|
this.requestCamera( observer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public requestCamera(observer: any) {
|
||||||
|
this.diagnostic.isCameraAvailable().then((isAvailable) => {
|
||||||
|
if (isAvailable) {
|
||||||
|
if ( this.mic ) {
|
||||||
|
this.requestMicophonePermission(observer);
|
||||||
|
} else {
|
||||||
|
this.observerDone(observer, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.diagnostic.requestCameraAuthorization(false).then((value) => {
|
||||||
|
// alert( JSON.stringify(value));
|
||||||
|
if (value.toLowerCase() === DevicePermissionsService.granted) {
|
||||||
|
if ( this.mic ) {
|
||||||
|
this.requestMicophonePermission(observer);
|
||||||
|
} else {
|
||||||
|
this.observerDone(observer, true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.cameraError(observer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, () => {
|
||||||
|
this.observerDone(observer, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private cameraError(observer) {
|
||||||
|
this.cs.presentConfirmDialog('camera permission required', () => {
|
||||||
|
this.requestCamera(observer);
|
||||||
|
}, () => {
|
||||||
|
this.observerDone(observer, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private requestMicophonePermission(observer: any) {
|
||||||
|
this.diagnostic.isMicrophoneAuthorized().then((isAvailable) => {
|
||||||
|
|
||||||
|
if (isAvailable) {
|
||||||
|
this.observerDone(observer, true);
|
||||||
|
} else {
|
||||||
|
this.diagnostic.requestMicrophoneAuthorization().then((value) => {
|
||||||
|
if (value.toLowerCase() === DevicePermissionsService.granted) {
|
||||||
|
this.observerDone(observer, true);
|
||||||
|
} else {
|
||||||
|
this.micError(observer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}, () => {
|
||||||
|
this.observerDone(observer, false);
|
||||||
|
});
|
||||||
|
// // Checks microphone permissions
|
||||||
|
}
|
||||||
|
|
||||||
|
private micError(observer) {
|
||||||
|
this.cs.presentConfirmDialog('Michrophone permission required', () => {
|
||||||
|
this.requestMicophonePermission(observer);
|
||||||
|
}, () => {
|
||||||
|
this.observerDone(observer, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private observerDone (observer: any, success: boolean ) {
|
||||||
|
observer.next( success ) ;
|
||||||
|
observer.complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GeofencingService } from './geofencing.service';
|
||||||
|
|
||||||
|
describe('GeofencingService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: GeofencingService = TestBed.get(GeofencingService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,446 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { BackgroundGeolocation, BackgroundGeolocationEvents } from '@ionic-native/background-geolocation/ngx';
|
||||||
|
import { BackgroundGeolocationConfig, BackgroundGeolocationResponse } from '@ionic-native/background-geolocation/ngx';
|
||||||
|
import { UserLocalNotificationService } from '../user-local-notification/user-local-notification.service';
|
||||||
|
import { Platform } from '@ionic/angular';
|
||||||
|
import { LocationModel } from './models/location.model';
|
||||||
|
import { ConnectorService } from '../connector/connector.service';
|
||||||
|
import { NativeStorage } from '@ionic-native/native-storage/ngx';
|
||||||
|
import { AuthenticationService } from '../authentication/authentication.service';
|
||||||
|
import { ZoneModel } from './models/zone.model';
|
||||||
|
import { CommonService } from '../common/common.service';
|
||||||
|
import { InsertLocationRequest } from './models/insert-location.request';
|
||||||
|
import { GeoUserModel } from './models/geo-user.model';
|
||||||
|
import { TranslatorService } from '../translator/translator.service';
|
||||||
|
|
||||||
|
export enum zoneState {
|
||||||
|
out = 0, enter = 1, exit = 2, in = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class GeofencingService {
|
||||||
|
public static ZONES_KEY = 'geofencing-zones';
|
||||||
|
public static USER_DATA_KEY = 'geofencing-user-data';
|
||||||
|
public static GEO_STATUS_KEY = 'geofencing-status';
|
||||||
|
public static zonesUrl = 'Services/Patients.svc/REST/GeoF_GetAllPoints';
|
||||||
|
public static loggingUrl = 'Services/Patients.svc/rest/GeoF_InsertPatientFileInfo';
|
||||||
|
private zonesList: ZoneModel [];
|
||||||
|
private userData: GeoUserModel;
|
||||||
|
private isPaused: boolean;
|
||||||
|
private debug: boolean;
|
||||||
|
|
||||||
|
locations: any [];
|
||||||
|
constructor(
|
||||||
|
private backgroundGeolocation: BackgroundGeolocation,
|
||||||
|
public notif: UserLocalNotificationService,
|
||||||
|
public platform: Platform,
|
||||||
|
public con: ConnectorService,
|
||||||
|
public auth: AuthenticationService,
|
||||||
|
public storage: NativeStorage,
|
||||||
|
public cs: CommonService,
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
public ts: TranslatorService,
|
||||||
|
) {
|
||||||
|
this.debug = false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* logs location on server.
|
||||||
|
*/
|
||||||
|
private logLocation(id: number, type: number, userData: GeoUserModel, zone: ZoneModel) {
|
||||||
|
this.toast('logging location..');
|
||||||
|
this.setNotification('Logging location ' , 'location id: ' + id + ' type: ' + type);
|
||||||
|
const req = new InsertLocationRequest();
|
||||||
|
req.PointsID = id;
|
||||||
|
req.GeoType = type;
|
||||||
|
req.PatientID = userData.PatientID;
|
||||||
|
req.PatientOutSA = userData.PatientOutSA;
|
||||||
|
this.auth.setPublicFields(req);
|
||||||
|
this.con.postNoLoad(GeofencingService.loggingUrl, req, () => {
|
||||||
|
zone.pendingRequest = type; // failed to log, setup pending request
|
||||||
|
this.storeZones(this.zonesList);
|
||||||
|
this.log('pending request from onError');
|
||||||
|
this.setNotification('Pending request from onError', 'zone: ' + zone.Description + ' request type: ' + type);
|
||||||
|
}).subscribe((response) => {
|
||||||
|
if (this.cs.validResponse(response)) {
|
||||||
|
this.setNotification('Log success' , 'location id: ' + id + ' patientID: ' + userData.PatientID);
|
||||||
|
this.log('logged successfuly');
|
||||||
|
zone.pendingRequest = zoneState.out; // cancel pending requests if any
|
||||||
|
} else {
|
||||||
|
zone.pendingRequest = type; // failed to log, setup pending request
|
||||||
|
this.log('pending request from invalid');
|
||||||
|
this.setNotification('Pending request from invalid', 'zone: ' + zone.Description + ' request type: ' + type);
|
||||||
|
}
|
||||||
|
this.storeZones(this.zonesList);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Requests geofence zones list
|
||||||
|
*/
|
||||||
|
private requestZones() {
|
||||||
|
const req = this.auth.getPublicRequest();
|
||||||
|
this.con.postNoLoad(GeofencingService.zonesUrl, req, _ => { // TODO: handle error
|
||||||
|
}).subscribe((response: any) => {
|
||||||
|
if (this.cs.validResponse(response)) {
|
||||||
|
if (this.cs.hasData(response.GeoF_PointsList)) {
|
||||||
|
// update zonelist if it doesnt exist or if the server has an updated one
|
||||||
|
if (!this.cs.hasData(this.zonesList) || (this.zonesList.length !== response.GeoF_PointsList.length)) {
|
||||||
|
this.log('setting new zone list');
|
||||||
|
this.zonesList = response.GeoF_PointsList;
|
||||||
|
for (const zone of this.zonesList) {
|
||||||
|
zone.in = false;
|
||||||
|
}
|
||||||
|
this.log('storing zones');
|
||||||
|
this.storeZones(this.zonesList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Store zones list in local storage
|
||||||
|
*/
|
||||||
|
public async storeZones(zones: ZoneModel []) {
|
||||||
|
return await this.storage.setItem(GeofencingService.ZONES_KEY, zones);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Retrieve and set list of zones from local storage
|
||||||
|
*/
|
||||||
|
public async setZones() {
|
||||||
|
try {
|
||||||
|
const data = await this.storage.getItem(GeofencingService.ZONES_KEY);
|
||||||
|
if (this.cs.hasData(data)) {
|
||||||
|
this.zonesList = data;
|
||||||
|
} else {
|
||||||
|
this.requestZones(); // zones list not stored in local storage
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
this.requestZones(); // zones list not stored in local storage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async storeUserData(user: GeoUserModel) {
|
||||||
|
return await this.storage.setItem(GeofencingService.USER_DATA_KEY, user);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Retrieve and set user data from local storage
|
||||||
|
*/
|
||||||
|
public async setUserFromStorage() {
|
||||||
|
const data = await this.storage.getItem(GeofencingService.USER_DATA_KEY);
|
||||||
|
if (data) {
|
||||||
|
this.userData = data;
|
||||||
|
} else {
|
||||||
|
this.userData = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// turns location tracking on. Sets geo user data and zones list
|
||||||
|
*/
|
||||||
|
public async turnTrackingOn(patientID?: number, outSa?: number): Promise<boolean> {
|
||||||
|
this.toast('turning tracking on');
|
||||||
|
// set zones list from storage
|
||||||
|
await this.setZones();
|
||||||
|
// update zone list from server
|
||||||
|
this.requestZones();
|
||||||
|
|
||||||
|
// Set user data
|
||||||
|
if (patientID) {
|
||||||
|
this.userData = new GeoUserModel;
|
||||||
|
this.userData.PatientID = patientID;
|
||||||
|
this.userData.PatientOutSA = outSa;
|
||||||
|
} else if (!this.userData) {
|
||||||
|
try {
|
||||||
|
await this.setUserFromStorage();
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.userData.isTrackingOn = true;
|
||||||
|
this.storeUserData(this.userData);
|
||||||
|
this.startTracking();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// turns location tracking off. Stops background tracking
|
||||||
|
*/
|
||||||
|
public turnTrackingOff() {
|
||||||
|
this.toast('turning tracking off');
|
||||||
|
this.stopTracking();
|
||||||
|
if (this.userData) {
|
||||||
|
this.userData.isTrackingOn = false;
|
||||||
|
this.storeUserData(this.userData);
|
||||||
|
} else {
|
||||||
|
this.setUserFromStorage().then(() => {
|
||||||
|
this.userData.isTrackingOn = false;
|
||||||
|
this.storeUserData(this.userData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Check if geofencing service is enabled
|
||||||
|
*/
|
||||||
|
public async isTrackingEnabled(): Promise<boolean> {
|
||||||
|
// if (this.userData) {
|
||||||
|
// return this.userData.isTrackingOn;
|
||||||
|
// } else {
|
||||||
|
try {
|
||||||
|
await this.setUserFromStorage();
|
||||||
|
if (this.userData) {
|
||||||
|
return this.userData.isTrackingOn;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
throw false;
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// setup and start background gelocation plugin
|
||||||
|
*/
|
||||||
|
public startTracking() {
|
||||||
|
const config: BackgroundGeolocationConfig = {
|
||||||
|
desiredAccuracy: 10000, // HIGH_ACCURACY = 1 // low = 10000
|
||||||
|
stationaryRadius: 20, // 20
|
||||||
|
distanceFilter: 10, // 10
|
||||||
|
debug: false, // enable this hear sounds for background-geolocation life-cycle.
|
||||||
|
stopOnTerminate: false, // enable this to clear background location settings when the app terminates
|
||||||
|
// startOnBoot: true,
|
||||||
|
// Android options
|
||||||
|
notificationsEnabled: false,
|
||||||
|
interval: 60000, // interval vars for improved battery life
|
||||||
|
fastestInterval: 120000,
|
||||||
|
activitiesInterval: 10000,
|
||||||
|
startForeground: false,
|
||||||
|
notificationTitle: 'Running in the background',
|
||||||
|
notificationText: '',
|
||||||
|
// IOS options
|
||||||
|
saveBatteryOnBackground: false
|
||||||
|
};
|
||||||
|
this.backgroundGeolocation.configure(config)
|
||||||
|
.then((location: BackgroundGeolocationResponse) => {
|
||||||
|
});
|
||||||
|
|
||||||
|
this.backgroundGeolocation.on(BackgroundGeolocationEvents.location)
|
||||||
|
.subscribe((location: BackgroundGeolocationResponse) => {
|
||||||
|
this.reportLocation(location);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.backgroundGeolocation.on(BackgroundGeolocationEvents.stationary)
|
||||||
|
.subscribe((location: BackgroundGeolocationResponse) => {
|
||||||
|
this.reportLocation(location);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.storage.getItem(GeofencingService.GEO_STATUS_KEY).then(status => {
|
||||||
|
if (!status) {
|
||||||
|
this.backgroundGeolocation.start();
|
||||||
|
this.storage.setItem(GeofencingService.GEO_STATUS_KEY, true);
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
this.toast('turning geofencing on');
|
||||||
|
this.backgroundGeolocation.start();
|
||||||
|
this.storage.setItem(GeofencingService.GEO_STATUS_KEY, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Helper to startTracking()
|
||||||
|
*/
|
||||||
|
private async reportLocation(location: BackgroundGeolocationResponse) {
|
||||||
|
// Check if zones and user is set
|
||||||
|
if (!this.userData) {
|
||||||
|
await this.setUserFromStorage();
|
||||||
|
}
|
||||||
|
if (!this.cs.hasData(this.zonesList)) {
|
||||||
|
await this.setZones();
|
||||||
|
}
|
||||||
|
if (this.platform.is('ios')) {
|
||||||
|
this.backgroundGeolocation.startTask().then((taskKey) => {
|
||||||
|
this.checklocationInZones(location, this.zonesList, this.userData);
|
||||||
|
this.backgroundGeolocation.endTask(taskKey);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.checklocationInZones(location, this.zonesList, this.userData);
|
||||||
|
}
|
||||||
|
this.storeZones(this.zonesList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// stops background geoloacation plugin tracking
|
||||||
|
*/
|
||||||
|
public stopTracking() {
|
||||||
|
this.toast('Stop Tracking' );
|
||||||
|
this.storage.setItem(GeofencingService.GEO_STATUS_KEY, false);
|
||||||
|
this.backgroundGeolocation.stop().then(value => {
|
||||||
|
// this.toast('Stop Tracking value returned: ' + value);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Checks if given location triggers any zone events (enter, exit) for all zones, and pauses the service if
|
||||||
|
// the location was far from all zones
|
||||||
|
*/
|
||||||
|
private checklocationInZones(location: BackgroundGeolocationResponse, zones: ZoneModel [], user: GeoUserModel) {
|
||||||
|
this.printLocation(location, 'check location in zones');
|
||||||
|
let currentMinDist = 9999999;
|
||||||
|
for (const zone of zones) {
|
||||||
|
const userLocation = new LocationModel(location.latitude, location.longitude);
|
||||||
|
const event = this.checkLocationInZone(userLocation, zone);
|
||||||
|
const currentDistance = this.distanceFromZone(userLocation, zone);
|
||||||
|
currentMinDist = (currentMinDist > currentDistance ? currentDistance : currentMinDist);
|
||||||
|
if (zone.GEOF_ID === 16) {
|
||||||
|
this.log(zone.Description);
|
||||||
|
this.log('zone state: ' + zone.in + ' pending: ' + zone.pendingRequest + 'current event: ' + event);
|
||||||
|
}
|
||||||
|
if (event === zoneState.in) {
|
||||||
|
zone.in = true;
|
||||||
|
}
|
||||||
|
// send enter request
|
||||||
|
if (event === zoneState.enter ||
|
||||||
|
(event === zoneState.in && zone.pendingRequest === zoneState.enter)) {
|
||||||
|
zone.in = true;
|
||||||
|
this.setNotification('Enter ZONE ' + zone.Description, 'location lat: ' + location.latitude + ' lng: ' + location.longitude);
|
||||||
|
this.log('enter Zone' + zone.Description + ' ' + 'location: ' + location.latitude + ',' + location.longitude);
|
||||||
|
this.logLocation(zone.GEOF_ID, zoneState.enter, user, zone);
|
||||||
|
}
|
||||||
|
// send exit request
|
||||||
|
if (event === zoneState.exit ||
|
||||||
|
(event === zoneState.out && zone.pendingRequest === zoneState.exit)) {
|
||||||
|
zone.in = false;
|
||||||
|
this.setNotification('Exit ZONE ' + zone.Description, 'location lat: ' + location.latitude + ' lng: ' + location.longitude);
|
||||||
|
this.log('exit Zone' + zone.Description + ' ' + 'location: ' + location.latitude + ',' + location.longitude);
|
||||||
|
this.logLocation(zone.GEOF_ID, zoneState.exit, user, zone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const minDist = this.toDecimalDegrees(5000); // minimum distance location needs to be to all zones to pause service
|
||||||
|
const maxDist = this.toDecimalDegrees(10000); // Max distance used to have a factor between 0-1
|
||||||
|
if (currentMinDist >= minDist) {
|
||||||
|
const currentDis = (currentMinDist > maxDist ? maxDist : currentMinDist);
|
||||||
|
this.pauseService((currentDis - minDist) / (maxDist - minDist));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Checks the state of given location for the given zone
|
||||||
|
*/
|
||||||
|
private checkLocationInZone(userLocation: LocationModel, zone: ZoneModel): zoneState {
|
||||||
|
const isIn = this.isPointInZone(userLocation.lng, userLocation.lat, zone.Longitude,
|
||||||
|
zone.Latitude, this.toDecimalDegrees(zone.Radius));
|
||||||
|
if (isIn === false && zone.in === true) {
|
||||||
|
return zoneState.exit;
|
||||||
|
}
|
||||||
|
if (isIn === true && zone.in === false) {
|
||||||
|
return zoneState.enter;
|
||||||
|
}
|
||||||
|
if (isIn) {
|
||||||
|
return zoneState.in;
|
||||||
|
}
|
||||||
|
return zoneState.out;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// calculates the distance between given location and given zone
|
||||||
|
*/
|
||||||
|
private distanceFromZone(userLocation: LocationModel, zone: ZoneModel): number {
|
||||||
|
return this.distance(userLocation.lng, userLocation.lat, zone.Longitude, zone.Latitude);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// checks if a point p is in a circular zone with center z and radius r
|
||||||
|
*/
|
||||||
|
public isPointInZone(xp, yp, xz, yz, r): boolean {
|
||||||
|
return this.distance(xp, yp, xz, yz) < r;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Measures distance between two points
|
||||||
|
*/
|
||||||
|
public distance(xp, yp, xz, yz): number {
|
||||||
|
return Math.sqrt(Math.pow(Math.abs(xp - xz), 2) + Math.pow(Math.abs(yp - yz) , 2));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Convert meters to decimal degrees
|
||||||
|
*/
|
||||||
|
public toDecimalDegrees(meters: number) {
|
||||||
|
return meters / 1000 / 111.32;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Pauses tracking service for a time multiplied by given factor
|
||||||
|
*/
|
||||||
|
public pauseService(factor: number) {
|
||||||
|
if (!this.isPaused) {
|
||||||
|
this.stopTracking();
|
||||||
|
this.isPaused = true;
|
||||||
|
// time to pause min=120 sec max=1800 sec
|
||||||
|
const time = (1680000 * factor); // time in milliseconds
|
||||||
|
this.setNotification('pausing tracking service', 'Pause for ' + time + ' FYI factor is: ' + factor);
|
||||||
|
setTimeout(() => {
|
||||||
|
this.startTracking();
|
||||||
|
this.isPaused = false;
|
||||||
|
this.setNotification('resuming tracking service', 'Paused for ' + time + ' FYI factor is: ' + factor);
|
||||||
|
}, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public startGeoFromHome() {
|
||||||
|
if (this.cs.isCordova()) {
|
||||||
|
this.isTrackingEnabled().then((result) => {
|
||||||
|
if (result) {
|
||||||
|
this.turnTrackingOff();
|
||||||
|
this.turnTrackingOn();
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// first time login, setup geofencing
|
||||||
|
// local storage should reset when user logs out
|
||||||
|
if (this.authService.isAuthenticated()) {
|
||||||
|
const user = this.authService.getAuthenticatedUser();
|
||||||
|
this.turnTrackingOff();
|
||||||
|
this.cs.presentConfirmDialog(this.ts.trPK('settings', 'enable-geo'), () => {
|
||||||
|
this.turnTrackingOn(user.PatientID, +user.PatientOutSA);
|
||||||
|
}, () => {
|
||||||
|
this.turnTrackingOn(user.PatientID, +user.PatientOutSA);
|
||||||
|
this.turnTrackingOff();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- TESTING FUNCTIONS -------------- //
|
||||||
|
public setNotification(title: string, text: string) {
|
||||||
|
if (this.debug) {
|
||||||
|
const date = new Date();
|
||||||
|
date.setSeconds(date.getSeconds() + 2);
|
||||||
|
this.notif.createNotification(title, text, date, 'geofencing');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public printLocation(location: BackgroundGeolocationResponse, source: string) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log('-------------------------------------------------------------');
|
||||||
|
console.log(source);
|
||||||
|
console.log(this.zonesList);
|
||||||
|
console.log(location);
|
||||||
|
console.log('location: ' + location.latitude + ', ' + location.longitude);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public printAllLocations() {
|
||||||
|
if (this.debug) {
|
||||||
|
this.backgroundGeolocation.getLocations().then(locations => {
|
||||||
|
console.log(locations);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public log(msg: string) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public toast(msg: string) {
|
||||||
|
if (this.debug) {
|
||||||
|
this.cs.toast(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
export class GeoUserModel {
|
||||||
|
PatientID: number;
|
||||||
|
PatientOutSA: number;
|
||||||
|
isTrackingOn: boolean;
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
import { Request } from 'src/app/hmg-common/services/models/request';
|
||||||
|
|
||||||
|
export class InsertLocationRequest extends Request {
|
||||||
|
PointsID: number;
|
||||||
|
GeoType: number; // 1 enter 2 exit
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
export class LocationModel {
|
||||||
|
lat: number;
|
||||||
|
lng: number;
|
||||||
|
constructor(lat: number, lng: number, radius?: number, name?: string) {
|
||||||
|
this.lat = lat;
|
||||||
|
this.lng = lng;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { zoneState } from '../geofencing.service';
|
||||||
|
|
||||||
|
export class ZoneModel {
|
||||||
|
CreatedBy?: number;
|
||||||
|
CreatedOn?: string;
|
||||||
|
Description: string;
|
||||||
|
DescriptionN?: string;
|
||||||
|
GEOF_ID?: number;
|
||||||
|
IsCity?: boolean;
|
||||||
|
Latitude: string;
|
||||||
|
Longitude: string;
|
||||||
|
ProjectID?: number;
|
||||||
|
Radius: number;
|
||||||
|
Type?: number;
|
||||||
|
in: boolean;
|
||||||
|
pendingRequest: zoneState;
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GuidService } from './guid.service';
|
||||||
|
|
||||||
|
describe('GuidService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: GuidService = TestBed.get(GuidService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class GuidService {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
public generate(): string {
|
||||||
|
let result = '';
|
||||||
|
let i: string;
|
||||||
|
|
||||||
|
for ( let j = 0; j < 32; j++) {
|
||||||
|
if (j == 8 || j == 12 || j == 16 || j == 20)
|
||||||
|
{
|
||||||
|
result = result + '-';
|
||||||
|
}
|
||||||
|
i = Math.floor(Math.random() * 16).toString(16).toUpperCase();
|
||||||
|
result = result + i;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HmgBrowserService } from './hmg-browser.service';
|
||||||
|
|
||||||
|
describe('HmgBrowserService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: HmgBrowserService = TestBed.get(HmgBrowserService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,101 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ThemeableBrowser, ThemeableBrowserOptions, ThemeableBrowserObject } from '@ionic-native/themeable-browser/ngx';
|
||||||
|
import { Platform } from '@ionic/angular';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class HmgBrowserService {
|
||||||
|
static options: ThemeableBrowserOptions = {
|
||||||
|
statusbar: {
|
||||||
|
color: '#ffffffff'
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
height: 44,
|
||||||
|
color: '#f0f0f0ff'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
color: '#60686b',
|
||||||
|
showPageTitle: true
|
||||||
|
},
|
||||||
|
backButton: {
|
||||||
|
image: 'back',
|
||||||
|
imagePressed: 'back_pressed',
|
||||||
|
align: 'left',
|
||||||
|
event: 'backPressed'
|
||||||
|
},
|
||||||
|
forwardButton: {
|
||||||
|
image: 'forward',
|
||||||
|
imagePressed: 'forward_pressed',
|
||||||
|
align: 'left',
|
||||||
|
event: 'forwardPressed'
|
||||||
|
},
|
||||||
|
closeButton: {
|
||||||
|
image: 'close',
|
||||||
|
imagePressed: 'close_pressed',
|
||||||
|
align: 'left',
|
||||||
|
event: 'closePressed'
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
customButtons: [
|
||||||
|
{
|
||||||
|
image: 'share',
|
||||||
|
imagePressed: 'share_pressed',
|
||||||
|
align: 'right',
|
||||||
|
event: 'sharePressed'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
menu: {
|
||||||
|
image: 'menu',
|
||||||
|
imagePressed: 'menu_pressed',
|
||||||
|
title: 'Test',
|
||||||
|
cancel: 'Cancel',
|
||||||
|
align: 'right',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
event: 'helloPressed',
|
||||||
|
label: 'Hello World!'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
event: 'testPressed',
|
||||||
|
label: 'Test!'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
backButtonCanClose: true
|
||||||
|
};
|
||||||
|
|
||||||
|
private browser: ThemeableBrowserObject;
|
||||||
|
constructor(
|
||||||
|
private themeableBrowser: ThemeableBrowser,
|
||||||
|
private platform: Platform
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public registerBack(event: any) {
|
||||||
|
this.registerEvent('backPressed', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public registerClose(event: any) {
|
||||||
|
this.registerEvent('closePressed', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private registerEvent(eventName: string, event: any) {
|
||||||
|
if (this.browser) {
|
||||||
|
this.browser.on(eventName).subscribe((data: any) => {
|
||||||
|
if (event) {
|
||||||
|
event();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public openURLThemable(url: string) {
|
||||||
|
this.platform.ready().then(() => {
|
||||||
|
this.browser = this.themeableBrowser.create(url, '_blank', HmgBrowserService.options);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
export class KeyboardStatusModel {
|
||||||
|
constructor ( public opened: boolean ) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { KeyboardService } from './keyboard.service';
|
||||||
|
|
||||||
|
describe('KeyboardService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: KeyboardService = TestBed.get(KeyboardService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
import { Injectable, AfterViewInit } from "@angular/core";
|
||||||
|
import { Events, Platform } from "@ionic/angular";
|
||||||
|
import { CommonService } from "../common/common.service";
|
||||||
|
import { Keyboard } from "@ionic-native/keyboard/ngx";
|
||||||
|
import { KeyboardStatusModel } from "./keyboard-status.model";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: "root"
|
||||||
|
})
|
||||||
|
export class KeyboardService {
|
||||||
|
public static KEYBOARD_STATUS = "keyboard-status-event";
|
||||||
|
public static keyboardOpened = false;
|
||||||
|
public static isOpened() {
|
||||||
|
return KeyboardService.keyboardOpened;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public events: Events,
|
||||||
|
public cs: CommonService,
|
||||||
|
public keyboard: Keyboard,
|
||||||
|
public platform: Platform
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public watchKeyboard() {
|
||||||
|
this.platform.ready().then(() => {
|
||||||
|
window.addEventListener('keyboardDidHide', () => {
|
||||||
|
this.publishEvent(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('keyboardDidShow', () => {
|
||||||
|
this.publishEvent(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
this.keyboard.onKeyboardHide().subscribe( (observer) => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
this.keyboard.onKeyboardHide().subscribe(() => {
|
||||||
|
this.publishEvent(false);
|
||||||
|
});
|
||||||
|
this.keyboard.onKeyboardShow().subscribe(() => {
|
||||||
|
this.publishEvent(true);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private publishEvent(opened: boolean) {
|
||||||
|
KeyboardService.keyboardOpened = opened;
|
||||||
|
this.events.publish(
|
||||||
|
KeyboardService.KEYBOARD_STATUS,
|
||||||
|
new KeyboardStatusModel(opened)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LazyLoadingService } from './lazy-loading.service';
|
||||||
|
|
||||||
|
describe('LazyLoadingService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: LazyLoadingService = TestBed.get(LazyLoadingService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { CommonService } from "../common/common.service";
|
||||||
|
import {
|
||||||
|
Router,
|
||||||
|
RouteConfigLoadStart,
|
||||||
|
RouteConfigLoadEnd
|
||||||
|
} from "@angular/router";
|
||||||
|
import { Route } from "@angular/compiler/src/core";
|
||||||
|
import { TranslatorService } from "../translator/translator.service";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: "root"
|
||||||
|
})
|
||||||
|
export class LazyLoadingService {
|
||||||
|
private static id = "splash-screen-custom";
|
||||||
|
|
||||||
|
private modulesCount = 5;
|
||||||
|
private loadedModulesCount = 0;
|
||||||
|
private isPresented = false;
|
||||||
|
constructor(public ts: TranslatorService, public router: Router) {
|
||||||
|
this.startSplashScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
monitorLazyLoading(modulesCount: number, debug = false) {
|
||||||
|
this.modulesCount = modulesCount;
|
||||||
|
this.loadedModulesCount = 0;
|
||||||
|
this.router.events.subscribe(event => {
|
||||||
|
if (event instanceof RouteConfigLoadStart) {
|
||||||
|
//console.log('start:' + event.route.path);
|
||||||
|
this.startSplashScreen();
|
||||||
|
} else if (event instanceof RouteConfigLoadEnd) {
|
||||||
|
//console.log('end:' + event.route.path);
|
||||||
|
if (++this.loadedModulesCount >= this.modulesCount) {
|
||||||
|
this.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( debug ) {
|
||||||
|
console.log('module:' + event.route.path + ' lazy modules:' + this.loadedModulesCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public startSplashScreen() {
|
||||||
|
if (!this.isPresented) {
|
||||||
|
this.isPresented = true;
|
||||||
|
document.body.appendChild(this.createSplashScreen());
|
||||||
|
this.disableEventsPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private disableEventsPropagation() {
|
||||||
|
const view = document.getElementById(LazyLoadingService.id);
|
||||||
|
|
||||||
|
view.addEventListener("click", e => {
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public dismiss() {
|
||||||
|
// this.isPresented = false;
|
||||||
|
const element = document.getElementById(LazyLoadingService.id);
|
||||||
|
if (element) {
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private innerTemplate(message: string): string {
|
||||||
|
return " <div class='splash' ></div> " + " <p>" + message + "</p>";
|
||||||
|
}
|
||||||
|
private createSplashScreen() {
|
||||||
|
const elemDiv = document.createElement("div");
|
||||||
|
elemDiv.id = LazyLoadingService.id;
|
||||||
|
elemDiv.className = "splash-screen-page";
|
||||||
|
//elemDiv.innerHTML = this.innerTemplate(this.ts.trPK('general', 'loading'));
|
||||||
|
return elemDiv;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LifeCycleService } from './life-cycle.service';
|
||||||
|
|
||||||
|
describe('LifeCycleService', () => {
|
||||||
|
beforeEach(() => TestBed.configureTestingModule({}));
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const service: LifeCycleService = TestBed.get(LifeCycleService);
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Router, NavigationEnd, NavigationStart } from '@angular/router';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class LifeCycleService {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public router: Router
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public pageRevisited(pageName: string): Observable<boolean> {
|
||||||
|
return Observable.create(observer => {
|
||||||
|
this.router.events.subscribe((val) => {
|
||||||
|
if (this.isSamePage(val, pageName)) {
|
||||||
|
observer.next(true);
|
||||||
|
observer.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private isSamePage(val: any, pageName: string) {
|
||||||
|
if (val instanceof NavigationEnd) {
|
||||||
|
const lastIndex = val.urlAfterRedirects.lastIndexOf('/');
|
||||||
|
const currentPageName = val.urlAfterRedirects.substr(lastIndex + 1);
|
||||||
|
return currentPageName === pageName;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { Request } from './request';
|
||||||
|
|
||||||
|
export class AppointmentRequest extends Request{
|
||||||
|
public AppointmentNo: number;
|
||||||
|
|
||||||
|
public setAppointment(no: number) {
|
||||||
|
this.AppointmentNo = no;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
import { Request } from './request';
|
||||||
|
|
||||||
|
export class EmailRequest extends Request {
|
||||||
|
DoctorName: string;
|
||||||
|
ProjectName: string;
|
||||||
|
ClinicName: string; // personal information
|
||||||
|
ProjectID: number;
|
||||||
|
DateofBirth: string; // json date personal information
|
||||||
|
PatientIditificationNum: string;
|
||||||
|
PatientMobileNumber: string;
|
||||||
|
PatientName: string;
|
||||||
|
PatientOutSA: number;
|
||||||
|
PatientTypeID: number;
|
||||||
|
To: string; // user email
|
||||||
|
SetupID: string;
|
||||||
|
OrderDate: string; // iso date
|
||||||
|
InvoiceNo: string;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
export class ExaminationInfo {
|
||||||
|
ProjectName: string;
|
||||||
|
ClinicName: string;
|
||||||
|
DoctorName: string;
|
||||||
|
ProjectID: string;
|
||||||
|
OrderDate: string;
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
// tslint:disable-next-line:class-name
|
||||||
|
export enum GENDER_TYPE {
|
||||||
|
MAN = 1,
|
||||||
|
WOMAN = 2
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
export enum PATIENT_POSITION {
|
||||||
|
INSIDE_KSA = 0,
|
||||||
|
OUTSIDE_KSA = 1
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
export enum PATIENT_TYPE {
|
||||||
|
TEMPORARILY = 0,
|
||||||
|
PERMANENT = 1
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue