working updates.
This commit is contained in:
parent
9e1c7455d1
commit
3c02bede7a
|
@ -5,7 +5,7 @@
|
|||
<app-medical-sources-card class="col-sm-3 mg-b-20 px-3"
|
||||
*ngFor="let sourceData of connectedSourceList"
|
||||
[sourceInfo]="sourceData"
|
||||
[status]="status[sourceData.metadata.source_type]"
|
||||
[status]="status[sourceData.source.id] || status[sourceData.metadata.source_type]"
|
||||
(onClick)="openModal(contentModalRef, $event)"
|
||||
></app-medical-sources-card>
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,7 @@ import {ToastNotification, ToastType} from '../../models/fasten/toast';
|
|||
import {ToastService} from '../../services/toast.service';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {Location} from '@angular/common';
|
||||
import {EventBusService} from '../../services/event-bus.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-medical-sources-connected',
|
||||
|
@ -33,6 +34,7 @@ export class MedicalSourcesConnectedComponent implements OnInit {
|
|||
private activatedRoute: ActivatedRoute,
|
||||
private router: Router,
|
||||
private location: Location,
|
||||
private eventBusService: EventBusService,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -64,6 +66,9 @@ export class MedicalSourcesConnectedComponent implements OnInit {
|
|||
.then(console.log)
|
||||
}
|
||||
|
||||
this.eventBusService.eventBusSourceSyncMessages.subscribe((event) => {
|
||||
this.status[event.source_id] = "token"
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
@ -171,6 +176,7 @@ export class MedicalSourcesConnectedComponent implements OnInit {
|
|||
.subscribe((resp) => {
|
||||
// const sourceSyncMessage = JSON.parse(msg) as SourceSyncMessage
|
||||
delete this.status[sourceType]
|
||||
delete this.status[resp.source.id]
|
||||
// window.location.reload();
|
||||
// this.connectedSourceList.
|
||||
|
||||
|
@ -269,7 +275,7 @@ export class MedicalSourcesConnectedComponent implements OnInit {
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public openModal(contentModalRef, sourceListItem: SourceListItem) {
|
||||
if(this.status[sourceListItem.metadata.source_type] || !sourceListItem.source){
|
||||
if(this.status[sourceListItem.metadata.source_type] || !sourceListItem.source || this.status[sourceListItem.source.id]){
|
||||
//if this source is currently "loading" dont open the modal window
|
||||
return
|
||||
}
|
||||
|
@ -287,15 +293,17 @@ export class MedicalSourcesConnectedComponent implements OnInit {
|
|||
|
||||
|
||||
public sourceSyncHandler(source: Source){
|
||||
this.status[source.source_type] = "authorize"
|
||||
this.status[source.id] = "authorize"
|
||||
this.modalService.dismissAll()
|
||||
|
||||
this.fastenApi.syncSource(source.id).subscribe(
|
||||
(respData) => {
|
||||
delete this.status[source.id]
|
||||
delete this.status[source.source_type]
|
||||
console.log("source sync response:", respData)
|
||||
},
|
||||
(err) => {
|
||||
delete this.status[source.id]
|
||||
delete this.status[source.source_type]
|
||||
console.log(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export interface Event {
|
||||
event_type: string;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export interface EventSourceComplete extends Event {
|
||||
event_type: string;
|
||||
source_id: string;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export interface EventSourceSync extends Event {
|
||||
event_type: string;
|
||||
source_id: string;
|
||||
resource_type: string;
|
||||
resource_id: string;
|
||||
}
|
|
@ -10,6 +10,7 @@ import * as jose from 'jose';
|
|||
import {UserRegisteredClaims} from '../models/fasten/user-registered-claims';
|
||||
import {uuidV4} from '../../lib/utils/uuid';
|
||||
import {HTTP_CLIENT_TOKEN} from "../dependency-injection";
|
||||
import {BehaviorSubject, Observable, Subject} from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -17,7 +18,7 @@ import {HTTP_CLIENT_TOKEN} from "../dependency-injection";
|
|||
export class AuthService {
|
||||
|
||||
FASTEN_JWT_LOCALSTORAGE_KEY = 'token';
|
||||
|
||||
public IsAuthenticatedSubject = new BehaviorSubject<boolean>(false)
|
||||
constructor(@Inject(HTTP_CLIENT_TOKEN) private _httpClient: HttpClient) {
|
||||
}
|
||||
|
||||
|
@ -129,17 +130,21 @@ export class AuthService {
|
|||
this.setAuthToken(resp.data)
|
||||
}
|
||||
|
||||
|
||||
//TODO: now that we've moved to remote-first database, we can refactor and simplify this function significantly.
|
||||
public async IsAuthenticated(): Promise<boolean> {
|
||||
let authToken = this.GetAuthToken()
|
||||
let hasAuthToken = !!authToken
|
||||
if(!hasAuthToken){
|
||||
this.publishAuthenticationState(false)
|
||||
return false
|
||||
}
|
||||
|
||||
//todo: check if the authToken has expired
|
||||
return true
|
||||
//check if the authToken has expired
|
||||
let jwtClaims = jose.decodeJwt(authToken)
|
||||
let valid = Date.now() < (jwtClaims.exp * 1000);
|
||||
this.publishAuthenticationState(valid)
|
||||
return valid
|
||||
|
||||
|
||||
// //check if the authToken has expired.
|
||||
// let databaseEndpointBase = GetEndpointAbsolutePath(globalThis.location, environment.couchdb_endpoint_base)
|
||||
|
@ -180,6 +185,7 @@ export class AuthService {
|
|||
}
|
||||
|
||||
public async Logout(): Promise<any> {
|
||||
this.publishAuthenticationState(false)
|
||||
return localStorage.removeItem(this.FASTEN_JWT_LOCALSTORAGE_KEY)
|
||||
// // let remotePouchDb = new PouchDB(this.getRemoteUserDb(localStorage.getItem("current_user")), {skip_setup: true});
|
||||
// if(this.pouchDb){
|
||||
|
@ -192,6 +198,13 @@ export class AuthService {
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private setAuthToken(token: string) {
|
||||
this.publishAuthenticationState(true)
|
||||
localStorage.setItem(this.FASTEN_JWT_LOCALSTORAGE_KEY, token)
|
||||
}
|
||||
|
||||
private publishAuthenticationState(authenticated){
|
||||
if(this.IsAuthenticatedSubject.value != authenticated){
|
||||
this.IsAuthenticatedSubject.next(authenticated)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EventBusService } from './event-bus.service';
|
||||
|
||||
describe('EventBusService', () => {
|
||||
let service: EventBusService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(EventBusService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
import {AfterViewInit, Injectable, OnInit} from '@angular/core';
|
||||
import {NavigationEnd, Router} from '@angular/router';
|
||||
import {BehaviorSubject, Observable, Subject, Subscription} from 'rxjs';
|
||||
import {AuthService} from './auth.service';
|
||||
import {FastenApiService} from './fasten-api.service';
|
||||
import {ToastService} from './toast.service';
|
||||
import {Event} from '../models/events/event';
|
||||
import {EventSourceComplete} from '../models/events/event_source_complete';
|
||||
import {EventSourceSync} from '../models/events/event_source_sync';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class EventBusService {
|
||||
eventBusSubscription: Subscription | undefined;
|
||||
eventBusSourceSyncMessages: Subject<EventSourceSync> = new Subject<EventSourceSync>();
|
||||
eventBusSourceCompleteMessages: Subject<EventSourceComplete> = new Subject<EventSourceComplete>();
|
||||
|
||||
constructor(
|
||||
public router: Router,
|
||||
public authService: AuthService,
|
||||
public fastenApiService: FastenApiService,
|
||||
public toastService: ToastService
|
||||
) {
|
||||
|
||||
// Ideally we want consistently listen to events, but only when the user is authenticated.
|
||||
//TODO: find a way to abort the event bus connection.
|
||||
this.authService.IsAuthenticatedSubject.subscribe((isAuthenticated) => {
|
||||
console.log("isAuthenticated changed:", isAuthenticated)
|
||||
if(isAuthenticated){
|
||||
this.eventBusSubscription = this.fastenApiService.listenEventBus().subscribe((event: Event | EventSourceSync | EventSourceComplete)=>{
|
||||
console.log("eventbus event:", event)
|
||||
//TODO: start toasts.
|
||||
if(event.event_type == "source_sync"){
|
||||
this.eventBusSourceSyncMessages.next(event as EventSourceSync)
|
||||
} else if(event.event_type == "source_complete"){
|
||||
this.eventBusSourceCompleteMessages.next(event as EventSourceComplete)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
//no longer authenticated, unsubscribe from eventbus
|
||||
if(this.eventBusSubscription){
|
||||
this.eventBusSubscription.unsubscribe()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ export class FastenApiService {
|
|||
'Authorization': `Bearer ${this.authService.GetAuthToken()}`
|
||||
},
|
||||
onmessage(ev) {
|
||||
observer.next(ev.data);
|
||||
observer.next(JSON.parse(ev.data));
|
||||
},
|
||||
onerror(event) {
|
||||
observer.error(event)
|
||||
|
|
Loading…
Reference in New Issue