🧲 New features Custom user role permissions Employee edit form updated Employee daily task list Attendance and employee distribution charts on dashboard Improvements to company structure and company assets module Improved tables for displaying data in several modules Faster data loading (specially for employee module) Initials based profile pictures Re-designed login page Re-designed user profile page Improvements to filtering New REST endpoints for employee qualifications 🐛 Bug fixes Fixed, issue with managers being able to create performance reviews for employees who are not their direct reports Fixed, issues related to using full profile image instead of using smaller version of profile image Changing third gender to other Improvements and fixes for internal frontend data caching
380 lines
9.8 KiB
JavaScript
380 lines
9.8 KiB
JavaScript
const gulp = require('gulp');
|
|
const browserify = require('browserify');
|
|
const source = require('vinyl-source-stream');
|
|
const uglify = require('gulp-uglify');
|
|
const uglifyes = require('gulp-uglify-es').default;
|
|
const composer = require('gulp-uglify/composer');
|
|
const sourcemaps = require('gulp-sourcemaps');
|
|
const buffer = require('vinyl-buffer');
|
|
const obfuscate = require('gulp-obfuscate');
|
|
const minify = require('gulp-minify');
|
|
const es = require('event-stream');
|
|
const rename = require('gulp-rename');
|
|
const concat = require('gulp-concat');
|
|
const copy = require('gulp-copy');
|
|
const babel = require('gulp-babel');
|
|
const less = require('gulp-less');
|
|
const path = require('path');
|
|
const cleanCSS = require('gulp-clean-css');
|
|
const javascriptObfuscator = require('gulp-javascript-obfuscator');
|
|
const ifElse = require('gulp-if-else');
|
|
const clean = require('gulp-clean');
|
|
|
|
const env = process.argv.filter((item) => item.substr(0, 3) === '--e');
|
|
let isProduction = false;
|
|
if (env.length === 1) {
|
|
isProduction = env[0].substr(3) === 'prod';
|
|
}
|
|
|
|
if (isProduction) {
|
|
process.env.NODE_ENV = 'production';
|
|
}
|
|
|
|
gulp.task('clean', () => gulp.src('web/dist', { read: false, allowEmpty: true }).pipe(clean()));
|
|
|
|
gulp.task('pack-js', (done) => gulp.src([
|
|
'web/js/jquery2.0.2.min.js',
|
|
'web/js/jquery-ui.js',
|
|
'web/themejs/bootstrap.js',
|
|
'web/js/jquery.placeholder.js',
|
|
'web/js/base64.js',
|
|
'web/js/bootstrap-datepicker.js',
|
|
'web/js/select2/select2.min.js',
|
|
'web/js/bootstrap-colorpicker-2.1.1/js/bootstrap-colorpicker.min.js',
|
|
'web/js/fullcaledar/lib/moment.min.js',
|
|
'web/js/fullcaledar/fullcalendar.min.js',
|
|
'web/js/clipboard.js',
|
|
'web/api-common/datatables/jquery.dataTables.js',
|
|
'web/api-common/datatables/dataTables.bootstrap.js',
|
|
'web/themejs/AdminLTE/app.js',
|
|
'web/bower_components/tinymce/tinymce.min.js',
|
|
'web/bower_components/simplemde/dist/simplemde.min.js',
|
|
'web/bower_components/inputmask/dist/min/jquery.inputmask.bundle.min.js',
|
|
'web/js/signature_pad.js',
|
|
'web/js/date.js',
|
|
'web/js/json2.js',
|
|
'web/api-common/app-global.js',
|
|
])
|
|
.pipe(concat('third-party.js'))
|
|
.pipe(gulp.dest('web/dist')));
|
|
|
|
gulp.task('compile-ant-less', () => gulp.src([
|
|
'web/node_modules/antd/dist/antd.less',
|
|
]).pipe(less({
|
|
paths: [path.join(__dirname, 'less', 'includes')],
|
|
javascriptEnabled: true,
|
|
}))
|
|
.pipe(concat('antd.css'))
|
|
.pipe(gulp.dest('web/dist')));
|
|
|
|
gulp.task('pack-css', (done) => gulp.src([
|
|
'web/themecss/bootstrap.css',
|
|
'web/themecss/fa-all-5.8.2.min.css',
|
|
// 'web/themecss/font-awesome.css',
|
|
'web/themecss/ionicons.min.css',
|
|
'web/bower_components/material-design-icons/iconfont/material-icons.css',
|
|
'web/js/fullcaledar/fullcalendar.css',
|
|
'web/themecss/datatables/dataTables.bootstrap.css',
|
|
'web/css/jquery.timepicker.css',
|
|
'web/css/datepicker.css',
|
|
'web/css/bootstrap-datetimepicker.min.css',
|
|
'web/js/select2/select2.css',
|
|
'web/js/bootstrap-colorpicker-2.1.1/css/bootstrap-colorpicker.css',
|
|
'web/themecss/AdminLTE.css',
|
|
'web/css/fa-animations.css',
|
|
'web/css/style.css',
|
|
'web/bower_components/simplemde/dist/simplemde.min.css',
|
|
'web/node_modules/codemirror/lib/codemirror.css',
|
|
'web/dist/antd.css',
|
|
])
|
|
.pipe(cleanCSS())
|
|
.pipe(concat('third-party.css'))
|
|
.pipe(gulp.dest('web/dist')));
|
|
|
|
gulp.task('login-css', (done) => gulp.src([
|
|
'web/css/login/bootstrap.css',
|
|
'web/css/login/main.css',
|
|
'web/themecss/fa-all-5.8.2.min.css',
|
|
'web/themecss/ionicons.min.css',
|
|
'web/bower_components/material-design-icons/iconfont/material-icons.css',
|
|
])
|
|
.pipe(cleanCSS())
|
|
.pipe(concat('login.css'))
|
|
.pipe(gulp.dest('web/dist')));
|
|
|
|
gulp.task('login-js', () => browserify({
|
|
entries: [
|
|
'web/js/jquery-1.8.1.js',
|
|
'web/bootstrap/js/bootstrap.js',
|
|
'web/api-common/login.js',
|
|
],
|
|
basedir: '.',
|
|
debug: true,
|
|
cache: {},
|
|
packageCache: {},
|
|
})
|
|
.transform('babelify', {
|
|
plugins: [
|
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
|
],
|
|
presets: ['@babel/preset-env'],
|
|
extensions: ['.js'],
|
|
})
|
|
.bundle()
|
|
.pipe(source('login.js'))
|
|
.pipe(buffer())
|
|
.pipe(ifElse(isProduction, () => uglifyes(
|
|
{
|
|
compress: true,
|
|
mangle: {
|
|
reserved: [],
|
|
},
|
|
},
|
|
)))
|
|
.pipe(gulp.dest('./web/dist')));
|
|
|
|
gulp.task('copy-assets', (done) => {
|
|
const tasks = [];
|
|
tasks.push(gulp
|
|
.src([
|
|
'web/js/select2/*.png',
|
|
'web/js/select2/*.gif',
|
|
'web/js/select2/*.gif',
|
|
]).pipe(gulp.dest('web/dist/img/select2')));
|
|
|
|
tasks.push(gulp
|
|
.src([
|
|
'web/js/bootstrap-colorpicker-2.1.1/img/bootstrap-colorpicker/*.png',
|
|
]).pipe(gulp.dest('web/dist/img/bootstrap-colorpicker')));
|
|
|
|
es.merge.apply(null, tasks).on('end', done);
|
|
});
|
|
|
|
gulp.task('api-common', (done) => browserify({
|
|
basedir: '.',
|
|
debug: true,
|
|
entries: ['web/api-common/entry.js'],
|
|
cache: {},
|
|
packageCache: {},
|
|
})
|
|
.transform('babelify', {
|
|
presets: ['@babel/preset-env', '@babel/preset-react'], extensions: ['.js', '.jsx'],
|
|
})
|
|
.transform(require('browserify-css'))
|
|
.bundle()
|
|
.pipe(source('common.js'))
|
|
.pipe(buffer())
|
|
.pipe(ifElse(!isProduction, () => sourcemaps.init({ loadMaps: true })))
|
|
.pipe(ifElse(isProduction, () => uglifyes(
|
|
{
|
|
compress: true,
|
|
mangle: {
|
|
reserved: [
|
|
'Aes',
|
|
'RequestCache',
|
|
'SocialShare',
|
|
'setupTimeUtils',
|
|
'setupNotifications',
|
|
],
|
|
},
|
|
},
|
|
)))
|
|
.pipe(ifElse(isProduction, () => javascriptObfuscator({
|
|
compact: true,
|
|
})))
|
|
.pipe(ifElse(!isProduction, () => sourcemaps.write('./')))
|
|
.pipe(gulp.dest('web/dist')));
|
|
|
|
const vendorReact = ['react', 'react-dom'];
|
|
const vendorAntd = ['antd'];
|
|
const vendorAntdIcons = ['@ant-design/icons'];
|
|
const vendorAntv = ['@antv/g2plot'];
|
|
const vendorOther = ['moment', 'codemirror'];
|
|
|
|
const vendorList = [
|
|
['vendorReact.js', vendorReact, []],
|
|
['vendorAntd.js', vendorAntd, vendorReact],
|
|
['vendorAntdIcons.js', vendorAntdIcons, vendorReact],
|
|
['vendorAntv.js', vendorAntv, vendorReact],
|
|
['vendorOther.js', vendorOther, []],
|
|
];
|
|
|
|
const vendorsFlat = vendorList.reduce((acc, item) => {
|
|
acc.push(...item[1]);
|
|
return acc;
|
|
}, []);
|
|
|
|
const compileVendor = (name, vendors, external) => {
|
|
const b = browserify({
|
|
basedir: './web',
|
|
debug: true,
|
|
});
|
|
|
|
// require all libs specified in vendors array
|
|
vendors.forEach((lib) => {
|
|
b.require(lib);
|
|
});
|
|
|
|
return b.external(external)
|
|
.bundle()
|
|
.pipe(source(name))
|
|
.pipe(buffer())
|
|
.pipe(ifElse(isProduction, () => uglifyes(
|
|
{
|
|
compress: true,
|
|
mangle: {
|
|
reserved: [],
|
|
},
|
|
},
|
|
)))
|
|
.pipe(gulp.dest('./web/dist'));
|
|
};
|
|
|
|
gulp.task('vendor', (done) => {
|
|
const tasks = vendorList
|
|
.map(([name, vendors, external]) => compileVendor(name, vendors, external));
|
|
|
|
es.merge.apply(null, tasks).on('end', done);
|
|
});
|
|
|
|
gulp.task('admin-js', (done) => {
|
|
// we define our input files, which we want to have
|
|
// bundled:
|
|
const files = [
|
|
'attendance',
|
|
'company_structure',
|
|
'clients',
|
|
'charts',
|
|
'dashboard',
|
|
'data',
|
|
'documents',
|
|
'employees',
|
|
'fieldnames',
|
|
'jobs',
|
|
'loans',
|
|
'metadata',
|
|
'modules',
|
|
'overtime',
|
|
'payroll',
|
|
'permissions',
|
|
'projects',
|
|
'qualifications',
|
|
'reports',
|
|
'salary',
|
|
'settings',
|
|
'travel',
|
|
'users',
|
|
];
|
|
|
|
// map them to our stream function
|
|
return browserify({
|
|
entries: files.map((file) => `web/admin/src/${file}/index.js`),
|
|
basedir: '.',
|
|
debug: true,
|
|
cache: {},
|
|
packageCache: {},
|
|
})
|
|
.external(vendorsFlat)
|
|
.transform('babelify', {
|
|
plugins: [
|
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
|
],
|
|
presets: ['@babel/preset-env', '@babel/preset-react'],
|
|
extensions: ['.js', '.jsx'],
|
|
})
|
|
.transform(require('browserify-css'))
|
|
.bundle()
|
|
.pipe(source('admin-bundle.js'))
|
|
.pipe(buffer())
|
|
.pipe(ifElse(!isProduction, () => sourcemaps.init({ loadMaps: true })))
|
|
.pipe(ifElse(isProduction, () => uglifyes(
|
|
{
|
|
compress: true,
|
|
mangle: {
|
|
reserved: [],
|
|
},
|
|
},
|
|
)))
|
|
.pipe(ifElse(isProduction, () => javascriptObfuscator({
|
|
compact: true,
|
|
})))
|
|
.pipe(ifElse(!isProduction, () => sourcemaps.write('./')))
|
|
.pipe(gulp.dest('./web/dist'));
|
|
});
|
|
|
|
gulp.task('modules-js', (done) => {
|
|
// we define our input files, which we want to have
|
|
// bundled:
|
|
const files = [
|
|
'attendance',
|
|
'dashboard',
|
|
'dependents',
|
|
'documents',
|
|
'emergency_contact',
|
|
'employees',
|
|
'loans',
|
|
'overtime',
|
|
'projects',
|
|
'qualifications',
|
|
'reports',
|
|
'salary',
|
|
'staffdirectory',
|
|
'time_sheets',
|
|
'travel',
|
|
];
|
|
|
|
// map them to our stream function
|
|
return browserify({
|
|
entries: files.map((file) => `web/modules/src/${file}/index.js`),
|
|
basedir: '.',
|
|
debug: true,
|
|
cache: {},
|
|
packageCache: {},
|
|
})
|
|
.external(vendorsFlat)
|
|
.transform('babelify', {
|
|
plugins: [
|
|
['@babel/plugin-proposal-class-properties', { loose: true }],
|
|
],
|
|
presets: ['@babel/preset-env', '@babel/preset-react'],
|
|
extensions: ['.js', '.jsx'],
|
|
})
|
|
.transform(require('browserify-css'))
|
|
.bundle()
|
|
.pipe(source('modules-bundle.js'))
|
|
.pipe(buffer())
|
|
.pipe(ifElse(!isProduction, () => sourcemaps.init({ loadMaps: true })))
|
|
.pipe(ifElse(isProduction, () => uglifyes(
|
|
{
|
|
compress: true,
|
|
mangle: {
|
|
reserved: [],
|
|
},
|
|
},
|
|
)))
|
|
.pipe(ifElse(isProduction, () => javascriptObfuscator({
|
|
compact: true,
|
|
})))
|
|
.pipe(ifElse(!isProduction, () => sourcemaps.write('./')))
|
|
.pipe(gulp.dest('./web/dist'));
|
|
});
|
|
|
|
|
|
gulp.task('watch', () => {
|
|
gulp.watch('web/admin/src/*/*.js', gulp.series('admin-js'));
|
|
gulp.watch('web/modules/src/*/*.js', gulp.series('modules-js'));
|
|
});
|
|
|
|
gulp.task('default', gulp.series(
|
|
'compile-ant-less',
|
|
'pack-js',
|
|
'pack-css',
|
|
'login-css',
|
|
'login-js',
|
|
'copy-assets',
|
|
'api-common',
|
|
'vendor',
|
|
'admin-js',
|
|
'modules-js',
|
|
));
|