web/vtctld: Implement topology browser.

This commit is contained in:
Anthony Yeh 2015-07-22 13:36:14 -07:00
Родитель 592d676f5c
Коммит 3ec559166c
5 изменённых файлов: 87 добавлений и 9 удалений

Просмотреть файл

@ -71,6 +71,12 @@ func HandleExplorer(name, url, templateName string, exp Explorer) {
panic(fmt.Sprintf("Only one Explorer can be registered in vtctld. Trying to register %q, but %q was already registered.", name, explorerName))
}
// Topo explorer API for client-side vtctld app.
handleCollection("topodata", func(r *http.Request) (interface{}, error) {
return exp.HandlePath(actionRepo, path.Clean(url+getItemPath(r.URL.Path)), r), nil
})
// Old server-side explorer.
explorer = exp
explorerName = name
indexContent.ToplevelLinks[name+" Explorer"] = url

Просмотреть файл

@ -61,3 +61,18 @@ md-toolbar h1 {
.card-table-row {
padding: 8px 0px 8px 0px;
}
.breadcrumb {
color: #E8EAF6;
background-color: #3F51B5;
padding: 0px 12px 0px 12px;
}
.breadcrumb md-icon {
color: #E8EAF6;
}
.breadcrumb-divider {
font-size: 1.5em;
font-weight: 900;
}

Просмотреть файл

@ -17,7 +17,8 @@ app.constant('routes', [
urlPattern: '/keyspaces/',
templateUrl: 'keyspaces.html',
controller: 'KeyspacesCtrl',
showInNav: true
showInNav: true,
icon: 'dashboard'
},
{
name: 'shard',
@ -34,7 +35,8 @@ app.constant('routes', [
urlPattern: '/schema/',
templateUrl: 'schema.html',
controller: 'SchemaCtrl',
showInNav: true
showInNav: true,
icon: 'storage'
},
{
name: 'topo',
@ -43,7 +45,8 @@ app.constant('routes', [
urlPattern: '/topo/:path*?',
templateUrl: 'topo.html',
controller: 'TopoCtrl',
showInNav: true
showInNav: true,
icon: 'folder'
},
]);
@ -247,8 +250,21 @@ app.controller('ShardCtrl', function($scope, $routeParams, $timeout,
app.controller('SchemaCtrl', function() {
});
app.controller('TopoCtrl', function($scope, $routeParams) {
$scope.path = $routeParams.path;
app.controller('TopoCtrl', function($scope, $routeParams, topodata) {
var path = $routeParams.path;
$scope.path = path;
$scope.node = topodata.get({path: path});
var crumbs = [];
if (path) {
var elems = path.split('/');
while (elems.length > 0) {
var elemPath = elems.join('/');
crumbs.unshift({name: elems.pop(), path: elemPath});
}
}
$scope.breadcrumbs = crumbs;
});
app.factory('actions', function($mdDialog, keyspaces, shards, tablets) {
@ -355,3 +371,7 @@ app.factory('tabletinfo', function($resource) {
app.factory('endpoints', function($resource) {
return $resource('/api/endpoints/:cell/:keyspace/:shard/:tabletType');
});
app.factory('topodata', function($resource) {
return $resource('/api/topodata/:path');
});

Просмотреть файл

@ -29,6 +29,7 @@
<md-list>
<md-list-item ng-repeat="route in routes | filter:{showInNav:true}">
<md-button ng-class="{ 'selected': navIsSelected(route) }" ng-href="#{{route.urlBase}}">
<md-icon md-font-set="material-icons" ng-bind="route.icon"></md-icon>
{{route.title}}
</md-button>
</md-list-item>
@ -38,14 +39,14 @@
<div flex layout="column" tabIndex="-1" role="main" class="md-whiteframe-z2">
<md-toolbar layout="row" class="md-whiteframe-z1">
<md-button hide-gt-md ng-click="toggleNav()" aria-label="Toggle Nav Bar">
<md-toolbar layout="row" class="md-whiteframe-z1" layout-align="space-between center">
<md-button class="md-icon-button" hide-gt-md ng-click="toggleNav()" aria-label="Toggle Nav Bar">
<md-icon md-font-set="material-icons">menu</md-icon>
</md-button>
<h1 ng-bind="navTitle()"></h1>
<md-button ng-click="refreshRoute()" aria-label="Refresh">
<md-button class="md-icon-button" ng-click="refreshRoute()" aria-label="Refresh">
<md-icon md-font-set="material-icons">refresh</md-icon>
</md-button>
</md-toolbar>

Просмотреть файл

@ -1 +1,37 @@
<h1 ng-bind="path"></h1>
<div ng-if="!node.$resolved" flex layout="column" layout-align="center center">
<md-progress-circular md-mode="indeterminate"></md-progress-circular>
<h3>Loading...</h3>
</div>
<md-content ng-if="node.$resolved" class="md-padding">
<div class="breadcrumb md-whiteframe-z1">
<md-button href="#/topo/">
<md-icon md-font-set="material-icons">folder</md-icon>
</md-button>
<span class="breadcrumb-divider">/</span>
<span ng-repeat="elem in breadcrumbs">
<md-button ng-href="#/topo/{{elem.path}}">{{elem.name}}</md-button>
<span ng-if="!$last" class="breadcrumb-divider">/</span>
</span>
</div>
<h2 ng-bind="node.Path"></h2>
<md-list ng-if="node.Children">
<md-list-item class="md-whiteframe-z1" ng-repeat="child in node.Children" ng-click="navigate('/topo/' + (path ? path+'/' : '') + child)">
<md-icon md-font-set="material-icons">folder</md-icon>
<h3 flex>{{child}}</h3>
</md-list-item>
</md-list>
<md-content ng-if="node.Data" class="md-padding md-whiteframe-z2">
<pre>{{node.Data}}</pre>
</md-content>
<div ng-if="node.Error">
<h2>Error</h2>
<p>{{node.Error}}</p>
</div>
</md-content>