adding loading spinner to desktop callback.
make sure modal popup is closed in sources window when app is redirected.
This commit is contained in:
parent
0ce1b3f20f
commit
7dc0318931
|
@ -30,7 +30,7 @@ export class AppComponent implements OnInit {
|
|||
|
||||
modifyHeader(event) {
|
||||
if (event instanceof NavigationEnd) {
|
||||
if (event.url?.startsWith('/auth')) {
|
||||
if (event.url?.startsWith('/auth') || event.url?.startsWith('/desktop')) {
|
||||
this.showHeader = false;
|
||||
} else {
|
||||
// console.log("NU")
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
<p>desktop-callback works!</p>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<app-loading-spinner [loadingTitle]="'Please wait, completing connection...'"></app-loading-spinner>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-desktop-callback',
|
||||
|
@ -8,14 +9,14 @@ import { Component, OnInit } from '@angular/core';
|
|||
export class DesktopCallbackComponent implements OnInit {
|
||||
|
||||
//This component is used to redirect the user to the desktop app after they have authenticated with a source
|
||||
constructor() { }
|
||||
constructor(private activatedRoute : ActivatedRoute) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
wails.Event.Emit({
|
||||
name: "wails:fasten-lighthouse:success",
|
||||
data:
|
||||
|
||||
)
|
||||
this.activatedRoute.queryParams.subscribe(values => {
|
||||
wails.Events.Emit({
|
||||
name: "wails:fasten-lighthouse:response",
|
||||
data: values,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import {LighthouseSourceMetadata} from '../../models/lighthouse/lighthouse-sourc
|
|||
import {Source} from '../../models/fasten/source';
|
||||
import {MetadataSource} from '../../models/fasten/metadata-source';
|
||||
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
|
||||
import {ActivatedRoute} from '@angular/router';
|
||||
import {ActivatedRoute, Router, UrlSerializer} from '@angular/router';
|
||||
import {environment} from '../../../environments/environment';
|
||||
import {BehaviorSubject, forkJoin, Observable, of, Subject} from 'rxjs';
|
||||
import {
|
||||
|
@ -17,7 +17,7 @@ import {debounceTime, distinctUntilChanged, pairwise, startWith} from 'rxjs/oper
|
|||
import {MedicalSourcesFilter, MedicalSourcesFilterService} from '../../services/medical-sources-filter.service';
|
||||
import {FormControl, FormGroup} from '@angular/forms';
|
||||
import * as _ from 'lodash';
|
||||
// If you dont import this angular will import the wrong "Location"
|
||||
import {Location} from '@angular/common';
|
||||
|
||||
export const sourceConnectWindowTimeout = 24*5000 //wait 2 minutes (5 * 24 = 120)
|
||||
|
||||
|
@ -79,6 +79,9 @@ export class MedicalSourcesComponent implements OnInit {
|
|||
private activatedRoute: ActivatedRoute,
|
||||
private filterService: MedicalSourcesFilterService,
|
||||
private modalService: NgbModal,
|
||||
private router: Router,
|
||||
private urlSerializer: UrlSerializer,
|
||||
private location: Location,
|
||||
) {
|
||||
this.filterService.filterChanges.subscribe((filterInfo) => {
|
||||
|
||||
|
@ -284,8 +287,31 @@ export class MedicalSourcesComponent implements OnInit {
|
|||
let authorizationUrl = await this.lighthouseApi.generateSourceAuthorizeUrl(sourceType, sourceMetadata)
|
||||
|
||||
console.log('authorize url:', authorizationUrl.toString());
|
||||
// redirect to lighthouse with uri's
|
||||
this.lighthouseApi.redirectWithOriginAndDestination(authorizationUrl.toString(), sourceType, sourceMetadata.redirect_uri)
|
||||
// redirect to lighthouse with uri's (or open a new window in desktop mode)
|
||||
this.lighthouseApi.redirectWithOriginAndDestination(authorizationUrl.toString(), sourceType, sourceMetadata.redirect_uri).subscribe((codeData) => {
|
||||
//Note: this code will only run in Desktop mode (with popups)
|
||||
//in non-desktop environments, the user is redirected in the same window, and this code is never executed.
|
||||
|
||||
//always close the modal
|
||||
this.modalService.dismissAll()
|
||||
|
||||
if(!codeData){
|
||||
//if we redirected completely, no callback data will be present.
|
||||
return
|
||||
}
|
||||
|
||||
//User was shown a popup, which was closed, and data was returned using events
|
||||
//redirect to callback page with code
|
||||
|
||||
let urlTree = this.router.createUrlTree(
|
||||
['/sources/callback/' + sourceType],
|
||||
{ queryParams: codeData, }
|
||||
);
|
||||
|
||||
let absUrl = this.location.prepareExternalUrl(this.urlSerializer.serialize(urlTree))
|
||||
console.log(absUrl);
|
||||
window.location.replace(absUrl)
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {Inject, Injectable} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {Observable, of, throwError, fromEvent } from 'rxjs';
|
||||
import {Observable, of, throwError, bindCallback} from 'rxjs';
|
||||
import {environment} from '../../environments/environment';
|
||||
import {concatMap, delay, retryWhen, timeout, first, map, filter, catchError, tap} from 'rxjs/operators';
|
||||
import {ResponseWrapper} from '../models/response-wrapper';
|
||||
|
@ -146,7 +146,7 @@ export class LighthouseService {
|
|||
* dest_url - https://patient360la.anthem.com/.../connect/authorize?redirect_uri=https://lighthouse.fastenhealth.com/callback/anthem
|
||||
* redirect_url - lighthouse.fastenhealth.com/sandbox/redirect/anthem?origin_url=...&dest_url=...
|
||||
*/
|
||||
redirectWithOriginAndDestination(destUrl: string, sourceType: string, callbackUri: string): void {
|
||||
redirectWithOriginAndDestination(destUrl: string, sourceType: string, callbackUri: string): Observable<any> {
|
||||
const originUrlParts = new URL(window.location.href)
|
||||
|
||||
if(environment.environment_desktop){
|
||||
|
@ -171,23 +171,15 @@ export class LighthouseService {
|
|||
if(environment.environment_desktop && environment.popup_source_auth){
|
||||
//@ts-ignore
|
||||
|
||||
OpenExternalLink(redirectUrlParts.toString(), environment.environment_desktop)
|
||||
// let openedWindow = window.runtime.BrowserOpenURL(redirectUrlParts.toString());
|
||||
OpenExternalLink(redirectUrlParts.toString(), environment.environment_desktop, sourceType)
|
||||
|
||||
wails.Event.Once("wails:fasten-lighthouse:success", (code: string) => {
|
||||
console.log("GOT CODE FROM DESKTOP", code)
|
||||
|
||||
})
|
||||
|
||||
this.waitForDesktopCodeOrTimeout(null, sourceType).subscribe(async (codeData) => {
|
||||
//TODO: redirect to the callback url with the code.
|
||||
console.log("DONE WAITING FOR CODE")
|
||||
})
|
||||
return this.waitForDesktopCodeOrTimeout(sourceType)
|
||||
|
||||
//now wait for response from the opened window
|
||||
} else {
|
||||
//redirect to the url in the same window
|
||||
window.location.href = redirectUrlParts.toString();
|
||||
return of(null) //should never happen
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -260,26 +252,32 @@ export class LighthouseService {
|
|||
return parts.join(separator);
|
||||
}
|
||||
|
||||
private waitForDesktopCodeOrTimeout(openedWindow: Window, sourceType: string): Observable<any> {
|
||||
console.log(`waiting for postMessage notification from ${sourceType} window`)
|
||||
private waitForDesktopCodeOrTimeout(sourceType: string): Observable<any> {
|
||||
console.log(`waiting for wails Event notification from window`)
|
||||
|
||||
if(typeof wails == "undefined"){
|
||||
return throwError("wails is not defined, this is likely because you're running in a browser.")
|
||||
}
|
||||
|
||||
let fromWailsEvent = bindCallback(wails.Events.Once)
|
||||
|
||||
//new code to listen to post message
|
||||
return fromEvent(window, 'message')
|
||||
return fromWailsEvent('wails:fasten-lighthouse:response')
|
||||
.pipe(
|
||||
//throw an error if we wait more than 2 minutes (this will close the window)
|
||||
timeout(sourceConnectDesktopTimeout),
|
||||
//make sure we're only listening to events from the "opened" window.
|
||||
filter((event: MessageEvent) => event.source == openedWindow),
|
||||
filter((eventPayload: any ) => eventPayload.sender == sourceType),
|
||||
//after filtering, we should only have one event to handle.
|
||||
first(),
|
||||
map((event) => {
|
||||
console.log(`received postMessage notification from ${sourceType} window & sending acknowledgment`, event)
|
||||
console.log(`received wails event notification from ${sourceType} window & sending acknowledgment`, event)
|
||||
// @ts-ignore
|
||||
event.source.postMessage(JSON.stringify({close:true}), event.origin);
|
||||
return event.data
|
||||
}),
|
||||
catchError((err) => {
|
||||
console.warn(`timed out waiting for notification from ${sourceType} (${sourceConnectDesktopTimeout/1000}s), closing window`)
|
||||
openedWindow.self.close()
|
||||
wails.Application.GetWindowByName(sourceType).Window.Close()
|
||||
return throwError(err)
|
||||
})
|
||||
)
|
||||
|
|
|
@ -3,7 +3,7 @@ export const environment = {
|
|||
environment_cloud: false,
|
||||
environment_desktop: true,
|
||||
environment_name: "desktop_prod",
|
||||
popup_source_auth: false,
|
||||
popup_source_auth: true,
|
||||
|
||||
lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/v1',
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export function OpenExternalLink(url: string, desktopMode: boolean){
|
||||
export function OpenExternalLink(url: string, desktopMode: boolean, windowId?: string){
|
||||
//check if url starts with https, and if not, prepend it (external links are never relative)
|
||||
if(!url.startsWith("https://") && !url.startsWith("http://")){
|
||||
url = "https://" + url;
|
||||
|
@ -6,7 +6,7 @@ export function OpenExternalLink(url: string, desktopMode: boolean){
|
|||
|
||||
//check if wails exists and is defined
|
||||
if(typeof wails !== "undefined" && desktopMode){
|
||||
wails.CallByName("pkg.AppService.BrowserOpenURL", url)
|
||||
wails.CallByName("pkg.AppService.BrowserOpenURL", url, windowId || 'external')
|
||||
} else{
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
|
|
|
@ -66,7 +66,10 @@ declare global {
|
|||
// let wails: any
|
||||
|
||||
let wails: {
|
||||
Event: {
|
||||
Application: {
|
||||
GetWindowByName: (sourceType: string) => any
|
||||
}
|
||||
Events: {
|
||||
Emit: (event: any) => void
|
||||
Once: (eventName, callback) => void
|
||||
On: (eventName, callback) => void
|
||||
|
|
Loading…
Reference in New Issue