summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo
diff options
context:
space:
mode:
authorSimon Rettberg2017-04-13 18:08:31 +0200
committerSimon Rettberg2017-04-13 18:08:31 +0200
commitfaf18b816b6fecce5ab5023a2d87fe1f2d44f132 (patch)
tree7f48d583c9efe5b4d7e528654e69f1123e88dd70 /modules-available/locationinfo
parent[locations] Return recursive list of children in getLocationsAssoc() (diff)
downloadslx-admin-faf18b816b6fecce5ab5023a2d87fe1f2d44f132.tar.gz
slx-admin-faf18b816b6fecce5ab5023a2d87fe1f2d44f132.tar.xz
slx-admin-faf18b816b6fecce5ab5023a2d87fe1f2d44f132.zip
[locationinfo] Refactor the main view
- Simplify javascript - Remove client count and locationid column from view, not useful for the average user - Remove/simplify queries, use Location helper more to deal with locations
Diffstat (limited to 'modules-available/locationinfo')
-rw-r--r--modules-available/locationinfo/inc/locationinfo.inc.php2
-rw-r--r--modules-available/locationinfo/page.inc.php217
-rw-r--r--modules-available/locationinfo/templates/config.html14
-rw-r--r--modules-available/locationinfo/templates/location-info.html117
-rw-r--r--modules-available/locationinfo/templates/server-settings.html4
5 files changed, 144 insertions, 210 deletions
diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php
index f924e469..9bd5ff5b 100644
--- a/modules-available/locationinfo/inc/locationinfo.inc.php
+++ b/modules-available/locationinfo/inc/locationinfo.inc.php
@@ -6,7 +6,7 @@ class LocationInfo
/**
* Gets the pc data and returns it's state.
*
- * @param $pc The pc data from the db. Array('logintime' =>, 'lastseen' =>, 'lastboot' =>)
+ * @param array $pc The pc data from the db. Array('logintime' =>, 'lastseen' =>, 'lastboot' =>)
* @return int pc state
*/
public static function getPcState($pc)
diff --git a/modules-available/locationinfo/page.inc.php b/modules-available/locationinfo/page.inc.php
index 88a762a8..8714bd34 100644
--- a/modules-available/locationinfo/page.inc.php
+++ b/modules-available/locationinfo/page.inc.php
@@ -53,13 +53,6 @@ class Page_LocationInfo extends Page
Util::redirect('?do=locationinfo&action=infoscreen');
}
- if ($getAction === 'hide') {
- $roomId = Request::get('id', 0, 'int');
- $hiddenValue = Request::get('value', 0, 'int');
- $this->toggleHidden($roomId, $hiddenValue);
- Util::redirect('?do=locationinfo&action=infoscreen#row' . $roomId);
- }
-
}
/**
@@ -341,79 +334,45 @@ class Page_LocationInfo extends Page
/**
* Sets the new hidden value and checks childs and parents.
*
- * @param $id The location id which was toggled
- * @param $val The hidden value true / false
+ * @param int $id The location id which was toggled
+ * @param bool $hidden The hidden value true / false
*/
- protected function toggleHidden($id, $val)
+ protected function toggleHidden($id, $hidden)
{
- Database::exec("INSERT INTO `location_info` (locationid, hidden) VALUES (:id, :hidden) ON DUPLICATE KEY UPDATE hidden=:hidden", array('id' => $id,
- 'hidden' => $val));
-
- $this->checkChildRecursive($id, $val);
- $this->checkParentRecursive($id);
-
- }
-
- /**
- * Recursivly sets all hidden values to all childs.
- *
- * @param $id The location id which childs should be checked
- * @param $val The hidden value
- */
- protected function checkChildRecursive($id, $val)
- {
- $dbquery = Database::simpleQuery("SELECT locationid FROM `location` WHERE parentlocationid = :locationid", array('locationid' => $id));
- $childs = array();
- while ($dbdata = $dbquery->fetch(PDO::FETCH_ASSOC)) {
- $childs[] = $dbdata['locationid'];
- }
-
- foreach ($childs as $key) {
- Database::exec("INSERT INTO `location_info` (locationid, hidden) VALUES (:id, :hidden) ON DUPLICATE KEY UPDATE hidden=:hidden", array('id' => $key,
- 'hidden' => $val));
-
- $this->checkChildRecursive($key, $val);
- }
- }
-
- /**
- * Recursively check all parent locations and updates the hidden values if necessary
- *
- * @param $id The id of the location which was toggled.
- */
- protected function checkParentRecursive($id)
- {
- $dbquery = Database::simpleQuery("SELECT parentlocationid FROM `location` WHERE locationid = :locationid", array('locationid' => $id));
- $parent = 0;
- while ($dbdata = $dbquery->fetch(PDO::FETCH_ASSOC)) {
- $parent = (int)$dbdata['parentlocationid'];
- }
- if ($parent === 0) {
- return;
- } else {
- $dbq = Database::simpleQuery("SELECT COUNT(CASE li.hidden WHEN '0' THEN 1 ELSE NULL END) AS '0',
- COUNT(CASE li.hidden WHEN '1' THEN 1 ELSE NULL END) AS '1',
- COUNT(*) - COUNT(CASE li.hidden WHEN '0' THEN 1 ELSE NULL END) - COUNT(CASE li.hidden WHEN '1' THEN 1 ELSE NULL END) AS 'NULL'
- FROM `location` AS l LEFT JOIN `location_info` AS li ON l.locationid=li.locationid
- WHERE parentlocationid = :parentId;", array('parentId' => $parent));
- $amountofzero = 0;
- $amountofnull = 0;
-
- while ($dbd = $dbq->fetch(PDO::FETCH_ASSOC)) {
- $amountofzero = (int)$dbd['0'];
- $amountofnull = (int)$dbd['NULL'];
- }
-
- if ($amountofzero == 0 AND $amountofnull == 0) {
- Database::exec("INSERT INTO `location_info` (locationid, hidden) VALUES (:id, :hidden) ON DUPLICATE KEY UPDATE hidden=:hidden", array('id' => $parent,
- 'hidden' => 1));
- } else {
- Database::exec("INSERT INTO `location_info` (locationid, hidden) VALUES (:id, :hidden) ON DUPLICATE KEY UPDATE hidden=:hidden", array('id' => $parent,
- 'hidden' => 0));
- }
-
- $this->checkParentRecursive($parent);
- }
+ $locs = Location::getLocationsAssoc();
+ if (!isset($locs[$id]))
+ die('Invalid location id');
+ $loc = $locs[$id];
+
+ // The JSON to return, telling the client which locationids to update in the view
+ $return = array();
+ $return[] = array('locationid' => $id, 'hidden' => $hidden);
+
+ // Update the location, plus all child locations
+ $qs = '(?,?)' . str_repeat(',(?,?)', count($loc['children']));
+ $params = array($id, $hidden);
+ foreach ($loc['children'] as $child) {
+ $params[] = $child;
+ $params[] = $hidden;
+ $return[] = array('locationid' => $child, 'hidden' => $hidden);
+ }
+ Database::exec("INSERT INTO location_info (locationid, hidden)
+ VALUES $qs ON DUPLICATE KEY UPDATE hidden = VALUES(hidden)", $params);
+
+ // Handle parents - uncheck if not all children are checked
+ while ($loc['parentlocationid'] != 0) {
+ $stats = Database::queryFirst('SELECT Count(*) AS total, Sum(li.hidden > 0) AS hidecount FROM location l
+ LEFT JOIN location_info li USING (locationid)
+ WHERE l.parentlocationid = :parent', array('parent' => $loc['parentlocationid']));
+ $hidden = ($stats['total'] == $stats['hidecount']) ? 1 : 0;
+ $params = array('locationid' => $loc['parentlocationid'], 'hidden' => $hidden);
+ Database::exec('INSERT INTO location_info (locationid, hidden)
+ VALUES (:locationid, :hidden) ON DUPLICATE KEY UPDATE hidden = VALUES(hidden)', $params);
+ $return[] = $params;
+ $loc = $locs[$loc['parentlocationid']];
+ }
+ error_log(print_r($return, true));
+ return $return;
}
/**
@@ -421,89 +380,47 @@ class Page_LocationInfo extends Page
*/
protected function getInfoScreenTable()
{
+ $locations = Location::getLocations(0, 0, false, true);
- // Get a table with the needed location info. name, id, hidden, pcState (Count of pcs that are in use), total pcs
- $dbquery = Database::simpleQuery("SELECT l.locationname, l.locationid, li.hidden, m.pcState, m.total FROM `location_info` AS li
- RIGHT JOIN `location` AS l ON li.locationid=l.locationid LEFT JOIN
- (SELECT locationid, Count(CASE m.logintime WHEN NOT 1 THEN NULL ELSE 1 END) AS pcState, Count(*) AS total FROM `machine` AS m
- WHERE locationid IS NOT NULL GROUP BY locationid) AS m ON l.locationid=m.locationid");
- $pcs = array();
-
- if (Module::isAvailable('locations')) {
- foreach (Location::getLocations() as $loc) {
- $data = array();
- $data['locationid'] = (int)$loc['locationid'];
- $data['locationname'] = $loc['locationname'];
- $data['depth'] = $loc['depth'];
- $data['hidden'] = null;
- $locid = (int)$loc['locationid'];
- $pcs[$locid] = $data;
- }
- }
-
- while ($roominfo = $dbquery->fetch(PDO::FETCH_ASSOC)) {
- $locid = (int)$roominfo['locationid'];
+ // Get hidden state of all locations
+ $dbquery = Database::simpleQuery("SELECT li.locationid, li.hidden FROM `location_info` AS li");
- if ($roominfo['hidden'] == null) {
- $pcs[$locid]['hidden'] = 0;
- } else {
- $pcs[$locid]['hidden'] = $roominfo['hidden'];
- }
-
- if ($roominfo['pcState'] != null) {
- $pcs[$locid]['pcState'] = $roominfo['pcState'];
- }
- if ($roominfo['total'] != null) {
- $pcs[$locid]['total'] = $roominfo['total'];
- $pcs[$locid]['hasPcs'] = true;
- } else {
- $pcs[$locid]['hasPcs'] = false;
- }
+ while ($row = $dbquery->fetch(PDO::FETCH_ASSOC)) {
+ $locid = (int)$row['locationid'];
+ $locations[$locid]['hidden_checked'] = $row['hidden'] != 0 ? 'checked' : '';
}
// Get a list of all the backend types.
$servertypes = array();
$s_list = CourseBackend::getList();
foreach ($s_list as $s) {
- $t['type'] = $s;
$typeInstance = CourseBackend::getInstance($s);
- $t['display'] = $typeInstance->getDisplayName();
- $servertypes[] = $t;
+ $servertypes[$s] = $typeInstance->getDisplayName();
}
- // Get the Serverlist from the DB and make it mustache accesable
+ // Get the Serverlist from the DB and make it mustache accessable
$serverlist = array();
$dbquery2 = Database::simpleQuery("SELECT * FROM `setting_location_info`");
- while ($db = $dbquery2->fetch(PDO::FETCH_ASSOC)) {
- $server['id'] = $db['serverid'];
- $server['name'] = $db['servername'];
- $server['type'] = $db['servertype'];
- foreach ($servertypes as $type) {
- if ($server['type'] == $type['type']) {
- $server['display'] = $type['display'];
- break;
+ while ($row = $dbquery2->fetch(PDO::FETCH_ASSOC)) {
+ $row['typename'] = $servertypes[$row['servertype']];
+
+ if (!empty($row['error'])) {
+ $row['autherror'] = true;
+ $error = json_decode($row['error'], true);
+ if (isset($error['timestamp'])) {
+ $time = date('Y/m/d H:i:s', $error['timestamp']);
+ } else {
+ $time = '???';
}
+ Message::addError('auth-failed', $row['servername'], $time, $error['error']);
}
-
- if ($db['error'] == null) {
- $server['auth'] = true;
- } else {
- $server['auth'] = false;
- $error = json_decode($db['error'], true);
-
- $time = date('Y/m/d H:i:s', $error['timestamp']);
-
- Message::addError('auth-failed', $server['name'], $time, $error['error']);
- }
-
- $server['url'] = $db['serverurl'];
- $serverlist[] = $server;
+ $serverlist[] = $row;
}
// Pass the data to the html and render it.
Render::addTemplate('location-info', array(
- 'list' => array_values($pcs),
- 'serverlist' => array_values($serverlist),
+ 'list' => array_values($locations),
+ 'serverlist' => $serverlist,
));
}
@@ -526,10 +443,26 @@ class Page_LocationInfo extends Page
} elseif ($action === 'serverSettings') {
$id = Request::any('id', 0, 'int');
$this->ajaxServerSettings($id);
+ } elseif ($action === 'hide') {
+ $this->ajaxHideLocation();
}
}
/**
+ * Request to deny displaying the door sign for the
+ * given location. Sends a list of all affected
+ * locations, so the client can update its view.
+ */
+ private function ajaxHideLocation()
+ {
+ $locationId = Request::post('locationid', 0, 'int');
+ $hidden = Request::post('hidden', 0, 'int');
+ Header('Content-Type: application/json; charset=utf-8');
+ $ret = $this->toggleHidden($locationId, $hidden);
+ echo json_encode(array('changed' => $ret));
+ }
+
+ /**
* Ajax the server settings.
*
* @param $id Serverid
diff --git a/modules-available/locationinfo/templates/config.html b/modules-available/locationinfo/templates/config.html
index 0c970f2a..e97b72fc 100644
--- a/modules-available/locationinfo/templates/config.html
+++ b/modules-available/locationinfo/templates/config.html
@@ -18,7 +18,7 @@
<select class="form-control" name="serverid">
<option value="0">{{lang_noServer}}</option>
{{#serverlist}}
- <option value="{{sid}}" {{selected}}>{{servername}}</option>
+ <option value="{{serverid}}" {{selected}}>{{servername}}</option>
{{/serverlist}}
</select>
</div>
@@ -319,17 +319,21 @@
</form>
<script type="text/javascript"><!--
-
- var customURL = window.location.protocol + "//" + window.location.hostname + "/slx-admin/modules/locationinfo/frontend/doorsign.html?id={{id}}";
- $('#custom-url').val(customURL);
+ // Get list of form elements which affect the generated custom URL
var $inputs = $('.modify-inputs input, .modify-inputs select');
+ // Base for displaying the custom URL
+ var customURL = window.location.protocol + "//" + window.location.hostname + "/slx-admin/modules/locationinfo/frontend/doorsign.html?id={{id}}";
+ // Initialize fancy tooltips
$('a.helptext').tooltip();
+ // Add listener to range sliders so their label can be updated
$('input[type="range"]').change(function () {
$(this).siblings().find('.range-display').text($(this).val());
});
+ // Set state of input controls that aren't statically initialized server side
loadValues();
+ // Update the custom URL
buildCustomUrl();
-
+ // Add listener to all the elements affecting custom URL
$inputs.change(function () {
$this = $(this);
if ($this.attr('type') === 'hidden')
diff --git a/modules-available/locationinfo/templates/location-info.html b/modules-available/locationinfo/templates/location-info.html
index 5b5e3e24..c27b4b12 100644
--- a/modules-available/locationinfo/templates/location-info.html
+++ b/modules-available/locationinfo/templates/location-info.html
@@ -14,33 +14,32 @@
<th width="1"></th>
</tr>
{{#serverlist}}
- <form method="post" action="?do=locationinfo" id="serverForm-{{id}}">
+ <form method="post" action="?do=locationinfo" id="serverForm-{{serverid}}">
<input type="hidden" name="token" value="{{token}}">
- <input id="serverFormAction-{{id}}" type="hidden" name="action" value="updateServer">
- <input type="submit" id="submit-serverForm-{{id}}" style="display:none;">
+ <input id="serverFormAction-{{serverid}}" type="hidden" name="action" value="updateServer">
+ <input type="submit" id="submit-serverForm-{{serverid}}" style="display:none;">
<tr>
- <input id="input-id-{{id}}" name="id" type="hidden" value="{{id}}">
- <td id="type-{{id}}" nowrap>{{display}}</td>
- <td id="name-{{id}}" nowrap>{{name}}</td>
- <td id="url-{{id}}" nowrap>{{url}}</td>
-
- <td align="center" id="credentials-{{id}}" onclick="event.cancelBubble = true;"
- style="white-space:nowrap;">
- <button class="btn btn-sm {{#auth}}btn-success{{/auth}}{{^auth}}btn-danger{{/auth}}"
- id="credentials-btn-{{id}}" type="button" onclick="loadSettingsModal({{id}},'{{name}}');">
+ <input id="input-id-{{serverid}}" name="id" type="hidden" value="{{serverid}}">
+ <td id="type-{{serverid}}" nowrap>{{typename}}</td>
+ <td id="name-{{serverid}}" nowrap>{{servername}}</td>
+ <td id="url-{{serverid}}" nowrap>{{serverurl}}</td>
+
+ <td align="center" id="credentials-{{serverid}}" style="white-space:nowrap;">
+ <button class="btn btn-sm {{^autherror}}btn-success{{/autherror}}{{#autherror}}btn-danger{{/autherror}}"
+ id="credentials-btn-{{serverid}}" type="button" onclick="loadSettingsModal({{serverid}},'{{servername}}');">
<span style="margin-right: 5px;" class="glyphicon glyphicon-cog"></span>
{{lang_locationSettings}}
</button>
- <button class="btn btn-sm btn-primary table-refresh" id="refresh-btn-{{id}}"
- title="{{lang_refresh_title}}" onclick="refreshButtonClick({{id}});">
- <span id="refresh-btn-animate-{{id}}" style="margin-right: 5px;"
+ <button class="btn btn-sm btn-primary table-refresh" id="refresh-btn-{{serverid}}"
+ title="{{lang_refresh_title}}" onclick="refreshButtonClick({{serverid}});">
+ <span id="refresh-btn-animate-{{serverid}}" style="margin-right: 5px;"
class="glyphicon glyphicon-refresh"></span>
{{lang_refresh}}
</button>
</td>
- <td align="center" id="btncell-{{id}}" style="white-space:nowrap;">
- <button class="btn btn-sm btn-danger table-delete" type="button" onclick="deleteButtonClick({{id}});">
+ <td align="center" id="btncell-{{serverid}}" style="white-space:nowrap;">
+ <button class="btn btn-sm btn-danger table-delete" type="button" onclick="deleteButtonClick({{serverid}});">
<span style="margin-right: 5px;" class="glyphicon glyphicon-remove"></span>
{{lang_delete}}
</button>
@@ -73,8 +72,6 @@
<tr>
<th>{{lang_locationName}}</th>
- <th width="10">{{lang_locationID}}</th>
- <th width="80">{{lang_locationInUse}}</th>
<th width="50" title="{{lang_locationIsHidden_title}}">{{lang_locationIsHidden}}</th>
<th width="50">{{lang_openingTime}}</th>
<th width="50">{{lang_locationSettings}}</th>
@@ -82,35 +79,20 @@
{{#list}}
<tr id="row{{locationid}}">
-
<td>
<div style="display:inline-block;width:{{depth}}em"></div>
- <a href="modules/locationinfo/frontend/doorsign.html?id={{locationid}}">{{locationname}}</a></td>
- <td align="center">[{{locationid}}]</td>
- <td align="center">{{#hasPcs}}{{pcState}} / {{total}}{{/hasPcs}}</td>
-
- <td id="{{locationid}}" onclick="event.cancelBubble = true;" align="center"></td>
- <script>
- var cbh = document.getElementById('{{locationid}}');
- var cb = document.createElement('input');
-
- cb.type = 'checkbox';
- cbh.appendChild(cb);
-
- cb.id = 'cb' + {{locationid}};
- cb.value = {{hidden}};
- if ({{hidden}} == 1) {
- cb.checked = true;
- }
- cb.addEventListener("click", function() { cbClick(this, {{locationid}}); });
- </script>
- <td onclick="event.cancelBubble = true;">
+ <a href="modules/locationinfo/frontend/doorsign.html?id={{locationid}}">{{locationname}}</a>
+ </td>
+ <td align="center">
+ <input class="hidden-toggle" type="checkbox" data-locationid="{{locationid}}" {{hidden_checked}}>
+ </td>
+ <td>
<a class="btn btn-sm btn-default" role="button" style="width: 100%"
onclick="loadTimeModal({{locationid}}, '{{locationname}}');">
<span style="margin-right: 5px;" class="glyphicon glyphicon-time"></span>
</a>
</td>
- <td onclick="event.cancelBubble = true;">
+ <td>
<a class="btn btn-sm btn-default" role="button" style="width: 100%;"
onclick="loadConfigModal({{locationid}}, '{{locationname}}');">
<span style="margin-right: 5px;" class="glyphicon glyphicon-cog"></span>
@@ -138,23 +120,43 @@
</div>
</div>
<script type="text/javascript"><!--
- var lastPcSubTable = false;
+
+ document.addEventListener("DOMContentLoaded", function () {
+
+ /**
+ * React to click on a "hidden" checkbox.
+ */
+ $('.hidden-toggle').change(function() {
+ $input = $(this);
+ $.ajax({
+ type: 'POST',
+ url: '?do=locationinfo&action=hide',
+ data: {locationid: $input.data('locationid'), hidden: $input[0].checked ? 1 : 0, token: TOKEN },
+ dataType: 'json'
+ }).done(function(data) {
+ if (data && $.isArray(data.changed)) {
+ markBoxes(data.changed);
+ } else {
+ $input.replaceWith('ERROR');
+ }
+ }).fail(function () {
+ $input.replaceWith('ERROR');
+ });
+ });
+
+ });
/**
- * Sets the checkbox value and calls the php hide action.
- *
- * @param cb The checkbox which was clicked.
- * @param locID the locationID of the checkbox.
+ * Gets a status array delivered by backend's ajaxHideLocation()
+ * and sets the checkbox states accordingly.
*/
- function cbClick(cb, locID) {
- var value;
-
- if (cb.checked) {
- value = 1;
- } else {
- value = 0;
+ function markBoxes(boxArray) {
+ for (var i = 0; i < boxArray.length; ++i) {
+ if (boxArray[i].locationid) {
+ var lid = parseInt(boxArray[i].locationid);
+ $('input.hidden-toggle[data-locationid="' + lid + '"]').prop('checked', !!boxArray[i].hidden);
+ }
}
- window.location.href = "?do=locationinfo&action=hide&id=" + locID + "&value=" + value;
}
/**
@@ -199,11 +201,6 @@
}
// ########### Server Table ###########
- var preEditName;
- var preEditUrl;
- var preEditUser;
- var preEditPassword;
- var preEditType;
/**
* Deletes a server.
@@ -224,7 +221,7 @@
* @param id The id of the server.
*/
function refreshButtonClick(id) {
- $('#refresh-btn-animate-' + id).addClass('glyphicon-refresh-animate');
+ $('#refresh-btn-animate-' + id).addClass('slx-rotation');
$('#serverFormAction-' + id).val("checkConnection");
$('#submit-serverForm-' + id).trigger("click");
}
diff --git a/modules-available/locationinfo/templates/server-settings.html b/modules-available/locationinfo/templates/server-settings.html
index a3e81272..c135543f 100644
--- a/modules-available/locationinfo/templates/server-settings.html
+++ b/modules-available/locationinfo/templates/server-settings.html
@@ -84,7 +84,7 @@
type = $('#input-type-{{id}}').val();
}
- loadCredentials();
+ loadCredentials(true);
initalizeBootstrap();
/**
@@ -101,7 +101,7 @@
*
* @param {bool} useValue If false the form elements will be empty. Default = true.
*/
- function loadCredentials(useValue = true) {
+ function loadCredentials(useValue) {
// {{name}} name of auth {{type}} type of auth (string, int etc.) {{value}} value from the db
{{#backendList}}
if (type == "{{typ}}") {