Add mix panel analytics to Quay
This commit is contained in:
parent
df36a0b913
commit
be1582ba29
4 changed files with 196 additions and 13 deletions
|
@ -1,5 +1,5 @@
|
|||
// Start the application code itself.
|
||||
quayApp = angular.module('quay', ['restangular', 'angularMoment'], function($provide) {
|
||||
quayApp = angular.module('quay', ['restangular', 'angularMoment', 'angulartics', 'angulartics.mixpanel'], function($provide) {
|
||||
$provide.factory('UserService', ['Restangular', function(Restangular) {
|
||||
var userResponse = {
|
||||
verified: false,
|
||||
|
@ -14,6 +14,15 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment'], function($pro
|
|||
var userFetch = Restangular.one('user/');
|
||||
userFetch.get().then(function(loadedUser) {
|
||||
userResponse = loadedUser;
|
||||
|
||||
if (!userResponse.anonymous) {
|
||||
mixpanel.identify(userResponse.username);
|
||||
mixpanel.people.set({
|
||||
'$email': userResponse.email,
|
||||
'$username': userResponse.username,
|
||||
'verified': userResponse.verified
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -39,18 +48,21 @@ quayApp = angular.module('quay', ['restangular', 'angularMoment'], function($pro
|
|||
}
|
||||
};
|
||||
}).
|
||||
config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
|
||||
$routeProvider.
|
||||
when('/repository/:namespace/:name', {templateUrl: '/static/partials/view-repo.html', controller: RepoCtrl}).
|
||||
when('/repository/:namespace/:name/tag/:tag', {templateUrl: '/static/partials/view-repo.html', controller: RepoCtrl}).
|
||||
when('/repository/:namespace/:name/admin', {templateUrl: '/static/partials/repo-admin.html', controller:RepoAdminCtrl}).
|
||||
when('/repository/', {title: 'Repositories', templateUrl: '/static/partials/repo-list.html', controller: RepoListCtrl}).
|
||||
when('/user', {title: 'User Admin', templateUrl: '/static/partials/user-admin.html', controller: UserAdminCtrl}).
|
||||
when('/guide/', {title: 'Getting Started Guide', templateUrl: '/static/partials/guide.html', controller: GuideCtrl}).
|
||||
when('/plans/', {title: 'Quay Plans', templateUrl: '/static/partials/plans.html', controller: PlansCtrl}).
|
||||
when('/', {title: 'Quay', templateUrl: '/static/partials/landing.html', controller: LandingCtrl}).
|
||||
otherwise({redirectTo: '/'});
|
||||
}]).
|
||||
config(['$routeProvider', '$locationProvider', '$analyticsProvider',
|
||||
function($routeProvider, $locationProvider, $analyticsProvider) {
|
||||
$analyticsProvider.virtualPageviews(true);
|
||||
|
||||
$routeProvider.
|
||||
when('/repository/:namespace/:name', {templateUrl: '/static/partials/view-repo.html', controller: RepoCtrl}).
|
||||
when('/repository/:namespace/:name/tag/:tag', {templateUrl: '/static/partials/view-repo.html', controller: RepoCtrl}).
|
||||
when('/repository/:namespace/:name/admin', {templateUrl: '/static/partials/repo-admin.html', controller:RepoAdminCtrl}).
|
||||
when('/repository/', {title: 'Repositories', templateUrl: '/static/partials/repo-list.html', controller: RepoListCtrl}).
|
||||
when('/user', {title: 'User Admin', templateUrl: '/static/partials/user-admin.html', controller: UserAdminCtrl}).
|
||||
when('/guide/', {title: 'Getting Started Guide', templateUrl: '/static/partials/guide.html', controller: GuideCtrl}).
|
||||
when('/plans/', {title: 'Quay Plans', templateUrl: '/static/partials/plans.html', controller: PlansCtrl}).
|
||||
when('/', {title: 'Quay', templateUrl: '/static/partials/landing.html', controller: LandingCtrl}).
|
||||
otherwise({redirectTo: '/'});
|
||||
}]).
|
||||
config(function(RestangularProvider) {
|
||||
RestangularProvider.setBaseUrl('/api/');
|
||||
});
|
||||
|
|
30
static/lib/angulartics-mixpanel.js
vendored
Executable file
30
static/lib/angulartics-mixpanel.js
vendored
Executable file
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* @license Angulartics v0.8.5
|
||||
* (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics
|
||||
* Contributed by http://github.com/L42y
|
||||
* License: MIT
|
||||
*/
|
||||
(function(angular) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name angulartics.mixpanel
|
||||
* Enables analytics support for Mixpanel (http://mixpanel.com)
|
||||
*/
|
||||
angular.module('angulartics.mixpanel', ['angulartics'])
|
||||
.config(['$analyticsProvider', function ($analyticsProvider) {
|
||||
angulartics.waitForVendorApi('mixpanel', 500, function (mixpanel) {
|
||||
$analyticsProvider.registerPageTrack(function (path) {
|
||||
if (path.indexOf('http') == 0) { return; }
|
||||
window.mixpanel.track('page_view', { 'url' : path });
|
||||
});
|
||||
});
|
||||
|
||||
angulartics.waitForVendorApi('mixpanel', 500, function (mixpanel) {
|
||||
$analyticsProvider.registerEventTrack(function (action, properties) {
|
||||
window.mixpanel.track(action, properties);
|
||||
});
|
||||
});
|
||||
}]);
|
||||
})(angular);
|
132
static/lib/angulartics.js
vendored
Executable file
132
static/lib/angulartics.js
vendored
Executable file
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* @license Angulartics v0.8.5
|
||||
* (c) 2013 Luis Farzati http://luisfarzati.github.io/angulartics
|
||||
* License: MIT
|
||||
*/
|
||||
(function(angular, analytics) {
|
||||
'use strict';
|
||||
|
||||
var angulartics = window.angulartics || (window.angulartics = {});
|
||||
angulartics.waitForVendorApi = function (objectName, delay, registerFn) {
|
||||
if (!window.hasOwnProperty(objectName)) {
|
||||
setTimeout(function () { angulartics.waitForVendorApi(objectName, delay, registerFn); }, delay);
|
||||
}
|
||||
else {
|
||||
registerFn(window[objectName]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name angulartics
|
||||
*/
|
||||
angular.module('angulartics', [])
|
||||
.provider('$analytics', function () {
|
||||
var settings = {
|
||||
pageTracking: {
|
||||
autoTrackFirstPage: true,
|
||||
autoTrackVirtualPages: true,
|
||||
basePath: '',
|
||||
bufferFlushDelay: 1000
|
||||
},
|
||||
eventTracking: {
|
||||
bufferFlushDelay: 1000
|
||||
}
|
||||
};
|
||||
|
||||
var cache = {
|
||||
pageviews: [],
|
||||
events: []
|
||||
};
|
||||
|
||||
var bufferedPageTrack = function (path) {
|
||||
cache.pageviews.push(path);
|
||||
};
|
||||
var bufferedEventTrack = function (event, properties) {
|
||||
cache.events.push({name: event, properties: properties});
|
||||
};
|
||||
|
||||
var api = {
|
||||
settings: settings,
|
||||
pageTrack: bufferedPageTrack,
|
||||
eventTrack: bufferedEventTrack
|
||||
};
|
||||
|
||||
var registerPageTrack = function (fn) {
|
||||
api.pageTrack = fn;
|
||||
angular.forEach(cache.pageviews, function (path, index) {
|
||||
setTimeout(function () { api.pageTrack(path); }, index * settings.pageTracking.bufferFlushDelay);
|
||||
});
|
||||
};
|
||||
var registerEventTrack = function (fn) {
|
||||
api.eventTrack = fn;
|
||||
angular.forEach(cache.events, function (event, index) {
|
||||
setTimeout(function () { api.eventTrack(event.name, event.properties); }, index * settings.eventTracking.bufferFlushDelay);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
$get: function() { return api; },
|
||||
settings: settings,
|
||||
virtualPageviews: function (value) { this.settings.pageTracking.autoTrackVirtualPages = value; },
|
||||
firstPageview: function (value) { this.settings.pageTracking.autoTrackFirstPage = value; },
|
||||
withBase: function (value) { this.settings.pageTracking.basePath = (value) ? angular.element('base').attr('href').slice(0, -1) : ''; },
|
||||
registerPageTrack: registerPageTrack,
|
||||
registerEventTrack: registerEventTrack
|
||||
};
|
||||
})
|
||||
|
||||
.run(['$rootScope', '$location', '$analytics', function ($rootScope, $location, $analytics) {
|
||||
if ($analytics.settings.pageTracking.autoTrackFirstPage) {
|
||||
$analytics.pageTrack($location.absUrl());
|
||||
}
|
||||
if ($analytics.settings.pageTracking.autoTrackVirtualPages) {
|
||||
$rootScope.$on('$routeChangeSuccess', function (event, current) {
|
||||
if (current && (current.$$route||current).redirectTo) return;
|
||||
var url = $analytics.settings.pageTracking.basePath + $location.url();
|
||||
$analytics.pageTrack(url);
|
||||
});
|
||||
}
|
||||
}])
|
||||
|
||||
.directive('analyticsOn', ['$analytics', function ($analytics) {
|
||||
function isCommand(element) {
|
||||
return ['a:','button:','button:button','button:submit','input:button','input:submit'].indexOf(
|
||||
element.tagName.toLowerCase()+':'+(element.type||'')) >= 0;
|
||||
}
|
||||
|
||||
function inferEventType(element) {
|
||||
if (isCommand(element)) return 'click';
|
||||
return 'click';
|
||||
}
|
||||
|
||||
function inferEventName(element) {
|
||||
if (isCommand(element)) return element.innerText || element.value;
|
||||
return element.id || element.name || element.tagName;
|
||||
}
|
||||
|
||||
function isProperty(name) {
|
||||
return name.substr(0, 9) === 'analytics' && ['on', 'event'].indexOf(name.substr(10)) === -1;
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: false,
|
||||
link: function ($scope, $element, $attrs) {
|
||||
var eventType = $attrs.analyticsOn || inferEventType($element[0]),
|
||||
eventName = $attrs.analyticsEvent || inferEventName($element[0]);
|
||||
|
||||
var properties = {};
|
||||
angular.forEach($attrs.$attr, function(attr, name) {
|
||||
if (isProperty(attr)) {
|
||||
properties[name.slice(9).toLowerCase()] = $attrs[name];
|
||||
}
|
||||
});
|
||||
|
||||
angular.element($element[0]).bind(eventType, function () {
|
||||
$analytics.eventTrack(eventName, properties);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
})(angular);
|
|
@ -19,6 +19,10 @@
|
|||
<script src="//cdn.jsdelivr.net/restangular/1.1.3/restangular.js"></script>
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.2.1/moment.min.js"></script>
|
||||
|
||||
<script src="static/lib/angulartics.js"></script>
|
||||
<script src="static/lib/angulartics-mixpanel.js"></script>
|
||||
|
||||
<script src="static/lib/angular-moment.min.js"></script>
|
||||
<script src="static/lib/pagedown/Markdown.Converter.js"></script>
|
||||
<script src="static/lib/pagedown/Markdown.Editor.js"></script>
|
||||
|
@ -30,6 +34,11 @@
|
|||
<script src="static/js/app.js"></script>
|
||||
<script src="static/js/controllers.js"></script>
|
||||
|
||||
<!-- start Mixpanel --><script type="text/javascript">(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==
|
||||
typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");for(g=0;g<i.length;g++)f(c,i[g]);
|
||||
b._i.push([a,e,d])};b.__SV=1.2}})(document,window.mixpanel||[]);
|
||||
mixpanel.init("38014a0f27e7bdc3ff8cc7cc29c869f9", { track_pageview : false });</script><!-- end Mixpanel -->
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<!-- Nav bar -->
|
||||
|
|
Reference in a new issue