1
0
Fork 0

Move webui to FountainJS with Webpack

This commit is contained in:
Micaël 2016-07-23 19:59:54 +02:00
parent 986ad9fc57
commit e059239bc3
58 changed files with 1027 additions and 1239 deletions

13
webui/src/.eslintrc Normal file
View file

@ -0,0 +1,13 @@
{
"extends": "eslint:recommended",
"plugins": ["angular"],
"env": {
"browser": true,
"jasmine": true
},
"globals": {
"angular": true,
"module": true,
"inject": true
}
}

View file

@ -1,13 +1,14 @@
(function () {
'use strict';
'use strict';
var angular = require('angular');
angular
.module('traefik.core.health', ['ngResource'])
.factory('Health', Health);
var traefikCoreHealth = 'traefik.core.health';
module.exports = traefikCoreHealth;
/** @ngInject */
function Health($resource) {
return $resource('../health');
}
angular
.module(traefikCoreHealth, ['ngResource'])
.factory('Health', Health);
})();
/** @ngInject */
function Health($resource) {
return $resource('../health');
}

View file

@ -1,13 +1,14 @@
(function () {
'use strict';
'use strict';
var angular = require('angular');
angular
.module('traefik.core.provider', ['ngResource'])
.factory('Providers', Providers);
var traefikCoreProvider = 'traefik.core.provider';
module.exports = traefikCoreProvider;
/** @ngInject */
function Providers($resource) {
return $resource('../api/providers');
}
angular
.module(traefikCoreProvider, ['ngResource'])
.factory('Providers', Providers);
})();
/** @ngInject */
function Providers($resource) {
return $resource('../api/providers');
}

View file

@ -1,15 +0,0 @@
(function() {
'use strict';
angular
.module('traefik')
.config(config);
/** @ngInject */
function config($logProvider) {
// Enable log
$logProvider.debugEnabled(true);
}
})();

View file

@ -1,9 +0,0 @@
/* global moment:false */
(function() {
'use strict';
angular
.module('traefik')
.constant('moment', moment);
})();

View file

@ -1,7 +0,0 @@
(function() {
'use strict';
angular
.module('traefik', ['ngAnimate', 'ngCookies', 'ngSanitize', 'ngMessages', 'ngAria', 'ngResource', 'ui.router', 'ui.bootstrap', 'traefik.section']);
})();

View file

@ -1,14 +0,0 @@
(function() {
'use strict';
angular
.module('traefik')
.run(runBlock);
/** @ngInject */
function runBlock($log) {
$log.debug('runBlock end');
}
})();

View file

@ -3,7 +3,6 @@
* The list of variables are listed here bower_components/bootstrap-sass/assets/stylesheets/bootstrap/_variables.scss
*/
$navbar-inverse-link-color: #5AADBB;
$icon-font-path: "../../bower_components/bootstrap-sass/assets/fonts/bootstrap/";
/**
* Do not remove the comments below. It's the markers used by wiredep to inject

View file

@ -1,209 +1,204 @@
/* global d3:false */
(function (d3) {
'use strict';
'use strict';
var d3 = require('d3');
angular
.module('traefik.section.health')
.controller('HealthController', HealthController);
/** @ngInject */
function HealthController($scope, $interval, $log, Health) {
/** @ngInject */
function HealthController($scope, $interval, $log, Health) {
var vm = this;
var vm = this;
vm.graph = {
averageResponseTime: {},
totalStatusCodeCount: {}
};
vm.graph = {
averageResponseTime: {},
totalStatusCodeCount: {}
};
vm.graph.totalStatusCodeCount.options = {
"chart": {
type: 'discreteBarChart',
height: 200,
margin: {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function (d) {
return d.label;
},
y: function (d) {
return d.value;
},
showValues: true,
valueFormat: function (d) {
return d3.format('d')(d);
},
transitionDuration: 50,
yAxis: {
axisLabelDistance: 30
}
},
"title": {
"enable": true,
"text": "Total Status Code Count",
"css": {
"textAlign": "center"
}
}
};
vm.graph.totalStatusCodeCount.options = {
"chart": {
type: 'discreteBarChart',
height: 200,
margin: {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function (d) {
return d.label;
},
y: function (d) {
return d.value;
},
showValues: true,
valueFormat: function (d) {
return d3.format('d')(d);
},
transitionDuration: 50,
yAxis: {
axisLabelDistance: 30
}
},
"title": {
"enable": true,
"text": "Total Status Code Count",
"css": {
"textAlign": "center"
}
}
};
vm.graph.totalStatusCodeCount.data = [
vm.graph.totalStatusCodeCount.data = [
{
key: "Total Status Code Count",
values: [
{
key: "Total Status Code Count",
values: [
{
"label": "200",
"value": 0
}
]
"label": "200",
"value": 0
}
];
]
}
];
/**
* Update Total Status Code Count graph
*
* @param {Object} totalStatusCodeCount Object from API
*/
function updateTotalStatusCodeCount(totalStatusCodeCount) {
// extract values
vm.graph.totalStatusCodeCount.data[0].values = [];
for (var code in totalStatusCodeCount) {
if (totalStatusCodeCount.hasOwnProperty(code)) {
vm.graph.totalStatusCodeCount.data[0].values.push({
label: code,
value: totalStatusCodeCount[code]
});
}
}
// Update Total Status Code Count graph render
if (vm.graph.totalStatusCodeCount.api) {
vm.graph.totalStatusCodeCount.api.update();
} else {
$log.error('fail');
}
/**
* Update Total Status Code Count graph
*
* @param {Object} totalStatusCodeCount Object from API
*/
function updateTotalStatusCodeCount(totalStatusCodeCount) {
// extract values
vm.graph.totalStatusCodeCount.data[0].values = [];
for (var code in totalStatusCodeCount) {
if (totalStatusCodeCount.hasOwnProperty(code)) {
vm.graph.totalStatusCodeCount.data[0].values.push({
label: code,
value: totalStatusCodeCount[code]
});
}
vm.graph.averageResponseTime.options = {
chart: {
type: 'lineChart',
height: 200,
margin: {
top: 20,
right: 40,
bottom: 40,
left: 55
},
transitionDuration: 50,
x: function (d) {
return d.x;
},
y: function (d) {
return d.y;
},
useInteractiveGuideline: true,
xAxis: {
tickFormat: function (d) {
return d3.time.format('%X')(new Date(d));
}
},
yAxis: {
tickFormat: function (d) {
return d3.format(',.1f')(d);
}
}
},
"title": {
"enable": true,
"text": "Average response time",
"css": {
"textAlign": "center"
}
}
};
var initialPoint = {
x: Date.now() - 3000,
y: 0
};
vm.graph.averageResponseTime.data = [
{
values: [initialPoint],
key: 'Average response time (ms)',
type: 'line',
color: '#2ca02c'
}
];
/**
* Update average response time graph
*
* @param {Number} x Coordinate X
* @param {Number} y Coordinate Y
*/
function updateAverageResponseTimeGraph(x, y) {
// x multiply 1000 by because unix time is in seconds and JS Date are in milliseconds
var data = {
x: x * 1000,
y: y * 1000
};
vm.graph.averageResponseTime.data[0].values.push(data);
// limit graph entries
if (vm.graph.averageResponseTime.data[0].values.length > 100) {
vm.graph.averageResponseTime.data[0].values.shift();
}
// Update Average Response Time graph render
if (vm.graph.averageResponseTime.api) {
vm.graph.averageResponseTime.api.update();
}
}
/**
* Load all graph's datas
*
* @param {Object} health Health data from server
*/
function loadData(health) {
// Load datas and update Average Response Time graph render
updateAverageResponseTimeGraph(health.unixtime, health.average_response_time_sec);
// Load datas and update Total Status Code Count graph render
updateTotalStatusCodeCount(health.total_status_code_count);
// set data's view
vm.health = health;
}
/**
* Action when load datas failed
*
* @param {Object} error Error state object
*/
function erroData(error) {
vm.health = {};
$log.error(error);
}
// first load
Health.get(loadData, erroData);
// Auto refresh data
var intervalId = $interval(function () {
Health.get(loadData, erroData);
}, 3000);
// Stop auto refresh when page change
$scope.$on('$destroy', function () {
$interval.cancel(intervalId);
});
}
})(d3);
// Update Total Status Code Count graph render
if (vm.graph.totalStatusCodeCount.api) {
vm.graph.totalStatusCodeCount.api.update();
} else {
$log.error('fail');
}
}
vm.graph.averageResponseTime.options = {
chart: {
type: 'lineChart',
height: 200,
margin: {
top: 20,
right: 40,
bottom: 40,
left: 55
},
transitionDuration: 50,
x: function (d) {
return d.x;
},
y: function (d) {
return d.y;
},
useInteractiveGuideline: true,
xAxis: {
tickFormat: function (d) {
return d3.time.format('%X')(new Date(d));
}
},
yAxis: {
tickFormat: function (d) {
return d3.format(',.1f')(d);
}
}
},
"title": {
"enable": true,
"text": "Average response time",
"css": {
"textAlign": "center"
}
}
};
var initialPoint = {
x: Date.now() - 3000,
y: 0
};
vm.graph.averageResponseTime.data = [
{
values: [initialPoint],
key: 'Average response time (ms)',
type: 'line',
color: '#2ca02c'
}
];
/**
* Update average response time graph
*
* @param {Number} x Coordinate X
* @param {Number} y Coordinate Y
*/
function updateAverageResponseTimeGraph(x, y) {
// x multiply 1000 by because unix time is in seconds and JS Date are in milliseconds
var data = {
x: x * 1000,
y: y * 1000
};
vm.graph.averageResponseTime.data[0].values.push(data);
// limit graph entries
if (vm.graph.averageResponseTime.data[0].values.length > 100) {
vm.graph.averageResponseTime.data[0].values.shift();
}
// Update Average Response Time graph render
if (vm.graph.averageResponseTime.api) {
vm.graph.averageResponseTime.api.update();
}
}
/**
* Load all graph's datas
*
* @param {Object} health Health data from server
*/
function loadData(health) {
// Load datas and update Average Response Time graph render
updateAverageResponseTimeGraph(health.unixtime, health.average_response_time_sec);
// Load datas and update Total Status Code Count graph render
updateTotalStatusCodeCount(health.total_status_code_count);
// set data's view
vm.health = health;
}
/**
* Action when load datas failed
*
* @param {Object} error Error state object
*/
function erroData(error) {
vm.health = {};
$log.error(error);
}
// first load
Health.get(loadData, erroData);
// Auto refresh data
var intervalId = $interval(function () {
Health.get(loadData, erroData);
}, 3000);
// Stop auto refresh when page change
$scope.$on('$destroy', function () {
$interval.cancel(intervalId);
});
}
module.exports = HealthController;

View file

@ -1,19 +1,24 @@
(function () {
'use strict';
'use strict';
var angular = require('angular');
var traefikCoreHealth = require('../../core/health.resource');
var HealthController = require('./health.controller');
angular.module('traefik.section.health', ['traefik.core.health'])
.config(config);
var traefikSectionHealth = 'traefik.section.health';
module.exports = traefikSectionHealth;
/** @ngInject */
function config($stateProvider) {
angular
.module(traefikSectionHealth, [traefikCoreHealth])
.controller('HealthController', HealthController)
.config(config);
$stateProvider.state('health', {
url: '/health',
templateUrl: 'app/sections/health/health.html',
controller: 'HealthController',
controllerAs: 'healthCtrl'
});
/** @ngInject */
function config($stateProvider) {
}
$stateProvider.state('health', {
url: '/health',
template: require('./health.html'),
controller: 'HealthController',
controllerAs: 'healthCtrl'
});
})();
}

View file

@ -1,26 +1,21 @@
(function () {
'use strict';
'use strict';
angular
.module('traefik.section.providers.backend-monitor')
.directive('backendMonitor', backendMonitor);
function backendMonitor() {
return {
restrict: 'EA',
templateUrl: 'app/sections/providers/backend-monitor/backend-monitor.html',
controller: BackendMonitorController,
controllerAs: 'backendCtrl',
bindToController: true,
scope: {
backend: '=',
backendId: '='
}
};
function backendMonitor() {
return {
restrict: 'EA',
template: require('./backend-monitor.html'),
controller: BackendMonitorController,
controllerAs: 'backendCtrl',
bindToController: true,
scope: {
backend: '=',
backendId: '='
}
};
}
function BackendMonitorController() {
// Nothing
}
function BackendMonitorController() {
// Nothing
}
})();
module.exports = backendMonitor;

View file

@ -1,7 +1,10 @@
(function () {
'use strict';
'use strict';
var angular = require('angular');
var backendMonitor = require('./backend-monitor.directive');
angular
.module('traefik.section.providers.backend-monitor', []);
var traefikBackendMonitor = 'traefik.section.providers.backend-monitor';
module.exports = traefikBackendMonitor;
})();
angular
.module(traefikBackendMonitor, [])
.directive('backendMonitor', backendMonitor);

View file

@ -1,26 +1,21 @@
(function () {
'use strict';
'use strict';
angular
.module('traefik.section.providers.frontend-monitor')
.directive('frontendMonitor', frontendMonitor);
function frontendMonitor() {
return {
restrict: 'EA',
templateUrl: 'app/sections/providers/frontend-monitor/frontend-monitor.html',
controller: FrontendMonitorController,
controllerAs: 'frontendCtrl',
bindToController: true,
scope: {
frontend: '=',
frontendId: '='
}
};
function frontendMonitor() {
return {
restrict: 'EA',
template: require('./frontend-monitor.html'),
controller: FrontendMonitorController,
controllerAs: 'frontendCtrl',
bindToController: true,
scope: {
frontend: '=',
frontendId: '='
}
};
}
function FrontendMonitorController() {
// Nothing
}
function FrontendMonitorController() {
// Nothing
}
})();
module.exports = frontendMonitor;

View file

@ -1,6 +1,10 @@
(function () {
'use strict';
'use strict';
var angular = require('angular');
var frontendMonitor = require('./frontend-monitor.directive');
angular.module('traefik.section.providers.frontend-monitor', []);
var traefikFrontendMonitor = 'traefik.section.providers.frontend-monitor';
module.exports = traefikFrontendMonitor;
})();
angular
.module(traefikFrontendMonitor, [])
.directive('frontendMonitor', frontendMonitor);

View file

@ -1,28 +1,23 @@
(function () {
'use strict';
'use strict';
angular
.module('traefik.section.providers')
.controller('ProvidersController', ProvidersController);
/** @ngInject */
function ProvidersController($scope, $interval, $log, Providers) {
var vm = this;
/** @ngInject */
function ProvidersController($scope, $interval, $log, Providers) {
var vm = this;
vm.providers = Providers.get();
vm.providers = Providers.get();
var intervalId = $interval(function () {
Providers.get(function (providers) {
vm.providers = providers;
}, function (error) {
vm.providers = {};
$log.error(error);
});
}, 2000);
var intervalId = $interval(function () {
Providers.get(function (providers) {
vm.providers = providers;
}, function (error) {
vm.providers = {};
$log.error(error);
});
}, 2000);
$scope.$on('$destroy', function () {
$interval.cancel(intervalId);
});
}
$scope.$on('$destroy', function () {
$interval.cancel(intervalId);
});
}
})();
module.exports = ProvidersController;

View file

@ -1,24 +1,30 @@
(function () {
'use strict';
'use strict';
var angular = require('angular');
var traefikCoreProvider = require('../../core/providers.resource');
var ProvidersController = require('./providers.controller');
var traefikBackendMonitor = require('./backend-monitor/backend-monitor.module');
var traefikFrontendMonitor = require('./frontend-monitor/frontend-monitor.module');
angular
.module('traefik.section.providers', [
'traefik.core.provider',
'traefik.section.providers.backend-monitor',
'traefik.section.providers.frontend-monitor'
])
.config(config);
var traefikSectionProviders = 'traefik.section.providers';
module.exports = traefikSectionProviders;
/** @ngInject */
function config($stateProvider) {
angular
.module(traefikSectionProviders, [
traefikCoreProvider,
traefikBackendMonitor,
traefikFrontendMonitor
])
.config(config)
.controller('ProvidersController', ProvidersController);
$stateProvider.state('provider', {
url: '/',
templateUrl: 'app/sections/providers/providers.html',
controller: 'ProvidersController',
controllerAs: 'providersCtrl'
});
/** @ngInject */
function config($stateProvider) {
}
$stateProvider.state('provider', {
url: '/',
template: require('./providers.html'),
controller: 'ProvidersController',
controllerAs: 'providersCtrl'
});
})();
}

View file

@ -1,13 +0,0 @@
(function () {
'use strict';
angular
.module('traefik.section')
.config(config);
/** @ngInject */
function config($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
}
})();

View file

@ -0,0 +1,24 @@
'use strict';
var angular = require('angular');
require('nvd3');
var ndv3 = require('angular-nvd3');
var traefikSectionHealth = require('./health/health.module');
var traefikSectionProviders = require('./providers/providers.module');
var traefikSection = 'traefik.section';
module.exports = traefikSection;
angular
.module(traefikSection, [
'ui.router',
'ui.bootstrap',
ndv3,
traefikSectionProviders,
traefikSectionHealth
])
.config(config);
/** @ngInject */
function config($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
}

View file

@ -1,13 +0,0 @@
(function () {
'use strict';
angular
.module('traefik.section', [
'ui.router',
'ui.bootstrap',
'nvd3',
'traefik.section.providers',
'traefik.section.health'
]);
})();

View file

@ -1,9 +1,9 @@
@font-face {
font-family: 'charterregular';
src: url('../assets/fonts/charter_regular-webfont.eot');
src: url('../assets/fonts/charter_regular-webfont.eot?#iefix') format('embedded-opentype'),
url('../assets/fonts/charter_regular-webfont.woff') format('woff');
src: url('./assets/fonts/charter_regular-webfont.eot');
src: url('./assets/fonts/charter_regular-webfont.eot?#iefix') format('embedded-opentype'),
url('./assets/fonts/charter_regular-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}

View file

@ -2,29 +2,17 @@
<html ng-app="traefik">
<head>
<meta charset="utf-8">
<title>Træfɪk</title>
<title>Træfɪk</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="icon" type="image/png" href="traefik.icon.png" />
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css({.tmp/serve,src}) styles/vendor.css -->
<!-- bower:css -->
<!-- run `gulp inject` to automatically populate bower styles dependencies -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css({.tmp/serve,src}) styles/app.css -->
<!-- inject:css -->
<!-- css files will be automatically insert here -->
<!-- endinject -->
<!-- endbuild -->
</head>
<body>
<!--[if lt IE 10]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div class="container">
<header>
<nav class="navbar navbar-default">
@ -56,22 +44,5 @@
</main>
</div>
<!-- build:js(src) scripts/vendor.js -->
<!-- bower:js -->
<!-- run `gulp inject` to automatically populate bower script dependencies -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp/serve,.tmp/partials,src}) scripts/app.js -->
<!-- inject:js -->
<!-- js files will be automatically insert here -->
<!-- endinject -->
<!-- inject:partials -->
<!-- angular templates will be automatically converted in js and inserted here -->
<!-- endinject -->
<!-- endbuild -->
</body>
</html>

46
webui/src/index.js Normal file
View file

@ -0,0 +1,46 @@
'use strict';
var angular = require('angular');
var ngAnimate = require('angular-animate');
var ngCookies = require('angular-cookies');
var ngSanitize = require('angular-sanitize');
var ngMessages = require('angular-messages');
var ngAria = require('angular-aria');
var ngResource = require('angular-resource');
var uiRouter = require('angular-ui-router');
var uiBootstrap = require('angular-ui-bootstrap');
var moment = require('moment');
var traefikSection = require('./app/sections/sections');
require('./index.scss');
require('animate.css/animate.css');
require('nvd3/build/nv.d3.css');
require('bootstrap/dist/css/bootstrap.css');
var app = 'traefik';
module.exports = app;
angular
.module(app, [
ngAnimate,
ngCookies,
ngSanitize,
ngMessages,
ngAria,
ngResource,
uiRouter,
uiBootstrap,
traefikSection
])
.run(runBlock)
.constant('moment', moment)
.config(config);
/** @ngInject */
function config($logProvider) {
// Enable log
$logProvider.debugEnabled(true);
}
/** @ngInject */
function runBlock($log) {
$log.debug('runBlock end');
}

3
webui/src/index.scss Normal file
View file

@ -0,0 +1,3 @@
$icon-font-path: "../bower_components/bootstrap-sass/assets/fonts/bootstrap/";
@import 'app/index.scss';
@import 'app/traefik.scss';