diff --git a/.gitignore b/.gitignore index 698862ddd855d7fa6edfa761553fa31520c61a1b..914440ea3720e6714467d6df97cf8503247e20e8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ profiles.clj /resources/frontend_client/app/bower_components /resources/frontend_client/app/dist/ /node_modules/ +/.js_hint_output/ diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000000000000000000000000000000000000..f39320a72c961c3de2174de74d3933a7a9e15529 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,7 @@ +{ + "globalstrict": true, + "globals": { + "angular": false, + "console": false + } +} diff --git a/bower.json b/bower.json index 7af767547b6f67e905718c772fcc1fca5eda9018..c78fffe3006d97a75d4ec8b34b324c1d3f8b4f9e 100644 --- a/bower.json +++ b/bower.json @@ -1,43 +1,43 @@ { - "name": "corvus", - "description": "Expa Analytics", - "version": "0.0.0", - "homepage": "https://github.com/expa/data", - "license": "private", - "private": true, - "dependencies": { - "angular": "1.2.26", - "angular-route": "1.2.26", - "angular-loader": "1.2.26", - "angular-mocks": "1.2.26", - "angular-resource": "1.2.26", - "angular-cookies": "1.2.26", - "angular-sanitize": "1.2.26", - "angular-xeditable": "0.1.8", - "angular-bootstrap": "0.11.0", - "angular-cookie": "4.0.6", - "jquery": "2.1.1", - "angular-animate": "1.2.26", - "underscore": "1.8.2", - "angularytics": "0.3.0", - "angular-gridster": "0.11.7", - "angular-http-auth": "1.2.1", - "ace-builds": "1.1.7", - "angular-ui-ace": "0.1.1", - "fastclick": "~1.0.3", - "ng-sortable": "1.1.6", - "angular-readable-time": "~0.1.1", - "d3": "3.5.3", - "crossfilter": "1.3.11", - "dc.js": "2.0.0-beta.1", - "ngReact": "~0.1.3", - "react": "~0.12.2", - "react-onclickoutside": "~0.2.2", - "react-date-picker": "~0.5.1", - "moment": "~2.9.0" - }, - "resolutions": { - "react-onclickoutside": "~0.2.2", - "moment": "2.8.2" - } + "name": "corvus", + "description": "Expa Analytics", + "version": "0.0.0", + "homepage": "https://github.com/expa/data", + "license": "private", + "private": true, + "dependencies": { + "ace-builds": "1.1.7", + "angular": "1.2.26", + "angular-animate": "1.2.26", + "angular-bootstrap": "0.11.0", + "angular-cookie": "4.0.6", + "angular-cookies": "1.2.26", + "angular-gridster": "0.11.7", + "angular-http-auth": "1.2.1", + "angular-loader": "1.2.26", + "angular-mocks": "1.2.26", + "angular-readable-time": "~0.1.1", + "angular-resource": "1.2.26", + "angular-route": "1.2.26", + "angular-sanitize": "1.2.26", + "angular-ui-ace": "0.1.1", + "angular-xeditable": "0.1.8", + "angularytics": "0.3.0", + "crossfilter": "1.3.11", + "d3": "3.5.3", + "dc.js": "2.0.0-beta.1", + "fastclick": "~1.0.3", + "jquery": "2.1.1", + "moment": "~2.9.0", + "ng-sortable": "1.1.6", + "ngReact": "~0.1.3", + "react": "~0.12.2", + "react-date-picker": "~0.5.1", + "react-onclickoutside": "~0.2.2", + "underscore": "1.8.2" + }, + "resolutions": { + "react-onclickoutside": "~0.2.2", + "moment": "2.8.2" + } } diff --git a/circle.yml b/circle.yml index 0711a63d7cb26730f3afd3ca7e4d21541137ae4e..2ece3029d06d2b84c00bd4709cccb47092024360 100644 --- a/circle.yml +++ b/circle.yml @@ -4,5 +4,5 @@ machine: oraclejdk8 test: override: - - case $CIRCLE_NODE_INDEX in 0) lein eastwood ;; 1) lein test ;; 2) lein bikeshed --max-line-length 240 && lein uberjar ;; esac: + - case $CIRCLE_NODE_INDEX in 0) lein eastwood ;; 1) lein test ;; 2) lein uberjar ;; 3) ./util/lint_js.sh && lein bikeshed --max-line-length 240 ;; esac: parallel: true diff --git a/package.json b/package.json index 12d7053f6a4b0ffe4641fc6a62d2466eacb3e129..b2b133457e1ecc31ffc7cc65f4f8eb18651800a5 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,30 @@ { - "name": "corvus", - "private": true, - "version": "0.0.0", - "description": "Expa Analytics", - "repository": "https://github.com/expa/data", - "license": "private", - "engines": { - "node": "0.10.25" - }, - "dependencies": { - "bower": "1.3.12", - "gulp": "^3.8.8", - "gulp-concat": "^2.4.0", - "gulp-myth": "^1.0.1", - "gulp-jsx": "^0.7.0", - "gulp-react": "^2.0.0" - }, - "devDependencies": { - "http-server": "^0.6.1", - "jshint": "2.4.4", - "karma": "~0.10", - "karma-junit-reporter": "^0.2.2", - "protractor": "~0.20.1", - "shelljs": "^0.2.6" - }, - "scripts": { - "postinstall": "./node_modules/bower/bin/bower install --allow-root --config.interactive=false" - } + "name": "corvus", + "private": true, + "version": "0.0.0", + "description": "Expa Analytics", + "repository": "https://github.com/expa/data", + "license": "private", + "engines": { + "node": "0.10.25" + }, + "dependencies": { + "bower": "1.3.12", + "gulp": "^3.8.8", + "gulp-concat": "^2.4.0", + "gulp-myth": "^1.0.1", + "gulp-jsx": "^0.7.0", + "gulp-react": "^2.0.0" + }, + "devDependencies": { + "http-server": "^0.6.1", + "jshint": "2.6.3", + "karma": "~0.10", + "karma-junit-reporter": "^0.2.2", + "protractor": "~0.20.1", + "shelljs": "^0.2.6" + }, + "scripts": { + "postinstall": "./node_modules/bower/bin/bower install --allow-root --config.interactive=false" + } } diff --git a/resources/frontend_client/app/js/google_maps.js b/resources/frontend_client/app/js/google_maps.js index 7b230e7155025f5014abe689e98296d566a08eab..6ab79307fa5a1431cddddc8ba346a385bec1da2e 100644 --- a/resources/frontend_client/app/js/google_maps.js +++ b/resources/frontend_client/app/js/google_maps.js @@ -1,23 +1,137 @@ - +'use strict'; +/*global google, window, document*/ window.google = window.google || {}; google.maps = google.maps || {}; (function() { - - function getScript(src) { - document.write('<' + 'script src="' + src + '"' + - ' type="text/javascript"><' + '/script>'); - } - - var modules = google.maps.modules = {}; - google.maps.__gjsload__ = function(name, text) { - modules[name] = text; - }; - - google.maps.Load = function(apiLoad) { - delete google.maps.Load; - apiLoad([0.009999999776482582,[[["https://mts0.googleapis.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.googleapis.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"m@267000000",["https://mts0.google.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.google.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026"]],[["https://khms0.googleapis.com/kh?v=152\u0026hl=en-US\u0026","https://khms1.googleapis.com/kh?v=152\u0026hl=en-US\u0026"],null,null,null,1,"152",["https://khms0.google.com/kh?v=152\u0026hl=en-US\u0026","https://khms1.google.com/kh?v=152\u0026hl=en-US\u0026"]],[["https://mts0.googleapis.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.googleapis.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"h@267000000",["https://mts0.google.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.google.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026"]],[["https://mts0.googleapis.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.googleapis.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026"],null,null,null,null,"t@132,r@267000000",["https://mts0.google.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026","https://mts1.google.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026"]],null,null,[["https://cbks0.googleapis.com/cbk?","https://cbks1.googleapis.com/cbk?"]],[["https://khms0.googleapis.com/kh?v=84\u0026hl=en-US\u0026","https://khms1.googleapis.com/kh?v=84\u0026hl=en-US\u0026"],null,null,null,null,"84",["https://khms0.google.com/kh?v=84\u0026hl=en-US\u0026","https://khms1.google.com/kh?v=84\u0026hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt?hl=en-US\u0026","https://mts1.googleapis.com/mapslt?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/ft?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/ft?hl=en-US\u0026"]],[["https://mts0.googleapis.com/vt?hl=en-US\u0026","https://mts1.googleapis.com/vt?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/loom?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/loom?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt?hl=en-US\u0026","https://mts1.googleapis.com/mapslt?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/ft?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/ft?hl=en-US\u0026"]],[["https://mts0.googleapis.com/mapslt/loom?hl=en-US\u0026","https://mts1.googleapis.com/mapslt/loom?hl=en-US\u0026"]]],["en-US","US",null,0,null,null,"https://maps.gstatic.com/mapfiles/","https://csi.gstatic.com","https://maps.googleapis.com","https://maps.googleapis.com"],["https://maps.gstatic.com/intl/en_us/mapfiles/api-3/17/7","3.17.7"],[487737768],1,null,null,null,null,null,"",["visualization"],null,1,"https://khms.googleapis.com/mz?v=152\u0026",null,"https://earthbuilder.googleapis.com","https://earthbuilder.googleapis.com",null,"https://mts.googleapis.com/vt/icon",[["https://mts0.googleapis.com/vt","https://mts1.googleapis.com/vt"],["https://mts0.googleapis.com/vt","https://mts1.googleapis.com/vt"],[null,[[0,"m",267000000]],[null,"en-US","US",null,18,null,null,null,null,null,null,[[47],[37,[["smartmaps"]]]]],0],[null,[[0,"m",267000000]],[null,"en-US","US",null,18,null,null,null,null,null,null,[[47],[37,[["smartmaps"]]]]],3],[null,[[0,"m",267000000]],[null,"en-US","US",null,18,null,null,null,null,null,null,[[50],[37,[["smartmaps"]]]]],0],[null,[[0,"m",267000000]],[null,"en-US","US",null,18,null,null,null,null,null,null,[[50],[37,[["smartmaps"]]]]],3],[null,[[4,"t",132],[0,"r",132000000]],[null,"en-US","US",null,18,null,null,null,null,null,null,[[5],[37,[["smartmaps"]]]]],0],[null,[[4,"t",132],[0,"r",132000000]],[null,"en-US","US",null,18,null,null,null,null,null,null,[[5],[37,[["smartmaps"]]]]],3],[null,null,[null,"en-US","US",null,18],0],[null,null,[null,"en-US","US",null,18],3],[null,null,[null,"en-US","US",null,18],6],[null,null,[null,"en-US","US",null,18],0],["https://mts0.google.com/vt","https://mts1.google.com/vt"],"/maps/vt"],2,500,["https://geo0.ggpht.com/cbk?cb_client=maps_sv.uv_api_demo","https://www.gstatic.com/landmark/tour","https://www.gstatic.com/landmark/config","/maps/preview/reveal?authuser=0","/maps/preview/log204","/gen204?tbm=map","https://static.panoramio.com.storage.googleapis.com/photos/"],["https://www.google.com/maps/api/js/widget","https://www.google.com/maps/api/js/slave_widget"]], loadScriptTime); - }; - var loadScriptTime = (new Date).getTime(); - getScript("https://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/17/7/%7Bmain,visualization%7D.js"); + + function getScript(src) { + document.write('<' + 'script src="' + src + '" type="text/javascript"></script>'); // jshint ignore:line + } + + var modules = google.maps.modules = {}; + google.maps.__gjsload__ = function(name, text) { + modules[name] = text; + }; + + google.maps.Load = function(apiLoad) { + delete google.maps.Load; + apiLoad([0.009999999776482582, [ + [ + ["https://mts0.googleapis.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026", "https://mts1.googleapis.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026"], null, null, null, null, "m@267000000", ["https://mts0.google.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026", "https://mts1.google.com/vt?lyrs=m@267000000\u0026src=api\u0026hl=en-US\u0026"] + ], + [ + ["https://khms0.googleapis.com/kh?v=152\u0026hl=en-US\u0026", "https://khms1.googleapis.com/kh?v=152\u0026hl=en-US\u0026"], null, null, null, 1, "152", ["https://khms0.google.com/kh?v=152\u0026hl=en-US\u0026", "https://khms1.google.com/kh?v=152\u0026hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026", "https://mts1.googleapis.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026"], null, null, null, null, "h@267000000", ["https://mts0.google.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026", "https://mts1.google.com/vt?lyrs=h@267000000\u0026src=api\u0026hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026", "https://mts1.googleapis.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026"], null, null, null, null, "t@132,r@267000000", ["https://mts0.google.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026", "https://mts1.google.com/vt?lyrs=t@132,r@267000000\u0026src=api\u0026hl=en-US\u0026"] + ], null, null, [ + ["https://cbks0.googleapis.com/cbk?", "https://cbks1.googleapis.com/cbk?"] + ], + [ + ["https://khms0.googleapis.com/kh?v=84\u0026hl=en-US\u0026", "https://khms1.googleapis.com/kh?v=84\u0026hl=en-US\u0026"], null, null, null, null, "84", ["https://khms0.google.com/kh?v=84\u0026hl=en-US\u0026", "https://khms1.google.com/kh?v=84\u0026hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/mapslt?hl=en-US\u0026", "https://mts1.googleapis.com/mapslt?hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/mapslt/ft?hl=en-US\u0026", "https://mts1.googleapis.com/mapslt/ft?hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/vt?hl=en-US\u0026", "https://mts1.googleapis.com/vt?hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/mapslt/loom?hl=en-US\u0026", "https://mts1.googleapis.com/mapslt/loom?hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/mapslt?hl=en-US\u0026", "https://mts1.googleapis.com/mapslt?hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/mapslt/ft?hl=en-US\u0026", "https://mts1.googleapis.com/mapslt/ft?hl=en-US\u0026"] + ], + [ + ["https://mts0.googleapis.com/mapslt/loom?hl=en-US\u0026", "https://mts1.googleapis.com/mapslt/loom?hl=en-US\u0026"] + ] + ], + ["en-US", "US", null, 0, null, null, "https://maps.gstatic.com/mapfiles/", "https://csi.gstatic.com", "https://maps.googleapis.com", "https://maps.googleapis.com"], + ["https://maps.gstatic.com/intl/en_us/mapfiles/api-3/17/7", "3.17.7"], + [487737768], 1, null, null, null, null, null, "", ["visualization"], null, 1, "https://khms.googleapis.com/mz?v=152\u0026", null, "https://earthbuilder.googleapis.com", "https://earthbuilder.googleapis.com", null, "https://mts.googleapis.com/vt/icon", [ + ["https://mts0.googleapis.com/vt", "https://mts1.googleapis.com/vt"], + ["https://mts0.googleapis.com/vt", "https://mts1.googleapis.com/vt"], + [null, [ + [0, "m", 267000000] + ], + [null, "en-US", "US", null, 18, null, null, null, null, null, null, [ + [47], + [37, [ + ["smartmaps"] + ]] + ]], 0 + ], + [null, [ + [0, "m", 267000000] + ], + [null, "en-US", "US", null, 18, null, null, null, null, null, null, [ + [47], + [37, [ + ["smartmaps"] + ]] + ]], 3 + ], + [null, [ + [0, "m", 267000000] + ], + [null, "en-US", "US", null, 18, null, null, null, null, null, null, [ + [50], + [37, [ + ["smartmaps"] + ]] + ]], 0 + ], + [null, [ + [0, "m", 267000000] + ], + [null, "en-US", "US", null, 18, null, null, null, null, null, null, [ + [50], + [37, [ + ["smartmaps"] + ]] + ]], 3 + ], + [null, [ + [4, "t", 132], + [0, "r", 132000000] + ], + [null, "en-US", "US", null, 18, null, null, null, null, null, null, [ + [5], + [37, [ + ["smartmaps"] + ]] + ]], 0 + ], + [null, [ + [4, "t", 132], + [0, "r", 132000000] + ], + [null, "en-US", "US", null, 18, null, null, null, null, null, null, [ + [5], + [37, [ + ["smartmaps"] + ]] + ]], 3 + ], + [null, null, [null, "en-US", "US", null, 18], 0], + [null, null, [null, "en-US", "US", null, 18], 3], + [null, null, [null, "en-US", "US", null, 18], 6], + [null, null, [null, "en-US", "US", null, 18], 0], + ["https://mts0.google.com/vt", "https://mts1.google.com/vt"], "/maps/vt" + ], 2, 500, ["https://geo0.ggpht.com/cbk?cb_client=maps_sv.uv_api_demo", "https://www.gstatic.com/landmark/tour", "https://www.gstatic.com/landmark/config", "/maps/preview/reveal?authuser=0", "/maps/preview/log204", "/gen204?tbm=map", "https://static.panoramio.com.storage.googleapis.com/photos/"], + ["https://www.google.com/maps/api/js/widget", "https://www.google.com/maps/api/js/slave_widget"] + ], loadScriptTime); + }; + var loadScriptTime = (new Date()).getTime(); + getScript("https://maps.gstatic.com/cat_js/intl/en_us/mapfiles/api-3/17/7/%7Bmain,visualization%7D.js"); })(); \ No newline at end of file diff --git a/resources/frontend_client/app/services.js b/resources/frontend_client/app/services.js index d48ab89f9c1a25f0ebfc97d8876f661298f65f92..6f575bc7b071fd42f41bc6ad0a2e830bbab2bd28 100644 --- a/resources/frontend_client/app/services.js +++ b/resources/frontend_client/app/services.js @@ -97,15 +97,15 @@ CorvusServices.factory('AppState', ['$rootScope', '$routeParams', '$q', '$locati return deferred.promise; }, - switchOrg: function (org_slug) { + switchOrg: function(org_slug) { console.log('changing org to ...', org_slug); Organization.get_by_slug({ - 'slug': org_slug - }, function (org) { + 'slug': org_slug + }, function(org) { service.model.currentOrgSlug = org.slug; service.model.currentOrg = org; $rootScope.$broadcast('appstate:organization', service.model.currentOrg); - }, function (error) { + }, function(error) { console.log('error getting current org', error); }); }, @@ -137,7 +137,7 @@ CorvusServices.factory('AppState', ['$rootScope', '$routeParams', '$q', '$locati routeContext = 'site-admin'; } else if ($routeParams.orgSlug) { // couple of options when within an org - if ($location.path().indexOf('/'+$routeParams.orgSlug+'/admin/') === 0) { + if ($location.path().indexOf('/' + $routeParams.orgSlug + '/admin/') === 0) { routeContext = 'org-admin'; } else { routeContext = 'org'; @@ -224,7 +224,7 @@ CorvusServices.factory('AppState', ['$rootScope', '$routeParams', '$q', '$locati if (service.model.currentOrgSlug != $routeParams.orgSlug) { // we just navigated to a new organization - this.switchOrg($routeParams.orgSlug) + this.switchOrg($routeParams.orgSlug); service.model.currentOrgSlug = $routeParams.orgSlug; service.setCurrentOrgCookie(service.model.currentOrgSlug); } @@ -877,4 +877,4 @@ CoreServices.factory('PermissionViolation', ['$resource', '$cookies', function($ }, }); -}]); +}]); \ No newline at end of file diff --git a/resources/frontend_client/app/setup/setup.controllers.js b/resources/frontend_client/app/setup/setup.controllers.js index 853cc16549ead0cc830956e17cad83b552f7da5c..84aa0c02f895fcb8fc34a4c5ac51e303b2d6448c 100644 --- a/resources/frontend_client/app/setup/setup.controllers.js +++ b/resources/frontend_client/app/setup/setup.controllers.js @@ -1,7 +1,9 @@ -var SetupControllers = angular.module('corvus.setup.controllers', ['corvus.metabase.services', 'corvus.setup.services']) +'use strict'; + +var SetupControllers = angular.module('corvus.setup.controllers', ['corvus.metabase.services', 'corvus.setup.services']); SetupControllers.controller('SetupInit', ['$scope', '$location', '$routeParams', 'AppState', - function ($scope, $location, $routeParams, AppState) { + function($scope, $location, $routeParams, AppState) { // The only thing this controller does is grab the setup token from the url and store it in our AppState // then we begin the actual setup workflow by sending the user to /setup/ @@ -13,9 +15,9 @@ SetupControllers.controller('SetupInit', ['$scope', '$location', '$routeParams', ]); SetupControllers.controller('SetupIntro', ['$scope', '$location', '$timeout', 'ipCookie', 'Organization', 'AppState', 'Setup', - function ($scope, $location, $timeout, ipCookie, Organization, AppState, Setup) { + function($scope, $location, $timeout, ipCookie, Organization, AppState, Setup) { - $scope.createOrgAndUser = function () { + $scope.createOrgAndUser = function() { // start off by creating the first user of the system // NOTE: this should both create the user AND log us in and return a session id @@ -25,7 +27,7 @@ SetupControllers.controller('SetupIntro', ['$scope', '$location', '$timeout', 'i 'first_name': $scope.newUser.firstName, 'last_name': $scope.newUser.lastName, 'password': $scope.newUser.password - }, function (result) { + }, function(result) { // result should have a single :id value which is our new session id var sessionId = result.id; @@ -34,7 +36,11 @@ SetupControllers.controller('SetupIntro', ['$scope', '$location', '$timeout', 'i // TODO - this session cookie code needs to be somewhere easily reusable var isSecure = ($location.protocol() === "https") ? true : false; - ipCookie('metabase.SESSION_ID', sessionId, {path: '/', expires: 14, secure: isSecure}); + ipCookie('metabase.SESSION_ID', sessionId, { + path: '/', + expires: 14, + secure: isSecure + }); // send a login notification event $scope.$emit('appstate:login', sessionId); @@ -48,151 +54,163 @@ SetupControllers.controller('SetupIntro', ['$scope', '$location', '$timeout', 'i Organization.create({ 'name': $scope.userOrgName, 'slug': $scope.userOrgName - }, function (org) { + }, function(org) { console.log('first org created', org); // switch the org // TODO - make sure this is up to snuff from a security standpoint - AppState.switchOrg(org.slug) + AppState.switchOrg(org.slug); // we should be good to carry on with setting up data at this point $location.path('/setup/data/'); - }, function(error){ + }, function(error) { $scope.error = error.data; console.log('error creating organization', error); }); }, 300); - }, function (error) { + }, function(error) { $scope.error = error.data; console.log('error with initial user creation', error); }); - } + }; } ]); SetupControllers.controller('SetupConnection', ['$scope', '$routeParams', '$location', 'Metabase', function($scope, $routeParams, $location, Metabase) { - // TODO - we should be getting all this info from the api - - var defaultPorts = {'MySql': 3306, 'Postgres': 5432, 'Mongo': 27017, "RedShift": 5439, 'Druid': 8083} - - $scope.engines = [ - {'id': 'postgres', 'name':'Postgres'}, - {'id': 'h2', 'name':'H2'}, - {'id': 'mysql', 'name':'MySQL'} - ]; - - $scope.connection = {}; - - // assume we have a new connection since this is the setup process - var newConnection = true - $scope.breadcrumb = 'Add connection' - - if($routeParams.dbId) { - newConnection = false - Metabase.db_get({ - 'dbId': $routeParams.dbId - }, function (result) { - $scope.database = result; - $scope.breadcrumb = result.name - $scope.connection = parseConnectionString(result.details.conn_str) - $scope.connection.engine = result.engine - }, function (error) { - console.log('error', error) - }) - } else { - var connectionType = 'Postgres' - $scope.connection = { - host: "localhost", - port: defaultPorts[connectionType], - engine: 'postgres' - } + // TODO - we should be getting all this info from the api + + var defaultPorts = { + 'MySql': 3306, + 'Postgres': 5432, + 'Mongo': 27017, + "RedShift": 5439, + 'Druid': 8083 + }; + + $scope.engines = [{ + 'id': 'postgres', + 'name': 'Postgres' + }, { + 'id': 'h2', + 'name': 'H2' + }, { + 'id': 'mysql', + 'name': 'MySQL' + }]; + + $scope.connection = {}; + + // assume we have a new connection since this is the setup process + var newConnection = true; + $scope.breadcrumb = 'Add connection'; + + if ($routeParams.dbId) { + newConnection = false; + Metabase.db_get({ + 'dbId': $routeParams.dbId + }, function(result) { + $scope.database = result; + $scope.breadcrumb = result.name; + $scope.connection = parseConnectionString(result.details.conn_str); + $scope.connection.engine = result.engine; + }, function(error) { + console.log('error', error); + }); + } else { + var connectionType = 'Postgres'; + $scope.connection = { + host: "localhost", + port: defaultPorts[connectionType], + engine: 'postgres' + }; + } + + function parseConnectionString(connectionString) { + // connection strings take the form of + // 'host="<value>" post="<value" dbname="<value>" user="<value>" password="<value>"' + + var parsedConnection = {}; + var string = connectionString.split(" "); + + for (var s in string) { + var connectionDetail = string[s].split("="); + parsedConnection[connectionDetail[0]] = connectionDetail[1]; } - function parseConnectionString (connectionString) { - // connection strings take the form of - // 'host="<value>" post="<value" dbname="<value>" user="<value>" password="<value>"' + return parsedConnection; + } - var parsedConnection = {}; - var string = connectionString.split(" "); + function buildConnectionString(values) { + // connection strings take the form of + // 'host="<value>" post="<value" dbname="<value>" user="<value>" password="<value>"' - for(var s in string) { - var connectionDetail = string[s].split("="); - parsedConnection[connectionDetail[0]] = connectionDetail[1]; - } + var connectionStringElements = ['host', 'port', 'dbname', 'user', 'password'], + conn_str = ''; - return parsedConnection; + for (var element in connectionStringElements) { + conn_str = conn_str + ' ' + connectionStringElements[element] + '=' + values[connectionStringElements[element]]; } - function buildConnectionString (values) { - // connection strings take the form of - // 'host="<value>" post="<value" dbname="<value>" user="<value>" password="<value>"' - - var connectionStringElements = ['host', 'port', 'dbname', 'user', 'password'], - conn_str = ''; + return conn_str; + } - for(var element in connectionStringElements) { - conn_str = conn_str + ' ' + connectionStringElements[element] + '=' + values[connectionStringElements[element]]; + $scope.setConnectionEngine = function(engine) { + $scope.connection.engine = engine; + }; + + $scope.submit = function() { + var database = { + org: $scope.currentOrg.id, + name: $scope.connection.dbname, + engine: $scope.connection.engine, + details: { + conn_str: buildConnectionString($scope.connection) } + }; - return conn_str; + function success(result) { + $location.path('/setup/data'); } - $scope.setConnectionEngine = function (engine) { - $scope.connection.engine = engine; + function error(err) { + $scope.error = err; + console.log('error', err); } - $scope.submit = function () { - var database = { - org: $scope.currentOrg.id, - name: $scope.connection.dbname, - engine: $scope.connection.engine, - details: { - conn_str: buildConnectionString($scope.connection) - } - }; - function success (result) { - $location.path('/setup/data'); - } - - function error (error) { - $scope.error = error; - console.log('error', error); + // api needs a int + $scope.connection.port = parseInt($scope.connection.port); + // Validate the connection string + Metabase.validate_connection($scope.connection, function(result) { + if (newConnection) { + Metabase.db_create(database, success, error); + } else { + // add the id since we're updating + database.id = $scope.database.id; + Metabase.db_update(database, success, error); } - // api needs a int - $scope.connection.port = parseInt($scope.connection.port); - // Validate the connection string - Metabase.validate_connection($scope.connection, function (result) { - if(newConnection) { - Metabase.db_create(database, success, error); - } else { - // add the id since we're updating - database.id = $scope.database.id - Metabase.db_update(database, success, error); - } - - }, function (error) { - console.log(error); - $scope.error = "Invalid Connection String - " + error.data.message; - }); - }; -}]) + }, function(error) { + console.log(error); + $scope.error = "Invalid Connection String - " + error.data.message; + }); + }; +}]); -SetupControllers.controller('SetupData', ['$scope', 'Metabase', function ($scope, Metabase) { - $scope.$watch('currentOrg', function (org) { - if(!org) return; +SetupControllers.controller('SetupData', ['$scope', 'Metabase', function($scope, Metabase) { + $scope.$watch('currentOrg', function(org) { + if (!org) return; Metabase.db_list({ - 'orgId': org.id + 'orgId': org.id }, - function (result) { - $scope.databases = result + function(result) { + $scope.databases = result; }, - function (error) { - console.log('error', error) + function(error) { + console.log('error', error); } ); - }) -}]) + }); +}]); \ No newline at end of file diff --git a/resources/frontend_client/app/setup/setup.directives.js b/resources/frontend_client/app/setup/setup.directives.js index b861761f171b5bd4094a83fde2bcea23b3a57235..66c7eeea4ba61ffa0c6fd22c63cd87b3b3d1c9dc 100644 --- a/resources/frontend_client/app/setup/setup.directives.js +++ b/resources/frontend_client/app/setup/setup.directives.js @@ -1,20 +1,22 @@ -var SetupDirectives = angular.module('corvus.setup.directives', []) +'use strict'; -var setupPartialsDir = '/app/setup/partials' +var SetupDirectives = angular.module('corvus.setup.directives', []); + +var setupPartialsDir = '/app/setup/partials'; SetupDirectives - .directive('cvSetupHeader', function () { + .directive('cvSetupHeader', function() { return { restrict: 'E', templateUrl: setupPartialsDir + '/_header.html', scope: { text: '@' } - } - }) + }; + }); SetupDirectives - .directive('cvConnectionList', function () { + .directive('cvConnectionList', function() { return { restrict: 'E', templateUrl: setupPartialsDir + '/_connection_list.html', @@ -22,11 +24,11 @@ SetupDirectives connections: '=', loading: '=' } - } - }) + }; + }); SetupDirectives - .directive('cvStepButton', function () { + .directive('cvStepButton', function() { return { restrict: 'E', templateUrl: setupPartialsDir + '/_step_button.html', @@ -35,7 +37,7 @@ SetupDirectives text: '@' }, compile: function(element, attrs) { - attrs.text = attrs.text || "Next" + attrs.text = attrs.text || "Next"; } - } - }) + }; + }); \ No newline at end of file diff --git a/resources/frontend_client/app/setup/setup.module.js b/resources/frontend_client/app/setup/setup.module.js index 5dbf97f79985fdbdd36e37a9e0b5bb8f16a52e09..88cc30be216ed7b78e0408bd06a0bda6b5482009 100644 --- a/resources/frontend_client/app/setup/setup.module.js +++ b/resources/frontend_client/app/setup/setup.module.js @@ -1,9 +1,11 @@ +'use strict'; + var Setup = angular.module('corvus.setup', [ 'corvus.setup.controllers', 'corvus.setup.directives' ]); -Setup.config(['$routeProvider', function ($routeProvider) { +Setup.config(['$routeProvider', function($routeProvider) { $routeProvider.when('/setup/data', { templateUrl: '/app/setup/partials/setup_data.html', controller: 'SetupData' @@ -18,4 +20,4 @@ Setup.config(['$routeProvider', function ($routeProvider) { templateUrl: '/app/setup/partials/setup_connection.html', controller: 'SetupConnection' }); -}]); +}]); \ No newline at end of file diff --git a/resources/frontend_client/app/superadmin/organization/organization.controllers.js b/resources/frontend_client/app/superadmin/organization/organization.controllers.js index 997a8c2e8422ee7f970ea697468d5de7570a9dd5..fb9631701e36c730782435051b1ad2732aec750f 100644 --- a/resources/frontend_client/app/superadmin/organization/organization.controllers.js +++ b/resources/frontend_client/app/superadmin/organization/organization.controllers.js @@ -1,10 +1,13 @@ 'use strict'; /*global _*/ -var OrganizationControllers = angular.module('superadmin.organization.controllers', ['corvus.services']); +var OrganizationControllers = angular.module('superadmin.organization.controllers', ['corvus.services', + 'superadmin.index.services' +]); + +OrganizationControllers.controller('OrganizationListController', ['$scope', 'Organization', 'SettingsAdminServices', -OrganizationControllers.controller('OrganizationListController', ['$scope', 'Organization', - function($scope, Organization) { + function($scope, Organization, SettingsAdminServices) { $scope.organizations = []; $scope.saveSetting = function(setting) { @@ -29,9 +32,9 @@ OrganizationControllers.controller('OrganizationListController', ['$scope', 'Org }; // initialize on load - Organization.list(function (orgs) { + Organization.list(function(orgs) { $scope.organizations = orgs; - }, function (error) { + }, function(error) { console.log("Error getting organizations: ", error); }); } @@ -42,26 +45,28 @@ OrganizationControllers.controller('OrganizationDetailController', ['$scope', '$ $scope.organization = undefined; // initialize on load - if($routeParams.orgId) { + if ($routeParams.orgId) { // editing an existing organization Organization.get({ - 'orgId': $routeParams.orgId - }, - function (org) { - $scope.organization = org; - }, function (error) { - console.log("Error getting organization: ", error); - // TODO - should be a 404 response - }); + 'orgId': $routeParams.orgId + }, + function(org) { + $scope.organization = org; + }, + function(error) { + console.log("Error getting organization: ", error); + // TODO - should be a 404 response + }); // provide a relevant save() function $scope.save = function(organization) { Organization.update(organization, - function (org) { - $scope.organization = org; - }, function (error) { - console.log(error); - }); + function(org) { + $scope.organization = org; + }, + function(error) { + console.log(error); + }); }; } else { // assume we are creating a new org @@ -72,12 +77,13 @@ OrganizationControllers.controller('OrganizationDetailController', ['$scope', '$ // TODO - some simple validation checks Organization.create(organization, - function (org) { - $location.path('/superadmin/organization/'+org.id); - }, function (error) { - console.log(error); - }); + function(org) { + $location.path('/superadmin/organization/' + org.id); + }, + function(error) { + console.log(error); + }); }; } } -]); +]); \ No newline at end of file diff --git a/util/lint_js.sh b/util/lint_js.sh new file mode 100755 index 0000000000000000000000000000000000000000..7e2572ce00dd00bc4473c215ea33504fd53dd419 --- /dev/null +++ b/util/lint_js.sh @@ -0,0 +1,81 @@ +#! /bin/bash + +# Simple shell script for running jshint and nicely formatting the output + +JS_HINT=./node_modules/jshint/bin/jshint +JS_HINT_OPTS='--config .jshintrc' +JS_FILES=`find resources/frontend_client/app -name "*.js" | grep -v bower_components | grep -v 'app/test/' | grep -v '\#' | grep -v 'app/dist/' | grep -v react` + +BOLD='\033[1;30m' +RED='\033[0;31m' # \e doesn't work on OS X but \033 works on either +NC='\033[0m' + +HAS_ERROR=0 + +# Make the .js_hint_output dir if needed +if [ ! -d .js_hint_output ]; then + mkdir .js_hint_output +fi + +# cache file names are are just filename with '/' replaced by '_' and stuck in the .js_hint_output dir +cache_file_name () { + echo ".js_hint_output/"`echo $1 | sed 's:/:_:g'` +} + +# return unix timestamp for file or 0 if it doesn't exist + +# find out if stat supports --format (Linux or Mac w/ updated coreutils via homebrew) or +# if we need to use -c (default OS X) +# OS X version doesn't support --version so see if doing that returns non-zero exit code +if (( `stat --version >/dev/null 2>/dev/null; echo "$?"` )); then + STAT_FORMAT_FLAG='-f%m'; +else + STAT_FORMAT_FLAG='--format=%Y'; +fi +file_modified () { + file=$1 + if [ -f "$file" ] && [ -n "$file" ]; then # make sure filename is non-empty, -f will return true otherwise + echo `stat $STAT_FORMAT_FLAG $file` + else + echo "0"; + fi +} + +# Default output repeats file name on every offending line; +# Instead, we'll print the filename once in bold for all bad files +# and then print just the errors in red +run_js_lint () { + file=$1 + output_file=$2 + $JS_HINT $JS_HINT_OPTS $file | perl -pe 's/^.*(line.*)$/$1/' | sort > $output_file +} + +for file in $JS_FILES; do + # Find matching cached output if file hasn't changed since last run + cache_file=$(cache_file_name $file) + + # get file modified dates + file_modified_date=$(file_modified $file) + cache_file_modified_date=$(file_modified $cache_file) + + # run js lint to (re-)generate cache file if it's older than $file + if [ $cache_file_modified_date -lt $file_modified_date ]; then + run_js_lint $file $cache_file + fi + + # ok, output the cached file either way + errors=$(cat $cache_file) + if [ -n "$errors" ]; then + echo -e "\n\n"${BOLD}"$file" + echo -e ${RED} + echo "$errors" + echo -e ${NC} + HAS_ERROR=1 + fi +done + +if [[ $HAS_ERROR -eq 1 ]]; then + exit 1 +else + exit 0 +fi