1
0
mirror of https://github.com/dkmstr/openuds-gui.git synced 2024-10-26 08:55:23 +03:00

Added wait until status is ready for machines on uds client transports && url transports

This commit is contained in:
Adolfo Gómez García 2021-04-29 12:10:17 +02:00
parent 7f015ca7ac
commit 21c412b8ff
8 changed files with 175 additions and 59 deletions

5
src/.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true
}

View File

@ -14,6 +14,7 @@ export interface ModalData {
title: string;
body: string;
autoclose?: number;
checkClose?: Observable<boolean>;
type: DialogType;
}
@ -98,6 +99,17 @@ export class ModalComponent implements OnInit {
/*window.setTimeout(() => {
this.dialogRef.close();
}, this.data.autoclose);*/
} else if (this.data.checkClose) {
this.dialogRef.afterClosed().subscribe(res => {
this.closed();
});
this.subscription = this.data.checkClose.subscribe(res => {
// Invoke the close after, result in fact is not important
window.setTimeout(() => {
this.doClose();
});
});
}
}

View File

@ -2,17 +2,18 @@ import { Injectable } from '@angular/core';
import { ModalComponent, DialogType } from './modal/modal.component';
import { MatDialog } from '@angular/material/dialog';
import { Observable } from 'rxjs';
@Injectable()
export class UDSGuiService {
constructor(public dialog: MatDialog) { }
alert(title: string, message: string, autoclose = 0 ) {
alert(title: string, message: string, autoclose = 0, checkClose: Observable<boolean> = null ) {
const width = window.innerWidth < 800 ? '80%' : '40%';
const dialogRef = this.dialog.open(ModalComponent, {
width,
data: { title, body: message, autoclose, type: DialogType.alert },
data: { title, body: message, autoclose, checkClose, type: DialogType.alert },
disableClose: true,
});
return dialogRef;

View File

@ -1,3 +1,4 @@
import { Observable } from 'rxjs';
import { UDSApiServiceType } from '../uds-api.service-type';
declare const django: any;
@ -17,14 +18,50 @@ export class Plugin {
launchURL(url: string): void {
// If uds url...
if (url.substring(0, 7) === 'udsa://') {
const params = url.split('//')[1].split('/');
this.showAlert(
django.gettext('Please wait until the service is launched.'),
django.gettext(
'Remember that you will need the UDS client on your platform to access the service.'
),
this.delay
0,
// Now UDS tries to check status
new Observable<boolean>((observer) => {
const notifyError = () => {
window.setTimeout(() => {
this.showAlert(
django.gettext('Error'),
django.gettext(
'Error communicating with your service. Please, retry again.'
),
5000
);
});
};
const checker = () => {
this.api.status(params[0], params[1]).subscribe(
(data) => {
if (data.status === 'ready') {
observer.next(true);
observer.complete();
} else if (data.status === 'running') {
window.setTimeout(checker, this.delay); // Recheck after 5 seconds
} else {
observer.next(true);
observer.complete();
notifyError();
}
},
(error) => {
observer.next(true);
observer.complete();
notifyError();
}
);
};
window.setTimeout(checker);
})
);
const params = url.split('//')[1].split('/');
this.api.enabler(params[0], params[1]).subscribe((data) => {
if (data.error) {
// TODO: show the error correctly
@ -52,54 +89,70 @@ export class Plugin {
django.gettext(
'Your connection is being prepared. It will open on a new window when ready.'
),
this.delay * 2
);
this.api.transportUrl(url).subscribe((data) => {
alert.close();
if (data.url) {
if (data.url.indexOf('o_s_w=') !== -1) {
window.location.href = data.url;
} else {
// If the url contains "o_n_w", will open the url on a new window ALWAYS
let name = 'global';
if (data.url.indexOf('o_n_w=') !== -1) {
// Extract window name from o_n_w parameter if present
const onw = /.*o_n_w=([a-zA-Z0-9._-]*)/.exec(data.url);
if (onw) {
name = onw[1];
0,
// Now UDS tries to check status before closing dialog...
new Observable<boolean>((observer) => {
const notifyError = () => {
window.setTimeout(() => {
this.showAlert(
django.gettext('Error'),
django.gettext(
'Error communicating with your service. Please, retry again.'
),
5000
);
});
};
const checker = () => {
this.api.transportUrl(url).subscribe(
(data) => {
if (data.url) {
observer.next(true);
observer.complete(); // Notify window to close...
if (data.url.indexOf('o_s_w=') !== -1) {
window.location.href = data.url;
} else {
// If the url contains "o_n_w", will open the url on a new window ALWAYS
let name = 'global';
if (data.url.indexOf('o_n_w=') !== -1) {
// Extract window name from o_n_w parameter if present
const onw = /.*o_n_w=([a-zA-Z0-9._-]*)/.exec(data.url);
if (onw) {
name = onw[1];
}
}
if (Plugin.transportsWindow[name]) {
Plugin.transportsWindow[name].close();
}
Plugin.transportsWindow[name] = window.open(
data.url,
'uds_trans_' + name
);
}
} else if (!data.running) {
observer.next(true);
observer.complete();
notifyError();
}
},
(error) => {
observer.next(true);
observer.complete();
notifyError();
}
}
if (Plugin.transportsWindow[name]) {
Plugin.transportsWindow[name].close();
}
Plugin.transportsWindow[name] = window.open(
data.url,
'uds_trans_' + name
);
}
} else if (data.running) {
// Already preparing, show some info and request wait a bit to user
this.showAlert(
django.gettext(
'The service is now being prepared. (It is at #).'.replace(
'#',
'' + data.running + '%'
)
),
django.gettext('Please, try again in a few moments.'),
this.delay
);
} else {
// error
this.api.gui.alert(
django.gettext('Error launching service'),
data.error
);
}
});
};
window.setTimeout(checker);
})
);
}
}
private showAlert(text: string, info: string, waitTime: number) {
private showAlert(
text: string,
info: string,
waitTime: number,
checker: Observable<boolean> = null
) {
return this.api.gui.alert(
django.gettext('Launching service'),
'<p stype="font-size: 1.2rem;">' +
@ -107,7 +160,8 @@ export class Plugin {
'</p><p style="font-size: 0.8rem;">' +
info +
'</p>',
waitTime
waitTime,
checker
);
}

View File

@ -24,6 +24,7 @@ export interface UDSUrls {
readonly services: string;
readonly admin: string;
readonly enabler: string;
readonly status: string;
readonly action: string;
readonly galleryImage: string;
readonly transportIcon: string;

View File

@ -49,6 +49,10 @@ export interface JSONEnabledService {
error: string;
}
export interface JSONStatusService {
status: string;
}
export interface JSONTransportURLService {
url?: string;
running?: string;

View File

@ -1,5 +1,11 @@
import { Observable } from 'rxjs';
import { JSONServicesInformation, JSONEnabledService, JSONService, JSONTransportURLService } from './types/services';
import {
JSONServicesInformation,
JSONEnabledService,
JSONStatusService,
JSONService,
JSONTransportURLService,
} from './types/services';
import { UDSGuiService } from './gui/uds-gui.service';
import { UDSConfig } from './types/config';
@ -10,7 +16,16 @@ export interface UDSApiServiceType {
config: UDSConfig;
/* Client enabler */
enabler(serviceId: string, transportId: string): Observable<JSONEnabledService>;
enabler(
serviceId: string,
transportId: string
): Observable<JSONEnabledService>;
/* Service status */
status(
serviceId: string,
transportId: string
): Observable<JSONStatusService>;
/* Services resetter */
action(action: string, serviceId: string): Observable<JSONService>;

View File

@ -3,7 +3,13 @@ import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { User, UDSConfig, Downloadable, Info } from './types/config';
import { Observable } from 'rxjs';
import { JSONServicesInformation, JSONEnabledService, JSONService, JSONTransportURLService } from './types/services';
import {
JSONServicesInformation,
JSONEnabledService,
JSONStatusService,
JSONService,
JSONTransportURLService,
} from './types/services';
import { UDSGuiService } from './gui/uds-gui.service';
import { Plugin } from './helpers/plugin';
@ -13,19 +19,21 @@ import { environment } from '../environments/environment';
declare const udsData: any;
@Injectable()
export class UDSApiService implements UDSApiServiceType {
readonly user: User;
transportsWindow: Window;
plugin: Plugin;
constructor(private http: HttpClient, public gui: UDSGuiService, public router: Router) {
constructor(
private http: HttpClient,
public gui: UDSGuiService,
public router: Router
) {
this.user = new User(udsData.profile);
this.transportsWindow = null;
this.plugin = new Plugin(this);
}
/**
* Gets configuration data from uds.js file
*/
@ -67,13 +75,28 @@ export class UDSApiService implements UDSApiServiceType {
/* Client enabler */
enabler(serviceId: string, transportId: string) {
const enabler = this.config.urls.enabler.replace('param1', serviceId).replace('param2', transportId);
const enabler = this.config.urls.enabler
.replace('param1', serviceId)
.replace('param2', transportId);
return this.http.get<JSONEnabledService>(enabler);
}
/* Check userService status */
status(
serviceId: string,
transportId: string
): Observable<JSONStatusService> {
const status = this.config.urls.status
.replace('param1', serviceId)
.replace('param2', transportId);
return this.http.get<JSONStatusService>(status);
}
/* Services resetter */
action(action: string, serviceId: string) {
const actionURL = this.config.urls.action.replace('param1', serviceId).replace('param2', action);
const actionURL = this.config.urls.action
.replace('param1', serviceId)
.replace('param2', action);
return this.http.get<JSONService>(actionURL);
}
@ -136,7 +159,8 @@ export class UDSApiService implements UDSApiServiceType {
* @returns Observable
*/
getAuthCustomHtml(authId: string) {
return this.http.get(this.config.urls.customAuth + authId, { responseType: 'text' });
return this.http.get(this.config.urls.customAuth + authId, {
responseType: 'text',
});
}
}