diff --git a/ui-ngx/src/app/core/http/device.service.ts b/ui-ngx/src/app/core/http/device.service.ts index fbabbaadfa..55c1dd5b57 100644 --- a/ui-ngx/src/app/core/http/device.service.ts +++ b/ui-ngx/src/app/core/http/device.service.ts @@ -28,13 +28,13 @@ import { DeviceInfo, DeviceInfoQuery, DeviceSearchQuery, - PublishLaunchCommand, PublishTelemetryCommand } from '@shared/models/device.models'; import { EntitySubtype } from '@shared/models/entity-type.models'; import { AuthService } from '@core/auth/auth.service'; import { BulkImportRequest, BulkImportResult } from '@shared/import-export/import-export.models'; import { PersistentRpc, RpcStatus } from '@shared/models/rpc.models'; +import { ResourcesService } from '@core/services/resources.service'; @Injectable({ providedIn: 'root' @@ -42,7 +42,8 @@ import { PersistentRpc, RpcStatus } from '@shared/models/rpc.models'; export class DeviceService { constructor( - private http: HttpClient + private http: HttpClient, + private resourcesService: ResourcesService ) { } public getDeviceInfosByQuery(deviceInfoQuery: DeviceInfoQuery, config?: RequestConfig): Observable> { @@ -215,8 +216,7 @@ export class DeviceService { return this.http.get(`/api/device-connectivity/${deviceId}`, defaultHttpOptionsFromConfig(config)); } - public getDevicePublishLaunchCommands(deviceId: string, config?: RequestConfig): Observable { - return this.http.get(`/api/device-connectivity/gateway-launch/${deviceId}`, defaultHttpOptionsFromConfig(config)); + public downloadGatewayDockerComposeFile(deviceId: string): Observable { + return this.resourcesService.downloadResource(`/api/device-connectivity/gateway-launch/${deviceId}/docker-compose/download`); } - } diff --git a/ui-ngx/src/app/core/http/image.service.ts b/ui-ngx/src/app/core/http/image.service.ts index b7a5ac9dab..b0fb772130 100644 --- a/ui-ngx/src/app/core/http/image.service.ts +++ b/ui-ngx/src/app/core/http/image.service.ts @@ -30,6 +30,7 @@ import { import { catchError, map, switchMap } from 'rxjs/operators'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { blobToBase64 } from '@core/utils'; +import { ResourcesService } from '@core/services/resources.service'; @Injectable({ providedIn: 'root' @@ -37,7 +38,8 @@ import { blobToBase64 } from '@core/utils'; export class ImageService { constructor( private http: HttpClient, - private sanitizer: DomSanitizer + private sanitizer: DomSanitizer, + private resourcesService: ResourcesService ) { } @@ -113,34 +115,7 @@ export class ImageService { } public downloadImage(type: ImageResourceType, key: string): Observable { - return this.http.get(`${IMAGES_URL_PREFIX}/${type}/${encodeURIComponent(key)}`, { - responseType: 'arraybuffer', - observe: 'response' - }).pipe( - map((response) => { - const headers = response.headers; - const filename = headers.get('x-filename'); - const contentType = headers.get('content-type'); - const linkElement = document.createElement('a'); - try { - const blob = new Blob([response.body], {type: contentType}); - const url = URL.createObjectURL(blob); - linkElement.setAttribute('href', url); - linkElement.setAttribute('download', filename); - const clickEvent = new MouseEvent('click', - { - view: window, - bubbles: true, - cancelable: false - } - ); - linkElement.dispatchEvent(clickEvent); - return null; - } catch (e) { - throw e; - } - }) - ); + return this.resourcesService.downloadResource(`${IMAGES_URL_PREFIX}/${type}/${encodeURIComponent(key)}`); } public deleteImage(type: ImageResourceType, key: string, force = false, config?: RequestConfig) { diff --git a/ui-ngx/src/app/core/http/ota-package.service.ts b/ui-ngx/src/app/core/http/ota-package.service.ts index bc3131fba5..6a8e995fb8 100644 --- a/ui-ngx/src/app/core/http/ota-package.service.ts +++ b/ui-ngx/src/app/core/http/ota-package.service.ts @@ -27,12 +27,13 @@ import { OtaPagesIds, OtaUpdateType } from '@shared/models/ota-package.models'; -import { catchError, map, mergeMap } from 'rxjs/operators'; +import { catchError, mergeMap } from 'rxjs/operators'; import { deepClone } from '@core/utils'; import { BaseData } from '@shared/models/base-data'; import { EntityId } from '@shared/models/id/entity-id'; import { TranslateService } from '@ngx-translate/core'; import { DialogService } from '@core/services/dialog.service'; +import { ResourcesService } from '@core/services/resources.service'; @Injectable({ providedIn: 'root' @@ -41,7 +42,8 @@ export class OtaPackageService { constructor( private http: HttpClient, private translate: TranslateService, - private dialogService: DialogService + private dialogService: DialogService, + private resourcesService: ResourcesService ) { } @@ -65,31 +67,7 @@ export class OtaPackageService { } public downloadOtaPackage(otaPackageId: string): Observable { - return this.http.get(`/api/otaPackage/${otaPackageId}/download`, { responseType: 'arraybuffer', observe: 'response' }).pipe( - map((response) => { - const headers = response.headers; - const filename = headers.get('x-filename'); - const contentType = headers.get('content-type'); - const linkElement = document.createElement('a'); - try { - const blob = new Blob([response.body], { type: contentType }); - const url = URL.createObjectURL(blob); - linkElement.setAttribute('href', url); - linkElement.setAttribute('download', filename); - const clickEvent = new MouseEvent('click', - { - view: window, - bubbles: true, - cancelable: false - } - ); - linkElement.dispatchEvent(clickEvent); - return null; - } catch (e) { - throw e; - } - }) - ); + return this.resourcesService.downloadResource(`/api/otaPackage/${otaPackageId}/download`); } public saveOtaPackage(otaPackage: OtaPackage, config?: RequestConfig): Observable { diff --git a/ui-ngx/src/app/core/http/resource.service.ts b/ui-ngx/src/app/core/http/resource.service.ts index d6820f93cb..86ffff87cf 100644 --- a/ui-ngx/src/app/core/http/resource.service.ts +++ b/ui-ngx/src/app/core/http/resource.service.ts @@ -21,15 +21,17 @@ import { defaultHttpOptionsFromConfig, RequestConfig } from '@core/http/http-uti import { forkJoin, Observable, of } from 'rxjs'; import { PageData } from '@shared/models/page/page-data'; import { Resource, ResourceInfo, ResourceType } from '@shared/models/resource.models'; -import { catchError, map, mergeMap } from 'rxjs/operators'; +import { catchError, mergeMap } from 'rxjs/operators'; import { isNotEmptyStr } from '@core/utils'; +import { ResourcesService } from '@core/services/resources.service'; @Injectable({ providedIn: 'root' }) export class ResourceService { constructor( - private http: HttpClient + private http: HttpClient, + private resourcesService: ResourcesService ) { } @@ -55,34 +57,7 @@ export class ResourceService { } public downloadResource(resourceId: string): Observable { - return this.http.get(`/api/resource/${resourceId}/download`, { - responseType: 'arraybuffer', - observe: 'response' - }).pipe( - map((response) => { - const headers = response.headers; - const filename = headers.get('x-filename'); - const contentType = headers.get('content-type'); - const linkElement = document.createElement('a'); - try { - const blob = new Blob([response.body], {type: contentType}); - const url = URL.createObjectURL(blob); - linkElement.setAttribute('href', url); - linkElement.setAttribute('download', filename); - const clickEvent = new MouseEvent('click', - { - view: window, - bubbles: true, - cancelable: false - } - ); - linkElement.dispatchEvent(clickEvent); - return null; - } catch (e) { - throw e; - } - }) - ); + return this.resourcesService.downloadResource(`/api/resource/${resourceId}/download`); } public saveResources(resources: Resource[], config?: RequestConfig): Observable { diff --git a/ui-ngx/src/app/core/services/resources.service.ts b/ui-ngx/src/app/core/services/resources.service.ts index f7a34c9ef5..727869e955 100644 --- a/ui-ngx/src/app/core/services/resources.service.ts +++ b/ui-ngx/src/app/core/services/resources.service.ts @@ -33,7 +33,7 @@ import { AuthService } from '@core/auth/auth.service'; import { select, Store } from '@ngrx/store'; import { selectIsAuthenticated } from '@core/auth/auth.selectors'; import { AppState } from '@core/core.state'; -import { tap } from 'rxjs/operators'; +import { map, tap } from 'rxjs/operators'; declare const System; @@ -106,6 +106,37 @@ export class ResourcesService { return this.loadResourceByType(fileType, url); } + public downloadResource(downloadUrl: string): Observable { + return this.http.get(downloadUrl, { + responseType: 'arraybuffer', + observe: 'response' + }).pipe( + map((response) => { + const headers = response.headers; + const filename = headers.get('x-filename'); + const contentType = headers.get('content-type'); + const linkElement = document.createElement('a'); + try { + const blob = new Blob([response.body], {type: contentType}); + const url = URL.createObjectURL(blob); + linkElement.setAttribute('href', url); + linkElement.setAttribute('download', filename); + const clickEvent = new MouseEvent('click', + { + view: window, + bubbles: true, + cancelable: false + } + ); + linkElement.dispatchEvent(clickEvent); + return null; + } catch (e) { + throw e; + } + }) + ); + } + public loadFactories(resourceId: string | TbResourceId, modulesMap: IModulesMap): Observable { const url = this.getDownloadUrl(resourceId); if (this.loadedModulesAndFactories[url]) { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html index 905d33730f..ed327c1c90 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.html @@ -32,10 +32,10 @@
gateway.download-configuration-file
gateway.download-docker-compose
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts index 95de2c4285..24aefe0e8a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/device-gateway-command.component.ts @@ -14,8 +14,8 @@ /// limitations under the License. /// -import { Component, Inject, Input, OnInit } from '@angular/core'; -import { WINDOW } from '@core/services/window.service'; +import { Component, Input } from '@angular/core'; +import { DeviceService } from '@core/http/device.service'; @Component({ selector: 'tb-gateway-command', @@ -23,20 +23,20 @@ import { WINDOW } from '@core/services/window.service'; styleUrls: ['./device-gateway-command.component.scss'] }) -export class DeviceGatewayCommandComponent implements OnInit { +export class DeviceGatewayCommandComponent { @Input() deviceId: string; - downloadUrl: string; - - constructor(@Inject(WINDOW) private window: Window) { + constructor(private deviceService: DeviceService) { } - - ngOnInit(): void { + download($event: Event) { + if ($event) { + $event.stopPropagation(); + } if (this.deviceId) { - this.downloadUrl = `${this.window.location.origin}/api/device-connectivity/gateway-launch/${this.deviceId}/docker-compose/download`; + this.deviceService.downloadGatewayDockerComposeFile(this.deviceId).subscribe(() => {}); } } } diff --git a/ui-ngx/src/app/shared/models/device.models.ts b/ui-ngx/src/app/shared/models/device.models.ts index 64cd6a1909..a82079ce67 100644 --- a/ui-ngx/src/app/shared/models/device.models.ts +++ b/ui-ngx/src/app/shared/models/device.models.ts @@ -865,14 +865,6 @@ export interface PublishTelemetryCommand { snmp?: string; } -export interface PublishLaunchCommand { - mqtt: { - linux: string; - windows: string; - macos: string; - }; -} - export const dayOfWeekTranslations = new Array( 'device-profile.schedule-day.monday', 'device-profile.schedule-day.tuesday',