You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@usergrid.apache.org by sn...@apache.org on 2014/03/31 23:23:43 UTC
[3/9] merging upstream
http://git-wip-us.apache.org/repos/asf/incubator-usergrid/blob/09611d5b/portal/js/usergrid-dev.min.js
----------------------------------------------------------------------
diff --cc portal/js/usergrid-dev.min.js
index 87fd017,af849c2..0e96767
--- a/portal/js/usergrid-dev.min.js
+++ b/portal/js/usergrid-dev.min.js
@@@ -4512,6 -4511,6 +4511,19760 @@@
$templateCache.put("users/users-tabs.html", "\n" + "\n" + "\n");
$templateCache.put("users/users.html", '<div class="content-page">\n' + "\n" + ' <page-title title=" Users" icon="👤"></page-title>\n' + ' <bsmodal id="newUser"\n' + ' title="Create New User"\n' + ' close="hideModal"\n' + ' closelabel="Cancel"\n' + ' buttonid="users"\n' + ' extrabutton="newUserDialog"\n' + ' extrabuttonlabel="Create"\n' + " ng-cloak>\n" + " <fieldset>\n" + ' <div class="control-group">\n' + ' <label for="new-user-username">Username</label>\n' + "\n" + ' <div class="controls">\n' + ' <input type="text" required ng-model="$parent.newUser.newusername" ng-pattern="usernameRegex" ng-attr-title="{{usernameRegexDescription}}" name="username" id="new-user-username" class="input-xlarge" ug-validate/>\n' + ' <p class="help-block hide"></p>\n' + " </div>\n" + " </div>\n" + ' <div class="control-group">\n' + ' <label for="new-u
ser-fullname">Full name</label>\n' + "\n" + ' <div class="controls">\n' + ' <input type="text" required ng-attr-title="{{nameRegexDescription}}" ng-pattern="nameRegex" ng-model="$parent.newUser.name" name="name" id="new-user-fullname" class="input-xlarge" ug-validate/>\n' + "\n" + ' <p class="help-block hide"></p>\n' + " </div>\n" + " </div>\n" + ' <div class="control-group">\n' + ' <label for="new-user-email">Email</label>\n' + "\n" + ' <div class="controls">\n' + ' <input type="email" required ng-model="$parent.newUser.email" pattern="emailRegex" ng-attr-title="{{emailRegexDescription}}" name="email" id="new-user-email" class="input-xlarge" ug-validate/>\n' + "\n" + ' <p class="help-block hide"></p>\n' + " </div>\n" + " </div>\n" + ' <div class="control-group">\n' + ' <label for="new-user-password">Password</label>\n' + "\n" + ' <div class="controls">\n' + ' <inpu
t type="password" required ng-pattern="passwordRegex" ng-attr-title="{{passwordRegexDescription}}" ng-model="$parent.newUser.newpassword" name="password" id="new-user-password" ug-validate\n' + ' class="input-xlarge"/>\n' + "\n" + ' <p class="help-block hide"></p>\n' + " </div>\n" + " </div>\n" + ' <div class="control-group">\n' + ' <label for="new-user-re-password">Confirm password</label>\n' + "\n" + ' <div class="controls">\n' + ' <input type="password" required ng-pattern="passwordRegex" ng-attr-title="{{passwordRegexDescription}}" ng-model="$parent.newUser.repassword" name="re-password" id="new-user-re-password" ug-validate\n' + ' class="input-xlarge"/>\n' + "\n" + ' <p class="help-block hide"></p>\n' + " </div>\n" + " </div>\n" + " </fieldset>\n" + " </bsmodal>\n" + "\n" + ' <bsmodal id="deleteUser"\n' + ' title="Delete User"\n' + ' close="hideModal"
\n' + ' closelabel="Cancel"\n' + ' extrabutton="deleteUsersDialog"\n' + ' extrabuttonlabel="Delete"\n' + ' buttonid="deleteusers"\n' + " ng-cloak>\n" + " <p>Are you sure you want to delete the user(s)?</p>\n" + " </bsmodal>\n" + "\n" + ' <section class="row-fluid">\n' + ' <div class="span3 user-col">\n' + "\n" + ' <div class="button-toolbar span12">\n' + ' <a title="Select All" class="btn btn-primary toolbar select-all" ng-show="hasUsers" ng-click="selectAllEntities(usersCollection._list,this,\'usersSelected\',true)" ng-model="usersSelected"> <i class="pictogram">⊟</i></a>\n' + ' <button title="Delete" class="btn btn-primary toolbar" ng-disabled="!hasUsers || !valueSelected(usersCollection._list)" ng-click="showModal(\'deleteUser\')" id="delete-user-button"><i class="pictogram">☕</i></button>\n' + ' <button title="Add" class="btn btn-primary toolbar" ng-click="showModal(\'newUser\
')" id="new-user-button" ng-attr-id="new-user-button"><i class="pictogram"></i></button>\n' + " </div>\n" + ' <ul class="user-list">\n' + ' <li ng-class="selectedUser._data.uuid === user._data.uuid ? \'selected\' : \'\'" ng-repeat="user in usersCollection._list" ng-click="selectUser(user._data.uuid)">\n' + " <input\n" + ' type="checkbox"\n' + " id=\"user-{{user.get('username')}}-checkbox\"\n" + " ng-value=\"user.get('uuid')\"\n" + ' ng-checked="master"\n' + ' ng-model="user.checked"\n' + " >\n" + " <a href=\"javaScript:void(0)\" id=\"user-{{user.get('username')}}-link\" >{{user.get('username')}}</a>\n" + ' <span ng-if="user.name" class="label">Display Name:</span>{{user.name}}\n' + " </li>\n" + " </ul>\n" + "\n" + ' <div style="padding: 10px 5px 10px 5px">\n' + ' <button class="btn btn-primary t
oolbar" ng-click="getPrevious()" style="display:{{previous_display}}">< Previous\n' + " </button>\n" + ' <button class="btn btn-primary toolbar" ng-click="getNext()" style="display:{{next_display}}; float:right;">Next >\n' + " </button>\n" + " </div>\n" + "\n" + " </div>\n" + "\n" + ' <div class="span9 tab-content" ng-show="hasUsers">\n' + ' <div class="menu-toolbar">\n' + ' <ul class="inline">\n' + ' <li class="tab" ng-class="currentUsersPage.route === \'/users/profile\' ? \'selected\' : \'\'"><a class="btn btn-primary toolbar" ng-click="selectUserPage(\'/users/profile\')"><i class="pictogram"></i>Profile</a></li>\n' + ' <li class="tab" ng-class="currentUsersPage.route === \'/users/groups\' ? \'selected\' : \'\'"><a class="btn btn-primary toolbar" ng-click="selectUserPage(\'/users/groups\')"><i class="pictogram">👥</i>Groups</a></li>\n' + ' <li class="tab" ng-class="currentUsersPage.route
=== \'/users/activities\' ? \'selected\' : \'\'"><a class="btn btn-primary toolbar" ng-click="selectUserPage(\'/users/activities\')"><i class="pictogram"></i>Activities</a></li>\n' + ' <li class="tab" ng-class="currentUsersPage.route === \'/users/feed\' ? \'selected\' : \'\'"><a class="btn btn-primary toolbar" ng-click="selectUserPage(\'/users/feed\')"><i class="pictogram">📄</i>Feed</a></li>\n' + ' <li class="tab" ng-class="currentUsersPage.route === \'/users/graph\' ? \'selected\' : \'\'"><a class="btn btn-primary toolbar" ng-click="selectUserPage(\'/users/graph\')"><i class="pictogram">☁</i>Graph</a></li>\n' + ' <li class="tab" ng-class="currentUsersPage.route === \'/users/roles\' ? \'selected\' : \'\'"><a class="btn btn-primary toolbar" ng-click="selectUserPage(\'/users/roles\')"><i class="pictogram">🌎</i>Roles & Permissions</a></li>\n' + " </ul>\n" + " </div>\n" + ' <span ng-include="currentUsersPage.t
emplate"></span>\n' + " </div>\n" + " </section>\n" + "</div>");
} ]);
++ (function(exports, global) {
++ global["true"] = exports;
++ "use strict";
++ var polyfills = function(window, Object) {
++ window.requestAnimFrame = function() {
++ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) {
++ window.setTimeout(callback, 1e3 / 60);
++ };
++ }();
++ Object.defineProperty(Object.prototype, "clone", {
++ enumerable: false,
++ writable: true,
++ value: function() {
++ var i, newObj = this instanceof Array ? [] : {};
++ for (i in this) {
++ if (i === "clone") {
++ continue;
++ }
++ if (this[i] && typeof this[i] === "object") {
++ newObj[i] = this[i].clone();
++ } else {
++ newObj[i] = this[i];
++ }
++ }
++ return newObj;
++ }
++ });
++ Object.defineProperty(Object.prototype, "stringifyJSON", {
++ enumerable: false,
++ writable: true,
++ value: function() {
++ return JSON.stringify(this, null, " ");
++ }
++ });
++ };
++ polyfills(window, Object);
++ var global = global || this;
++ var AppServices = AppServices || {};
++ global.AppServices = global.AppServices || AppServices;
++ AppServices.Constants = angular.module("appservices.constants", []);
++ AppServices.Services = angular.module("appservices.services", []);
++ AppServices.Controllers = angular.module("appservices.controllers", []);
++ AppServices.Filters = angular.module("appservices.filters", []);
++ AppServices.Directives = angular.module("appservices.directives", []);
++ AppServices.Performance = angular.module("appservices.performance", []);
++ AppServices.MAX = angular.module("appservices.max", []);
++ angular.module("appservices", [ "ngRoute", "ngResource", "ngSanitize", "ui.bootstrap", "angulartics", "angulartics.google.analytics", "appservices.filters", "appservices.services", "appservices.directives", "appservices.constants", "appservices.controllers", "appservices.max", "angular-intro" ]).config([ "$routeProvider", "$locationProvider", "$sceDelegateProvider", "$analyticsProvider", function($routeProvider, $locationProvider, $sceDelegateProvider, $analyticsProvider) {
++ $routeProvider.when("/org-overview", {
++ templateUrl: "org-overview/org-overview.html",
++ controller: "OrgOverviewCtrl"
++ }).when("/login", {
++ templateUrl: "login/login.html",
++ controller: "LoginCtrl"
++ }).when("/login/loading", {
++ templateUrl: "login/loading.html",
++ controller: "LoginCtrl"
++ }).when("/app-overview/summary", {
++ templateUrl: "app-overview/app-overview.html",
++ controller: "AppOverviewCtrl"
++ }).when("/getting-started/setup", {
++ templateUrl: "app-overview/getting-started.html",
++ controller: "GettingStartedCtrl"
++ }).when("/forgot-password", {
++ templateUrl: "login/forgot-password.html",
++ controller: "ForgotPasswordCtrl"
++ }).when("/register", {
++ templateUrl: "login/register.html",
++ controller: "RegisterCtrl"
++ }).when("/users", {
++ templateUrl: "users/users.html",
++ controller: "UsersCtrl"
++ }).when("/users/profile", {
++ templateUrl: "users/users-profile.html",
++ controller: "UsersProfileCtrl"
++ }).when("/users/groups", {
++ templateUrl: "users/users-groups.html",
++ controller: "UsersGroupsCtrl"
++ }).when("/users/activities", {
++ templateUrl: "users/users-activities.html",
++ controller: "UsersActivitiesCtrl"
++ }).when("/users/feed", {
++ templateUrl: "users/users-feed.html",
++ controller: "UsersFeedCtrl"
++ }).when("/users/graph", {
++ templateUrl: "users/users-graph.html",
++ controller: "UsersGraphCtrl"
++ }).when("/users/roles", {
++ templateUrl: "users/users-roles.html",
++ controller: "UsersRolesCtrl"
++ }).when("/groups", {
++ templateUrl: "groups/groups.html",
++ controller: "GroupsCtrl"
++ }).when("/groups/details", {
++ templateUrl: "groups/groups-details.html",
++ controller: "GroupsDetailsCtrl"
++ }).when("/groups/members", {
++ templateUrl: "groups/groups-members.html",
++ controller: "GroupsMembersCtrl"
++ }).when("/groups/activities", {
++ templateUrl: "groups/groups-activities.html",
++ controller: "GroupsActivitiesCtrl"
++ }).when("/groups/roles", {
++ templateUrl: "groups/groups-roles.html",
++ controller: "GroupsRolesCtrl"
++ }).when("/roles", {
++ templateUrl: "roles/roles.html",
++ controller: "RolesCtrl"
++ }).when("/roles/settings", {
++ templateUrl: "roles/roles-settings.html",
++ controller: "RolesSettingsCtrl"
++ }).when("/roles/users", {
++ templateUrl: "roles/roles-users.html",
++ controller: "RolesUsersCtrl"
++ }).when("/roles/groups", {
++ templateUrl: "roles/roles-groups.html",
++ controller: "RolesGroupsCtrl"
++ }).when("/data", {
++ templateUrl: "data/data.html",
++ controller: "DataCtrl"
++ }).when("/data/entity", {
++ templateUrl: "data/entity.html",
++ controller: "EntityCtrl"
++ }).when("/data/shell", {
++ templateUrl: "data/shell.html",
++ controller: "ShellCtrl"
++ }).when("/profile/organizations", {
++ templateUrl: "profile/organizations.html",
++ controller: "OrgCtrl"
++ }).when("/profile/profile", {
++ templateUrl: "profile/profile.html",
++ controller: "ProfileCtrl"
++ }).when("/profile", {
++ templateUrl: "profile/account.html",
++ controller: "AccountCtrl"
++ }).when("/activities", {
++ templateUrl: "activities/activities.html",
++ controller: "ActivitiesCtrl"
++ }).when("/shell", {
++ templateUrl: "shell/shell.html",
++ controller: "ShellCtrl"
++ }).when("/logout", {
++ templateUrl: "login/logout.html",
++ controller: "LogoutCtrl"
++ }).otherwise({
++ redirectTo: "/org-overview"
++ });
++ $locationProvider.html5Mode(false).hashPrefix("!");
++ $sceDelegateProvider.resourceUrlWhitelist([ "self", "http://apigee-internal-prod.jupiter.apigee.net/**", "http://apigee-internal-prod.mars.apigee.net/**", "https://appservices.apigee.com/**", "https://api.usergrid.com/**" ]);
++ $analyticsProvider.virtualPageviews(false);
++ $analyticsProvider.firstPageview(false);
++ } ]);
++ AppServices.Controllers.controller("ActivitiesCtrl", [ "ug", "$scope", "$rootScope", "$location", "$route", function(ug, $scope, $rootScope, $location, $route) {
++ $scope.$on("app-activities-received", function(evt, data) {
++ $scope.activities = data;
++ $scope.$apply();
++ });
++ $scope.$on("app-activities-error", function(evt, data) {
++ $rootScope.$broadcast("alert", "error", "Application failed to retreive activities data.");
++ });
++ ug.getActivities();
++ } ]);
++ "use strict";
++ AppServices.Controllers.controller("AppOverviewCtrl", [ "ug", "charts", "$scope", "$rootScope", "$log", function(ug, charts, $scope, $rootScope, $log) {
++ var createGradient = function(color1, color2) {
++ var perShapeGradient = {
++ x1: 0,
++ y1: 0,
++ x2: 0,
++ y2: 1
++ };
++ return {
++ linearGradient: perShapeGradient,
++ stops: [ [ 0, color1 ], [ 1, color2 ] ]
++ };
++ };
++ $scope.appOverview = {};
++ $scope.collections = [];
++ $scope.graph = "";
++ $scope.$on("top-collections-received", function(event, collections) {
++ var dataDescription = {
++ bar1: {
++ labels: [ "Total" ],
++ dataAttr: [ "title", "count" ],
++ colors: [ createGradient("rgba(36,151,212,0.6)", "rgba(119,198,240,0.6)") ],
++ borderColor: "#1b97d1"
++ }
++ };
++ $scope.collections = collections;
++ var arr = [];
++ for (var i in collections) {
++ if (collections.hasOwnProperty(i)) {
++ arr.push(collections[i]);
++ }
++ }
++ $scope.appOverview = {};
++ if (!$rootScope.chartTemplate) {
++ ug.httpGet(null, "js/charts/highcharts.json").then(function(success) {
++ $rootScope.chartTemplate = success;
++ $scope.appOverview.chart = angular.copy($rootScope.chartTemplate.pareto);
++ $scope.appOverview.chart = charts.convertParetoChart(arr, $scope.appOverview.chart, dataDescription.bar1, "1h", "NOW");
++ $scope.applyScope();
++ }, function(fail) {
++ $log.error("Problem getting chart template", fail);
++ });
++ } else {
++ $scope.appOverview.chart = angular.copy($rootScope.chartTemplate.pareto);
++ $scope.appOverview.chart = charts.convertParetoChart(arr, $scope.appOverview.chart, dataDescription.bar1, "1h", "NOW");
++ $scope.applyScope();
++ }
++ });
++ $scope.$on("app-initialized", function() {
++ ug.getTopCollections();
++ });
++ if ($rootScope.activeUI) {
++ ug.getTopCollections();
++ }
++ } ]);
++ "use strict";
++ AppServices.Controllers.controller("GettingStartedCtrl", [ "ug", "$scope", "$rootScope", "$location", "$timeout", "$anchorScroll", function(ug, $scope, $rootScope, $location, $timeout, $anchorScroll) {
++ $scope.collections = [];
++ $scope.graph = "";
++ $scope.clientID = "";
++ $scope.clientSecret = "";
++ var getKeys = function() {
++ return ug.jsonpRaw("credentials", "", {});
++ };
++ $scope.regenerateCredentialsDialog = function(modalId) {
++ $scope.orgAPICredentials = {
++ client_id: "regenerating...",
++ client_secret: "regenerating..."
++ };
++ ug.regenerateAppCredentials();
++ $scope.hideModal(modalId);
++ };
++ $scope.$on("app-creds-updated", function(event, credentials) {
++ if (credentials) {
++ $scope.clientID = credentials.client_id;
++ $scope.clientSecret = credentials.client_secret;
++ if (!$scope.$$phase) {
++ $scope.$apply();
++ }
++ } else {
++ setTimeout(function() {
++ ug.getAppCredentials();
++ }, 5e3);
++ }
++ });
++ ug.getAppCredentials();
++ $scope.contentTitle;
++ $scope.showSDKDetail = function(name) {
++ var introContainer = document.getElementById("intro-container");
++ if (name === "nocontent") {
++ introContainer.style.height = "0";
++ return true;
++ }
++ introContainer.style.opacity = .1;
++ introContainer.style.height = "0";
++ var timeout = 0;
++ if ($scope.contentTitle) {
++ timeout = 500;
++ }
++ $timeout(function() {
++ introContainer.style.height = "1000px";
++ introContainer.style.opacity = 1;
++ }, timeout);
++ $scope.optionName = name;
++ $scope.contentTitle = name;
++ $scope.sdkLink = "http://apigee.com/docs/content/" + name + "-sdk-redirect";
++ $scope.docsLink = "http://apigee.com/docs/app-services/content/installing-apigee-sdk-" + name;
++ $scope.getIncludeURL = function() {
++ return "app-overview/doc-includes/" + $scope.optionName + ".html";
++ };
++ };
++ $scope.scrollToElement = function(elem) {
++ $location.hash(elem);
++ $anchorScroll();
++ return false;
++ };
++ } ]);
++ "use strict";
++ AppServices.Controllers.controller("ChartCtrl", [ "$scope", "$location", function($scope, $location) {} ]);
++ "use strict";
++ AppServices.Directives.directive("chart", function($rootScope) {
++ return {
++ restrict: "E",
++ scope: {
++ chartdata: "=chartdata"
++ },
++ template: "<div></div>",
++ replace: true,
++ controller: function($scope, $element) {},
++ link: function(scope, element, attrs) {
++ scope.$watch("chartdata", function(chartdata, oldchartdata) {
++ if (chartdata) {
++ var chartsDefaults = {
++ chart: {
++ renderTo: element[0],
++ type: attrs.type || null,
++ height: attrs.height || null,
++ width: attrs.width || null,
++ reflow: true,
++ animation: false,
++ zoomType: "x"
++ }
++ };
++ if (attrs.type === "pie") {
++ chartsDefaults.chart.margin = [ 0, 0, 0, 0 ];
++ chartsDefaults.chart.spacingLeft = 0;
++ chartsDefaults.chart.spacingRight = 0;
++ chartsDefaults.chart.spacingTop = 0;
++ chartsDefaults.chart.spacingBottom = 0;
++ if (attrs.titleimage) {
++ chartdata.title.text = '<img src="' + attrs.titleimage + '">';
++ }
++ if (attrs.titleicon) {
++ chartdata.title.text = '<i class="pictogram ' + attrs.titleiconclass + '">' + attrs.titleicon + "</i>";
++ }
++ if (attrs.titlecolor) {
++ chartdata.title.style.color = attrs.titlecolor;
++ }
++ if (attrs.titleimagetop) {
++ chartdata.title.style.marginTop = attrs.titleimagetop;
++ }
++ if (attrs.titleimageleft) {
++ chartdata.title.style.marginLeft = attrs.titleimageleft;
++ }
++ }
++ if (attrs.type === "line") {
++ chartsDefaults.chart.marginTop = 30;
++ chartsDefaults.chart.spacingTop = 50;
++ }
++ if (attrs.type === "column") {
++ chartsDefaults.chart.marginBottom = 80;
++ }
++ if (attrs.type === "area") {
++ chartsDefaults.chart.spacingLeft = 0;
++ chartsDefaults.chart.spacingRight = 0;
++ chartsDefaults.chart.marginLeft = 0;
++ chartsDefaults.chart.marginRight = 0;
++ }
++ Highcharts.setOptions({
++ global: {
++ useUTC: false
++ },
++ chart: {
++ style: {
++ fontFamily: "marquette-light, Helvetica, Arial, sans-serif"
++ }
++ }
++ });
++ if (attrs.type === "line") {
++ var xAxis1 = chartdata.xAxis[0];
++ if (!xAxis1.labels.formatter) {
++ xAxis1.labels.formatter = new Function(attrs.xaxislabel);
++ }
++ if (!xAxis1.labels.step) {
++ xAxis1.labels.step = attrs.xaxisstep;
++ }
++ }
++ if (chartdata.tooltip) {
++ if (typeof chartdata.tooltip.formatter === "string") {
++ chartdata.tooltip.formatter = new Function(chartdata.tooltip.formatter);
++ }
++ }
++ renderChart(chartsDefaults, chartdata);
++ }
++ }, true);
++ }
++ };
++ });
++ function renderChart(chartsDefaults, chartdata, attrs) {
++ var newSettings = {};
++ $.extend(true, newSettings, chartsDefaults, chartdata);
++ var chart = new Highcharts.Chart(newSettings);
++ }
++ AppServices.Services.factory("charts", function() {
++ var lineChart, areaChart, paretoChart, pieChart, pieCompare, xaxis, seriesIndex;
++ return {
++ convertLineChart: function(chartData, chartTemplate, dataDescription, settings, currentCompare) {
++ lineChart = chartTemplate;
++ if (typeof chartData[0] === "undefined") {
++ chartData[0] = {};
++ chartData[0].datapoints = [];
++ }
++ var dataPoints = chartData[0].datapoints, dPLength = dataPoints.length, label;
++ if (currentCompare === "YESTERDAY") {
++ seriesIndex = dataDescription.dataAttr.length;
++ label = "Yesterday ";
++ } else if (currentCompare === "LAST_WEEK") {
++ seriesIndex = dataDescription.dataAttr.length;
++ label = "Last Week ";
++ } else {
++ lineChart = chartTemplate;
++ seriesIndex = 0;
++ lineChart.series = [];
++ label = "";
++ }
++ xaxis = lineChart.xAxis[0];
++ xaxis.categories = [];
++ if (settings.xaxisformat) {
++ xaxis.labels.formatter = new Function(settings.xaxisformat);
++ }
++ if (settings.step) {
++ xaxis.labels.step = settings.step;
++ }
++ for (var i = 0; i < dPLength; i++) {
++ var dp = dataPoints[i];
++ xaxis.categories.push(dp.timestamp);
++ }
++ if (chartData.length > 1) {
++ for (var l = 0; l < chartData.length; l++) {
++ if (chartData[l].chartGroupName) {
++ dataPoints = chartData[l].datapoints;
++ lineChart.series[l] = {};
++ lineChart.series[l].data = [];
++ lineChart.series[l].name = chartData[l].chartGroupName;
++ lineChart.series[l].yAxis = 0;
++ lineChart.series[l].type = "line";
++ lineChart.series[l].color = dataDescription.colors[i];
++ lineChart.series[l].dashStyle = "solid";
++ lineChart.series[l].yAxis.title.text = dataDescription.yAxisLabels;
++ plotData(l, dPLength, dataPoints, dataDescription.detailDataAttr, true);
++ }
++ }
++ } else {
++ var steadyCounter = 0;
++ for (var i = seriesIndex; i < dataDescription.dataAttr.length + (seriesIndex > 0 ? seriesIndex : 0); i++) {
++ var yAxisIndex = dataDescription.multiAxis ? steadyCounter : 0;
++ lineChart.series[i] = {};
++ lineChart.series[i].data = [];
++ lineChart.series[i].name = label + dataDescription.labels[steadyCounter];
++ lineChart.series[i].yAxis = yAxisIndex;
++ lineChart.series[i].type = "line";
++ lineChart.series[i].color = dataDescription.colors[i];
++ lineChart.series[i].dashStyle = "solid";
++ lineChart.yAxis[yAxisIndex].title.text = dataDescription.yAxisLabels[dataDescription.yAxisLabels > 1 ? steadyCounter : 0];
++ steadyCounter++;
++ }
++ plotData(seriesIndex, dPLength, dataPoints, dataDescription.dataAttr, false);
++ }
++ function plotData(counter, dPLength, dataPoints, dataAttrs, detailedView) {
++ for (var i = 0; i < dPLength; i++) {
++ var dp = dataPoints[i];
++ var localCounter = counter;
++ for (var j = 0; j < dataAttrs.length; j++) {
++ if (typeof dp === "undefined") {
++ lineChart.series[localCounter].data.push([ i, 0 ]);
++ } else {
++ lineChart.series[localCounter].data.push([ i, dp[dataAttrs[j]] ]);
++ }
++ if (!detailedView) {
++ localCounter++;
++ }
++ }
++ }
++ }
++ return lineChart;
++ },
++ convertAreaChart: function(chartData, chartTemplate, dataDescription, settings, currentCompare) {
++ areaChart = angular.copy(areaChart);
++ if (typeof chartData[0] === "undefined") {
++ chartData[0] = {};
++ chartData[0].datapoints = [];
++ }
++ var dataPoints = chartData[0].datapoints, dPLength = dataPoints.length, label;
++ if (currentCompare === "YESTERDAY") {
++ seriesIndex = dataDescription.dataAttr.length;
++ label = "Yesterday ";
++ } else if (currentCompare === "LAST_WEEK") {
++ seriesIndex = dataDescription.dataAttr.length;
++ label = "Last Week ";
++ } else {
++ areaChart = chartTemplate;
++ seriesIndex = 0;
++ areaChart.series = [];
++ label = "";
++ }
++ xaxis = areaChart.xAxis[0];
++ xaxis.categories = [];
++ if (settings.xaxisformat) {
++ xaxis.labels.formatter = new Function(settings.xaxisformat);
++ }
++ if (settings.step) {
++ xaxis.labels.step = settings.step;
++ }
++ for (var i = 0; i < dPLength; i++) {
++ var dp = dataPoints[i];
++ xaxis.categories.push(dp.timestamp);
++ }
++ if (chartData.length > 1) {
++ for (var l = 0; l < chartData.length; l++) {
++ if (chartData[l].chartGroupName) {
++ dataPoints = chartData[l].datapoints;
++ areaChart.series[l] = {};
++ areaChart.series[l].data = [];
++ areaChart.series[l].fillColor = dataDescription.areaColors[l];
++ areaChart.series[l].name = chartData[l].chartGroupName;
++ areaChart.series[l].yAxis = 0;
++ areaChart.series[l].type = "area";
++ areaChart.series[l].pointInterval = 1;
++ areaChart.series[l].color = dataDescription.colors[l];
++ areaChart.series[l].dashStyle = "solid";
++ areaChart.series[l].yAxis.title.text = dataDescription.yAxisLabels;
++ plotData(l, dPLength, dataPoints, dataDescription.detailDataAttr, true);
++ }
++ }
++ } else {
++ var steadyCounter = 0;
++ for (var i = seriesIndex; i < dataDescription.dataAttr.length + (seriesIndex > 0 ? seriesIndex : 0); i++) {
++ var yAxisIndex = dataDescription.multiAxis ? steadyCounter : 0;
++ areaChart.series[i] = {};
++ areaChart.series[i].data = [];
++ areaChart.series[i].fillColor = dataDescription.areaColors[i];
++ areaChart.series[i].name = label + dataDescription.labels[steadyCounter];
++ areaChart.series[i].yAxis = yAxisIndex;
++ areaChart.series[i].type = "area";
++ areaChart.series[i].pointInterval = 1;
++ areaChart.series[i].color = dataDescription.colors[i];
++ areaChart.series[i].dashStyle = "solid";
++ areaChart.yAxis[yAxisIndex].title.text = dataDescription.yAxisLabels[dataDescription.yAxisLabels > 1 ? steadyCounter : 0];
++ steadyCounter++;
++ }
++ plotData(seriesIndex, dPLength, dataPoints, dataDescription.dataAttr, false);
++ }
++ function plotData(counter, dPLength, dataPoints, dataAttrs, detailedView) {
++ for (var i = 0; i < dPLength; i++) {
++ var dp = dataPoints[i];
++ var localCounter = counter;
++ for (var j = 0; j < dataAttrs.length; j++) {
++ if (typeof dp === "undefined") {
++ areaChart.series[localCounter].data.push(0);
++ } else {
++ areaChart.series[localCounter].data.push(dp[dataAttrs[j]]);
++ }
++ if (!detailedView) {
++ localCounter++;
++ }
++ }
++ }
++ }
++ return areaChart;
++ },
++ convertParetoChart: function(chartData, chartTemplate, dataDescription, settings, currentCompare) {
++ paretoChart = chartTemplate;
++ if (typeof chartData === "undefined") {
++ chartData = [];
++ }
++ var label, cdLength = chartData.length, compare = false, allParetoOptions = [], stackedBar = false;
++ seriesIndex = 0;
++ function getPreviousData() {
++ for (var i = 0; i < chartTemplate.series[0].data.length; i++) {
++ allParetoOptions.push(chartTemplate.xAxis.categories[i]);
++ }
++ }
++ if (typeof dataDescription.dataAttr[1] === "object") {
++ stackedBar = true;
++ }
++ if (currentCompare === "YESTERDAY") {
++ label = "Yesterday ";
++ compare = true;
++ if (stackedBar) {
++ seriesIndex = dataDescription.dataAttr[1].length;
++ }
++ getPreviousData();
++ } else if (currentCompare === "LAST_WEEK") {
++ label = "Last Week ";
++ compare = true;
++ if (stackedBar) {
++ seriesIndex = dataDescription.dataAttr[1].length;
++ }
++ seriesIndex = getPreviousData();
++ } else {
++ compare = false;
++ label = "";
++ paretoChart.xAxis.categories = [];
++ paretoChart.series = [];
++ paretoChart.series[0] = {};
++ paretoChart.series[0].data = [];
++ paretoChart.legend.enabled = false;
++ }
++ paretoChart.plotOptions.series.borderColor = dataDescription.borderColor;
++ if (compare && !stackedBar) {
++ paretoChart.series[1] = {};
++ paretoChart.series[1].data = [];
++ for (var i = 0; i < allParetoOptions.length; i++) {
++ paretoChart.series[1].data.push(0);
++ }
++ paretoChart.legend.enabled = true;
++ }
++ for (var i = 0; i < cdLength; i++) {
++ var bar = chartData[i];
++ if (!compare) {
++ paretoChart.xAxis.categories.push(bar[dataDescription.dataAttr[0]]);
++ if (typeof dataDescription.dataAttr[1] === "object") {
++ createStackedBar(dataDescription, paretoChart, paretoChart.series.length);
++ } else {
++ paretoChart.series[0].data.push(bar[dataDescription.dataAttr[1]]);
++ paretoChart.series[0].name = dataDescription.labels[0];
++ paretoChart.series[0].color = dataDescription.colors[0];
++ }
++ } else {
++ var newLabel = bar[dataDescription.dataAttr[0]], newValue = bar[dataDescription.dataAttr[1]], previousIndex = allParetoOptions.indexOf(newLabel);
++ if (previousIndex > -1) {
++ if (typeof dataDescription.dataAttr[1] === "object") {
++ createStackedBar(dataDescription, paretoChart, paretoChart.series.length);
++ } else {
++ paretoChart.series[1].data[previousIndex] = newValue;
++ paretoChart.series[1].name = label !== "" ? label + " " + dataDescription.labels[0] : dataDescription.labels[0];
++ paretoChart.series[1].color = dataDescription.colors[1];
++ }
++ } else {}
++ }
++ }
++ function createStackedBar(dataDescription, paretoChart, startingPoint) {
++ paretoChart.plotOptions = {
++ series: {
++ shadow: false,
++ borderColor: dataDescription.borderColor,
++ borderWidth: 1
++ },
++ column: {
++ stacking: "normal",
++ dataLabels: {
++ enabled: true,
++ color: Highcharts.theme && Highcharts.theme.dataLabelsColor || "white"
++ }
++ }
++ };
++ var start = dataDescription.dataAttr[1].length, steadyCounter = 0, stackName = label;
++ if (compare) {
++ paretoChart.legend.enabled = true;
++ }
++ for (var f = seriesIndex; f < start + seriesIndex; f++) {
++ if (!paretoChart.series[f]) {
++ paretoChart.series[f] = {
++ data: []
++ };
++ }
++ paretoChart.series[f].data.push(bar[dataDescription.dataAttr[1][steadyCounter]]);
++ paretoChart.series[f].name = label !== "" ? label + " " + dataDescription.labels[steadyCounter] : dataDescription.labels[steadyCounter];
++ paretoChart.series[f].color = dataDescription.colors[f];
++ paretoChart.series[f].stack = label;
++ steadyCounter++;
++ }
++ }
++ return paretoChart;
++ },
++ convertPieChart: function(chartData, chartTemplate, dataDescription, settings, currentCompare) {
++ var label, cdLength = chartData.length, compare = false;
++ pieChart = chartTemplate;
++ if (currentCompare === "YESTERDAY") {
++ label = "Yesterday ";
++ compare = false;
++ } else if (currentCompare === "LAST_WEEK") {
++ label = "Last Week ";
++ compare = false;
++ } else {
++ compare = false;
++ pieChart.series[0].data = [];
++ if (pieChart.series[0].dataLabels) {
++ if (typeof pieChart.series[0].dataLabels.formatter === "string") {
++ pieChart.series[0].dataLabels.formatter = new Function(pieChart.series[0].dataLabels.formatter);
++ }
++ }
++ }
++ pieChart.plotOptions.pie.borderColor = dataDescription.borderColor;
++ if (compare) {
++ pieChart.series[1].data = [];
++ if (pieChart.series[1].dataLabels) {
++ if (typeof pieChart.series[1].dataLabels.formatter === "string") {
++ pieChart.series[1].dataLabels.formatter = new Function(pieChart.series[1].dataLabels.formatter);
++ }
++ }
++ }
++ var tempArray = [];
++ for (var i = 0; i < cdLength; i++) {
++ var pie = chartData[i];
++ tempArray.push({
++ name: pie[dataDescription.dataAttr[0]],
++ y: pie[dataDescription.dataAttr[1]],
++ color: ""
++ });
++ }
++ sortJsonArrayByProperty(tempArray, "name");
++ for (var i = 0; i < tempArray.length; i++) {
++ tempArray[i].color = dataDescription.colors[i];
++ }
++ if (!compare) {
++ pieChart.series[0].data = tempArray;
++ } else {
++ pieChart.series[1].data = tempArray;
++ }
++ return pieChart;
++ }
++ };
++ function sortJsonArrayByProperty(objArray, prop, direction) {
++ if (arguments.length < 2) throw new Error("sortJsonArrayByProp requires 2 arguments");
++ var direct = arguments.length > 2 ? arguments[2] : 1;
++ if (objArray && objArray.constructor === Array) {
++ var propPath = prop.constructor === Array ? prop : prop.split(".");
++ objArray.sort(function(a, b) {
++ for (var p in propPath) {
++ if (a[propPath[p]] && b[propPath[p]]) {
++ a = a[propPath[p]];
++ b = b[propPath[p]];
++ }
++ }
++ a = a.match(/^\d+$/) ? +a : a;
++ b = b.match(/^\d+$/) ? +b : b;
++ return a < b ? -1 * direct : a > b ? 1 * direct : 0;
++ });
++ }
++ }
++ });
++ $(".sessions-bar").sparkline([ 3, 5, 6, 3, 4, 5, 6, 7, 8, 4, 3, 5, 6, 3, 4, 5, 6, 7, 8, 4, 3, 5, 6, 3, 4, 5, 6, 7, 8, 4, 3, 5, 6, 3, 4, 5, 6, 7, 8, 4, 3, 5, 6, 3, 4, 5, 6, 7, 8, 4, 3, 5, 6, 3, 4, 5, 6, 7, 8, 1 ], {
++ type: "bar",
++ barColor: "#c5c5c5",
++ width: "800px",
++ height: 100,
++ barWidth: 12,
++ barSpacing: "1px"
++ });
++ "use strict";
++ AppServices.Controllers.controller("DataCtrl", [ "ug", "$scope", "$rootScope", "$location", function(ug, $scope, $rootScope, $location) {
++ var init = function() {
++ $scope.verb = "GET";
++ $scope.display = "";
++ $scope.queryBodyDetail = {};
++ $scope.queryBodyDisplay = "none";
++ $scope.queryLimitDisplay = "block";
++ $scope.queryStringDisplay = "block";
++ $scope.entitySelected = {};
++ $scope.newCollection = {};
++ $rootScope.queryCollection = {};
++ $scope.data = {};
++ $scope.data.queryPath = "";
++ $scope.data.queryBody = '{ "name":"value" }';
++ $scope.data.searchString = "";
++ $scope.data.queryLimit = "";
++ };
++ var runQuery = function(verb) {
++ $scope.loading = true;
++ var queryPath = $scope.removeFirstSlash($scope.data.queryPath || "");
++ var searchString = $scope.data.searchString || "";
++ var queryLimit = $scope.data.queryLimit || "";
++ var body = JSON.parse($scope.data.queryBody || "{}");
++ if (verb == "POST" && $scope.validateJson(true)) {
++ ug.runDataPOSTQuery(queryPath, body);
++ } else if (verb == "PUT" && $scope.validateJson(true)) {
++ ug.runDataPutQuery(queryPath, searchString, queryLimit, body);
++ } else if (verb == "DELETE") {
++ ug.runDataDeleteQuery(queryPath, searchString, queryLimit);
++ } else {
++ ug.runDataQuery(queryPath, searchString, queryLimit);
++ }
++ };
++ $scope.$on("top-collections-received", function(event, collectionList) {
++ $scope.loading = false;
++ var ignoredCollections = [ "events" ];
++ ignoredCollections.forEach(function(ignoredCollection) {
++ collectionList.hasOwnProperty(ignoredCollection) && delete collectionList[ignoredCollection];
++ });
++ $scope.collectionList = collectionList;
++ $scope.queryBoxesSelected = false;
++ if (!$scope.queryPath) {
++ $scope.loadCollection("/" + collectionList[Object.keys(collectionList).sort()[0]].name);
++ }
++ $scope.applyScope();
++ });
++ $scope.$on("error-running-query", function(event) {
++ $scope.loading = false;
++ runQuery("GET");
++ $scope.applyScope();
++ });
++ $scope.$on("entity-deleted", function(event) {
++ $scope.deleteLoading = false;
++ $rootScope.$broadcast("alert", "success", "Entities deleted sucessfully");
++ $scope.queryBoxesSelected = false;
++ $scope.checkNextPrev();
++ $scope.applyScope();
++ });
++ $scope.$on("entity-deleted-error", function(event) {
++ $scope.deleteLoading = false;
++ runQuery("GET");
++ $scope.applyScope();
++ });
++ $scope.$on("collection-created", function() {
++ $scope.newCollection.name = "";
++ });
++ $scope.$on("query-received", function(event, collection) {
++ $scope.loading = false;
++ $rootScope.queryCollection = collection;
++ ug.getIndexes($scope.data.queryPath);
++ $scope.setDisplayType();
++ $scope.checkNextPrev();
++ $scope.applyScope();
++ $scope.queryBoxesSelected = false;
++ });
++ $scope.$on("indexes-received", function(event, indexes) {
++ var fred = indexes;
++ });
++ $scope.$on("app-changed", function() {
++ init();
++ });
++ $scope.setDisplayType = function() {
++ $scope.display = "generic";
++ };
++ $scope.deleteEntitiesDialog = function(modalId) {
++ $scope.deleteLoading = false;
++ $scope.deleteEntities($rootScope.queryCollection, "entity-deleted", "error deleting entity");
++ $scope.hideModal(modalId);
++ };
++ $scope.newCollectionDialog = function(modalId) {
++ if ($scope.newCollection.name) {
++ ug.createCollection($scope.newCollection.name);
++ ug.getTopCollections();
++ $rootScope.$broadcast("alert", "success", "Collection created successfully.");
++ $scope.hideModal(modalId);
++ } else {
++ $rootScope.$broadcast("alert", "error", "You must specify a collection name.");
++ }
++ };
++ $scope.addToPath = function(uuid) {
++ $scope.data.queryPath = "/" + $rootScope.queryCollection._type + "/" + uuid;
++ };
++ $scope.isDeep = function(item) {
++ return Object.prototype.toString.call(item) === "[object Object]";
++ };
++ $scope.loadCollection = function(type) {
++ $scope.data.queryPath = "/" + type.substring(1, type.length);
++ $scope.data.searchString = "";
++ $scope.data.queryLimit = "";
++ $scope.data.body = '{ "name":"value" }';
++ $scope.selectGET();
++ $scope.applyScope();
++ $scope.run();
++ };
++ $scope.selectGET = function() {
++ $scope.queryBodyDisplay = "none";
++ $scope.queryLimitDisplay = "block";
++ $scope.queryStringDisplay = "block";
++ $scope.verb = "GET";
++ };
++ $scope.selectPOST = function() {
++ $scope.queryBodyDisplay = "block";
++ $scope.queryLimitDisplay = "none";
++ $scope.queryStringDisplay = "none";
++ $scope.verb = "POST";
++ };
++ $scope.selectPUT = function() {
++ $scope.queryBodyDisplay = "block";
++ $scope.queryLimitDisplay = "block";
++ $scope.queryStringDisplay = "block";
++ $scope.verb = "PUT";
++ };
++ $scope.selectDELETE = function() {
++ $scope.queryBodyDisplay = "none";
++ $scope.queryLimitDisplay = "block";
++ $scope.queryStringDisplay = "block";
++ $scope.verb = "DELETE";
++ };
++ $scope.validateJson = function(skipMessage) {
++ var queryBody = $scope.data.queryBody;
++ try {
++ queryBody = JSON.parse(queryBody);
++ } catch (e) {
++ $rootScope.$broadcast("alert", "error", "JSON is not valid");
++ return false;
++ }
++ queryBody = JSON.stringify(queryBody, null, 2);
++ !skipMessage && $rootScope.$broadcast("alert", "success", "JSON is valid");
++ $scope.data.queryBody = queryBody;
++ return true;
++ };
++ $scope.saveEntity = function(entity) {
++ if (!$scope.validateJson()) {
++ return false;
++ }
++ var queryBody = entity._json;
++ queryBody = JSON.parse(queryBody);
++ $rootScope.selectedEntity.set();
++ $rootScope.selectedEntity.set(queryBody);
++ $rootScope.selectedEntity.set("type", entity._data.type);
++ $rootScope.selectedEntity.set("uuid", entity._data.uuid);
++ $rootScope.selectedEntity.save(function(err, data) {
++ if (err) {
++ $rootScope.$broadcast("alert", "error", "error: " + data.error_description);
++ } else {
++ $rootScope.$broadcast("alert", "success", "entity saved");
++ }
++ });
++ };
++ $scope.run = function() {
++ $rootScope.queryCollection = "";
++ var verb = $scope.verb;
++ runQuery(verb);
++ };
++ $scope.hasProperty = function(prop) {
++ var retval = false;
++ if (typeof $rootScope.queryCollection._list !== "undefined") {
++ angular.forEach($rootScope.queryCollection._list, function(value, key) {
++ if (!retval) {
++ if (value._data[prop]) {
++ retval = true;
++ }
++ }
++ });
++ }
++ return retval;
++ };
++ $scope.resetNextPrev = function() {
++ $scope.previous_display = "none";
++ $scope.next_display = "none";
++ };
++ $scope.checkNextPrev = function() {
++ $scope.resetNextPrev();
++ if ($rootScope.queryCollection.hasPreviousPage()) {
++ $scope.previous_display = "default";
++ }
++ if ($rootScope.queryCollection.hasNextPage()) {
++ $scope.next_display = "default";
++ }
++ };
++ $scope.selectEntity = function(uuid) {
++ $rootScope.selectedEntity = $rootScope.queryCollection.getEntityByUUID(uuid);
++ $scope.addToPath(uuid);
++ };
++ $scope.getJSONView = function(entity) {
++ var tempjson = entity.get();
++ var queryBody = JSON.stringify(tempjson, null, 2);
++ queryBody = JSON.parse(queryBody);
++ delete queryBody.metadata;
++ delete queryBody.uuid;
++ delete queryBody.created;
++ delete queryBody.modified;
++ delete queryBody.type;
++ $scope.queryBody = JSON.stringify(queryBody, null, 2);
++ };
++ $scope.getPrevious = function() {
++ $rootScope.queryCollection.getPreviousPage(function(err) {
++ if (err) {
++ $rootScope.$broadcast("alert", "error", "error getting previous page of data");
++ }
++ $scope.checkNextPrev();
++ $scope.applyScope();
++ });
++ };
++ $scope.getNext = function() {
++ $rootScope.queryCollection.getNextPage(function(err) {
++ if (err) {
++ $rootScope.$broadcast("alert", "error", "error getting next page of data");
++ }
++ $scope.checkNextPrev();
++ $scope.applyScope();
++ });
++ };
++ init();
++ $rootScope.queryCollection = $rootScope.queryCollection || {};
++ $rootScope.selectedEntity = {};
++ if ($rootScope.queryCollection && $rootScope.queryCollection._type) {
++ $scope.loadCollection($rootScope.queryCollection._type);
++ $scope.setDisplayType();
++ }
++ ug.getTopCollections();
++ $scope.resetNextPrev();
++ } ]);
++ "use strict";
++ AppServices.Controllers.controller("EntityCtrl", [ "ug", "$scope", "$rootScope", "$location", function(ug, $scope, $rootScope, $location) {
++ if (!$rootScope.selectedEntity) {
++ $location.path("/data");
++ return;
++ }
++ $scope.entityUUID = $rootScope.selectedEntity.get("uuid");
++ $scope.entityType = $rootScope.selectedEntity.get("type");
++ var tempjson = $rootScope.selectedEntity.get();
++ var queryBody = JSON.stringify(tempjson, null, 2);
++ queryBody = JSON.parse(queryBody);
++ delete queryBody.metadata;
++ delete queryBody.uuid;
++ delete queryBody.created;
++ delete queryBody.modified;
++ delete queryBody.type;
++ $scope.queryBody = JSON.stringify(queryBody, null, 2);
++ $scope.validateJson = function() {
++ var queryBody = $scope.queryBody;
++ try {
++ queryBody = JSON.parse(queryBody);
++ } catch (e) {
++ $rootScope.$broadcast("alert", "error", "JSON is not valid");
++ return false;
++ }
++ queryBody = JSON.stringify(queryBody, null, 2);
++ $rootScope.$broadcast("alert", "success", "JSON is valid");
++ $scope.queryBody = queryBody;
++ return true;
++ };
++ $scope.saveEntity = function() {
++ if (!$scope.validateJson()) {
++ return false;
++ }
++ var queryBody = $scope.queryBody;
++ queryBody = JSON.parse(queryBody);
++ $rootScope.selectedEntity.set();
++ $rootScope.selectedEntity.set(queryBody);
++ $rootScope.selectedEntity.set("type", $scope.entityType);
++ $rootScope.selectedEntity.set("uuid", $scope.entityUUID);
++ $rootScope.selectedEntity.save(function(err, data) {
++ if (err) {
++ $rootScope.$broadcast("alert", "error", "error: " + data.error_description);
++ } else {
++ $rootScope.$broadcast("alert", "success", "entity saved");
++ }
++ });
++ };
++ } ]);
++ "use strict";
++ AppServices.Directives.directive("balloon", [ "$window", "$timeout", function($window, $timeout) {
++ return {
++ restrict: "ECA",
++ scope: "=",
++ template: "" + '<div class="baloon {{direction}}" ng-transclude>' + "</div>",
++ replace: true,
++ transclude: true,
++ link: function linkFn(scope, lElement, attrs) {
++ scope.direction = attrs.direction;
++ var runScroll = true;
++ var windowEl = angular.element($window);
++ windowEl.on("scroll", function() {
++ if (runScroll) {
++ lElement.addClass("fade-out");
++ $timeout(function() {
++ lElement.addClass("hide");
++ }, 1e3);
++ runScroll = false;
++ }
++ });
++ }
++ };
++ } ]);
++ "use strict";
++ AppServices.Directives.directive("bsmodal", [ "$rootScope", function($rootScope) {
++ return {
++ restrict: "ECA",
++ scope: {
++ title: "@title",
++ buttonid: "=buttonid",
++ footertext: "=footertext",
++ closelabel: "=closelabel"
++ },
++ transclude: true,
++ templateUrl: "dialogs/modal.html",
++ replace: true,
++ link: function linkFn(scope, lElement, attrs, parentCtrl) {
++ scope.title = attrs.title;
++ scope.footertext = attrs.footertext;
++ scope.closelabel = attrs.closelabel;
++ scope.close = attrs.close;
++ scope.extrabutton = attrs.extrabutton;
++ scope.extrabuttonlabel = attrs.extrabuttonlabel;
++ scope.buttonId = attrs.buttonid;
++ scope.closeDelegate = function(attr) {
++ scope.$parent[attr](attrs.id, scope);
++ };
++ scope.extraDelegate = function(attr) {
++ if (scope.dialogForm.$valid) {
++ console.log(parentCtrl);
++ scope.$parent[attr](attrs.id);
++ } else {
++ $rootScope.$broadcast("alert", "error", "Please check your form input and resubmit.");
++ }
++ };
++ }
++ };
++ } ]);
++ "use strict";
++ AppServices.Controllers.controller("AlertCtrl", [ "$scope", "$rootScope", "$timeout", function($scope, $rootScope, $timeout) {
++ $scope.alertDisplay = "none";
++ $scope.alerts = [];
++ $scope.$on("alert", function(event, type, message, permanent) {
++ $scope.addAlert(type, message, permanent);
++ });
++ $scope.$on("clear-alerts", function(event, message) {
++ $scope.alerts = [];
++ });
++ $scope.addAlert = function(type, message, permanent) {
++ $scope.alertDisplay = "block";
++ $scope.alerts.push({
++ type: type,
++ msg: message
++ });
++ $scope.applyScope();
++ if (!permanent) {
++ $timeout(function() {
++ $scope.alerts.shift();
++ }, 5e3);
++ }
++ };
++ $scope.closeAlert = function(index) {
++ $scope.alerts.splice(index, 1);
++ };
++ } ]);
++ "use strict";
++ AppServices.Directives.directive("alerti", [ "$rootScope", "$timeout", function($rootScope, $timeout) {
++ return {
++ restrict: "ECA",
++ scope: {
++ type: "=type",
++ closeable: "@closeable",
++ index: "&index"
++ },
++ template: '<div class="alert" ng-class="type && \'alert-\' + type">' + ' <button ng-show="closeable" type="button" class="close" ng-click="closeAlert(index)">×</button>' + ' <i ng-if="type === \'warning\'" class="pictogram pull-left" style="font-size:3em;line-height:0.4">💥</i>' + ' <i ng-if="type === \'info\'" class="pictogram pull-left">ℹ</i>' + ' <i ng-if="type === \'error\'" class="pictogram pull-left">⚡</i>' + ' <i ng-if="type === \'success\'" class="pictogram pull-left">👍</i>' + "<div ng-transclude></div>" + "</div>",
++ replace: true,
++ transclude: true,
++ link: function linkFn(scope, lElement, attrs) {
++ $timeout(function() {
++ lElement.addClass("fade-out");
++ }, 4e3);
++ lElement.click(function() {
++ if (attrs.index) {
++ scope.$parent.closeAlert(attrs.index);
++ }
++ });
++ setTimeout(function() {
++ lElement.addClass("alert-animate");
++ }, 10);
++ }
++ };
++ } ]);
++ "use strict";
++ AppServices.Directives.directive("appswitcher", [ "$rootScope", function($rootScope) {
++ return {
++ restrict: "ECA",
++ scope: "=",
++ templateUrl: "global/appswitcher-template.html",
++ replace: true,
++ transclude: true,
++ link: function linkFn(scope, lElement, attrs) {
++ var classNameOpen = "open";
++ $("ul.nav li.dropdownContainingSubmenu").hover(function() {
++ $(this).addClass(classNameOpen);
++ }, function() {
++ $(this).removeClass(classNameOpen);
++ });
++ $("#globalNav > a").mouseover(globalNavDetail);
++ $("#globalNavDetail").mouseover(globalNavDetail);
++ $("#globalNavSubmenuContainer ul li").mouseover(function() {
++ $("#globalNavDetail > div").removeClass(classNameOpen);
++ $("#" + this.getAttribute("data-globalNavDetail")).addClass(classNameOpen);
++ });
++ function globalNavDetail() {
++ $("#globalNavDetail > div").removeClass(classNameOpen);
++ $("#globalNavDetailApiPlatform").addClass(classNameOpen);
++ }
++ }
++ };
++ } ]);
++ "use strict";
++ AppServices.Services.factory("help", function($rootScope, $http, $analytics) {
++ $rootScope.help = {};
++ $rootScope.help.helpButtonStatus = "Enable Help";
++ $rootScope.help.helpTooltipsEnabled = false;
++ $rootScope.help.clicked = false;
++ $rootScope.help.showHelpButtons = false;
++ var tooltipStartTime;
++ var helpStartTime;
++ var introjs_step;
++ $rootScope.help.sendTooltipGA = function(tooltipName) {
++ $analytics.eventTrack("tooltip - " + $rootScope.currentPath, {
++ category: "App Services",
++ label: tooltipName
++ });
++ };
++ $rootScope.help.toggleTooltips = function() {
++ if ($rootScope.help.helpTooltipsEnabled == false) {
++ $rootScope.help.helpButtonStatus = "Disable Help";
++ $rootScope.help.helpTooltipsEnabled = true;
++ showHelpModal("tooltips");
++ } else {
++ $rootScope.help.helpButtonStatus = "Enable Help";
++ $rootScope.help.helpTooltipsEnabled = false;
++ }
++ };
++ $rootScope.help.IntroOptions = {
++ steps: [],
++ showStepNumbers: false,
++ exitOnOverlayClick: true,
++ exitOnEsc: true,
++ nextLabel: "Next",
++ prevLabel: "Back",
++ skipLabel: "Exit",
++ doneLabel: "Done"
++ };
++ $rootScope.$on("$routeChangeSuccess", function(event, current) {
++ var path = current.$$route ? current.$$route.originalPath : null;
++ if (path == "/org-overview") {
++ $rootScope.help.showHelpButtons = true;
++ getHelpJson(path).success(function(json) {
++ var helpJson = json;
++ setHelpStrings(helpJson);
++ showHelpModal("tour");
++ });
++ } else {
++ $rootScope.help.showHelpButtons = false;
++ }
++ });
++ var showHelpModal = function(helpType) {
++ var shouldHelp = location.search.indexOf("noHelp") <= 0;
++ if (helpType == "tour" && !getHelpStatus(helpType)) {
++ shouldHelp && $rootScope.showModal("introjs");
++ } else if (helpType == "tooltips" && !getHelpStatus(helpType)) {
++ shouldHelp && $rootScope.showModal("tooltips");
++ }
++ };
++ var setHelpStrings = function(helpJson) {
++ $rootScope.help.IntroOptions.steps = helpJson.introjs;
++ angular.forEach(helpJson.tooltip, function(value, binding) {
++ $rootScope[binding] = value;
++ });
++ };
++ $rootScope.help.introjs_StartEvent = function() {
++ helpStartTime = Date.now();
++ introjs_step = 1;
++ };
++ $rootScope.help.introjs_ExitEvent = function() {
++ var introjs_time = Math.round((Date.now() - helpStartTime) / 1e3);
++ $analytics.eventTrack("introjs timing - " + $rootScope.currentPath, {
++ category: "App Services",
++ label: introjs_time + "s"
++ });
++ $analytics.eventTrack("introjs exit - " + $rootScope.currentPath, {
++ category: "App Services",
++ label: "step" + introjs_step
++ });
++ };
++ $rootScope.help.introjs_ChangeEvent = function() {
++ introjs_step++;
++ };
++ var getHelpJson = function(path) {
++ return $http.jsonp("http://sdk.apigee.com.s3.amazonaws.com/portal_help" + path + "/helpJson.json?callback=JSON_CALLBACK");
++ };
++ var getHelpStatus = function(helpType) {
++ var status;
++ if (helpType == "tour") {
++ status = localStorage.getItem("ftu_tour");
++ localStorage.setItem("ftu_tour", "false");
++ } else if (helpType == "tooltips") {
++ status = localStorage.getItem("ftu_tooltips");
++ localStorage.setItem("ftu_tooltips", "false");
++ }
++ return status;
++ };
++ });
++ AppServices.Directives.directive("insecureBanner", [ "$rootScope", "ug", function($rootScope, ug) {
++ return {
++ restrict: "E",
++ transclude: true,
++ templateUrl: "global/insecure-banner.html",
++ link: function linkFn(scope, lElement, attrs) {
++ scope.securityWarning = false;
++ scope.$on("roles-received", function(evt, roles) {
++ scope.securityWarning = false;
++ if (!roles || !roles._list) return;
++ roles._list.forEach(function(roleHolder) {
++ var role = roleHolder._data;
++ if (role.name.toUpperCase() === "GUEST") {
++ roleHolder.getPermissions(function(err, data) {
++ if (!err) {
++ if (roleHolder.permissions) {
++ roleHolder.permissions.forEach(function(permission) {
++ if (permission.path.indexOf("/**") >= 0) {
++ scope.securityWarning = true;
++ scope.applyScope();
++ }
++ });
++ }
++ }
++ });
++ }
++ });
++ });
++ var initialized = false;
++ scope.$on("app-initialized", function() {
++ !initialized && ug.getRoles();
++ initialized = true;
++ });
++ scope.$on("app-changed", function() {
++ scope.securityWarning = false;
++ ug.getRoles();
++ });
++ }
++ };
++ } ]);
++ "use strict";
++ AppServices.Constants.constant("configuration", {
++ ITEMS_URL: "global/temp.json"
++ });
++ "use strict";
++ AppServices.Controllers.controller("PageCtrl", [ "ug", "help", "utility", "$scope", "$rootScope", "$location", "$routeParams", "$q", "$route", "$log", "$analytics", function(ug, help, utility, $scope, $rootScope, $location, $routeParams, $q, $route, $log, $analytics) {
++ var initScopeVariables = function() {
++ $scope.loadingText = "Loading...";
++ $scope.use_sso = false;
++ $scope.newApp = {
++ name: ""
++ };
++ $scope.getPerm = "";
++ $scope.postPerm = "";
++ $scope.putPerm = "";
++ $scope.deletePerm = "";
++ $scope.usersTypeaheadValues = [];
++ $scope.groupsTypeaheadValues = [];
++ $scope.rolesTypeaheadValues = [];
++ $rootScope.sdkActive = false;
++ $rootScope.demoData = false;
++ $scope.queryStringApplied = false;
++ $rootScope.autoUpdateTimer = Usergrid.config ? Usergrid.config.autoUpdateTimer : 61;
++ $rootScope.requiresDeveloperKey = Usergrid.config ? Usergrid.config.client.requiresDeveloperKey : false;
++ $rootScope.loaded = $rootScope.activeUI = false;
++ for (var key in Usergrid.regex) {
++ $scope[key] = Usergrid.regex[key];
++ }
++ $scope.options = Usergrid.options;
++ var getQuery = function() {
++ var result = {}, queryString = location.search.slice(1), re = /([^&=]+)=([^&]*)/g, m;
++ while (m = re.exec(queryString)) {
++ result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
++ }
++ return result;
++ };
++ $scope.queryString = getQuery();
++ };
++ initScopeVariables();
++ $rootScope.urls = function() {
++ var urls = ug.getUrls($scope.queryString);
++ $scope.apiUrl = urls.apiUrl;
++ $scope.use_sso = urls.use_sso;
++ return urls;
++ };
++ $rootScope.gotoPage = function(path) {
++ $location.path(path);
++ };
++ var notRegistration = function() {
++ return "/forgot-password" !== $location.path() && "/register" !== $location.path();
++ };
++ var verifyUser = function() {
++ if ($location.path().slice(0, "/login".length) !== "/login") {
++ $rootScope.currentPath = $location.path();
++ }
++ if ($routeParams.access_token && $routeParams.admin_email && $routeParams.uuid) {
++ ug.set("token", $routeParams.access_token);
++ ug.set("email", $routeParams.admin_email);
++ ug.set("uuid", $routeParams.uuid);
++ $location.search("access_token", null);
++ $location.search("admin_email", null);
++ $location.search("uuid", null);
++ }
++ ug.checkAuthentication(true);
++ };
++ $scope.profile = function() {
++ if ($scope.use_sso) {
++ window.location = $rootScope.urls().PROFILE_URL + "?callback=" + encodeURIComponent($location.absUrl());
++ } else {
++ $location.path("/profile");
++ }
++ };
++ $rootScope.showModal = function(id) {
++ $("#" + id).modal("show");
++ };
++ $rootScope.hideModal = function(id) {
++ $("#" + id).modal("hide");
++ };
++ $scope.deleteEntities = function(collection, successBroadcast, errorMessage) {
++ collection.resetEntityPointer();
++ var entitiesToDelete = [];
++ while (collection.hasNextEntity()) {
++ var entity = collection.getNextEntity();
++ var checked = entity.checked;
++ if (checked) {
++ entitiesToDelete.push(entity);
++ }
++ }
++ var count = 0, success = false;
++ for (var i = 0; i < entitiesToDelete.length; i++) {
++ var entity = entitiesToDelete[i];
++ collection.destroyEntity(entity, function(err) {
++ count++;
++ if (err) {
++ $rootScope.$broadcast("alert", "error", errorMessage);
++ $rootScope.$broadcast(successBroadcast + "-error", err);
++ } else {
++ success = true;
++ }
++ if (count === entitiesToDelete.length) {
++ success && $rootScope.$broadcast(successBroadcast);
++ $scope.applyScope();
++ }
++ });
++ }
++ };
++ $scope.selectAllEntities = function(list, that, varName, setValue) {
++ varName = varName || "master";
++ var val = that[varName];
++ if (setValue == undefined) {
++ setValue = true;
++ }
++ if (setValue) {
++ that[varName] = val = !val;
++ }
++ list.forEach(function(entitiy) {
++ entitiy.checked = val;
++ });
++ };
++ $scope.createPermission = function(type, entity, path, permissions) {
++ if (path.charAt(0) != "/") {
++ path = "/" + path;
++ }
++ var ops = "";
++ var s = "";
++ if (permissions.getPerm) {
++ ops = "get";
++ s = ",";
++ }
++ if (permissions.postPerm) {
++ ops = ops + s + "post";
++ s = ",";
++ }
++ if (permissions.putPerm) {
++ ops = ops + s + "put";
++ s = ",";
++ }
++ if (permissions.deletePerm) {
++ ops = ops + s + "delete";
++ s = ",";
++ }
++ var permission = ops + ":" + path;
++ return permission;
++ };
++ $scope.formatDate = function(date) {
++ return new Date(date).toUTCString();
++ };
++ $scope.clearCheckbox = function(id) {
++ if ($("#" + id).attr("checked")) {
++ $("#" + id).click();
++ }
++ };
++ $scope.removeFirstSlash = function(path) {
++ return path.indexOf("/") === 0 ? path.substring(1, path.length) : path;
++ };
++ $scope.applyScope = function(cb) {
++ cb = typeof cb === "function" ? cb : function() {};
++ if (!this.$$phase) {
++ return this.$apply(cb);
++ } else {
++ cb();
++ }
++ };
++ $scope.valueSelected = function(list) {
++ return list && list.some(function(item) {
++ return item.checked;
++ });
++ };
++ $scope.sendHelp = function(modalId) {
++ ug.jsonpRaw("apigeeuihelpemail", "", {
++ useremail: $rootScope.userEmail
++ }).then(function() {
++ $rootScope.$broadcast("alert", "success", "Email sent. Our team will be in touch with you shortly.");
++ }, function() {
++ $rootScope.$broadcast("alert", "error", "Problem Sending Email. Try sending an email to mobile@apigee.com.");
++ });
++ $scope.hideModal(modalId);
++ };
++ $scope.$on("users-typeahead-received", function(event, users) {
++ $scope.usersTypeaheadValues = users;
++ if (!$scope.$$phase) {
++ $scope.$apply();
++ }
++ });
++ $scope.$on("groups-typeahead-received", function(event, groups) {
++ $scope.groupsTypeaheadValues = groups;
++ if (!$scope.$$phase) {
++ $scope.$apply();
++ }
++ });
++ $scope.$on("roles-typeahead-received", function(event, roles) {
++ $scope.rolesTypeaheadValues = roles;
++ if (!$scope.$$phase) {
++ $scope.$apply();
++ }
++ });
++ $scope.$on("checkAuthentication-success", function() {
++ sessionStorage.setItem("authenticateAttempts", 0);
++ $scope.loaded = true;
++ $rootScope.activeUI = true;
++ $scope.applyScope();
++ if (!$scope.queryStringApplied) {
++ $scope.queryStringApplied = true;
++ setTimeout(function() {
++ if ($scope.queryString.org) {
++ $rootScope.$broadcast("change-org", $scope.queryString.org);
++ }
++ }, 1e3);
++ }
++ $rootScope.$broadcast("app-initialized");
++ });
++ $scope.$on("checkAuthentication-error", function(args, err, missingData, email) {
++ $scope.loaded = true;
++ if (err && !$scope.use_sso && notRegistration()) {
++ ug.logout();
++ $location.path("/login");
++ $scope.applyScope();
++ } else {
++ if (missingData && notRegistration()) {
++ if (!email && $scope.use_sso) {
++ window.location = $rootScope.urls().LOGIN_URL + "?callback=" + encodeURIComponent($location.absUrl().split("?")[0]);
++ return;
++ }
++ ug.reAuthenticate(email);
++ }
++ }
++ });
++ $scope.$on("reAuthenticate-success", function(args, err, data, user, organizations, applications) {
++ sessionStorage.setItem("authenticateAttempts", 0);
++ $rootScope.$broadcast("loginSuccesful", user, organizations, applications);
++ $rootScope.$emit("loginSuccesful", user, organizations, applications);
++ $rootScope.$broadcast("checkAuthentication-success");
++ $scope.applyScope(function() {
++ $scope.deferredLogin.resolve();
++ $location.path("/org-overview");
++ });
++ });
++ var authenticateAttempts = parseInt(sessionStorage.getItem("authenticateAttempts") || 0);
++ $scope.$on("reAuthenticate-error", function() {
++ if ($scope.use_sso) {
++ if (authenticateAttempts++ > 5) {
++ $rootScope.$broadcast("alert", "error", "There is an issue with authentication. Please contact support.");
++ return;
++ }
++ console.error("Failed to login via sso " + authenticateAttempts);
++ sessionStorage.setItem("authenticateAttempts", authenticateAttempts);
++ window.location = $rootScope.urls().LOGIN_URL + "?callback=" + encodeURIComponent($location.absUrl().split("?")[0]);
++ } else {
++ if (notRegistration()) {
++ ug.logout();
++ $location.path("/login");
++ $scope.applyScope();
++ }
++ }
++ });
++ $scope.$on("loginSuccessful", function() {
++ $rootScope.activeUI = true;
++ });
++ $scope.$on("app-changed", function(args, oldVal, newVal, preventReload) {
++ if (newVal !== oldVal && !preventReload) {
++ $route.reload();
++ }
++ });
++ $scope.$on("org-changed", function(args, oldOrg, newOrg) {
++ ug.getApplications();
++ $route.reload();
++ });
++ $scope.$on("app-settings-received", function(evt, data) {});
++ $scope.$on("request-times-slow", function(evt, averageRequestTimes) {
++ $rootScope.$broadcast("alert", "info", "We are experiencing performance issues on our server. Please click Get Help for support if this continues.");
++ });
++ var lastPage = "";
++ $scope.$on("$routeChangeSuccess", function() {
++ verifyUser();
++ $scope.showDemoBar = $location.path().slice(0, "/performance".length) === "/performance";
++ if (!$scope.showDemoBar) {
++ $rootScope.demoData = false;
++ }
++ setTimeout(function() {
++ lastPage = "";
++ }, 50);
++ var path = window.location.pathname.replace("index-debug.html", "");
++ lastPage === "" && $analytics.pageTrack((path + $location.path()).replace("//", "/"));
++ lastPage = $location.path();
++ });
++ $scope.$on("applications-received", function(event, applications) {
++ $scope.applications = applications;
++ $scope.hasApplications = Object.keys(applications).length > 0;
++ });
++ ug.getAppSettings();
++ $rootScope.startFirstTimeUser = function() {
++ $rootScope.hideModal("introjs");
++
<TRUNCATED>