summaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/directives/download-artifact/download-artifact.ts
blob: 7c817935cf070e4c057f3b404a4a6073d0b4b14e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use strict';
import {IFileDownload, Component, ArtifactModel} from "app/models";
import {EventListenerService, CacheService} from "app/services";
import {EVENTS, FileUtils} from "app/utils";

export class DOWNLOAD_CSS_CLASSES {
    static DOWNLOAD_ICON = "table-download-btn tosca";
    static LOADER_ICON = "tlv-loader small loader";
}

export interface IDownloadArtifactScope extends ng.IScope {
    $window:any;
    artifact:ArtifactModel;
    component:Component;
    instance:boolean;
    download:Function;
    showLoader:boolean;
    downloadIconClass:string;
    updateDownloadIcon:Function;
}

export class DownloadArtifactDirective implements ng.IDirective {

    constructor(private $window:any, private cacheService:CacheService, private EventListenerService:EventListenerService, private fileUtils:FileUtils) {
    }

    scope = {
        artifact: '=',
        component: '=',
        instance: '=',
        showLoader: '=',
        downloadIconClass: '@'
    };
    restrict = 'EA';

    link = (scope:IDownloadArtifactScope, element:any) => {
        scope.$window = this.$window;

        element.on("click", function () {
            scope.download(scope.artifact);
        });


        let initDownloadLoader = ()=> {
            //if the artifact is in a middle of download progress register form callBack & change icon from download to loader
            if (scope.showLoader && this.cacheService.get(scope.artifact.uniqueId)) {
                this.EventListenerService.registerObserverCallback(EVENTS.DOWNLOAD_ARTIFACT_FINISH_EVENT + scope.artifact.uniqueId, scope.updateDownloadIcon);
                window.setTimeout(():void => {
                    if (this.cacheService.get(scope.artifact.uniqueId)) {
                        element[0].className = DOWNLOAD_CSS_CLASSES.LOADER_ICON;
                    }
                }, 1000);

            }
        };

        let setDownloadedFileLoader = ()=> {
            if (scope.showLoader) {
                //set in cache service thet the artifact is in download progress
                this.cacheService.set(scope.artifact.uniqueId, true);
                initDownloadLoader();
            }
        };

        let removeDownloadedFileLoader = ()=> {
            if (scope.showLoader) {
                this.cacheService.set(scope.artifact.uniqueId, false);
                this.EventListenerService.notifyObservers(EVENTS.DOWNLOAD_ARTIFACT_FINISH_EVENT + scope.artifact.uniqueId);
            }
        };


        //replace the loader to download icon
        scope.updateDownloadIcon = () => {
            element[0].className = scope.downloadIconClass || DOWNLOAD_CSS_CLASSES.DOWNLOAD_ICON;
        };


        initDownloadLoader();

        scope.download = (artifact:ArtifactModel):void => {

            let onFaild = (response):void => {
                console.info('onFaild', response);
                removeDownloadedFileLoader();
            };

            let onSuccess = (data:IFileDownload):void => {
                downloadFile(data);
                removeDownloadedFileLoader();
            };

            setDownloadedFileLoader();

            if (scope.instance) {
                scope.component.downloadInstanceArtifact(artifact.uniqueId).then(onSuccess, onFaild);
            } else {
                scope.component.downloadArtifact(artifact.uniqueId).then(onSuccess, onFaild);
            }
        };

        let downloadFile = (file:IFileDownload):void => {
            if (file) {
                let blob = this.fileUtils.base64toBlob(file.base64Contents, '');
                let fileName = file.artifactName;
                this.fileUtils.downloadFile(blob, fileName);
            }
        };

        element.on('$destroy', ()=> {
            //remove listener of download event
            if (scope.artifact && scope.artifact.uniqueId) {
                this.EventListenerService.unRegisterObserver(EVENTS.DOWNLOAD_ARTIFACT_FINISH_EVENT + scope.artifact.uniqueId);
            }
        });

    };

    public static factory = ($window:any, cacheService:CacheService, EventListenerService:EventListenerService, fileUtils:FileUtils)=> {
        return new DownloadArtifactDirective($window, cacheService, EventListenerService, fileUtils);
    };

}

DownloadArtifactDirective.factory.$inject = ['$window', 'Sdc.Services.CacheService', 'EventListenerService', 'FileUtils'];
, slide to it $scope.goToPrevSlide = ():void => { let previousSlide = $scope.slidesData[$scope.currentSlide.index-1]; if (previousSlide) { $scope.goToSlide(previousSlide); } }; // If there's a next slide, slide to it $scope.goToNextSlide = ():void => { let nextSlide = $scope.slidesData[$scope.currentSlide.index+1]; if (nextSlide) { $scope.goToSlide(nextSlide); } }; // Actual transition between slides $scope.goToSlide = (slide:SlideData):void => { //console.log("start goToSlide"); //If the slides are not changing and there's such a slide if(!isAnimating && slide) { //setting animating flag to true isAnimating = true; $scope.currentSlide = slide; $scope.currentSlide.callback(); //Sliding to current slide let calculatedY = pageHeight * ($scope.currentSlide.index); //console.log("$scope.currentSlide.index: " + $scope.currentSlide.index + " | calculatedY: " + calculatedY); $('.slides-container').animate( { scrollTop: calculatedY + 'px' }, { duration: 1000, specialEasing: { width: "linear", height: "easeInOutQuart" }, complete: function() { $scope.onSlideChangeEnd(); } } ); //Animating menu items $(".sdc-page-scroller nav a.active").removeClass("active"); $(".sdc-page-scroller nav [href='#" + $scope.currentSlide.id + "']").addClass("active"); } }; // Once the sliding is finished, we need to restore "isAnimating" flag. // You can also do other things in this function, such as changing page title $scope.onSlideChangeEnd = ():void => { isAnimating = false; }; // When user scrolls with the mouse, we have to change slides $scope.onMouseWheel = (event):void => { //Normalize event wheel delta let delta = event.originalEvent.wheelDelta / 30 || -event.originalEvent.detail; //If the user scrolled up, it goes to previous slide, otherwise - to next slide if(delta < -1) { this.delayAction($scope.goToNextSlide); } else if(delta > 1) { this.delayAction($scope.goToPrevSlide); } event.preventDefault(); }; // Getting the pressed key. Only if it's up or down arrow, we go to prev or next slide and prevent default behaviour // This way, if there's text input, the user is still able to fill it $scope.onKeyDown = (event):void => { let PRESSED_KEY = event.keyCode; if(PRESSED_KEY == keyCodes.UP){ $scope.goToPrevSlide(); event.preventDefault(); } else if(PRESSED_KEY == keyCodes.DOWN){ $scope.goToNextSlide(); event.preventDefault(); } }; // When user resize it's browser we need to know the new height, so we can properly align the current slide $scope.onResize = (event):void => { //This will give us the new height of the window let newPageHeight = $(window).innerHeight(); // If the new height is different from the old height ( the browser is resized vertically ), the slides are resized if(pageHeight !== newPageHeight) { pageHeight = newPageHeight; } }; }; private initSlides = ():void => { //pageHeight }; private delayAction = (action:Function):void => { clearTimeout(this.delayExec); this.delayExec = setTimeout(function () { action(); }, 100); }; public static factory = ($templateCache:ng.ITemplateCacheService)=> { return new SdcPageScrollDirective($templateCache); }; } SdcPageScrollDirective.factory.$inject = ['$templateCache']; }