Catalog alignment
[sdc.git] / catalog-ui / src / app / ng2 / components / ui / download-artifact / download-artifact.component.ts
1 import { Component, Input } from "@angular/core";
2 import {IFileDownload, Component as TopologyTemplate, ArtifactModel, FullComponentInstance} from "app/models";
3 import {EventListenerService} from "app/services";
4 import {CacheService} from "app/services-ng2";
5 import {EVENTS} from "app/utils";
6 import { TopologyTemplateService } from "app/ng2/services/component-services/topology-template.service";
7 import { WorkspaceService } from "app/ng2/pages/workspace/workspace.service";
8 import { ComponentInstanceServiceNg2 } from "app/ng2/services/component-instance-services/component-instance.service";
9
10 @Component({
11     selector: 'download-artifact',
12     template: `
13         <svg-icon [mode]="'primary2'" [disabled]="disabled" [clickable]="!disabled" [name]="iconType" [testId]="testId" mode="info" clickable="true" size="medium" (click)="download($event)"></svg-icon>
14 `
15 })
16 export class DownloadArtifactComponent {
17     
18     @Input() showLoader:boolean;
19     @Input() artifact:ArtifactModel;
20     @Input() isInstance: boolean;
21     @Input() downloadIconClass: string;
22     @Input() componentType: string;
23     @Input() componentId: string;
24     @Input() testId: string;
25     @Input() disabled: boolean;
26
27     public iconType:string;
28
29     private DOWNLOAD_CSS_CLASSES = {
30         DOWNLOAD_ICON: "download-o",
31         LOADER_ICON: "spinner"
32     }
33     constructor(private cacheService:CacheService, private EventListenerService:EventListenerService, private topologyTemplateService:TopologyTemplateService,
34                 private componentInstanceService: ComponentInstanceServiceNg2, private workspaceService:WorkspaceService) {
35         
36     }
37
38     ngOnInit () {
39         this.iconType = this.DOWNLOAD_CSS_CLASSES.DOWNLOAD_ICON;
40         this.initDownloadLoader();
41
42     }
43
44     private initDownloadLoader = ()=> {
45         //if the artifact is in a middle of download progress register form callBack & change icon from download to loader
46         if (this.showLoader && this.cacheService.get(this.artifact.uniqueId)) {
47             this.EventListenerService.registerObserverCallback(EVENTS.DOWNLOAD_ARTIFACT_FINISH_EVENT + this.artifact.uniqueId, this.updateDownloadIcon);
48             window.setTimeout(():void => {
49                 if (this.cacheService.get(this.artifact.uniqueId)) {
50                     this.iconType = this.DOWNLOAD_CSS_CLASSES.LOADER_ICON;
51                 }
52             }, 1000);
53         }
54     };
55
56     private updateDownloadIcon = () => {
57         this.iconType = this.downloadIconClass || this.DOWNLOAD_CSS_CLASSES.DOWNLOAD_ICON;
58     };
59
60     public download = (event) => {
61         event.stopPropagation();
62         let onFaild = (response):void => {
63             console.info('onFaild', response);
64             this.removeDownloadedFileLoader();
65         };
66
67         let onSuccess = (data:IFileDownload):void => {
68             this.downloadFile(data);
69             this.removeDownloadedFileLoader();
70         };
71
72         this.setDownloadedFileLoader();
73
74         if (this.isInstance) {
75             this.componentInstanceService.downloadInstanceArtifact(this.workspaceService.metadata.componentType, this.workspaceService.metadata.uniqueId, this.componentId, this.artifact.uniqueId).subscribe(onSuccess, onFaild);
76         } else {
77             this.topologyTemplateService.downloadArtifact(this.componentType, this.componentId, this.artifact.uniqueId).subscribe(onSuccess, onFaild);
78         }
79     };
80
81     private setDownloadedFileLoader = ()=> {
82         if (this.showLoader) {
83             //set in cache service thet the artifact is in download progress
84             this.cacheService.set(this.artifact.uniqueId, true);
85             this.initDownloadLoader();
86         }
87     };
88
89     private removeDownloadedFileLoader = ()=> {
90         if (this.showLoader) {
91             this.cacheService.set(this.artifact.uniqueId, false);
92             this.EventListenerService.notifyObservers(EVENTS.DOWNLOAD_ARTIFACT_FINISH_EVENT + this.artifact.uniqueId);
93         }
94     };
95
96     private downloadFile = (file:IFileDownload):void => {
97         if (file) {
98             let blob = this.base64toBlob(file.base64Contents, '');
99             let fileName = file.artifactName;
100             this.triggerFileDownload(blob, fileName);
101         }
102     };
103
104     public base64toBlob = (base64Data, contentType):any => {
105         let byteCharacters = atob(base64Data);
106         return this.byteCharactersToBlob(byteCharacters, contentType);
107     };
108
109     public byteCharactersToBlob = (byteCharacters, contentType):any => {
110         contentType = contentType || '';
111         let sliceSize = 1024;
112         let bytesLength = byteCharacters.length;
113         let slicesCount = Math.ceil(bytesLength / sliceSize);
114         let byteArrays = new Array(slicesCount);
115
116         for (let sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
117             let begin = sliceIndex * sliceSize;
118             let end = Math.min(begin + sliceSize, bytesLength);
119
120             let bytes = new Array(end - begin);
121             for (let offset = begin, i = 0; offset < end; ++i, ++offset) {
122                 bytes[i] = byteCharacters[offset].charCodeAt(0);
123             }
124             byteArrays[sliceIndex] = new Uint8Array(bytes);
125         }
126         return new Blob(byteArrays, {type: contentType});
127     };
128
129     public triggerFileDownload = (blob, fileName):void=> {
130         let url = window.URL.createObjectURL(blob);
131         let downloadLink = document.createElement("a");
132
133         downloadLink.setAttribute('href', url);
134         downloadLink.setAttribute('download', fileName);
135         document.body.appendChild(downloadLink);
136
137         var clickEvent = new MouseEvent("click", {
138             "view": window,
139             "bubbles": true,
140             "cancelable": true
141         });
142         downloadLink.dispatchEvent(clickEvent);
143
144     }
145 }