You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2017/05/08 19:23:06 UTC
[2/5] incubator-trafficcontrol git commit: hooks up dashboard page
hooks up dashboard page
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/a81c975a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/a81c975a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/a81c975a
Branch: refs/heads/master
Commit: a81c975ab034791f38e6638f845266cbe3c700fa
Parents: 848c0c8
Author: Jeremy Mitchell <mi...@gmail.com>
Authored: Fri May 5 15:08:58 2017 -0600
Committer: Dan Kirkwood <da...@gmail.com>
Committed: Mon May 8 13:21:54 2017 -0600
----------------------------------------------------------------------
traffic_ops/experimental/ui/app/src/app.js | 8 +
.../ui/app/src/common/api/AuthService.js | 2 +-
.../ui/app/src/common/api/CDNService.js | 36 +-
.../ui/app/src/common/api/CacheStatsService.js | 63 +++
.../experimental/ui/app/src/common/api/index.js | 3 +-
.../ui/app/src/common/filters/PercentFilter.js | 16 +
.../ui/app/src/common/filters/index.js | 1 +
.../cacheGroups/WidgetCacheGroupsController.js | 41 ++
.../common/modules/widget/cacheGroups/index.js | 21 +
.../cacheGroups/widget.cacheGroups.tpl.html | 44 ++
.../widget/capacity/WidgetCapacityController.js | 101 ++++
.../widget/capacity/_widget.capacity.scss | 14 +
.../src/common/modules/widget/capacity/index.js | 21 +
.../widget/capacity/widget.capacity.tpl.html | 40 ++
.../widget/cdnChart/WidgetCDNChartController.js | 189 +++++++
.../widget/cdnChart/_widget.cdnChart.scss | 30 ++
.../src/common/modules/widget/cdnChart/index.js | 21 +
.../widget/cdnChart/widget.cdnChart.tpl.html | 37 ++
.../changeLogs/WidgetChangeLogsController.js | 37 ++
.../common/modules/widget/changeLogs/index.js | 21 +
.../changeLogs/widget.changeLogs.tpl.html | 26 +
.../widget/routing/WidgetRoutingController.js | 33 ++
.../src/common/modules/widget/routing/index.js | 21 +
.../widget/routing/widget.routing.tpl.html | 88 ++++
.../app/src/common/service/utils/DateUtils.js | 131 +++++
.../app/src/common/service/utils/NumberUtils.js | 80 +++
.../ui/app/src/common/service/utils/index.js | 2 +
.../monitor/dashboard/DashboardController.js | 33 +-
.../monitor/dashboard/dashboard.tpl.html | 509 ++-----------------
.../modules/private/monitor/dashboard/index.js | 11 +-
.../private/monitor/dashboard/view/index.js | 53 ++
.../ui/app/src/scripts/shared-libs.js | 8 +
.../experimental/ui/app/src/styles/main.scss | 2 +
.../experimental/ui/app/src/styles/theme.scss | 2 +-
.../experimental/ui/grunt/browserify2.js | 60 +++
35 files changed, 1296 insertions(+), 509 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/app.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/app.js b/traffic_ops/experimental/ui/app/src/app.js
index ac4a99d..082872c 100644
--- a/traffic_ops/experimental/ui/app/src/app.js
+++ b/traffic_ops/experimental/ui/app/src/app.js
@@ -155,6 +155,7 @@ var trafficOps = angular.module('trafficOps', [
// dashboards
require('./modules/private/monitor/dashboard').name,
+ require('./modules/private/monitor/dashboard/view').name,
require('./modules/private/monitor/map').name,
// common modules
@@ -264,6 +265,13 @@ var trafficOps = angular.module('trafficOps', [
require('./common/modules/table/users').name,
require('./common/modules/table/userDeliveryServices').name,
+ // widgets
+ require('./common/modules/widget/cacheGroups').name,
+ require('./common/modules/widget/capacity').name,
+ require('./common/modules/widget/cdnChart').name,
+ require('./common/modules/widget/changeLogs').name,
+ require('./common/modules/widget/routing').name,
+
// models
require('./common/models').name,
require('./common/api').name,
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/api/AuthService.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/api/AuthService.js b/traffic_ops/experimental/ui/app/src/common/api/AuthService.js
index d1b7c9c..e302de4 100644
--- a/traffic_ops/experimental/ui/app/src/common/api/AuthService.js
+++ b/traffic_ops/experimental/ui/app/src/common/api/AuthService.js
@@ -30,7 +30,7 @@ var AuthService = function($rootScope, $http, $state, $location, $q, $state, htt
$location.search('redirect', null); // remove the redirect query param
$location.url(redirect);
} else {
- $location.url('/monitor/map');
+ $location.url('/monitor/dashboard');
}
},
function(fault) {
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/api/CDNService.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/api/CDNService.js b/traffic_ops/experimental/ui/app/src/common/api/CDNService.js
index 2616c80..b24f412 100644
--- a/traffic_ops/experimental/ui/app/src/common/api/CDNService.js
+++ b/traffic_ops/experimental/ui/app/src/common/api/CDNService.js
@@ -17,7 +17,7 @@
* under the License.
*/
-var CDNService = function(Restangular, locationUtils, messageModel) {
+var CDNService = function($http, $q, Restangular, locationUtils, messageModel, ENV) {
this.getCDNs = function(queryParams) {
return Restangular.all('cdns').getList(queryParams);
@@ -88,7 +88,39 @@ var CDNService = function(Restangular, locationUtils, messageModel) {
);
};
+ this.getCapacity = function() {
+ var request = $q.defer();
+
+ $http.get(ENV.api['root'] + "cdns/capacity")
+ .then(
+ function(result) {
+ request.resolve(result.data.response);
+ },
+ function(fault) {
+ request.reject();
+ }
+ );
+
+ return request.promise;
+ };
+
+ this.getCurrentStats = function() {
+ var request = $q.defer();
+
+ $http.get(ENV.api['root'] + "current_stats")
+ .then(
+ function(result) {
+ request.resolve(result.data.response);
+ },
+ function(fault) {
+ request.reject();
+ }
+ );
+
+ return request.promise;
+ };
+
};
-CDNService.$inject = ['Restangular', 'locationUtils', 'messageModel'];
+CDNService.$inject = ['$http', '$q', 'Restangular', 'locationUtils', 'messageModel', 'ENV'];
module.exports = CDNService;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/api/CacheStatsService.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/api/CacheStatsService.js b/traffic_ops/experimental/ui/app/src/common/api/CacheStatsService.js
new file mode 100644
index 0000000..3bcd97a
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/api/CacheStatsService.js
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var CacheStatsService = function($http, $q, httpService, ENV) {
+
+ this.getBandwidth = function(cdnName, start, end) {
+ var request = $q.defer();
+
+ var url = ENV.api['root'] + "cache_stats",
+ params = { cdnName: cdnName, metricType: 'bandwidth', startDate: start.seconds(00).format(), endDate: end.seconds(00).format()};
+
+ $http.get(url, { params: params })
+ .then(
+ function(result) {
+ request.resolve(result.data.response);
+ },
+ function(fault) {
+ request.reject();
+ }
+ );
+
+ return request.promise;
+ };
+
+ this.getConnections = function(cdnName, start, end) {
+ var request = $q.defer();
+
+ var url = ENV.api['root'] + "cache_stats",
+ params = { cdnName: cdnName, metricType: 'connections', startDate: start.seconds(00).format(), endDate: end.seconds(00).format()};
+
+ $http.get(url, { params: params })
+ .then(
+ function(result) {
+ request.resolve(result.data.response);
+ },
+ function(fault) {
+ request.reject();
+ }
+ );
+
+ return request.promise;
+ };
+
+};
+
+CacheStatsService.$inject = ['$http', '$q', 'httpService', 'ENV'];
+module.exports = CacheStatsService;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/api/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/api/index.js b/traffic_ops/experimental/ui/app/src/common/api/index.js
index 042cd93..1e6c597 100644
--- a/traffic_ops/experimental/ui/app/src/common/api/index.js
+++ b/traffic_ops/experimental/ui/app/src/common/api/index.js
@@ -22,7 +22,8 @@ module.exports = angular.module('trafficOps.api', [])
.service('asnService', require('./ASNService'))
.service('cacheGroupService', require('./CacheGroupService'))
.service('cacheGroupParameterService', require('./CacheGroupParameterService'))
- .service('cdnService', require('./CDNService'))
+ .service('cacheStatsService', require('./CacheStatsService'))
+ .service('cdnService', require('./CDNService'))
.service('changeLogService', require('./ChangeLogService'))
.service('deliveryServiceService', require('./DeliveryServiceService'))
.service('deliveryServiceRegexService', require('./DeliveryServiceRegexService'))
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/filters/PercentFilter.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/filters/PercentFilter.js b/traffic_ops/experimental/ui/app/src/common/filters/PercentFilter.js
new file mode 100644
index 0000000..21951d9
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/filters/PercentFilter.js
@@ -0,0 +1,16 @@
+var PercentFilter = function() {
+ return function(input) {
+ input = parseFloat(input);
+ input *= 100;
+ if(input % 1 === 0) {
+ input = input.toFixed(0);
+ }
+ else {
+ input = input.toFixed(2);
+ }
+ return input + '%';
+ };
+};
+
+PercentFilter.$inject = [];
+module.exports = PercentFilter;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/filters/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/filters/index.js b/traffic_ops/experimental/ui/app/src/common/filters/index.js
index 93c6a6c..f912a6c 100644
--- a/traffic_ops/experimental/ui/app/src/common/filters/index.js
+++ b/traffic_ops/experimental/ui/app/src/common/filters/index.js
@@ -19,4 +19,5 @@
module.exports = angular.module('trafficOps.filters', [])
.filter('offsetFilter', require('./OffsetFilter'))
+ .filter('percentFilter', require('./PercentFilter'))
;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/WidgetCacheGroupsController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/WidgetCacheGroupsController.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/WidgetCacheGroupsController.js
new file mode 100644
index 0000000..c5c0f54
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/WidgetCacheGroupsController.js
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var WidgetCacheGroupsController = function(cacheGroupHealth, $scope) {
+
+ // pagination
+ $scope.currentLocationPage = 1;
+ $scope.cacheGroupsPerPage = 10;
+
+ $scope.onlinePercent = function(location) {
+ return (location.online / (location.online + location.offline)) * 100;
+ };
+
+ var init = function() {
+ if (cacheGroupHealth) {
+ // only set this if it's passed in
+ $scope.cacheGroupHealth = cacheGroupHealth;
+ }
+ };
+ init();
+
+};
+
+WidgetCacheGroupsController.$inject = ['cacheGroupHealth', '$scope'];
+module.exports = WidgetCacheGroupsController;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/index.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/index.js
new file mode 100644
index 0000000..21abb68
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = angular.module('trafficOps.widget.cacheGroups', [])
+ .controller('WidgetCacheGroupsController', require('./WidgetCacheGroupsController'));
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/widget.cacheGroups.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/widget.cacheGroups.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/widget.cacheGroups.tpl.html
new file mode 100644
index 0000000..eeb0fe5
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cacheGroups/widget.cacheGroups.tpl.html
@@ -0,0 +1,44 @@
+<div class="x_title">
+ <h3>Cache Groups <small>{{cacheGroupHealth.totalOnline/(cacheGroupHealth.totalOnline + cacheGroupHealth.totalOffline) | percentFilter}} online</small></h3>
+</div>
+<div class="x_content">
+ <div id="cache-groups-outer-container">
+ <div id="cacheGroupsContainer">
+ <div class="alert alert-info" ng-show="(cacheGroupHealth.cachegroups | filter:search:strict).length == 0">
+ No matching cache groups
+ </div>
+ <div class="list-group">
+ <a class="cache-group-health list-group-item" ng-repeat="cg in cacheGroupHealth.cachegroups | orderBy:[onlinePercent, 'name'] | filter:search:strict | offsetFilter:(currentCacheGroupsPage-1)*cacheGroupsPerPage | limitTo:cacheGroupsPerPage">
+ <div class="row">
+ <table class="cache-groups-table table">
+ <tbody>
+ <tr>
+ <td class="col-lg-4 col-md-4 col-sm-4">{{cg.name}}</td>
+ <td class="col-lg-4 col-md-4 col-sm-4">{{cg.online/(cg.online + cg.offline) | percentFilter}} Online [ {{cg.online}} Online | {{cg.offline}} Offline ]</td>
+ <td class="col-lg-4 col-md-4 col-sm-4">
+ <div class="progress">
+ <div class="progress-bar bg-green" role="progressbar" ng-style="{'width': onlinePercent(cg) + '%'}">
+ <span class="sr-only">{{cg.online}} Servers Online | {{cg.offline}} Servers Offline</span>
+ </div>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </a>
+ </div>
+ </div>
+ <div>
+ <div ng-show="(cacheGroupHealth.cachegroups | filter:search:strict).length > 0">
+ <uib-pagination class="cache-groups-pagination pagination-md" boundary-links="true" max-size="2" total-items="(cacheGroupHealth.cachegroups | filter:search:strict).length" items-per-page="cacheGroupsPerPage" ng-model="currentCacheGroupsPage" previous-text="‹" next-text="›" first-text="«" last-text="»"></uib-pagination>
+ </div>
+ <div class="input-group cache-group-search-form">
+ <input type="text" class="filter-input form-control" placeholder="Filter cache groups..." ng-model="search.name">
+ <span class="filter-input-group-btn input-group-btn">
+ <button class="btn btn-default" type="button"><i class="fa fa-search"></i></button>
+ </span>
+ </div>
+ </div>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/WidgetCapacityController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/WidgetCapacityController.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/WidgetCapacityController.js
new file mode 100644
index 0000000..6a0227a
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/WidgetCapacityController.js
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var WidgetCapacityController = function($scope, cdnService) {
+
+ var getCapacity = function() {
+ cdnService.getCapacity()
+ .then(function(response) {
+ $scope.availablePercent = Math.round(response.availablePercent * 100) / 100;
+ $scope.utilizedPercent = Math.round(response.utilizedPercent * 100) / 100;
+ $scope.maintenancePercent = Math.round(response.maintenancePercent * 100) / 100;
+ $scope.unavailablePercent = Math.round(response.unavailablePercent * 100) / 100;
+
+ var data = [];
+
+ data.push({
+ label: "Available",
+ color: '#1ABB9C',
+ data: $scope.availablePercent
+ });
+ data.push({
+ label: "Utilized",
+ color: '#3498DB',
+ data: $scope.utilizedPercent
+ });
+ data.push({
+ label: "Maintenance",
+ color: '#73879C',
+ data: $scope.maintenancePercent
+ });
+ data.push({
+ label: "Down",
+ color: '#E74C3C',
+ data: $scope.unavailablePercent
+ });
+
+ buildGraph(data);
+ });
+
+ };
+
+ var buildGraph = function(graphData) {
+
+ var options = {
+ series: {
+ pie: {
+ show: true,
+ innerRadius: 0.5,
+ radius: 1,
+ label: {
+ show: false
+ }
+ }
+ },
+ grid: {
+ hoverable: true
+ },
+ tooltip: true,
+ tooltipOpts: {
+ cssClass: "capacityChartTooltip",
+ content: "%s: %p.2%",
+ defaultTheme: false
+ },
+ legend: {
+ show: false
+ }
+ };
+
+ $.plot($("#capacityChart"), graphData, options);
+ };
+
+ $scope.availablePercent = 0;
+ $scope.utilizedPercent = 0;
+ $scope.maintenancePercent = 0;
+ $scope.unavailablePercent = 0;
+
+ var init = function() {
+ getCapacity();
+ };
+ init();
+
+};
+
+WidgetCapacityController.$inject = ['$scope', 'cdnService'];
+module.exports = WidgetCapacityController;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/_widget.capacity.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/_widget.capacity.scss b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/_widget.capacity.scss
new file mode 100644
index 0000000..33723c8
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/_widget.capacity.scss
@@ -0,0 +1,14 @@
+#capacityChart {
+ left: 0px;
+ top: 0px;
+ width: 200px;
+ height: 200px;
+}
+.capacityChartTooltip {
+ padding: 3px 5px;
+ background-color: #000;
+ z-index: 100;
+ color: #fff;
+ opacity: .80;
+ filter: alpha(opacity=85);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/index.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/index.js
new file mode 100644
index 0000000..cecf072
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = angular.module('trafficOps.widget.capacity', [])
+ .controller('WidgetCapacityController', require('./WidgetCapacityController'));
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/widget.capacity.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/widget.capacity.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/widget.capacity.tpl.html
new file mode 100644
index 0000000..96f1fb5
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/capacity/widget.capacity.tpl.html
@@ -0,0 +1,40 @@
+<div class="x_title">
+ <h3>Overall Capacity</h3>
+</div>
+<div class="x_content">
+ <table class="" style="width:100%">
+ <tr>
+ <td>
+ <div id="capacityChart"></div>
+ </td>
+ <td>
+ <table class="tile_info">
+ <tr>
+ <td>
+ <p><i class="fa fa-square green"></i>Available </p>
+ </td>
+ <td>{{availablePercent}}%</td>
+ </tr>
+ <tr>
+ <td>
+ <p><i class="fa fa-square blue"></i>Utilized </p>
+ </td>
+ <td>{{utilizedPercent}}%</td>
+ </tr>
+ <tr>
+ <td>
+ <p><i class="fa fa-square gray"></i>Maint </p>
+ </td>
+ <td>{{maintenancePercent}}%</td>
+ </tr>
+ <tr>
+ <td>
+ <p><i class="fa fa-square red"></i>Down </p>
+ </td>
+ <td>{{unavailablePercent}}%</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/WidgetCDNChartController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/WidgetCDNChartController.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/WidgetCDNChartController.js
new file mode 100644
index 0000000..22e2a64
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/WidgetCDNChartController.js
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var WidgetCDNChartController = function(cdn, $scope, $timeout, $filter, $q, cdnService, cacheStatsService, dateUtils, locationUtils, numberUtils) {
+
+ var getCDN = function(id) {
+ cdnService.getCDN(id)
+ .then(function(result) {
+ $scope.cdn = result;
+ getCurrentStats($scope.cdn.name);
+ getChartData($scope.cdn.name, moment().subtract(1, 'days'), moment().subtract(10, 'seconds'));
+ });
+ };
+
+ var getCurrentStats = function(cdnName) {
+ cdnService.getCurrentStats()
+ .then(function(result) {
+ $scope.currentStats = _.find(result.currentStats, function(item) {
+ return item.cdn == cdnName;
+ });
+ });
+ };
+
+ var getChartData = function(cdnName, start, end) {
+ var promises = [];
+
+ // get cdn bandwidth
+ promises.push(cacheStatsService.getBandwidth(cdnName, start, end));
+
+ // get cdn connections
+ promises.push(cacheStatsService.getConnections(cdnName, start, end));
+
+ $q.all(promises)
+ .then(
+ function(responses) {
+ // set chart data
+ var bandwidthChartData = buildBandwidthChartData(responses[0], start),
+ connectionsChartData = buildConnectionsChartData(responses[1], start);
+
+ $timeout(function () {
+ buildChart(bandwidthChartData, connectionsChartData);
+ }, 100);
+ },
+ function(fault) {
+ buildChart([], []); // build an empty chart
+ });
+
+ };
+
+ var buildBandwidthChartData = function(result, start) {
+ var normalizedChartData = [],
+ series = result.series;
+
+ if (angular.isDefined(series)) {
+ _.each(series.values, function(seriesItem) {
+ if (moment(seriesItem[0]).isSame(start) || moment(seriesItem[0]).isAfter(start)) {
+ normalizedChartData.push([ moment(seriesItem[0]).valueOf(), numberUtils.convertTo(seriesItem[1], $scope.unitSize) ]); // converts data to appropriate unit
+ }
+ });
+ }
+
+ return normalizedChartData;
+ };
+
+ var buildConnectionsChartData = function(result, start) {
+ var normalizedChartData = [],
+ series = result.series;
+
+ if (angular.isDefined(series)) {
+ _.each(series.values, function(seriesItem) {
+ if (moment(seriesItem[0]).isSame(start) || moment(seriesItem[0]).isAfter(start)) {
+ if (_.isNumber(seriesItem[1])) {
+ normalizedChartData.push([ moment(seriesItem[0]).valueOf(), seriesItem[1] ]);
+ }
+ }
+ });
+ }
+
+ return normalizedChartData;
+ };
+
+ var buildChart = function(bandwidthChartData, connectionsChartData) {
+
+ var options = {
+ xaxis: {
+ mode: "time",
+ timezone: "utc",
+ twelveHourClock: false
+ },
+ yaxes: [
+ {
+ position: "left",
+ axisLabel: "Bandwidth (Gbps)",
+ axisLabelUseCanvas: true,
+ axisLabelFontSizePixels: 12,
+ axisLabelFontFamily: 'Verdana, Arial',
+ axisLabelPadding: 3
+ },
+ {
+ position: "right",
+ axisLabel: "Connections",
+ axisLabelUseCanvas: true,
+ axisLabelFontSizePixels: 12,
+ axisLabelFontFamily: 'Verdana, Arial',
+ axisLabelPadding: 3
+ }
+ ],
+ grid: {
+ hoverable: true,
+ axisMargin: 20
+ },
+ tooltip: {
+ show: true,
+ content: function(label, xval, yval, flotItem){
+ var tooltipString = dateUtils.dateFormat(xval, "UTC: ddd mmm d yyyy H:MM:ss tt (Z)") + '<br>';
+ tooltipString += '<span>' + label + ': ' + $filter('number')(yval, 2) + '</span><br>'
+ return tooltipString;
+ }
+ }
+ };
+
+ var series = [
+ { label: "Bandwidth", yaxis: 1, color: colors[Math.floor(Math.random() * 17) + 1], data: bandwidthChartData },
+ { label: "Connections", yaxis: 2, color: colors[Math.floor(Math.random() * 17) + 1], data: connectionsChartData }
+ ];
+
+ $.plot($("#bps-chart-" + $scope.cdn.id), series, options);
+
+ };
+
+ var colors = [
+ '#1ABB9C',
+ '#3498DB',
+ '#73879C',
+ '#E74C3C',
+ '#946E83',
+ '#615055',
+ '#000000',
+ '#9FD356',
+ '#3A6B3D',
+ '#405672',
+ '#FF5000',
+ '#E39878',
+ '#6D6B6D',
+ '#54000B',
+ '#077187',
+ '#0D295E',
+ '#5B0554'
+ ];
+
+ $scope.cdn;
+
+ $scope.unitSize = 'Gb';
+
+ $scope.randomId = '_' + Math.random().toString(36).substr(2, 9);
+
+ $scope.navigateToPath = locationUtils.navigateToPath;
+
+ angular.element(document).ready(function () {
+ var cdnId;
+ if (cdn) {
+ cdnId = cdn.id;
+ } else {
+ // cdn wasn't passed in. we need to figure it out on our own
+ cdnId = $('#' + $scope.randomId).closest('.chartContainer').data('cdnid');
+ }
+ getCDN(cdnId);
+ });
+
+};
+
+WidgetCDNChartController.$inject = ['cdn', '$scope', '$timeout', '$filter', '$q', 'cdnService', 'cacheStatsService', 'dateUtils', 'locationUtils', 'numberUtils'];
+module.exports = WidgetCDNChartController;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/_widget.cdnChart.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/_widget.cdnChart.scss b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/_widget.cdnChart.scss
new file mode 100644
index 0000000..e5ff8b2
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/_widget.cdnChart.scss
@@ -0,0 +1,30 @@
+/*
+
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+.bps-chart-container {
+ position: relative;
+ text-align: center;
+ background-color: transparent;
+ padding: 30px 60px;
+
+ .bps-chart {
+ height: 200px;
+ min-width: 310px;
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/index.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/index.js
new file mode 100644
index 0000000..7100951
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = angular.module('trafficOps.widget.cdnChart', [])
+ .controller('WidgetCDNChartController', require('./WidgetCDNChartController'));
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/widget.cdnChart.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/widget.cdnChart.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/widget.cdnChart.tpl.html
new file mode 100644
index 0000000..c1bef77
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/cdnChart/widget.cdnChart.tpl.html
@@ -0,0 +1,37 @@
+<div id="{{::randomId}}" class="dashboard_graph">
+ <div class="row x_title">
+ <div class="col-md-6">
+ <h3><a ng-click="navigateToPath('/admin/cdns/' + cdn.id)">{{::cdn.name}}</a></h3>
+ </div>
+ </div>
+ <div class="col-md-9 col-sm-9 col-xs-12">
+ <div class="bps-chart-container">
+ <div id="bps-chart-{{::cdn.id}}" class="bps-chart"></div>
+ </div>
+ </div>
+ <div class="col-md-3 col-sm-3 col-xs-12 bg-white">
+ <div class="x_title">
+ <h3>Statistics</h3>
+ <div class="clearfix"></div>
+ </div>
+ <div class="col-md-12 col-sm-12 col-xs-6">
+ <table class="countries_list">
+ <tbody>
+ <tr>
+ <td>Utilization %</td>
+ <td class="fs15 fw700 text-right">{{currentStats.bandwidth/currentStats.capacity | percentFilter}} of {{currentStats.capacity | number:0}} Gbps</td>
+ </tr>
+ <tr>
+ <td>Current Bandwidth</td>
+ <td class="fs15 fw700 text-right">{{currentStats.bandwidth | number:2}} Gbps</td>
+ </tr>
+ <tr>
+ <td>Current Connections</td>
+ <td class="fs15 fw700 text-right">{{currentStats.connections | number:0}}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div class="clearfix"></div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/WidgetChangeLogsController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/WidgetChangeLogsController.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/WidgetChangeLogsController.js
new file mode 100644
index 0000000..335fac5
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/WidgetChangeLogsController.js
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var WidgetChangeLogsController = function(changeLogs, $scope) {
+
+ $scope.getRelativeTime = function(date) {
+ return moment(date).fromNow();
+ };
+
+ var init = function() {
+ if (changeLogs) {
+ // only set this if it's passed in
+ $scope.changeLogs = changeLogs;
+ }
+ };
+ init();
+
+};
+
+WidgetChangeLogsController.$inject = ['changeLogs', '$scope'];
+module.exports = WidgetChangeLogsController;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/index.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/index.js
new file mode 100644
index 0000000..e71fb2c
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = angular.module('trafficOps.widget.changeLogs', [])
+ .controller('WidgetChangeLogsController', require('./WidgetChangeLogsController'));
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/widget.changeLogs.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/widget.changeLogs.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/widget.changeLogs.tpl.html
new file mode 100644
index 0000000..a3ceba2
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/changeLogs/widget.changeLogs.tpl.html
@@ -0,0 +1,26 @@
+<div class="x_title">
+ <h3>Change Logs</h3>
+</div>
+<div class="x_content">
+ <div class="dashboard-widget-content">
+ <ul class="list-unstyled timeline widget">
+ <li ng-repeat="changeLog in ::changeLogs">
+ <div class="block">
+ <div class="block_content">
+ <h2 class="title">{{::changeLog.level}}</h2>
+ <div class="byline">
+ <span>{{::getRelativeTime(changeLog.lastUpdated)}}</span> by <a>{{::changeLog.user}}</a>
+ </div>
+ <p class="excerpt">{{::changeLog.message}}</p>
+ </div>
+ </div>
+ </li>
+ </ul>
+ </div>
+ <div class="text-center">
+ <a>
+ <strong><a ng-click="navigateToPath('/admin/change-logs')">See All Change Logs</a></strong>
+ <i class="fa fa-angle-right"></i>
+ </a>
+ </div>
+</div>
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/WidgetRoutingController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/WidgetRoutingController.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/WidgetRoutingController.js
new file mode 100644
index 0000000..dc8f03c
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/WidgetRoutingController.js
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var WidgetRoutingController = function(routing, $scope) {
+
+ var init = function() {
+ if (routing) {
+ // only set this if it's passed in
+ $scope.routing = routing;
+ }
+ };
+ init();
+
+};
+
+WidgetRoutingController.$inject = ['routing', '$scope'];
+module.exports = WidgetRoutingController;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/index.js b/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/index.js
new file mode 100644
index 0000000..b7b3e94
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/index.js
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+module.exports = angular.module('trafficOps.widget.routing', [])
+ .controller('WidgetRoutingController', require('./WidgetRoutingController'));
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/widget.routing.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/widget.routing.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/widget.routing.tpl.html
new file mode 100644
index 0000000..d45372c
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/modules/widget/routing/widget.routing.tpl.html
@@ -0,0 +1,88 @@
+<div class="x_title">
+ <h3>Routing Methods</h3>
+</div>
+<div class="x_content">
+ <div class="widget_summary">
+ <div class="w_left w_25">
+ <span>Native</span>
+ </div>
+ <div class="w_center w_55">
+ <div class="progress">
+ <div class="progress-bar bg-green" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
+ <span class="sr-only">60% Complete</span>
+ </div>
+ </div>
+ </div>
+ <div class="w_right w_20">
+ <span>60%</span>
+ </div>
+ <div class="clearfix"></div>
+ </div>
+
+ <div class="widget_summary">
+ <div class="w_left w_25">
+ <span>3rd Party</span>
+ </div>
+ <div class="w_center w_55">
+ <div class="progress">
+ <div class="progress-bar bg-green" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 20%;">
+ <span class="sr-only">60% Complete</span>
+ </div>
+ </div>
+ </div>
+ <div class="w_right w_20">
+ <span>20%</span>
+ </div>
+ <div class="clearfix"></div>
+ </div>
+ <div class="widget_summary">
+ <div class="w_left w_25">
+ <span>DSR</span>
+ </div>
+ <div class="w_center w_55">
+ <div class="progress">
+ <div class="progress-bar bg-green" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 10%;">
+ <span class="sr-only">60% Complete</span>
+ </div>
+ </div>
+ </div>
+ <div class="w_right w_20">
+ <span>10%</span>
+ </div>
+ <div class="clearfix"></div>
+ </div>
+ <div class="widget_summary">
+ <div class="w_left w_25">
+ <span>Static</span>
+ </div>
+ <div class="w_center w_55">
+ <div class="progress">
+ <div class="progress-bar bg-green" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 5%;">
+ <span class="sr-only">60% Complete</span>
+ </div>
+ </div>
+ </div>
+ <div class="w_right w_20">
+ <span>5%</span>
+ </div>
+ <div class="clearfix"></div>
+ </div>
+ <div class="widget_summary">
+ <div class="w_left w_25">
+ <span>Federated</span>
+ </div>
+ <div class="w_center w_55">
+ <div class="progress">
+ <div class="progress-bar bg-green" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 5%;">
+ <span class="sr-only">60% Complete</span>
+ </div>
+ </div>
+ </div>
+ <div class="w_right w_20">
+ <span>5%</span>
+ </div>
+ <div class="clearfix"></div>
+ </div>
+
+</div>
+
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/service/utils/DateUtils.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/service/utils/DateUtils.js b/traffic_ops/experimental/ui/app/src/common/service/utils/DateUtils.js
new file mode 100644
index 0000000..e554d02
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/service/utils/DateUtils.js
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+var DateUtils = function() {
+
+ this.dateFormat = function () {
+ // source: http://blog.stevenlevithan.com/archives/date-time-format
+ var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
+ timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
+ timezoneClip = /[^-+\dA-Z]/g,
+ pad = function (val, len) {
+ val = String(val);
+ len = len || 2;
+ while (val.length < len) val = "0" + val;
+ return val;
+ };
+
+ // Regexes and supporting functions are cached through closure
+ return function (date, mask, utc) {
+ var dF = this.dateFormat;
+
+ // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
+ if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
+ mask = date;
+ date = undefined;
+ }
+
+ // Passing date through Date applies Date.parse, if necessary
+ date = date ? new Date(date) : new Date;
+ if (isNaN(date)) throw SyntaxError("invalid date");
+
+ mask = String(dF.masks[mask] || mask || dF.masks["default"]);
+
+ // Allow setting the utc argument via the mask
+ if (mask.slice(0, 4) == "UTC:") {
+ mask = mask.slice(4);
+ utc = true;
+ }
+
+ var _ = utc ? "getUTC" : "get",
+ d = date[_ + "Date"](),
+ D = date[_ + "Day"](),
+ m = date[_ + "Month"](),
+ y = date[_ + "FullYear"](),
+ H = date[_ + "Hours"](),
+ M = date[_ + "Minutes"](),
+ s = date[_ + "Seconds"](),
+ L = date[_ + "Milliseconds"](),
+ o = utc ? 0 : date.getTimezoneOffset(),
+ flags = {
+ d: d,
+ dd: pad(d),
+ ddd: dF.i18n.dayNames[D],
+ dddd: dF.i18n.dayNames[D + 7],
+ m: m + 1,
+ mm: pad(m + 1),
+ mmm: dF.i18n.monthNames[m],
+ mmmm: dF.i18n.monthNames[m + 12],
+ yy: String(y).slice(2),
+ yyyy: y,
+ h: H % 12 || 12,
+ hh: pad(H % 12 || 12),
+ H: H,
+ HH: pad(H),
+ M: M,
+ MM: pad(M),
+ s: s,
+ ss: pad(s),
+ l: pad(L, 3),
+ L: pad(L > 99 ? Math.round(L / 10) : L),
+ t: H < 12 ? "a" : "p",
+ tt: H < 12 ? "am" : "pm",
+ T: H < 12 ? "A" : "P",
+ TT: H < 12 ? "AM" : "PM",
+ Z: utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
+ o: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
+ S: ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
+ };
+
+ return mask.replace(token, function ($0) {
+ return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
+ });
+ };
+ }();
+
+ this.dateFormat.masks = {
+ "default": "ddd mmm dd yyyy HH:MM:ss",
+ shortDate: "m/d/yy",
+ mediumDate: "mmm d, yyyy",
+ longDate: "mmmm d, yyyy",
+ fullDate: "dddd, mmmm d, yyyy",
+ shortTime: "h:MM TT",
+ mediumTime: "h:MM:ss TT",
+ longTime: "h:MM:ss TT Z",
+ isoDate: "yyyy-mm-dd",
+ isoTime: "HH:MM:ss",
+ isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
+ isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
+ };
+
+ this.dateFormat.i18n = {
+ dayNames: [
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+ ],
+ monthNames: [
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+ ]
+ };
+
+};
+
+DateUtils.$inject = [];
+module.exports = DateUtils;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/service/utils/NumberUtils.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/service/utils/NumberUtils.js b/traffic_ops/experimental/ui/app/src/common/service/utils/NumberUtils.js
new file mode 100644
index 0000000..9a66563
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/common/service/utils/NumberUtils.js
@@ -0,0 +1,80 @@
+/*
+
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+var NumberUtils = function($filter) {
+
+ var k = 1000,
+ sizes = ['B', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'];
+
+ this.addCommas = function(nStr)
+ {
+ nStr += '';
+ x = nStr.split('.');
+ x1 = x[0];
+ x2 = x.length > 1 ? '.' + x[1] : '';
+ var rgx = /(\d+)(\d{3})/;
+ while (rgx.test(x1)) {
+ x1 = x1.replace(rgx, '$1' + ',' + '$2');
+ }
+ return x1 + x2;
+ };
+
+ /**
+ * This function takes big scary kilobit numbers and 'shrinks' them to a friendly version
+ * i.e. 10,000 kilobits is easier read as 10 megabits...
+ */
+ this.shrink = function(kilounits) {
+ if (!angular.isNumber(kilounits) || kilounits == 0) return [ 0, 'Kb' ];
+ var units = kilounits * 1000;
+ var i = Math.floor(Math.log(units) / Math.log(k));
+ if (i < 1) { i = 1 } // kilobits is the lowest we will go
+ if (i > 5) { i = 5 } // petabits is the highest we will go
+ return [ Math.round((units / Math.pow(k, i)) * 100) / 100, sizes[i] ];
+ };
+
+ this.convertTo = function(kilounits, size) {
+ if (!angular.isNumber(kilounits)) return null;
+ if (kilounits == 0) return 0;
+ var units = kilounits * 1000;
+ var i = sizes.indexOf(size);
+ if (i == -1) {
+ return 0;
+ }
+ return Math.round((units / Math.pow(k, i)) * 100) / 100;
+ };
+
+ this.average = function(arr)
+ {
+ if (!angular.isArray(arr) || arr.length == 0 ) return 0;
+ return _.reduce(arr, function(memo, num) {
+ return memo + num;
+ }, 0) / arr.length;
+ }
+
+ this.ratio = function(numerator, denominator)
+ {
+ if (numerator === 0 || denominator === 0) {
+ return 'N/A';
+ } else {
+ return $filter('number')(numerator/denominator, 2) + ':1';
+ }
+ }
+
+};
+
+NumberUtils.$inject = ['$filter'];
+module.exports = NumberUtils;
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/common/service/utils/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/service/utils/index.js b/traffic_ops/experimental/ui/app/src/common/service/utils/index.js
index 0eaa2d1..1420100 100644
--- a/traffic_ops/experimental/ui/app/src/common/service/utils/index.js
+++ b/traffic_ops/experimental/ui/app/src/common/service/utils/index.js
@@ -18,7 +18,9 @@
*/
module.exports = angular.module('trafficOps.utils', [])
+ .service('dateUtils', require('./DateUtils'))
.service('formUtils', require('./FormUtils'))
.service('locationUtils', require('./LocationUtils'))
+ .service('numberUtils', require('./NumberUtils'))
.service('serverUtils', require('./ServerUtils'))
.service('stringUtils', require('./StringUtils'));
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/DashboardController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/DashboardController.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/DashboardController.js
index 2abe702..e4715d3 100644
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/DashboardController.js
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/DashboardController.js
@@ -17,32 +17,21 @@
* under the License.
*/
-var DashboardController = function(changeLogs, cacheGroupHealth, $scope, locationUtils) {
+var DashboardController = function(cacheGroupHealth, cdns, currentStats, $scope) {
- $scope.changeLogs = changeLogs;
+ $scope.cacheGroupHealth = cacheGroupHealth;
- $scope.getRelativeTime = function(date) {
- return moment(date).fromNow();
- };
+ $scope.cdns = _.filter(cdns, function(cdn) {
+ // we don't want the "ALL" cdn which is not really a cdn
+ return cdn.name != 'ALL';
+ });
- $scope.navigateToPath = locationUtils.navigateToPath;
-
-
- $scope.locationHealth = {
- totalOnline: cacheGroupHealth.totalOnline,
- totalOffline: cacheGroupHealth.totalOffline,
- locations: cacheGroupHealth.cachegroups
- };
-
- // pagination
- $scope.currentLocationPage = 1;
- $scope.locationsPerPage = 10;
-
- $scope.onlinePercent = function(location) {
- return location.online / (location.online + location.offline);
- };
+ $scope.totalStats = _.find(currentStats.currentStats, function(item) {
+ // total stats are buried in a hash where cdn = total
+ return item.cdn == 'total';
+ });
};
-DashboardController.$inject = ['changeLogs', 'cacheGroupHealth', '$scope', 'locationUtils'];
+DashboardController.$inject = ['cacheGroupHealth', 'cdns', 'currentStats', '$scope'];
module.exports = DashboardController;