fossasia/loklak_webclient

View on GitHub
app/js/directives/add-connection-modal.js

Summary

Maintainability
D
2 days
Test Coverage
'use strict';
/* global angular */
/* jshint unused:false */

var directivesModule = require('./_index.js');

directivesModule.directive("addConnectionModal", ['$http', '$stateParams', 'SearchService', 'HarvestingFrequencyService',
    'LoklakFieldService', 'PushService', 'SourceTypeService', 'JsonFieldAccessorService', 'ImportProfileService',
    function($http, $stateParams, SearchService, HarvestingFrequencyService,
        LoklakFieldService, PushService, SourceTypeService, JsonFieldAccessorService, ImportProfileService) {
    return {
        restrict: 'A',
        templateUrl: "data-connect/add-connection-modal.html",
        controller: function($scope, $element, $attrs) {

            $scope.harvestingFreqList = HarvestingFrequencyService.values;
            $scope.sourceTypeList = SourceTypeService.sourceTypeList;
            $scope.sourceTypeListWEndpoint = {};
            $scope.loklakFields = LoklakFieldService.fieldList;

            const sourceTypeFields = LoklakFieldService.sourceTypeFields;
            // List of fields that user can map data to. Depending on selected source type
            $scope.currentLoklakFields = null;
            // Form inputs
            $scope.inputs = { mapRules : {}};
            // Submit validation messages
            $scope.messages = {};

            for (var key in $scope.sourceTypeList) {
                if ($scope.sourceTypeList[key].endpoint) {
                    $scope.sourceTypeListWEndpoint[key] = $scope.sourceTypeList[key];
                }
            }
            // Add geojson as a datasource format
            $scope.sourceTypeListWEndpoint.geojson =
            {
                'key': 'FOSSASIA_API',
                'name': 'GeoJson',
                'logo': '/images/external/geojson.png'
            };

            $scope.tabItems = [
                {
                    'title' : 'Source Format',
                    'icon' : 'fa fa-file-code-o',
                    'target' : 'source-format-tab'
                },
                {
                    'title' : 'Source URL & Info',
                    'icon' : 'fa fa-cloud-upload',
                    'target' : 'source-info-tab'
                },
                {
                    'title' : 'Mapping Rules',
                    'icon' : 'fa fa-exchange',
                    'target' : 'mapping-rule-tab'
                }
            ];
            $scope.selectedTab = 0;
            $scope.showNext = true;

            $scope.setSourceFormat = function(e) {
                $scope.inputs.sourceFormat = e.currentTarget.id;
                $scope.proceed();
                // refresh validation state
                $scope.validateSourceUrl();

                // pick only map rules that apply for this source type
                $scope.currentLoklakFields = {};
                if (sourceTypeFields[$scope.inputs.sourceFormat] &&
                    sourceTypeFields[$scope.inputs.sourceFormat].length !== 0) {
                    for (var key in sourceTypeFields[$scope.inputs.sourceFormat]) {
                        var data = sourceTypeFields[$scope.inputs.sourceFormat][key];
                        $scope.currentLoklakFields[data] = $scope.loklakFields[data];
                    }
                } else {
                    $scope.currentLoklakFields = null;
                }
            };

            $scope.proceed = function() {
                $scope.selectedTab++;
                if ($scope.selectedTab === 2) {
                    $scope.showNext = false;
                }
                setTimeout(function() {
                    angular.element('.nav-tabs > .active').next('li').find('a').trigger('click');
                }, 0);
            };

            $scope.tabSelected = function(selected) {
                $scope.selectedTab =selected;
                if ($scope.selectedTab === 2) {
                    $scope.showNext = false;
                } else {
                    $scope.showNext = true;
                }
            };

            function pushActionOnSuccess(data) {
                $scope.messages.error = '';
                setTimeout(function() {
                    angular.element('#close-add-connection-modal').trigger('click');
                }, 0);
                var returnMessage;
                if (data.new > 0) {
                    returnMessage = data.new + ' new source(s) added.';
                } else {
                    returnMessage = 'No new source added.';
                }
                if (data.known > 0) {
                    ImportProfileService.search(null, null, data.knownIds[0]).then(function(result) {
                        $scope.returnFromAddConnection(returnMessage, result.profiles);
                    }, function(err) {
                        console.error(err);
                        $scope.returnFromAddConnection(returnMessage);
                    });
                } else {
                    $scope.returnFromAddConnection(returnMessage);
                }
            }

            $scope.submit = function() {
                if (!$scope.inputs.url) {
                    $scope.messages.error = 'Please provide a valid source url';
                    return;
                }
                if (!$scope.inputs.sourceFormat) {
                    $scope.messages.error = 'Please select a data source format';
                    return;
                }
                function constructMapRules() {
                    var mapRulesStr = '';
                    const mapRules = $scope.inputs.mapRules;
                    var prefix = '';
                    for (var key in mapRules) {
                        if(mapRules.hasOwnProperty(key)){
                            var data = $scope.inputs.mapRules[key];
                            if (data[0] && data[0].length > 0) {
                                mapRulesStr += prefix + mapRules[key][0] + ':' + mapRules[key][1];
                                prefix = ',';
                            }
                        }
                    }
                    return mapRulesStr;
                }
                var lifetime = null;
                if ($scope.inputs.lifetime) {
                    lifetime = new Date($scope.inputs.lifetime).getTime();
                }
                if ($scope.inputs.sourceFormat === 'geojson') {
                    if (!$scope.inputs.sourceType) {
                        $scope.messages.error = 'Please select a source type';
                        return;
                    }
                    PushService.pushGeoJsonData(
                        { url: $scope.inputs.url,
                          source_type: $scope.inputs.sourceType.key,
                          map_type: constructMapRules(),
                          harvesting_freq: $scope.inputs.harvesting_freq.value,
                          lifetime: lifetime
                        }
                    ).then(function(data) {
                        pushActionOnSuccess(data);
                     }, function(err, status) {
                         $scope.messages.success = '';
                         $scope.messages.error = 'Add new source failed. Please verify link avaibility & data format.';
                    });
                } else {
                    PushService.pushCustomData(
                        { url: $scope.inputs.url,
                          source_type: $scope.inputs.sourceFormat,
                          map_type: constructMapRules(),
                          harvesting_freq: $scope.inputs.harvesting_freq.value,
                          lifetime: lifetime
                        }, $scope.sourceTypeList[$scope.inputs.sourceFormat].endpoint).then(function(data) {
                            pushActionOnSuccess(data);
                        }, function(err, status) {
                        $scope.messages.success = '';
                        $scope.messages.error = 'Add new source failed. Please verify link avaibility & data format.';
                    });
                }
            };

            $scope.hideErrorPanel = function() {
                $scope.messages.error = '';
            };

            $scope.hideSuccessPanel = function() {
                $scope.messages.success = '';
            };

            $scope.hideValidateErrorPanel = function() {
                $scope.messages.validateError = '';
            };

            $scope.validateSourceUrl = function() {
                $scope.currentData = null;
                $scope.showCurrentData = false;
                if (!$scope.inputs.url) {
                    $scope.validateStatus = '';
                    $scope.messages.validateError = '';
                    return;
                }

                if (!$scope.inputs.sourceFormat) {
                    $scope.messages.validateError = 'Please select a source type';
                }
                $scope.validateStatus = 'waiting';
                PushService.validate($scope.inputs.url, $scope.inputs.sourceFormat).then(function(data) {
                    if (data.status === 'offline') {
                        $scope.validateStatus = 'error';
                        $scope.messages.validateError = 'The provided url is unreachable.';
                    } else if (data.status === 'invalid') {
                        $scope.validateStatus = 'error';
                        $scope.messages.validateError = 'Data format is not valid for source type ' + $scope.sourceTypeList[$scope.inputs.sourceFormat].name;
                    } else if (data.status === 'unsupported') {
                        $scope.validateStatus = '';
                        $scope.messages.validateError = '';
                        $scope.currentData = JSON.parse(data.content);
                    } else {
                        $scope.validateStatus = 'success';
                        $scope.messages.validateError = '';
                        $scope.currentData = JSON.parse(data.content);

                    }
                }, function(err, status) {
                    $scope.validateStatus = 'error';
                    $scope.messages.validateError = 'Unknown server error';
                    if (err) {
                        $scope.messages.validateError += ': ' + err;
                    }
                });
            };

            function accessDataField(data, field) {
                var dotPos = field.indexOf(".");
                if (dotPos === -1) {
                    return data[field];
                }
                var firstPart = field.substr(0, dotPos);
                var secondPart = field.substr(dotPos+1);
                return accessDataField(data[firstPart], secondPart);
            }

            $scope.accessDataField = function(row) {
                if ($scope.inputs.mapRules[row][0] && $scope.currentData) {
                    return JsonFieldAccessorService.accessField($scope.currentData, $scope.inputs.mapRules[row][0]);
                }
            };

            $scope.clearModalData = function() {
                $scope.currentData = null;
                $scope.showCurrentData = false;
                $scope.inputs = { mapRules : {}};
                $scope.validateStatus = '';
                $scope.messages = {};
                // Default values
                $scope.inputs.harvesting_freq = {'value': 360, 'label':'6 hours'};

                for (var key in $scope.loklakFields) {
                    if (!$scope.inputs.mapRules[key]) {
                        $scope.inputs.mapRules[key] = [];
                    }
                    $scope.inputs.mapRules[key][1] = $scope.loklakFields[key].value; // fill second column with loklak fields
                }
            };

            $scope.clearModalData();
        }
    };
}]);