application skeleton
parent
62f2cfcda3
commit
48a4360ac1
@ -1,3 +1,83 @@
|
||||
<ion-app>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-app>
|
||||
|
||||
<!-- <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>
|
||||
@ -1,26 +1,36 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
import { Platform } from '@ionic/angular';
|
||||
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
|
||||
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
|
||||
import { Platform, Events, MenuController } from '@ionic/angular';
|
||||
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({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html'
|
||||
selector: 'app-root',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
templateUrl: 'app.component.html'
|
||||
})
|
||||
export class AppComponent {
|
||||
constructor(
|
||||
private platform: Platform,
|
||||
private splashScreen: SplashScreen,
|
||||
private statusBar: StatusBar
|
||||
) {
|
||||
this.initializeApp();
|
||||
}
|
||||
export class AppComponent implements OnInit, AfterViewInit {
|
||||
// rootPage:any = LoginPage;
|
||||
// @ViewChild(Nav) nav: Nav;
|
||||
|
||||
menuList:any=[];
|
||||
User_name_Emp:string="";
|
||||
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