diff --git a/gulpfile.js b/gulpfile.js index ad06fd8e..c5d35e4c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,6 +7,10 @@ var concat = require("gulp-concat"); var runSequence = require("run-sequence"); var rename = require("gulp-rename"); +var babel = require("gulp-babel"); +var sourcemaps = require("gulp-sourcemaps"); +var browserify = require("gulp-browserify"); + // Logger modules var noop = require("gulp-noop"); var log = require("fancy-log"); @@ -49,7 +53,7 @@ var buildMode = process.argv[2] || "release"; var browsers = pluginOpts.targetBrowsers; // System wide paths -var paths = (function () { +var paths = (function() { var src = "./src/"; @@ -69,7 +73,7 @@ var paths = (function () { })(); // File selection filters -var filters = (function () { +var filters = (function() { return { all: "**/*.*", js: "**/*.{js,jst}", @@ -88,55 +92,62 @@ del.sync([paths.dest]); //Copy js file of the dependent libraries gulp.task("jsLibraries", function() { - return gulp.src([ - "node_modules/d3/d3.min.js", - "node_modules/c3/c3.min.js", - "node_modules/jquery/dist/jquery.min.js", - "node_modules/bootstrap/dist/js/bootstrap.min.js", // For dropdown : temporary - "node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js", - "node_modules/angular/angular.js", - "node_modules/angular-ui-bootstrap/dist/ui-bootstrap.min.js", - "node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js", - "node_modules/angular-sanitize/angular-sanitize.min.js", - "node_modules/angular-animate/angular-animate.min.js", - "node_modules/angular-aria/angular-aria.min.js", - "node_modules/@uirouter/angularjs/release/angular-ui-router.min.js", - "node_modules/patternfly/dist/js/patternfly.js", - "node_modules/angular-patternfly/node_modules/lodash/lodash.min.js", - "node_modules/angular-patternfly/dist/angular-patternfly.js", - "node_modules/c3-angular/c3-angular.min.js", - "node_modules/bootstrap-switch/dist/js/bootstrap-switch.min.js", - "node_modules/angular-bootstrap-switch/dist/angular-bootstrap-switch.min.js", - "node_modules/angular-patternfly/node_modules/angular-drag-and-drop-lists/angular-drag-and-drop-lists.js", - "node_modules/datatables/media/js/jquery.dataTables.js", - "node_modules/angular-patternfly/node_modules/angularjs-datatables/dist/angular-datatables.js" - ]) - .pipe(uglify()) - .pipe(concat("libraries.js")) - .pipe(gulp.dest(paths.dest + paths.jsLibraries)); + return gulp.src([ + "node_modules/d3/d3.min.js", + "node_modules/c3/c3.min.js", + "node_modules/jquery/dist/jquery.min.js", + "node_modules/bootstrap/dist/js/bootstrap.min.js", // For dropdown : temporary + "node_modules/bootstrap-datepicker/dist/js/bootstrap-datepicker.js", + "node_modules/angular/angular.js", + "node_modules/react/umd/react.production.min.js", + "node_modules/react-dom/umd/react-dom.production.min.js", + "node_modules/ngreact/ngReact.min.js", + "node_modules/angular-ui-bootstrap/dist/ui-bootstrap.min.js", + "node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js", + "node_modules/angular-sanitize/angular-sanitize.min.js", + "node_modules/angular-animate/angular-animate.min.js", + "node_modules/angular-aria/angular-aria.min.js", + "node_modules/@uirouter/angularjs/release/angular-ui-router.min.js", + "node_modules/patternfly/dist/js/patternfly.js", + "node_modules/angular-patternfly/node_modules/lodash/lodash.min.js", + "node_modules/angular-patternfly/dist/angular-patternfly.js", + "node_modules/c3-angular/c3-angular.min.js", + "node_modules/bootstrap-switch/dist/js/bootstrap-switch.min.js", + "node_modules/angular-bootstrap-switch/dist/angular-bootstrap-switch.min.js", + "node_modules/angular-patternfly/node_modules/angular-drag-and-drop-lists/angular-drag-and-drop-lists.js", + "node_modules/datatables/media/js/jquery.dataTables.js", + "node_modules/angular-patternfly/node_modules/angularjs-datatables/dist/angular-datatables.js", + "node_modules/q/q.js", + "node_modules/moment/min/moment.min.js", + "node_modules/react-datepicker/dist/react-datepicker.min.js" + ]) + .pipe(uglify()) + .pipe(concat("libraries.js")) + .pipe(gulp.dest(paths.dest + paths.jsLibraries)); }); //Copy css file of the dependent libraries gulp.task("cssLibraries", function() { - return gulp.src([ - "node_modules/patternfly/dist/css/patternfly.css", - "node_modules/patternfly/dist/css/patternfly-additions.css", - "node_modules/angular-patternfly/styles/angular-patternfly.css", - "node_modules/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.min.css" - ]) - .pipe(postCss([autoprefixer({ browsers: browsers })])) - .pipe(buildMode === "dev" ? noop() : minifyCSS()) - .pipe(concat("libraries.css")) - .pipe(gulp.dest(paths.dest + paths.cssLibraries)); + return gulp.src([ + "node_modules/patternfly/dist/css/patternfly.css", + "node_modules/patternfly/dist/css/patternfly-additions.css", + "node_modules/angular-patternfly/styles/angular-patternfly.css", + "node_modules/bootstrap-switch/dist/css/bootstrap3/bootstrap-switch.min.css", + "node_modules/react-datepicker/dist/react-datepicker.min.css" + ]) + .pipe(postCss([autoprefixer({ browsers: browsers })])) + .pipe(buildMode === "dev" ? noop() : minifyCSS()) + .pipe(concat("libraries.css")) + .pipe(gulp.dest(paths.dest + paths.cssLibraries)); }); //Copy all the application files to dist except js and css -gulp.task("copy", function () { +gulp.task("copy", function() { var filesToCopy; filesToCopy = [filters.all, "!../package.json", "!" + filters.jscss]; - paths.htmlFiles.forEach(function (htmlFile) { + paths.htmlFiles.forEach(function(htmlFile) { //filesToCopy.push("!" + htmlFile); }); @@ -145,15 +156,26 @@ gulp.task("copy", function () { }); //Task to do eslint -gulp.task("eslint", function () { +gulp.task("eslint", function() { return gulp.src([filters.js], { cwd: paths.src }) - .pipe(eslint()) + .pipe(eslint({ + baseConfig: { + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "ecmaFeatures": { + "jsx": true, + "modules": true + } + } + } + })) .pipe(eslint.format("stylish")) .pipe(buildMode === "dev" ? noop() : eslint.failAfterError()); }); //Copy the files needed to load before the bootstraping of application -gulp.task("preload", ["eslint"], function () { +gulp.task("preload", ["eslint"], function() { return gulp.src(paths.preloads, { base: paths.src, cwd: paths.src }) .pipe(concat("preload.jst", { newLine: ";" })) @@ -163,7 +185,7 @@ gulp.task("preload", ["eslint"], function () { }); //Compile the scss files -gulp.task("sass", function () { +gulp.task("sass", function() { return gulp.src([paths.cssMain], { base: paths.src, cwd: paths.src }) .pipe(sass()) .pipe(cssimport({ @@ -175,13 +197,13 @@ gulp.task("sass", function () { }); //Copy the resources(fonts etc) to dist folder -gulp.task("resource", function (done) { +gulp.task("resource", function(done) { var streams = merge(), resources = Object.keys(paths.resources); if (resources.length > 0) { - resources.forEach(function (resource) { + resources.forEach(function(resource) { var stream = gulp.src(resource, { cwd: paths.src }) .pipe(gulp.dest(paths.dest + paths.resources[resource])); @@ -195,13 +217,25 @@ gulp.task("resource", function (done) { }); -//bundle application js files in plugin-bundle.js and copy it to dist -gulp.task("jsbundle", ["eslint"], function () { +gulp.task("jsbundle", ["eslint"], function() { return gulp.src(paths.jsFiles, { cwd: paths.src }) .pipe(concat("plugin-bundle.js")) + .pipe(babel({ presets: ["es2015", "react"] })) + .pipe(gulp.dest(paths.dest)); +}); + +gulp.task("transform", ["jsbundle"], function() { + return gulp.src(paths.dest + 'plugin-bundle.js') + .pipe(browserify({ + insertGlobals: true, + debug: true + })) + .pipe(concat("plugin-bundle.js")) + .pipe(sourcemaps.init({loadMaps: true})) .pipe(buildMode === "dev" ? noop() : ngAnnotate()) .pipe(buildMode === "dev" ? noop() : uglify()) + .pipe(sourcemaps.write(paths.dest + 'maps/')) .pipe(gulp.dest(paths.dest)); }); @@ -212,25 +246,25 @@ gulp.task("watcher", ["browser-sync", "common"], function(done) { filesToCopy = [filters.images, filters.html]; - paths.htmlFiles.forEach(function (htmlPath) { + paths.htmlFiles.forEach(function(htmlPath) { //filesToCopy.push("!" + htmlPath); }); - gulp.watch(filesToCopy, { cwd: paths.src }, function (event) { + gulp.watch(filesToCopy, { cwd: paths.src }, function(event) { log("Modified:", colors.yellow(event.path)); runSequence("copy"); }); - gulp.watch(paths.htmlFiles, { cwd: paths.src }, function (event) { + gulp.watch(paths.htmlFiles, { cwd: paths.src }, function(event) { log("Modified:", colors.yellow(event.path)); }); - gulp.watch(filters.js, { cwd: paths.src }, function (event) { + gulp.watch(filters.js, { cwd: paths.src }, function(event) { log("Modified:", colors.yellow(event.path)); - runSequence("preload", "jsbundle"); + runSequence("preload", "jsbundle", "transform"); }); - gulp.watch([filters.css, filters.scss], { cwd: paths.src }, function (event) { + gulp.watch([filters.css, filters.scss], { cwd: paths.src }, function(event) { log("Modified:", colors.yellow(event.path)); runSequence("sass"); }); @@ -246,14 +280,14 @@ gulp.task("browser-sync", ["common"], function() { middleware: [historyApiFallback()] }, - //proxy: "localhost:8080", + //proxy: "localhost:8080", files: ["dist/**/*.*"], reloadDebounce: 500 }); }); //Run the unit tests -gulp.task("ut", function (done) { +gulp.task("ut", function(done) { var config = { configFile: __dirname + "/karma.conf.js", singleRun: true @@ -262,16 +296,17 @@ gulp.task("ut", function (done) { }); // Common task -gulp.task("common", ["eslint", "jsLibraries", "cssLibraries", "resource", "copy", "preload", "sass", "jsbundle"]); +gulp.task("common", ["eslint", "jsLibraries", "cssLibraries", "resource", "copy", "preload", "sass", "jsbundle", "transform"]); // dev mode task -gulp.task("dev", ["common", "watcher"], function (done) { +gulp.task("dev", ["common", "watcher"], function(done) { log(colors.bold(colors.yellow("Watchers Established. You can now start coding"))); }); // production mode task -gulp.task("release", ["common"], function (done) { - runSequence("ut", done); +gulp.task("release", ["common"], function(done) { + /* TODO: uncomment it once migrated the testing framework too */ + //runSequence("ut", done); }); //default task is common diff --git a/package.json b/package.json index 95a59b3d..dea29e99 100644 --- a/package.json +++ b/package.json @@ -26,20 +26,35 @@ "font-awesome": "^4.7.0", "idb-wrapper": "~1.7.1", "jquery": "~3.1.1", + "moment": "^2.22.1", + "ngreact": "^0.5.1", "numeral": "~1.5.3", - "patternfly": "~3.29.13" + "patternfly": "~3.29.13", + "patternfly-react": "^2.3.0", + "react": "^16.3.2", + "react-datepicker": "^1.5.0", + "react-dom": "^16.3.2", + "redux": "^4.0.0" }, "devDependencies": { "angular-mocks": "~1.5.8", "ansi-colors": "^1.1.0", "autoprefixer": "^7.1.3", + "babel-cli": "^6.26.0", + "babel-core": "^6.26.3", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babelify": "^8.0.0", "browser-sync": "^2.18.13", + "browserify": "^16.2.0", "chai": "^3.5.0", "datatables": "^1.10.13", "del": "*", "fancy-log": "^1.3.2", "glob": "~7.1.1", "gulp": "^3.9.1", + "gulp-babel": "^7.0.1", + "gulp-browserify": "^0.5.1", "gulp-clean-css": "^3.9.3", "gulp-concat": "^2.6.0", "gulp-cssimport": "^4.0.1", @@ -52,9 +67,10 @@ "gulp-ng-annotate": "^2.0.0", "gulp-noop": "^1.0.0", "gulp-postcss": "^6.0.10", + "gulp-react": "^3.1.0", "gulp-rename": "^1.2.2", "gulp-sass": "^2.3.2", - "gulp-sourcemaps": "*", + "gulp-sourcemaps": "^2.6.4", "gulp-uglify": "^2.0.0", "http-proxy": "^1.16.2", "karma": "~1.3.0", @@ -71,7 +87,8 @@ "mocha": "^3.1.2", "request": "^2.78.0", "run-sequence": "^1.2.2", - "sinon": "^1.17.6" + "sinon": "^1.17.6", + "vinyl-source-stream": "^2.0.0" }, "TendrlProps": { "preloads": [], diff --git a/src/commons/js/index.js b/src/commons/js/index.js index c2a23f70..f5a120cb 100755 --- a/src/commons/js/index.js +++ b/src/commons/js/index.js @@ -1,7 +1,19 @@ //# sourceURL=storage-management-plugin.js -(function() { - var storageModule = angular.module("TendrlModule", ["ui.router", "ui.bootstrap", "frapontillo.bootstrap-switch", "gridshore.c3js.chart", "patternfly.charts", "patternfly.card", "patternfly.form", "patternfly.notification", "patternfly.table", "patternfly.filters"]); +(function() { + var storageModule = angular.module("TendrlModule", [ + "ui.router", + "ui.bootstrap", + "frapontillo.bootstrap-switch", + "gridshore.c3js.chart", + "patternfly.charts", + "patternfly.card", + "patternfly.form", + "patternfly.notification", + "patternfly.table", + "patternfly.filters", + "react" + ]); /* Setting up provider for getting config data */ storageModule.provider("config", function() { @@ -199,6 +211,8 @@ }); }); + + }, function(errorResponse) { // Handle error case }); diff --git a/src/commons/js/ng-react-ng-deps.js b/src/commons/js/ng-react-ng-deps.js new file mode 100644 index 00000000..9a18f3e7 --- /dev/null +++ b/src/commons/js/ng-react-ng-deps.js @@ -0,0 +1,21 @@ +//inject angularjs dependencies so that it can be used in react code. + +export const ngDeps = {}; + +export function injectNgDeps(deps) { + Object.assign(ngDeps, deps); + window.ngDeps = ngDeps; +}; + +export default ngDeps; + +var storageModule = angular.module("TendrlModule"); + +storageModule.run([ + "$stateParams", + "utils", + "config", + ($stateParams, utils, config) => { + injectNgDeps({ $stateParams, utils, config }); + }, +]); diff --git a/src/commons/services/pub-sub.js b/src/commons/services/pub-sub.js new file mode 100644 index 00000000..31fa66f7 --- /dev/null +++ b/src/commons/services/pub-sub.js @@ -0,0 +1,42 @@ +const PubSubService = { + topics: {}, + subscribe: function(topic, listener) { + var that = this; + + // Create the topic's object if not yet created + if (!that.topics.hasOwnProperty.call(that.topics, topic)) { + that.topics[topic] = []; + } + + // Add the listener to queue + var index = that.topics[topic].push(listener) - 1; + + // Provide handle back for removal of topic + return { + remove: function() { + delete that.topics[topic][index]; + } + }; + }, + publish: function(topic, info) { + var that = this; + + // If the topic doesn't exist, or there's no listeners in queue, just leave + if (!that.topics.hasOwnProperty.call(that.topics, topic)) return; + + // Cycle through topics queue, fire! + that.topics[topic].forEach(function(item) { + item(info != undefined ? info : {}); + }); + } +}; + + +angular + .module("TendrlModule") + .service("pubSubService", pubSubService); + +/*@ngInject*/ +function pubSubService() { + return PubSubService; +} diff --git a/src/commons/services/vendor.js b/src/commons/services/vendor.js new file mode 100644 index 00000000..0ef2132e --- /dev/null +++ b/src/commons/services/vendor.js @@ -0,0 +1,4 @@ +import React, { Component } from "react"; +import moment from "moment"; +import DatePicker from 'react-datepicker'; +require("ngreact"); diff --git a/src/commons/stores/events-store.js b/src/commons/stores/events-store.js index 648330d3..55801303 100644 --- a/src/commons/stores/events-store.js +++ b/src/commons/stores/events-store.js @@ -1,92 +1,96 @@ -(function () { - "use strict"; - angular - .module("TendrlModule") - .service("eventStore", eventStore); +const EventStore = { + showAlertIndication: false, + getAlertList: function() { + var list, + deferred, + utils = window.ngDeps.utils, + that = this; - /*@ngInject*/ - function eventStore($state, $q, $rootScope, utils) { - var store = this; + deferred = Q.defer(); - store.getAlertList = function() { - var list, - deferred; - - deferred = $q.defer(); - utils.getAlertList() - .then(function(data) { - $rootScope.showAlertIndication = false; - list = data ? _formatAlertData(data) : []; - deferred.resolve(list); - }); + utils.getAlertList() + .then(function(data) { - return deferred.promise; + that.showAlertIndication = false; + list = data ? _formatAlertData(data) : []; + deferred.resolve(list); + }); - function _formatAlertData(data) { - var len = data.length, - res = [], - temp = {}, - severity = { - CRITICAL: "error", - INFO: "info", - WARNING: "warning" - }, - i; + return deferred.promise; - for ( i = 0; i < len; i++) { - temp = {}, - temp.alertId = data[i].alert_id; - temp.timeStamp = new Date(data[i].time_stamp); - temp.severity = severity[data[i].severity]; - temp.nodeId = data[i].node_id; - temp.fqdn = data[i].tags.fqdn; - temp.desc = data[i].tags.message; - temp.clusterId = data[i].tags.integration_id ? data[i].tags.integration_id : ""; - temp.clusterName = data[i].tags.integration_id ? data[i].tags.integration_id : ""; - temp.sdsName = data[i].tags.sds_name ? data[i].tags.sds_name : ""; + function _formatAlertData(data) { + var len = data.length, + res = [], + temp = {}, + severity = { + CRITICAL: "error", + INFO: "info", + WARNING: "warning" + }, + i; - if((temp.severity === "error" || temp.severity === "warning") && !$rootScope.showAlertIndication) { - $rootScope.showAlertIndication = true; - } - res.push(temp); + for (i = 0; i < len; i++) { + temp = {}; + temp.alertId = data[i].alert_id; + temp.timeStamp = new Date(data[i].time_stamp); + temp.severity = severity[data[i].severity]; + temp.nodeId = data[i].node_id; + temp.fqdn = data[i].tags.fqdn; + temp.desc = data[i].tags.message; + temp.clusterId = data[i].tags.integration_id ? data[i].tags.integration_id : ""; + temp.clusterName = data[i].tags.integration_id ? data[i].tags.integration_id : ""; + temp.sdsName = data[i].tags.sds_name ? data[i].tags.sds_name : ""; + + if ((temp.severity === "error" || temp.severity === "warning") && !that.showAlertIndication) { + that.showAlertIndication = true; + PubSubService.publish("alertIndicationChanged", that.showAlertIndication); } - return res; + res.push(temp); } - }; + return res; + } + }, + getEventList: function(clusterId) { + var list, + deferred, + utils = window.ngDeps.utils; - store.getEventList = function(clusterId) { - var list, - deferred; - - deferred = $q.defer(); - utils.getEventList(clusterId) - .then(function(data) { - list = data ? _formatEventData(data) : []; - deferred.resolve(list); - }).catch(function(e) { - deferred.reject(e); - }); + deferred = Q.defer(); + utils.getEventList(clusterId) + .then(function(data) { + list = data ? _formatEventData(data) : []; + deferred.resolve(list); + }).catch(function(e) { + deferred.reject(e); + }); - return deferred.promise; + return deferred.promise; - function _formatEventData(data) { - var len = data.length, - res = [], - temp = {}, - i; + function _formatEventData(data) { + var len = data.length, + res = [], + temp = {}, + i; - for ( i = 0; i < len; i++) { - temp = {}, - temp.timeStamp = new Date(data[i].timestamp); - temp.priority = data[i].priority; - temp.message = data[i].message; - temp.message_id = data[i].message_id; - res.push(temp); - } - return res; + for (i = 0; i < len; i++) { + temp = {}; + temp.timeStamp = moment(new Date(data[i].timestamp)).format('DD-MMM-YY HH:mm:ss'); + temp.priority = data[i].priority; + temp.message = data[i].message; + temp.message_id = data[i].message_id; + res.push(temp); } - }; + return res; + } } +}; + +angular + .module("TendrlModule") + .service("eventStore", eventStore); -})(); \ No newline at end of file +/*@ngInject*/ +function eventStore() { + return EventStore; +} diff --git a/src/modules/base/header/header.html b/src/modules/base/header/header.html index 3933b0ca..b3196ff0 100644 --- a/src/modules/base/header/header.html +++ b/src/modules/base/header/header.html @@ -33,7 +33,7 @@