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:05 UTC

[1/5] incubator-trafficcontrol git commit: hooks up dashboard page

Repository: incubator-trafficcontrol
Updated Branches:
  refs/heads/master 26d3ca012 -> 38c9da30c


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
index ffee368..5254378 100644
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
@@ -17,299 +17,79 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-<script src="../../../../../../../../../traffic_portal/app/src/modules/private/deliveryService/view/overview/DeliveryServiceViewOverviewController.js"></script>
 <div role="main">
     <!-- top tiles -->
     <div class="row tile_count">
         <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
-            <span class="count_top"><i class="fa fa-user"></i> Total Users</span>
-            <div class="count">2500</div>
-            <span class="count_bottom"><i class="green">4% </i> From last Week</span>
+            <span class="count_top"><i class="fa fa-bolt"></i> Total Bandwidth</span>
+            <div class="count">{{totalStats.bandwidth | number:2}} Gbps</div>
         </div>
         <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
-            <span class="count_top"><i class="fa fa-clock-o"></i> Average Time</span>
-            <div class="count">123.50</div>
-            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>3% </i> From last Week</span>
+            <span class="count_top"><i class="fa fa-clock-o"></i> Total Connections</span>
+            <div class="count">{{totalStats.connections | number:0}}</div>
         </div>
         <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
-            <span class="count_top"><i class="fa fa-user"></i> Total Males</span>
-            <div class="count green">2,500</div>
-            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>34% </i> From last Week</span>
+            <span class="count_top"><i class="fa fa-server"></i> Total Online Caches</span>
+            <div class="count green">{{cacheGroupHealth.totalOnline}}</div>
         </div>
         <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
-            <span class="count_top"><i class="fa fa-user"></i> Total Females</span>
-            <div class="count">4,567</div>
-            <span class="count_bottom"><i class="red"><i class="fa fa-sort-desc"></i>12% </i> From last Week</span>
+            <span class="count_top"><i class="fa fa-server"></i> Total Offline Caches</span>
+            <div class="count red">{{cacheGroupHealth.totalOffline}}</div>
         </div>
         <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
-            <span class="count_top"><i class="fa fa-user"></i> Total Collections</span>
-            <div class="count">2,315</div>
-            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>34% </i> From last Week</span>
+            <span class="count_top"><i class="fa fa-user"></i> Another Metric</span>
+            <div class="count">999</div>
         </div>
         <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
-            <span class="count_top"><i class="fa fa-user"></i> Total Connections</span>
-            <div class="count">7,325</div>
-            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>34% </i> From last Week</span>
+            <span class="count_top"><i class="fa fa-user"></i> Another Metric</span>
+            <div class="count">999</div>
         </div>
     </div>
     <!-- /top tiles -->
 
-    <div class="row">
-        <div class="col-md-12 col-sm-12 col-xs-12">
-            <div class="dashboard_graph">
-
-                <div class="row x_title">
-                    <div class="col-md-6">
-                        <h3>Network Activities <small>Graph title sub-title</small></h3>
-                    </div>
-                    <div class="col-md-6">
-                        <div id="reportrange" class="pull-right" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc">
-                            <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
-                            <span>December 30, 2014 - January 28, 2015</span> <b class="caret"></b>
-                        </div>
-                    </div>
-                </div>
-
-                <div class="col-md-9 col-sm-9 col-xs-12">
-                    <div id="chart_plot_01" class="demo-placeholder"></div>
-                </div>
-                <div class="col-md-3 col-sm-3 col-xs-12 bg-white">
-                    <div class="x_title">
-                        <h3>Top Campaign Performance</h3>
-                        <div class="clearfix"></div>
-                    </div>
-
-                    <div class="col-md-12 col-sm-12 col-xs-6">
-                        <div>
-                            <p>Facebook Campaign</p>
-                            <div class="">
-                                <div class="progress progress_sm" style="width: 76%;">
-                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="80"></div>
-                                </div>
-                            </div>
-                        </div>
-                        <div>
-                            <p>Twitter Campaign</p>
-                            <div class="">
-                                <div class="progress progress_sm" style="width: 76%;">
-                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="60"></div>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <div class="col-md-12 col-sm-12 col-xs-6">
-                        <div>
-                            <p>Conventional Media</p>
-                            <div class="">
-                                <div class="progress progress_sm" style="width: 76%;">
-                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="40"></div>
-                                </div>
-                            </div>
-                        </div>
-                        <div>
-                            <p>Bill boards</p>
-                            <div class="">
-                                <div class="progress progress_sm" style="width: 76%;">
-                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="50"></div>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-
-                </div>
-
-                <div class="clearfix"></div>
-            </div>
+    <!-- cdn graphs -->
+    <div ng-repeat="cdn in ::cdns">
+        <div class="row">
+            <div class="col-md-12 col-sm-12 col-xs-12 chartContainer" data-cdnid="{{::cdn.id}}" ui-view="cdnChartContent"></div>
         </div>
-
+        <br>
     </div>
-    <br />
+    <!-- /cdn graphs -->
 
     <div class="row">
 
 
         <div class="col-md-4 col-sm-4 col-xs-12">
-            <div class="x_panel tile fixed_height_320">
-                <div class="x_title">
-                    <h3>App Versions</h3>
-                </div>
-                <div class="x_content">
-                    <h4>App Usage across versions</h4>
-                    <div class="widget_summary">
-                        <div class="w_left w_25">
-                            <span>0.1.5.2</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: 66%;">
-                                    <span class="sr-only">60% Complete</span>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="w_right w_20">
-                            <span>123k</span>
-                        </div>
-                        <div class="clearfix"></div>
-                    </div>
-
-                    <div class="widget_summary">
-                        <div class="w_left w_25">
-                            <span>0.1.5.3</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: 45%;">
-                                    <span class="sr-only">60% Complete</span>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="w_right w_20">
-                            <span>53k</span>
-                        </div>
-                        <div class="clearfix"></div>
-                    </div>
-                    <div class="widget_summary">
-                        <div class="w_left w_25">
-                            <span>0.1.5.4</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: 25%;">
-                                    <span class="sr-only">60% Complete</span>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="w_right w_20">
-                            <span>23k</span>
-                        </div>
-                        <div class="clearfix"></div>
-                    </div>
-                    <div class="widget_summary">
-                        <div class="w_left w_25">
-                            <span>0.1.5.5</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>3k</span>
-                        </div>
-                        <div class="clearfix"></div>
-                    </div>
-                    <div class="widget_summary">
-                        <div class="w_left w_25">
-                            <span>0.1.5.6</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: 2%;">
-                                    <span class="sr-only">60% Complete</span>
-                                </div>
-                            </div>
-                        </div>
-                        <div class="w_right w_20">
-                            <span>1k</span>
-                        </div>
-                        <div class="clearfix"></div>
-                    </div>
-
-                </div>
-            </div>
+            <div class="x_panel tile fixed_height_320" ui-view="capacityContent"></div>
         </div>
 
         <div class="col-md-4 col-sm-4 col-xs-12">
-            <div class="x_panel tile fixed_height_320 overflow_hidden">
-                <div class="x_title">
-                    <h3>Device Usage</h3>
-                </div>
-                <div class="x_content">
-                    <table class="" style="width:100%">
-                        <tr>
-                            <th style="width:37%;">
-                                <p>Top 5</p>
-                            </th>
-                            <th>
-                                <div class="col-lg-7 col-md-7 col-sm-7 col-xs-7">
-                                    <p class="">Device</p>
-                                </div>
-                                <div class="col-lg-5 col-md-5 col-sm-5 col-xs-5">
-                                    <p class="">Progress</p>
-                                </div>
-                            </th>
-                        </tr>
-                        <tr>
-                            <td>
-                                <canvas class="canvasDoughnut" height="140" width="140" style="margin: 15px 10px 10px 0"></canvas>
-                            </td>
-                            <td>
-                                <table class="tile_info">
-                                    <tr>
-                                        <td>
-                                            <p><i class="fa fa-square blue"></i>IOS </p>
-                                        </td>
-                                        <td>30%</td>
-                                    </tr>
-                                    <tr>
-                                        <td>
-                                            <p><i class="fa fa-square green"></i>Android </p>
-                                        </td>
-                                        <td>10%</td>
-                                    </tr>
-                                    <tr>
-                                        <td>
-                                            <p><i class="fa fa-square purple"></i>Blackberry </p>
-                                        </td>
-                                        <td>20%</td>
-                                    </tr>
-                                    <tr>
-                                        <td>
-                                            <p><i class="fa fa-square aero"></i>Symbian </p>
-                                        </td>
-                                        <td>15%</td>
-                                    </tr>
-                                    <tr>
-                                        <td>
-                                            <p><i class="fa fa-square red"></i>Others </p>
-                                        </td>
-                                        <td>30%</td>
-                                    </tr>
-                                </table>
-                            </td>
-                        </tr>
-                    </table>
-                </div>
-            </div>
+            <div class="x_panel tile fixed_height_320" ui-view="routingContent"></div>
         </div>
-
-
         <div class="col-md-4 col-sm-4 col-xs-12">
             <div class="x_panel tile fixed_height_320">
                 <div class="x_title">
-                    <h3>Quick Settings</h3>
+                    <h3>Something Else</h3>
                 </div>
                 <div class="x_content">
                     <div class="dashboard-widget-content">
                         <ul class="quick-list">
-                            <li><i class="fa fa-calendar-o"></i><a href="#">Settings</a>
+                            <li><i class="fa fa-calendar-o"></i><a href="#">Foo</a>
                             </li>
-                            <li><i class="fa fa-bars"></i><a href="#">Subscription</a>
+                            <li><i class="fa fa-bars"></i><a href="#">Bar</a>
                             </li>
-                            <li><i class="fa fa-bar-chart"></i><a href="#">Auto Renewal</a> </li>
-                            <li><i class="fa fa-line-chart"></i><a href="#">Achievements</a>
+                            <li><i class="fa fa-bar-chart"></i><a href="#">Foo</a> </li>
+                            <li><i class="fa fa-line-chart"></i><a href="#">Bar</a>
                             </li>
-                            <li><i class="fa fa-bar-chart"></i><a href="#">Auto Renewal</a> </li>
-                            <li><i class="fa fa-line-chart"></i><a href="#">Achievements</a>
+                            <li><i class="fa fa-bar-chart"></i><a href="#">Foo</a> </li>
+                            <li><i class="fa fa-line-chart"></i><a href="#">Bar</a>
                             </li>
-                            <li><i class="fa fa-area-chart"></i><a href="#">Logout</a>
+                            <li><i class="fa fa-area-chart"></i><a href="#">Foo</a>
                             </li>
                         </ul>
 
                         <div class="sidebar-widget">
-                            <h4>Profile Completion</h4>
+                            <h4>Something</h4>
                             <canvas width="150" height="80" id="chart_gauge_01" class="" style="width: 160px; height: 100px;"></canvas>
                             <div class="goal-wrapper">
                                 <span id="gauge-text" class="gauge-value pull-left">0</span>
@@ -321,243 +101,16 @@ under the License.
                 </div>
             </div>
         </div>
-
     </div>
-
-
     <div class="row">
         <div class="col-md-4 col-sm-4 col-xs-12">
-            <div class="x_panel">
-                <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>
-            </div>
+            <div class="x_panel" ui-view="changeLogsContent"></div>
         </div>
-
-
         <div class="col-md-8 col-sm-8 col-xs-12">
-
-
-
             <div class="row">
-
                 <div class="col-md-12 col-sm-12 col-xs-12">
-                    <div class="x_panel">
-                        <div class="x_title">
-                            <h3>Cache Groups <small>100% online</small></h3>
-                        </div>
-                        <div class="x_content">
-                            <div id="cache-groups-outer-container">
-                                <div id="cacheGroupsOverallHealth">
-                                    <h4 class="cache-groups-online">Cache Groups <small>{{locationHealth.totalOnline/(locationHealth.totalOnline + locationHealth.totalOffline) | percentFilter}} online</small></h4>
-                                </div>
-                                <div id="cacheGroupsContainer">
-                                    <div class="alert alert-info" ng-show="(locationHealth.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="location in locationHealth.cachegroups | orderBy:[onlinePercent, 'name'] | filter:search:strict | offsetFilter:(currentLocationPage-1)*locationsPerPage | limitTo:locationsPerPage">
-                                            <div class="row">
-                                                <table class="cache-groups-table table">
-                                                    <tbody>
-                                                    <tr>
-                                                        <td class="col-lg-4 col-md-4 col-sm-4">{{location.name}}</td>
-                                                        <td class="col-lg-4 col-md-4 col-sm-4">{{location.online/(location.online + location.offline) | percentFilter}} Online</td>
-                                                        <td class="col-lg-4 col-md-4 col-sm-4">{{location.online}} Servers Online | {{location.offline}} Servers Offline</td>
-                                                    </tr>
-                                                    </tbody>
-                                                </table>
-                                            </div>
-                                        </a>
-                                    </div>
-                                </div>
-                                <div>
-                                    <div ng-show="(locationHealth.cachegroups | filter:search:strict).length > 0">
-                                        <uib-pagination class="cache-groups-pagination pagination-md" boundary-links="true" max-size="2" total-items="(locationHealth.cachegroups | filter:search:strict).length" items-per-page="locationsPerPage" ng-model="currentLocationPage" previous-text="&lsaquo;" next-text="&rsaquo;" first-text="&laquo;" last-text="&raquo;"></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>
-                    </div>
-                </div>
-
-            </div>
-            <div class="row">
-
-
-                <!-- Start to do list -->
-                <div class="col-md-6 col-sm-6 col-xs-12">
-                    <div class="x_panel">
-                        <div class="x_title">
-                            <h3>To Do List <small>Sample tasks</small></h3>
-                        </div>
-                        <div class="x_content">
-
-                            <div class="">
-                                <ul class="to_do">
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Schedule meeting with new client </p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Create email address for new intern</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Have IT fix the network printer</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Copy backups to offsite location</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Food truck fixie locavors mcsweeney</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Food truck fixie locavors mcsweeney</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Create email address for new intern</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Have IT fix the network printer</p>
-                                    </li>
-                                    <li>
-                                        <p>
-                                            <input type="checkbox" class="flat"> Copy backups to offsite location</p>
-                                    </li>
-                                </ul>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <!-- End to do list -->
-
-                <!-- start of weather widget -->
-                <div class="col-md-6 col-sm-6 col-xs-12">
-                    <div class="x_panel">
-                        <div class="x_title">
-                            <h3>Daily active users <small>Sessions</small></h3>
-                        </div>
-                        <div class="x_content">
-                            <div class="row">
-                                <div class="col-sm-12">
-                                    <div class="temperature"><b>Monday</b>, 07:30 AM
-                                        <span>F</span>
-                                        <span><b>C</b></span>
-                                    </div>
-                                </div>
-                            </div>
-                            <div class="row">
-                                <div class="col-sm-4">
-                                    <div class="weather-icon">
-                                        <canvas height="84" width="84" id="partly-cloudy-day"></canvas>
-                                    </div>
-                                </div>
-                                <div class="col-sm-8">
-                                    <div class="weather-text">
-                                        <h3>Texas <br><i>Partly Cloudy Day</i></h3>
-                                    </div>
-                                </div>
-                            </div>
-                            <div class="col-sm-12">
-                                <div class="weather-text pull-right">
-                                    <h3 class="degrees">23</h3>
-                                </div>
-                            </div>
-
-                            <div class="clearfix"></div>
-
-                            <div class="row weather-days">
-                                <div class="col-sm-2">
-                                    <div class="daily-weather">
-                                        <h2 class="day">Mon</h2>
-                                        <h3 class="degrees">25</h3>
-                                        <canvas id="clear-day" width="32" height="32"></canvas>
-                                        <h5>15 <i>km/h</i></h5>
-                                    </div>
-                                </div>
-                                <div class="col-sm-2">
-                                    <div class="daily-weather">
-                                        <h2 class="day">Tue</h2>
-                                        <h3 class="degrees">25</h3>
-                                        <canvas height="32" width="32" id="rain"></canvas>
-                                        <h5>12 <i>km/h</i></h5>
-                                    </div>
-                                </div>
-                                <div class="col-sm-2">
-                                    <div class="daily-weather">
-                                        <h2 class="day">Wed</h2>
-                                        <h3 class="degrees">27</h3>
-                                        <canvas height="32" width="32" id="snow"></canvas>
-                                        <h5>14 <i>km/h</i></h5>
-                                    </div>
-                                </div>
-                                <div class="col-sm-2">
-                                    <div class="daily-weather">
-                                        <h2 class="day">Thu</h2>
-                                        <h3 class="degrees">28</h3>
-                                        <canvas height="32" width="32" id="sleet"></canvas>
-                                        <h5>15 <i>km/h</i></h5>
-                                    </div>
-                                </div>
-                                <div class="col-sm-2">
-                                    <div class="daily-weather">
-                                        <h2 class="day">Fri</h2>
-                                        <h3 class="degrees">28</h3>
-                                        <canvas height="32" width="32" id="wind"></canvas>
-                                        <h5>11 <i>km/h</i></h5>
-                                    </div>
-                                </div>
-                                <div class="col-sm-2">
-                                    <div class="daily-weather">
-                                        <h2 class="day">Sat</h2>
-                                        <h3 class="degrees">26</h3>
-                                        <canvas height="32" width="32" id="cloudy"></canvas>
-                                        <h5>10 <i>km/h</i></h5>
-                                    </div>
-                                </div>
-                                <div class="clearfix"></div>
-                            </div>
-                        </div>
-                    </div>
-
+                    <div class="x_panel" ui-view="cacheGroupsContent"></div>
                 </div>
-                <!-- end of weather widget -->
             </div>
         </div>
     </div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
index 2b887f7..b1e1312 100644
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
@@ -23,17 +23,20 @@ module.exports = angular.module('trafficOps.private.monitor.dashboard', [])
         $stateProvider
             .state('trafficOps.private.monitor.dashboard', {
                 url: '/dashboard',
+                abstract: true,
                 views: {
                     monitorContent: {
                         templateUrl: 'modules/private/monitor/dashboard/dashboard.tpl.html',
                         controller: 'DashboardController',
                         resolve: {
-                            changeLogs: function(changeLogService) {
-                                return [];
-                                // return changeLogService.getChangeLogs({ limit: 6 });
-                            },
                             cacheGroupHealth: function(cacheGroupService) {
                                 return cacheGroupService.getCacheGroupHealth();
+                            },
+                            cdns: function(cdnService) {
+                                return cdnService.getCDNs();
+                            },
+                            currentStats: function(cdnService) {
+                                return cdnService.getCurrentStats();
                             }
                         }
 

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/view/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/view/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/view/index.js
new file mode 100644
index 0000000..3076a70
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/view/index.js
@@ -0,0 +1,53 @@
+module.exports = angular.module('trafficOps.private.monitor.dashboard.view', [])
+	.config(function($stateProvider, $urlRouterProvider) {
+		$stateProvider
+			.state('trafficOps.private.monitor.dashboard.view', {
+				url: '',
+				views: {
+					cacheGroupsContent: {
+						templateUrl: 'common/modules/widget/cacheGroups/widget.cacheGroups.tpl.html',
+						controller: 'WidgetCacheGroupsController',
+						resolve: {
+							cacheGroupHealth: function() {
+								// this is already defined in a parent template that shares the $scope
+								return null;
+							}
+						}
+					},
+					capacityContent: {
+						templateUrl: 'common/modules/widget/capacity/widget.capacity.tpl.html',
+						controller: 'WidgetCapacityController'
+					},
+					cdnChartContent: {
+						templateUrl: 'common/modules/widget/cdnChart/widget.cdnChart.tpl.html',
+						controller: 'WidgetCDNChartController',
+						resolve: {
+							cdn: function() {
+								// the controller will take care of fetching the cdn
+								return null;
+							}
+						}
+					},
+					changeLogsContent: {
+						templateUrl: 'common/modules/widget/changeLogs/widget.changeLogs.tpl.html',
+						controller: 'WidgetChangeLogsController',
+						resolve: {
+							changeLogs: function(changeLogService) {
+								return changeLogService.getChangeLogs({ limit: 5 });
+							}
+						}
+					},
+					routingContent: {
+						templateUrl: 'common/modules/widget/routing/widget.routing.tpl.html',
+						controller: 'WidgetRoutingController',
+						resolve: {
+							routing: function() {
+								return [];
+							}
+						}
+					},
+				}
+			})
+		;
+		$urlRouterProvider.otherwise('/');
+	});

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/scripts/shared-libs.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/scripts/shared-libs.js b/traffic_ops/experimental/ui/app/src/scripts/shared-libs.js
index 87e28cb..06c68f2 100644
--- a/traffic_ops/experimental/ui/app/src/scripts/shared-libs.js
+++ b/traffic_ops/experimental/ui/app/src/scripts/shared-libs.js
@@ -45,6 +45,14 @@ require('restangular');
 // jquery
 require('jquery');
 
+// flot charts
+require('jquery-flot');
+require('jquery-flot-pie');
+require('jquery-flot-stack');
+require('jquery-flot-time');
+require('jquery-flot-tooltip');
+require('jquery-flot-axislabels');
+
 // misc
 require('es5-shim');
 require('json3');

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/styles/main.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/styles/main.scss b/traffic_ops/experimental/ui/app/src/styles/main.scss
index c79d6bd..b981edb 100755
--- a/traffic_ops/experimental/ui/app/src/styles/main.scss
+++ b/traffic_ops/experimental/ui/app/src/styles/main.scss
@@ -33,6 +33,8 @@ $fa-font-path: "../assets/fonts";
 @import "../common/modules/navigation/navigation";
 @import "../common/modules/table/table";
 @import "../common/modules/release/release";
+@import "../common/modules/widget/capacity/widget.capacity";
+@import "../common/modules/widget/cdnChart/widget.cdnChart";
 
 // public
 @import "../modules/public/login/login";

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/app/src/styles/theme.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/styles/theme.scss b/traffic_ops/experimental/ui/app/src/styles/theme.scss
index 8de46f6..f78a16d 100644
--- a/traffic_ops/experimental/ui/app/src/styles/theme.scss
+++ b/traffic_ops/experimental/ui/app/src/styles/theme.scss
@@ -1715,7 +1715,7 @@ span.right {
 }
 @media (min-width: 768px) {
   .tile_count .tile_stats_count .count {
-    font-size: 40px
+    font-size: 30px
   }
 }
 @media (min-width: 992px) and (max-width: 1100px) {

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a81c975a/traffic_ops/experimental/ui/grunt/browserify2.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/grunt/browserify2.js b/traffic_ops/experimental/ui/grunt/browserify2.js
index 9bb4376..2528df4 100644
--- a/traffic_ops/experimental/ui/grunt/browserify2.js
+++ b/traffic_ops/experimental/ui/grunt/browserify2.js
@@ -44,6 +44,36 @@ module.exports = {
                                 'json3/lib/json3.min.js',
                                 'restangular/dist/restangular.min.js'
                             ]
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.js' ],
+                        rename: function () { return 'jquery-flot.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.pie.js' ],
+                        rename: function () { return 'jquery-flot-pie.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.stack.js' ],
+                        rename: function () { return 'jquery-flot-stack.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.time.js' ],
+                        rename: function () { return 'jquery-flot-time.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot.tooltip/js/jquery.flot.tooltip.min.js' ],
+                        rename: function () { return 'jquery-flot-tooltip.min.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot-axislabels/jquery.flot.axislabels.js' ],
+                        rename: function () { return 'jquery-flot-axislabels.js'; }
                     }
                 ]
             }
@@ -75,6 +105,36 @@ module.exports = {
                                 'json3/lib/json3.js',
                                 'restangular/dist/restangular.js'
                             ]
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.js' ],
+                        rename: function () { return 'jquery-flot.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.pie.js' ],
+                        rename: function () { return 'jquery-flot-pie.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.stack.js' ],
+                        rename: function () { return 'jquery-flot-stack.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot/jquery.flot.time.js' ],
+                        rename: function () { return 'jquery-flot-time.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot.tooltip/js/jquery.flot.tooltip.js' ],
+                        rename: function () { return 'jquery-flot-tooltip.js'; }
+                    },
+                    {
+                        cwd: '<%= globalConfig.app %>/bower_components/',
+                        src: [ 'flot-axislabels/jquery.flot.axislabels.js' ],
+                        rename: function () { return 'jquery-flot-axislabels.js'; }
                     }
                 ]
             }



[3/5] incubator-trafficcontrol git commit: adds dashboard page

Posted by da...@apache.org.
adds 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/848c0c8e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/848c0c8e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/848c0c8e

Branch: refs/heads/master
Commit: 848c0c8e05c5373793724ac2e331bf0ee5eb53f9
Parents: a53c064
Author: Jeremy Mitchell <mi...@gmail.com>
Authored: Wed May 3 15:30:34 2017 -0600
Committer: Dan Kirkwood <da...@gmail.com>
Committed: Mon May 8 13:21:54 2017 -0600

----------------------------------------------------------------------
 .../monitor/dashboard/DashboardController.js    |  28 +-
 .../private/monitor/dashboard/_dashboard.scss   |  46 ++
 .../monitor/dashboard/dashboard.tpl.html        | 546 ++++++++++++++++++-
 .../modules/private/monitor/dashboard/index.js  |  12 +-
 traffic_ops/experimental/ui/bower.json          |   3 +
 5 files changed, 631 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/848c0c8e/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 f6d611f..2abe702 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,8 +17,32 @@
  * under the License.
  */
 
-var DashboardController = function($scope) {
+var DashboardController = function(changeLogs, cacheGroupHealth, $scope, locationUtils) {
+
+	$scope.changeLogs = changeLogs;
+
+	$scope.getRelativeTime = function(date) {
+		return moment(date).fromNow();
+	};
+
+	$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);
+	};
+
 };
 
-DashboardController.$inject = ['$scope'];
+DashboardController.$inject = ['changeLogs', 'cacheGroupHealth', '$scope', 'locationUtils'];
 module.exports = DashboardController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/848c0c8e/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
index d57b9c6..99435c4 100644
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
@@ -14,3 +14,49 @@
  limitations under the License.
 
 */
+
+#cache-groups-outer-container {
+
+  #cacheGroupsContainer {
+    max-height: 452px;
+    margin-bottom: 0;
+
+    .list-group-item {
+      background-color: transparent;
+    }
+
+    .cache-group-health {
+      height: 45px;
+
+      .cache-groups-table {
+        margin-top: -10px;
+        border-style: none;
+
+        td {
+          border-top: none !important;
+          padding: 12px 8px !important;
+        }
+
+      }
+
+    }
+
+  }
+
+  .cache-groups-pagination {
+    margin: 0 0 10px 0;
+    float: left;
+  }
+
+  .cache-group-search-form {
+    float: right;
+    width: 250px;
+    margin-bottom: 10px;
+  }
+
+}
+
+#cacheGroupsLoadingContainer {
+  height: 555px;
+  background-color: transparent;
+}

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/848c0c8e/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
index cc3c2fc..ffee368 100644
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
@@ -17,4 +17,548 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-<h3>Dashboard</h3>
+<script src="../../../../../../../../../traffic_portal/app/src/modules/private/deliveryService/view/overview/DeliveryServiceViewOverviewController.js"></script>
+<div role="main">
+    <!-- top tiles -->
+    <div class="row tile_count">
+        <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
+            <span class="count_top"><i class="fa fa-user"></i> Total Users</span>
+            <div class="count">2500</div>
+            <span class="count_bottom"><i class="green">4% </i> From last Week</span>
+        </div>
+        <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
+            <span class="count_top"><i class="fa fa-clock-o"></i> Average Time</span>
+            <div class="count">123.50</div>
+            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>3% </i> From last Week</span>
+        </div>
+        <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
+            <span class="count_top"><i class="fa fa-user"></i> Total Males</span>
+            <div class="count green">2,500</div>
+            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>34% </i> From last Week</span>
+        </div>
+        <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
+            <span class="count_top"><i class="fa fa-user"></i> Total Females</span>
+            <div class="count">4,567</div>
+            <span class="count_bottom"><i class="red"><i class="fa fa-sort-desc"></i>12% </i> From last Week</span>
+        </div>
+        <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
+            <span class="count_top"><i class="fa fa-user"></i> Total Collections</span>
+            <div class="count">2,315</div>
+            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>34% </i> From last Week</span>
+        </div>
+        <div class="col-md-2 col-sm-4 col-xs-6 tile_stats_count">
+            <span class="count_top"><i class="fa fa-user"></i> Total Connections</span>
+            <div class="count">7,325</div>
+            <span class="count_bottom"><i class="green"><i class="fa fa-sort-asc"></i>34% </i> From last Week</span>
+        </div>
+    </div>
+    <!-- /top tiles -->
+
+    <div class="row">
+        <div class="col-md-12 col-sm-12 col-xs-12">
+            <div class="dashboard_graph">
+
+                <div class="row x_title">
+                    <div class="col-md-6">
+                        <h3>Network Activities <small>Graph title sub-title</small></h3>
+                    </div>
+                    <div class="col-md-6">
+                        <div id="reportrange" class="pull-right" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc">
+                            <i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
+                            <span>December 30, 2014 - January 28, 2015</span> <b class="caret"></b>
+                        </div>
+                    </div>
+                </div>
+
+                <div class="col-md-9 col-sm-9 col-xs-12">
+                    <div id="chart_plot_01" class="demo-placeholder"></div>
+                </div>
+                <div class="col-md-3 col-sm-3 col-xs-12 bg-white">
+                    <div class="x_title">
+                        <h3>Top Campaign Performance</h3>
+                        <div class="clearfix"></div>
+                    </div>
+
+                    <div class="col-md-12 col-sm-12 col-xs-6">
+                        <div>
+                            <p>Facebook Campaign</p>
+                            <div class="">
+                                <div class="progress progress_sm" style="width: 76%;">
+                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="80"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div>
+                            <p>Twitter Campaign</p>
+                            <div class="">
+                                <div class="progress progress_sm" style="width: 76%;">
+                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="60"></div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="col-md-12 col-sm-12 col-xs-6">
+                        <div>
+                            <p>Conventional Media</p>
+                            <div class="">
+                                <div class="progress progress_sm" style="width: 76%;">
+                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="40"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div>
+                            <p>Bill boards</p>
+                            <div class="">
+                                <div class="progress progress_sm" style="width: 76%;">
+                                    <div class="progress-bar bg-green" role="progressbar" data-transitiongoal="50"></div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+
+                </div>
+
+                <div class="clearfix"></div>
+            </div>
+        </div>
+
+    </div>
+    <br />
+
+    <div class="row">
+
+
+        <div class="col-md-4 col-sm-4 col-xs-12">
+            <div class="x_panel tile fixed_height_320">
+                <div class="x_title">
+                    <h3>App Versions</h3>
+                </div>
+                <div class="x_content">
+                    <h4>App Usage across versions</h4>
+                    <div class="widget_summary">
+                        <div class="w_left w_25">
+                            <span>0.1.5.2</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: 66%;">
+                                    <span class="sr-only">60% Complete</span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="w_right w_20">
+                            <span>123k</span>
+                        </div>
+                        <div class="clearfix"></div>
+                    </div>
+
+                    <div class="widget_summary">
+                        <div class="w_left w_25">
+                            <span>0.1.5.3</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: 45%;">
+                                    <span class="sr-only">60% Complete</span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="w_right w_20">
+                            <span>53k</span>
+                        </div>
+                        <div class="clearfix"></div>
+                    </div>
+                    <div class="widget_summary">
+                        <div class="w_left w_25">
+                            <span>0.1.5.4</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: 25%;">
+                                    <span class="sr-only">60% Complete</span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="w_right w_20">
+                            <span>23k</span>
+                        </div>
+                        <div class="clearfix"></div>
+                    </div>
+                    <div class="widget_summary">
+                        <div class="w_left w_25">
+                            <span>0.1.5.5</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>3k</span>
+                        </div>
+                        <div class="clearfix"></div>
+                    </div>
+                    <div class="widget_summary">
+                        <div class="w_left w_25">
+                            <span>0.1.5.6</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: 2%;">
+                                    <span class="sr-only">60% Complete</span>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="w_right w_20">
+                            <span>1k</span>
+                        </div>
+                        <div class="clearfix"></div>
+                    </div>
+
+                </div>
+            </div>
+        </div>
+
+        <div class="col-md-4 col-sm-4 col-xs-12">
+            <div class="x_panel tile fixed_height_320 overflow_hidden">
+                <div class="x_title">
+                    <h3>Device Usage</h3>
+                </div>
+                <div class="x_content">
+                    <table class="" style="width:100%">
+                        <tr>
+                            <th style="width:37%;">
+                                <p>Top 5</p>
+                            </th>
+                            <th>
+                                <div class="col-lg-7 col-md-7 col-sm-7 col-xs-7">
+                                    <p class="">Device</p>
+                                </div>
+                                <div class="col-lg-5 col-md-5 col-sm-5 col-xs-5">
+                                    <p class="">Progress</p>
+                                </div>
+                            </th>
+                        </tr>
+                        <tr>
+                            <td>
+                                <canvas class="canvasDoughnut" height="140" width="140" style="margin: 15px 10px 10px 0"></canvas>
+                            </td>
+                            <td>
+                                <table class="tile_info">
+                                    <tr>
+                                        <td>
+                                            <p><i class="fa fa-square blue"></i>IOS </p>
+                                        </td>
+                                        <td>30%</td>
+                                    </tr>
+                                    <tr>
+                                        <td>
+                                            <p><i class="fa fa-square green"></i>Android </p>
+                                        </td>
+                                        <td>10%</td>
+                                    </tr>
+                                    <tr>
+                                        <td>
+                                            <p><i class="fa fa-square purple"></i>Blackberry </p>
+                                        </td>
+                                        <td>20%</td>
+                                    </tr>
+                                    <tr>
+                                        <td>
+                                            <p><i class="fa fa-square aero"></i>Symbian </p>
+                                        </td>
+                                        <td>15%</td>
+                                    </tr>
+                                    <tr>
+                                        <td>
+                                            <p><i class="fa fa-square red"></i>Others </p>
+                                        </td>
+                                        <td>30%</td>
+                                    </tr>
+                                </table>
+                            </td>
+                        </tr>
+                    </table>
+                </div>
+            </div>
+        </div>
+
+
+        <div class="col-md-4 col-sm-4 col-xs-12">
+            <div class="x_panel tile fixed_height_320">
+                <div class="x_title">
+                    <h3>Quick Settings</h3>
+                </div>
+                <div class="x_content">
+                    <div class="dashboard-widget-content">
+                        <ul class="quick-list">
+                            <li><i class="fa fa-calendar-o"></i><a href="#">Settings</a>
+                            </li>
+                            <li><i class="fa fa-bars"></i><a href="#">Subscription</a>
+                            </li>
+                            <li><i class="fa fa-bar-chart"></i><a href="#">Auto Renewal</a> </li>
+                            <li><i class="fa fa-line-chart"></i><a href="#">Achievements</a>
+                            </li>
+                            <li><i class="fa fa-bar-chart"></i><a href="#">Auto Renewal</a> </li>
+                            <li><i class="fa fa-line-chart"></i><a href="#">Achievements</a>
+                            </li>
+                            <li><i class="fa fa-area-chart"></i><a href="#">Logout</a>
+                            </li>
+                        </ul>
+
+                        <div class="sidebar-widget">
+                            <h4>Profile Completion</h4>
+                            <canvas width="150" height="80" id="chart_gauge_01" class="" style="width: 160px; height: 100px;"></canvas>
+                            <div class="goal-wrapper">
+                                <span id="gauge-text" class="gauge-value pull-left">0</span>
+                                <span class="gauge-value pull-left">%</span>
+                                <span id="goal-text" class="goal-value pull-right">100%</span>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+    </div>
+
+
+    <div class="row">
+        <div class="col-md-4 col-sm-4 col-xs-12">
+            <div class="x_panel">
+                <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>
+            </div>
+        </div>
+
+
+        <div class="col-md-8 col-sm-8 col-xs-12">
+
+
+
+            <div class="row">
+
+                <div class="col-md-12 col-sm-12 col-xs-12">
+                    <div class="x_panel">
+                        <div class="x_title">
+                            <h3>Cache Groups <small>100% online</small></h3>
+                        </div>
+                        <div class="x_content">
+                            <div id="cache-groups-outer-container">
+                                <div id="cacheGroupsOverallHealth">
+                                    <h4 class="cache-groups-online">Cache Groups <small>{{locationHealth.totalOnline/(locationHealth.totalOnline + locationHealth.totalOffline) | percentFilter}} online</small></h4>
+                                </div>
+                                <div id="cacheGroupsContainer">
+                                    <div class="alert alert-info" ng-show="(locationHealth.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="location in locationHealth.cachegroups | orderBy:[onlinePercent, 'name'] | filter:search:strict | offsetFilter:(currentLocationPage-1)*locationsPerPage | limitTo:locationsPerPage">
+                                            <div class="row">
+                                                <table class="cache-groups-table table">
+                                                    <tbody>
+                                                    <tr>
+                                                        <td class="col-lg-4 col-md-4 col-sm-4">{{location.name}}</td>
+                                                        <td class="col-lg-4 col-md-4 col-sm-4">{{location.online/(location.online + location.offline) | percentFilter}} Online</td>
+                                                        <td class="col-lg-4 col-md-4 col-sm-4">{{location.online}} Servers Online | {{location.offline}} Servers Offline</td>
+                                                    </tr>
+                                                    </tbody>
+                                                </table>
+                                            </div>
+                                        </a>
+                                    </div>
+                                </div>
+                                <div>
+                                    <div ng-show="(locationHealth.cachegroups | filter:search:strict).length > 0">
+                                        <uib-pagination class="cache-groups-pagination pagination-md" boundary-links="true" max-size="2" total-items="(locationHealth.cachegroups | filter:search:strict).length" items-per-page="locationsPerPage" ng-model="currentLocationPage" previous-text="&lsaquo;" next-text="&rsaquo;" first-text="&laquo;" last-text="&raquo;"></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>
+                    </div>
+                </div>
+
+            </div>
+            <div class="row">
+
+
+                <!-- Start to do list -->
+                <div class="col-md-6 col-sm-6 col-xs-12">
+                    <div class="x_panel">
+                        <div class="x_title">
+                            <h3>To Do List <small>Sample tasks</small></h3>
+                        </div>
+                        <div class="x_content">
+
+                            <div class="">
+                                <ul class="to_do">
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Schedule meeting with new client </p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Create email address for new intern</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Have IT fix the network printer</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Copy backups to offsite location</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Food truck fixie locavors mcsweeney</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Food truck fixie locavors mcsweeney</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Create email address for new intern</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Have IT fix the network printer</p>
+                                    </li>
+                                    <li>
+                                        <p>
+                                            <input type="checkbox" class="flat"> Copy backups to offsite location</p>
+                                    </li>
+                                </ul>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <!-- End to do list -->
+
+                <!-- start of weather widget -->
+                <div class="col-md-6 col-sm-6 col-xs-12">
+                    <div class="x_panel">
+                        <div class="x_title">
+                            <h3>Daily active users <small>Sessions</small></h3>
+                        </div>
+                        <div class="x_content">
+                            <div class="row">
+                                <div class="col-sm-12">
+                                    <div class="temperature"><b>Monday</b>, 07:30 AM
+                                        <span>F</span>
+                                        <span><b>C</b></span>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="row">
+                                <div class="col-sm-4">
+                                    <div class="weather-icon">
+                                        <canvas height="84" width="84" id="partly-cloudy-day"></canvas>
+                                    </div>
+                                </div>
+                                <div class="col-sm-8">
+                                    <div class="weather-text">
+                                        <h3>Texas <br><i>Partly Cloudy Day</i></h3>
+                                    </div>
+                                </div>
+                            </div>
+                            <div class="col-sm-12">
+                                <div class="weather-text pull-right">
+                                    <h3 class="degrees">23</h3>
+                                </div>
+                            </div>
+
+                            <div class="clearfix"></div>
+
+                            <div class="row weather-days">
+                                <div class="col-sm-2">
+                                    <div class="daily-weather">
+                                        <h2 class="day">Mon</h2>
+                                        <h3 class="degrees">25</h3>
+                                        <canvas id="clear-day" width="32" height="32"></canvas>
+                                        <h5>15 <i>km/h</i></h5>
+                                    </div>
+                                </div>
+                                <div class="col-sm-2">
+                                    <div class="daily-weather">
+                                        <h2 class="day">Tue</h2>
+                                        <h3 class="degrees">25</h3>
+                                        <canvas height="32" width="32" id="rain"></canvas>
+                                        <h5>12 <i>km/h</i></h5>
+                                    </div>
+                                </div>
+                                <div class="col-sm-2">
+                                    <div class="daily-weather">
+                                        <h2 class="day">Wed</h2>
+                                        <h3 class="degrees">27</h3>
+                                        <canvas height="32" width="32" id="snow"></canvas>
+                                        <h5>14 <i>km/h</i></h5>
+                                    </div>
+                                </div>
+                                <div class="col-sm-2">
+                                    <div class="daily-weather">
+                                        <h2 class="day">Thu</h2>
+                                        <h3 class="degrees">28</h3>
+                                        <canvas height="32" width="32" id="sleet"></canvas>
+                                        <h5>15 <i>km/h</i></h5>
+                                    </div>
+                                </div>
+                                <div class="col-sm-2">
+                                    <div class="daily-weather">
+                                        <h2 class="day">Fri</h2>
+                                        <h3 class="degrees">28</h3>
+                                        <canvas height="32" width="32" id="wind"></canvas>
+                                        <h5>11 <i>km/h</i></h5>
+                                    </div>
+                                </div>
+                                <div class="col-sm-2">
+                                    <div class="daily-weather">
+                                        <h2 class="day">Sat</h2>
+                                        <h3 class="degrees">26</h3>
+                                        <canvas height="32" width="32" id="cloudy"></canvas>
+                                        <h5>10 <i>km/h</i></h5>
+                                    </div>
+                                </div>
+                                <div class="clearfix"></div>
+                            </div>
+                        </div>
+                    </div>
+
+                </div>
+                <!-- end of weather widget -->
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/848c0c8e/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
index 041dc19..2b887f7 100644
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
@@ -26,7 +26,17 @@ module.exports = angular.module('trafficOps.private.monitor.dashboard', [])
                 views: {
                     monitorContent: {
                         templateUrl: 'modules/private/monitor/dashboard/dashboard.tpl.html',
-                        controller: 'DashboardController'
+                        controller: 'DashboardController',
+                        resolve: {
+                            changeLogs: function(changeLogService) {
+                                return [];
+                                // return changeLogService.getChangeLogs({ limit: 6 });
+                            },
+                            cacheGroupHealth: function(cacheGroupService) {
+                                return cacheGroupService.getCacheGroupHealth();
+                            }
+                        }
+
                     }
                 }
             })

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/848c0c8e/traffic_ops/experimental/ui/bower.json
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/bower.json b/traffic_ops/experimental/ui/bower.json
index a09ab06..6364104 100755
--- a/traffic_ops/experimental/ui/bower.json
+++ b/traffic_ops/experimental/ui/bower.json
@@ -14,6 +14,9 @@
         "angular-jwt": "0.0.9",
         "bootstrap-sass-official": "3.3.6",
         "es5-shim": "4.5.6",
+        "flot": "0.8.3",
+        "flot.tooltip": "0.8.7",
+        "flot-axislabels": "release-2.0.1",
         "font-awesome": "4.5.0",
         "jquery": "2.0.0",
         "json3": "3.3.2",


[5/5] incubator-trafficcontrol git commit: This closes #549

Posted by da...@apache.org.
This closes #549


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/38c9da30
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/38c9da30
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/38c9da30

Branch: refs/heads/master
Commit: 38c9da30cf49e449edddda8fdda55d625bdc6d78
Parents: a81c975
Author: Dan Kirkwood <da...@gmail.com>
Authored: Mon May 8 13:22:56 2017 -0600
Committer: Dan Kirkwood <da...@gmail.com>
Committed: Mon May 8 13:22:56 2017 -0600

----------------------------------------------------------------------

----------------------------------------------------------------------



[2/5] incubator-trafficcontrol git commit: hooks up dashboard page

Posted by da...@apache.org.
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="&lsaquo;" next-text="&rsaquo;" first-text="&laquo;" last-text="&raquo;"></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;


[4/5] incubator-trafficcontrol git commit: moved a couple pages around; button and tooltip changes as well

Posted by da...@apache.org.
moved a couple pages around; button and tooltip changes as well


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/a53c064c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/a53c064c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/a53c064c

Branch: refs/heads/master
Commit: a53c064ccb2999eac401856aff0be09d75d2fcc6
Parents: 26d3ca0
Author: Jeremy Mitchell <mi...@gmail.com>
Authored: Wed May 3 08:19:09 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      |  6 +-
 .../ui/app/src/common/api/AuthService.js        |  2 +-
 .../form/cacheGroup/form.cacheGroup.tpl.html    |  7 ++-
 .../modules/form/cdn/FormCDNController.js       |  4 --
 .../common/modules/form/cdn/form.cdn.tpl.html   | 12 ++--
 .../FormDeliveryServiceController.js            |  6 +-
 .../form.deliveryService.tpl.html               |  9 +--
 .../modules/form/profile/form.profile.tpl.html  |  6 +-
 .../modules/form/server/form.server.tpl.html    | 11 +++-
 .../modules/navigation/navigation.tpl.html      |  5 +-
 .../table.cacheGroupParameters.tpl.html         |  4 +-
 .../table/cdnServers/table.cdnServers.tpl.html  | 32 +++++-----
 .../table.deliveryServiceJobs.tpl.html          |  2 +-
 .../table.deliveryServiceRegexes.tpl.html       |  2 +-
 .../table.deliveryServiceServers.tpl.html       |  4 +-
 .../table.parameterProfiles.tpl.html            |  4 +-
 .../table.profileParameters.tpl.html            |  4 +-
 .../table.serverDeliveryServices.tpl.html       |  4 +-
 .../table/servers/table.servers.tpl.html        |  5 +-
 .../table.userDeliveryServices.tpl.html         |  4 +-
 .../monitor/dashboard/DashboardController.js    | 24 ++++++++
 .../private/monitor/dashboard/_dashboard.scss   | 16 +++++
 .../monitor/dashboard/dashboard.tpl.html        | 20 +++++++
 .../modules/private/monitor/dashboard/index.js  | 35 +++++++++++
 .../monitor/dashboards/DashboardsController.js  | 24 --------
 .../private/monitor/dashboards/_dashboards.scss | 16 -----
 .../monitor/dashboards/dashboards.tpl.html      | 22 -------
 .../modules/private/monitor/dashboards/index.js | 35 -----------
 .../dashboards/map/DashboardsMapController.js   | 62 --------------------
 .../monitor/dashboards/map/_dashboards.map.scss | 21 -------
 .../dashboards/map/dashboards.map.tpl.html      | 37 ------------
 .../private/monitor/dashboards/map/index.js     | 43 --------------
 .../three/DashboardsThreeController.js          | 24 --------
 .../dashboards/three/_dashboards.three.scss     | 16 -----
 .../dashboards/three/dashboards.three.tpl.html  | 20 -------
 .../private/monitor/dashboards/three/index.js   | 35 -----------
 .../dashboards/two/DashboardsTwoController.js   | 24 --------
 .../monitor/dashboards/two/_dashboards.two.scss | 16 -----
 .../dashboards/two/dashboards.two.tpl.html      | 20 -------
 .../private/monitor/dashboards/two/index.js     | 35 -----------
 .../private/monitor/map/MapController.js        | 62 ++++++++++++++++++++
 .../src/modules/private/monitor/map/_map.scss   | 21 +++++++
 .../src/modules/private/monitor/map/index.js    | 43 ++++++++++++++
 .../modules/private/monitor/map/map.tpl.html    | 37 ++++++++++++
 .../experimental/ui/app/src/styles/main.scss    |  6 +-
 45 files changed, 326 insertions(+), 521 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/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 820ee28..ac4a99d 100644
--- a/traffic_ops/experimental/ui/app/src/app.js
+++ b/traffic_ops/experimental/ui/app/src/app.js
@@ -154,10 +154,8 @@ var trafficOps = angular.module('trafficOps', [
         require('./modules/private/monitor').name,
 
         // dashboards
-        require('./modules/private/monitor/dashboards').name,
-        require('./modules/private/monitor/dashboards/map').name,
-        require('./modules/private/monitor/dashboards/two').name,
-        require('./modules/private/monitor/dashboards/three').name,
+        require('./modules/private/monitor/dashboard').name,
+        require('./modules/private/monitor/map').name,
 
         // common modules
         require('./common/modules/dialog/confirm').name,

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/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 da534fa..d1b7c9c 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/dashboards/map');
+                        $location.url('/monitor/map');
                     }
                 },
                 function(fault) {

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/cacheGroup/form.cacheGroup.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/cacheGroup/form.cacheGroup.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/form/cacheGroup/form.cacheGroup.tpl.html
index 5275808..40beeb4 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/cacheGroup/form.cacheGroup.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/cacheGroup/form.cacheGroup.tpl.html
@@ -24,14 +24,17 @@ under the License.
             <li class="active">{{cacheGroupName}}</li>
         </ol>
         <div class="pull-right" ng-show="!settings.isNew">
-            <button class="btn btn-primary" title="Queue {{cacheGroup.name}} server updates" ng-click="confirmQueueServerUpdates(cacheGroup)"><i class="fa fa-flag"></i></button>
-            <button class="btn btn-primary" title="Clear {{cacheGroup.name}} server updates" ng-click="confirmClearServerUpdates(cacheGroup)"><i class="fa fa-ban"></i></button>
+            <button class="btn btn-primary" title="Queue Server Updates" ng-click="confirmQueueServerUpdates(cacheGroup)"><i class="fa fa-flag"></i></button>
+            <button class="btn btn-primary" title="Clear Server Updates" ng-click="confirmClearServerUpdates(cacheGroup)"><i class="fa fa-ban"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
                     More
                     <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
+                    <li role="menuitem"><a ng-click="confirmQueueServerUpdates(cacheGroup)">Queue Server Updates</a></li>
+                    <li role="menuitem"><a ng-click="confirmQueueServerUpdates(cacheGroup)">Clear Server Updates</a></li>
+                    <li class="divider"></li>
                     <li role="menuitem"><a ng-click="viewAsns()">View ASNs</a></li>
                     <li role="menuitem"><a ng-click="viewParams()">View Parameters</a></li>
                     <li role="menuitem"><a ng-click="viewServers()">View Servers</a></li>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/FormCDNController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/FormCDNController.js b/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/FormCDNController.js
index d76772d..41f8147 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/FormCDNController.js
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/FormCDNController.js
@@ -34,10 +34,6 @@ var FormCDNController = function(cdn, $scope, $location, formUtils, stringUtils,
         alert('not hooked up yet: manageSSL for cdn');
     };
 
-    $scope.cachegroupHealth = function() {
-        alert('not hooked up yet: cachegroupHealth for CDN');
-    };
-
     $scope.queueServerUpdates = function(cdn) {
         cdnService.queueServerUpdates(cdn.id);
     };

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/form.cdn.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/form.cdn.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/form.cdn.tpl.html
index 661c3a8..8528350 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/form.cdn.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/cdn/form.cdn.tpl.html
@@ -24,19 +24,23 @@ under the License.
             <li class="active">{{cdnName}}</li>
         </ol>
         <div class="pull-right" ng-show="!settings.isNew">
-            <button class="btn btn-primary" title="Snapshot {{cdn.name}} config" ng-click="manageSnapshots()"><i class="fa fa-camera"></i></button>
-            <button class="btn btn-primary" title="Queue {{cdn.name}} server updates" ng-click="queueServerUpdates(cdn)"><i class="fa fa-flag"></i></button>
-            <button class="btn btn-primary" title="Cancel {{cdn.name}} server updates" ng-click="clearServerUpdates(cdn)"><i class="fa fa-ban"></i></button>
+            <button class="btn btn-primary" title="Snapshot {{cdn.name}} Config" ng-click="manageSnapshots()"><i class="fa fa-camera"></i></button>
+            <button class="btn btn-primary" title="Queue {{cdn.name}} Server Updates" ng-click="queueServerUpdates(cdn)"><i class="fa fa-flag"></i></button>
+            <button class="btn btn-primary" title="Clear {{cdn.name}} Server Updates" ng-click="clearServerUpdates(cdn)"><i class="fa fa-ban"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
                     More
                     <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
+                    <li role="menuitem"><a ng-click="manageSnapshots()">Snapshot {{cdn.name}} Config</a></li>
+                    <li class="divider"></li>
+                    <li role="menuitem"><a ng-click="queueServerUpdates(cdn)">Queue {{cdn.name}} Server Updates</a></li>
+                    <li role="menuitem"><a ng-click="clearServerUpdates(cdn)">Clear {{cdn.name}} Server Updates</a></li>
+                    <li class="divider"></li>
                     <li role="menuitem"><a ng-click="manageDNSSEC()">Manage DNSSEC Keys</a></li>
                     <li role="menuitem"><a ng-click="manageSSL()">Manage SSL Keys</a></li>
                     <li class="divider"></li>
-                    <li role="menuitem"><a ng-click="cachegroupHealth()">View Cachegroup Health</a></li>
                     <li role="menuitem"><a ng-click="viewDeliveryServices()">View Delivery Services</a></li>
                     <li role="menuitem"><a ng-click="viewProfiles()">View Profiles</a></li>
                     <li role="menuitem"><a ng-click="viewServers()">View Servers</a></li>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js b/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
index 30a2378..e1e7cbe 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/FormDeliveryServiceController.js
@@ -122,7 +122,7 @@ var FormDeliveryServiceController = function(deliveryService, $scope, $location,
         { value: 4, label: "4 - Latch on Failover" }
     ];
 
-    $scope.assignServers = function() {
+    $scope.viewServers = function() {
         $location.path($location.path() + '/servers');
     };
 
@@ -130,10 +130,6 @@ var FormDeliveryServiceController = function(deliveryService, $scope, $location,
         $location.path($location.path() + '/regexes');
     };
 
-    $scope.cachegroupHealth = function() {
-        alert('not hooked up yet: cachegroupHealth for DS');
-    };
-
     $scope.viewJobs = function() {
         $location.path($location.path() + '/jobs');
     };

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/form.deliveryService.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/form.deliveryService.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/form.deliveryService.tpl.html
index 3cddf16..fed8aa3 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/form.deliveryService.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/deliveryService/form.deliveryService.tpl.html
@@ -24,21 +24,18 @@ under the License.
             <li class="active">{{deliveryServiceName}}</li>
         </ol>
         <div class="pull-right" role="group" ng-show="!settings.isNew">
-            <button class="btn btn-primary" title="Assign Caches" ng-click="assignServers()"><i class="fa fa-server"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
                     More
                     <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
-                    <li role="menuitem"><a ng-click="viewRegexes()">Edit Delivery Service Regexes</a></li>
-                    <li class="divider"></li>
-                    <li role="menuitem"><a ng-click="viewJobs()">View Invalidate Content Jobs</a></li>
-                    <li class="divider"></li>
                     <li role="menuitem"><a ng-click="manageSslKeys()">Manage SSL Keys</a></li>
                     <li role="menuitem"><a ng-click="manageUrlSigKeys()">Manage URL Sig Keys</a></li>
                     <li class="divider"></li>
-                    <li role="menuitem"><a ng-click="cachegroupHealth()">View Cachegroup Health</a></li>
+                    <li role="menuitem"><a ng-click="viewServers()">View Servers</a></li>
+                    <li role="menuitem"><a ng-click="viewRegexes()">View Regexes</a></li>
+                    <li role="menuitem"><a ng-click="viewJobs()">View Invalidate Content Jobs</a></li>
                     <li role="menuitem"><a ng-click="viewStaticDnsEntries()">View Static DNS Entries</a></li>
                 </ul>
             </div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/profile/form.profile.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/profile/form.profile.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/form/profile/form.profile.tpl.html
index f2d5450..00c41a7 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/profile/form.profile.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/profile/form.profile.tpl.html
@@ -24,15 +24,15 @@ under the License.
             <li class="active">{{profileName}}</li>
         </ol>
         <div class="pull-right" role="group" ng-show="!settings.isNew">
-            <button class="btn btn-primary" title="View Parameters" ng-click="viewParams()"><i class="fa fa-clone"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
                     More
                     <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
-                    <li role="menuitem"><a ng-click="viewDeliveryServices()" ng-show="profile.type == 'DS_PROFILE'">View Delivery Services</a></li>
-                    <li role="menuitem"><a ng-click="viewServers()" ng-show="profile.type != 'DS_PROFILE'">View Servers</a></li>
+                    <li role="menuitem"><a ng-click="viewDeliveryServices()" ng-if="profile.type == 'DS_PROFILE'">View Delivery Services</a></li>
+                    <li role="menuitem"><a ng-click="viewParams()">View Parameters</a></li>
+                    <li role="menuitem"><a ng-click="viewServers()" ng-if="profile.type != 'DS_PROFILE'">View Servers</a></li>
                     <li class="divider"></li>
                     <li role="menuitem"><a ng-click="cloneProfile()">Clone Profile</a></li>
                     <li role="menuitem"><a ng-click="exportProfile()">Export Profile</a></li>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/form/server/form.server.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/form/server/form.server.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/form/server/form.server.tpl.html
index 7cf7d03..c5e4a54 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/form/server/form.server.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/form/server/form.server.tpl.html
@@ -26,16 +26,21 @@ under the License.
         <div class="pull-right" role="group" ng-show="!settings.isNew">
             <button class="btn btn-primary" ng-click="confirmStatusUpdate()">Update Status</button>
             <!--<button class="btn btn-success" ng-click="onlineServer()">Online Server</button>-->
-            <button class="btn btn-primary" title="Queue {{server.hostName}} updates" ng-show="!server.updPending" ng-click="queueServerUpdates(server)"><i class="fa fa-flag"></i></button>
-            <button class="btn btn-primary" title="Cancel {{server.hostName}} updates" ng-show="server.updPending" ng-click="clearServerUpdates(server)"><i class="fa fa-ban"></i></button>
+            <button class="btn btn-primary" title="Queue Server Updates" ng-show="!server.updPending" ng-click="queueServerUpdates(server)"><i class="fa fa-flag"></i></button>
+            <button class="btn btn-primary" title="Clear Server Updates" ng-show="server.updPending" ng-click="clearServerUpdates(server)"><i class="fa fa-ban"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
                     More
                     <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
+                    <li ng-show="!server.updPending"><a ng-click="queueServerUpdates(server)">Queue Server Updates</a></li>
+                    <li ng-show="server.updPending"><a ng-click="clearServerUpdates(server)">Clear Server Updates</a></li>
+                    <li class="divider"></li>
+                    <li><a ng-click="confirmStatusUpdate()">Update Status</a></li>
+                    <li class="divider"></li>
                     <li><a ng-click="viewDeliveryServices()">View Delivery Services</a></li>
-                    <li><a ng-click="viewConfig()">View Server Config Files</a></li>
+                    <li><a ng-click="viewConfig()">View Config Files</a></li>
                 </ul>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/navigation/navigation.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/navigation/navigation.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/navigation/navigation.tpl.html
index 3e0821d..7a1bb82 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/navigation/navigation.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/navigation/navigation.tpl.html
@@ -27,9 +27,8 @@ under the License.
             <ul class="nav side-menu">
                 <li class="side-menu-category"><a href="javascript:void(0);"><i class="fa fa-bar-chart"></i> Monitor <span class="fa fa-chevron-down"></span></a>
                     <ul class="nav child_menu" style="display: none">
-                        <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficOps.private.monitor.dashboards.map')}"><a ng-click="navigateToPath('/monitor/dashboards/map')">Map</a></li>
-                        <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficOps.private.monitor.dashboards.two')}"><a ng-click="navigateToPath('/monitor/dashboards/two')">Graphs</a></li>
-                        <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficOps.private.monitor.dashboards.three')}"><a ng-click="navigateToPath('/monitor/dashboards/three')">Dashboard 3</a></li>
+                        <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficOps.private.monitor.dashboard')}"><a ng-click="navigateToPath('/monitor/dashboard')">Dashboard</a></li>
+                        <li class="side-menu-category-item" ng-class="{'current-page': isState('trafficOps.private.monitor.map')}"><a ng-click="navigateToPath('/monitor/map')">Map</a></li>
                     </ul>
                 </li>
                 <li class="side-menu-category"><a href="javascript:void(0);"><i class="fa fa-cog"></i> Configure <span class="fa fa-chevron-down"></span></a>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/cacheGroupParameters/table.cacheGroupParameters.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/cacheGroupParameters/table.cacheGroupParameters.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/cacheGroupParameters/table.cacheGroupParameters.tpl.html
index 4a66d01..6ab49f0 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/cacheGroupParameters/table.cacheGroupParameters.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/cacheGroupParameters/table.cacheGroupParameters.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Parameters</li>
         </ol>
         <div class="pull-right" role="group" ng-show="!settings.isNew">
-            <button class="btn btn-primary" title="Add Parameter" ng-click="addParameter()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Link Parameter to Cache Group" ng-click="addParameter()"><i class="fa fa-link"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>
@@ -48,7 +48,7 @@ under the License.
                 <td>{{::parameter.name}}</td>
                 <td>{{::parameter.configFile}}</td>
                 <td>{{::parameter.value}}</td>
-                <td><button type="button" class="btn btn-link" title="Remove from Cache Group" ng-click="removeParameter()"><i class="fa fa-trash-o"></i></button></td>
+                <td><button type="button" class="btn btn-link" title="Remove from Cache Group" ng-click="removeParameter()"><i class="fa fa-chain-broken"></i></button></td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/cdnServers/table.cdnServers.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/cdnServers/table.cdnServers.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/cdnServers/table.cdnServers.tpl.html
index 8d4e6b0..4401e1e 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/cdnServers/table.cdnServers.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/cdnServers/table.cdnServers.tpl.html
@@ -21,12 +21,12 @@ under the License.
     <div class="x_title">
         <ol class="breadcrumb pull-left">
             <li><a ng-click="navigateToPath('/admin/cdns')">CDNs</a></li>
-            <li><a ng-click="navigateToPath('/admin/cdns/' + cdn.id)">{{cdn.name}}</a></li>
+            <li><a ng-click="navigateToPath('/admin/cdns/' + cdn.id)">{{::cdn.name}}</a></li>
             <li class="active">Servers</li>
         </ol>
         <div class="pull-right">
-            <button class="btn btn-primary" title="Queue {{cdn.name}} server updates" ng-click="queueServerUpdates(cdn)"><i class="fa fa-flag"></i></button>
-            <button class="btn btn-primary" title="Cancel {{cdn.name}} server updates" ng-click="clearServerUpdates(cdn)"><i class="fa fa-ban"></i></button>
+            <button class="btn btn-primary" title="Queue {{::cdn.name}} Server Updates" ng-click="queueServerUpdates(cdn)"><i class="fa fa-flag"></i></button>
+            <button class="btn btn-primary" title="Cancel {{::cdn.name}} Server Updates" ng-click="clearServerUpdates(cdn)"><i class="fa fa-ban"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>
@@ -57,21 +57,21 @@ under the License.
                     <i class="fa fa-flag" ng-if="server.updPending"></i>
                     <i class="fa fa-ban" ng-if="!server.updPending"></i>
                 </td>
-                <td>{{server.hostName}}</td>
-                <td>{{server.domainName}}</td>
-                <td>{{server.cdnName}}</td>
-                <td>{{server.cachegroup}}</td>
-                <td>{{server.type}}</td>
-                <td>{{server.physLocation}}</td>
-                <td>{{server.ipAddress}}</td>
-                <td>{{server.ip6Address}}</td>
+                <td>{{::server.hostName}}</td>
+                <td>{{::server.domainName}}</td>
+                <td>{{::server.cdnName}}</td>
+                <td>{{::server.cachegroup}}</td>
+                <td>{{::server.type}}</td>
+                <td>{{::server.physLocation}}</td>
+                <td>{{::server.ipAddress}}</td>
+                <td>{{::server.ip6Address}}</td>
                 <td>
-                    <span ng-if="!isOffline(server.status)">{{server.status}}</span>
-                    <span ng-if="isOffline(server.status)" uib-popover="{{offlineReason(server)}}" popover-title="Offline Reason" popover-trigger="mouseenter" popover-placement="bottom" popover-append-to-body="true">{{server.status}}</span>
+                    <span ng-if="!isOffline(server.status)">{{::server.status}}</span>
+                    <span ng-if="isOffline(server.status)" uib-popover="{{::offlineReason(server)}}" popover-title="Offline Reason" popover-trigger="mouseenter" popover-placement="bottom" popover-append-to-body="true">{{::server.status}}</span>
                 </td>
-                <td>{{server.profile}}</td>
-                <td>{{server.iloIpAddress}}</td>
-                <td>{{server.iloIpGateway}}</td>
+                <td>{{::server.profile}}</td>
+                <td>{{::server.iloIpAddress}}</td>
+                <td>{{::server.iloIpGateway}}</td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceJobs/table.deliveryServiceJobs.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceJobs/table.deliveryServiceJobs.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceJobs/table.deliveryServiceJobs.tpl.html
index ba214d5..d43f3a4 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceJobs/table.deliveryServiceJobs.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceJobs/table.deliveryServiceJobs.tpl.html
@@ -37,7 +37,7 @@ under the License.
             <tr class="headings">
                 <th>assetUrl</th>
                 <th>parameters</th>
-                <th>start</th>
+                <th>start (UTC)</th>
                 <th>createdBy</th>
             </tr>
             </thead>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceRegexes/table.deliveryServiceRegexes.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceRegexes/table.deliveryServiceRegexes.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceRegexes/table.deliveryServiceRegexes.tpl.html
index 9c6045a..5e7f1f3 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceRegexes/table.deliveryServiceRegexes.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceRegexes/table.deliveryServiceRegexes.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Regexes</li>
         </ol>
         <div class="pull-right">
-            <button class="btn btn-primary" title="Create Regex" ng-click="createRegex(deliveryService.id)"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Create Delivery Service Regex" ng-click="createRegex(deliveryService.id)"><i class="fa fa-plus"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceServers/table.deliveryServiceServers.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceServers/table.deliveryServiceServers.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceServers/table.deliveryServiceServers.tpl.html
index 3a91cde..2fa9e92 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceServers/table.deliveryServiceServers.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/deliveryServiceServers/table.deliveryServiceServers.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Servers</li>
         </ol>
         <div class="pull-right">
-            <button class="btn btn-primary" title="Add Server" ng-click="addServer()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Link Server to Delivery Service" ng-click="addServer()"><i class="fa fa-link"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>
@@ -72,7 +72,7 @@ under the License.
                 <td>{{::server.profile}}</td>
                 <td>{{::server.iloIpAddress}}</td>
                 <td>{{::server.iloIpGateway}}</td>
-                <td><button type="button" class="btn btn-link" title="Remove Server from Delivery Service" ng-show="server.type == 'EDGE'" ng-click="removeServer(deliveryService.id, server.id)"><i class="fa fa-chain-broken"></i></button></td>
+                <td><button type="button" class="btn btn-link" title="Unlink Server from Delivery Service" ng-show="server.type == 'EDGE'" ng-click="removeServer(deliveryService.id, server.id)"><i class="fa fa-chain-broken"></i></button></td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/parameterProfiles/table.parameterProfiles.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/parameterProfiles/table.parameterProfiles.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/parameterProfiles/table.parameterProfiles.tpl.html
index 975f4cd..51f00e8 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/parameterProfiles/table.parameterProfiles.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/parameterProfiles/table.parameterProfiles.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Profiles</li>
         </ol>
         <div class="pull-right">
-            <button class="btn btn-primary" title="Add Profile" ng-click="addProfile()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Link Profile to Parameter" ng-click="addProfile()"><i class="fa fa-link"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>
@@ -44,7 +44,7 @@ under the License.
             <tr ng-repeat="parameterProfile in ::parameterProfiles">
                 <td>{{::parameterProfile.name}}</td>
                 <td>{{::parameterProfile.description}}</td>
-                <td><button type="button" class="btn btn-link" title="Remove Profile from Parameter" ng-click="removeProfile(parameterProfile.id)"><i class="fa fa-chain-broken"></i></button></td>
+                <td><button type="button" class="btn btn-link" title="Unlink Profile from Parameter" ng-click="removeProfile(parameterProfile.id)"><i class="fa fa-chain-broken"></i></button></td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/profileParameters/table.profileParameters.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/profileParameters/table.profileParameters.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/profileParameters/table.profileParameters.tpl.html
index 1f70b10..3a36e8b 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/profileParameters/table.profileParameters.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/profileParameters/table.profileParameters.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Parameters</li>
         </ol>
         <div class="pull-right">
-            <button class="btn btn-primary" title="Add Parameter" ng-click="addParameter()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Link Parameter to Profile" ng-click="addParameter()"><i class="fa fa-link"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>
@@ -48,7 +48,7 @@ under the License.
                 <td>{{::parameter.name}}</td>
                 <td>{{::parameter.configFile}}</td>
                 <td>{{::parameter.value}}</td>
-                <td><button type="button" class="btn btn-link" title="Remove Parameter from Profile" ng-click="removeParameter(parameter.id)"><i class="fa fa-chain-broken"></i></button></td>
+                <td><button type="button" class="btn btn-link" title="Unlink Parameter from Profile" ng-click="removeParameter(parameter.id)"><i class="fa fa-chain-broken"></i></button></td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/serverDeliveryServices/table.serverDeliveryServices.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/serverDeliveryServices/table.serverDeliveryServices.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/serverDeliveryServices/table.serverDeliveryServices.tpl.html
index 6bcd542..a9efa33 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/serverDeliveryServices/table.serverDeliveryServices.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/serverDeliveryServices/table.serverDeliveryServices.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Delivery Services</li>
         </ol>
         <div class="pull-right" role="group">
-            <button class="btn btn-primary" title="Add Delivery Service" ng-click="addDeliveryService()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Link Delivery Service to Server" ng-click="addDeliveryService()"><i class="fa fa-link"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
@@ -77,7 +77,7 @@ under the License.
                 <td>{{::deliveryService.protocol}}</td>
                 <td>{{::deliveryService.ipv6RoutingEnabled}}</td>
                 <td>{{::deliveryService.rangeRequestHandling}}</td>
-                <td><button type="button" class="btn btn-link" title="Remove Delivery Service from Server" ng-click="removeDeliveryService(deliveryService.id, server.id)"><i class="fa fa-chain-broken"></i></button></td>
+                <td><button type="button" class="btn btn-link" title="Unlink Delivery Service from Server" ng-click="removeDeliveryService(deliveryService.id, server.id)"><i class="fa fa-chain-broken"></i></button></td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/servers/table.servers.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/servers/table.servers.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/servers/table.servers.tpl.html
index c449343..a7be280 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/servers/table.servers.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/servers/table.servers.tpl.html
@@ -24,8 +24,6 @@ under the License.
         </ol>
         <div class="pull-right">
             <button class="btn btn-primary" title="Create Server" ng-click="createServer()"><i class="fa fa-plus"></i></button>
-            <button class="btn btn-primary" title="Queue server updates" ng-click="confirmQueueServerUpdates()"><i class="fa fa-flag"></i></button>
-            <button class="btn btn-primary" title="Clear server updates" ng-click="confirmClearServerUpdates()"><i class="fa fa-ban"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
             <div class="btn-group" role="group" uib-dropdown is-open="more.isopen">
                 <button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">
@@ -33,6 +31,9 @@ under the License.
                     <span class="caret"></span>
                 </button>
                 <ul class="dropdown-menu-right dropdown-menu" uib-dropdown-menu>
+                    <li role="menuitem"><a ng-click="confirmQueueServerUpdates()">Queue Server Updates</a></li>
+                    <li role="menuitem"><a ng-click="confirmClearServerUpdates()">Clear Server Updates</a></li>
+                    <li class="divider"></li>
                     <li role="menuitem"><a ng-click="uploadServerCSV()">Upload Bulk CSV</a></li>
                 </ul>
             </div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/common/modules/table/userDeliveryServices/table.userDeliveryServices.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/common/modules/table/userDeliveryServices/table.userDeliveryServices.tpl.html b/traffic_ops/experimental/ui/app/src/common/modules/table/userDeliveryServices/table.userDeliveryServices.tpl.html
index a0de18e..e5c5a90 100644
--- a/traffic_ops/experimental/ui/app/src/common/modules/table/userDeliveryServices/table.userDeliveryServices.tpl.html
+++ b/traffic_ops/experimental/ui/app/src/common/modules/table/userDeliveryServices/table.userDeliveryServices.tpl.html
@@ -25,7 +25,7 @@ under the License.
             <li class="active">Delivery Services</li>
         </ol>
         <div class="pull-right">
-            <button class="btn btn-primary" title="Add Delivery Service" ng-click="addDeliveryService()"><i class="fa fa-plus"></i></button>
+            <button class="btn btn-primary" title="Link Delivery Service to User" ng-click="addDeliveryService()"><i class="fa fa-link"></i></button>
             <button class="btn btn-default" title="Refresh" ng-click="refresh()"><i class="fa fa-refresh"></i></button>
         </div>
         <div class="clearfix"></div>
@@ -46,7 +46,7 @@ under the License.
                 <td>{{::deliveryService.xmlId}}</td>
                 <td>{{::deliveryService.orgServerFqdn}}</td>
                 <td>{{::deliveryService.cdnName}}</td>
-                <td><button type="button" class="btn btn-link" title="Remove Delivery Service" ng-click="removeDeliveryService()"><i class="fa fa-trash-o"></i></button></td>
+                <td><button type="button" class="btn btn-link" title="Unlink Delivery Service from User" ng-click="removeDeliveryService()"><i class="fa fa-chain-broken"></i></button></td>
             </tr>
             </tbody>
         </table>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/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
new file mode 100644
index 0000000..f6d611f
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/DashboardController.js
@@ -0,0 +1,24 @@
+/*
+ * 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 DashboardController = function($scope) {
+};
+
+DashboardController.$inject = ['$scope'];
+module.exports = DashboardController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
new file mode 100644
index 0000000..d57b9c6
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/_dashboard.scss
@@ -0,0 +1,16 @@
+/*
+
+
+ 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.
+
+*/

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
new file mode 100644
index 0000000..cc3c2fc
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/dashboard.tpl.html
@@ -0,0 +1,20 @@
+<!--
+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.
+-->
+
+<h3>Dashboard</h3>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
new file mode 100644
index 0000000..041dc19
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboard/index.js
@@ -0,0 +1,35 @@
+/*
+ * 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.private.monitor.dashboard', [])
+    .controller('DashboardController', require('./DashboardController'))
+    .config(function($stateProvider, $urlRouterProvider) {
+        $stateProvider
+            .state('trafficOps.private.monitor.dashboard', {
+                url: '/dashboard',
+                views: {
+                    monitorContent: {
+                        templateUrl: 'modules/private/monitor/dashboard/dashboard.tpl.html',
+                        controller: 'DashboardController'
+                    }
+                }
+            })
+        ;
+        $urlRouterProvider.otherwise('/');
+    });

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/DashboardsController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/DashboardsController.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/DashboardsController.js
deleted file mode 100644
index ab114c2..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/DashboardsController.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 DashboardsController = function($scope) {
-};
-
-DashboardsController.$inject = ['$scope'];
-module.exports = DashboardsController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/_dashboards.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/_dashboards.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/_dashboards.scss
deleted file mode 100644
index d57b9c6..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/_dashboards.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-
-
- 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.
-
-*/

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/dashboards.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/dashboards.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/dashboards.tpl.html
deleted file mode 100644
index 3a7a94a..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/dashboards.tpl.html
+++ /dev/null
@@ -1,22 +0,0 @@
-<!--
-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.
--->
-
-<div id="dashboardsContainer">
-    <div ui-view="dashboardsContent"></div>
-</div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/index.js
deleted file mode 100644
index aa6994a..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.private.monitor.dashboards', [])
-    .controller('DashboardsController', require('./DashboardsController'))
-    .config(function($stateProvider, $urlRouterProvider) {
-        $stateProvider
-            .state('trafficOps.private.monitor.dashboards', {
-                url: '/dashboards',
-                abstract: true,
-                views: {
-                    monitorContent: {
-                        templateUrl: 'modules/private/monitor/dashboards/dashboards.tpl.html',
-                        controller: 'DashboardsController'
-                    }
-                }
-            });
-        $urlRouterProvider.otherwise('/');
-    });

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/DashboardsMapController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/DashboardsMapController.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/DashboardsMapController.js
deleted file mode 100644
index 192804b..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/DashboardsMapController.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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 DashboardsMapController = function(cacheGroups, cacheGroupHealth, $scope, NgMap) {
-
-	$scope.map = NgMap.getMap('cgMap');
-
-	$scope.cacheGroups = [];
-
-	$scope.parentCg = function(cg) {
-		return cg.parent ? cg.parent : 'None'
-	};
-
-	$scope.secondaryParentCg = function(cg) {
-		return cg.secondaryParent ? cg.secondaryParent : 'None'
-	};
-
-	var massageCacheGroups = function() {
-		var cgHealthCacheGroups = cacheGroupHealth.cachegroups,
-			cgHealth;
-		_.each(cacheGroups, function(cg) {
-			cgHealth = _.find(cgHealthCacheGroups, function(cghcg){ return cghcg.name == cg.name });
-			$scope.cacheGroups.push(
-				{
-					name: cg.name,
-					parent: cg.parentCachegroupName,
-					secondaryParent: cg.secondaryParentCachegroupName,
-					pos: [ cg.latitude, cg.longitude ],
-					type: cg.typeName,
-					offline: cgHealth ? cgHealth.offline : '-',
-					online: cgHealth ? cgHealth.online : '-'
-				}
-			);
-		});
-	};
-
-	var init = function() {
-		massageCacheGroups();
-	};
-	init();
-
-
-};
-
-DashboardsMapController.$inject = ['cacheGroups', 'cacheGroupHealth', '$scope', 'NgMap'];
-module.exports = DashboardsMapController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/_dashboards.map.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/_dashboards.map.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/_dashboards.map.scss
deleted file mode 100644
index 72d3f1b..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/_dashboards.map.scss
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-
-
- 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.
-
-*/
-ng-map {
-  position: absolute;
-  width:100%;
-  height:100%;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/dashboards.map.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/dashboards.map.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/dashboards.map.tpl.html
deleted file mode 100644
index 671e0d7..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/dashboards.map.tpl.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
-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.
--->
-
-<div class="angular-google-map-container" map-lazy-load="https://maps.google.com/maps/api/js">
-    <ng-map id="cgMap" zoom="5" center="[41,-87]">
-        <marker ng-repeat="cg in ::cacheGroups"
-                position="{{::cg.pos}}"
-                on-click="map.showInfoWindow(event, cg.name)"></marker>
-        <info-window id="{{::cg.name}}" ng-repeat="cg in ::cacheGroups">
-            <div>
-                <h3>{{::cg.name}} ({{::cg.type}})</h3>
-                <hr>
-                <h5>Coordinates: {{::cg.pos}}</h5>
-                <h5>1st Parent: {{::parentCg(cg)}}</h5>
-                <h5>2nd Parent: {{::secondaryParentCg(cg)}}</h5>
-                <h5>Online Caches: {{::cg.online}}</h5>
-                <h5>Offline Caches: {{::cg.offline}}</h5>
-            </div>
-        </info-window>
-    </ng-map>
-</div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/index.js
deleted file mode 100644
index 74fe61a..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/map/index.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.private.monitor.dashboards.map', [])
-    .controller('DashboardsMapController', require('./DashboardsMapController'))
-    .config(function($stateProvider, $urlRouterProvider) {
-        $stateProvider
-            .state('trafficOps.private.monitor.dashboards.map', {
-                url: '/map',
-                views: {
-                    dashboardsContent: {
-                        templateUrl: 'modules/private/monitor/dashboards/map/dashboards.map.tpl.html',
-                        controller: 'DashboardsMapController',
-                        resolve: {
-                            cacheGroups: function(cacheGroupService) {
-                                return cacheGroupService.getCacheGroups();
-                            },
-                            cacheGroupHealth: function(cacheGroupService) {
-                                return cacheGroupService.getCacheGroupHealth();
-                            }
-                        }
-                    }
-                }
-            })
-        ;
-        $urlRouterProvider.otherwise('/');
-    });

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/DashboardsThreeController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/DashboardsThreeController.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/DashboardsThreeController.js
deleted file mode 100644
index 65317c2..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/DashboardsThreeController.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 DashboardsThreeController = function($scope) {
-};
-
-DashboardsThreeController.$inject = ['$scope'];
-module.exports = DashboardsThreeController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/_dashboards.three.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/_dashboards.three.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/_dashboards.three.scss
deleted file mode 100644
index d57b9c6..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/_dashboards.three.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-
-
- 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.
-
-*/

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/dashboards.three.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/dashboards.three.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/dashboards.three.tpl.html
deleted file mode 100644
index 5fc86dd..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/dashboards.three.tpl.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-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.
--->
-
-<h3>Dashboard #3</h3>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/index.js
deleted file mode 100644
index 28fe8c4..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/three/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.private.monitor.dashboards.three', [])
-    .controller('DashboardsThreeController', require('./DashboardsThreeController'))
-    .config(function($stateProvider, $urlRouterProvider) {
-        $stateProvider
-            .state('trafficOps.private.monitor.dashboards.three', {
-                url: '/three',
-                views: {
-                    dashboardsContent: {
-                        templateUrl: 'modules/private/monitor/dashboards/three/dashboards.three.tpl.html',
-                        controller: 'DashboardsThreeController'
-                    }
-                }
-            })
-        ;
-        $urlRouterProvider.otherwise('/');
-    });

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/DashboardsTwoController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/DashboardsTwoController.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/DashboardsTwoController.js
deleted file mode 100644
index 5cc6f60..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/DashboardsTwoController.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 DashboardsTwoController = function($scope) {
-};
-
-DashboardsTwoController.$inject = ['$scope'];
-module.exports = DashboardsTwoController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/_dashboards.two.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/_dashboards.two.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/_dashboards.two.scss
deleted file mode 100644
index d57b9c6..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/_dashboards.two.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
-
-
- 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.
-
-*/

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/dashboards.two.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/dashboards.two.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/dashboards.two.tpl.html
deleted file mode 100644
index de5ac12..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/dashboards.two.tpl.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-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.
--->
-
-<h3>Dashboard #2</h3>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/index.js
deleted file mode 100644
index 7e14aed..0000000
--- a/traffic_ops/experimental/ui/app/src/modules/private/monitor/dashboards/two/index.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.private.monitor.dashboards.two', [])
-    .controller('DashboardsTwoController', require('./DashboardsTwoController'))
-    .config(function($stateProvider, $urlRouterProvider) {
-        $stateProvider
-            .state('trafficOps.private.monitor.dashboards.two', {
-                url: '/two',
-                views: {
-                    dashboardsContent: {
-                        templateUrl: 'modules/private/monitor/dashboards/two/dashboards.two.tpl.html',
-                        controller: 'DashboardsTwoController'
-                    }
-                }
-            })
-        ;
-        $urlRouterProvider.otherwise('/');
-    });

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/MapController.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/MapController.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/MapController.js
new file mode 100644
index 0000000..a85185d
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/MapController.js
@@ -0,0 +1,62 @@
+/*
+ * 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 MapController = function(cacheGroups, cacheGroupHealth, $scope, NgMap) {
+
+	$scope.map = NgMap.getMap('cgMap');
+
+	$scope.cacheGroups = [];
+
+	$scope.parentCg = function(cg) {
+		return cg.parent ? cg.parent : 'None'
+	};
+
+	$scope.secondaryParentCg = function(cg) {
+		return cg.secondaryParent ? cg.secondaryParent : 'None'
+	};
+
+	var massageCacheGroups = function() {
+		var cgHealthCacheGroups = cacheGroupHealth.cachegroups,
+			cgHealth;
+		_.each(cacheGroups, function(cg) {
+			cgHealth = _.find(cgHealthCacheGroups, function(cghcg){ return cghcg.name == cg.name });
+			$scope.cacheGroups.push(
+				{
+					name: cg.name,
+					parent: cg.parentCachegroupName,
+					secondaryParent: cg.secondaryParentCachegroupName,
+					pos: [ cg.latitude, cg.longitude ],
+					type: cg.typeName,
+					offline: cgHealth ? cgHealth.offline : '-',
+					online: cgHealth ? cgHealth.online : '-'
+				}
+			);
+		});
+	};
+
+	var init = function() {
+		massageCacheGroups();
+	};
+	init();
+
+
+};
+
+MapController.$inject = ['cacheGroups', 'cacheGroupHealth', '$scope', 'NgMap'];
+module.exports = MapController;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/_map.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/_map.scss b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/_map.scss
new file mode 100644
index 0000000..72d3f1b
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/_map.scss
@@ -0,0 +1,21 @@
+/*
+
+
+ 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.
+
+*/
+ng-map {
+  position: absolute;
+  width:100%;
+  height:100%;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/index.js
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/index.js b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/index.js
new file mode 100644
index 0000000..22083bb
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/index.js
@@ -0,0 +1,43 @@
+/*
+ * 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.private.monitor.map', [])
+    .controller('MapController', require('./MapController'))
+    .config(function($stateProvider, $urlRouterProvider) {
+        $stateProvider
+            .state('trafficOps.private.monitor.map', {
+                url: '/map',
+                views: {
+                    monitorContent: {
+                        templateUrl: 'modules/private/monitor/map/map.tpl.html',
+                        controller: 'MapController',
+                        resolve: {
+                            cacheGroups: function(cacheGroupService) {
+                                return cacheGroupService.getCacheGroups();
+                            },
+                            cacheGroupHealth: function(cacheGroupService) {
+                                return cacheGroupService.getCacheGroupHealth();
+                            }
+                        }
+                    }
+                }
+            })
+        ;
+        $urlRouterProvider.otherwise('/');
+    });

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/map.tpl.html
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/map.tpl.html b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/map.tpl.html
new file mode 100644
index 0000000..671e0d7
--- /dev/null
+++ b/traffic_ops/experimental/ui/app/src/modules/private/monitor/map/map.tpl.html
@@ -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.
+-->
+
+<div class="angular-google-map-container" map-lazy-load="https://maps.google.com/maps/api/js">
+    <ng-map id="cgMap" zoom="5" center="[41,-87]">
+        <marker ng-repeat="cg in ::cacheGroups"
+                position="{{::cg.pos}}"
+                on-click="map.showInfoWindow(event, cg.name)"></marker>
+        <info-window id="{{::cg.name}}" ng-repeat="cg in ::cacheGroups">
+            <div>
+                <h3>{{::cg.name}} ({{::cg.type}})</h3>
+                <hr>
+                <h5>Coordinates: {{::cg.pos}}</h5>
+                <h5>1st Parent: {{::parentCg(cg)}}</h5>
+                <h5>2nd Parent: {{::secondaryParentCg(cg)}}</h5>
+                <h5>Online Caches: {{::cg.online}}</h5>
+                <h5>Offline Caches: {{::cg.offline}}</h5>
+            </div>
+        </info-window>
+    </ng-map>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a53c064c/traffic_ops/experimental/ui/app/src/styles/main.scss
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/ui/app/src/styles/main.scss b/traffic_ops/experimental/ui/app/src/styles/main.scss
index 8a3c1c5..c79d6bd 100755
--- a/traffic_ops/experimental/ui/app/src/styles/main.scss
+++ b/traffic_ops/experimental/ui/app/src/styles/main.scss
@@ -60,10 +60,8 @@ $fa-font-path: "../assets/fonts";
 @import "../modules/private/monitor/monitor";
 
 // dashboards
-@import "../modules/private/monitor/dashboards/dashboards";
-@import "../modules/private/monitor/dashboards/map/dashboards.map";
-@import "../modules/private/monitor/dashboards/two/dashboards.two";
-@import "../modules/private/monitor/dashboards/three/dashboards.three";
+@import "../modules/private/monitor/dashboard/dashboard";
+@import "../modules/private/monitor/map/map";
 
 [ng-click] {
   cursor: pointer;