Merge pull request #558 from micaelmbagira/webui-webpack-fountainjs
Move webui to FountainJS with Webpack
This commit is contained in:
commit
2a596b8162
58 changed files with 1027 additions and 1239 deletions
2
Makefile
2
Makefile
|
@ -73,7 +73,7 @@ run-dev:
|
|||
generate-webui: build-webui
|
||||
if [ ! -d "static" ]; then \
|
||||
mkdir -p static; \
|
||||
docker run --rm -v "$$PWD/static":'/src/static' traefik-webui gulp; \
|
||||
docker run --rm -v "$$PWD/static":'/src/static' traefik-webui npm run build; \
|
||||
echo 'For more informations show `webui/readme.md`' > $$PWD/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"directory": "bower_components"
|
||||
}
|
1
webui/.gitattributes
vendored
Normal file
1
webui/.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
* text=auto
|
9
webui/.gitignore
vendored
9
webui/.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
node_modules/
|
||||
bower_components/
|
||||
coverage/
|
||||
.sass-cache/
|
||||
.tmp/
|
||||
coverage/
|
||||
dist/
|
||||
node_modules/
|
||||
.sass-cache/
|
||||
|
||||
|
|
|
@ -1,74 +1,20 @@
|
|||
{
|
||||
"generator-gulp-angular": {
|
||||
"version": "1.0.2",
|
||||
"generator-fountain-angular1": {
|
||||
"version": "0.6.0",
|
||||
"props": {
|
||||
"angularVersion": "~1.4.2",
|
||||
"angularModules": [
|
||||
{
|
||||
"key": "animate",
|
||||
"module": "ngAnimate"
|
||||
},
|
||||
{
|
||||
"key": "cookies",
|
||||
"module": "ngCookies"
|
||||
},
|
||||
{
|
||||
"key": "sanitize",
|
||||
"module": "ngSanitize"
|
||||
},
|
||||
{
|
||||
"key": "messages",
|
||||
"module": "ngMessages"
|
||||
},
|
||||
{
|
||||
"key": "aria",
|
||||
"module": "ngAria"
|
||||
}
|
||||
],
|
||||
"jQuery": {
|
||||
"key": "jquery2"
|
||||
"resolved": "/Users/micael/Documents/zenika/fountain/generator-fountain-angular1/generators/app/index.js",
|
||||
"namespace": "fountain-angular1:app",
|
||||
"argv": {
|
||||
"remain": [],
|
||||
"cooked": [],
|
||||
"original": []
|
||||
},
|
||||
"resource": {
|
||||
"key": "angular-resource",
|
||||
"module": "ngResource"
|
||||
},
|
||||
"router": {
|
||||
"key": "ui-router",
|
||||
"module": "ui.router"
|
||||
},
|
||||
"ui": {
|
||||
"key": "bootstrap",
|
||||
"module": null
|
||||
},
|
||||
"bootstrapComponents": {
|
||||
"key": "ui-bootstrap",
|
||||
"module": "ui.bootstrap"
|
||||
},
|
||||
"cssPreprocessor": {
|
||||
"key": "node-sass",
|
||||
"extension": "scss"
|
||||
},
|
||||
"jsPreprocessor": {
|
||||
"key": "noJsPrepro",
|
||||
"extension": "js",
|
||||
"srcExtension": "js"
|
||||
},
|
||||
"htmlPreprocessor": {
|
||||
"key": "noHtmlPrepro",
|
||||
"extension": "html"
|
||||
},
|
||||
"foundationComponents": {
|
||||
"name": null,
|
||||
"version": null,
|
||||
"key": null,
|
||||
"module": null
|
||||
},
|
||||
"paths": {
|
||||
"src": "src",
|
||||
"dist": "../static",
|
||||
"e2e": "e2e",
|
||||
"tmp": ".tmp"
|
||||
}
|
||||
"framework": "angular1",
|
||||
"modules": "webpack",
|
||||
"css": "scss",
|
||||
"js": "js",
|
||||
"sample": "hello",
|
||||
"router": "none"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,16 +3,11 @@ FROM node:6.3.0
|
|||
ENV WEBUI_DIR /src/webui
|
||||
RUN mkdir -p $WEBUI_DIR
|
||||
|
||||
RUN npm install -g gulp bower
|
||||
|
||||
COPY package.json $WEBUI_DIR/
|
||||
COPY .bowerrc $WEBUI_DIR/
|
||||
COPY bower.json $WEBUI_DIR/
|
||||
|
||||
WORKDIR $WEBUI_DIR
|
||||
RUN npm set progress=false
|
||||
RUN npm install --quiet
|
||||
RUN bower install --allow-root --quiet
|
||||
|
||||
COPY . $WEBUI_DIR/
|
||||
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"name": "traefik",
|
||||
"version": "2.0.0",
|
||||
"homepage": "http://traefik.io",
|
||||
"authors": [
|
||||
"Fernandez Ludovic <lfernandez.dev@gmail.com>"
|
||||
],
|
||||
"description": "Front end for Træfɪk",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"angular-animate": "~1.4.2",
|
||||
"angular-cookies": "~1.4.2",
|
||||
"angular-sanitize": "~1.4.2",
|
||||
"angular-messages": "~1.4.2",
|
||||
"angular-aria": "~1.4.2",
|
||||
"jquery": "~2.1.4",
|
||||
"angular-resource": "~1.4.2",
|
||||
"angular-ui-router": "~0.2.15",
|
||||
"bootstrap-sass": "~3.3.5",
|
||||
"angular-bootstrap": "~0.13.4",
|
||||
"moment": "~2.10.6",
|
||||
"animate.css": "~3.4.0",
|
||||
"angular": "~1.4.2",
|
||||
"angular-nvd3": "~1.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"angular-mocks": "~1.4.2"
|
||||
},
|
||||
"overrides": {
|
||||
"bootstrap-sass": {
|
||||
"main": [
|
||||
"assets/stylesheets/_bootstrap.scss",
|
||||
"assets/fonts/bootstrap/glyphicons-halflings-regular.eot",
|
||||
"assets/fonts/bootstrap/glyphicons-halflings-regular.svg",
|
||||
"assets/fonts/bootstrap/glyphicons-halflings-regular.ttf",
|
||||
"assets/fonts/bootstrap/glyphicons-halflings-regular.woff",
|
||||
"assets/fonts/bootstrap/glyphicons-halflings-regular.woff2"
|
||||
]
|
||||
}
|
||||
},
|
||||
"resolutions": {
|
||||
"jquery": "~2.1.4",
|
||||
"angular": "~1.4.2"
|
||||
}
|
||||
}
|
12
webui/conf/browsersync-dist.conf.js
Executable file
12
webui/conf/browsersync-dist.conf.js
Executable file
|
@ -0,0 +1,12 @@
|
|||
const conf = require('./gulp.conf');
|
||||
|
||||
module.exports = function () {
|
||||
return {
|
||||
server: {
|
||||
baseDir: [
|
||||
conf.paths.dist
|
||||
]
|
||||
},
|
||||
open: false
|
||||
};
|
||||
};
|
13
webui/conf/browsersync.conf.js
Executable file
13
webui/conf/browsersync.conf.js
Executable file
|
@ -0,0 +1,13 @@
|
|||
const conf = require('./gulp.conf');
|
||||
|
||||
module.exports = function () {
|
||||
return {
|
||||
server: {
|
||||
baseDir: [
|
||||
conf.paths.tmp,
|
||||
conf.paths.src
|
||||
]
|
||||
},
|
||||
open: false
|
||||
};
|
||||
};
|
47
webui/conf/gulp.conf.js
Normal file
47
webui/conf/gulp.conf.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* This file contains the variables used in other gulp files
|
||||
* which defines tasks
|
||||
* By design, we only put there very generic config values
|
||||
* which are used in several places to keep good readability
|
||||
* of the tasks
|
||||
*/
|
||||
|
||||
const path = require('path');
|
||||
const gutil = require('gulp-util');
|
||||
|
||||
exports.ngModule = 'traefik';
|
||||
|
||||
/**
|
||||
* The main paths of your project handle these with care
|
||||
*/
|
||||
exports.paths = {
|
||||
src: 'src',
|
||||
dist: '../static',
|
||||
tmp: '.tmp',
|
||||
e2e: 'e2e',
|
||||
tasks: 'gulp_tasks'
|
||||
};
|
||||
|
||||
exports.path = {};
|
||||
for (const pathName in exports.paths) {
|
||||
if (exports.paths.hasOwnProperty(pathName)) {
|
||||
exports.path[pathName] = function pathJoin() {
|
||||
const pathValue = exports.paths[pathName];
|
||||
const funcArgs = Array.prototype.slice.call(arguments);
|
||||
const joinArgs = [pathValue].concat(funcArgs);
|
||||
return path.join.apply(this, joinArgs);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Common implementation for an error handler of a Gulp plugin
|
||||
*/
|
||||
exports.errorHandler = function (title) {
|
||||
return function (err) {
|
||||
gutil.log(gutil.colors.red(`[${title}]`), err.toString());
|
||||
this.emit('end');
|
||||
};
|
||||
};
|
55
webui/conf/karma-auto.conf.js
Normal file
55
webui/conf/karma-auto.conf.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
const conf = require('./gulp.conf');
|
||||
|
||||
module.exports = function (config) {
|
||||
const configuration = {
|
||||
basePath: '../',
|
||||
singleRun: false,
|
||||
autoWatch: true,
|
||||
logLevel: 'INFO',
|
||||
junitReporter: {
|
||||
outputDir: 'test-reports'
|
||||
},
|
||||
browsers: [
|
||||
'PhantomJS'
|
||||
],
|
||||
frameworks: [
|
||||
'jasmine'
|
||||
],
|
||||
files: [
|
||||
'node_modules/es6-shim/es6-shim.js',
|
||||
conf.path.src('index.spec.js'),
|
||||
conf.path.src('**/*.html')
|
||||
],
|
||||
preprocessors: {
|
||||
[conf.path.src('index.spec.js')]: [
|
||||
'webpack'
|
||||
],
|
||||
[conf.path.src('**/*.html')]: [
|
||||
'ng-html2js'
|
||||
]
|
||||
},
|
||||
ngHtml2JsPreprocessor: {
|
||||
stripPrefix: `${conf.paths.src}/`
|
||||
},
|
||||
reporters: ['progress', 'coverage'],
|
||||
coverageReporter: {
|
||||
type: 'html',
|
||||
dir: 'coverage/'
|
||||
},
|
||||
webpack: require('./webpack-test.conf'),
|
||||
webpackMiddleware: {
|
||||
noInfo: true
|
||||
},
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-junit-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('karma-phantomjs-launcher'),
|
||||
require('karma-phantomjs-shim'),
|
||||
require('karma-ng-html2js-preprocessor'),
|
||||
require('karma-webpack')
|
||||
]
|
||||
};
|
||||
|
||||
config.set(configuration);
|
||||
};
|
55
webui/conf/karma.conf.js
Normal file
55
webui/conf/karma.conf.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
const conf = require('./gulp.conf');
|
||||
|
||||
module.exports = function (config) {
|
||||
const configuration = {
|
||||
basePath: '../',
|
||||
singleRun: true,
|
||||
autoWatch: false,
|
||||
logLevel: 'INFO',
|
||||
junitReporter: {
|
||||
outputDir: 'test-reports'
|
||||
},
|
||||
browsers: [
|
||||
'PhantomJS'
|
||||
],
|
||||
frameworks: [
|
||||
'jasmine'
|
||||
],
|
||||
files: [
|
||||
'node_modules/es6-shim/es6-shim.js',
|
||||
conf.path.src('index.spec.js'),
|
||||
conf.path.src('**/*.html')
|
||||
],
|
||||
preprocessors: {
|
||||
[conf.path.src('index.spec.js')]: [
|
||||
'webpack'
|
||||
],
|
||||
[conf.path.src('**/*.html')]: [
|
||||
'ng-html2js'
|
||||
]
|
||||
},
|
||||
ngHtml2JsPreprocessor: {
|
||||
stripPrefix: `${conf.paths.src}/`
|
||||
},
|
||||
reporters: ['progress', 'coverage'],
|
||||
coverageReporter: {
|
||||
type: 'html',
|
||||
dir: 'coverage/'
|
||||
},
|
||||
webpack: require('./webpack-test.conf'),
|
||||
webpackMiddleware: {
|
||||
noInfo: true
|
||||
},
|
||||
plugins: [
|
||||
require('karma-jasmine'),
|
||||
require('karma-junit-reporter'),
|
||||
require('karma-coverage'),
|
||||
require('karma-phantomjs-launcher'),
|
||||
require('karma-phantomjs-shim'),
|
||||
require('karma-ng-html2js-preprocessor'),
|
||||
require('karma-webpack')
|
||||
]
|
||||
};
|
||||
|
||||
config.set(configuration);
|
||||
};
|
74
webui/conf/webpack-dist.conf.js
Normal file
74
webui/conf/webpack-dist.conf.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
const webpack = require('webpack');
|
||||
const conf = require('./gulp.conf');
|
||||
const path = require('path');
|
||||
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const SplitByPathPlugin = require('webpack-split-by-path');
|
||||
const ExtractTextPlugin = require("extract-text-webpack-plugin");
|
||||
const autoprefixer = require('autoprefixer');
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
preLoaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'eslint'
|
||||
}
|
||||
],
|
||||
|
||||
loaders: [
|
||||
{
|
||||
test: /.json$/,
|
||||
loaders: [
|
||||
'json'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(css|scss)$/,
|
||||
loaders: ExtractTextPlugin.extract('style', 'css?minimize!sass', 'postcss')
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loaders: [
|
||||
'ng-annotate'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /.html$/,
|
||||
loaders: [
|
||||
'html'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
|
||||
loader: 'url-loader?limit=100000'
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurrenceOrderPlugin(),
|
||||
new webpack.NoErrorsPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: conf.path.src('index.html'),
|
||||
inject: true
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {unused: true, dead_code: true} // eslint-disable-line camelcase
|
||||
}),
|
||||
new SplitByPathPlugin([{
|
||||
name: 'vendor',
|
||||
path: path.join(__dirname, '../node_modules')
|
||||
}]),
|
||||
new ExtractTextPlugin('./index-[contenthash].css')
|
||||
],
|
||||
postcss: () => [autoprefixer],
|
||||
output: {
|
||||
path: path.join(process.cwd(), conf.paths.dist),
|
||||
filename: './[name]-[hash].js'
|
||||
},
|
||||
entry: {
|
||||
app: `./${conf.path.src('index')}`
|
||||
}
|
||||
};
|
41
webui/conf/webpack-test.conf.js
Normal file
41
webui/conf/webpack-test.conf.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
module.exports = {
|
||||
module: {
|
||||
preLoaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: 'eslint'
|
||||
}
|
||||
],
|
||||
|
||||
loaders: [
|
||||
{
|
||||
test: /.json$/,
|
||||
loaders: [
|
||||
'json'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loaders: [
|
||||
'ng-annotate'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /.html$/,
|
||||
loaders: [
|
||||
'html'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /(node_modules|.*\.spec\.js)/,
|
||||
loader: 'isparta'
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [],
|
||||
debug: true,
|
||||
devtool: 'cheap-module-eval-source-map'
|
||||
};
|
61
webui/conf/webpack.conf.js
Normal file
61
webui/conf/webpack.conf.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
const webpack = require('webpack');
|
||||
const conf = require('./gulp.conf');
|
||||
const path = require('path');
|
||||
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const autoprefixer = require('autoprefixer');
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /.json$/,
|
||||
loaders: [
|
||||
'json'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(css|scss)$/,
|
||||
loaders: [
|
||||
'style',
|
||||
'css',
|
||||
'sass',
|
||||
'postcss'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loaders: [
|
||||
'ng-annotate'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /.html$/,
|
||||
loaders: [
|
||||
'html'
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.(png|woff|woff2|eot|ttf|svg)$/,
|
||||
loader: 'url-loader?limit=100000'
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.OccurrenceOrderPlugin(),
|
||||
new webpack.NoErrorsPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
template: conf.path.src('index.html'),
|
||||
inject: true
|
||||
})
|
||||
],
|
||||
postcss: () => [autoprefixer],
|
||||
debug: true,
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
output: {
|
||||
path: path.join(process.cwd(), conf.paths.tmp),
|
||||
filename: 'index.js'
|
||||
},
|
||||
entry: `./${conf.path.src('index')}`
|
||||
};
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"globals": {
|
||||
"browser": false,
|
||||
"element": false,
|
||||
"by": false,
|
||||
"$": false,
|
||||
"$$": false
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"env": {
|
||||
"node": true
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var $ = require('gulp-load-plugins')({
|
||||
pattern: ['gulp-*', 'main-bower-files', 'uglify-save-license', 'del']
|
||||
});
|
||||
|
||||
gulp.task('partials', function () {
|
||||
return gulp.src([
|
||||
path.join(conf.paths.src, '/app/**/*.html'),
|
||||
path.join(conf.paths.tmp, '/serve/app/**/*.html')
|
||||
])
|
||||
.pipe($.minifyHtml({
|
||||
empty: true,
|
||||
spare: true,
|
||||
quotes: true
|
||||
}))
|
||||
.pipe($.angularTemplatecache('templateCacheHtml.js', {
|
||||
module: 'traefik',
|
||||
root: 'app'
|
||||
}))
|
||||
.pipe(gulp.dest(conf.paths.tmp + '/partials/'));
|
||||
});
|
||||
|
||||
gulp.task('html', ['inject', 'partials'], function () {
|
||||
var partialsInjectFile = gulp.src(path.join(conf.paths.tmp, '/partials/templateCacheHtml.js'), { read: false });
|
||||
var partialsInjectOptions = {
|
||||
starttag: '<!-- inject:partials -->',
|
||||
ignorePath: path.join(conf.paths.tmp, '/partials'),
|
||||
addRootSlash: false
|
||||
};
|
||||
|
||||
var htmlFilter = $.filter('*.html', { restore: true });
|
||||
var jsFilter = $.filter('**/*.js', { restore: true });
|
||||
var cssFilter = $.filter('**/*.css', { restore: true });
|
||||
var assets;
|
||||
|
||||
return gulp.src(path.join(conf.paths.tmp, '/serve/*.html'))
|
||||
.pipe($.inject(partialsInjectFile, partialsInjectOptions))
|
||||
.pipe(assets = $.useref.assets())
|
||||
.pipe($.rev())
|
||||
.pipe(jsFilter)
|
||||
.pipe($.sourcemaps.init())
|
||||
.pipe($.ngAnnotate())
|
||||
.pipe($.uglify({ preserveComments: $.uglifySaveLicense })).on('error', conf.errorHandler('Uglify'))
|
||||
.pipe($.sourcemaps.write('maps'))
|
||||
.pipe(jsFilter.restore)
|
||||
.pipe(cssFilter)
|
||||
.pipe($.sourcemaps.init())
|
||||
.pipe($.replace('../../bower_components/bootstrap-sass/assets/fonts/bootstrap/', '../fonts/'))
|
||||
.pipe($.minifyCss({ processImport: false }))
|
||||
.pipe($.sourcemaps.write('maps'))
|
||||
.pipe(cssFilter.restore)
|
||||
.pipe(assets.restore())
|
||||
.pipe($.useref())
|
||||
.pipe($.revReplace())
|
||||
.pipe(htmlFilter)
|
||||
.pipe($.minifyHtml({
|
||||
empty: true,
|
||||
spare: true,
|
||||
quotes: true,
|
||||
conditionals: true
|
||||
}))
|
||||
.pipe(htmlFilter.restore)
|
||||
.pipe(gulp.dest(path.join(conf.paths.dist, '/')))
|
||||
.pipe($.size({ title: path.join(conf.paths.dist, '/'), showFiles: true }));
|
||||
});
|
||||
|
||||
// Only applies for fonts from bower dependencies
|
||||
// Custom fonts are handled by the "other" task
|
||||
gulp.task('fonts', function () {
|
||||
return gulp.src($.mainBowerFiles())
|
||||
.pipe($.filter('**/*.{eot,svg,ttf,woff,woff2}'))
|
||||
.pipe($.flatten())
|
||||
.pipe(gulp.dest(path.join(conf.paths.dist, '/fonts/')));
|
||||
});
|
||||
|
||||
gulp.task('other', function () {
|
||||
var fileFilter = $.filter(function (file) {
|
||||
return file.stat.isFile();
|
||||
});
|
||||
|
||||
return gulp.src([
|
||||
path.join(conf.paths.src, '/**/*'),
|
||||
path.join('!' + conf.paths.src, '/**/*.{html,css,js,scss}')
|
||||
])
|
||||
.pipe(fileFilter)
|
||||
.pipe(gulp.dest(path.join(conf.paths.dist, '/')));
|
||||
});
|
||||
|
||||
gulp.task('clean', function () {
|
||||
return $.del([path.join(conf.paths.dist, '/**'), '!' + conf.paths.dist, path.join(conf.paths.tmp, '/')], {force: true});
|
||||
});
|
||||
|
||||
gulp.task('build', ['html', 'fonts', 'other']);
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* This file contains the variables used in other gulp files
|
||||
* which defines tasks
|
||||
* By design, we only put there very generic config values
|
||||
* which are used in several places to keep good readability
|
||||
* of the tasks
|
||||
*/
|
||||
|
||||
var gutil = require('gulp-util');
|
||||
|
||||
/**
|
||||
* The main paths of your project handle these with care
|
||||
*/
|
||||
exports.paths = {
|
||||
src: 'src',
|
||||
dist: '../static',
|
||||
tmp: '.tmp',
|
||||
e2e: 'e2e'
|
||||
};
|
||||
|
||||
/**
|
||||
* Wiredep is the lib which inject bower dependencies in your project
|
||||
* Mainly used to inject script tags in the index.html but also used
|
||||
* to inject css preprocessor deps and js files in karma
|
||||
*/
|
||||
exports.wiredep = {
|
||||
exclude: [/\/bootstrap\.js$/, /\/bootstrap-sass\/.*\.js/, /\/bootstrap\.css/],
|
||||
directory: 'bower_components'
|
||||
};
|
||||
|
||||
/**
|
||||
* Common implementation for an error handler of a Gulp plugin
|
||||
*/
|
||||
exports.errorHandler = function(title) {
|
||||
'use strict';
|
||||
|
||||
return function(err) {
|
||||
gutil.log(gutil.colors.red('[' + title + ']'), err.toString());
|
||||
this.emit('end');
|
||||
};
|
||||
};
|
|
@ -1,38 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var browserSync = require('browser-sync');
|
||||
|
||||
var $ = require('gulp-load-plugins')();
|
||||
|
||||
// Downloads the selenium webdriver
|
||||
gulp.task('webdriver-update', $.protractor.webdriver_update);
|
||||
|
||||
gulp.task('webdriver-standalone', $.protractor.webdriver_standalone);
|
||||
|
||||
function runProtractor (done) {
|
||||
var params = process.argv;
|
||||
var args = params.length > 3 ? [params[3], params[4]] : [];
|
||||
|
||||
gulp.src(path.join(conf.paths.e2e, '/**/*.js'))
|
||||
.pipe($.protractor.protractor({
|
||||
configFile: 'protractor.conf.js',
|
||||
args: args
|
||||
}))
|
||||
.on('error', function (err) {
|
||||
// Make sure failed tests cause gulp to exit non-zero
|
||||
throw err;
|
||||
})
|
||||
.on('end', function () {
|
||||
// Close browser sync server
|
||||
browserSync.exit();
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
gulp.task('protractor', ['protractor:src']);
|
||||
gulp.task('protractor:src', ['serve:e2e', 'webdriver-update'], runProtractor);
|
||||
gulp.task('protractor:dist', ['serve:e2e-dist', 'webdriver-update'], runProtractor);
|
|
@ -1,42 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var $ = require('gulp-load-plugins')();
|
||||
|
||||
var wiredep = require('wiredep').stream;
|
||||
var _ = require('lodash');
|
||||
|
||||
var browserSync = require('browser-sync');
|
||||
|
||||
gulp.task('inject-reload', ['inject'], function() {
|
||||
browserSync.reload();
|
||||
});
|
||||
|
||||
gulp.task('inject', ['scripts', 'styles'], function () {
|
||||
var injectStyles = gulp.src([
|
||||
path.join(conf.paths.tmp, '/serve/app/**/*.css'),
|
||||
path.join('!' + conf.paths.tmp, '/serve/app/vendor.css')
|
||||
], { read: false });
|
||||
|
||||
var injectScripts = gulp.src([
|
||||
path.join(conf.paths.src, '/app/**/*.module.js'),
|
||||
path.join(conf.paths.src, '/app/**/*.js'),
|
||||
path.join('!' + conf.paths.src, '/app/**/*.spec.js'),
|
||||
path.join('!' + conf.paths.src, '/app/**/*.mock.js'),
|
||||
])
|
||||
.pipe($.angularFilesort()).on('error', conf.errorHandler('AngularFilesort'));
|
||||
|
||||
var injectOptions = {
|
||||
ignorePath: [conf.paths.src, path.join(conf.paths.tmp, '/serve')],
|
||||
addRootSlash: false
|
||||
};
|
||||
|
||||
return gulp.src(path.join(conf.paths.src, '/*.html'))
|
||||
.pipe($.inject(injectStyles, injectOptions))
|
||||
.pipe($.inject(injectScripts, injectOptions))
|
||||
.pipe(wiredep(_.extend({}, conf.wiredep)))
|
||||
.pipe(gulp.dest(path.join(conf.paths.tmp, '/serve')));
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var browserSync = require('browser-sync');
|
||||
|
||||
var $ = require('gulp-load-plugins')();
|
||||
|
||||
|
||||
gulp.task('scripts-reload', function() {
|
||||
return buildScripts()
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task('scripts', function() {
|
||||
return buildScripts();
|
||||
});
|
||||
|
||||
function buildScripts() {
|
||||
return gulp.src(path.join(conf.paths.src, '/app/**/*.js'))
|
||||
.pipe($.eslint())
|
||||
.pipe($.eslint.format())
|
||||
.pipe($.size())
|
||||
};
|
|
@ -1,63 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var browserSync = require('browser-sync');
|
||||
var browserSyncSpa = require('browser-sync-spa');
|
||||
|
||||
var util = require('util');
|
||||
|
||||
var proxyMiddleware = require('http-proxy-middleware');
|
||||
|
||||
function browserSyncInit(baseDir, browser) {
|
||||
browser = browser === undefined ? 'default' : browser;
|
||||
|
||||
var routes = null;
|
||||
if(baseDir === conf.paths.src || (util.isArray(baseDir) && baseDir.indexOf(conf.paths.src) !== -1)) {
|
||||
routes = {
|
||||
'/bower_components': 'bower_components'
|
||||
};
|
||||
}
|
||||
|
||||
var server = {
|
||||
baseDir: baseDir,
|
||||
routes: routes
|
||||
};
|
||||
|
||||
/*
|
||||
* You can add a proxy to your backend by uncommenting the line below.
|
||||
* You just have to configure a context which will we redirected and the target url.
|
||||
* Example: $http.get('/users') requests will be automatically proxified.
|
||||
*
|
||||
* For more details and option, https://github.com/chimurai/http-proxy-middleware/blob/v0.9.0/README.md
|
||||
*/
|
||||
// server.middleware = proxyMiddleware('/users', {target: 'http://jsonplaceholder.typicode.com', changeOrigin: true});
|
||||
|
||||
browserSync.instance = browserSync.init({
|
||||
startPath: '/',
|
||||
server: server,
|
||||
browser: browser
|
||||
});
|
||||
}
|
||||
|
||||
browserSync.use(browserSyncSpa({
|
||||
selector: '[ng-app]'// Only needed for angular apps
|
||||
}));
|
||||
|
||||
gulp.task('serve', ['watch'], function () {
|
||||
browserSyncInit([path.join(conf.paths.tmp, '/serve'), conf.paths.src]);
|
||||
});
|
||||
|
||||
gulp.task('serve:dist', ['build'], function () {
|
||||
browserSyncInit(conf.paths.dist);
|
||||
});
|
||||
|
||||
gulp.task('serve:e2e', ['inject'], function () {
|
||||
browserSyncInit([conf.paths.tmp + '/serve', conf.paths.src], []);
|
||||
});
|
||||
|
||||
gulp.task('serve:e2e-dist', ['build'], function () {
|
||||
browserSyncInit(conf.paths.dist, []);
|
||||
});
|
|
@ -1,54 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var browserSync = require('browser-sync');
|
||||
|
||||
var $ = require('gulp-load-plugins')();
|
||||
|
||||
var wiredep = require('wiredep').stream;
|
||||
var _ = require('lodash');
|
||||
|
||||
gulp.task('styles-reload', ['styles'], function() {
|
||||
return buildStyles()
|
||||
.pipe(browserSync.stream());
|
||||
});
|
||||
|
||||
gulp.task('styles', function() {
|
||||
return buildStyles();
|
||||
});
|
||||
|
||||
var buildStyles = function() {
|
||||
var sassOptions = {
|
||||
style: 'expanded'
|
||||
};
|
||||
|
||||
var injectFiles = gulp.src([
|
||||
path.join(conf.paths.src, '/app/**/*.scss'),
|
||||
path.join('!' + conf.paths.src, '/app/index.scss')
|
||||
], { read: false });
|
||||
|
||||
var injectOptions = {
|
||||
transform: function(filePath) {
|
||||
filePath = filePath.replace(conf.paths.src + '/app/', '');
|
||||
return '@import "' + filePath + '";';
|
||||
},
|
||||
starttag: '// injector',
|
||||
endtag: '// endinjector',
|
||||
addRootSlash: false
|
||||
};
|
||||
|
||||
|
||||
return gulp.src([
|
||||
path.join(conf.paths.src, '/app/index.scss')
|
||||
])
|
||||
.pipe($.inject(injectFiles, injectOptions))
|
||||
.pipe(wiredep(_.extend({}, conf.wiredep)))
|
||||
.pipe($.sourcemaps.init())
|
||||
.pipe($.sass(sassOptions)).on('error', conf.errorHandler('Sass'))
|
||||
.pipe($.autoprefixer()).on('error', conf.errorHandler('Autoprefixer'))
|
||||
.pipe($.sourcemaps.write())
|
||||
.pipe(gulp.dest(path.join(conf.paths.tmp, '/serve/app/')));
|
||||
};
|
|
@ -1,52 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var karma = require('karma');
|
||||
|
||||
var pathSrcHtml = [
|
||||
path.join(conf.paths.src, '/**/*.html')
|
||||
];
|
||||
|
||||
var pathSrcJs = [
|
||||
path.join(conf.paths.src, '/**/!(*.spec).js')
|
||||
];
|
||||
|
||||
function runTests (singleRun, done) {
|
||||
var reporters = ['progress'];
|
||||
var preprocessors = {};
|
||||
|
||||
pathSrcHtml.forEach(function(path) {
|
||||
preprocessors[path] = ['ng-html2js'];
|
||||
});
|
||||
|
||||
if (singleRun) {
|
||||
pathSrcJs.forEach(function(path) {
|
||||
preprocessors[path] = ['coverage'];
|
||||
});
|
||||
reporters.push('coverage')
|
||||
}
|
||||
|
||||
var localConfig = {
|
||||
configFile: path.join(__dirname, '/../karma.conf.js'),
|
||||
singleRun: singleRun,
|
||||
autoWatch: !singleRun,
|
||||
reporters: reporters,
|
||||
preprocessors: preprocessors
|
||||
};
|
||||
|
||||
var server = new karma.Server(localConfig, function(failCount) {
|
||||
done(failCount ? new Error("Failed " + failCount + " tests.") : null);
|
||||
})
|
||||
server.start();
|
||||
}
|
||||
|
||||
gulp.task('test', ['scripts'], function(done) {
|
||||
runTests(true, done);
|
||||
});
|
||||
|
||||
gulp.task('test:auto', ['watch'], function(done) {
|
||||
runTests(false, done);
|
||||
});
|
|
@ -1,39 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var gulp = require('gulp');
|
||||
var conf = require('./conf');
|
||||
|
||||
var browserSync = require('browser-sync');
|
||||
|
||||
function isOnlyChange(event) {
|
||||
return event.type === 'changed';
|
||||
}
|
||||
|
||||
gulp.task('watch', ['inject'], function () {
|
||||
|
||||
gulp.watch([path.join(conf.paths.src, '/*.html'), 'bower.json'], ['inject-reload']);
|
||||
|
||||
gulp.watch([
|
||||
path.join(conf.paths.src, '/app/**/*.css'),
|
||||
path.join(conf.paths.src, '/app/**/*.scss')
|
||||
], function(event) {
|
||||
if(isOnlyChange(event)) {
|
||||
gulp.start('styles-reload');
|
||||
} else {
|
||||
gulp.start('inject-reload');
|
||||
}
|
||||
});
|
||||
|
||||
gulp.watch(path.join(conf.paths.src, '/app/**/*.js'), function(event) {
|
||||
if(isOnlyChange(event)) {
|
||||
gulp.start('scripts-reload');
|
||||
} else {
|
||||
gulp.start('inject-reload');
|
||||
}
|
||||
});
|
||||
|
||||
gulp.watch(path.join(conf.paths.src, '/app/**/*.html'), function(event) {
|
||||
browserSync.reload(event.path);
|
||||
});
|
||||
});
|
21
webui/gulp_tasks/browsersync.js
Normal file
21
webui/gulp_tasks/browsersync.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
const gulp = require('gulp');
|
||||
const browserSync = require('browser-sync');
|
||||
const spa = require('browser-sync-spa');
|
||||
|
||||
const browserSyncConf = require('../conf/browsersync.conf');
|
||||
const browserSyncDistConf = require('../conf/browsersync-dist.conf');
|
||||
|
||||
browserSync.use(spa());
|
||||
|
||||
gulp.task('browsersync', browserSyncServe);
|
||||
gulp.task('browsersync:dist', browserSyncDist);
|
||||
|
||||
function browserSyncServe(done) {
|
||||
browserSync.init(browserSyncConf());
|
||||
done();
|
||||
}
|
||||
|
||||
function browserSyncDist(done) {
|
||||
browserSync.init(browserSyncDistConf());
|
||||
done();
|
||||
}
|
25
webui/gulp_tasks/karma.js
Normal file
25
webui/gulp_tasks/karma.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const path = require('path');
|
||||
|
||||
const gulp = require('gulp');
|
||||
const karma = require('karma');
|
||||
|
||||
gulp.task('karma:single-run', karmaSingleRun);
|
||||
gulp.task('karma:auto-run', karmaAutoRun);
|
||||
|
||||
function karmaFinishHandler(done) {
|
||||
return failCount => {
|
||||
done(failCount ? new Error(`Failed ${failCount} tests.`) : null);
|
||||
};
|
||||
}
|
||||
|
||||
function karmaSingleRun(done) {
|
||||
const configFile = path.join(process.cwd(), 'conf', 'karma.conf.js');
|
||||
const karmaServer = new karma.Server({configFile}, karmaFinishHandler(done));
|
||||
karmaServer.start();
|
||||
}
|
||||
|
||||
function karmaAutoRun(done) {
|
||||
const configFile = path.join(process.cwd(), 'conf', 'karma-auto.conf.js');
|
||||
const karmaServer = new karma.Server({configFile}, karmaFinishHandler(done));
|
||||
karmaServer.start();
|
||||
}
|
25
webui/gulp_tasks/misc.js
Normal file
25
webui/gulp_tasks/misc.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
const path = require('path');
|
||||
|
||||
const gulp = require('gulp');
|
||||
const del = require('del');
|
||||
const filter = require('gulp-filter');
|
||||
|
||||
const conf = require('../conf/gulp.conf');
|
||||
|
||||
gulp.task('clean', clean);
|
||||
gulp.task('other', other);
|
||||
|
||||
function clean() {
|
||||
return del([conf.paths.tmp]);
|
||||
}
|
||||
|
||||
function other() {
|
||||
const fileFilter = filter(file => file.stat.isFile());
|
||||
|
||||
return gulp.src([
|
||||
path.join(conf.paths.src, '/**/*'),
|
||||
path.join(`!${conf.paths.src}`, '/**/*.{scss,js,html}')
|
||||
])
|
||||
.pipe(fileFilter)
|
||||
.pipe(gulp.dest(conf.paths.dist));
|
||||
}
|
48
webui/gulp_tasks/webpack.js
Normal file
48
webui/gulp_tasks/webpack.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* eslint angular/module-getter:0 */
|
||||
const gulp = require('gulp');
|
||||
const gutil = require('gulp-util');
|
||||
|
||||
const webpack = require('webpack');
|
||||
const webpackConf = require('../conf/webpack.conf');
|
||||
const webpackDistConf = require('../conf/webpack-dist.conf');
|
||||
const browsersync = require('browser-sync');
|
||||
|
||||
gulp.task('webpack:dev', done => {
|
||||
webpackWrapper(false, webpackConf, done);
|
||||
});
|
||||
|
||||
gulp.task('webpack:watch', done => {
|
||||
webpackWrapper(true, webpackConf, done);
|
||||
});
|
||||
|
||||
gulp.task('webpack:dist', done => {
|
||||
webpackWrapper(false, webpackDistConf, done);
|
||||
});
|
||||
|
||||
function webpackWrapper(watch, conf, done) {
|
||||
const webpackBundler = webpack(conf);
|
||||
|
||||
const webpackChangeHandler = (err, stats) => {
|
||||
if (err) {
|
||||
conf.errorHandler('Webpack')(err);
|
||||
}
|
||||
gutil.log(stats.toString({
|
||||
colors: true,
|
||||
chunks: false,
|
||||
hash: false,
|
||||
version: false
|
||||
}));
|
||||
if (done) {
|
||||
done();
|
||||
done = null;
|
||||
} else {
|
||||
browsersync.reload();
|
||||
}
|
||||
};
|
||||
|
||||
if (watch) {
|
||||
webpackBundler.watch(200, webpackChangeHandler);
|
||||
} else {
|
||||
webpackBundler.run(webpackChangeHandler);
|
||||
}
|
||||
}
|
|
@ -1,29 +1,29 @@
|
|||
/**
|
||||
* Welcome to your gulpfile!
|
||||
* The gulp tasks are splitted in several files in the gulp directory
|
||||
* because putting all here was really too long
|
||||
*/
|
||||
const gulp = require('gulp');
|
||||
const HubRegistry = require('gulp-hub');
|
||||
const browserSync = require('browser-sync');
|
||||
|
||||
'use strict';
|
||||
const conf = require('./conf/gulp.conf');
|
||||
|
||||
var gulp = require('gulp');
|
||||
var wrench = require('wrench');
|
||||
// Load some files into the registry
|
||||
const hub = new HubRegistry([conf.path.tasks('*.js')]);
|
||||
|
||||
/**
|
||||
* This will load all js or coffee files in the gulp directory
|
||||
* in order to load all gulp tasks
|
||||
*/
|
||||
wrench.readdirSyncRecursive('./gulp').filter(function(file) {
|
||||
return (/\.(js|coffee)$/i).test(file);
|
||||
}).map(function(file) {
|
||||
require('./gulp/' + file);
|
||||
});
|
||||
// Tell gulp to use the tasks just loaded
|
||||
gulp.registry(hub);
|
||||
|
||||
gulp.task('build', gulp.series(gulp.parallel('other', 'webpack:dist')));
|
||||
gulp.task('test', gulp.series('karma:single-run'));
|
||||
gulp.task('test:auto', gulp.series('karma:auto-run'));
|
||||
gulp.task('serve', gulp.series('webpack:watch', 'watch', 'browsersync'));
|
||||
gulp.task('serve:dist', gulp.series('default', 'browsersync:dist'));
|
||||
gulp.task('default', gulp.series('clean', 'build'));
|
||||
gulp.task('watch', watch);
|
||||
|
||||
/**
|
||||
* Default task clean temporaries directories and launch the
|
||||
* main optimization build task
|
||||
*/
|
||||
gulp.task('default', ['clean'], function () {
|
||||
gulp.start('build');
|
||||
});
|
||||
function reloadBrowserSync(cb) {
|
||||
browserSync.reload();
|
||||
cb();
|
||||
}
|
||||
|
||||
function watch(done) {
|
||||
gulp.watch(conf.path.src('app/**/*.html'), reloadBrowserSync);
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var conf = require('./gulp/conf');
|
||||
|
||||
var _ = require('lodash');
|
||||
var wiredep = require('wiredep');
|
||||
|
||||
var pathSrcHtml = [
|
||||
path.join(conf.paths.src, '/**/*.html')
|
||||
];
|
||||
|
||||
function listFiles() {
|
||||
var wiredepOptions = _.extend({}, conf.wiredep, {
|
||||
dependencies: true,
|
||||
devDependencies: true
|
||||
});
|
||||
|
||||
var patterns = wiredep(wiredepOptions).js
|
||||
.concat([
|
||||
path.join(conf.paths.src, '/app/**/*.module.js'),
|
||||
path.join(conf.paths.src, '/app/**/*.js'),
|
||||
path.join(conf.paths.src, '/**/*.spec.js'),
|
||||
path.join(conf.paths.src, '/**/*.mock.js'),
|
||||
])
|
||||
.concat(pathSrcHtml);
|
||||
|
||||
var files = patterns.map(function(pattern) {
|
||||
return {
|
||||
pattern: pattern
|
||||
};
|
||||
});
|
||||
files.push({
|
||||
pattern: path.join(conf.paths.src, '/assets/**/*'),
|
||||
included: false,
|
||||
served: true,
|
||||
watched: false
|
||||
});
|
||||
return files;
|
||||
}
|
||||
|
||||
module.exports = function(config) {
|
||||
|
||||
var configuration = {
|
||||
files: listFiles(),
|
||||
|
||||
singleRun: true,
|
||||
|
||||
autoWatch: false,
|
||||
|
||||
ngHtml2JsPreprocessor: {
|
||||
stripPrefix: conf.paths.src + '/',
|
||||
moduleName: 'traefik'
|
||||
},
|
||||
|
||||
logLevel: 'WARN',
|
||||
|
||||
frameworks: ['jasmine', 'angular-filesort'],
|
||||
|
||||
angularFilesort: {
|
||||
whitelist: [path.join(conf.paths.src, '/**/!(*.html|*.spec|*.mock).js')]
|
||||
},
|
||||
|
||||
browsers : ['PhantomJS'],
|
||||
|
||||
plugins : [
|
||||
'karma-phantomjs-launcher',
|
||||
'karma-angular-filesort',
|
||||
'karma-coverage',
|
||||
'karma-jasmine',
|
||||
'karma-ng-html2js-preprocessor'
|
||||
],
|
||||
|
||||
coverageReporter: {
|
||||
type : 'html',
|
||||
dir : 'coverage/'
|
||||
},
|
||||
|
||||
reporters: ['progress'],
|
||||
|
||||
proxies: {
|
||||
'/assets/': path.join('/base/', conf.paths.src, '/assets/')
|
||||
}
|
||||
};
|
||||
|
||||
// This is the default preprocessors configuration for a usage with Karma cli
|
||||
// The coverage preprocessor is added in gulp/unit-test.js only for single tests
|
||||
// It was not possible to do it there because karma doesn't let us now if we are
|
||||
// running a single test or not
|
||||
configuration.preprocessors = {};
|
||||
pathSrcHtml.forEach(function(path) {
|
||||
configuration.preprocessors[path] = ['ng-html2js'];
|
||||
});
|
||||
|
||||
// This block is needed to execute Chrome on Travis
|
||||
// If you ever plan to use Chrome and Travis, you can keep it
|
||||
// If not, you can safely remove it
|
||||
// https://github.com/karma-runner/karma/issues/1144#issuecomment-53633076
|
||||
if(configuration.browsers[0] === 'Chrome' && process.env.TRAVIS) {
|
||||
configuration.customLaunchers = {
|
||||
'chrome-travis-ci': {
|
||||
base: 'Chrome',
|
||||
flags: ['--no-sandbox']
|
||||
}
|
||||
};
|
||||
configuration.browsers = ['chrome-travis-ci'];
|
||||
}
|
||||
|
||||
config.set(configuration);
|
||||
};
|
|
@ -1,55 +1,102 @@
|
|||
{
|
||||
"name": "traefik",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {},
|
||||
"scripts": {
|
||||
"test": "gulp test"
|
||||
"version": "2.0.0",
|
||||
"homepage": "http://traefik.io",
|
||||
"authors": [
|
||||
"Fernandez Ludovic <lfernandez.dev@gmail.com>",
|
||||
"Micaël Mbagira <micael.mbagira@icloud.com>"
|
||||
],
|
||||
"description": "Front end for Træfɪk",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"angular": "^1.4.2",
|
||||
"angular-animate": "^1.5.8",
|
||||
"animate.css": "^3.4.0",
|
||||
"angular-aria": "^1.5.8",
|
||||
"angular-cookies": "^1.5.8",
|
||||
"angular-messages": "^1.5.8",
|
||||
"angular-nvd3": "^1.0.8",
|
||||
"angular-resource": "^1.5.8",
|
||||
"angular-sanitize": "^1.5.8",
|
||||
"angular-ui-bootstrap": "^2.0.0",
|
||||
"angular-ui-router": "^0.3.1",
|
||||
"bootstrap": "^3.3.6",
|
||||
"moment": "^2.14.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"estraverse": "~4.1.0",
|
||||
"gulp": "~3.9.0",
|
||||
"gulp-autoprefixer": "~3.0.2",
|
||||
"gulp-angular-templatecache": "~1.8.0",
|
||||
"del": "~2.0.2",
|
||||
"lodash": "~3.10.1",
|
||||
"gulp-minify-css": "~1.2.1",
|
||||
"gulp-filter": "~3.0.1",
|
||||
"gulp-flatten": "~0.2.0",
|
||||
"gulp-eslint": "~1.0.0",
|
||||
"eslint-plugin-angular": "~0.12.0",
|
||||
"gulp-load-plugins": "~0.10.0",
|
||||
"gulp-size": "~2.0.0",
|
||||
"gulp-uglify": "~1.4.1",
|
||||
"gulp-useref": "~1.3.0",
|
||||
"gulp-util": "~3.0.6",
|
||||
"gulp-ng-annotate": "~1.1.0",
|
||||
"gulp-replace": "~0.5.4",
|
||||
"gulp-rename": "~1.2.2",
|
||||
"gulp-rev": "~6.0.1",
|
||||
"gulp-rev-replace": "~0.4.2",
|
||||
"gulp-minify-html": "~1.0.4",
|
||||
"gulp-inject": "~3.0.0",
|
||||
"gulp-protractor": "~1.0.0",
|
||||
"gulp-sourcemaps": "~1.6.0",
|
||||
"gulp-sass": "~2.0.4",
|
||||
"gulp-angular-filesort": "~1.1.1",
|
||||
"main-bower-files": "~2.9.0",
|
||||
"wiredep": "~2.2.2",
|
||||
"karma": "~0.13.10",
|
||||
"karma-jasmine": "~0.3.6",
|
||||
"karma-phantomjs-launcher": "~0.2.1",
|
||||
"phantomjs": "~1.9.18",
|
||||
"karma-angular-filesort": "~1.0.0",
|
||||
"karma-coverage": "~0.5.2",
|
||||
"karma-ng-html2js-preprocessor": "~0.2.0",
|
||||
"browser-sync": "~2.9.11",
|
||||
"browser-sync-spa": "~1.0.3",
|
||||
"http-proxy-middleware": "~0.9.0",
|
||||
"chalk": "~1.1.1",
|
||||
"uglify-save-license": "~0.4.1",
|
||||
"wrench": "~1.5.8"
|
||||
"angular-mocks": "^1.4.2",
|
||||
"autoprefixer": "^6.2.2",
|
||||
"babel-loader": "^6.2.0",
|
||||
"browser-sync": "^2.9.11",
|
||||
"browser-sync-spa": "^1.0.3",
|
||||
"css-loader": "^0.23.1",
|
||||
"del": "^2.0.2",
|
||||
"es6-shim": "^0.35.0",
|
||||
"eslint": "^2.11.0",
|
||||
"eslint-config-angular": "^0.5.0",
|
||||
"eslint-config-xo-space": "^0.12.0",
|
||||
"eslint-loader": "^1.3.0",
|
||||
"eslint-plugin-angular": "^1.3.0",
|
||||
"extract-text-webpack-plugin": "^1.0.1",
|
||||
"file-loader": "^0.9.0",
|
||||
"gulp": "gulpjs/gulp#4ed9a4a3275559c73a396eff7e1fde3824951ebb",
|
||||
"gulp-angular-filesort": "^1.1.1",
|
||||
"gulp-angular-templatecache": "^1.8.0",
|
||||
"gulp-filter": "^4.0.0",
|
||||
"gulp-htmlmin": "^1.3.0",
|
||||
"gulp-hub": "frankwallis/gulp-hub#d461b9c700df9010d0a8694e4af1fb96d9f38bf4",
|
||||
"gulp-insert": "^0.5.0",
|
||||
"gulp-ng-annotate": "^1.1.0",
|
||||
"gulp-sass": "^2.1.1",
|
||||
"gulp-util": "^3.0.7",
|
||||
"html-loader": "^0.4.3",
|
||||
"html-webpack-plugin": "^2.9.0",
|
||||
"isparta-loader": "^2.0.0",
|
||||
"jasmine": "^2.4.1",
|
||||
"json-loader": "^0.5.4",
|
||||
"karma": "^0.13.14",
|
||||
"karma-angular-filesort": "^1.0.0",
|
||||
"karma-coverage": "^0.5.3",
|
||||
"karma-jasmine": "^0.3.8",
|
||||
"karma-junit-reporter": "^0.4.2",
|
||||
"karma-ng-html2js-preprocessor": "^0.2.0",
|
||||
"karma-phantomjs-launcher": "^1.0.0",
|
||||
"karma-phantomjs-shim": "^1.1.2",
|
||||
"karma-webpack": "^1.7.0",
|
||||
"ng-annotate-loader": "^0.0.10",
|
||||
"node-sass": "^3.4.2",
|
||||
"phantomjs-prebuilt": "^2.1.6",
|
||||
"postcss-loader": "^0.8.0",
|
||||
"sass-loader": "^3.1.2",
|
||||
"style-loader": "^0.13.0",
|
||||
"url-loader": "^0.5.7",
|
||||
"webpack": "2.1.0-beta.15",
|
||||
"webpack-split-by-path": "^0.0.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
"scripts": {
|
||||
"build": "gulp",
|
||||
"serve": "gulp serve",
|
||||
"serve:dist": "gulp serve:dist",
|
||||
"test": "gulp test",
|
||||
"test:auto": "gulp test:auto"
|
||||
},
|
||||
"overrides": {
|
||||
"angular-nvd3": {
|
||||
"main": "dist/angular-nvd3.js"
|
||||
}
|
||||
},
|
||||
"eslintConfig": {
|
||||
"globals": {
|
||||
"expect": true
|
||||
},
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"jasmine": true
|
||||
},
|
||||
"extends": [
|
||||
"angular",
|
||||
"xo-space"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var paths = require('./.yo-rc.json')['generator-gulp-angular'].props.paths;
|
||||
|
||||
// An example configuration file.
|
||||
exports.config = {
|
||||
// The address of a running selenium server.
|
||||
//seleniumAddress: 'http://localhost:4444/wd/hub',
|
||||
//seleniumServerJar: deprecated, this should be set on node_modules/protractor/config.json
|
||||
|
||||
// Capabilities to be passed to the webdriver instance.
|
||||
capabilities: {
|
||||
'browserName': 'chrome'
|
||||
},
|
||||
|
||||
baseUrl: 'http://localhost:3000',
|
||||
|
||||
// Spec patterns are relative to the current working directory when
|
||||
// protractor is called.
|
||||
specs: [paths.e2e + '/**/*.js'],
|
||||
|
||||
// Options to be passed to Jasmine-node.
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 30000
|
||||
}
|
||||
};
|
|
@ -19,13 +19,12 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
|
|||
|
||||
## How to build (only for frontends developer)
|
||||
|
||||
- prerequisite: [Node](https://nodejs.org)
|
||||
- prerequisite: [Node 4+ and NPM 3+](https://nodejs.org)
|
||||
|
||||
- Go to the directory `webui`
|
||||
|
||||
- To install dependencies, execute the following commands:
|
||||
- `npm install`
|
||||
- `bower install`
|
||||
|
||||
- Build static Web UI, execute the following command:
|
||||
- `gulp`
|
||||
|
@ -40,6 +39,7 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
|
|||
- add vendor prefixes to CSS (cross-bowser support)
|
||||
- add a hash in the file names to prevent browser cache problems
|
||||
- all images will be optimized at build
|
||||
- bundle JavaScript in one file
|
||||
|
||||
|
||||
## How to edit (only for frontends developer)
|
||||
|
@ -62,7 +62,8 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
|
|||
## Libraries
|
||||
|
||||
- [Node](https://nodejs.org)
|
||||
- [Generator Gulp-Angular](https://github.com/Swiip/generator-gulp-angular)
|
||||
- [Generator FountainJS](https://github.com/FountainJS/generator-fountain-webapp)
|
||||
- [Webpack](https://github.com/webpack/webpack)
|
||||
- [AngularJS](https://docs.angularjs.org/api)
|
||||
- [UI Router](https://github.com/angular-ui/ui-router)
|
||||
- [UI Router - Documentation](https://github.com/angular-ui/ui-router/wiki)
|
||||
|
@ -71,4 +72,4 @@ make generate-webui # Generate static contents in `traefik/static/` folder.
|
|||
- [D3](http://d3js.org)
|
||||
- [D3 - Documentation](https://github.com/mbostock/d3/wiki)
|
||||
- [NVD3](http://nvd3.org)
|
||||
- [Angular nvD3](http://krispo.github.io/angular-nvd3)
|
||||
- [Angular nvD3](http://krispo.github.io/angular-nvd3)
|
|
@ -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');
|
||||
}
|
|
@ -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');
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('traefik')
|
||||
.config(config);
|
||||
|
||||
/** @ngInject */
|
||||
function config($logProvider) {
|
||||
// Enable log
|
||||
$logProvider.debugEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
})();
|
|
@ -1,9 +0,0 @@
|
|||
/* global moment:false */
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('traefik')
|
||||
.constant('moment', moment);
|
||||
|
||||
})();
|
|
@ -1,7 +0,0 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('traefik', ['ngAnimate', 'ngCookies', 'ngSanitize', 'ngMessages', 'ngAria', 'ngResource', 'ui.router', 'ui.bootstrap', 'traefik.section']);
|
||||
|
||||
})();
|
|
@ -1,14 +0,0 @@
|
|||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('traefik')
|
||||
.run(runBlock);
|
||||
|
||||
/** @ngInject */
|
||||
function runBlock($log) {
|
||||
|
||||
$log.debug('runBlock end');
|
||||
}
|
||||
|
||||
})();
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
||||
});
|
||||
|
||||
})();
|
||||
}
|
|
@ -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;
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
|
@ -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'
|
||||
});
|
||||
|
||||
})();
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('traefik.section')
|
||||
.config(config);
|
||||
|
||||
/** @ngInject */
|
||||
function config($urlRouterProvider) {
|
||||
$urlRouterProvider.otherwise('/');
|
||||
}
|
||||
|
||||
})();
|
24
webui/src/app/sections/sections.js
Normal file
24
webui/src/app/sections/sections.js
Normal 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('/');
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
(function () {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('traefik.section', [
|
||||
'ui.router',
|
||||
'ui.bootstrap',
|
||||
'nvd3',
|
||||
'traefik.section.providers',
|
||||
'traefik.section.health'
|
||||
]);
|
||||
|
||||
})();
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
46
webui/src/index.js
Normal 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
3
webui/src/index.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
$icon-font-path: "../bower_components/bootstrap-sass/assets/fonts/bootstrap/";
|
||||
@import 'app/index.scss';
|
||||
@import 'app/traefik.scss';
|
Loading…
Reference in a new issue