Replace require.js loader/r.js builder with webpack
Webpack is much more powerful than r.js and opens path to further improvements in testing, build speed, developer convenience, ES2015, etc. Implements blueprint webpack Change-Id: I18a3b74db243f29e5dacb004569d66463f4ab16d
This commit is contained in:
parent
aa6e317fb1
commit
ac33818194
|
@ -98,10 +98,12 @@
|
|||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"mocha": true,
|
||||
"amd": true
|
||||
},
|
||||
"globals": {
|
||||
"app": false,
|
||||
"requirejs": false
|
||||
"assert": false,
|
||||
"sinon": false
|
||||
}
|
||||
}
|
||||
|
|
215
gulpfile.js
215
gulpfile.js
|
@ -21,77 +21,19 @@ var argv = require('minimist')(process.argv.slice(2));
|
|||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var glob = require('glob');
|
||||
var spawn = require('child_process').spawn;
|
||||
var rimraf = require('rimraf');
|
||||
var es = require('event-stream');
|
||||
var _ = require('lodash');
|
||||
|
||||
var webpack = require('webpack');
|
||||
|
||||
var gulp = require('gulp');
|
||||
var gutil = require('gulp-util');
|
||||
var shell = require('gulp-shell');
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
var filter = require('gulp-filter');
|
||||
var react = require('gulp-react');
|
||||
var less = require('gulp-less');
|
||||
var autoprefixer = require('gulp-autoprefixer');
|
||||
var replace = require('gulp-replace');
|
||||
var jison = require('gulp-jison');
|
||||
var lintspaces = require('gulp-lintspaces');
|
||||
|
||||
var jscs = require('gulp-jscs');
|
||||
var jscsConfig = JSON.parse(fs.readFileSync('./.jscsrc'));
|
||||
|
||||
var intermediate = require('gulp-intermediate');
|
||||
var rjs = require('requirejs');
|
||||
var rjsConfig = _.merge(rjs('static/config.js'), {
|
||||
baseUrl: '.',
|
||||
appDir: 'static',
|
||||
optimize: 'uglify2',
|
||||
optimizeCss: 'standard',
|
||||
generateSourceMaps: true,
|
||||
preserveLicenseComments: false, // required for generateSourceMaps
|
||||
wrapShim: true,
|
||||
pragmas: {
|
||||
compressed: true
|
||||
},
|
||||
map: {
|
||||
'*': {
|
||||
JSXTransformer: 'empty:'
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
react: 'vendor/npm/react/dist/react-with-addons.min'
|
||||
},
|
||||
stubModules: ['jsx'],
|
||||
modules: [
|
||||
{
|
||||
name: 'main',
|
||||
exclude: ['require-css/normalize']
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
var jsFilter = filter('**/*.js');
|
||||
var jsxFilter = filter('**/*.jsx');
|
||||
var lessFilter = filter('**/*.less');
|
||||
var indexFilter = filter('index.html');
|
||||
var buildSourceFilter = filter([
|
||||
'**',
|
||||
'!tests/**'
|
||||
]);
|
||||
var buildResultFilter = filter([
|
||||
'index.html',
|
||||
'main.js',
|
||||
'main.js.map',
|
||||
'vendor/npm/requirejs/require.js',
|
||||
'vendor/npm/requirejs/require.js.map',
|
||||
'styles/*.css',
|
||||
'favicon.ico',
|
||||
'img/**',
|
||||
'**/*.+(ttf|eot|svg|woff|woff2)',
|
||||
'plugins/**'
|
||||
]);
|
||||
|
||||
var validateTranslations = require('./gulp/i18n').validate;
|
||||
gulp.task('i18n:validate', function() {
|
||||
|
@ -100,20 +42,6 @@ gulp.task('i18n:validate', function() {
|
|||
validateTranslations(tranlations, locales);
|
||||
});
|
||||
|
||||
gulp.task('copy-main', function() {
|
||||
var config = JSON.parse(fs.readFileSync('package.json'));
|
||||
var streams = _.map(config.mainFiles, function(files, package) {
|
||||
if (!(package in config.dependencies) && !(package in config.devDependencies)) {
|
||||
throw new Error(package + ' is not a dependency');
|
||||
}
|
||||
return _.map(_.isArray(files) ? files : [files], function(file) {
|
||||
return gulp.src('node_modules/' + package + '/' + file, {base: 'node_modules'})
|
||||
.pipe(gulp.dest('static/vendor/npm/'));
|
||||
});
|
||||
});
|
||||
return es.merge(_.flatten(streams));
|
||||
});
|
||||
|
||||
var selenium = require('selenium-standalone');
|
||||
var seleniumProcess = null;
|
||||
function shutdownSelenium() {
|
||||
|
@ -148,6 +76,14 @@ gulp.task('selenium', ['selenium:fetch'], function(cb) {
|
|||
);
|
||||
});
|
||||
|
||||
gulp.task('karma', function(cb) {
|
||||
var Server = require('karma').Server;
|
||||
new Server({
|
||||
configFile: __dirname + '/karma.config.js',
|
||||
browsers: [argv.browser || 'firefox']
|
||||
}, cb).start();
|
||||
});
|
||||
|
||||
function runIntern(params) {
|
||||
return function() {
|
||||
var baseDir = 'static';
|
||||
|
@ -175,11 +111,10 @@ function runIntern(params) {
|
|||
};
|
||||
}
|
||||
|
||||
gulp.task('intern:unit', runIntern({suites: argv.suites || 'static/tests/unit/**/*.js'}));
|
||||
gulp.task('intern:functional', runIntern({functionalSuites: argv.suites || 'static/tests/functional/**/test_*.js'}));
|
||||
|
||||
gulp.task('unit-tests', function(cb) {
|
||||
runSequence('selenium', 'intern:unit', function(err) {
|
||||
runSequence('selenium', 'karma', function(err) {
|
||||
shutdownSelenium();
|
||||
cb(err);
|
||||
});
|
||||
|
@ -201,6 +136,7 @@ gulp.task('jison', function() {
|
|||
var jsFiles = [
|
||||
'static/**/*.js',
|
||||
'static/**/*.jsx',
|
||||
'!static/build/**',
|
||||
'!static/vendor/**',
|
||||
'!static/expression/parser.js',
|
||||
'static/tests/**/*.js'
|
||||
|
@ -208,22 +144,26 @@ var jsFiles = [
|
|||
var styleFiles = [
|
||||
'static/**/*.less',
|
||||
'static/**/*.css',
|
||||
'!static/build/**',
|
||||
'!static/vendor/**'
|
||||
];
|
||||
|
||||
gulp.task('jscs:fix', function() {
|
||||
var jscs = require('gulp-jscs');
|
||||
var jscsConfig = JSON.parse(fs.readFileSync('./.jscsrc'));
|
||||
return gulp.src(jsFiles, {base: '.'})
|
||||
.pipe(jscs(_.extend({fix: true}, jscsConfig)))
|
||||
.pipe(gulp.dest('.'));
|
||||
});
|
||||
|
||||
gulp.task('jscs', function() {
|
||||
var jscs = require('gulp-jscs');
|
||||
var jscsConfig = JSON.parse(fs.readFileSync('./.jscsrc'));
|
||||
return gulp.src(jsFiles)
|
||||
.pipe(jscs(jscsConfig));
|
||||
});
|
||||
|
||||
gulp.task('eslint', function() {
|
||||
// FIXME(vkramskikh): move to top after fixing packaging issues
|
||||
var eslint = require('gulp-eslint');
|
||||
var eslintConfig = JSON.parse(fs.readFileSync('./.eslintrc'));
|
||||
return gulp.src(jsFiles)
|
||||
|
@ -240,6 +180,7 @@ var lintspacesConfig = {
|
|||
};
|
||||
|
||||
gulp.task('lintspaces:js', function() {
|
||||
var lintspaces = require('gulp-lintspaces');
|
||||
return gulp.src(jsFiles)
|
||||
.pipe(lintspaces(_.extend({}, lintspacesConfig, {
|
||||
ignores: ['js-comments'],
|
||||
|
@ -249,6 +190,7 @@ gulp.task('lintspaces:js', function() {
|
|||
});
|
||||
|
||||
gulp.task('lintspaces:styles', function() {
|
||||
var lintspaces = require('gulp-lintspaces');
|
||||
return gulp.src(styleFiles)
|
||||
.pipe(lintspaces(_.extend({}, lintspacesConfig, {
|
||||
ignores: ['js-comments'],
|
||||
|
@ -265,46 +207,95 @@ gulp.task('lint', [
|
|||
'lintspaces:styles'
|
||||
]);
|
||||
|
||||
gulp.task('rjs', function() {
|
||||
var targetDir = argv['static-dir'] || '/tmp/static_compressed';
|
||||
rimraf.sync(targetDir);
|
||||
var WEBPACK_STATS_OPTIONS = {
|
||||
colors: true,
|
||||
hash: false,
|
||||
version: false,
|
||||
assets: false,
|
||||
chunks: false
|
||||
};
|
||||
|
||||
return gulp.src(['static/**'])
|
||||
.pipe(jsxFilter)
|
||||
.pipe(react())
|
||||
.pipe(jsxFilter.restore())
|
||||
.pipe(lessFilter)
|
||||
.pipe(less())
|
||||
.pipe(autoprefixer())
|
||||
.pipe(lessFilter.restore())
|
||||
.pipe(jsFilter)
|
||||
// use CSS loader instead LESS loader - styles are precompiled
|
||||
.pipe(replace(/less!/g, 'require-css/css!'))
|
||||
// remove explicit calls to JSX loader plugin
|
||||
.pipe(replace(/jsx!/g, ''))
|
||||
.pipe(jsFilter.restore())
|
||||
.pipe(indexFilter)
|
||||
.pipe(replace('__CACHE_BUST__', Date.now()))
|
||||
.pipe(indexFilter.restore())
|
||||
.pipe(buildSourceFilter)
|
||||
.pipe(intermediate({output: '_build'}, function(tempDir, cb) {
|
||||
var configFile = path.join(tempDir, 'build.json');
|
||||
rjsConfig.appDir = tempDir;
|
||||
rjsConfig.dir = path.join(tempDir, '_build');
|
||||
fs.createWriteStream(configFile).write(JSON.stringify(rjsConfig));
|
||||
gulp.task('dev-server', function() {
|
||||
var devServerHost = argv['dev-server-host'] || '127.0.0.1';
|
||||
var devServerPort = argv['dev-server-port'] || 8080;
|
||||
var devServerUrl = 'http://' + devServerHost + ':' + devServerPort;
|
||||
var nailgunHost = argv['nailgun-host'] || '127.0.0.1';
|
||||
var nailgunPort = argv['nailgun-port'] || 8000;
|
||||
var nailgunUrl = 'http://' + nailgunHost + ':' + nailgunPort;
|
||||
var hotReload = !argv['no-hot'];
|
||||
|
||||
var rjs = spawn('./node_modules/.bin/r.js', ['-o', configFile]);
|
||||
rjs.stdout.on('data', function(data) {
|
||||
_(data.toString().split('\n')).compact().each(_.ary(gutil.log, 1)).value();
|
||||
});
|
||||
rjs.on('close', cb);
|
||||
}))
|
||||
.pipe(buildResultFilter)
|
||||
.pipe(gulp.dest(targetDir));
|
||||
var config = require('./webpack.config');
|
||||
config.entry.push('webpack-dev-server/client?' + devServerUrl);
|
||||
if (hotReload) {
|
||||
config.entry.push('webpack/hot/dev-server');
|
||||
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
||||
config.plugins.push(new webpack.NoErrorsPlugin());
|
||||
}
|
||||
|
||||
var WebpackDevServer = require('webpack-dev-server');
|
||||
var options = {
|
||||
hot: hotReload,
|
||||
stats: WEBPACK_STATS_OPTIONS,
|
||||
proxy: [
|
||||
{path: '/', target: devServerUrl, rewrite: function(req) {
|
||||
req.url = '/static/index.html';
|
||||
}},
|
||||
{path: /^\/(?!static\/).+/, target: nailgunUrl}
|
||||
]
|
||||
};
|
||||
_.extend(options, config.output);
|
||||
new WebpackDevServer(webpack(config), options).listen(devServerPort, devServerHost, function(err) {
|
||||
if (err) throw err;
|
||||
gutil.log('Development server started at ' + devServerUrl);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('build', function(cb) {
|
||||
runSequence('copy-main', 'rjs', cb);
|
||||
var sourceDir = path.resolve('static');
|
||||
var targetDir = argv['static-dir'] ? path.resolve(argv['static-dir']) : sourceDir;
|
||||
|
||||
var config = require('./webpack.config');
|
||||
config.output.path = path.join(targetDir, 'build');
|
||||
if (!argv.dev) {
|
||||
config.plugins.push(
|
||||
new webpack.DefinePlugin({'process.env': {NODE_ENV: '"production"'}}),
|
||||
new webpack.optimize.DedupePlugin()
|
||||
);
|
||||
}
|
||||
if (argv.uglify) {
|
||||
config.plugins.push(
|
||||
new webpack.optimize.UglifyJsPlugin({compress: {warnings: false}})
|
||||
);
|
||||
}
|
||||
|
||||
rimraf.sync(config.output.path);
|
||||
|
||||
webpack(config).run(function(err, stats) {
|
||||
if (err) return cb(err);
|
||||
|
||||
gutil.log(stats.toString(WEBPACK_STATS_OPTIONS));
|
||||
|
||||
if (stats.hasErrors()) return cb('Build failed');
|
||||
|
||||
if (targetDir != sourceDir) {
|
||||
var indexFilter = filter('index.html');
|
||||
gulp
|
||||
.src([
|
||||
'index.html',
|
||||
'favicon.ico',
|
||||
'img/loader-bg.svg',
|
||||
'img/loader-logo.svg',
|
||||
'styles/layout.css'
|
||||
], {cwd: sourceDir, base: sourceDir})
|
||||
.pipe(indexFilter)
|
||||
.pipe(replace('__CACHE_BUST__', Date.now()))
|
||||
.pipe(indexFilter.restore())
|
||||
.pipe(gulp.dest(targetDir))
|
||||
.on('end', cb);
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('default', ['build']);
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*eslint-disable strict*/
|
||||
|
||||
var webpackConfig = require('./webpack.config');
|
||||
|
||||
module.exports = function(config) {
|
||||
config.set({
|
||||
browsers: ['firefox'],
|
||||
files: [
|
||||
'static/tests/unit/**/*.js'
|
||||
],
|
||||
frameworks: [
|
||||
'chai',
|
||||
'mocha',
|
||||
'sinon'
|
||||
],
|
||||
plugins: [
|
||||
'karma-webdriver-launcher',
|
||||
'karma-chai',
|
||||
'karma-mocha',
|
||||
'karma-sinon',
|
||||
'karma-webpack'
|
||||
],
|
||||
preprocessors: {
|
||||
'static/tests/unit/**/*.js': ['webpack']
|
||||
},
|
||||
reporters: ['dots'],
|
||||
singleRun: true,
|
||||
client: {
|
||||
mocha: {
|
||||
ui: 'tdd'
|
||||
}
|
||||
},
|
||||
customLaunchers: {
|
||||
chrome: {
|
||||
base: 'WebDriver',
|
||||
browserName: 'chrome'
|
||||
},
|
||||
firefox: {
|
||||
base: 'WebDriver',
|
||||
browserName: 'firefox'
|
||||
},
|
||||
phantomjs: {
|
||||
base: 'WebDriver',
|
||||
browserName: 'phantomjs'
|
||||
}
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {
|
||||
noInfo: true
|
||||
}
|
||||
});
|
||||
};
|
File diff suppressed because it is too large
Load Diff
108
package.json
108
package.json
|
@ -5,93 +5,63 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/openstack/fuel-web.git"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "./node_modules/.bin/gulp copy-main"
|
||||
},
|
||||
"dependencies": {
|
||||
"autoprefixer": "5.2.0",
|
||||
"babel-core": "5.8.23",
|
||||
"babel-loader": "5.3.2",
|
||||
"backbone": "1.2.1",
|
||||
"backbone.stickit": "0.9.2",
|
||||
"bootstrap": "3.3.4",
|
||||
"classnames": "1.1.4",
|
||||
"css-loader": "0.17.0",
|
||||
"exports-loader": "0.6.2",
|
||||
"expose-loader": "0.7.0",
|
||||
"file-loader": "0.8.4",
|
||||
"gulp": "3.8.11",
|
||||
"gulp-filter": "2.0.1",
|
||||
"gulp-jison": "1.2.0",
|
||||
"gulp-replace": "0.5.3",
|
||||
"gulp-util": "3.0.4",
|
||||
"i18next": "1.7.1",
|
||||
"imports-loader": "0.6.4",
|
||||
"jquery": "1.11.3",
|
||||
"js-cookie": "1.5.1",
|
||||
"json-loader": "0.5.3",
|
||||
"less": "2.4.0",
|
||||
"less-loader": "2.2.1",
|
||||
"lodash": "3.9.3",
|
||||
"minimist": "1.1.1",
|
||||
"open-sans-fontface": "1.4.0",
|
||||
"postcss-loader": "0.5.1",
|
||||
"raw-loader": "0.5.1",
|
||||
"react": "0.13.3",
|
||||
"react-dnd": "1.1.3",
|
||||
"require-css": "0.1.8",
|
||||
"requirejs": "2.1.20",
|
||||
"requirejs-plugins": "1.0.2"
|
||||
"rimraf": "2.2.8",
|
||||
"run-sequence": "1.0.2",
|
||||
"style-loader": "0.12.4",
|
||||
"webpack": "1.12.0",
|
||||
"uglify-js": "2.4.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"es5-shim": "~4.1.11",
|
||||
"eslint-plugin-react": "~3.1.0",
|
||||
"chai": "~3.2.0",
|
||||
"es5-shim": "4.1.11",
|
||||
"eslint-plugin-react": "3.1.0",
|
||||
"esprima-fb": "13001.1001.0-dev-harmony-fb",
|
||||
"event-stream": "~3.3.1",
|
||||
"glob": "~5.0.5",
|
||||
"gulp": "~3.8.11",
|
||||
"gulp-autoprefixer": "~2.1.0",
|
||||
"gulp-eslint": "~1.0.0",
|
||||
"gulp-filter": "~2.0.1",
|
||||
"gulp-intermediate": "~3.0.1",
|
||||
"gulp-jison": "~1.2.0",
|
||||
"gulp-jscs": "~1.6.0",
|
||||
"gulp-less": "~3.0.2",
|
||||
"gulp-lintspaces": "~0.3.1",
|
||||
"gulp-react": "~3.0.1",
|
||||
"gulp-replace": "~0.5.3",
|
||||
"gulp-shell": "~0.4.1",
|
||||
"gulp-util": "~3.0.4",
|
||||
"intern": "~2.2.2",
|
||||
"minimist": "~1.1.1",
|
||||
"rimraf": "~2.2.8",
|
||||
"run-sequence": "~1.0.2",
|
||||
"gulp-eslint": "1.0.0",
|
||||
"gulp-jscs": "1.6.0",
|
||||
"gulp-lintspaces": "0.3.1",
|
||||
"gulp-shell": "0.4.1",
|
||||
"intern": "2.2.2",
|
||||
"karma": "~0.13.9",
|
||||
"karma-chai": "~0.1.0",
|
||||
"karma-mocha": "~0.2.0",
|
||||
"karma-sinon": "~1.0.4",
|
||||
"karma-webdriver-launcher": "1.0.0",
|
||||
"karma-webpack": "~1.7.0",
|
||||
"mocha": "~2.3.2",
|
||||
"selenium-standalone": "~4.4.0",
|
||||
"sinon": "~1.15.3",
|
||||
"uglify-js": "~2.4.21"
|
||||
},
|
||||
"mainFiles": {
|
||||
"backbone": "backbone.js",
|
||||
"backbone.stickit": "backbone.stickit.js",
|
||||
"bootstrap": [
|
||||
"dist/js/bootstrap.js",
|
||||
"dist/css/bootstrap.css",
|
||||
"dist/css/bootstrap.css.map",
|
||||
"dist/fonts/*"
|
||||
],
|
||||
"classnames": "index.js",
|
||||
"es5-shim": "es5-shim.js",
|
||||
"i18next": "lib/dep/i18next-1.7.1.js",
|
||||
"jquery": "dist/jquery.js",
|
||||
"js-cookie": "src/js.cookie.js",
|
||||
"less": "dist/less.js",
|
||||
"lodash": "index.js",
|
||||
"open-sans-fontface": [
|
||||
"./open-sans.css",
|
||||
"./fonts/**/*"
|
||||
],
|
||||
"react": [
|
||||
"dist/JSXTransformer.js",
|
||||
"dist/react-with-addons.js",
|
||||
"dist/react-with-addons.min.js"
|
||||
],
|
||||
"react-dnd": "dist/ReactDnD.min.js",
|
||||
"require-css": [
|
||||
"css.js",
|
||||
"css-builder.js",
|
||||
"normalize.js"
|
||||
],
|
||||
"requirejs": "require.js",
|
||||
"requirejs-plugins": [
|
||||
"lib/text.js",
|
||||
"src/json.js"
|
||||
],
|
||||
"sinon": [
|
||||
"lib/sinon.js",
|
||||
"lib/sinon/*",
|
||||
"lib/sinon/util/*"
|
||||
]
|
||||
"webpack-dev-server": "1.11.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,26 +22,25 @@ define(
|
|||
'backbone',
|
||||
'react',
|
||||
'utils',
|
||||
'jsx!views/layout',
|
||||
'views/layout',
|
||||
'coccyx',
|
||||
'models',
|
||||
'keystone_client',
|
||||
'jsx!views/root',
|
||||
'jsx!views/login_page',
|
||||
'jsx!views/welcome_page',
|
||||
'jsx!views/cluster_page',
|
||||
'jsx!views/clusters_page',
|
||||
'jsx!views/releases_page',
|
||||
'jsx!views/plugins_page',
|
||||
'jsx!views/notifications_page',
|
||||
'jsx!views/support_page',
|
||||
'jsx!views/capacity_page',
|
||||
'views/root',
|
||||
'views/login_page',
|
||||
'views/welcome_page',
|
||||
'views/cluster_page',
|
||||
'views/clusters_page',
|
||||
'views/releases_page',
|
||||
'views/plugins_page',
|
||||
'views/notifications_page',
|
||||
'views/support_page',
|
||||
'views/capacity_page',
|
||||
|
||||
'react.backbone',
|
||||
'stickit',
|
||||
'routefilter',
|
||||
'backbone.routefilter',
|
||||
'bootstrap',
|
||||
'less!/static/styles/main'
|
||||
'./styles/main.less'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, layoutComponents, Coccyx, models, KeystoneClient, RootComponent, LoginPage, WelcomePage, ClusterPage, ClustersPage, ReleasesPage, PluginsPage, NotificationsPage, SupportPage, CapacityPage) {
|
||||
'use strict';
|
||||
|
|
|
@ -46,7 +46,7 @@ define(['jquery', 'underscore', 'backbone', 'utils', 'i18n', 'dispatcher', 'reac
|
|||
if (Backbone.history.getHash() != href.substr(1) && _.result(this, 'hasChanges')) {
|
||||
e.preventDefault();
|
||||
|
||||
var dialogs = require('jsx!views/dialogs');
|
||||
var dialogs = require('views/dialogs');
|
||||
dialogs.DiscardSettingsChangesDialog
|
||||
.show({
|
||||
reasonToStay: _.result(this, 'getStayMessage'),
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Mirantis, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
baseUrl: 'static',
|
||||
waitSeconds: 60,
|
||||
paths: {
|
||||
jquery: 'vendor/npm/jquery/dist/jquery',
|
||||
'js-cookie': 'vendor/npm/js-cookie/src/js.cookie',
|
||||
lodash: 'vendor/npm/lodash/index',
|
||||
underscore: 'vendor/npm/lodash/index',
|
||||
backbone: 'vendor/npm/backbone/backbone',
|
||||
classnames: 'vendor/npm/classnames/index',
|
||||
react: 'vendor/npm/react/dist/react-with-addons',
|
||||
JSXTransformer: 'vendor/npm/react/dist/JSXTransformer',
|
||||
jsx: 'vendor/custom/jsx',
|
||||
'react.backbone': 'vendor/custom/react.backbone',
|
||||
'react-dnd': 'vendor/npm/react-dnd/dist/ReactDnD.min',
|
||||
stickit: 'vendor/npm/backbone.stickit/backbone.stickit',
|
||||
coccyx: 'vendor/custom/coccyx',
|
||||
routefilter: 'vendor/custom/backbone.routefilter',
|
||||
bootstrap: 'vendor/npm/bootstrap/dist/js/bootstrap',
|
||||
text: 'vendor/npm/requirejs-plugins/lib/text',
|
||||
json: 'vendor/npm/requirejs-plugins/src/json',
|
||||
i18next: 'vendor/npm/i18next/lib/dep/i18next-1.7.1',
|
||||
deepModel: 'vendor/custom/deep-model',
|
||||
lessLibrary: 'vendor/npm/less/dist/less',
|
||||
'require-css': 'vendor/npm/require-css'
|
||||
},
|
||||
shim: {
|
||||
'expression/parser': {
|
||||
// non-AMD module; gulp-jison supports generation of AMD
|
||||
// modules, but they have broken stacktrace
|
||||
exports: 'parser'
|
||||
},
|
||||
coccyx: {
|
||||
// non-AMD module
|
||||
deps: ['backbone', 'underscore'],
|
||||
exports: 'Coccyx'
|
||||
},
|
||||
classnames: {
|
||||
// non-AMD module
|
||||
exports: 'classNames'
|
||||
},
|
||||
bootstrap: {
|
||||
// non-AMD module, relies on global jQuery
|
||||
deps: ['jquery']
|
||||
},
|
||||
i18next: {
|
||||
// non-AMD module, relies on global jQuery; there is AMD
|
||||
// version, but we still use i18n var in lodash templates,
|
||||
// so we should use non-AMD version until we get rid of
|
||||
// Backbone.View's completely
|
||||
deps: ['jquery'],
|
||||
exports: 'i18n'
|
||||
},
|
||||
deepModel: {
|
||||
// even though deepmodel uses AMD format, it uses _.mixin
|
||||
// before define() call
|
||||
deps: ['underscore']
|
||||
}
|
||||
},
|
||||
map: {
|
||||
'*': {
|
||||
less: 'require-less'
|
||||
}
|
||||
},
|
||||
jsx: {
|
||||
fileExtension: '.jsx'
|
||||
}
|
||||
};
|
||||
});
|
|
@ -20,7 +20,7 @@ define([
|
|||
'jquery',
|
||||
'underscore',
|
||||
'i18next',
|
||||
'json!translations/core.json'
|
||||
'./translations/core.json'
|
||||
], function($, _, i18next, translations) {
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@
|
|||
<meta http-equiv="cache-control" content="no-cache" />
|
||||
<meta http-equiv="expires" content="0" />
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" type="text/css" href="/static/styles/layout.css">
|
||||
<script src="/static/vendor/npm/requirejs/require.js"></script>
|
||||
<link rel="shortcut icon" href="static/favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" type="text/css" href="static/styles/layout.css">
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
'use strict';
|
||||
|
@ -24,6 +23,14 @@
|
|||
if (mainContainer && loadingErrors.length) mainContainer.textContent = loadingErrors.join('; ');
|
||||
}
|
||||
|
||||
function loadScript(src, errorMessage) {
|
||||
var script = document.createElement('script');
|
||||
script.type = 'text/javascript';
|
||||
script.src = src;
|
||||
script.onerror = showError.bind(null, errorMessage);
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
mainContainer = document.getElementById('main-container');
|
||||
mainContainer.style.display = 'block';
|
||||
|
@ -53,9 +60,12 @@
|
|||
}());
|
||||
|
||||
if (hasCookies && hasStorage) {
|
||||
requirejs.config({baseUrl: '/static', urlArgs: '_=__CACHE_BUST__'});
|
||||
requirejs.onError = showError;
|
||||
requirejs(['main']);
|
||||
loadScript(
|
||||
'static/build/bundle.js?__CACHE_BUST__',
|
||||
'Failed to load compressed Fuel UI bundle. ' +
|
||||
'If you are using development environment, ' +
|
||||
'please run "gulp build" to compile Fuel UI.'
|
||||
);
|
||||
} else {
|
||||
showError('Fuel UI requires Cookies and LocalStorage to work');
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright 2013 Mirantis, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
|
||||
//>>excludeStart("compressed", pragmas.compressed);
|
||||
requirejs.config({
|
||||
urlArgs: '_=' + (new Date()).getTime()
|
||||
});
|
||||
require(['./config'], function(config) {
|
||||
'use strict';
|
||||
//>>excludeEnd("compressed");
|
||||
requirejs.config({baseUrl: 'static'});
|
||||
//>>excludeStart("compressed", pragmas.compressed);
|
||||
requirejs.config(config);
|
||||
//>>excludeEnd("compressed");
|
||||
require(['app']);
|
||||
//>>excludeStart("compressed", pragmas.compressed);
|
||||
});
|
||||
//>>excludeEnd("compressed");
|
|
@ -21,8 +21,8 @@ define([
|
|||
'utils',
|
||||
'expression',
|
||||
'expression/objects',
|
||||
'jsx!views/custom_controls',
|
||||
'deepModel'
|
||||
'views/custom_controls',
|
||||
'deep-model'
|
||||
], function($, _, i18n, Backbone, utils, Expression, expressionObjects, customControls) {
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -16,17 +16,18 @@
|
|||
|
||||
define(
|
||||
[
|
||||
'jsx!./vmware_tab',
|
||||
'./vmware_tab',
|
||||
'./vmware_models',
|
||||
'json!./translations.json',
|
||||
'less!./styles',
|
||||
'./translations.json',
|
||||
'./styles.less',
|
||||
'jquery',
|
||||
'underscore'
|
||||
'underscore',
|
||||
'i18next'
|
||||
],
|
||||
function(VmWareTab, vmWareModels, translations, styles, $, _) {
|
||||
function(VmWareTab, vmWareModels, translations, styles, $, _, i18next) {
|
||||
'use strict';
|
||||
|
||||
_.merge($.i18n.options.resStore, translations);
|
||||
_.merge(i18next.options.resStore, translations);
|
||||
|
||||
return {
|
||||
VmWareTab: VmWareTab,
|
||||
|
|
|
@ -22,8 +22,8 @@ define(
|
|||
'underscore',
|
||||
'dispatcher',
|
||||
'utils',
|
||||
'jsx!views/controls',
|
||||
'jsx!component_mixins',
|
||||
'views/controls',
|
||||
'component_mixins',
|
||||
'plugins/vmware/vmware_models'
|
||||
], function(React, $, i18n, _, dispatcher, utils, controls, componentMixins, vmwareModels) {
|
||||
'use strict';
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Copyright 2014 Mirantis, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
|
||||
define(['jquery', 'lessLibrary'], function($, less) {
|
||||
'use strict';
|
||||
|
||||
return {
|
||||
load: function(name, req, onLoad) {
|
||||
var url = req.toUrl(name + '.less');
|
||||
var link = $('<link/>', {href: url, rel: 'stylesheet/less'});
|
||||
link.appendTo('head');
|
||||
less.sheets.push(link[0]);
|
||||
less.refresh();
|
||||
onLoad();
|
||||
}
|
||||
};
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
@import "../vendor/npm/bootstrap/dist/css/bootstrap.css";
|
||||
@import "../../node_modules/bootstrap/dist/css/bootstrap.css";
|
||||
|
||||
// COLOR SETTINGS
|
||||
|
||||
|
@ -100,7 +100,7 @@
|
|||
@slider-color: @tab-color + 20%;
|
||||
|
||||
// Fonts and Weight
|
||||
@import "../vendor/npm/open-sans-fontface/open-sans.css";
|
||||
@import "../../node_modules/open-sans-fontface/open-sans.css";
|
||||
|
||||
@open-sans-font: 'Open Sans', helvetica, arial, tahoma, verdana, sans-serif;
|
||||
|
||||
|
@ -116,7 +116,7 @@
|
|||
// Bebas Bold
|
||||
@font-face {
|
||||
font-family: 'bebas bold';
|
||||
src: url('../fonts/bebas-bold.eot');
|
||||
src: url('../fonts/bebas_bold.eot');
|
||||
src: url('../fonts/bebas_bold.eot?#iefix') format('embedded-opentype'), url('../fonts/bebas_bold.woff2') format('woff2'), url('../fonts/bebas_bold.woff') format('woff'), url('../fonts/bebas_bold.ttf') format('truetype'), url('../fonts/bebas_bold.svg#bebas_bold') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'tests/functional/pages/modal',
|
||||
'intern/dojo/node!leadfoot/helpers/pollUntil',
|
||||
'../../helpers'
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'tests/functional/pages/modal',
|
||||
'../../helpers'
|
||||
], function(_, ModalWindow) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'intern/chai!assert',
|
||||
'../../helpers',
|
||||
'tests/functional/pages/login',
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'intern/chai!assert'
|
||||
], function(_, assert) {
|
||||
'use strict';
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'tests/helpers',
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'tests/functional/pages/common',
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'tests/helpers',
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'underscore',
|
||||
'intern/dojo/node!lodash',
|
||||
'intern/chai!assert',
|
||||
'intern/dojo/node!fs',
|
||||
'intern/dojo/node!leadfoot/Command'
|
||||
|
|
|
@ -14,17 +14,9 @@
|
|||
* under the License.
|
||||
**/
|
||||
|
||||
define(['config'], function(config) {
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
config.baseUrl = '';
|
||||
config.waitSeconds = 7;
|
||||
|
||||
config.paths.sinon = 'vendor/npm/sinon/lib/sinon';
|
||||
|
||||
// FIXME(vkramskikh): workaround for https://github.com/theintern/intern/issues/348
|
||||
delete config.map['*'];
|
||||
|
||||
return {
|
||||
proxyPort: 9057,
|
||||
proxyUrl: 'http://localhost:9057/',
|
||||
|
@ -38,7 +30,6 @@ define(['config'], function(config) {
|
|||
},
|
||||
grep: /^/,
|
||||
excludeInstrumentation: /^/,
|
||||
loader: config,
|
||||
reporters: ['console', 'tests/screenshot_on_fail']
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,16 +1,29 @@
|
|||
/*
|
||||
* Copyright 2015 Mirantis, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
|
||||
define([
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'underscore',
|
||||
'lodash',
|
||||
'models',
|
||||
'expression',
|
||||
'expression/objects'
|
||||
], function(registerSuite, assert, _, models, Expression, expressionObjects) {
|
||||
], function(_, models, Expression, expressionObjects) {
|
||||
'use strict';
|
||||
|
||||
registerSuite({
|
||||
name: 'Expression',
|
||||
'Expression parser test': function() {
|
||||
suite('Expression', function() {
|
||||
test('Expression parser test', function() {
|
||||
var hypervisor = 'kvm';
|
||||
var testModels = {
|
||||
cluster: new models.Cluster({mode: 'ha_compact'}),
|
||||
|
@ -82,6 +95,6 @@ define([
|
|||
assert.strictEqual(evaluate(expression, options), result, expression + ' evaluates correctly');
|
||||
}
|
||||
}));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
define([
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'underscore',
|
||||
'sinon'
|
||||
], function(registerSuite, assert, _, sinon) {
|
||||
/*
|
||||
* Copyright 2015 Mirantis, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
|
||||
define(function() {
|
||||
'use strict';
|
||||
|
||||
var input;
|
||||
|
||||
registerSuite({
|
||||
name: 'File Control',
|
||||
|
||||
beforeEach: function() {
|
||||
suite('File Control', function() {
|
||||
setup(function() {
|
||||
var controls = require('views/controls');
|
||||
|
||||
input = new controls.Input({
|
||||
|
@ -26,17 +35,17 @@ define([
|
|||
content: 'CERTIFICATE'
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
Initialization: function() {
|
||||
test('Initialization', function() {
|
||||
var initialState = input.getInitialState();
|
||||
|
||||
assert.equal(input.props.type, 'file', 'Input type should be equal to file');
|
||||
assert.equal(initialState.fileName, 'certificate.crt', 'Default file name must correspond to provided one');
|
||||
assert.equal(initialState.content, 'CERTIFICATE', 'Content should be equal to the default');
|
||||
},
|
||||
});
|
||||
|
||||
'File selection': function() {
|
||||
test('File selection', function() {
|
||||
var clickSpy = sinon.spy();
|
||||
|
||||
sinon.stub(input, 'getInputDOMNode').returns({
|
||||
|
@ -45,9 +54,9 @@ define([
|
|||
|
||||
input.pickFile();
|
||||
assert.ok(clickSpy.calledOnce, 'When icon clicked input control should be clicked too to open select file dialog');
|
||||
},
|
||||
});
|
||||
|
||||
'File fetching': function() {
|
||||
test('File fetching', function() {
|
||||
var readMethod = sinon.mock(),
|
||||
readerObject = {
|
||||
readAsBinaryString: readMethod,
|
||||
|
@ -70,9 +79,9 @@ define([
|
|||
readerObject.onload();
|
||||
assert.ok(saveMethod.calledOnce, 'saveFile handler called once');
|
||||
sinon.assert.calledWith(saveMethod, 'somefile.ext', 'File contents');
|
||||
},
|
||||
});
|
||||
|
||||
'File saving': function() {
|
||||
test('File saving', function() {
|
||||
var setState = sinon.spy(input, 'setState'),
|
||||
dummyName = 'dummy.ext',
|
||||
dummyContent = 'Lorem ipsum dolores';
|
||||
|
@ -87,6 +96,6 @@ define([
|
|||
name: dummyName,
|
||||
content: dummyContent
|
||||
}, 'Control sends updated data upon changes');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,10 +1,20 @@
|
|||
define([
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'underscore',
|
||||
'sinon',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/offloading_modes_control'
|
||||
], function(registerSuite, assert, _, sinon, OffloadingModes) {
|
||||
/*
|
||||
* Copyright 2015 Mirantis, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
* a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
|
||||
define(['views/cluster_page_tabs/nodes_tab_screens/offloading_modes_control'], function(OffloadingModes) {
|
||||
'use strict';
|
||||
|
||||
var offloadingModesConrol,
|
||||
|
@ -23,10 +33,8 @@ define([
|
|||
}
|
||||
};
|
||||
|
||||
registerSuite({
|
||||
name: 'Offloadning Modes control',
|
||||
|
||||
beforeEach: function() {
|
||||
suite('Offloadning Modes control', function() {
|
||||
setup(function() {
|
||||
TestMode22 = {name: 'TestName22', state: false, sub: []};
|
||||
TestMode31 = {name: 'TestName31', state: null, sub: []};
|
||||
fakeOffloadingModes = [
|
||||
|
@ -54,25 +62,26 @@ define([
|
|||
offloadingModesConrol = new OffloadingModes({
|
||||
interface: fakeInterface
|
||||
});
|
||||
},
|
||||
'Finding mode by name': function() {
|
||||
});
|
||||
|
||||
test('Finding mode by name', function() {
|
||||
var mode = offloadingModesConrol.findMode(TestMode22.name, fakeOffloadingModes);
|
||||
assert.deepEqual(mode, TestMode22, 'Mode can be found by name');
|
||||
},
|
||||
'Set mode state logic': function() {
|
||||
});
|
||||
test('Set mode state logic', function() {
|
||||
offloadingModesConrol.setModeState(TestMode31, true);
|
||||
assert.strictEqual(TestMode31.state, true, 'Mode state is changing');
|
||||
},
|
||||
'Set submodes states logic': function() {
|
||||
});
|
||||
test('Set submodes states logic', function() {
|
||||
var mode = offloadingModesConrol.findMode('TestName1', fakeOffloadingModes);
|
||||
offloadingModesConrol.setModeState(mode, false);
|
||||
assert.strictEqual(TestMode31.state, false, 'Parent state changing leads to all child modes states changing');
|
||||
},
|
||||
'Disabled reversed logic': function() {
|
||||
});
|
||||
test('Disabled reversed logic', function() {
|
||||
var mode = offloadingModesConrol.findMode('TestName2', fakeOffloadingModes);
|
||||
offloadingModesConrol.setModeState(TestMode22, true);
|
||||
offloadingModesConrol.checkModes(null, fakeOffloadingModes);
|
||||
assert.strictEqual(mode.state, null, 'Parent state changing leads to all child modes states changing');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,18 +15,15 @@
|
|||
**/
|
||||
|
||||
define([
|
||||
'intern!object',
|
||||
'intern/chai!assert',
|
||||
'underscore',
|
||||
'utils',
|
||||
'i18n',
|
||||
'backbone'
|
||||
], function(registerSuite, assert, _, utils, i18n, Backbone) {
|
||||
], function(_, utils, i18n, Backbone) {
|
||||
'use strict';
|
||||
|
||||
registerSuite({
|
||||
name: 'Test utils',
|
||||
'Test getResponseText': function() {
|
||||
suite('Test utils', function() {
|
||||
test('Test getResponseText', function() {
|
||||
var response;
|
||||
var getResponseText = utils.getResponseText;
|
||||
var serverErrorMessage = i18n('dialog.error_dialog.server_error');
|
||||
|
@ -46,8 +43,9 @@ define([
|
|||
|
||||
response = {status: 400, responseText: JSON.stringify({message: '123'})};
|
||||
assert.equal(getResponseText(response), '123', 'HTTP 400 with JSON response is treated correctly');
|
||||
},
|
||||
'Test comparison': function() {
|
||||
});
|
||||
|
||||
test('Test comparison', function() {
|
||||
var compare = utils.compare;
|
||||
var model1 = new Backbone.Model({
|
||||
string: 'bond2',
|
||||
|
@ -83,8 +81,9 @@ define([
|
|||
assert.equal(compare(model2, model2, {attr: 'boolean'}), 0, 'Boolean comparison false and false');
|
||||
|
||||
assert.equal(compare(model1, model2, {attr: 'booleanFlagWithNull'}), 0, 'Comparison null and false');
|
||||
},
|
||||
'Test highlightTestStep': function() {
|
||||
});
|
||||
|
||||
test('Test highlightTestStep', function() {
|
||||
var text;
|
||||
var highlight = utils.highlightTestStep;
|
||||
|
||||
|
@ -135,6 +134,6 @@ define([
|
|||
text,
|
||||
'Attempting to highlight non-existent step keeps text as it is'
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -123,7 +123,7 @@ define([
|
|||
}
|
||||
},
|
||||
showErrorDialog: function(options) {
|
||||
var dialogs = require('jsx!views/dialogs'); // avoid circular dependencies
|
||||
var dialogs = require('views/dialogs'); // avoid circular dependencies
|
||||
options.message = options.response ? utils.getResponseText(options.response) :
|
||||
options.message || i18n('dialog.error_dialog.warning');
|
||||
dialogs.ErrorDialog.show(options);
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
* @license The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 Felipe O. Carvalho
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
define(['JSXTransformer', 'text'], function (JSXTransformer, text) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var buildMap = {};
|
||||
|
||||
var jsx = {
|
||||
version: '0.6.2',
|
||||
|
||||
load: function (name, req, onLoadNative, config) {
|
||||
var jsxOptions = config.jsx || {};
|
||||
var fileExtension = jsxOptions.fileExtension || '.js';
|
||||
|
||||
var transformOptions = {
|
||||
harmony: !!jsxOptions.harmony,
|
||||
stripTypes: !!jsxOptions.stripTypes
|
||||
};
|
||||
|
||||
var onLoad = function(content) {
|
||||
try {
|
||||
content = JSXTransformer.transform(content, transformOptions).code;
|
||||
} catch (err) {
|
||||
onLoadNative.error(err);
|
||||
}
|
||||
|
||||
if (config.isBuild) {
|
||||
buildMap[name] = content;
|
||||
} else if (typeof location !== 'undefined') { // Do not create sourcemap when loaded in Node
|
||||
content += '\n//# sourceURL=' + location.protocol + '//' + location.hostname +
|
||||
config.baseUrl + name + fileExtension;
|
||||
}
|
||||
|
||||
onLoadNative.fromText(content);
|
||||
};
|
||||
|
||||
onLoad.error = function(err) {
|
||||
onLoadNative.error(err);
|
||||
};
|
||||
|
||||
text.load(name + fileExtension, req, onLoad, config);
|
||||
},
|
||||
|
||||
write: function (pluginName, moduleName, write) {
|
||||
if (buildMap.hasOwnProperty(moduleName)) {
|
||||
var content = buildMap[moduleName];
|
||||
write.asModule(pluginName + '!' + moduleName, content);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return jsx;
|
||||
});
|
||||
|
|
@ -19,8 +19,8 @@ define(
|
|||
'i18n',
|
||||
'react',
|
||||
'models',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls'
|
||||
'component_mixins',
|
||||
'views/controls'
|
||||
],
|
||||
function(_, i18n, React, models, componentMixins, controls) {
|
||||
'use strict';
|
||||
|
|
|
@ -23,14 +23,14 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'dispatcher',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!views/cluster_page_tabs/dashboard_tab',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab',
|
||||
'jsx!views/cluster_page_tabs/network_tab',
|
||||
'jsx!views/cluster_page_tabs/settings_tab',
|
||||
'jsx!views/cluster_page_tabs/logs_tab',
|
||||
'jsx!views/cluster_page_tabs/healthcheck_tab',
|
||||
'component_mixins',
|
||||
'views/dialogs',
|
||||
'views/cluster_page_tabs/dashboard_tab',
|
||||
'views/cluster_page_tabs/nodes_tab',
|
||||
'views/cluster_page_tabs/network_tab',
|
||||
'views/cluster_page_tabs/settings_tab',
|
||||
'views/cluster_page_tabs/logs_tab',
|
||||
'views/cluster_page_tabs/healthcheck_tab',
|
||||
'plugins/vmware/vmware'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, models, dispatcher, componentMixins, dialogs, DashboardTab, NodesTab, NetworkTab, SettingsTab, LogsTab, HealthCheckTab, vmWare) {
|
||||
|
|
|
@ -22,9 +22,9 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'dispatcher',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls'
|
||||
'views/dialogs',
|
||||
'component_mixins',
|
||||
'views/controls'
|
||||
],
|
||||
function(_, i18n, $, React, utils, models, dispatcher, dialogs, componentMixins, controls) {
|
||||
'use strict';
|
||||
|
|
|
@ -22,8 +22,8 @@ define(
|
|||
'react',
|
||||
'models',
|
||||
'utils',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls'
|
||||
'component_mixins',
|
||||
'views/controls'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, models, utils, componentMixins, controls) {
|
||||
'use strict';
|
||||
|
|
|
@ -21,8 +21,8 @@ define(
|
|||
'react',
|
||||
'utils',
|
||||
'models',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls'
|
||||
'component_mixins',
|
||||
'views/controls'
|
||||
],
|
||||
function($, _, i18n, React, utils, models, componentMixins, controls) {
|
||||
'use strict';
|
||||
|
|
|
@ -23,8 +23,8 @@ define(
|
|||
'models',
|
||||
'dispatcher',
|
||||
'utils',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls'
|
||||
'component_mixins',
|
||||
'views/controls'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, models, dispatcher, utils, componentMixins, controls) {
|
||||
'use strict';
|
||||
|
|
|
@ -18,12 +18,12 @@ define(
|
|||
'jquery',
|
||||
'underscore',
|
||||
'react',
|
||||
'jsx!views/controls',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/cluster_nodes_screen',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/add_nodes_screen',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/edit_nodes_screen',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/edit_node_disks_screen',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/edit_node_interfaces_screen'
|
||||
'views/controls',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/cluster_nodes_screen',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/add_nodes_screen',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/edit_nodes_screen',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/edit_node_disks_screen',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/edit_node_interfaces_screen'
|
||||
],
|
||||
function($, _, React, controls, ClusterNodesScreen, AddNodesScreen, EditNodesScreen, EditNodeDisksScreen, EditNodeInterfacesScreen) {
|
||||
'use strict';
|
||||
|
|
|
@ -19,7 +19,7 @@ define(
|
|||
'underscore',
|
||||
'react',
|
||||
'models',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/node_list_screen'
|
||||
'views/cluster_page_tabs/nodes_tab_screens/node_list_screen'
|
||||
],
|
||||
function($, _, React, models, NodeListScreen) {
|
||||
'use strict';
|
||||
|
|
|
@ -17,7 +17,7 @@ define(
|
|||
[
|
||||
'underscore',
|
||||
'react',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/node_list_screen'
|
||||
'views/cluster_page_tabs/nodes_tab_screens/node_list_screen'
|
||||
],
|
||||
function(_, React, NodeListScreen) {
|
||||
'use strict';
|
||||
|
|
|
@ -22,8 +22,8 @@ define(
|
|||
'react',
|
||||
'utils',
|
||||
'models',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls'
|
||||
'component_mixins',
|
||||
'views/controls'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, models, ComponentMixins, controls) {
|
||||
'use strict';
|
||||
|
|
|
@ -23,11 +23,11 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'dispatcher',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!views/controls',
|
||||
'jsx!component_mixins',
|
||||
'views/dialogs',
|
||||
'views/controls',
|
||||
'component_mixins',
|
||||
'react-dnd',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/offloading_modes_control'
|
||||
'views/cluster_page_tabs/nodes_tab_screens/offloading_modes_control'
|
||||
],
|
||||
function($, _, Backbone, React, i18n, utils, models, dispatcher, dialogs, controls, ComponentMixins, DND, OffloadingModes) {
|
||||
'use strict';
|
||||
|
|
|
@ -20,8 +20,8 @@ define(
|
|||
'react',
|
||||
'models',
|
||||
'utils',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/node_list_screen'
|
||||
'component_mixins',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/node_list_screen'
|
||||
],
|
||||
function($, _, React, models, utils, ComponentMixins, NodeListScreen) {
|
||||
'use strict';
|
||||
|
|
|
@ -23,9 +23,9 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'dispatcher',
|
||||
'jsx!views/controls',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!component_mixins'
|
||||
'views/controls',
|
||||
'views/dialogs',
|
||||
'component_mixins'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialogs, componentMixins) {
|
||||
'use strict';
|
||||
|
|
|
@ -23,10 +23,10 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'dispatcher',
|
||||
'jsx!views/controls',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/cluster_page_tabs/nodes_tab_screens/node'
|
||||
'views/controls',
|
||||
'views/dialogs',
|
||||
'component_mixins',
|
||||
'views/cluster_page_tabs/nodes_tab_screens/node'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, dialogs, componentMixins, Node) {
|
||||
'use strict';
|
||||
|
|
|
@ -22,9 +22,9 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'expression',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/controls',
|
||||
'jsx!views/custom_controls'
|
||||
'component_mixins',
|
||||
'views/controls',
|
||||
'views/custom_controls'
|
||||
],
|
||||
function($, _, i18n, React, utils, models, Expression, componentMixins, controls, customControls) {
|
||||
'use strict';
|
||||
|
|
|
@ -22,7 +22,7 @@ define(
|
|||
'models',
|
||||
'utils',
|
||||
'dispatcher',
|
||||
'jsx!component_mixins',
|
||||
'component_mixins',
|
||||
'views/wizard'
|
||||
],
|
||||
function($, _, i18n, React, models, utils, dispatcher, componentMixins, wizard) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
* Based on https://github.com/react-bootstrap/react-bootstrap/blob/master/src/Input.jsx
|
||||
**/
|
||||
|
||||
define(['i18n', 'jquery', 'underscore', 'react', 'utils', 'jsx!component_mixins'],
|
||||
define(['i18n', 'jquery', 'underscore', 'react', 'utils', 'component_mixins'],
|
||||
function(i18n, $, _, React, utils, componentMixins) {
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ define([
|
|||
'i18n',
|
||||
'react',
|
||||
'utils',
|
||||
'jsx!views/controls'
|
||||
'views/controls'
|
||||
], function($, _, i18n, React, utils, controls) {
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ define(
|
|||
'utils',
|
||||
'models',
|
||||
'dispatcher',
|
||||
'jsx!views/controls',
|
||||
'jsx!component_mixins'
|
||||
'views/controls',
|
||||
'component_mixins'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, models, dispatcher, controls, componentMixins) {
|
||||
'use strict';
|
||||
|
|
|
@ -22,9 +22,9 @@ define(
|
|||
'react',
|
||||
'utils',
|
||||
'models',
|
||||
'jsx!views/controls',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/dialogs'
|
||||
'views/controls',
|
||||
'component_mixins',
|
||||
'views/dialogs'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, utils, models, controls, componentMixins, dialogs) {
|
||||
'use strict';
|
||||
|
|
|
@ -19,8 +19,8 @@ define(
|
|||
'react',
|
||||
'utils',
|
||||
'models',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!component_mixins'
|
||||
'views/dialogs',
|
||||
'component_mixins'
|
||||
],
|
||||
function(i18n, React, utils, models, dialogs, componentMixins) {
|
||||
'use strict';
|
||||
|
|
|
@ -19,8 +19,8 @@ define(
|
|||
'i18n',
|
||||
'react',
|
||||
'models',
|
||||
'jsx!views/controls',
|
||||
'jsx!component_mixins'
|
||||
'views/controls',
|
||||
'component_mixins'
|
||||
],
|
||||
function(_, i18n, React, models, controls, componentMixins) {
|
||||
'use strict';
|
||||
|
|
|
@ -18,11 +18,12 @@ define([
|
|||
'i18n',
|
||||
'react',
|
||||
'utils',
|
||||
'jsx!views/layout',
|
||||
'views/layout',
|
||||
'dispatcher',
|
||||
'jsx!component_mixins',
|
||||
'react-dnd'
|
||||
], function(_, i18n, React, utils, layoutComponents, dispatcher, componentMixins, DND) {
|
||||
'component_mixins',
|
||||
'react-dnd',
|
||||
'react-dnd/modules/backends/HTML5'
|
||||
], function(_, i18n, React, utils, layoutComponents, dispatcher, componentMixins, DND, HTML5Backend) {
|
||||
'use strict';
|
||||
|
||||
var RootComponent = React.createClass({
|
||||
|
@ -81,5 +82,5 @@ define([
|
|||
}
|
||||
});
|
||||
|
||||
return DND.DragDropContext(DND.HTML5)(RootComponent);
|
||||
return DND.DragDropContext(HTML5Backend)(RootComponent);
|
||||
});
|
||||
|
|
|
@ -20,8 +20,8 @@ define([
|
|||
'react',
|
||||
'utils',
|
||||
'models',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!views/controls'
|
||||
'views/dialogs',
|
||||
'views/controls'
|
||||
], function($, _, i18n, React, utils, models, dialogs, controls) {
|
||||
'use strict';
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@ define(
|
|||
'i18n',
|
||||
'backbone',
|
||||
'react',
|
||||
'jsx!views/dialogs',
|
||||
'jsx!component_mixins',
|
||||
'views/dialogs',
|
||||
'component_mixins',
|
||||
'models',
|
||||
'jsx!views/statistics_mixin'
|
||||
'views/statistics_mixin'
|
||||
],
|
||||
function($, _, i18n, Backbone, React, dialogs, componentMixins, models, statisticsMixin) {
|
||||
'use strict';
|
||||
|
|
|
@ -19,8 +19,8 @@ define(
|
|||
'i18n',
|
||||
'react',
|
||||
'models',
|
||||
'jsx!component_mixins',
|
||||
'jsx!views/statistics_mixin'
|
||||
'component_mixins',
|
||||
'views/statistics_mixin'
|
||||
],
|
||||
function(_, i18n, React, models, componentMixins, statisticsMixin) {
|
||||
'use strict';
|
||||
|
|
|
@ -20,20 +20,21 @@ define(
|
|||
'underscore',
|
||||
'i18n',
|
||||
'backbone',
|
||||
'backbone.stickit',
|
||||
'utils',
|
||||
'models',
|
||||
'text!templates/wizard/create_cluster_wizard.html',
|
||||
'text!templates/wizard/name_and_release.html',
|
||||
'text!templates/wizard/common_wizard_panel.html',
|
||||
'text!templates/wizard/mode.html',
|
||||
'text!templates/wizard/network.html',
|
||||
'text!templates/wizard/storage.html',
|
||||
'text!templates/wizard/ready.html',
|
||||
'text!templates/wizard/control_template.html',
|
||||
'text!templates/wizard/warning.html',
|
||||
'text!templates/wizard/text_input.html'
|
||||
'templates/wizard/create_cluster_wizard.html',
|
||||
'templates/wizard/name_and_release.html',
|
||||
'templates/wizard/common_wizard_panel.html',
|
||||
'templates/wizard/mode.html',
|
||||
'templates/wizard/network.html',
|
||||
'templates/wizard/storage.html',
|
||||
'templates/wizard/ready.html',
|
||||
'templates/wizard/control_template.html',
|
||||
'templates/wizard/warning.html',
|
||||
'templates/wizard/text_input.html'
|
||||
],
|
||||
function(require, $, _, i18n, Backbone, utils, models, createClusterWizardTemplate, clusterNameAndReleasePaneTemplate, commonWizardTemplate, modePaneTemplate, networkPaneTemplate, storagePaneTemplate, clusterReadyPaneTemplate, controlTemplate, warningTemplate, textInputTemplate) {
|
||||
function(require, $, _, i18n, Backbone, stickit, utils, models, createClusterWizardTemplate, clusterNameAndReleasePaneTemplate, commonWizardTemplate, modePaneTemplate, networkPaneTemplate, storagePaneTemplate, clusterReadyPaneTemplate, controlTemplate, warningTemplate, textInputTemplate) {
|
||||
'use strict';
|
||||
|
||||
var views = {},
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*eslint-disable strict*/
|
||||
module.exports = {
|
||||
entry: ['./static/app.js'],
|
||||
output: {
|
||||
path: __dirname + '/static/build/',
|
||||
publicPath: '/static/build/',
|
||||
filename: 'bundle.js',
|
||||
chunkFilename: null,
|
||||
sourceMapFilename: 'bundle.js.map'
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{test: /\/expression\/parser\.js$/, loader: 'exports?parser'},
|
||||
{test: require.resolve('jquery'), loader: 'expose?jQuery!expose?$'},
|
||||
{test: /\.css$/, loader: 'style!css!postcss'},
|
||||
{test: /\.less$/, loader: 'style!css!postcss!less'},
|
||||
{test: /\.html$/, loader: 'raw'},
|
||||
{test: /\.json$/, loader: 'json'},
|
||||
{test: /\.jison$/, loader: 'jison'},
|
||||
{test: /\.jsx$/, loader: 'babel', exclude: /(node_modules|bower_components)/},
|
||||
{test: /\.(woff|woff2|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, loader: 'file'},
|
||||
{test: /\.(gif|png)$/, loader: 'file'}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
modulesDirectories: ['static', 'node_modules', 'vendor/custom'],
|
||||
extensions: ['', '.js', '.jsx'],
|
||||
alias: {
|
||||
underscore: 'lodash',
|
||||
react: 'react/addons',
|
||||
// FIXME(vkramskikh): node.js version depends on express
|
||||
// and causes warnings
|
||||
i18next: 'i18next/lib/dep/i18next-1.7.1.js'
|
||||
}
|
||||
},
|
||||
node: {},
|
||||
plugins: [],
|
||||
postcss: function() {
|
||||
return [require('autoprefixer')];
|
||||
},
|
||||
devtool: 'cheap-source-map',
|
||||
watchOptions: {
|
||||
aggregateTimeout: 300,
|
||||
poll: 1000
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue