diff --git a/app/helpers.php b/app/helpers.php index d3f7e07b..5fa040f4 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -99,7 +99,6 @@ if (! function_exists('bs_footer')) { $scripts = [ assets('js/app.min.js'), assets('lang/'.config('app.locale').'/locale.js'), - assets('js/general.js') ]; if ($page_identification !== "") { diff --git a/gulpfile.js b/gulpfile.js index 1c098792..4e509a14 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,24 +2,26 @@ * @Author: printempw * @Date: 2016-07-21 13:38:26 * @Last Modified by: printempw -* @Last Modified time: 2017-01-18 23:04:20 +* @Last Modified time: 2017-01-19 23:07:05 */ 'use strict'; -let gulp = require('gulp'), +var gulp = require('gulp'), + babel = require('gulp-babel'), elixir = require('laravel-elixir'), uglify = require('gulp-uglify'), sass = require('gulp-sass'), cleanCss = require('gulp-clean-css'), del = require('del'), - zip = require('gulp-zip'); + zip = require('gulp-zip'), + notify = require('gulp-notify'); require('laravel-elixir-replace'); let version = require('./package.json').version; -let vendor_js = [ +let vendorJs = [ 'jquery/dist/jquery.min.js', 'bootstrap/dist/js/bootstrap.min.js', 'AdminLTE/dist/js/app.min.js', @@ -28,11 +30,11 @@ let vendor_js = [ 'AdminLTE/plugins/datatables/dataTables.bootstrap.min.js', 'iCheck/icheck.min.js', 'toastr/toastr.min.js', + 'es6-promise/es6-promise.auto.min.js', 'sweetalert2/dist/sweetalert2.min.js', - 'es6-promise/es6-promise.min.js' ]; -let vendor_css = [ +let vendorCss = [ 'bootstrap/dist/css/bootstrap.min.css', 'AdminLTE/dist/css/AdminLTE.min.css', 'AdminLTE/plugins/datatables/dataTables.bootstrap.css', @@ -40,72 +42,67 @@ let vendor_css = [ 'font-awesome/css/font-awesome.min.css', 'iCheck/skins/square/blue.css', 'toastr/toastr.min.css', - 'sweetalert2/dist/sweetalert2.min.css' + 'sweetalert2/dist/sweetalert2.min.css', ]; let replacements = [ - ['@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);', ''], - ['../fonts/glyphicons', '../fonts/glyphicons'], - ['../fonts/fontawesome', '../fonts/fontawesome'], ['blue.png', '"../images/blue.png"'], ['blue@2x.png', '"../images/blue@2x.png"'], + ['../fonts/glyphicons', '../fonts/glyphicons'], + ['../fonts/fontawesome', '../fonts/fontawesome'], ['../img/loading.gif', '"../images/loading.gif"'], - ['../img/loading-sm.gif', '"../images/loading-sm.gif"'] + ['../img/loading-sm.gif', '"../images/loading-sm.gif"'], + ['@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic);', ''], +]; + +let fonts = [ + 'font-awesome/fonts/**', + 'bootstrap/dist/fonts/**', +]; + +let images = [ + 'iCheck/skins/square/blue.png', + 'iCheck/skins/square/blue@2x.png', + 'bootstrap-fileinput/img/loading.gif', + 'bootstrap-fileinput/img/loading-sm.gif', ]; elixir.config.sourcemaps = false; elixir((mix) => { - mix - .scripts(vendor_js.map((js) => 'resources/assets/src/bower_components/' + js).concat([ - 'resources/assets/src/js/utils.js' + mix // compile sass files & ES6 scripts first + .task('compile-sass') + .task('compile-es6') + + .scripts(convertRelativePath(vendorJs).concat([ + 'resources/assets/dist/js/general.js' ]), 'resources/assets/dist/js/app.min.js', './') - .styles(vendor_css.map((css) => 'resources/assets/src/bower_components/' + css), 'resources/assets/dist/css/app.min.css', './') + .styles(convertRelativePath(vendorCss), 'resources/assets/dist/css/app.min.css', './') .replace('resources/assets/dist/css/app.min.css', replacements) // copy fonts & images - .copy([ - 'resources/assets/src/bower_components/bootstrap/dist/fonts/**', - 'resources/assets/src/bower_components/font-awesome/fonts/**' - ], 'resources/assets/dist/fonts/') - .copy([ - 'resources/assets/src/bower_components/iCheck/skins/square/blue.png', - 'resources/assets/src/bower_components/iCheck/skins/square/blue@2x.png', - 'resources/assets/src/bower_components/bootstrap-fileinput/img/loading.gif', - 'resources/assets/src/bower_components/bootstrap-fileinput/img/loading-sm.gif' - ], 'resources/assets/dist/images/') - - .task('sass') - .task('uglify'); + .copy(convertRelativePath(fonts), 'resources/assets/dist/fonts/') + .copy(convertRelativePath(images), 'resources/assets/dist/images/'); }); // compile sass -gulp.task('sass', () => { +gulp.task('compile-sass', () => { gulp.src('resources/assets/src/sass/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(cleanCss()) .pipe(gulp.dest('./resources/assets/dist/css')); }); -gulp.task('uglify', () => { +gulp.task('compile-es6', () => { gulp.src('resources/assets/src/js/*.js') + .pipe(babel({ + presets: ['es2015'] + })) .pipe(uglify()) .pipe(gulp.dest('./resources/assets/dist/js')); }); -function clearCache() { - return del([ - 'storage/logs/*', - 'storage/debugbar/*', - 'storage/update_cache/*', - 'storage/yaml-translation/*', - 'storage/framework/cache/*', - 'storage/framework/sessions/*', - 'storage/framework/views/*' - ]); -} - // delete cache files gulp.task('clear', () => { clearCache(); @@ -115,6 +112,14 @@ gulp.task('clear', () => { gulp.task('zip', () => { clearCache(); + console.info("============================================================================") + console.info("= Don't forget to compile Sass & ES2015 files before publishing a release! ="); + console.info("============================================================================") + + let zipPath = `blessing-skin-server-v${version}.zip`; + + console.log(`Zip archive will be saved to ${zipPath}.`); + return gulp.src([ '**/*.*', 'LICENSE', @@ -144,6 +149,33 @@ gulp.task('zip', () => { '!vendor/symfony/css-selector/**/*.*', '!vendor/symfony/dom-crawler/**/*.*' ], { dot: true }) - .pipe(zip('blessing-skin-server-v'+version+'.zip')) - .pipe(gulp.dest('../')); + .pipe(zip(zipPath)) + .pipe(gulp.dest('../')) + .pipe(notify({ message: `Zip archive saved to ${zipPath}!` })); }); + +gulp.task('notify') + +gulp.task('watch', () => { + // Watch .scss files + gulp.watch('resources/assets/src/sass/*.scss', ['compile-sass'], () => notify({ message: 'Sass files compiled!' })); + // Watch .js files + gulp.watch('resources/assets/src/js/*.js', ['compile-es6'], () => notify({ message: 'ES6 scripts compiled!' })); + gulp.watch('resources/assets/src/js/general.js', ['scripts']); +}); + +function convertRelativePath(paths) { + return paths.map(relativePath => 'resources/assets/src/bower_components/' + relativePath); +} + +function clearCache() { + return del([ + 'storage/logs/*', + 'storage/debugbar/*', + 'storage/update_cache/*', + 'storage/yaml-translation/*', + 'storage/framework/cache/*', + 'storage/framework/sessions/*', + 'storage/framework/views/*' + ]); +} diff --git a/package.json b/package.json index f433c147..74dbe3cc 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,9 @@ "dev": "gulp watch" }, "devDependencies": { + "babel-preset-es2015": "^6.18.0", "gulp": "^3.9.1", + "gulp-babel": "^6.1.2", "gulp-clean-css": "^2.0.11", "gulp-concat": "^2.6.0", "gulp-jshint": "^2.0.1", diff --git a/resources/assets/src/js/general.js b/resources/assets/src/js/general.js index bd30d654..09c5c21f 100644 --- a/resources/assets/src/js/general.js +++ b/resources/assets/src/js/general.js @@ -2,49 +2,227 @@ * @Author: printempw * @Date: 2016-09-15 10:39:41 * @Last Modified by: printempw -* @Last Modified time: 2017-01-18 21:35:01 +* @Last Modified time: 2017-01-19 22:42:44 */ 'use strict'; -function logout(with_out_confirm, callback) { - if (!with_out_confirm) { - swal({ - text: trans('general.confirmLogout'), - type: 'warning', - showCancelButton: true, - confirmButtonText: trans('general.confirm'), - cancelButtonText: trans('general.cancel') - }).then(function() { - do_logout(function(json) { - swal({ - type: 'success', - html: json.msg - }); - window.setTimeout(function() { - window.location = url(); - }, 1000); - }); - }); - } else { - do_logout(function(json) { - if (callback) callback(json); - }); +$.locales = {}; +$.currentLocale = {}; + +/** + * Check if given value is empty. + * + * @param {any} obj + * @return {Boolean} + */ +function isEmpty(obj) { + + // null and undefined are "empty" + if (obj == null) return true; + + // Assume if it has a length property with a non-zero value + // that that property is correct. + if (obj.length > 0) return false; + if (obj.length === 0) return true; + + // If it isn't an object at this point + // it is empty, but it can't be anything *but* empty + // Is it empty? Depends on your application. + if (typeof obj !== "object") return true; + + // Otherwise, does it have any properties of its own? + // Note that this doesn't handle + // toString and valueOf enumeration bugs in IE < 9 + for (var key in obj) { + if (hasOwnProperty.call(obj, key)) return false; + } + + return true; +} + +/** + * Load current selected language. + * + * @return void + */ +function loadLocales() { + for (lang in $.locales) { + if (!isEmpty($.locales[lang])) { + $.currentLocale = $.locales[lang] || {}; + } } } -function do_logout(callback) { - $.ajax({ - type: "POST", - url: url('auth/logout'), - dataType: "json", - success: function(json) { - if (callback) callback(json); - }, - error: showAjaxError +/** + * Translate according to given key. + * + * @param {string} key + * @param {dict} parameters + * @return {string} + */ +function trans(key, parameters = {}) { + if (isEmpty($.currentLocale)) { + loadLocales(); + } + + let segments = key.split('.'); + let temp = $.currentLocale || {}; + + for (i in segments) { + if (isEmpty(temp[segments[i]])) { + return key; + } else { + temp = temp[segments[i]]; + } + } + + for (i in parameters) { + if (!isEmpty(parameters[i])) { + temp = temp.replace(':'+i, parameters[i]); + } + } + + return temp; +} + +function showModal(msg, title = 'Messgae', type = 'default', callback) { + let btnType = (type != "default") ? "btn-outline" : "btn-primary"; + + let dom = ` +