function link()

in ui-modules/utils/catalog-uploader/catalog-uploader.js [63:141]


    function link(scope, element, attrs) {
        let div = document.createElement('div');
        if ((('draggable' in div) || ('ondragstart' in div && 'ondrop' in div)) && 'FormData' in window && 'FileReader' in window) {
            element.addClass('br-has-drag-upload');
        }

        element.append($compile(template)(scope));

        let counter = 0;
        let requireManualClose = false;
        element.bind('drag dragstart dragend dragover dragenter dragleave drop', (event)=> {
            event.preventDefault();
            event.stopPropagation();
        }).bind('drag dragstart dragover dragenter', (event)=> {
            event.dataTransfer.dropEffect = 'copy';
            element.addClass('br-drag-active');
            element.addClass('br-drag-active-2');
        }).bind('dragenter', ()=> {
            counter++;
        }).bind('dragleave', (event)=> {
            counter--;
            element.removeClass('br-drag-active-2');
            if (!requireManualClose && counter === 0) element.removeClass('br-drag-active'); // close if we were triggered by a drag
        }).bind('drop', (event)=> {
            scope.upload(event.dataTransfer.files);
            counter--;
            element.removeClass('br-drag-active-2');
            requireManualClose = true;
            if (!requireManualClose && counter === 0) element.removeClass('br-drag-active'); // close if we were triggered by a drag
        });

        let field = attrs.brooklynCatalogUploader;
        if (angular.isDefined(field)) {
            scope.$on(field, ()=> {
                requireManualClose = true;
                element.addClass('br-drag-active');
            });
        }

        scope.selectedFiles = [];

        scope.close = ()=> {
            requireManualClose = false;
            counter = 0;
            scope.selectedFiles = []; // clean up the imported file list on returning to catalog, still needs a manual refresh to show the imported bundle
            element.removeClass('br-drag-active');
        };

        scope.filesChanged = (event)=> {
            scope.upload(event.target.files);
        };

        scope.upload = (files)=> {
            for (let i = 0; i < files.length; i++) {
                let file = files[i];

                brooklynCatalogUploader.upload(file).then((data)=> {
                    file.result = data;
                    $rootScope.$broadcast(CATALOG_UPLOAD_COMPLETED);
                }).catch((error)=> {
                    console.warn("ERROR uploading "+file, error);
                    file.error = error;
                }).finally(()=> {
                    scope.$applyAsync();
                });

                scope.selectedFiles.unshift(file);
                scope.$apply();
            }
        };

        scope.getCatalogItemUrl = (item)=> {
            let itemTraits = item.tags? item.tags.find(item => item.hasOwnProperty("traits")) : {"traits":[]};
            return (item.supertypes ? item.supertypes : itemTraits.traits)
                .includes('org.apache.brooklyn.api.location.Location')
                ? `/brooklyn-ui-location-manager/#!/location?symbolicName=${item.symbolicName}&version=${item.version}`
                : `/brooklyn-ui-catalog/#!/bundles/${item.containingBundle.split(':')[0]}/${item.containingBundle.split(':')[1]}/types/${item.symbolicName}/${item.version}`;
        };
    }