Browse Source

ADD: admin module

Giancarlo Voci 7 years ago
parent
commit
633f2d40f9

+ 5 - 4
.gitignore

@@ -1,5 +1,6 @@
 # OS generated files #
 ######################
+package-lock.json
 .DS_Store
 .DS_Store?
 ._*
@@ -53,8 +54,8 @@ import
 # Custom for current project
 /bundle.js
 /bundle.css
-*.min.js
-*.min.css
 /cfg/*.bin
-/ui/css/omlink.css
-/ui/js/omlink.min.js
+omlink.css
+omlink.min.js
+admin.css
+admin.min.js

+ 15 - 15
package-lock.json

@@ -570,7 +570,7 @@
     },
     "camelcase-keys": {
       "version": "2.1.0",
-      "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
       "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
       "requires": {
         "camelcase": "^2.0.0",
@@ -765,7 +765,7 @@
     },
     "colors": {
       "version": "1.1.2",
-      "resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
       "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM="
     },
     "combined-stream": {
@@ -1529,7 +1529,7 @@
     },
     "jsesc": {
       "version": "1.3.0",
-      "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
       "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
     },
     "json-schema": {
@@ -1593,7 +1593,7 @@
       "dependencies": {
         "pify": {
           "version": "2.3.0",
-          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
         }
       }
@@ -1700,7 +1700,7 @@
     },
     "meow": {
       "version": "3.7.0",
-      "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
       "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
       "requires": {
         "camelcase-keys": "^2.0.0",
@@ -2009,7 +2009,7 @@
     },
     "os-homedir": {
       "version": "1.0.2",
-      "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
       "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
     },
     "os-locale": {
@@ -2022,7 +2022,7 @@
     },
     "os-tmpdir": {
       "version": "1.0.2",
-      "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
       "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
     },
     "osenv": {
@@ -2076,7 +2076,7 @@
     },
     "path-is-absolute": {
       "version": "1.0.1",
-      "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
     },
     "path-is-inside": {
@@ -2101,7 +2101,7 @@
       "dependencies": {
         "pify": {
           "version": "2.3.0",
-          "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
           "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
         }
       }
@@ -2130,9 +2130,9 @@
       }
     },
     "popper.js": {
-      "version": "1.14.5",
-      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.5.tgz",
-      "integrity": "sha512-fs4Sd8bZLgEzrk8aS7Em1qh+wcawtE87kRUJQhK6+LndyV1HerX7+LURzAylVaTyWIn5NTB/lyjnWqw/AZ6Yrw=="
+      "version": "1.14.6",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.6.tgz",
+      "integrity": "sha512-AGwHGQBKumlk/MDfrSOf0JHhJCImdDMcGNoqKmKkU+68GFazv3CQ6q9r7Ja1sKDZmYWTckY/uLyEznheTDycnA=="
     },
     "prepend-http": {
       "version": "1.0.4",
@@ -2370,7 +2370,7 @@
       "dependencies": {
         "source-map": {
           "version": "0.4.4",
-          "resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
           "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
           "requires": {
             "amdefine": ">=0.0.4"
@@ -2549,7 +2549,7 @@
     },
     "strip-eof": {
       "version": "1.0.0",
-      "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
       "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
     },
     "strip-indent": {
@@ -2605,7 +2605,7 @@
     },
     "tar": {
       "version": "2.2.1",
-      "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
       "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
       "requires": {
         "block-stream": "*",

+ 1 - 1
package.json

@@ -13,6 +13,6 @@
     "jquery": "^3.3.1",
     "node-minify": "^3.6.0",
     "node-sass": "^4.10.0",
-    "popper.js": "^1.14.5"
+    "popper.js": "^1.14.6"
   }
 }

+ 0 - 3
src/Modules/Blank/Blank.php

@@ -8,10 +8,7 @@
 
 namespace Modules\Blank;
 
-use DB\SQL;
-use DB\SQL\Mapper;
 use OpenMind\System\PluginStrategy;
-use OpenMind\System\User;
 use OpenMind\System\UserRoles;
 
 class Blank extends PluginStrategy

+ 21 - 0
src/OpenMind/Admin/Admin.php

@@ -0,0 +1,21 @@
+<?
+/**
+ * @author Open Mind
+ * @date 04/12/2018
+ * @time 15:17
+ */
+
+namespace OpenMind\Admin;
+
+use OpenMind\System\PluginStrategy;
+
+class Admin extends PluginStrategy
+{
+  public function __construct()
+  {
+    $this->AddRoute('GET /admin', __NAMESPACE__ . '\Pages->Admin');
+  }
+}
+
+/** @var \OpenMind\Admin $Admin */
+Global $Admin;

+ 26 - 0
src/OpenMind/Admin/Pages.php

@@ -0,0 +1,26 @@
+<?php
+/**
+ * @author Open Mind
+ * @date 04/12/2018
+ * @time 15:22
+ */
+
+namespace OpenMind\Admin;
+
+use OpenMind\Web\Controller;
+
+class Pages extends Controller
+{
+  public function __construct($f3)
+  {
+    parent::__construct($f3);
+
+    // Set Admin F3 UI folder
+    $f3->set('UI', 'src/OpenMind/Admin/ui/');
+  }
+
+  public function Admin($f3)
+  {
+    echo \Template::instance()->render('masterpage.tpl');
+  }
+}

+ 49 - 0
src/OpenMind/Admin/build.js

@@ -0,0 +1,49 @@
+const compressor = require('../../../node_modules/node-minify');
+const sass = require('../../../node_modules/node-sass');
+const {writeFileSync} = require('fs');
+
+// The Libraries to join in minified files
+const libList = [
+  "../../../node_modules/jquery/dist/jquery.min.js",
+  "../../../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
+];
+
+// The css files to minify
+const cssList = [
+  "../../../node_modules/bootstrap/dist/css/bootstrap.min.css",
+  "ui/css/admin.css"
+];
+
+// The javascript files to minify
+const jsList = [
+  "ui/js/admin.js"
+];
+
+/**
+ * MAIN
+ */
+
+let buffer = sass.renderSync({file: 'ui/css/admin.scss'});
+
+writeFileSync('ui/css/admin.css', buffer.css);
+
+compressor.minify({
+    compressor: 'clean-css',
+    input: cssList,
+    output: 'ui/bundle.css'
+  }
+);
+
+compressor.minify({
+    compressor: 'uglify-es',
+    input: jsList,
+    output: 'ui/js/admin.min.js'
+  }
+);
+
+compressor.minify({
+    compressor: 'no-compress',
+    input: [].concat(libList, ["ui/js/admin.min.js"]),
+    output: 'ui/bundle.js'
+  }
+);

+ 193 - 0
src/OpenMind/Admin/ui/css/admin.scss

@@ -0,0 +1,193 @@
+/**
+ * Main SCSS file
+ *
+ * @author Open Mind
+ * @date 04/12/2018
+ * @time 16:00
+ * @since 18/07/2018 in SCSS format
+ */
+
+// DEFAULTS
+// Background color
+$mainColor: #eeeeee;
+
+// Main text color
+$textColor: white;
+
+// Upper and Lower navbar background color
+$navbarsColor: rgba(94, 107, 116, 0.95);
+
+// drop-shadow and box-shadow color
+$shadowColor: #444444;
+
+// All input tag colors
+$inputBgColor: rgb(77, 80, 153);
+$inputColor: white;
+
+$placeholderColor: gray !important;
+
+.navbar.fixed-bottom {
+  color: white;
+}
+
+html, body {
+  height: 100%;
+}
+
+body {
+  background-color: $mainColor !important;
+  color: $textColor !important;
+  font-family: 'Roboto';
+}
+
+/* latin */
+@font-face {
+  font-family: 'Roboto';
+  font-style: normal;
+  font-weight: 400;
+  src: local('Roboto'), local('Roboto-Regular'), url('ui/fonts/Roboto-Regular.ttf') format('truetype');
+  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+}
+
+.error_body:before {
+  content: "";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  height: 100%;
+  background: url('ui/images/error_bg.png');
+  background-size: cover;
+}
+
+.error_body .card {
+  opacity: 0.9;
+}
+
+/*
+input[type="text"], input[type="password"] {
+  border-color: #C5AC0F !important;
+  background-color: #484848 !important;
+}
+
+input[type="text"]:focus, input[type="password"]:focus {
+  border-color: #C5AC0F !important;
+  color: #ffd242 !important;
+}
+*/
+
+/*input {
+  border-color: darken($inputBgColor, 10%);
+  color: darken($inputColor, 10%);
+}
+
+input:focus {
+  background-color: $inputBgColor !important;
+  border-color: $inputColor !important;
+}*/
+
+.form-control, .btn {
+  background-color: $inputBgColor !important;
+  color: $inputColor !important;
+}
+
+.form-control:focus, .btn:focus {
+  //  border-color: #c5ac0f !important;
+  background-color: lighten($inputBgColor, 8%) !important;
+  border-color: darken($inputBgColor, 10%) !important;
+  box-shadow: 0 0 10px $inputBgColor !important;
+}
+
+.form-control:disabled {
+  color: darken($inputColor, 10%) !important;
+  background-color: darken($inputBgColor, 8%) !important;
+}
+
+.debugborder {
+  border: 1px solid red !important;
+}
+
+.disablebutton {
+  opacity: 0.4;
+}
+
+.imgbuttonmenu {
+  max-height: 180px !important;
+  border-radius: 10px !important;
+}
+
+.om-shadow {
+  filter: drop-shadow(0px 0.2em 5px $shadowColor);
+}
+
+input::placeholder {
+  color: $placeholderColor;
+}
+
+input::-ms-input-placeholder {
+  color: $placeholderColor;
+}
+
+.navbar {
+  background-color: $navbarsColor !important;
+}
+
+.rounded {
+  border-radius: 15px !important;
+}
+
+@mixin prefix($property, $parameters...) {
+  @each $prefix in -webkit-, -moz-, -ms-, -o-, "" {
+    #{$prefix}#{$property}: $parameters;
+  }
+}
+
+// Blink Effect
+@keyframes blink {
+  0% {
+    @include prefix(opacity, 0.1);
+    // background-color: lighten(#28a745, 40%);
+  }
+  100% {
+    @include prefix(opacity, 1);
+    // background-color: darken(#28a745, 10%);
+  }
+}
+
+@-webkit-keyframes blink {
+  0% {
+    @include prefix(opacity, 0.1);
+    // background-color: lighten(#28a745, 40%);
+  }
+  100% {
+    @include prefix(opacity, 1);
+    // background-color: darken(#28a745, 10%);
+  }
+}
+
+.blink {
+  @include prefix(transition, all 0.1s ease-in-out);
+  @include prefix(animation, blink alternate 1s infinite ease-in-out);
+}
+
+#sysmsgnum {
+  color: white;
+  background-color: red;
+  font-size: 40%;
+  position: absolute;
+  left: 15px;
+  bottom: 0;
+}
+
+#notification_area {
+  padding-bottom: 0;
+  border-radius: 10px 10px
+}
+
+#notification_area_deleteall {
+  background-color: #3380BD;
+  color: white;
+  border-radius: 0 0 10px 10px;
+  padding: 0;
+}
+

+ 12 - 0
src/OpenMind/Admin/ui/footer.tpl

@@ -0,0 +1,12 @@
+<nav class="navbar fixed-bottom navbar-expand navbar-dark">
+	<check if="{{ isset(@PREVPAGE) }}">
+		<a href="{{@PREVPAGE}}"><img class="navbar-brand" src="{{@BASEURL}}/ui/images/arrow-left.svg" height="50px"/></a>
+	</check>
+	<div class="nav-item">Utente: {{@COOKIE.username}}</div>
+	<div class="collapse navbar-collapse"></div>
+	<div class="navbar-brand">
+		<a href="{{@BASEURL}}">
+			<img src="{{@BASEURL}}/ui/images/om-link-logo.png" height="40"/>
+		</a>
+	</div>
+</nav>

+ 29 - 0
src/OpenMind/Admin/ui/header.tpl

@@ -0,0 +1,29 @@
+<nav class="navbar navbar-expand-sm navbar-dark bg-dark om-shadow">
+	<a href="{{@BASEURL}}/"><img class="img-fluid om-shadow navbar-brand customerlogo" src="{{@LOGO_CUSTOMER}}"/></a>
+	<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#headerMenu" aria-controls="headerMenu" aria-expanded="false" aria-label="Toggle navigation">
+		<span class="navbar-toggler-icon"></span>
+	</button>
+
+	<div class="collapse navbar-collapse" id="headerMenu">
+		<ul class="navbar-nav">
+			<repeat group="{{@GLOBALMENU}}" key="{{ @ikey }}" value="{{@menuitem}}">
+				<check if="{{ !empty(@menuitem.url) }}">
+					<li class="nav-item">
+						<a role="button" class="nav-link btn btn-secondary" href="{{@BASEURL . '/' . @menuitem.url}}">{{@ikey}}</a>
+					</li>
+				</check>
+			</repeat>
+		</ul>
+	</div>
+
+	<div class="ml-auto dropdown dropleft navbar-brand">
+		<a id="notification_area_button" class="disabled" href="javascript:void(0)" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="mr-3" style="position: relative">
+			<img src="{{@BASEURL}}/ui/images/bell.png"/>
+			<span id="sysmsgnum" class="blink badge badge-light"></span>
+		</a>
+		<div id="notification_area" class="dropdown-menu" aria-labelledby="dropdownMenuButton"></div>
+	</div>
+	<div>
+		<a href="{{@BASEURL}}/logout"><img src="{{@ICON_LOGOUT}}" class="img-fluid om-shadow"/></a>
+	</div>
+</nav>

+ 71 - 0
src/OpenMind/Admin/ui/js/admin.js

@@ -0,0 +1,71 @@
+/**
+ * Main Javascript file
+ *
+ * @author Open Mind
+ * @date 04/12/2018
+ * @time 16:00
+ */
+
+var fetchHeaders = {
+  'Accept': 'text/html',
+  'Content-Type': 'text/html',
+  'X-Requested-With': 'XMLHttpRequest',
+  'Cache-Control': 'no-cache',
+  'Pragma': 'no-cache',
+  'Expires': '0'
+};
+
+/* usefull if a blinking text is need, like in MaxMara project, you need to place this code in html:
+ *
+ * <nav class="navbar navbar-collapse p-0">
+ *   <span class="navbar-text blink" style="color: red" id="statusbartext"></span>
+ * </nav>
+ */
+function SetStatusBarText(msg) {
+  $('#statusbartext').text(msg);
+  setTimeout(() => {
+    $('#statusbartext').text('');
+  }, 60000);
+}
+
+/*
+function refreshNotificationArea() {
+  fetch(`${BASEURL}/api.system.getserverstatus`, {headers: fetchHeaders})
+    .then(resp => {
+      if (resp.status === 200)
+        return resp.json();
+      else
+        return Promise.reject("getserverstatus: error");
+    })
+    .then(data => {
+      NotificationBuilder(data.notify);
+    })
+    .catch(err => {
+      console.log(err);
+    });
+}
+*/
+
+function SetupConfirmationDialog() {
+  $('.requestconfirm').on('click', function (ev) {
+    let confirmText = $(this).data('confirmtext');
+    if (!confirm(confirmText))
+      ev.preventDefault();
+  });
+}
+
+function SetupSubmitFormDisabler() {
+  $('body').on('submit', 'form', function () {
+    $('form input,form select').prop('disabled', false);
+    setTimeout(function () {
+      $('form input,form select').prop('disabled', true);
+    }, 500);
+  });
+}
+
+$(function () {
+  SetupConfirmationDialog();
+
+  SetupSubmitFormDisabler();
+});
+

+ 37 - 0
src/OpenMind/Admin/ui/masterpage.tpl

@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="it">
+<head>
+	<meta charset="UTF-8">
+	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
+	<title>{{@SITENAME}}</title>
+	<link type="text/css" rel="stylesheet" href="{{@BASEURL}}/{{@UI}}bundle.css"/>
+	<link rel="shortcut icon" type="image/x-icon" href="{{@BASEURL}}/{{@UI}}favicon.ico">
+
+	<script type="text/javascript">
+    const BASEURL = '{{@BASEURL}}';
+	</script>
+</head>
+<body>
+
+<include href="header.tpl"/>
+
+<div class="d-flex flex-row justify-content-around align-items-center" style="overflow-y: auto; height: calc(100% - 150px)">
+	<include if="{{isset(@CONTENT)}}" href="{{@CONTENT}}"/>
+</div>
+
+<include href="footer.tpl"/>
+
+<script src="{{@BASEURL}}/{{@UI}}bundle.js"></script>
+
+<check if="{{isset(@REQ_REDIRECT}})">
+	<true>
+		<script>
+      setTimeout(() => {
+        window.location.href = "{{@BASEURL}}/{{@REQ_REDIRECT}}";
+      }, {{@REQ_REDIRECT_MS}});
+		</script>
+	</true>
+</check>
+
+</body>
+</html>

+ 2 - 0
ui/js/omlink.js

@@ -17,6 +17,7 @@ var fetchHeaders = {
   'Pragma': 'no-cache',
   'Expires': '0'
 };
+
 /* usefull if a blinking text is need, like in MaxMara project, you need to place this code in html:
  *
  * <nav class="navbar navbar-collapse p-0">
@@ -29,6 +30,7 @@ function SetStatusBarText(msg) {
     $('#statusbartext').text('');
   }, 60000);
 }
+
 function NotificationBuilder(notifications) {
   let tplNotify = '';
   let htmlNotificationArea = '';