Merge pull request #9861 from vvlladd28/bug/gateway-dashboard/download-file
Fixed download gateway launch file and refactoring downloads file
This commit is contained in:
commit
41f81b161c
@ -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<PageData<DeviceInfo>> {
|
||||
@ -215,8 +216,7 @@ export class DeviceService {
|
||||
return this.http.get<PublishTelemetryCommand>(`/api/device-connectivity/${deviceId}`, defaultHttpOptionsFromConfig(config));
|
||||
}
|
||||
|
||||
public getDevicePublishLaunchCommands(deviceId: string, config?: RequestConfig): Observable<PublishLaunchCommand> {
|
||||
return this.http.get<PublishLaunchCommand>(`/api/device-connectivity/gateway-launch/${deviceId}`, defaultHttpOptionsFromConfig(config));
|
||||
public downloadGatewayDockerComposeFile(deviceId: string): Observable<any> {
|
||||
return this.resourcesService.downloadResource(`/api/device-connectivity/gateway-launch/${deviceId}/docker-compose/download`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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<any> {
|
||||
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) {
|
||||
|
||||
@ -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<any> {
|
||||
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<OtaPackage> {
|
||||
|
||||
@ -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<any> {
|
||||
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<Resource[]> {
|
||||
|
||||
@ -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<any> {
|
||||
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<ModulesWithFactories> {
|
||||
const url = this.getDownloadUrl(resourceId);
|
||||
if (this.loadedModulesAndFactories[url]) {
|
||||
|
||||
@ -32,10 +32,10 @@
|
||||
<div class="tb-form-panel-title" translate>gateway.download-configuration-file</div>
|
||||
<div class="tb-form-row no-border no-padding space-between">
|
||||
<div class="tb-no-data-text tb-commands-hint" translate>gateway.download-docker-compose</div>
|
||||
<a mat-stroked-button color="primary" href="{{downloadUrl}}" target="_blank">
|
||||
<button mat-stroked-button color="primary" (click)="download($event)">
|
||||
<mat-icon>download</mat-icon>
|
||||
{{ 'action.download' | translate }}
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -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(() => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,14 +865,6 @@ export interface PublishTelemetryCommand {
|
||||
snmp?: string;
|
||||
}
|
||||
|
||||
export interface PublishLaunchCommand {
|
||||
mqtt: {
|
||||
linux: string;
|
||||
windows: string;
|
||||
macos: string;
|
||||
};
|
||||
}
|
||||
|
||||
export const dayOfWeekTranslations = new Array<string>(
|
||||
'device-profile.schedule-day.monday',
|
||||
'device-profile.schedule-day.tuesday',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user