fix(dashboard): bugs in key browser and stats page.

Fixed key add, key delete bugs. More refactoring.
This commit is contained in:
Ed Rooth
2014-02-04 15:12:32 -08:00
parent 06f990236c
commit 4e21405647
12 changed files with 109 additions and 50 deletions

View File

@@ -19,16 +19,16 @@
<body>
<h1>etcd Dashboard</h1>
<div ng-view></div>
<div id="view-container" ng-view></div>
<div id="footer">
<div id="powered-by">Powered by <a href="https://github.com/coreos/etcd">etcd</a></div>
<div id="powered-by" class="text-center">Powered by <a href="https://github.com/coreos/etcd">etcd</a></div>
<div id="coreos-logo">
<a href="http://coreos.com"><img src="img/logo.svg"/></a>
</div>
</div>
<!-- build:js scripts/stats-modules.js -->
<!-- build:js scripts/modules.js -->
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-resource/angular-resource.js"></script>
@@ -41,6 +41,7 @@
<script src="bower_components/moment/moment.js"></script>
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/app.js -->
<script src="scripts/app.js"></script>
<script src="scripts/controllers/root.js"></script>
<script src="scripts/directives.js"></script>
@@ -52,11 +53,9 @@
<script src="scripts/common/services/prefix-url.js"></script>
<script src="scripts/common/directives/highlight.js"></script>
<script src="scripts/common/directives/enter.js"></script>
<!-- build:js({.tmp,app}) scripts/stats-scripts.js -->
<script src="scripts/vega.js"></script>
<script src="scripts/common/services/etcd.js"></script>
<!--<script src="scripts/controllers/stats.js"></script>-->
<script src="scripts/controllers/stats.js"></script>
<!-- endbuild -->
</body>

View File

@@ -27,10 +27,10 @@ app.config(function($routeProvider, $locationProvider, urlPrefix) {
controller: 'HomeCtrl',
templateUrl: prefixUrl('/views/home.html')
})
//.when(prefixUrl('/stats'), {
//controller: 'StatsCtrl',
//templateUrl: prefixUrl('/views/stats.html')
//})
.when(prefixUrl('/stats'), {
controller: 'StatsCtrl',
templateUrl: prefixUrl('/views/stats.html')
})
.when(prefixUrl('/browser'), {
controller: 'BrowserCtrl',
templateUrl: prefixUrl('/views/browser.html')

View File

@@ -1,11 +1,17 @@
'use strict';
angular.module('etcdControlPanel')
.directive('highlight', function() {
.directive('highlight', function(keyPrefix) {
return {
restrict: 'A',
restrict: 'E',
scope: {
highlightBase: '=',
highlightCurrent: '='
},
link: function(scope, element, attrs) {
if('#' + scope.etcdPath === attrs.href) {
var base = _.str.strRight(scope.highlightBase, keyPrefix),
current = _.str.trim(scope.highlightCurrent, '/');
if (base === current) {
element.parent().parent().addClass('etcd-selected');
}
}

View File

@@ -1,22 +1,39 @@
'use strict';
angular.module('etcdControlPanel')
.controller('BrowserCtrl', function ($scope, $location, $window, EtcdV2, keyPrefix, $, _, moment) {
.controller('BrowserCtrl', function ($scope, $window, EtcdV2, keyPrefix, $, _, moment) {
$scope.save = 'etcd-save-hide';
$scope.preview = 'etcd-preview-hide';
$scope.enableBack = true;
$scope.writingNew = false;
$scope.key = '';
$scope.key = null;
$scope.list = [];
// etcdPath is the path to the key that is currenly being looked at.
$scope.etcdPath = keyPrefix;
$scope.inputPath = keyPrefix;
$scope.resetInputPath = function() {
$scope.inputPath = $scope.etcdPath;
};
$scope.setActiveKey = function(key) {
$scope.etcdPath = keyPrefix + _.str.trim(key, '/');
$scope.resetInputPath();
};
$scope.$watch('etcdPath', function() {
$scope.stripPrefix = function(path) {
return _.str.strRight(path, keyPrefix);
};
$scope.onEnter = function() {
var path = $scope.stripPrefix($scope.inputPath);
if (path !== '') {
$scope.setActiveKey(path);
}
};
$scope.updateCurrentKey = function() {
function etcdPathKey() {
return pathKey($scope.etcdPath);
}
@@ -28,7 +45,6 @@ angular.module('etcdControlPanel')
}
return parts[1];
}
// Notify everyone of the update
localStorage.setItem('etcdPath', $scope.etcdPath);
$scope.enableBack = true;
@@ -36,9 +52,10 @@ angular.module('etcdControlPanel')
if ($scope.etcdPath === keyPrefix) {
$scope.enableBack = false;
}
$scope.key = EtcdV2.getKey(etcdPathKey($scope.etcdPath));
});
};
$scope.$watch('etcdPath', $scope.updateCurrentKey);
$scope.$watch('key', function() {
if ($scope.writingNew === true) {
@@ -68,20 +85,18 @@ angular.module('etcdControlPanel')
//back button click
$scope.back = function() {
$scope.etcdPath = $scope.key.getParent().path();
//$scope.syncLocation();
$scope.resetInputPath();
$scope.preview = 'etcd-preview-hide';
$scope.writingNew = false;
};
//$scope.syncLocation = function() {
//$location.path($scope.etcdPath);
//};
$scope.showSave = function() {
$scope.save = 'etcd-save-reveal';
};
$scope.saveData = function() {
$scope.setActiveKey($scope.stripPrefix($scope.inputPath));
$scope.updateCurrentKey();
// TODO: fixup etcd to allow for empty values
$scope.key.set($scope.singleValue || ' ').then(function(response) {
$scope.save = 'etcd-save-hide';
@@ -93,7 +108,9 @@ angular.module('etcdControlPanel')
});
};
$scope.deleteKey = function() {
$scope.deleteKey = function(key) {
$scope.setActiveKey(key);
$scope.updateCurrentKey();
$scope.key.deleteKey().then(function(response) {
//TODO: remove loader
$scope.save = 'etcd-save-hide';
@@ -128,9 +145,9 @@ angular.module('etcdControlPanel')
return $($window).height();
};
$scope.$watch($scope.getHeight, function() {
$('.etcd-body').css('height', $scope.getHeight()-45);
});
//$scope.$watch($scope.getHeight, function() {
////$('.etcd-container.etcd-browser etcd-body').css('height', $scope.getHeight()-45);
//});
$window.onresize = function(){
$scope.$apply();

View File

@@ -2,7 +2,7 @@
angular.module('etcdControlPanel')
.controller('StatsCtrl', ['$scope', 'EtcdV2', 'statsVega', function ($scope, EtcdV2, statsVega) {
.controller('StatsCtrl', function ($scope, $rootScope, $interval, EtcdV2, statsVega) {
$scope.graphContainer = '#latency';
$scope.graphVisibility = 'etcd-graph-show';
$scope.tableVisibility = 'etcd-table-hide';
@@ -74,10 +74,10 @@ angular.module('etcdControlPanel')
$scope.getWidth = function() {
return $(window).width();
};
$scope.$watch($scope.getHeight, function() {
$('.etcd-body').css('height', $scope.getHeight()-5);
readStats();
});
//$scope.$watch($scope.getHeight, function() {
////$('.etcd-container.etcd-stats .etcd-body').css('height', $scope.getHeight()-5);
//readStats();
//});
$scope.$watch($scope.getWidth, function() {
readStats();
});
@@ -85,12 +85,31 @@ angular.module('etcdControlPanel')
$scope.$apply();
};
// Update the graphs live
setInterval(function() {
readStats();
$scope.$apply();
}, 500);
}])
$scope.pollPromise = null;
$scope.startPolling = function() {
// Update the graphs live
if ($scope.pollPromise) {
return;
}
$scope.pollPromise = $interval(function() {
readStats();
}, 500);
};
$scope.stopPolling = function() {
$interval.cancel($scope.pollPromise);
$scope.pollPromise = null;
};
// Stop polling when navigating away from a view with this controller.
$rootScope.$on('$routeChangeStart', function () {
$scope.stopPolling();
});
$scope.startPolling();
})
/* statsVega returns the vega configuration for the stats dashboard */

View File

@@ -1,4 +1,10 @@
.etcd-container.etcd-browser {
width: 100%;
height: 500px;
}
.home-container .etcd-container.etcd-browser {
height: 400px;
}
.etcd-container.etcd-browser .etcd-header {

View File

@@ -16,6 +16,8 @@ body {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
margin: 20px 0;
height: 100%;
}
a {
@@ -167,8 +169,7 @@ h2 {
top: 0px;
left: 0px;
position: relative;
overflow-y: auto;
overflow-x: hidden;
overflow: hidden;
height: 100%;
width: 100%;
box-sizing: border-box;

View File

@@ -1,9 +1,14 @@
html {
height: 100%;
}
body {
background: #fafafa;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #333;
padding: 30px;
margin: 0px;
height: 100%;
}
h1 {
font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;

View File

@@ -1,8 +1,10 @@
.etcd-stats {
width: 100%; height: 400px;
.etcd-container.etcd-stats {
width: 100%;
height: 500px;
}
.etcd-container.etcd-stats {
.home-container .etcd-container.etcd-stats {
height: 400px;
}
.etcd-container.etcd-stats h2 {

View File

@@ -16,7 +16,7 @@
</a>
<a class="etcd-add" ng-click="add()"><img src="img/add.svg"/></a>
<div class="etcd-browser-path">
<input type="text" ng-model="etcdPath" ng-enter="syncLocation()" tabindex="888" />
<input type="text" ng-model="inputPath" ng-enter="onEnter()" tabindex="888" />
</div>
<button class="etcd-button etcd-button-small etcd-button-primary etcd-save" ng-click="saveData()">Save</button>
</div>
@@ -33,7 +33,9 @@
</thead>
<tbody>
<tr ng-repeat="key in list | orderBy:'key'">
<td><a ng-class="{true:'directory'}[key.dir]" ng-click="setActiveKey(key.key)" highlight>{{key.key}}</a></td>
<td>
<highlight ng-class="{true:'directory'}[key.dir]" ng-click="setActiveKey(key.key)" highlight-base="etcdPath" highlight-current="key.key">{{key.key}}</highlight>
</td>
<td ng-switch on="!!key.expiration" class="etcd-ttl">
<div ng-switch-when="true"><time relative datetime="{{key.expiration.substring(0, key.expiration.lastIndexOf('-'))}}"></time></div>
<div ng-switch-default class="etcd-ttl-none">&mdash;</div>
@@ -41,7 +43,7 @@
<td>
<div class="etcd-actions">
<div ng-switch on="!!key.dir">
<img class="etcd-delete" src="img/delete.svg" ng-switch-when="false" ng-click="deleteKey()" />
<img class="etcd-delete" src="img/delete.svg" ng-switch-when="false" ng-click="deleteKey(key.key)" />
<div ng-switch-when="true"></div>
</div>
</div>

View File

@@ -1,2 +1,4 @@
<!--<div ng-include="prefixUrl('/views/stats.html')" style="width: 100%; height: 400px;"></div>-->
<div ng-include="prefixUrl('/views/browser.html')" style="width: 100%; height: 400px;"></div>
<a href="stats">stats only</a>
<div ng-include="prefixUrl('/views/stats.html')" class="home-container"></div>
<a href="browser">browser only</a>
<div ng-include="prefixUrl('/views/browser.html')" class="home-container"></div>

View File

@@ -1,4 +1,4 @@
<div class="etcd-container etcd-stats {{columns}} {{tableVisibility}}">
<div ng-controller="StatsCtrl" class="etcd-container etcd-stats {{columns}} {{tableVisibility}}">
<div class="etcd-body">
<div class="etcd-format-selector">
<div class="etcd-selector-item etcd-selector-graph" ng-click="showGraph()">