From 23389fca6a9b6c3ef22f3f76511cd77e02f76e8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Wed, 18 Jan 2023 12:52:57 +0100 Subject: [PATCH] fixing and refactoring frontend --- .browserslistrc | 3 +- .hintrc | 7 +- src/app/gui/modal/modal.component.ts | 2 +- src/app/helpers/plugin.ts | 38 +++------- src/app/pages/about/about.component.html | 20 +++--- .../client-download.component.html | 2 +- .../client-download.component.ts | 4 -- .../pages/downloads/downloads.component.html | 2 +- .../pages/downloads/downloads.component.ts | 21 +++--- src/app/pages/error/error.component.ts | 2 +- src/app/uds-api.service-type.ts | 3 + src/app/uds-api.service.ts | 71 +++++++++---------- 12 files changed, 74 insertions(+), 101 deletions(-) diff --git a/.browserslistrc b/.browserslistrc index bc4ef54..2895490 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -5,8 +5,7 @@ # You can see what browsers were selected by your queries by running: # npx browserslist -> 0.2% +> 0.2% and not dead last 2 versions last 4 years Firefox ESR -not dead diff --git a/.hintrc b/.hintrc index cda7829..8e92c6f 100644 --- a/.hintrc +++ b/.hintrc @@ -7,5 +7,10 @@ "axe/text-alternatives": "off", "button-type": "off", "typescript-config/consistent-casing": "off" - } + }, + "browserslist": [ + "defaults", + "not ie 11", + "not ie <= 10" + ] } \ No newline at end of file diff --git a/src/app/gui/modal/modal.component.ts b/src/app/gui/modal/modal.component.ts index 54335cf..00aa5ca 100644 --- a/src/app/gui/modal/modal.component.ts +++ b/src/app/gui/modal/modal.component.ts @@ -51,7 +51,7 @@ export class ModalComponent implements OnInit { this.extra = ' (' + Math.floor(miliseconds / 1000) + ' ' + django.gettext('seconds') + ') '; } - async initAlert(): Promise { + async initAlert() { const autoclose = this.data.autoclose || 0; if (autoclose > 0) { this.dialogRef.afterClosed().subscribe((res) => { diff --git a/src/app/helpers/plugin.ts b/src/app/helpers/plugin.ts index 8f367d6..b9f12da 100644 --- a/src/app/helpers/plugin.ts +++ b/src/app/helpers/plugin.ts @@ -15,7 +15,7 @@ export class Plugin { this.delay = api.config.launcher_wait_time; } - async launchURL(url: string): Promise { + async launchURL(url: string) { // If uds url... if (url.substring(0, 7) === 'udsa://') { await this.processUDSUrl(url); @@ -45,27 +45,7 @@ export class Plugin { * @param url uds url to be lauhcned */ private launchUDSUrl(url: string) { - let elem: HTMLIFrameElement = document.getElementById( - 'hiddenUdsLauncherIFrame' - ) as HTMLIFrameElement; - if (elem === null) { - const i = document.createElement('div'); - i.id = 'testID'; - i.innerHTML = - ''; - document.body.appendChild(i); - elem = document.getElementById( - 'hiddenUdsLauncherIFrame' - ) as HTMLIFrameElement; - } - // Ensure all is ok - if (elem === null) { - throw new Error('Unable to create hidden iframe'); - } - if (elem.contentWindow === null) { - throw new Error('Unable to get content window'); - } - elem.contentWindow.location.href = url; + this.api.download(url); } /** @@ -74,7 +54,7 @@ export class Plugin { * @param url uds url (udsa://serviceId/transportId) * @returns nothing */ - private async processUDSUrl(url: string): Promise { + private async processUDSUrl(url: string) { // Extract params from url, serviceId and transportId const params = url.split('//')[1].split('/'); if (params.length !== 2) { @@ -96,7 +76,7 @@ export class Plugin { // Connect close dialog to "cancel" variable toPromise(dialog.afterClosed()).then(() => (cancel = true)); - let readyTime = -1; + let readySinceTime = -1; try { // Enable service const enabledData = await this.api.enabler(serviceId, transportId); @@ -119,7 +99,7 @@ export class Plugin { while (!cancel) { const data = await this.api.status(serviceId, transportId); // Wait 5 times the default delay before notifying that client is not installed - if (readyTime > 0 && Date.now() - readyTime > this.delay * 5) { + if (readySinceTime > 0 && Date.now() - readySinceTime > this.delay * 5) { dialog.componentInstance.data.title = django.gettext('Service ready') + ' - ' + @@ -137,9 +117,9 @@ export class Plugin { ''; } if (data.status === 'ready') { - if (readyTime === -1) { + if (readySinceTime === -1) { // Service is ready, wait for client, update dialog text - readyTime = Date.now(); // Milisecodns + readySinceTime = Date.now(); // Milisecodns dialog.componentInstance.data.title = django.gettext('Service ready'); dialog.componentInstance.data.body = django.gettext( @@ -167,7 +147,7 @@ export class Plugin { } } - private async processExternalUrl(url: string): Promise { + private async processExternalUrl(url: string) { const dialog = await this.showAlert( django.gettext('Please wait until the service is launched.'), django.gettext( @@ -281,7 +261,7 @@ export class Plugin { } } - private async notifyError(error?: any): Promise { + private async notifyError(error?: any) { let msg: string = django.gettext( 'Error communicating with your service. Please, retry again.' ); diff --git a/src/app/pages/about/about.component.html b/src/app/pages/about/about.component.html index ad06a35..03cd256 100644 --- a/src/app/pages/about/about.component.html +++ b/src/app/pages/about/about.component.html @@ -1,8 +1,8 @@

Universal Desktop Services {{ api.config.version }} build {{ api.config.version_stamp }}

-

© 2012-{{ year }} Virtual Cable S.L.U.

+

© 2012-{{ year }} Virtual Cable S.L.U.

- You can access UDS Open Source code at You can access UDS Open Source code at OpenUDS github repository

@@ -10,15 +10,15 @@ UDS has been developed using these components:

* If you find that we missed any component, please let us know

diff --git a/src/app/pages/client-download/client-download.component.html b/src/app/pages/client-download/client-download.component.html index 0be9471..f31c8c1 100644 --- a/src/app/pages/client-download/client-download.component.html +++ b/src/app/pages/client-download/client-download.component.html @@ -10,7 +10,7 @@
-
+
diff --git a/src/app/pages/client-download/client-download.component.ts b/src/app/pages/client-download/client-download.component.ts index 7f1e101..2c83e68 100644 --- a/src/app/pages/client-download/client-download.component.ts +++ b/src/app/pages/client-download/client-download.component.ts @@ -15,10 +15,6 @@ export class ClientDownloadComponent implements OnInit { ngOnInit() { } - download(url: string) { - window.location.href = url; - } - img(image: string) { return this.api.staticURL( 'modern/img/' + image + '.png'); } diff --git a/src/app/pages/downloads/downloads.component.html b/src/app/pages/downloads/downloads.component.html index 2baeee3..c5e0028 100644 --- a/src/app/pages/downloads/downloads.component.html +++ b/src/app/pages/downloads/downloads.component.html @@ -9,7 +9,7 @@
-
+
diff --git a/src/app/pages/downloads/downloads.component.ts b/src/app/pages/downloads/downloads.component.ts index 4887866..e1a76d2 100644 --- a/src/app/pages/downloads/downloads.component.ts +++ b/src/app/pages/downloads/downloads.component.ts @@ -5,31 +5,27 @@ import { Downloadable } from '../../types/config'; @Component({ selector: 'uds-downloads', templateUrl: './downloads.component.html', - styleUrls: ['./downloads.component.scss'] + styleUrls: ['./downloads.component.scss'], }) export class DownloadsComponent implements OnInit { - actors: Downloadable[] = []; - constructor(public api: UDSApiService) { } + constructor(public api: UDSApiService) {} ngOnInit() { - this.actors = []; // Put legacy at end of downloadables... + // Sort legacy actors to the end of the list + this.actors = []; // Put legacy at end of downloadables... const legacy: Downloadable[] = []; - this.api.actors.forEach(a => { + for (const a of this.api.actors) { if (a.name.includes('legacy')) { legacy.push(a); } else { this.actors.push(a); } - }); - legacy.forEach(l => { + } + for (const l of legacy) { this.actors.push(l); - }); - } - - download(url: string) { - window.location.href = url; + } } img(filename: string) { @@ -52,5 +48,4 @@ export class DownloadsComponent implements OnInit { } return styles; } - } diff --git a/src/app/pages/error/error.component.ts b/src/app/pages/error/error.component.ts index b512e69..f8f3730 100644 --- a/src/app/pages/error/error.component.ts +++ b/src/app/pages/error/error.component.ts @@ -17,7 +17,7 @@ export class ErrorComponent implements OnInit { await this.getError(); } - async getError(): Promise { + async getError() { const id = this.route.snapshot.paramMap.get('id') || '-1'; if (id === '19') { // 19 is MFA error, return to MFA this.returnUrl = '/mfa'; diff --git a/src/app/uds-api.service-type.ts b/src/app/uds-api.service-type.ts index f0388a5..d54db6e 100644 --- a/src/app/uds-api.service-type.ts +++ b/src/app/uds-api.service-type.ts @@ -42,6 +42,9 @@ export interface UDSApiServiceType { /* Executes logout */ logout(): void; + /* Download file/launches a custom uro */ + download(url: string): Promise; + /* sleep milliseconds */ sleep(ms: number): Promise; /** diff --git a/src/app/uds-api.service.ts b/src/app/uds-api.service.ts index 77906c9..9972341 100644 --- a/src/app/uds-api.service.ts +++ b/src/app/uds-api.service.ts @@ -19,7 +19,6 @@ import { UDSApiServiceType } from './uds-api.service-type'; import { environment } from '../environments/environment'; - const DARK_THEME = 'dark-theme'; const LIGHT_THEME = 'light-theme'; const TIMEOUT = 10000; @@ -32,14 +31,10 @@ const toPromise = (observable: Observable, wait?: number): Promise => { @Injectable() export class UDSApiService implements UDSApiServiceType { readonly user: User; - transportsWindow: Window|null = null; + transportsWindow: Window | null = null; 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.plugin = new Plugin(this); } @@ -91,32 +86,20 @@ export class UDSApiService implements UDSApiServiceType { } /* Client enabler */ - async enabler( - serviceId: string, - transportId: string - ): Promise { - const enabler = this.config.urls.enabler - .replace('param1', serviceId) - .replace('param2', transportId); + async enabler(serviceId: string, transportId: string): Promise { + const enabler = this.config.urls.enabler.replace('param1', serviceId).replace('param2', transportId); return toPromise(this.http.get(enabler)); } /* Check userService status */ - async status( - serviceId: string, - transportId: string - ): Promise { - const status = this.config.urls.status - .replace('param1', serviceId) - .replace('param2', transportId); + async status(serviceId: string, transportId: string): Promise { + const status = this.config.urls.status.replace('param1', serviceId).replace('param2', transportId); return toPromise(this.http.get(status)); } /* Services resetter */ async action(action: string, serviceId: string): Promise { - 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 toPromise(this.http.get(actionURL)); } @@ -131,9 +114,7 @@ export class UDSApiService implements UDSApiServiceType { password: string, domain: string ): Promise { - const url = this.config.urls.updateTransportTicket - .replace('param1', ticketId) - .replace('param2', scrambler); + const url = this.config.urls.updateTransportTicket.replace('param1', ticketId).replace('param2', scrambler); return toPromise( this.http.post(url, { username, @@ -164,20 +145,14 @@ export class UDSApiService implements UDSApiServiceType { * Gets services information */ async getServicesInformation(): Promise { - return toPromise( - this.http.get(this.config.urls.services) - ); + return toPromise(this.http.get(this.config.urls.services)); } /** * Gets error string from a code */ async getErrorInformation(errorCode: string): Promise { - return toPromise( - this.http.get( - this.config.urls.error.replace('9999', errorCode) - ) - ); + return toPromise(this.http.get(this.config.urls.error.replace('9999', errorCode))); } /** @@ -200,6 +175,28 @@ export class UDSApiService implements UDSApiServiceType { window.location.href = this.config.urls.logout; } + async download(url: string): Promise { + // Launch the download + // Create an iframe and set the src to the url + // This will trigger the download + // First, loof for an existing download iframe + let iframe = document.getElementById('download') as HTMLIFrameElement; + // If not found, create it + if (!iframe) { + iframe = document.createElement('iframe'); + iframe.id = 'download'; + iframe.style.display = 'none'; + document.body.appendChild(iframe); + } + // Set the src to the url + iframe.src = url; + // onload in iframe will only be triggered if an html page is downloaded. If it is loaded, it's not a download + iframe.onload = () => { + alert('Error downloading file. Please try again later.'); + }; + //window.location.href = url; + } + sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } @@ -215,9 +212,7 @@ export class UDSApiService implements UDSApiServiceType { * @returns Observable */ async getAuthCustomJavascript(authId: string): Promise { - return toPromise( - this.http.get(this.config.urls.customAuth + authId, {responseType: 'text'}) - ); + return toPromise(this.http.get(this.config.urls.customAuth + authId, { responseType: 'text' })); } // Switch dark/light theme