Merge pull request #1437 from ldez/feat/backends-filter

feat(webui): Dashboard filter
This commit is contained in:
Vincent Demeester 2017-04-24 10:25:46 +02:00 committed by GitHub
commit 6012a0f3c5
12 changed files with 61 additions and 32 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 255 KiB

View file

@ -162,11 +162,6 @@ func (server *Server) Close() {
func (server *Server) startLeadership() { func (server *Server) startLeadership() {
if server.leadership != nil { if server.leadership != nil {
server.leadership.Participate(server.routinesPool) server.leadership.Participate(server.routinesPool)
// server.leadership.AddGoCtx(func(ctx context.Context) {
// log.Debugf("Started test routine")
// <-ctx.Done()
// log.Debugf("Stopped test routine")
// })
} }
} }

View file

@ -92,13 +92,13 @@ func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessag
systemRouter.Methods("PUT").Path(provider.Path + "api/providers/{provider}").HandlerFunc(func(response http.ResponseWriter, request *http.Request) { systemRouter.Methods("PUT").Path(provider.Path + "api/providers/{provider}").HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
if provider.ReadOnly { if provider.ReadOnly {
response.WriteHeader(http.StatusForbidden) response.WriteHeader(http.StatusForbidden)
fmt.Fprintf(response, "REST API is in read-only mode") fmt.Fprint(response, "REST API is in read-only mode")
return return
} }
vars := mux.Vars(request) vars := mux.Vars(request)
if vars["provider"] != "web" { if vars["provider"] != "web" {
response.WriteHeader(http.StatusBadRequest) response.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(response, "Only 'web' provider can be updated through the REST API") fmt.Fprint(response, "Only 'web' provider can be updated through the REST API")
return return
} }
@ -174,7 +174,7 @@ func (provider *WebProvider) getHealthHandler(response http.ResponseWriter, requ
} }
func (provider *WebProvider) getPingHandler(response http.ResponseWriter, request *http.Request) { func (provider *WebProvider) getPingHandler(response http.ResponseWriter, request *http.Request) {
fmt.Fprintf(response, "OK") fmt.Fprint(response, "OK")
} }
func (provider *WebProvider) getConfigHandler(response http.ResponseWriter, request *http.Request) { func (provider *WebProvider) getConfigHandler(response http.ResponseWriter, request *http.Request) {
@ -319,14 +319,14 @@ func (provider *WebProvider) getRouteHandler(response http.ResponseWriter, reque
func expvarHandler(w http.ResponseWriter, r *http.Request) { func expvarHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8") w.Header().Set("Content-Type", "application/json; charset=utf-8")
fmt.Fprintf(w, "{\n") fmt.Fprint(w, "{\n")
first := true first := true
expvar.Do(func(kv expvar.KeyValue) { expvar.Do(func(kv expvar.KeyValue) {
if !first { if !first {
fmt.Fprintf(w, ",\n") fmt.Fprint(w, ",\n")
} }
first = false first = false
fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value) fmt.Fprintf(w, "%q: %s", kv.Key, kv.Value)
}) })
fmt.Fprintf(w, "\n}\n") fmt.Fprint(w, "\n}\n")
} }

View file

@ -27,7 +27,7 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
- `yarn install` - `yarn install`
- Build static Web UI, execute the following command: - Build static Web UI, execute the following command:
- `gulp` - `yarn run build`
- Static contents are build in the directory `static` - Static contents are build in the directory `static`
@ -50,7 +50,7 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
- Edit files in `webui/src` - Edit files in `webui/src`
- Run in development mode : - Run in development mode :
- `gulp serve` - `yarn run serve`
- Træfɪk API connections are defined in: - Træfɪk API connections are defined in:
- `webui/src/app/core/health.resource.js` - `webui/src/app/core/health.resource.js`

View file

@ -8,7 +8,40 @@ angular
.module(traefikCoreProvider, ['ngResource']) .module(traefikCoreProvider, ['ngResource'])
.factory('Providers', Providers); .factory('Providers', Providers);
/** @ngInject */ /** @ngInject */
function Providers($resource) { function Providers($resource) {
return $resource('../api/providers'); const resourceProvider = $resource('../api/providers');
} return {
get: function () {
const rawProviders = resourceProvider.get();
for (let providerName in rawProviders) {
if (rawProviders.hasOwnProperty(providerName)) {
// BackEnds mapping
let bckends = rawProviders[providerName].backends;
rawProviders[providerName].backends = Object.keys(bckends)
.map(key => {
const goodBackend = bckends[key];
goodBackend.backendId = key;
return goodBackend;
});
// FrontEnds mapping
let frtends = rawProviders[providerName].frontends;
rawProviders[providerName].frontends = Object.keys(frtends)
.map(key => {
const goodFrontend = frtends[key];
goodFrontend.frontendId = key;
return goodFrontend;
});
}
}
return rawProviders;
}
};
}

View file

@ -8,8 +8,7 @@ function backendMonitor() {
controllerAs: 'backendCtrl', controllerAs: 'backendCtrl',
bindToController: true, bindToController: true,
scope: { scope: {
backend: '=', backend: '='
backendId: '='
} }
}; };
} }
@ -18,4 +17,4 @@ function BackendMonitorController() {
// Nothing // Nothing
} }
module.exports = backendMonitor; module.exports = backendMonitor;

View file

@ -1,6 +1,6 @@
<div class="panel panel-success"> <div class="panel panel-success">
<div class="panel-heading"> <div class="panel-heading">
<strong><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> {{backendCtrl.backendId}}</strong> <strong><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> {{backendCtrl.backend.backendId}}</strong>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="panel-table__servers table table-striped table-hover"> <table class="panel-table__servers table table-striped table-hover">

View file

@ -8,8 +8,7 @@ function frontendMonitor() {
controllerAs: 'frontendCtrl', controllerAs: 'frontendCtrl',
bindToController: true, bindToController: true,
scope: { scope: {
frontend: '=', frontend: '='
frontendId: '='
} }
}; };
} }

View file

@ -1,6 +1,6 @@
<div class="panel panel-warning"> <div class="panel panel-warning">
<div class="panel-heading"> <div class="panel-heading">
<strong><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> {{frontendCtrl.frontendId}}</strong> <strong><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> {{frontendCtrl.frontend.frontendId}}</strong>
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="panel-table__routes table table-striped table-hover"> <table class="panel-table__routes table table-striped table-hover">

View file

@ -2,17 +2,18 @@
/** @ngInject */ /** @ngInject */
function ProvidersController($scope, $interval, $log, Providers) { function ProvidersController($scope, $interval, $log, Providers) {
var vm = this; const vm = this;
vm.providers = Providers.get(); vm.providers = Providers.get();
var intervalId = $interval(function () { const intervalId = $interval(function () {
Providers.get(function (providers) { Providers.get(function (providers) {
vm.providers = providers; vm.providers = providers;
}, function (error) { }, function (error) {
vm.providers = {}; vm.providers = {};
$log.error(error); $log.error(error);
}); });
}, 2000); }, 2000);
$scope.$on('$destroy', function () { $scope.$on('$destroy', function () {
@ -20,4 +21,4 @@ function ProvidersController($scope, $interval, $log, Providers) {
}); });
} }
module.exports = ProvidersController; module.exports = ProvidersController;

View file

@ -1,16 +1,18 @@
<div> <div>
<div><input type="text" data-ng-model="providersCtrl.providerFilter" placeholder="Filter" class="form-control"></div>
<br>
<uib-tabset> <uib-tabset>
<uib-tab data-ng-repeat="(providerId, provider) in providersCtrl.providers" heading="{{providerId}}"> <uib-tab data-ng-repeat="(providerId, provider) in providersCtrl.providers" heading="{{providerId}}">
<div class="row tabset-row__providers"> <div class="row tabset-row__providers">
<div class="col-md-6"> <div class="col-md-6">
<div data-ng-repeat="(frontendId, frontend) in provider.frontends"> <div data-ng-repeat="frontend in provider.frontends | filter: providersCtrl.providerFilter ">
<frontend-monitor data-provider-id="providerId" data-frontend-id="frontendId" data-frontend="frontend"></frontend-monitor> <frontend-monitor data-provider-id="providerId" data-frontend="frontend"></frontend-monitor>
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div data-ng-repeat="(backendId, backend) in provider.backends"> <div data-ng-repeat="backend in provider.backends | filter: providersCtrl.providerFilter">
<backend-monitor data-provider-id="providerId" data-backend-id="backendId" data-backend="backend"></backend-monitor> <backend-monitor data-provider-id="providerId" data-backend="backend"></backend-monitor>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/** @ngInject */ /** @ngInject */
function VersionController($scope, $interval, $log, Version) { function VersionController($scope, Version) {
Version.get(function (version) { Version.get(function (version) {
$scope.version = version; $scope.version = version;
}); });