Browse Source

NEW: build tools of admin and fronted switched to webpack
CHG: changed dest/build folder to /assets/{admin|frontend}

Giancarlo 7 years ago
parent
commit
7a97d9da6c

+ 5 - 8
.gitignore

@@ -50,14 +50,11 @@ node_modules
 tmp
 tmp
 src_minified
 src_minified
 import
 import
-dist
-
-# Custom for current project
-omlink.min.js
-omlink.css
-bundle.js
-bundle.css
 /cfg/*.old
 /cfg/*.old
-/src/OpenMind/Admin/ui/assets/build
 /fbtpl
 /fbtpl
+
+# webpack generated files
 masterpage.tpl
 masterpage.tpl
+errors.tpl
+assets/admin
+assets/frontend

+ 0 - 0
ui/images/bell.png → assets/images/bell.png


+ 0 - 0
ui/images/favicon_omlink.ico → assets/images/favicon.ico


+ 0 - 0
src/OpenMind/Admin/ui/assets/images/logo-sm.png → assets/images/logo-sm.png


+ 0 - 0
src/OpenMind/Admin/ui/assets/images/logo.png → assets/images/logo.png


+ 0 - 0
ui/images/om-link-logo.png → assets/images/om-link-logo.png


+ 0 - 0
src/OpenMind/Admin/ui/assets/images/users/default.png → assets/images/users/default.png


+ 1 - 1
cfg/config.bin

@@ -1 +1 @@
-eJx9kV1v2jAUhu8t+T9YXG2aGpwGaDdkaSEYSBtilA/EVlVRCC5ETWLmOPQD8d/nQKvdzZLl4yMfv895z8O2EOu0qB8hWNIgdJlPTKNvYAjsOGIes8ekU8us24HAsZ0ZRQRFQUwhiF3S5F0IxnQUT8k1BNR32Nj1p6QTR5OrW10wc6czT++IPGkFDsGdHRj8dZ9LTo5HlZf8y9dvltm3Bhjj00n/FfqkU77Vf4ofO1ErUogsLdpouBdSEcvCg+FmXaUlJ6Is8upZi2zWTc0lkUKo9rJP65qIPa/KvNpAMLdXychz/fskcuc0CalDLIwv+YBGwa9kwoJkYsdeREzcdrMkSjaaFYIhWqRqB8HIDmkceKR70YQgdCPq23NK2PzKO2c8NmWJE4cRm9NA9/bzo+Z06mqT8jLd8rpbiK0w9tUWAtdhftLWxNH/Hjfq8rxFCXnBM4Vednm2Q1lTK1FyibJCt4t4la4LjfwJcGb7hIXgwWEBNZ7Wj+eWpNg0mcpFBcHZY/P7tWEObg0TG2ZPO3B2uo97PesiKw9aJ6JhBMEzfyMO/rdMs3fTw9cW7t/outb433L7/ny4k+y+8kOnWlTTd6s52gM+C/3V8lC3OBpo4vrjEVuFNFi6DtVcoUfpop2QVsYX3UxUmxopgV7SXKEnIVHN9amnuhavOpaHPOOoEgqlhzQvLg5MA9uhyYIGLht/DBuCv3u+284=
+eJx9UVtv2jAUfj+/wsrTpqnBIUC7VZYWgoG0IUa5oG5VFYVgIGoSM8ehF8R/n8k67W2WLH86Osff5TzuSrHOyuYJVjSMPBYQyxyaGJwkZj5zJsRoZN4zwHXcOUUExWFCIfFIW/RgQsfJjPSBBi6beMGMGEk8vboxYO7N5r6+MdnqrzncOaHJXw+F5OR0UkXFP33+YltDe4QxPp9hEgXEqN6aX+W3vWgUKUWelRd0exBSEdvGo9vNus4qTkRVFvWzAZt123BJpBBK40PWNEQceF0V9QYWzkM69r3gPo29BU0j6hIb464c0jj8kU5ZmE6dxI+JhbWJFVGy5QC3aJmpPYydiCahT3p/uCDyYho4C0rY4sq/FHw2Y6mbRDFb0FAb+v4xcT73dCpFle140yvFTpiHegeey4L0MpLE/+ttVdetRUS85LlCL/si36O8bZSouER5qT0iXmfrksNf8k7Wh0x4dFlIze366WJEik2bq0LU0CVqfe2b1ujGtLBpDTB0sQ7xYGB3fPKoCWIaxfDM34iL/x3LGlwPcN/Gw2voQv4pd+/PxzvJ7usgcutlPXu325Mz4vMoeFgdG9A6pl4wGbOHiIYrz6VPEPmULi+r0JS4I8xFvWmQEuglKxTaCokarl+9vLV41Vgei5yjWiiUHbOi7DzPQsel6ZKGHpt87BR+A+3b2eA=

+ 3 - 0
package.json

@@ -13,8 +13,10 @@
 		"Deploy": "zip -x ui/css/* ui/js/* -9 -r deploy.zip omlink.sql lib cfg/config.bin cfg/labels.ini index.php bundle.* src_minified ui"
 		"Deploy": "zip -x ui/css/* ui/js/* -9 -r deploy.zip omlink.sql lib cfg/config.bin cfg/labels.ini index.php bundle.* src_minified ui"
 	},
 	},
 	"devDependencies": {
 	"devDependencies": {
+		"acorn": "^6.1.1",
 		"clean-webpack-plugin": "^2.0.1",
 		"clean-webpack-plugin": "^2.0.1",
 		"css-loader": "^2.1.1",
 		"css-loader": "^2.1.1",
+		"file-loader": "^3.0.1",
 		"html-webpack-plugin": "^3.2.0",
 		"html-webpack-plugin": "^3.2.0",
 		"html-webpack-prefix-plugin": "^1.1.0",
 		"html-webpack-prefix-plugin": "^1.1.0",
 		"mini-css-extract-plugin": "^0.6.0",
 		"mini-css-extract-plugin": "^0.6.0",
@@ -22,6 +24,7 @@
 		"optimize-css-assets-webpack-plugin": "^5.0.1",
 		"optimize-css-assets-webpack-plugin": "^5.0.1",
 		"sass-loader": "^7.1.0",
 		"sass-loader": "^7.1.0",
 		"terser": "^3.17.0",
 		"terser": "^3.17.0",
+		"url-loader": "^1.1.2",
 		"webpack": "^4.30.0",
 		"webpack": "^4.30.0",
 		"webpack-cli": "^3.3.1"
 		"webpack-cli": "^3.3.1"
 	},
 	},

+ 42 - 28
src/OpenMind/Admin/package.json

@@ -1,30 +1,44 @@
 {
 {
-  "name": "admin",
-  "version": "1.0.0",
-  "scripts": {
-    "Build DEV": "webpack --mode=none --config webpack.config.js --display-error-details"
-  },
-  "author": "",
-  "license": "ISC",
-  "dependencies": {
-    "bootstrap": "^4.3.1",
-    "datatables.net": "^1.10.19",
-    "datatables.net-bs4": "^1.10.19",
-    "datatables.net-keytable": "^2.5.0",
-    "datatables.net-keytable-bs4": "^2.5.0",
-    "datatables.net-responsive": "^2.2.3",
-    "datatables.net-responsive-bs4": "^2.2.3",
-    "datatables.net-select": "^1.3.0",
-    "datatables.net-select-bs4": "^1.3.0",
-    "jquery": "^3.4.1",
-    "jquery-slimscroll": "^1.3.8",
-    "jszip": "^3.2.1",
-    "node-waves": "^0.7.6",
-    "pdfmake": "^0.1.55",
-    "toastr": "^2.1.4"
-  },
-  "devDependencies": {
-    "webpack": "^4.30.0",
-    "webpack-cli": "^3.3.1"
-  }
+	"name": "admin",
+	"version": "1.2.0",
+	"private": true,
+	"description": "OM-Link Admin Module",
+	"author": "Open Mind",
+	"scripts": {
+		"Build DEV": "webpack --mode=none --config webpack.config.js --display-error-details"
+	},
+	"author": "",
+	"license": "ISC",
+	"dependencies": {
+		"bootstrap": "^4.2.1",
+		"datatables.net": "^1.10.19",
+		"datatables.net-bs4": "^1.10.19",
+		"datatables.net-keytable": "^2.5.0",
+		"datatables.net-keytable-bs4": "^2.5.0",
+		"datatables.net-responsive": "^2.2.3",
+		"datatables.net-responsive-bs4": "^2.2.3",
+		"datatables.net-select": "^1.3.0",
+		"datatables.net-select-bs4": "^1.3.0",
+		"jquery": "^3.4.1",
+		"jquery-slimscroll": "^1.3.8",
+		"jszip": "^3.2.1",
+		"node-waves": "^0.7.6",
+		"pdfmake": "^0.1.55",
+		"toastr": "^2.1.4"
+	},
+	"devDependencies": {
+		"clean-webpack-plugin": "^2.0.1",
+		"css-loader": "^2.1.1",
+		"file-loader": "^3.0.1",
+		"html-webpack-plugin": "^3.2.0",
+		"html-webpack-prefix-plugin": "^1.1.0",
+		"mini-css-extract-plugin": "^0.6.0",
+		"node-sass": "^4.12.0",
+		"optimize-css-assets-webpack-plugin": "^5.0.1",
+		"sass-loader": "^7.1.0",
+		"terser": "^3.17.0",
+		"url-loader": "^1.1.2",
+		"webpack": "^4.30.0",
+		"webpack-cli": "^3.3.1"
+	}
 }
 }

+ 1 - 1
src/OpenMind/Admin/ui/assets/css/style.css

@@ -4594,7 +4594,7 @@ div.hopscotch-bubble .hopscotch-bubble-arrow-container.down .hopscotch-bubble-ar
    Accounts pages
    Accounts pages
 ============= */
 ============= */
 .account-pages {
 .account-pages {
-  background: url("../images/big/bg.jpg") center;
+  background: url("../images/bg.jpg") center;
   position: absolute;
   position: absolute;
   height: 100%;
   height: 100%;
   top: 0;
   top: 0;

+ 0 - 0
src/OpenMind/Admin/ui/assets/images/big/bg.jpg → src/OpenMind/Admin/ui/assets/images/bg.jpg


+ 33 - 0
src/OpenMind/Admin/ui/assets/js/OMGUtils.js

@@ -0,0 +1,33 @@
+const fetchHeaders = {
+	'Accept': 'text/html',
+	'Content-Type': 'text/html',
+	'X-Requested-With': 'XMLHttpRequest',
+	'Cache-Control': 'no-cache',
+	'Pragma': 'no-cache',
+	'Expires': '0'
+};
+
+/**
+ * Make an AJAX request.
+ *
+ * If error, catch return a promise error object:
+ *
+ *  .catch(err => alert(`${err.url}\n\n${err.status} (${err.statusText})`));
+ *
+ * @param url URL of RESTful api to call
+ * @param options the fetch() options
+ * @returns {Promise<Response | never>}
+ */
+export function AjaxReq(url, options) {
+	let defaults = {headers: fetchHeaders};
+	// Extend default options
+	Object.assign(defaults, options);
+
+	return fetch(url, defaults)
+		.then(resp => {
+			if (resp.status === 200)
+				return resp.json();
+			else
+				return Promise.reject(resp);
+		});
+}

+ 11 - 38
src/OpenMind/Admin/ui/assets/js/admin.js

@@ -1,19 +1,13 @@
-import ModalEslDetails from 'ModalEslDetails';
+import {ModalEslDetails} from "./ModalEslDetails";
+import * as OMGUtils from "./OMGUtils";
 
 
 let modalEslDetails = new ModalEslDetails();
 let modalEslDetails = new ModalEslDetails();
 
 
-const fetchHeaders = {
-	'Accept': 'text/html',
-	'Content-Type': 'text/html',
-	'X-Requested-With': 'XMLHttpRequest',
-	'Cache-Control': 'no-cache',
-	'Pragma': 'no-cache',
-	'Expires': '0'
-};
-
 // MAIN JS
 // MAIN JS
 document.addEventListener('DOMContentLoaded', function () {
 document.addEventListener('DOMContentLoaded', function () {
 
 
+	Waves.init();
+
 	$.fn.dataTable.ext.order['dom-checkbox'] = function (settings, col) {
 	$.fn.dataTable.ext.order['dom-checkbox'] = function (settings, col) {
 		return this.api().column(col, {order: 'index'}).nodes().map(function (td, i) {
 		return this.api().column(col, {order: 'index'}).nodes().map(function (td, i) {
 			return $(td).closest('tr').hasClass('selected') ? '1' : '0';
 			return $(td).closest('tr').hasClass('selected') ? '1' : '0';
@@ -52,34 +46,9 @@ document.addEventListener('DOMContentLoaded', function () {
 	});
 	});
 });
 });
 
 
-/**
- * Make an AJAX request.
- *
- * If error, catch return a promise error object:
- *
- *  .catch(err => alert(`${err.url}\n\n${err.status} (${err.statusText})`));
- *
- * @param url
- * @param options
- * @returns {Promise<Response | never>}
- */
-function AjaxReq(url, options) {
-	let defaults = {headers: fetchHeaders};
-	// Extend default options
-	Object.assign(defaults, options);
-
-	return fetch(url, defaults)
-		.then(resp => {
-			if (resp.status === 200)
-				return resp.json();
-			else
-				return Promise.reject(resp);
-		});
-}
-
 function SaveConfig() {
 function SaveConfig() {
 	let config = $('#config_text').val();
 	let config = $('#config_text').val();
-	AjaxReq(`${BASEURL}/admin/config`, {
+	OMGUtils.AjaxReq(`${BASEURL}/admin/config`, {
 		method: 'POST',
 		method: 'POST',
 		body: JSON.stringify({"method": "saveconfig", "value": config})
 		body: JSON.stringify({"method": "saveconfig", "value": config})
 	})
 	})
@@ -88,7 +57,7 @@ function SaveConfig() {
 }
 }
 
 
 function LoadConfig() {
 function LoadConfig() {
-	AjaxReq(`${BASEURL}/admin/config`, {
+	OMGUtils.AjaxReq(`${BASEURL}/admin/config`, {
 		method: 'POST',
 		method: 'POST',
 		body: JSON.stringify({"method": "loadconfig"})
 		body: JSON.stringify({"method": "loadconfig"})
 	})
 	})
@@ -99,6 +68,10 @@ function LoadConfig() {
 		.catch(err => toastr.error(err.url, `${err.status} (${err.statusText})`));
 		.catch(err => toastr.error(err.url, `${err.status} (${err.statusText})`));
 }
 }
 
 
-export function OpenESLDetails(labelID) {
+function OpenESLDetails(labelID) {
 	modalEslDetails.OpenESLDetails(labelID);
 	modalEslDetails.OpenESLDetails(labelID);
 }
 }
+
+window.OpenESLDetails = OpenESLDetails;
+window.LoadConfig = LoadConfig;
+window.SaveConfig = SaveConfig;

+ 7 - 6
src/OpenMind/Admin/ui/assets/js/index.js

@@ -10,21 +10,24 @@ import 'jquery-slimscroll';
 // Required datatable js
 // Required datatable js
 import 'datatables.net';
 import 'datatables.net';
 import 'datatables.net-bs4/css/dataTables.bootstrap4.min.css';
 import 'datatables.net-bs4/css/dataTables.bootstrap4.min.css';
+import 'datatables.net-bs4/js/dataTables.bootstrap4.min.js';
 
 
 // Key Tables
 // Key Tables
 import 'datatables.net-keytable';
 import 'datatables.net-keytable';
-import 'datatables.net-keytable-bs4/css/keyTable.bootstrap4.min.css'
+import 'datatables.net-keytable-bs4/css/keyTable.bootstrap4.min.css';
+import 'datatables.net-keytable-bs4/js/keyTable.bootstrap4.min.js';
 
 
 // Responsive examples
 // Responsive examples
 import 'datatables.net-responsive';
 import 'datatables.net-responsive';
-import 'datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css'
+import 'datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css';
+import 'datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js';
 
 
 // Selection table
 // Selection table
 import "datatables.net-select";
 import "datatables.net-select";
 import 'datatables.net-select-bs4/css/select.bootstrap4.min.css';
 import 'datatables.net-select-bs4/css/select.bootstrap4.min.css';
+import 'datatables.net-select-bs4/js/select.bootstrap4.min.js';
 
 
 // Toastr
 // Toastr
-import 'toastr';
 import 'toastr/build/toastr.min.css';
 import 'toastr/build/toastr.min.css';
 
 
 // CSS
 // CSS
@@ -35,6 +38,4 @@ import '../css/admin.scss';
 // App js
 // App js
 import './jquery.core.js';
 import './jquery.core.js';
 import './jquery.app.js';
 import './jquery.app.js';
-import 'admin';
-
-window.OpenESLDetails = OpenESLDetails;
+import "./admin.js";

+ 2 - 1
src/OpenMind/Admin/ui/labelstatus.tpl

@@ -19,7 +19,7 @@
 		<h4 class="header-title mt-0 m-b-30">ESL Status</h4>
 		<h4 class="header-title mt-0 m-b-30">ESL Status</h4>
 
 
 		<div class="table-responsive-sm">
 		<div class="table-responsive-sm">
-			<table id="datatable" class="table table-sm dt-responsive responsive table-bordered mb-0">
+			<table id="datatable" class="table table-sm dt-responsive responsive table-bordered mb-0 table-striped">
 				<thead>
 				<thead>
 				<tr>
 				<tr>
 					<th></th>
 					<th></th>
@@ -103,6 +103,7 @@
 
 
 					<div class="col-6 mt-2">
 					<div class="col-6 mt-2">
 						<div class="card">
 						<div class="card">
+							<h5 class="card-header">Label info</h5>
 							<h5 class="card-header">Label info</h5>
 							<h5 class="card-header">Label info</h5>
 							<div class="card-body">
 							<div class="card-body">
 								<table class="table table-borderless table-sm" id="cardbox_esl_status">
 								<table class="table table-borderless table-sm" id="cardbox_esl_status">

+ 7 - 12
src/OpenMind/Admin/ui/masterpage_template.tpl

@@ -3,12 +3,10 @@
 <head>
 <head>
 	<meta charset="UTF-8">
 	<meta charset="UTF-8">
 	<title>{{@SITENAME}}</title>
 	<title>{{@SITENAME}}</title>
-	<link href="{{@BASEURL}}/ui/images/favicon.ico" rel="shortcut icon" type="image/x-icon">
+	<link href="{{@BASEURL}}/assets/images/favicon.ico" rel="shortcut icon" type="image/x-icon">
 	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
 	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
 	<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
 	<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
 
 
-	<!-- link href="{{@BASEURL}}/{{@UI}}assets/build/bundle.min.css" rel="stylesheet" type="text/css"/ -->
-
 	<script type="text/javascript">
 	<script type="text/javascript">
 		const BASEURL = '{{@BASEURL}}';
 		const BASEURL = '{{@BASEURL}}';
 	</script>
 	</script>
@@ -27,12 +25,11 @@
 					<span class="logo-small"><i class="mdi mdi-radar"></i></span>
 					<span class="logo-small"><i class="mdi mdi-radar"></i></span>
 					<span class="logo-large"><i class="mdi mdi-radar"></i> OM-Link</span>
 					<span class="logo-large"><i class="mdi mdi-radar"></i> OM-Link</span>
 				</a>
 				</a>
-				<!-- Image Logo -->
+				{*<!-- Image Logo -->
 				<!-- a href="index.html" class="logo">
 				<!-- a href="index.html" class="logo">
-					<img src="{{@BASEURL}}/{{@UI}}assets/images/logo-sm.png" alt="" height="26" class="logo-small">
-					<img src="{{@BASEURL}}/{{@UI}}assets/images/logo.png" alt="" height="24" class="logo-large">
-				</a -->
-
+					<img src="{{@BASEURL}}/assets/images/logo-sm.png" alt="" height="26" class="logo-small">
+					<img src="{{@BASEURL}}/assets/images/logo.png" alt="" height="24" class="logo-large">
+				</a -->*}
 			</div>
 			</div>
 			<!-- End Logo container-->
 			<!-- End Logo container-->
 
 
@@ -80,7 +77,7 @@
 					<li class="dropdown notification-list">
 					<li class="dropdown notification-list">
 						<a class="nav-link dropdown-toggle waves-effect waves-light nav-user" data-toggle="dropdown" href="#" role="button"
 						<a class="nav-link dropdown-toggle waves-effect waves-light nav-user" data-toggle="dropdown" href="#" role="button"
 							 aria-haspopup="false" aria-expanded="false">
 							 aria-haspopup="false" aria-expanded="false">
-							<img src="{{@BASEURL}}/{{@UI}}assets/images/users/default.png" alt="user" class="rounded-circle">
+							<img src="{{@BASEURL}}/assets/images/users/default.png" alt="user" class="rounded-circle">
 						</a>
 						</a>
 						<div class="dropdown-menu dropdown-menu-right profile-dropdown ">
 						<div class="dropdown-menu dropdown-menu-right profile-dropdown ">
 
 
@@ -171,7 +168,7 @@
 				<li class="list-group-item">
 				<li class="list-group-item">
 					<a href="#" class="user-list-item">
 					<a href="#" class="user-list-item">
 						<div class="avatar">
 						<div class="avatar">
-							<img src="{{@BASEURL}}/{{@UI}}assets/images/users/default.png" alt="">
+							<img src="{{@BASEURL}}/assets/images/users/default.png" alt="">
 						</div>
 						</div>
 						<div class="user-desc">
 						<div class="user-desc">
 							<span class="name">FindBox service</span>
 							<span class="name">FindBox service</span>
@@ -201,8 +198,6 @@
 </footer>
 </footer>
 <!-- End Footer -->
 <!-- End Footer -->
 
 
-<!-- script src="{{@BASEURL}}/{{@UI}}assets/build/bundle.min.js"></script -->
-
 </body>
 </body>
 
 
 </body>
 </body>

+ 11 - 6
src/OpenMind/Admin/webpack.config.js

@@ -12,14 +12,15 @@ module.exports = {
 		new HtmlPlugin(
 		new HtmlPlugin(
 			{
 			{
 				template: "./ui/masterpage_template.tpl",
 				template: "./ui/masterpage_template.tpl",
-				filename: "../../masterpage.tpl",
+				filename: path.resolve(__dirname, './ui/masterpage.tpl'),
 			}
 			}
 		),
 		),
 		new MiniCssExtractPlugin({filename: "styles.[contenthash].css"}),
 		new MiniCssExtractPlugin({filename: "styles.[contenthash].css"}),
 		new webpack.ProvidePlugin({
 		new webpack.ProvidePlugin({
 			$: 'jquery',
 			$: 'jquery',
 			jQuery: 'jquery',
 			jQuery: 'jquery',
-			"window.jQuery": 'jquery'
+			"window.jQuery": 'jquery',
+			toastr: 'toastr'
 		})
 		})
 	],
 	],
 	module: {
 	module: {
@@ -30,10 +31,12 @@ module.exports = {
 				// ...use this loaders
 				// ...use this loaders
 				use: [
 				use: [
 					MiniCssExtractPlugin.loader,
 					MiniCssExtractPlugin.loader,
-					{loader: "css-loader", options: {url: false,}},
+					"css-loader",
 					"sass-loader"
 					"sass-loader"
 				]
 				]
-			}
+			},
+			// Import various assets
+			{test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000'}
 		]
 		]
 	},
 	},
 	optimization: {
 	optimization: {
@@ -50,8 +53,10 @@ module.exports = {
 	},
 	},
 	entry: "./ui/assets/js/index.js",
 	entry: "./ui/assets/js/index.js",
 	output: {
 	output: {
-		publicPath: '/omlink/src/openmind/admin/ui/assets/dist/',
-		path: path.resolve(__dirname, "ui/assets/dist/"),
+		publicPath: '/omlink/assets/admin/',
+		path: path.resolve(__dirname, "../../../assets/admin/"),
+		//publicPath: '/omlink/src/openmind/admin/ui/assets/dist/',
+		//path: path.resolve(__dirname, "ui/assets/dist/"),
 		filename: "bundle.[contenthash].js"
 		filename: "bundle.[contenthash].js"
 	},
 	},
 };
 };

+ 2 - 1
src/OpenMind/System/OMUtils.php

@@ -54,7 +54,7 @@ class OMUtils
 	{
 	{
 		// <class priority>
 		// <class priority>
 		//TODO if is necessary to give a priority to some classes before other, initialize here
 		//TODO if is necessary to give a priority to some classes before other, initialize here
-		Global $System, $Web;
+		Global $System, $Web, $f3;
 		$System = new System();  // we need System Base class first, so will force to load as first
 		$System = new System();  // we need System Base class first, so will force to load as first
 		$Web = new Web();
 		$Web = new Web();
 		// </class priority>
 		// </class priority>
@@ -72,6 +72,7 @@ class OMUtils
 				if (!isset($$moduleName)) {
 				if (!isset($$moduleName)) {
 					Global $$moduleName;  // Declare visibility to Global
 					Global $$moduleName;  // Declare visibility to Global
 					$$moduleName = new $className(); // Instantiate the Module, all init procedure must reside in __constructor() method
 					$$moduleName = new $className(); // Instantiate the Module, all init procedure must reside in __constructor() method
+					$$moduleName->setTsStartLoad();
 				}
 				}
 			}
 			}
 		}
 		}

+ 17 - 0
src/OpenMind/System/PluginStrategy.php

@@ -47,11 +47,28 @@ interface IPluginStrategy
  */
  */
 class PluginStrategy implements IPluginStrategy
 class PluginStrategy implements IPluginStrategy
 {
 {
+	static private $timeLoadStart = null;
+
 	public function __construct()
 	public function __construct()
 	{
 	{
 		throw new \Exception("Plugin " . $this->getName() . ' doesn\'t have a __constructor() function. Please provide one.');
 		throw new \Exception("Plugin " . $this->getName() . ' doesn\'t have a __constructor() function. Please provide one.');
 	}
 	}
 
 
+	static function setTsStartLoad() {
+		self::$timeLoadStart = round(microtime(true) * 1000);
+	}
+
+	public function __destruct()
+	{
+		global $f3, $frameworkUtils;
+		if ($f3->get('DEBUG') > 2) {
+			$timeEnd = round(microtime(true) * 1000);
+			$totalMS = $timeEnd - self::$timeLoadStart;
+			$className = get_called_class();
+			$frameworkUtils->getLogger()->write("Class $className loaded in {$totalMS}ms", 'd/m/Y H:i:s');
+		}
+	}
+
 	/**
 	/**
 	 * Return Class name, useful when a list of installed plugins is need
 	 * Return Class name, useful when a list of installed plugins is need
 	 *
 	 *

+ 14 - 11
src/OpenMind/System/System.php

@@ -7,6 +7,9 @@
 
 
 namespace OpenMind\System;
 namespace OpenMind\System;
 
 
+use Base;
+use Cache;
+use DB\SQL;
 
 
 class System extends PluginStrategy
 class System extends PluginStrategy
 {
 {
@@ -14,7 +17,7 @@ class System extends PluginStrategy
 	 * Normal F3 session file cache.
 	 * Normal F3 session file cache.
 	 * Every session will be client related
 	 * Every session will be client related
 	 *
 	 *
-	 * @var \Cache
+	 * @var Cache
 	 */
 	 */
 	private $cache;
 	private $cache;
 
 
@@ -22,7 +25,7 @@ class System extends PluginStrategy
 	 * The shared cache, cache file will be created with prefix 'OMLINK_SHARED_CACHE.xxxxxx' where 'xxxxxx' is the variable name.
 	 * The shared cache, cache file will be created with prefix 'OMLINK_SHARED_CACHE.xxxxxx' where 'xxxxxx' is the variable name.
 	 * Every session will be server related
 	 * Every session will be server related
 	 *
 	 *
-	 * @var \Cache
+	 * @var Cache
 	 */
 	 */
 	private $sharedCache;
 	private $sharedCache;
 
 
@@ -32,9 +35,9 @@ class System extends PluginStrategy
 		// Set Error Handler
 		// Set Error Handler
 		$f3->set('ONERROR', __NAMESPACE__ . '\ErrorHandlers->Handler');
 		$f3->set('ONERROR', __NAMESPACE__ . '\ErrorHandlers->Handler');
 
 
-		$this->cache = \Cache::instance();
+		$this->cache = Cache::instance();
 
 
-		$this->sharedCache = new \Cache();
+		$this->sharedCache = new Cache();
 		$this->sharedCache->load($f3->get('CACHE'), 'OMLINK_SHARED_CACHE');
 		$this->sharedCache->load($f3->get('CACHE'), 'OMLINK_SHARED_CACHE');
 
 
 		// Set Database connection
 		// Set Database connection
@@ -43,7 +46,7 @@ class System extends PluginStrategy
 			if ($f3->get('CLI')) // from cli, always persistent mode
 			if ($f3->get('CLI')) // from cli, always persistent mode
 				$dbMode = TRUE;
 				$dbMode = TRUE;
 
 
-			$db = new \DB\SQL(
+			$db = new SQL(
 				$f3->get('DSN'),
 				$f3->get('DSN'),
 				$f3->get('dbuser'),
 				$f3->get('dbuser'),
 				$f3->get('dbpass'),
 				$f3->get('dbpass'),
@@ -73,14 +76,14 @@ class System extends PluginStrategy
 	/**
 	/**
 	 * Get cache cache
 	 * Get cache cache
 	 *
 	 *
-	 * @return \Cache
+	 * @return Cache
 	 */
 	 */
-	public function getCache(): \Cache
+	public function getCache(): Cache
 	{
 	{
 		return $this->cache;
 		return $this->cache;
 	}
 	}
 
 
-	public function getSharedCache(): \Cache
+	public function getSharedCache(): Cache
 	{
 	{
 		return $this->sharedCache;
 		return $this->sharedCache;
 	}
 	}
@@ -88,7 +91,7 @@ class System extends PluginStrategy
 	/**
 	/**
 	 * AJAX web service for bell notifications and system checking
 	 * AJAX web service for bell notifications and system checking
 	 *
 	 *
-	 * @param $f3
+	 * @param Base $f3
 	 */
 	 */
 	public function getServerStatus($f3)
 	public function getServerStatus($f3)
 	{
 	{
@@ -128,8 +131,8 @@ class System extends PluginStrategy
 	/**
 	/**
 	 * Store in F3 cache the session id, usefull for CLI call
 	 * Store in F3 cache the session id, usefull for CLI call
 	 *
 	 *
-	 * @see System::RestoreWebSession()
 	 * @param string $cacheName
 	 * @param string $cacheName
+	 * @see System::RestoreWebSession()
 	 */
 	 */
 	public Function StoreWebSession(string $cacheName = 'WEBSESSIONID')
 	public Function StoreWebSession(string $cacheName = 'WEBSESSIONID')
 	{
 	{
@@ -139,8 +142,8 @@ class System extends PluginStrategy
 	/**
 	/**
 	 * Restore the web session for CLI calls
 	 * Restore the web session for CLI calls
 	 *
 	 *
-	 * @see System::StoreWebSession()
 	 * @param string $cacheName
 	 * @param string $cacheName
+	 * @see System::StoreWebSession()
 	 */
 	 */
 	public function RestoreWebSession(string $cacheName = 'WEBSESSIONID')
 	public function RestoreWebSession(string $cacheName = 'WEBSESSIONID')
 	{
 	{

+ 15 - 2
src/OpenMind/Web/Controller.php

@@ -14,8 +14,9 @@ class Controller
 {
 {
   /** @var SQL $dbHandle OM-Link Database */
   /** @var SQL $dbHandle OM-Link Database */
   protected $dbHandle;
   protected $dbHandle;
+	private $timeLoadStart = null;
 
 
-  /**
+	/**
    * Sanitized POST request, useful if sanitized POST is need
    * Sanitized POST request, useful if sanitized POST is need
    * @var array $sanitizedPostRequest
    * @var array $sanitizedPostRequest
    */
    */
@@ -23,6 +24,8 @@ class Controller
 
 
   public function __construct($f3)
   public function __construct($f3)
   {
   {
+		$this->timeLoadStart = round(microtime(true) * 1000);
+
     $this->sanitizedPostRequest = $f3->clean($f3->get('POST'));
     $this->sanitizedPostRequest = $f3->clean($f3->get('POST'));
     $this->dbHandle = $f3->get('DB');
     $this->dbHandle = $f3->get('DB');
 
 
@@ -51,8 +54,18 @@ class Controller
 
 
     return;
     return;
   }
   }
+  public function __destruct()
+	{
+		global $f3, $frameworkUtils;
+		if ($f3->get('DEBUG') > 2) {
+			$timeEnd = round(microtime(true) * 1000);
+			$totalMS = $timeEnd - $this->timeLoadStart;
+			$className = get_called_class();
+			$frameworkUtils->getLogger()->write("Page $className loaded in {$totalMS}ms", 'd/m/Y H:i:s');
+		}
+	}
 
 
-  /**
+	/**
    * Return the sanitized POST parameters
    * Return the sanitized POST parameters
    *
    *
    * @return mixed
    * @return mixed

+ 3 - 3
ui/errors.tpl → ui/errors_template.tpl

@@ -4,7 +4,9 @@
 	<meta charset="UTF-8">
 	<meta charset="UTF-8">
 	<meta content="width=device-width, initial-scale=1" name="viewport">
 	<meta content="width=device-width, initial-scale=1" name="viewport">
 	<title>{{@SITENAME}} error page</title>
 	<title>{{@SITENAME}} error page</title>
-	<link href="{{@BASEURL}}/bundle.css" rel="stylesheet" type="text/css"/>
+	<script type="text/javascript">
+		const BASEURL = '{{@BASEURL}}';
+	</script>
 </head>
 </head>
 <body class="bg-light error_body">
 <body class="bg-light error_body">
 
 
@@ -25,7 +27,5 @@
 	</div>
 	</div>
 </div>
 </div>
 
 
-<script src="{{@BASEURL}}/bundle.js"></script>
-
 </body>
 </body>
 </html>
 </html>

+ 2 - 2
ui/footer.tpl

@@ -1,13 +1,13 @@
 <nav class="navbar fixed-bottom navbar-expand navbar-dark">
 <nav class="navbar fixed-bottom navbar-expand navbar-dark">
 	<check if="{{ isset(@PREVPAGE) }}">
 	<check if="{{ isset(@PREVPAGE) }}">
-		<a href="{{@PREVPAGE}}"><img class="navbar-brand" height="50px" src="{{@BASEURL}}/ui/images/arrow-left.svg"/></a>
+		<a href="{{@PREVPAGE}}"><img class="navbar-brand" height="50px" src="{{@BASEURL}}/assets/images/arrow-left.svg"/></a>
 	</check>
 	</check>
 	<div class="nav-item">Utente: {{@COOKIE.username}}</div>
 	<div class="nav-item">Utente: {{@COOKIE.username}}</div>
 	<div class="collapse navbar-collapse"></div>
 	<div class="collapse navbar-collapse"></div>
 	<div class="nav-item text-dark pr-2" style="font-size: 0.7em">Version: {{@VERSION}}</div>
 	<div class="nav-item text-dark pr-2" style="font-size: 0.7em">Version: {{@VERSION}}</div>
 	<div class="navbar-brand">
 	<div class="navbar-brand">
 		<a href="{{@BASEURL}}">
 		<a href="{{@BASEURL}}">
-			<img height="40" src="{{@BASEURL}}/ui/images/om-link-logo.png"/>
+			<img height="40" src="{{@BASEURL}}/assets/images/om-link-logo.png"/>
 		</a>
 		</a>
 	</div>
 	</div>
 </nav>
 </nav>

+ 1 - 1
ui/header.tpl

@@ -18,7 +18,7 @@
 
 
 	<div class="ml-auto dropdown dropleft navbar-brand">
 	<div class="ml-auto dropdown dropleft navbar-brand">
 		<a aria-expanded="false" aria-haspopup="true" class="disabled" class="mr-3" data-toggle="dropdown" href="#" id="notification_area_button" style="position: relative">
 		<a aria-expanded="false" aria-haspopup="true" class="disabled" class="mr-3" data-toggle="dropdown" href="#" id="notification_area_button" style="position: relative">
-			<img src="{{@BASEURL}}/ui/images/bell.png"/>
+			<img src="{{@BASEURL}}/assets/images/bell.png"/>
 			<span class="blink badge badge-light" id="sysmsgnum"></span>
 			<span class="blink badge badge-light" id="sysmsgnum"></span>
 		</a>
 		</a>
 		<div aria-labelledby="dropdownMenuButton" class="dropdown-menu" id="notification_area"></div>
 		<div aria-labelledby="dropdownMenuButton" class="dropdown-menu" id="notification_area"></div>

+ 1 - 1
ui/login.tpl

@@ -1,5 +1,5 @@
 <div class="text-center mx-auto col-md-3 mt-3">
 <div class="text-center mx-auto col-md-3 mt-3">
-	<img alt="" class="img-fluid om-shadow" src="{{@BASEURL}}/ui/images/logo.png">
+	<img alt="" class="img-fluid om-shadow" src="{{@BASEURL}}/assets/images/logo.png">
 	<form action="loginform" enctype="multipart/form-data" method="POST">
 	<form action="loginform" enctype="multipart/form-data" method="POST">
 		<h1 class="mb-4" style="font-size: 4vw">Login</h1>
 		<h1 class="mb-4" style="font-size: 4vw">Login</h1>
 		<check if="{{ isset(@INFOTEXT) }}">
 		<check if="{{ isset(@INFOTEXT) }}">

+ 1 - 1
ui/masterpage_template.tpl

@@ -4,7 +4,7 @@
   <meta charset="UTF-8">
   <meta charset="UTF-8">
   <meta content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no" name="viewport">
   <meta content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no" name="viewport">
   <title>{{@SITENAME}}</title>
   <title>{{@SITENAME}}</title>
-  <link href="{{@BASEURL}}/ui/images/favicon_{{@CUSTOMERNAME}}.ico?v={{@VERSION}}" rel="shortcut icon" type="image/x-icon">
+  <link href="{{@BASEURL}}/assets/images/favicon.ico?v={{@VERSION}}" rel="shortcut icon" type="image/x-icon">
 
 
   <script type="text/javascript">
   <script type="text/javascript">
     const BASEURL = '{{@BASEURL}}';
     const BASEURL = '{{@BASEURL}}';

+ 17 - 6
webpack.config.js

@@ -9,16 +9,23 @@ const webpack = require("webpack");
 module.exports = {
 module.exports = {
 	plugins: [
 	plugins: [
 		new CleanWebpackPlugin(),
 		new CleanWebpackPlugin(),
+		new HtmlPlugin(
+			{
+				template: "./ui/errors_template.tpl",
+				filename: path.resolve(__dirname, './ui/errors.tpl'),
+			}
+		),
 		new HtmlPlugin(
 		new HtmlPlugin(
 			{
 			{
 				template: "./ui/masterpage_template.tpl",
 				template: "./ui/masterpage_template.tpl",
-				filename: "../masterpage.tpl",
+				filename: path.resolve(__dirname, './ui/masterpage.tpl'),
 			}
 			}
 		),
 		),
 		new MiniCssExtractPlugin({filename: "styles.[contenthash].css"}),
 		new MiniCssExtractPlugin({filename: "styles.[contenthash].css"}),
 		new webpack.ProvidePlugin({
 		new webpack.ProvidePlugin({
 			$: 'jquery',
 			$: 'jquery',
-			jQuery: 'jquery'
+			jQuery: 'jquery',
+			"window.jQuery": 'jquery'
 		})
 		})
 	],
 	],
 	module: {
 	module: {
@@ -29,10 +36,12 @@ module.exports = {
 				// ...use this loaders
 				// ...use this loaders
 				use: [
 				use: [
 					MiniCssExtractPlugin.loader,
 					MiniCssExtractPlugin.loader,
-					{loader: "css-loader", options: {url: false,}},
+					"css-loader",
 					"sass-loader"
 					"sass-loader"
 				]
 				]
-			}
+			},
+			// Import various assets
+			{test: /\.(jpg|png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000'}
 		]
 		]
 	},
 	},
 	optimization: {
 	optimization: {
@@ -49,8 +58,10 @@ module.exports = {
 	},
 	},
 	entry: "./ui/js/index.js",
 	entry: "./ui/js/index.js",
 	output: {
 	output: {
-		publicPath: 'ui/dist/',
-		path: path.resolve(__dirname, "ui/dist/"),
+		publicPath: '/omlink/assets/frontend/',
+		path: path.resolve(__dirname, "assets/frontend/"),
+		//publicPath: '/omlink/src/openmind/admin/ui/assets/dist/',
+		//path: path.resolve(__dirname, "ui/assets/dist/"),
 		filename: "bundle.[contenthash].js"
 		filename: "bundle.[contenthash].js"
 	},
 	},
 };
 };