+
-
diff --git a/app/js/app.factory.js b/app/js/app.factory.js
index f58332b..10b2cf8 100644
--- a/app/js/app.factory.js
+++ b/app/js/app.factory.js
@@ -194,10 +194,11 @@ function snorql($http, $q, $timeout, $location, config) {
// html output is done by parsing json
params.output='json'
this.$promise=$http({method:'GET', url:url,params:params,headers:accept, timeout: this.canceler.promise});
- console.log(this.$promise)
+
this.$promise.then(function(config){
self.result=(config.data);
- console.log(self.result);
+ }, function() {
+ console.log('promise failed');
})
return this;
}
@@ -229,7 +230,6 @@ function snorql($http, $q, $timeout, $location, config) {
// TODO: Refactor; non-standard link makers should be passed into the class by the caller
this._getLinkMaker = function(varName) {
- //console.log(varName);
if (varName == 'property') {
return function(uri) { return '?property=' + encodeURIComponent(uri); };
} else if (varName == 'class') {
diff --git a/app/js/app.js b/app/js/app.js
index 53d0c1a..1d2b93a 100755
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -1,232 +1,252 @@
-(function (angular, undefined) {'use strict';
-/**
- * create application snorql and load deps
- */
-var app = angular.module('snorql', [
- 'ngRoute',
- 'ngResource',
- 'npHelp',
- 'ui.codemirror',
- 'snorql.config',
- 'snorql.service',
- 'snorql.ui',
- 'snorql.user', // user
- 'auth0', // authorization (auth0)
- 'angular-jwt', // token
- 'ipCookie' // cookie
-]).controller('SnorqlCtrl',SnorqlCtrl)
- .factory('errorInterceptor',errorInterceptor)
- .config(appConfig)
- .run(appRun)
+(function (angular, undefined) {
+ 'use strict';
+ /**
+ * create application snorql and load deps
+ */
+ var app = angular.module('snorql', [
+ 'ngRoute',
+ 'ngResource',
+ 'npHelp',
+ 'ui.codemirror',
+ 'snorql.config',
+ 'snorql.service',
+ 'snorql.ui',
+ 'snorql.version',
+ 'snorql.tracker',
+ 'snorql.user', // user
+ 'auth0', // authorization (auth0)
+ 'angular-jwt', // token
+ 'ipCookie' // cookie
+ ]);
+
+ app.controller('SnorqlCtrl', SnorqlCtrl)
+ .factory('errorInterceptor', errorInterceptor)
+ .config(appConfig)
+ .run(appRun);
// init app
-appRun.$inject=['gitHubContent', 'config']
-function appRun(gitHubContent, config) {
- gitHubContent.initialize({
- // baseUrl:"http://uat-web2:8080",
- helpPath:'rdfhelp.json',
- helpTitle:'Generalities',
- root:'help', // specify the root of RDF entity routes
- githubRepo: '/',
- githubApi:config.apiUrl,
- githubEditPage : "https://github.com/calipho-sib/nextprot-docs/edit/master/",
- githubToken : null
- });
-};
+ appRun.$inject = ['gitHubContent', 'config']
+ function appRun(gitHubContent, config) {
+ gitHubContent.initialize({
+ // baseUrl:"http://uat-web2:8080",
+ helpPath: 'rdfhelp.json',
+ helpTitle: 'Generalities',
+ root: 'help', // specify the root of RDF entity routes
+ githubRepo: '/',
+ githubApi: config.apiUrl,
+ githubEditPage: "https://github.com/calipho-sib/nextprot-docs/edit/master/",
+ githubToken: null
+ });
+ };
//
// implement controller SnorqlCtrl
-SnorqlCtrl.$inject=['$scope','$timeout','$window','$location','snorql','config','gitHubContent','user']
-function SnorqlCtrl( $scope, $timeout, $window, $location, snorql, config, gitHubContent, user) {
- // user
- $scope.user=user;
-
- //
- // go home link
- $scope.home=config.home;
- $scope.pushState=config.pushState;
-
- //
- // snorql service provide examples, examples tags, config and executeQuery
- $scope.snorql=snorql;
-
- //
- // setup default output
- $scope.outputs=['html','json','csv','xml'];
- $scope.output='html';
- $scope.showPrefixes = false;
-
- //
- // default message
- $scope.message="Executing query ...";
-
- $scope.waiting=false;
- $scope.filter=""
- $scope.filterTag = null;
-
- // codemirror option
- $scope.cmOption = {
- lineNumbers: false,
- indentWithTabs: true,
- uiRefresh:true,
- mode:'sparql'
- };
-
- // vocabulary query
- var vocSparqlQuery='SELECT DISTINCT * WHERE { ?term rdfs:label ?label ; a ?type . filter(regex(?label,"^__CV__","i")) } LIMIT 30';
- $scope.searchTerm=function(term){
- var time=Date.now();
- $scope.executionTime=false;
- $scope.waiting=true;
- $scope.error=false;
- snorql.executeQuery(vocSparqlQuery.replace('__CV__',term), {output:'html'}).$promise.then(function(){
- $scope.waiting=false;
- $scope.executionTime=(Date.now()-time)/1000;
- },function(reason){
- $scope.error=reason.data.message
- $scope.waiting=false
- });
- }
-
- $scope.executeQuery=function(sparql,output){
- var time=Date.now();
- $scope.executionTime=false;
- $scope.waiting=true;
- $scope.error=false;
- $location.search('query',sparql)
- $location.search('class',null)
- $location.search('property',null)
- $location.search('describe',null)
- var params=angular.extend($location.search(),{output:output});
- snorql.executeQuery(sparql, params).$promise.then(function(){
- $scope.waiting=false;
- $scope.executionTime=(Date.now()-time)/1000;
- },function(reason){
- $scope.error=reason.data.message
- $scope.waiting=false
- });
- };
-
- $scope.selectExample=function(elm){
- snorql.query=snorql.examples[elm].sparql;
- snorql.description=snorql.examples[elm].description;
- snorql.selectedQueryId=snorql.examples[elm].userQueryId;
- snorql.queryTitle=snorql.examples[elm].title;
- $scope.qSelected=elm
- $('.row-offcanvas').removeClass('active')
- };
-
- $scope.setFilterTag=function(tag){
- $scope.filterTag=tag;
- };
-
- $scope.resetFilters=function(){
- $scope.filterTag=null;
- };
-
- $scope.reset=function(){
- snorql.reset();
- };
-
- $scope.login=function(){
- user.login();
- };
-
- $scope.logout=function(){
- user.logout();
- };
-
- //
- // load sparql examples
- snorql.loadExamples()
-
- //
- // kind of queries,
- // query, describe, class, property
- snorql.updateQuery($location.search())
- // $scope.executeQuery(snorql.updateQuery($location.search()));
- $scope.$on('$locationChangeSuccess',function(url){
- snorql.updateQuery($location.search())
-
- if($location.path()==='/') {
- $window.document.title = "neXtProt SnorQL";
- }
-
- })
-};
-
-
-/**
- * ANGULAR BOOTSTRAP
- */
-appConfig.$inject=['$routeProvider','$locationProvider','$httpProvider','authProvider','jwtInterceptorProvider']
-function appConfig($routeProvider, $locationProvider, $httpProvider, authProvider, jwtInterceptorProvider) {
-
- authProvider.init({
- clientID: '7vS32LzPoIR1Y0JKahOvUCgGbn94AcFW',
- callbackURL: window.location.origin,
- domain: 'nextprot.auth0.com',
- icon: '/img/np.png'
- });
-
- jwtInterceptorProvider.tokenGetter = ['ipCookie', function (ipCookie) {
- // Return the saved token
- return ipCookie('nxtoken');
- }];
- $httpProvider.interceptors.push('jwtInterceptor');
-
- // intercept errors
- $httpProvider.interceptors.push('errorInterceptor')
-
-
- // List of routes of the application
- $routeProvider
- // Home page
- .when('/', {title: 'welcome to snorql', templateUrl: '/partials/home.html'})
- // Pages (in nextprot-docs/pages): about, copyright...
- .when('/:article', {title: 'page', templateUrl: '/partials/page.html'})
- //// Help pages
- // GENERALITIES
- .when('/help/doc/:article',{title: 'help for snorql', templateUrl: '/partials/doc.html'})
- // RDF ENTITIES
- .when('/help/entity/:entity',{title: 'help for snorql', templateUrl: '/partials/help.html'})
-
- // Without serve side support html5 must be disabled.
- $locationProvider.html5Mode(true);
- //$locationProvider.hashPrefix = '!';
-};
-
-errorInterceptor.$inject=['$q', '$rootScope', '$location']
-function errorInterceptor($q, $rootScope, $location) {
- return {
- request: function (config) {
- return config || $q.when(config);
- },
- requestError: function(request){
- return $q.reject(request);
- },
- response: function (response) {
- return response || $q.when(response);
- },
- responseError: function (response) {
- if (response && response.status === 0) {
- $rootScope.error="The API is not accessible";
- }
- if (response && response.status === 401) {
- $rootScope.error="You are not authorized to access the resource. Please login or review your privileges.";
- }
- if (response && response.status === 404) {
- $rootScope.error="URL not found";
- }
- if (response && response.status >= 500) {
- $rootScope.error="Request Failed";
- }
- return $q.reject(response);
+ SnorqlCtrl.$inject = ['Tracker', '$scope', '$routeParams', '$timeout', '$window', '$location', 'snorql', 'config', 'gitHubContent', 'user']
+ function SnorqlCtrl(Tracker, $scope, $routeParams, $timeout, $window, $location, snorql, config, gitHubContent, user) {
+ // user
+ $scope.user = user;
+
+ //
+ // go home link
+ $scope.home = config.home;
+ $scope.pushState = config.pushState;
+
+ //
+ // snorql service provide examples, examples tags, config and executeQuery
+ $scope.snorql = snorql;
+
+ //
+ // setup default output
+ $scope.outputs = ['html', 'json', 'csv', 'xml'];
+ $scope.output = 'html';
+ $scope.showPrefixes = false;
+
+ //
+ // default message
+ $scope.message = "Executing query ...";
+
+ $scope.waiting = false;
+ $scope.filter = ""
+ $scope.filterTag = null;
+
+ // codemirror option
+ $scope.cmOption = {
+ lineNumbers: false,
+ indentWithTabs: true,
+ uiRefresh: true,
+ mode: 'sparql'
+ };
+
+ $scope.$on('$routeChangeSuccess', function (event, next, current) {
+ Tracker.trackPageView();
+ Tracker.trackRouteChangeEvent();
+ });
+
+ // vocabulary query
+ var vocSparqlQuery = 'SELECT DISTINCT * WHERE { ?term rdfs:label ?label ; a ?type . filter(regex(?label,"^__CV__","i")) } LIMIT 30';
+ $scope.searchTerm = function (term) {
+
+ var time = Date.now();
+ $scope.executionTime = false;
+ $scope.waiting = true;
+ $scope.error = false;
+ snorql.executeQuery(vocSparqlQuery.replace('__CV__', term), {output: 'html'}).$promise.then(function () {
+ $scope.waiting = false;
+ $scope.executionTime = (Date.now() - time) / 1000;
+
+ Tracker.trackSearchTermEvent(term, true);
+ }, function (reason) {
+ $scope.error = reason.data.message;
+ $scope.waiting = false;
+
+ Tracker.trackSearchTermEvent(term, false);
+ });
}
+
+ $scope.routingOutside = function(input) {
+ Tracker.trackTransitionRouteChangeEvent(input);
+ };
+
+ $scope.executeQuery = function (sparql, output) {
+ var time = Date.now();
+ $scope.executionTime = false;
+ $scope.waiting = true;
+ $scope.error = false;
+ $location.search('query', sparql)
+ $location.search('class', null)
+ $location.search('property', null)
+ $location.search('describe', null)
+ var params = angular.extend($location.search(), {output: output});
+ snorql.executeQuery(sparql, params).$promise.then(function () {
+ $scope.waiting = false;
+ $scope.executionTime = (Date.now() - time) / 1000;
+ }, function (reason) {
+ $scope.error = reason.data.message
+ $scope.waiting = false
+ });
+ };
+
+ $scope.selectExample = function (elm) {
+ snorql.query = snorql.examples[elm].sparql;
+ snorql.description = snorql.examples[elm].description;
+ snorql.selectedQueryId = snorql.examples[elm].userQueryId;
+ snorql.queryTitle = snorql.examples[elm].title;
+ $scope.qSelected = elm
+ $('.row-offcanvas').removeClass('active')
+
+ Tracker.trackSelectExampleEvent(snorql.selectedQueryId);
+ };
+
+ $scope.setFilterTag = function (tag) {
+ $scope.filterTag = tag;
+ };
+
+ $scope.resetFilters = function () {
+ $scope.filterTag = null;
+ };
+
+ $scope.reset = function () {
+ snorql.reset();
+ };
+
+ $scope.login = function () {
+ user.login();
+ };
+
+ $scope.logout = function () {
+ user.logout();
+ };
+
+ //
+ // load sparql examples
+ snorql.loadExamples()
+
+ //
+ // kind of queries,
+ // query, describe, class, property
+ snorql.updateQuery($location.search())
+ // $scope.executeQuery(snorql.updateQuery($location.search()));
+ $scope.$on('$locationChangeSuccess', function (url) {
+ snorql.updateQuery($location.search())
+
+ if ($location.path() === '/') {
+ $window.document.title = "neXtProt SnorQL";
+ }
+
+ })
+ };
+
+
+ /**
+ * ANGULAR BOOTSTRAP
+ */
+ appConfig.$inject = ['$routeProvider', '$locationProvider', '$httpProvider', 'authProvider', 'jwtInterceptorProvider']
+ function appConfig($routeProvider, $locationProvider, $httpProvider, authProvider, jwtInterceptorProvider) {
+
+ authProvider.init({
+ clientID: '7vS32LzPoIR1Y0JKahOvUCgGbn94AcFW',
+ callbackURL: window.location.origin,
+ domain: 'nextprot.auth0.com',
+ icon: '/img/np.png'
+ });
+
+ jwtInterceptorProvider.tokenGetter = ['ipCookie', function (ipCookie) {
+ // Return the saved token
+ return ipCookie('nxtoken');
+ }];
+ $httpProvider.interceptors.push('jwtInterceptor');
+
+ // intercept errors
+ $httpProvider.interceptors.push('errorInterceptor')
+
+
+ // List of routes of the application
+ $routeProvider
+ // Home page
+ .when('/', {title: 'welcome to snorql', templateUrl: '/partials/home.html'})
+ // Pages (in nextprot-docs/pages): about, copyright...
+ .when('/:article', {title: 'page', templateUrl: '/partials/page.html'})
+ //// Help pages
+ // GENERALITIES
+ .when('/help/doc/:article', {title: 'help for snorql', templateUrl: '/partials/doc.html'})
+ // RDF ENTITIES
+ .when('/help/entity/:entity', {title: 'help for snorql', templateUrl: '/partials/help.html'})
+
+ // Without serve side support html5 must be disabled.
+ $locationProvider.html5Mode(true);
+ //$locationProvider.hashPrefix = '!';
};
-};
+ errorInterceptor.$inject = ['$q', '$rootScope', '$location']
+ function errorInterceptor($q, $rootScope, $location) {
+ return {
+ request: function (config) {
+ return config || $q.when(config);
+ },
+ requestError: function (request) {
+ return $q.reject(request);
+ },
+ response: function (response) {
+ return response || $q.when(response);
+ },
+ responseError: function (response) {
+ if (response && response.status === 0) {
+ $rootScope.error = "The API is not accessible";
+ }
+ if (response && response.status === 401) {
+ $rootScope.error = "You are not authorized to access the resource. Please login or review your privileges.";
+ }
+ if (response && response.status === 404) {
+ $rootScope.error = "URL not found";
+ }
+ if (response && response.status >= 500) {
+ $rootScope.error = "Request Failed";
+ }
+ return $q.reject(response);
+ }
+ };
+ };
})(angular);
diff --git a/app/js/tracker/snorql.tracker.service.js b/app/js/tracker/snorql.tracker.service.js
new file mode 100644
index 0000000..6f5bcaf
--- /dev/null
+++ b/app/js/tracker/snorql.tracker.service.js
@@ -0,0 +1,235 @@
+'use strict';
+
+var TrackingService = angular.module('snorql.tracker', []);
+
+TrackingService
+ .value('developTrackingId', 'UA-61448300-1')
+ .value('productionTrackingId', 'UA-61448300-2')
+ .value('trackingProduction', 'NX_TRACKING_PROD');
+
+TrackingService.factory('Tracker', [
+ '$window',
+ '$location',
+ '$routeParams',
+ 'version', 'build',
+ 'developTrackingId','productionTrackingId','trackingProduction',
+ function ($window, $location, $routeParams,
+ version, build,
+ developTrackingId, productionTrackingId, trackingProduction) {
+
+ var separator = '_';
+
+ var tracker = {};
+
+ tracker.trackPageView = function () {
+ $window.ga('send', 'pageview', $location.url());
+ };
+
+ tracker.trackTransitionRouteChangeEvent = function(dest) {
+
+ var gaEvent = {
+ 'hitType': 'event',
+ 'eventCategory': 'snorql'+separator+'routing-'+dest
+ };
+
+ if (Object.keys(gaEvent).length>0) {
+
+ console.log("tracking transition route -> ga event:", gaEvent);
+ ga('send', gaEvent);
+ }
+ };
+
+ tracker.trackRouteChangeEvent = function() {
+
+ var gaEvent = {};
+
+ if ("article" in $routeParams) {
+ gaEvent = new HelpRouteEvent('doc', $routeParams.article);
+ }
+ else if ("entity" in $routeParams) {
+ gaEvent = new HelpRouteEvent('entity', $routeParams.entity);
+ }
+ else if ("query" in $routeParams) {
+ gaEvent = new SparqlSearchRouteEvent($routeParams.output);
+ }
+
+ if (Object.keys(gaEvent).length>0) {
+
+ console.log("tracking route -> ga event:", gaEvent);
+ ga('send', gaEvent);
+ }
+ };
+
+ tracker.trackSelectExampleEvent = function(selectedQueryId) {
+
+ var gaEvent = {
+ 'hitType': 'event',
+ 'eventCategory': 'snorql'+separator+'select-example'
+ };
+
+ gaEvent.eventAction = gaEvent.eventCategory;
+ gaEvent.eventLabel = gaEvent.eventAction+separator+formatQueryId(selectedQueryId);
+
+ console.log("tracking example selection event -> ga event:", gaEvent);
+
+ ga('send', gaEvent);
+ };
+
+ tracker.trackSearchTermEvent = function(term, hasSucceed) {
+
+ if (!hasSucceed) {
+
+ var exceptionEvent = {
+ 'exDescription': 'could not search term "'+term+'"',
+ 'exFatal': false,
+ 'appName': 'nextprot-snorql',
+ 'appVersion': version
+ };
+
+ if (!isNaN(build))
+ exceptionEvent.appVersion += "-build."+build;
+
+ console.log("tracking searching term exception -> ga event:", exceptionEvent);
+ ga('send', 'exception', exceptionEvent);
+ } else {
+
+ var gaEvent = newSearchTermEvent(term);
+
+ console.log("tracking searching term event -> ga event:", gaEvent);
+ ga('send', gaEvent);
+ }
+ };
+
+ tracker.trackContactUsEvent = function(subject) {
+
+ var gaEvent = {
+ 'hitType': 'event',
+ 'eventCategory': 'snorql'+separator+'contact-us'
+ };
+
+ gaEvent.actionCategory = gaEvent.eventCategory+separator+subject;
+
+ console.log("tracking contacting us -> ga event:", gaEvent);
+ ga('send', gaEvent);
+ };
+
+ function newSearchTermEvent(term) {
+
+ var gaEvent = {
+ 'hitType': 'event',
+ 'eventCategory': 'snorql'+separator+'search'
+ };
+
+ gaEvent.eventAction = gaEvent.eventCategory+separator+'term';
+ gaEvent.eventLabel = gaEvent.eventAction+separator+term;
+
+ console.log("tracking search term -> ga event:", gaEvent);
+
+ return gaEvent;
+ }
+
+ function RouteEvent(funcCategory, funcAction, funcLabel) {
+
+ funcCategory = typeof funcCategory !== 'undefined' ? funcCategory : function() {return ""};
+ funcAction = typeof funcAction !== 'undefined' ? funcAction : function() {return ""};
+
+ var event = {
+ 'hitType': 'event',
+ 'eventCategory': 'snorql'+separator+funcCategory(),
+ 'eventAction': 'snorql'+separator+funcAction()
+ };
+
+ if (typeof funcLabel !== 'undefined')
+ event.eventLabel = 'snorql'+separator+funcLabel();
+
+ return event;
+ }
+
+ function HelpRouteEvent(doctype, docname) {
+
+ var object = new RouteEvent(category, action, label);
+
+ function category() {
+ return 'help';
+ }
+
+ function action() {
+ return category()+separator+doctype;
+ }
+
+ function label() {
+ return action()+separator+docname;
+ }
+
+ return object;
+ }
+
+ function SparqlSearchRouteEvent(output) {
+
+ function category() {
+ return 'search';
+ }
+
+ function action() {
+
+ return category()+separator+'sparql';
+ }
+
+ function label() {
+
+ return action()+separator+((output) ? output : 'html');
+ }
+
+ return new RouteEvent(category, action, label);
+ }
+
+ function formatQueryId(queryId) {
+
+ function log10(val) {
+ return Math.log(val) / Math.LN10;
+ }
+ var numOf0s = 4-Math.floor(log10(queryId));
+ var query = "NXQ_";
+
+ while (numOf0s--) {
+ query += '0';
+ }
+ query += queryId;
+
+ return query;
+ }
+
+ // The ga() function provides a single access point for everything in the analytics.js library
+ // all tracking calls are made via the ga() function
+ function createAndInitGATracker(propertyId) {
+
+ // Google Analytics
+ // Asynchronously loads the analytics.js library onto this page
+ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+ m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+ })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+ // Creates a new default tracker object
+ ga('create', propertyId, 'auto');
+ }
+
+ function getTrackingId() {
+
+ var trackingId = (trackingProduction != 'NX_TRACKING_PROD') ? productionTrackingId : developTrackingId;
+
+ console.log('tracking ids: develop:', developTrackingId, ', production:', productionTrackingId);
+ console.log('tracking '+trackingId);
+
+ return trackingId;
+ }
+
+ // Setup Universal Analytics Web Tracking (analytics.js)
+ createAndInitGATracker(getTrackingId());
+
+ // Sends a first pageview hit for the current page to Google Analytics
+ ga('send', 'pageview');
+
+ return tracker;
+ }]);
+
diff --git a/app/js/version/version-directive.js b/app/js/version/version-directive.js
new file mode 100644
index 0000000..cefd187
--- /dev/null
+++ b/app/js/version/version-directive.js
@@ -0,0 +1,16 @@
+'use strict';
+
+angular.module('snorql.version.version-directive', [])
+
+.directive('sqBuildVersion', ['version', 'build', function (version, build) {
+
+ return function (scope, elm, attrs) {
+
+ var content = version;
+
+ if (!isNaN(build))
+ content += " (build "+build+")";
+
+ elm.text(content);
+ };
+}]);
diff --git a/app/js/version/version.js b/app/js/version/version.js
new file mode 100644
index 0000000..99afb3b
--- /dev/null
+++ b/app/js/version/version.js
@@ -0,0 +1,8 @@
+'use strict';
+
+angular.module('snorql.version', [
+ 'snorql.version.version-directive'
+])
+
+.value('version', '0.1.2')
+.value('build', 'NX_BUILD');