From 187eae16e186565d07f66dc47dcb73f1607e8a80 Mon Sep 17 00:00:00 2001 From: Axel Date: Sat, 18 Dec 2021 20:42:21 +0100 Subject: [PATCH] New version with VueJS --- .gitignore | 2 + web/DB.php | 80 +++++++++------ web/api.php | 64 ++++++++++++ web/css/styles.css | 75 +++++++++++++- web/img/unknown.png | Bin 0 -> 1205 bytes web/index.php | 231 +++++++++++++++++++------------------------- web/js/scripts.js | 25 ----- 7 files changed, 289 insertions(+), 188 deletions(-) create mode 100644 web/api.php create mode 100644 web/img/unknown.png diff --git a/.gitignore b/.gitignore index 1840dc6..ec04b3c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ web/vendor/**/* .env +web/sync.php +/**/node_modules diff --git a/web/DB.php b/web/DB.php index 137d69f..dd9b92a 100644 --- a/web/DB.php +++ b/web/DB.php @@ -9,24 +9,28 @@ $dotenv->required(['DB_TYPE', 'DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASSWORD']); class DB { private $link; - - + + public function __construct() { if (! is_resource($this->link)) { $dsn = $_ENV['DB_TYPE'].':dbname='.$_ENV['DB_NAME'].';host='.$_ENV['DB_HOST'].';port='.$_ENV['DB_PORT']; - $this->link = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASSWORD']); - $this->link->query('SET NAMES "UTF8"'); + $driver_options = array( + PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'", + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + ); + $this->link = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $driver_options); } } - + public function get_all_contacts($task = null) { $query = ' - SELECT c.id, c.surname, c.firstname, c.email, c.phone, c.creation_date, c.active - FROM contacts c + SELECT c.id, c.surname, c.firstname, c.email, c.phone, c.creation_date, c.active + FROM contacts c LEFT JOIN notifications as n ON (n.contact_id = c.id) LEFT JOIN tasks as t ON (n.task_id = t.id) '; - + if (! is_null($task)) { $query .= ' WHERE t.id = '.$task; } @@ -37,19 +41,24 @@ class DB { public function get_all_tasks($status = null) { if (is_null($status)) { $query = ' - SELECT id, host, type, params, creation_date, frequency, last_execution, active - FROM tasks + SELECT DISTINCT t.id, t.host, t.type, t.params, t.frequency, t.creation_date, t.last_execution, t.active, t.group_id, h.status, g.name as group_name + FROM `tasks` as t + LEFT JOIN `tasks_history` as h ON (h.task_id = t.id) + LEFT JOIN `groups` as g ON (g.id = t.group_id) + WHERE (t.last_execution IS NULL OR h.datetime = t.last_execution) + ORDER BY group_id DESC '; } else { $query = ' - SELECT DISTINCT t.id, t.host, t.type, t.params, t.creation_date, t.last_execution, t.active - FROM tasks as t + SELECT DISTINCT t.id, t.host, t.type, t.params, t.creation_date, t.last_execution, t.active, t.group_id + FROM tasks as t JOIN tasks_history as h ON (h.task_id = t.id) WHERE h.status = '.intval($status).' AND h.datetime = t.last_execution + ORDER BY group_id DESC '; } - + return $this->query($query); } @@ -57,21 +66,21 @@ class DB { $args = [ ':limit' => $limit ]; - + $query = ' - SELECT id, status, datetime, task_id + SELECT id, status, datetime, task_id FROM tasks_history '; - + if (! is_null($task)) { $query .= ' WHERE task_id = :task_id'; $args[':task_id'] = $task; } $query .= ' ORDER BY datetime DESC LIMIT :limit '; - + return $this->query($query, $args); } - + public function get_task_last_status($task) { $result = $this->query('SELECT t.id, th.status FROM tasks_history th JOIN tasks t ON (th.task_id = t.id) WHERE t.id = :task ORDER BY datetime DESC LIMIT 1', [':task' => $task]); foreach ($result as $r) { @@ -81,45 +90,58 @@ class DB { public function query($query, $args = null) { + $result = $this->prepare($query, $args); + if (! $result->execute()) { + throw new DatabaseException($result->errorInfo()[2]. ' in ('.$query.')'); + } + + return $result->fetchAll(); + } + + private function prepare($query, $args = null) { if (! $result = $this->link->prepare($query)) { throw new DatabaseException('Cannot prepare query ('.$query.') for execution'); } - + if (! is_null($args)) { foreach ($args as $n => $v) { $type = gettype($v); - + switch ($type) { - + case 'boolean': $cast = PDO::PARAM_BOOL; break; - + case 'integer': $cast = PDO::PARAM_INT; break; - + case 'null': $cast = PDO::PARAM_NULL; break; - + case 'double': case 'string': default: $cast = PDO::PARAM_STR; - + } $result->bindValue($n, $v, $cast); } } - - + return $result; + } + + public function insert($query, $args = null) { + $result = $this->prepare($query, $args); + if (! $result->execute()) { throw new DatabaseException($result->errorInfo()[2]. ' in ('.$query.')'); } - - return $result->fetchAll(); + + return $this->link->lastInsertId(); } } diff --git a/web/api.php b/web/api.php new file mode 100644 index 0000000..6909e0c --- /dev/null +++ b/web/api.php @@ -0,0 +1,64 @@ +db = $db; + } + + public function get_tasks() { + $tasks = []; + $ret = $this->db->get_all_tasks(); + foreach ($ret as $t) { + if (is_null($t['group_id'])) { + $group_id = $t['id']; + $group_name = 'ungrouped'; + } + else { + $group_id = $t['group_id']; + $group_name = $t['group_name']; + } + + + if (isset($tasks[$group_id])) { + array_push($tasks[$group_id]['tasks'], $t); + } + else { + $tasks[$group_id] = [ + 'id' => $group_id, + 'name' => $group_name, + 'tasks' => [ $t ] + ]; + } + } + return $tasks; + } + +} + + + +if (isset($_GET['a'])) { + $action = trim(htmlentities($_GET['a']), '_'); + $api = new Api($db); + + if (method_exists($api, $action)) { + try { + echo json_encode(call_user_func([$api, $action])); + } + catch (Exception $e) { + echo json_encode([ + 'result' => false + ]); + } + + exit; + } +} + +header("HTTP/1.1 404 Not Found"); + diff --git a/web/css/styles.css b/web/css/styles.css index 1af524c..8455596 100644 --- a/web/css/styles.css +++ b/web/css/styles.css @@ -16,9 +16,18 @@ body { color: #3D3D3D; } +a, a:visited { + color: inherit; + text-decoration: inherit; +} + +a:hover { + text-decoration: underline; +} + h1, h2, h3, h4 { - margin-top: 2rem; - margin-bottom: 1rem; + margin-top: .8rem; + margin-bottom: .8rem; } h1 { @@ -28,7 +37,7 @@ h1 { } h2 { - font-size: 1.8rem; + font-size: 1.4rem; margin-top: 0; padding-top: 0; } @@ -63,13 +72,54 @@ td { border: 1px solid #9ccece; text-align: center; vertical-align: middle; - + } #tasks_tbl, #contacts_tbl { width: 100%; } +.quick-view { + margin: 3rem auto; + max-width: 1000px; + padding: 1rem; + -webkit-box-shadow: 5px 5px 15px 0px rgba(0,0,0,0.3); + -moz-box-shadow: 5px 5px 15px 0px rgba(0,0,0,0.3); + box-shadow: 5px 5px 15px 0px rgba(0,0,0,0.3); + border-radius: 5px; + position: relative; +} + + +.new-group { + margin: .2rem; + display: inline-block; + border: 1px solid rgba(7, 7, 7, 0.432); + padding: 1px; + +} + +.quick-view .square { + width: 2rem; + min-width: 2rem; + max-width: 2rem; + height: 2rem; + min-height: 2rem; + max-height: 2rem; + margin: 0.1rem; + text-align: center; + vertical-align: middle; + float: left; +} + +.spacer { + clear:both; + line-height: 0; + padding: 0; + margin:0; +} + + .task { margin: 3rem auto; max-width: 1000px; @@ -124,6 +174,23 @@ td { background-image: url('../img/collapse.png'); } +.up { + background-color: #c9ecc9; +} + +.down { + background-color: #ffc5c5; +} + +.unknown { + background-color: rgb(243, 192, 97); +} + + +.square.unknown img, .square.down img, .square.up img { + opacity: .5; +} + @keyframes shake { 10%, 90% { transform: translate3d(-1px, 0, 0); diff --git a/web/img/unknown.png b/web/img/unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..10b42f89b36defb58c62774b9de274722c65eec2 GIT binary patch literal 1205 zcmV;m1WNmfP)*5NBFCzN05*dtA)brig1zW=V@$WC$(PL`Dn#ruHYGe6#5zmNHZMoQAqJ?O1lWiqlF~?};C;~1et~39VI3d&zD?D8Bp6_9bi2`To6oBKN z$E)hFNbhXmsyiZh#uilpbUU_#A@~boRnP=P>}q+&kjL(H1LIQssu{FX#D>SZ1|Rn| za~UL-`wfVDMt6|&mRJ~6aSB^Rywl97P568s9MlX1HfqUDZJQYK+UFGn6Pr((L2h}( zm`0o;9uPlV@b^h#s>iX-nz{86vs3}jX$Amm75=k{H;Q9>i8YGj*D>T*CUcI5jqYow zN0Iyz;cw=Mv$R;@M|Z%4*K*4Bgc421pjwgm^)&okQ~2Q+n;cK&_$h{10eo$f_}a>p>xgGn4U^NGL~ROM0{Ge^DZmD%Tt^I% zIWB*0R!a)NF+>MX;tsL)uCsJ)f)0sz*lDI1c+Sj)!=eZXP6Xq2+1ZEPV~kY*hvg9v zohW|2Li|#}d$pFrX=4P0`we=;k*WI@A+XQH$@_Tv*lczfl#^SpzkH( zVfB`CafZT$mV-W46rj^`F6eczJ{|5-6u{>5=>K#WW^+L#Dg}6y7?^8G%n#TXD3+kw zGvMZYVgYh22965ZBFUn-E@+BT%i=JOjgd?t<;DoMi)?m#hJ|!%3|0|=1Wi*a6Awf0 zZJ4dErujh3R22Yrz;F^_jss-7O(P6#B<*9c0Ied8mN|514UVA#ptsp~lT_SH?HGko zfP!?z$E|t{6reJwco^=Px(qG=`jE9d$I;@-*({BP$W%Q9wL-r`Es-X{*fBnyxWt&8 zY3ez}#|^hbRRqMTz`{ MonitoLite - Network monitoring tool - + + -

MonitoLite Dashboard

- - get_all_tasks()): ?> - - -
-

 

- -

Task # ยป for host

+
+

MonitoLite Dashboard

- - - - - - - - - - - - - get_task_last_status($task['id']); - $color = $status == 1 ? '#c9ecc9' : '#ffc5c5'; - $icon = $status == 1 ? 'up.png': 'down.png'; - ?> - - - - - - - - - - -
Up?HostTypeParametersLast executionFrequency (min)Active -
Status - - Warning - - Warning - -
- - +
+

Quick overview

+ - - - - -

No task found here

- +

 

+
+ +
+

Tasks for group {{ group.name }} (#{{ group.id }})

+ + + + + + + + + + + + + + + + + + + + +
Up?HostTypeLast executionFrequency (min)Active +
+ Status + + + {{ task.host }} + + Type of check + {{ task.last_execution ?? 'never' }}{{ task.frequency }}{{ task.active == 1 ? 'Yes' : 'No' }}
+
+ + diff --git a/web/js/scripts.js b/web/js/scripts.js index f06dc8c..e69de29 100644 --- a/web/js/scripts.js +++ b/web/js/scripts.js @@ -1,25 +0,0 @@ -$(document).ready(function() { - $('.task .exp-icon').on('click', function() { - var el = $(this).parent('.task'); - - if (el.hasClass('active')) { - el.removeClass('active'); - el.children('.hidden').slideUp(); - } - else { - $('.task').removeClass('active'); - $('.task').children('.hidden').slideUp(); - el.addClass('active'); - el.children('.hidden').slideDown(); - } - }); - - $('.task').not('.active').on('mouseover', function() { - $(this).children('.task-overlay').show(); - }); - - $('.task').not('.active').on('mouseout', function() { - $(this).children('.task-overlay').hide(); - }); - -})