summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo
diff options
context:
space:
mode:
authorSimon Rettberg2017-06-16 18:45:02 +0200
committerSimon Rettberg2017-06-16 18:45:02 +0200
commit29c705766604abcab61ea3c5eb5adeb942679507 (patch)
tree0713de2bed5844546ff79755363ad0a456cbcae8 /modules-available/locationinfo
parent[locationinfo] slxadmin part done, todo: frontend+api (diff)
downloadslx-admin-29c705766604abcab61ea3c5eb5adeb942679507.tar.gz
slx-admin-29c705766604abcab61ea3c5eb5adeb942679507.tar.xz
slx-admin-29c705766604abcab61ea3c5eb5adeb942679507.zip
[locationinfo] Frontend mostly working again...
Diffstat (limited to 'modules-available/locationinfo')
-rw-r--r--modules-available/locationinfo/api.inc.php319
-rwxr-xr-xmodules-available/locationinfo/frontend/doorsign.html1185
-rwxr-xr-xmodules-available/locationinfo/frontend/jquery-week-calendar/jquery.weekcalendar.js21
-rw-r--r--modules-available/locationinfo/inc/locationinfo.inc.php10
-rw-r--r--modules-available/locationinfo/page.inc.php18
5 files changed, 747 insertions, 806 deletions
diff --git a/modules-available/locationinfo/api.inc.php b/modules-available/locationinfo/api.inc.php
index 34c2a41a..760a9be7 100644
--- a/modules-available/locationinfo/api.inc.php
+++ b/modules-available/locationinfo/api.inc.php
@@ -8,134 +8,114 @@ HandleParameters();
function HandleParameters()
{
- $getAction = Request::get('action', 0, 'string');
+ $get = Request::get('get', 0, 'string');
+ $uuid = Request::get('uuid', false, 'string');
$output = false;
- if ($getAction == "locationinfo") {
- $locationIds = Request::get('id', 0, 'string');
- $array = filterIdList($locationIds);
- $getCoords = Request::get('coords', false, 'bool');
- $output = getLocationInfo($array, $getCoords);
- } elseif ($getAction == "openingtime") {
- $locationIds = Request::get('id', 0, 'string');
- $array = filterIdList($locationIds);
- $output = getOpeningTime($array);
- } elseif ($getAction == "config") {
- $locationId = Request::get('id', 0, 'int');
- $output = getConfig($locationId);
- } elseif ($getAction == "pcstates") {
- $locationIds = Request::get('id', 0, 'string');
- $array = filterIdList($locationIds);
- $output = getPcStates($array);
- } elseif ($getAction == "locationtree") {
- $locationIds = Request::get('id', 0, 'string');
- $array = filterIdList($locationIds);
- $output = getLocationTree($array);
- } elseif ($getAction == "calendar") {
- $locationIds = Request::get('id', 0, 'string');
- $array = filterIdList($locationIds);
- $output = getCalendar($array);
+ if ($get === "machines") {
+ $locationIds = getLocationsOr404($uuid);
+ $output = array();
+ appendMachineData($output, $locationIds, false);
+ $output = array_values($output);
+ } elseif ($get === "timestamp") {
+ $output = array('ts' => getLastChangeTs($uuid));
+ } elseif ($get === "config") {
+ $output = getConfig($uuid);
+ } elseif ($get === "pcstates") {
+ $locationIds = getLocationsOr404($uuid);
+ $output = getPcStates($locationIds);
+ } elseif ($get === "locationtree") {
+ $locationIds = getLocationsOr404($uuid);
+ $output = getLocationTree($locationIds);
+ } elseif ($get === "calendar") {
+ $locationIds = getLocationsOr404($uuid);
+ $output = getCalendar($locationIds);
}
if ($output !== false) {
echo json_encode($output);
+ } else {
+ http_response_code(404);
+ echo 'Unknown get option';
}
}
/**
- * Filters the id list. Removes Double / non-int / hidden locations.
- *
- * @param string $locationIds comma separated list of location ids
- * @return array The filtered array of the location ids.
+ * Return list of locationids associated with given panel.
+ * @param string $paneluuid panel
+ * @return int[] locationIds
*/
-function filterIdList($locationIds)
+function getLocationsOr404($paneluuid)
{
- $idList = explode(',', $locationIds);
- $filteredIdList = array_filter($idList, 'is_numeric');
- $filteredIdList = array_unique($filteredIdList);
- $filteredIdList = filterHiddenLocations($filteredIdList);
-
- return $filteredIdList;
-}
-
-/**
- * Filters the hidden locations from an array.
- *
- * @param int[] $idArray Id list
- * @return array Filtered id list
- */
-function filterHiddenLocations($idArray)
-{
- $idArray = array_flip($idArray);
- if (!empty($idArray)) {
- $query = "SELECT locationid FROM `locationinfo_locationconfig` WHERE hidden <> 0 AND locationid IN (:idlist)";
- $dbquery = Database::simpleQuery($query, array('idlist' => $idArray));
- while ($dbresult = $dbquery->fetch(PDO::FETCH_ASSOC)) {
- unset($idArray[$dbresult['locationid']]);
- }
+ $panel = Database::queryFirst('SELECT locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid',
+ compact('paneluuid'));
+ if ($panel !== false) {
+ return array_map('intval', explode(',', $panel['locationids']));
}
-
- return array_flip($idArray);
+ http_response_code(404);
+ die('Panel not found');
}
// ########## <Locationinfo> ##########
/**
* Gets the location info of the given locations.
+ * Append to passed array which is expected to
+ * map location ids to properties of that location.
+ * A new key 'machines' will be created in each
+ * entry of $array that will take all the machine data.
*
- * @param int[] $idList list of ids.
- * @param bool $coords Defines if coords should be included or not.
- * @return array location info struct
+ * @param array $array location list to populate with machine data
+ * @param bool $withPosition Defines if coords should be included or not.
*/
-function getLocationInfo($idList, $coords = false)
+function appendMachineData(&$array, $idList = false, $withPosition = false)
{
- if (empty($idList))
- return [];
+ if (empty($array) && $idList === false)
+ return;
+ if ($idList === false) {
+ $idList = array_keys($array);
+ }
- $positionCol = $coords ? 'm.position,' : '';
+ $positionCol = $withPosition ? 'm.position,' : '';
$query = "SELECT m.locationid, m.machineuuid, $positionCol m.logintime, m.lastseen, m.lastboot FROM machine m
WHERE m.locationid IN (:idlist)";
$dbquery = Database::simpleQuery($query, array('idlist' => $idList));
// Iterate over matching machines
- $dbresult = array();
- while ($dbdata = $dbquery->fetch(PDO::FETCH_ASSOC)) {
-
- // Set the id if the locationid changed.
- if (!isset($dbresult[$dbdata['locationid']])) {
- $dbresult[$dbdata['locationid']] = array('id' => $dbdata['locationid'], 'computer' => array());
+ while ($row = $dbquery->fetch(PDO::FETCH_ASSOC)) {
+ settype($row['locationid'], 'int');
+ if (!isset($array[$row['locationid']])) {
+ $array[$row['locationid']] = array('id' => $row['locationid'], 'machines' => array());
+ }
+ if (!isset($array[$row['locationid']]['machines'])) {
+ $array[$row['locationid']]['machines'] = array();
}
// Compact the pc data in one array.
- $pc = array('id' => $dbdata['machineuuid']);
- if ($coords && !empty($dbdata['position'])) {
- $position = json_decode($dbdata['position'], true);
+ $pc = array('id' => $row['machineuuid']);
+ if ($withPosition && !empty($row['position'])) {
+ $position = json_decode($row['position'], true);
if (isset($position['gridCol']) && isset($position['gridRow'])) {
$pc['x'] = $position['gridCol'];
$pc['y'] = $position['gridRow'];
- if (isset($position['overlays']) && is_array($position['overlays'])) {
+ if (!empty($position['overlays']) && is_array($position['overlays'])) {
$pc['overlays'] = $position['overlays'];
- } else {
- $pc['overlays'] = array();
}
}
}
- $pc['pcState'] = LocationInfo::getPcState($dbdata);
+ $pc['pcState'] = LocationInfo::getPcState($row);
- // Add the array to the computer list.
- $dbresult[$dbdata['locationid']]['computer'][] = $pc;
+ // Add the array to the machines list.
+ $array[$row['locationid']]['machines'][] = $pc;
}
-
- // The array keys are only used for the isset -> Return only the values.
- return array_values($dbresult);
}
// ########## </Locationinfo> ###########
-// ########## <Openingtime> ##########
/**
- * Gets the Opening time of the given locations.
+ * Returns all the passed location ids and appends
+ * all their direct and indirect parent location ids.
*
- * @param int[] $idList list of locations
- * @return array Opening times struct
+ * @param int[] $idList location ids
+ * @return int[] more location ids
*/
-function getOpeningTime($idList)
+function getLocationsWithParents($idList)
{
$locations = Location::getLocationsAssoc();
$allIds = $idList;
@@ -144,36 +124,59 @@ function getOpeningTime($idList)
$allIds = array_merge($allIds, $locations[$id]['parents']);
}
}
+ return array_map('intval', $allIds);
+}
+
+// ########## <Openingtime> ##########
+/**
+ * Gets the Opening time of the given locations.
+ *
+ * @param int[] $idList list of locations
+ * @return int modification timestamp of most recently updated locationconfig
+ */
+function appendOpeningTimes(&$array, $idList)
+{
+ // First, lets get all the parent ids for the given locations
+ // in case we need to get inherited opening times
+ $allIds = getLocationsWithParents($idList);
if (empty($allIds))
- return [];
+ return 0;
+ $latest = 0;
+ $res = Database::simpleQuery("SELECT locationid, openingtime, lastchange FROM locationinfo_locationconfig
+ WHERE locationid IN (:lids)", array('lids' => $allIds));
$openingTimes = array();
- $qs = '?' . str_repeat(',?', count($allIds) - 1);
- $res = Database::simpleQuery("SELECT locationid, openingtime FROM locationinfo_locationconfig WHERE locationid IN ($qs)",
- array_values($allIds));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $openingTimes[(int)$row['locationid']] = $row['openingtime'];
+ $openingTimes[(int)$row['locationid']] = $row;
+ if (in_array($row['locationid'], $idList)) {
+ $latest = max($row['lastchange'], $latest);
+ }
}
- $returnValue = array();
- foreach ($idList as $locationid) {
- $id = $locationid;
- while ($id !== 0) {
- if (!empty($openingTimes[$id])) {
- $cal = json_decode($openingTimes[$id], true);
+ // Now we got all the calendars for locations and parents
+ // Iterate over the locations we're actually interested in
+ $locations = Location::getLocationsAssoc();
+ foreach ($idList as $locationId) {
+ // Start checking at actual location...
+ $currentId = $locationId;
+ while ($currentId !== 0) {
+ if (!empty($openingTimes[$currentId]['openingtime'])) {
+ $cal = json_decode($openingTimes[$currentId]['openingtime'], true);
if (is_array($cal)) {
$cal = formatOpeningtime($cal);
}
if (!empty($cal)) {
- $returnValue[] = array(
- 'id' => $locationid,
- 'openingtime' => $cal,
- );
+ // Got a valid calendar
+ if (!isset($array[$locationId])) {
+ $array[$locationId] = array('id' => $locationId);
+ }
+ $array[$locationId]['openingtime'] = $cal;
break;
}
}
- $id = $locations[$id]['parentlocationid'];
+ // Keep trying with parent
+ $currentId = $locations[$currentId]['parentlocationid'];
}
}
- return $returnValue;
+ return $latest;
}
/**
@@ -188,30 +191,22 @@ function getOpeningTime($idList)
function formatOpeningtime($openingtime)
{
$result = array();
- $weekarray = array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday");
- foreach ($weekarray as $checkDay) {
- $array = array();
- foreach ($openingtime as $opt) {
- if (!isset($opt['days']) || !is_array($opt['days']))
- continue;
- $openTime = explode(':', $opt['openingtime']);
- $closeTime = explode(':', $opt['closingtime']);
- if (count($openTime) !== 2 || count($closeTime) !== 2)
- continue;
- $arr = array(
- 'HourOpen' => $openTime[0],
- 'MinutesOpen' => $openTime[1],
- 'HourClose' => $closeTime[0],
- 'MinutesClose' => $closeTime[1],
- );
- foreach ($opt['days'] as $calDay) {
- if ($calDay === $checkDay) {
- $array[] = $arr;
- }
- }
- if (!empty($array)) {
- $result[$checkDay] = $array;
+ foreach ($openingtime as $entry) {
+ $openTime = explode(':', $entry['openingtime']);
+ $closeTime = explode(':', $entry['closingtime']);
+ if (count($openTime) !== 2 || count($closeTime) !== 2)
+ continue;
+ $convertedTime = array(
+ 'HourOpen' => $openTime[0],
+ 'MinutesOpen' => $openTime[1],
+ 'HourClose' => $closeTime[0],
+ 'MinutesClose' => $closeTime[1],
+ );
+ foreach ($entry['days'] as $day) {
+ if (!isset($result[$day])) {
+ $result[$day] = array();
}
+ $result[$day][] = $convertedTime;
}
}
return $result;
@@ -224,30 +219,70 @@ function formatOpeningtime($openingtime)
* @param int $locationID ID of the location
* @return array configuration struct
*/
-function getConfig($locationID)
+function getConfig($paneluuid)
{
- $dbresult = Database::queryFirst("SELECT l.locationname, li.config FROM `location` AS l
- LEFT JOIN `locationinfo_locationconfig` AS li ON (l.locationid = li.locationid)
- WHERE l.locationid = :locationID", array('locationID' => $locationID));
+ $panel = Database::queryFirst('SELECT panelconfig, paneltype, locationids, lastchange FROM locationinfo_panel WHERE paneluuid = :paneluuid',
+ compact('paneluuid'));
- $config = LocationInfo::defaultPanelConfig();
+ if ($panel === false || empty($panel['locationids'])) {
+ http_response_code(404);
+ die('Panel not found');
+ }
- if ($dbresult !== false) {
- if (!empty($dbresult['config'])) {
- $json = json_decode($dbresult['config'], true);
- if (is_array($json)) {
- $config = $json + $config;
- }
+ $config = LocationInfo::defaultPanelConfig($panel['paneltype']);
+ $locations = Location::getLocationsAssoc();
+
+ if (!empty($panel['config'])) {
+ $json = json_decode($panel['config'], true);
+ if (is_array($json)) {
+ $config = $json + $config;
}
- $config['room'] = $dbresult['locationname'];
}
+ $config['locations'] = array();
+ $lids = array_map('intval', explode(',', $panel['locationids']));
+ foreach ($lids as $lid) {
+ $config['locations'][$lid] = array(
+ 'id' => $lid,
+ 'name' => isset($locations[$lid]) ? $locations[$lid]['locationname'] : 'noname00.pas',
+ );
+ }
+ appendMachineData($config['locations'], $lids, true);
+ $locChange = appendOpeningTimes($config['locations'], $lids);
+ $config['ts'] = max($panel['lastchange'], $locChange);
+ $config['locations'] = array_values($config['locations']);
$config['time'] = date('Y-m-d H:i:s');
return $config;
}
/**
+ * Get last config modification timestamp for given panel. This checks
+ * the modification of the panel config itself as well as all involved locations
+ *
+ * @param $paneluuid
+ * @return mixed
+ */
+function getLastChangeTs($paneluuid)
+{
+ $panel = Database::queryFirst('SELECT paneltype, locationids, lastchange FROM locationinfo_panel WHERE paneluuid = :paneluuid',
+ compact('paneluuid'));
+ if ($panel === false) {
+ http_response_code(404);
+ die('Panel not found');
+ }
+ $latest = $panel['lastchange'];
+ // TODO: summary
+ $lids = explode(',', $panel['locationids']);
+ $res = Database::simpleQuery('SELECT lastchange FROM locationinfo_locationconfig WHERE locationid IN (:lids)',
+ compact('lids'));
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ $latest = max($row['lastchange'], $latest);
+ }
+ return (int)$latest;
+}
+
+/**
* Gets the pc states of the given locations.
*
* @param int[] $idList list of the location ids.
@@ -265,11 +300,13 @@ function getPcStates($idList)
'broken' => 0,
);
}
- $locationInfoList = getLocationInfo($idList);
+
+ $locationInfoList = array();
+ appendMachineData($locationInfoList, $idList);
foreach ($locationInfoList as $locationInfo) {
$id = $locationInfo['id'];
- foreach ($locationInfo['computer'] as $computer) {
- $key = strtolower($computer['pcState']);
+ foreach ($locationInfo['machines'] as $pc) {
+ $key = strtolower($pc['pcState']);
if (isset($pcStates[$id][$key])) {
$pcStates[$id][$key]++;
}
@@ -325,7 +362,7 @@ function getCalendar($idList)
$query = "SELECT l.locationid, l.serverid, l.serverlocationid, s.servertype, s.credentials
FROM `locationinfo_locationconfig` AS l
INNER JOIN locationinfo_coursebackend AS s ON (s.serverid = l.serverid)
- WHERE l.hidden = 0 AND l.locationid IN (:idlist)
+ WHERE l.locationid IN (:idlist)
ORDER BY s.servertype ASC";
$dbquery = Database::simpleQuery($query, array('idlist' => array_values($idList)));
diff --git a/modules-available/locationinfo/frontend/doorsign.html b/modules-available/locationinfo/frontend/doorsign.html
index ee4f8c6c..eb15c9d0 100755
--- a/modules-available/locationinfo/frontend/doorsign.html
+++ b/modules-available/locationinfo/frontend/doorsign.html
@@ -1,11 +1,12 @@
+<!DOCTYPE html>
<!--
parameter
required:
- id: [integer] room id, see in admin panel
-optional:
+ uuid: [integer] panel id, see in admin panel
+optional:
lang:[en,de] set the language
mode:[1,2,3,4] sets the displaying
1: Calendar & Room
@@ -19,11 +20,9 @@ optional:
roomupdate: Time the PCs in the room gets updated,in seconds.
rotation:[0-3] rotation of the roomplan
vertical:[true] only mode 1, sets the calendar above the roomplan
- configupdate: Time interval the config gets updated (in minutes)
scaledaysauto: [true] if true it finds automaticly the daystoshow parameter depending on display size
-->
-<!DOCTYPE html>
<html lang="de">
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8">
<head>
@@ -73,8 +72,8 @@ optional:
height: 2px;
position: absolute;
background-color: red;
- bottom: 2px;
- z-index: 1;
+ bottom: 0px;
+ z-index: 100;
}
.font {
@@ -94,8 +93,8 @@ optional:
display: block;
}
- [class*="col-"] {
- float: left;;
+ [class|="col"] {
+ float: left;
padding: 0;
box-sizing: border-box;
}
@@ -278,13 +277,14 @@ optional:
<script type='text/javascript'>
var rooms = {};
- var lastSwitchTime;
- var roomsToshow = 0;
- var roomIds;
- //Todo change these
- var date;
- var supportSvg = typeof SVGRect != "undefined";
- var calendarQueryUrl;
+ var lastRoomUpdate = 0;
+ var lastCalendarUpdate = 0;
+ var lastSwitchTime = 0;
+ var globalConfig = {};
+ var roomIds = [];
+ var panelUuid = false;
+ var supportSvg = typeof SVGRect !== "undefined";
+ // TODO: Get languages from slx-admin
var translation = {
"en": {
"room": "Room",
@@ -317,105 +317,88 @@ optional:
$(document).ready(function () {
- if (!getId()) {
-
+ var uuid = getUrlParameter("uuid");
+ if (!uuid) {
+ console.log('No panel uuid given');
+ $("body").empty().append($('<h1>').text('No panel UUID given.'));
+ return;
}
+ getConfig(uuid);
});
+ /**
+ * Display given error message and try reloading page once a minute
+ */
+ function fatalError(message) {
+ $('body').empty().append($('<h1>').text(message));
+ window.setInterval(function () {
+ $.ajax('/').done(function () {
+ window.location.reload(true);
+ }).fail(function () {
+ $('body').append('...');
+ });
+ }, 60000);
+ }
+
/**
* Downloads the config of a room, also reloads the page if the config hase changed over time
- * @param id ID of the room
+ * @param uuid ID of the room
* @param room Room Object, only needed if it already exists
*/
- function getConfig(id, room) {
+ function getConfig(uuid) {
$.ajax({
- url: "../../../api.php?do=locationinfo&action=config&id=" + id,
+ url: "../../../api.php?do=locationinfo&get=config&uuid=" + uuid,
dataType: 'json',
cache: false,
timeout: 30000,
success: function (result) {
- if (room == null) {
-
- if (result.room == null) {
-
- for (var i = roomIds.length - 1; i >= 0; i--) {
- if (roomIds[i] === id) {
- roomIds.splice(i, 1);
- }
- }
- if (roomsToshow == roomIds.length) {
-
- initRooms();
-
- }
- return;
- }
-
- var time = new Date(result.time);
- if (isNaN(time.getTime())) {
- time = new Date();
- }
- SetUpDate(time);
- delete result.time;
-
- room = addRoom(id, result.room, result);
- roomsToshow++;
- if (roomsToshow == roomIds.length) {
-
- initRooms();
+ if (!result.locations || result.locations.constructor !== Array) {
+ fatalError("Requested panel doesn't contain locations / not array");
+ return;
+ }
- }
+ var fetchedRooms = result.locations.filter(function (x) {
+ // filter out if no numeric id, or id already present, or already got 4 locations
+ if (typeof(x.id) !== 'number' || x.id <= 0 || roomIds.indexOf(x.id) !== -1 || roomIds.length >= 4)
+ return false;
+ roomIds.push(x.id);
+ return true;
+ });
+
+ if (roomIds.length === 0) {
+ fatalError("List of location ids is empty");
+ return;
+ }
+ var time = new Date(result.time);
+ if (isNaN(time.getTime()) || time.getYear() < 2010) {
+ time = new Date();
+ }
+ SetUpDate(time);
+ delete result.time;
+ delete result.locations;
- } else {
+ globalConfig = result;
+ sanitizeGlobalConfig();
+ lastRoomUpdate = MyDate().getTime();
- delete result.time;
- if (JSON.stringify(rooms[id].config) != JSON.stringify(result)) {
- // reload Page if someone changed config
- location.reload(true);
- }
+ for (var i = 0; i < fetchedRooms.length; ++i) {
+ var r = addRoom(fetchedRooms[i]);
}
- // check for config changes from time to time
- setTimeout(function () {
- getConfig(id, room);
- }, room.config.configupdate);
+ initRooms();
+ // TODO: Check for changed config using get=timestamp and reload whole page on change
+ panelUuid = uuid;
}, error: function () {
- //Todo Error handling:
+ fatalError('Could not fetch panel config');
}
})
}
-
- /**
- * gets the Parameter IDs from the Urls
- */
- function getId() {
- roomIds = getUrlParameter("id");
- if (roomIds == null) {
-
- var text = "<h1>Error: No Room Id's given in parameter </h1>";
- $("body").append(text);
-
- return false;
- }
-
- roomIds = roomIds.split(',');
- if (roomIds.length > 4) {
- roomIds.length = 4;
- }
-
- for (var i = 0; i < roomIds.length; i++) {
- getConfig(roomIds[i], null);
-
- }
-
- }
-
const PARAM_STRING = 1;
const PARAM_INT = 2;
const PARAM_BOOL = 3;
@@ -440,7 +423,7 @@ optional:
}
} else if (paramType === PARAM_BOOL) {
val = val.toLowerCase();
- config[property] = val.length > 0 && val !== 'false' && val !== 'off' ? true : false;
+ config[property] = val.length > 0 && val !== 'false' && val !== 'off' && val !== '0';
} else {
console.log('Invalid paramType: ' + paramType);
}
@@ -470,45 +453,36 @@ optional:
* gets Additional Parameters from the URL, and from the
* downloaded json.
* also makes sure parameters are in a given range
- * @param room Room Object
*/
- function getParamerter(room) {
-
-
- if (room.config) {
- room.config.switchtime = room.config.switchtime * 1000;
- room.config.calupdate = room.config.calupdate * 60 * 1000;
- room.config.roomupdate = room.config.roomupdate * 1000;
- room.config.configupdate = room.config.configupdate * 60 * 1000;
+ function sanitizeGlobalConfig() {
+ if (globalConfig) {
+ globalConfig.switchtime = globalConfig.switchtime * 1000;
+ globalConfig.calupdate = globalConfig.calupdate * 60 * 1000;
+ globalConfig.roomupdate = globalConfig.roomupdate * 1000;
}
- setRoomConfigFromUrl(room.config, 'mode', PARAM_INT);
- setRoomConfigFromUrl(room.config, 'calupdate', PARAM_INT, 60 * 1000);
- setRoomConfigFromUrl(room.config, 'roomupdate', PARAM_INT, 1000);
- setRoomConfigFromUrl(room.config, 'daystoshow', PARAM_INT);
- setRoomConfigFromUrl(room.config, 'scaledaysauto', PARAM_BOOL);
- setRoomConfigFromUrl(room.config, 'vertical', PARAM_BOOL);
- setRoomConfigFromUrl(room.config, 'eco', PARAM_BOOL);
+ setRoomConfigFromUrl(globalConfig, 'mode', PARAM_INT);
+ setRoomConfigFromUrl(globalConfig, 'calupdate', PARAM_INT, 60 * 1000);
+ setRoomConfigFromUrl(globalConfig, 'roomupdate', PARAM_INT, 1000);
+ setRoomConfigFromUrl(globalConfig, 'daystoshow', PARAM_INT);
+ setRoomConfigFromUrl(globalConfig, 'scaledaysauto', PARAM_BOOL);
+ setRoomConfigFromUrl(globalConfig, 'vertical', PARAM_BOOL);
+ setRoomConfigFromUrl(globalConfig, 'eco', PARAM_BOOL);
- setRoomConfigFromUrl(room.config, 'scale', PARAM_INT);
- setRoomConfigFromUrl(room.config, 'rotation', PARAM_INT);
- setRoomConfigFromUrl(room.config, 'switchtime', PARAM_INT, 1000);
- setRoomConfigFromUrl(room.config, 'configupdate', PARAM_INT, 60 * 1000);
+ setRoomConfigFromUrl(globalConfig, 'scale', PARAM_INT);
+ setRoomConfigFromUrl(globalConfig, 'rotation', PARAM_INT);
+ setRoomConfigFromUrl(globalConfig, 'switchtime', PARAM_INT, 1000);
// parameter validation
- putInRange(room.config, 'switchtime', 5, 120, 6, 1000);
- putInRange(room.config, 'scale', 10, 90, 50);
- putInRange(room.config, 'daystoshow', 1, 7, 7);
- putInRange(room.config, 'roomupdate', 15, 5*60, 60, 1000);
- putInRange(room.config, 'configupdate', 5, 60, 30, 60*1000);
- putInRange(room.config, 'calupdate', 1, 60, 30, 60*1000);
- putInRange(room.config, 'mode', 1, 4, 1);
- putInRange(room.config, 'rotation', 0, 3, 0);
+ putInRange(globalConfig, 'switchtime', 5, 120, 6, 1000);
+ putInRange(globalConfig, 'scale', 10, 90, 50);
+ putInRange(globalConfig, 'daystoshow', 1, 7, 7);
+ putInRange(globalConfig, 'roomupdate', 15, 5 * 60, 60, 1000);
+ putInRange(globalConfig, 'calupdate', 1, 60, 30, 60 * 1000);
+ putInRange(globalConfig, 'mode', 1, 4, 1);
+ putInRange(globalConfig, 'rotation', 0, 3, 0);
- if (getUrlParameter("lang") != null && getUrlParameter("lang") in translation) {
- room.config.language = getUrlParameter("lang");
- }
- $('html').attr('lang', room.config.language);
+ $('html').attr('lang', globalConfig.language);
}
/**
@@ -518,227 +492,193 @@ optional:
var width = "100%";
var height = "100%";
- if (roomsToshow == 2 || roomsToshow == 4) {
+ var hasMode4 = (globalConfig.mode === 4);
+ if (roomIds.length === 2 || roomIds.length === 4) {
width = "50%";
}
- if (roomsToshow == 3) {
+ if (roomIds.length === 3) {
width = "33%";
}
- if (roomsToshow == 4) {
+ if (roomIds.length === 4) {
height = "50%";
}
- var i = 0;
for (var t = 0; t < roomIds.length; t++) {
- var property = roomIds[t];
- var text = "<div class='roompadding' id ='roompadding_" + rooms[property].id + "'></div>";
+ var headers;
+ var rid = roomIds[t];
+ var text = "<div class='roompadding' id='roompadding_" + rid + "'></div>";
$("body").append(text);
- var obj = document.getElementById("roompadding_" + rooms[property].id);
+ var obj = document.getElementById("roompadding_" + rid);
obj.style.height = height;
obj.style.width = width;
- text = "<div class='room' id ='room_" + rooms[property].id + "'></div>";
+ text = "<div class='room' id ='room_" + rid + "'></div>";
- $("#roompadding_" + rooms[property].id).append(text);
+ $("#roompadding_" + rid).append(text);
- text = "<div id='header_" + rooms[property].id + "' class='row'>" +
+ text = "<div id='header_" + rid + "' class='row'>" +
"<div class='header col-2'>" +
- "<div class='font' id='roomHeader_" + rooms[property].id + "'></div>" +
+ "<div class='font' id='roomHeader_" + rid + "'></div>" +
"</div>" +
"<div class='col-1 courseText header'>" +
- "<div class='font' id='courseHeading_" + rooms[property].id + "'></div>" +
+ "<div class='font' id='courseHeading_" + rid + "'></div>" +
"</div>" +
- "<div class='square .col-2' id='square_" + rooms[property].id + "'>" +
- "<div class='FreeSeatsFont' id='freeSeatsHeader_" + rooms[property].id + "'></div>" +
+ "<div class='square .col-2' id='square_" + rid + "'>" +
+ "<div class='FreeSeatsFont' id='freeSeatsHeader_" + rid + "'></div>" +
"</div>" +
"</div>";
- $("#room_" + rooms[property].id).append(text);
+ $("#room_" + rid).append(text);
- if (rooms[property].name != null) {
- $("#roomHeader_" + rooms[property].id).text(rooms[property].name);
+ if (rooms[rid].name !== null) {
+ $("#roomHeader_" + rid).text(rooms[rid].name);
}
- if (roomsToshow == 2) {
- document.getElementById("square_" + rooms[property].id).style.width = "6vw";
- document.getElementById("square_" + rooms[property].id).style.height = "6vw";
- document.getElementById("roomHeader_" + rooms[property].id).style.fontSize = "1.8vw";
- document.getElementById("freeSeatsHeader_" + rooms[property].id).style.fontSize = "4.5vw";
- document.getElementById("courseHeading_" + rooms[property].id).style.fontSize = "1.8vw";
- var headers = document.getElementsByClassName('header');
+ if (roomIds.length === 2) {
+ document.getElementById("square_" + rid).style.width = "6vw";
+ document.getElementById("square_" + rid).style.height = "6vw";
+ document.getElementById("roomHeader_" + rid).style.fontSize = "1.8vw";
+ document.getElementById("freeSeatsHeader_" + rid).style.fontSize = "4.5vw";
+ document.getElementById("courseHeading_" + rid).style.fontSize = "1.8vw";
+ headers = document.getElementsByClassName('header');
for (var j = 0; j < headers.length; j++) {
headers[j].style.height = "6vw";
}
}
- if (roomsToshow == 3) {
- document.getElementById("square_" + rooms[property].id).style.width = "4vw";
- document.getElementById("square_" + rooms[property].id).style.height = "4vw";
- document.getElementById("roomHeader_" + rooms[property].id).style.fontSize = "1.2vw";
- document.getElementById("freeSeatsHeader_" + rooms[property].id).style.fontSize = "2.5vw";
- document.getElementById("courseHeading_" + rooms[property].id).style.fontSize = "1.2vw";
- var headers = document.getElementsByClassName('header');
+ if (roomIds.length === 3) {
+ document.getElementById("square_" + rid).style.width = "4vw";
+ document.getElementById("square_" + rid).style.height = "4vw";
+ document.getElementById("roomHeader_" + rid).style.fontSize = "1.2vw";
+ document.getElementById("freeSeatsHeader_" + rid).style.fontSize = "2.5vw";
+ document.getElementById("courseHeading_" + rid).style.fontSize = "1.2vw";
+ headers = document.getElementsByClassName('header');
for (var j = 0; j < headers.length; j++) {
headers[j].style.height = "4vw";
}
}
- if (roomsToshow == 4) {
- document.getElementById("square_" + rooms[property].id).style.width = "4vw";
- document.getElementById("square_" + rooms[property].id).style.height = "4vw";
- document.getElementById("roomHeader_" + rooms[property].id).style.fontSize = "1.5vw";
- document.getElementById("freeSeatsHeader_" + rooms[property].id).style.fontSize = "2.5vw";
- document.getElementById("courseHeading_" + rooms[property].id).style.fontSize = "1.5vw";
-
- var headers = document.getElementsByClassName('header');
+ if (roomIds.length === 4) {
+ document.getElementById("square_" + rid).style.width = "4vw";
+ document.getElementById("square_" + rid).style.height = "4vw";
+ document.getElementById("roomHeader_" + rid).style.fontSize = "1.5vw";
+ document.getElementById("freeSeatsHeader_" + rid).style.fontSize = "2.5vw";
+ document.getElementById("courseHeading_" + rid).style.fontSize = "1.5vw";
+
+ headers = document.getElementsByClassName('header');
for (var j = 0; j < headers.length; j++) {
headers[j].style.height = "4vw";
}
}
- if (rooms[property].config.mode == 1) {
- setUpCalendar(rooms[property].config.scale + "%", rooms[property].config.daystoshow, rooms[property]);
- preInitRoom(rooms[property]);
+ if (globalConfig.mode === 1) {
+ setUpCalendar(globalConfig.scale + "%", globalConfig.daystoshow, rooms[rid]);
+ initRoomLayout(rooms[rid]);
- } else if (rooms[property].config.mode == 2) {
- setUpCalendar("100%", rooms[property].config.daystoshow, rooms[property]);
+ } else if (globalConfig.mode === 2) {
+ setUpCalendar("100%", globalConfig.daystoshow, rooms[rid]);
- } else if (rooms[property].config.mode == 3) {
- preInitRoom(rooms[property]);
- getOpeningTimes(rooms[property]);
- } else if (rooms[property].config.mode == 4) {
+ } else if (globalConfig.mode === 3) {
+ initRoomLayout(rooms[rid]);
- setUpCalendar("100%", rooms[property].config.daystoshow, rooms[property]);
- preInitRoom(rooms[property]);
- generateProgressBar(rooms[property].id);
+ } else if (globalConfig.mode === 4) {
+ setUpCalendar("100%", globalConfig.daystoshow, rooms[rid]);
+ initRoomLayout(rooms[rid]);
+ hasMode4 = true;
}
-
- i++;
+ SetOpeningTimes(rooms[rid]);
+ UpdateRoomHeader(rooms[rid]);
}
- setInterval(mainUpdateLoop, 1000);
- }
-
- /**
- * Helper function to generate id string used in query functions
- * @param list A string, wicht contains ids or not(for now)
- * @param id An ID which should be added to the list
- */
- function addIdToUpdateList(list, id) {
- if (list == "") {
- list += id;
- } else {
- list += ("," + id);
+ if (hasMode4) {
+ generateProgressBar();
}
- return list;
+ setInterval(mainUpdateLoop, 1000);
}
-
var timeSteps = 10;
+ var lastDate = false;
/**
* Main Update loop, this loop runs every 1 seconds and calls all
* function which should be called periodically
*/
function mainUpdateLoop() {
-
+ var date = MyDate();
+ var now = date.getTime();
// check ervery 10 sec if rooms need new calendar data or room data
// groups request
if (timeSteps > 9) {
timeSteps = 0;
- var calendarUpdateIds = "";
- var rommUpdateIds = "";
- for (var property in rooms) {
- if (rooms[property].config.lastCalendarUpdate == null || rooms[property].config.lastCalendarUpdate + rooms[property].config.calupdate < MyDate().getTime()) {
-
- calendarUpdateIds = addIdToUpdateList(calendarUpdateIds, rooms[property].id);
- rooms[property].config.lastCalendarUpdate = MyDate().getTime();
- }
- if (rooms[property].config.lastRoomUpdate == null || rooms[property].config.lastRoomUpdate + rooms[property].config.roomupdate < MyDate().getTime()) {
- rommUpdateIds = addIdToUpdateList(rommUpdateIds, rooms[property].id);
- rooms[property].config.lastRoomUpdate = MyDate().getTime();
- }
- }
-
-
- if (calendarUpdateIds != "") {
- queryCalendars(calendarUpdateIds);
+ if (lastCalendarUpdate + globalConfig.calupdate < now) {
+ lastCalendarUpdate = now;
+ queryCalendars();
}
- if (rommUpdateIds != "") {
- queryRooms(rommUpdateIds);
+ if (lastRoomUpdate + globalConfig.roomupdate < now) {
+ lastRoomUpdate = now;
+ queryRooms();
}
}
// switches calendar and roomlayout in mode 4
+ if (globalConfig.mode === 4 && lastSwitchTime + globalConfig.switchtime < now) {
+ doSwitch = true;
+ lastSwitchTime = now;
+ }
for (var property in rooms) {
- if (rooms[property].config.mode == 4) {
- if (rooms[property].lastSwitchTime == null
- || rooms[property].lastSwitchTime + rooms[property].config.switchtime < MyDate().getTime()) {
-
-
- switchLayout(rooms[property]);
- MoveProgressBar(rooms[property].id, rooms[property].config.switchtime);
-
- if (rooms[property].lastSwitchTime == null) {
- rooms[property].lastSwitchTime = MyDate().getTime();
- } else {
- rooms[property].lastSwitchTime = rooms[property].lastSwitchTime + rooms[property].config.switchtime;
- }
- }
-
- //
+ if (rooms[property].state.end) {
+ // Updating All room Headers
+ UpdateRoomHeader(rooms[property]);
}
- // Updateing All room Headers
-
- UpdateRoomHeader(rooms[property]);
}
-
// reload site at midnight
- var now = new MyDate();
- if (date != null) {
- if (date.getDate() != now.getDate()) {
+ var today = date.getDate();
+ if (lastDate !== false) {
+ if (lastDate !== today) {
location.reload(true);
}
+ } else {
+ lastDate = today;
}
- date = now;
timeSteps++;
}
/**
* Generates a room Object and adds it to the rooms array
- * @param id ID of the room
- * @param name Name of the room
- * @param config Config Json of the room
+ * @param roomData Config Json of the room
*/
- function addRoom(id, name, config) {
+ function addRoom(roomData) {
+ var now = MyDate().getTime();
var room = {
- id: id,
- name: name,
+ id: roomData.id,
+ name: roomData.name,
+ config: globalConfig,
timetable: null,
currentEvent: null,
nextEventEnd: null,
timeTilFree: null,
state: null,
+ rawOpeningTimes: roomData.openingtime || null,
openingTimes: null,
- config: config,
+ openTimes: 24,
currentfreePcs: 0,
- layout: null,
+ layout: roomData.machines || null,
freePcs: 0,
resized: true,
- lastCalendarUpdate: null,
- lastRoomUpdate: null,
+ lastCalendarUpdate: now,
+ lastRoomUpdate: now,
getState: function () {
- if (this.state == null) {
+ if (this.state === null) {
ComputeCurrentState(this);
return this.state;
}
- if (this.state.end != "") {
- if (this.state.end < new MyDate()) {
+ if (this.state.end) {
+ if (this.state.end < MyDate()) {
ComputeCurrentState(this);
}
}
@@ -747,10 +687,8 @@ optional:
};
- getParamerter(room);
- rooms[id] = room;
+ rooms[roomData.id] = room;
return room;
-
}
/**
@@ -767,7 +705,7 @@ optional:
daysToShow: daysToShow,
height: function ($calendar) {
var height = $(window).height();
- if (roomsToshow == 4) {
+ if (roomIds.length == 4) {
height = height / 2;
}
@@ -778,10 +716,10 @@ optional:
return height;
},
eventRender: function (calEvent, $event) {
- if (calEvent.end.getTime() < new MyDate().getTime()) {
+ if (calEvent.end.getTime() < MyDate().getTime()) {
$event.css("backgroundColor", "#aaa");
$event.find(".time").css({"backgroundColor": "#999", "border": "1px solid #888"});
- } else if (calEvent.end.getTime() > new MyDate().getTime() && calEvent.start.getTime() < new MyDate().getTime()) {
+ } else if (calEvent.end.getTime() > MyDate().getTime() && calEvent.start.getTime() < MyDate().getTime()) {
$event.css("backgroundColor", "#25B002");
$event.find(".time").css({"backgroundColor": "#25B002", "border": "1px solid #888"});
}
@@ -802,33 +740,9 @@ optional:
displayFreeBusys: true,
defaultFreeBusy: {free: false}
});
- getOpeningTimes(room);
-
-
}
/**
- * downloads openingTimes for an room
- * @param room Room Object
- */
- function getOpeningTimes(room) {
- $.getJSON("../../../api.php?do=locationinfo&action=openingtime&id=" + room.id, function (result) {
- if (Object.prototype.toString.call(result) === '[object Array]') {
- if (result.length > 0) {
- SetOpeningTimes(result[0].openingtime, room);
- }
- }
- scaleCalendar(room);
-
- })
- .error(function () {
- scaleCalendar(room);
-
- })
- }
-
-
- /**
* Generates the Calendar Div, depending on it's width
* @param width width of the Calendar Div
* @param room Room Object
@@ -838,7 +752,7 @@ optional:
var div = document.createElement("div");
div.id = "calendar_" + room.id;
div.className = "calendar";
- if (room.config.vertical && room.config.mode == 1) {
+ if (room.config.vertical && room.config.mode === 1) {
width = 100 + "%";
$(div).css('float', "none");
}
@@ -848,27 +762,43 @@ optional:
}
+ const OT_DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+ const OT_KEYS = ['HourOpen', 'HourClose', 'MinutesOpen', 'MinutesClose'];
+
/**
* sets the opening Time in the calendar plugin and saves it in the room object
- * @param parsedOpenings Dictonary of Opening times.
* @param room Room Object
*/
- function SetOpeningTimes(parsedOpenings, room) {
+ function SetOpeningTimes(room) {
var opening = 24;
var close = 0;
- room.openingTimesCalendar = [];
- room.openingTimes = [parsedOpenings['Sunday'], parsedOpenings['Monday'], parsedOpenings['Tuesday'],
- parsedOpenings['Wednesday'], parsedOpenings['Thursday'],
- parsedOpenings['Friday'], parsedOpenings['Saturday']];
- if (room.config.mode == 3) {
+ var i;
+ if (room.rawOpeningTimes && typeof(room.rawOpeningTimes) === 'object') {
+ // TODO: wtf! we have three(!) formats for storing the opening times (DB, API, now this one) - WHY!?
+ var parsedOpenings = room.rawOpeningTimes;
+ room.state = null;
+ room.openingTimesCalendar = [];
+ room.openingTimes = [];
+ for (i = 0; i < OT_DAYS.length; ++i) {
+ room.openingTimes.push(filterOpeningTimesDay(parsedOpenings[OT_DAYS[i]]));
+ }
+ delete room.rawOpeningTimes;
+ }
+ if (!room.openingTimes) {
+ scaleCalendar(room);
+ return;
+ }
+ if (room.config.mode === 3) {
+ // Calendar is not displayed, don't need to do additional work
return;
}
- for (var i = 0; i < 7; i++) {
+ var now = MyDate();
+ for (i = 0; i < 7; i++) {
var tmp = room.openingTimes[i];
- if (tmp != null) {
- for (var d = 0; d < tmp.length; d++) {
- var day = getNextDayOfWeek(new MyDate(), i);
+ for (var d = 0; d < tmp.length; d++) {
+ var day = getNextDayOfWeek(now, i);
+ if (room.openingTimesCalendar) {
room.openingTimesCalendar.push({
"start": new Date(day.getFullYear(), day.getMonth(), day.getDate(),
tmp[d]['HourOpen'], tmp[d]['MinutesOpen']),
@@ -876,82 +806,124 @@ optional:
day.getDate(), tmp[d]['HourClose'], tmp[d]['MinutesClose']),
"free": true
});
- if (parseInt(tmp[d]['HourOpen']) < opening) {
- opening = tmp[d]['HourOpen'];
- }
- if (parseInt(tmp[d]['HourClose']) > close) {
- close = tmp[d]['HourClose'];
- if (parseInt(tmp[d]['MinutesClose']) != 0) {
- close++;
- }
+ }
+ if (tmp[d]['HourOpen'] < opening) {
+ opening = tmp[d]['HourOpen'];
+ }
+ if (tmp[d]['HourClose'] >= close) {
+ close = tmp[d]['HourClose'];
+ if (tmp[d]['MinutesClose'] !== 0) {
+ close++;
}
}
}
}
- if (parsedOpenings.length == 0) {
+ if (opening === 24 && close === 0) {
opening = 0;
close = 24;
}
room.openTimes = close - opening;
$('#calendar_' + room.id).weekCalendar("option", "businessHours", {
- start: parseInt(opening),
- end: parseInt(close),
+ start: opening,
+ end: close,
limitDisplay: true
});
+ scaleCalendar(room);
+ }
+
+ /**
+ * Filter out invalid opening time entries from given array,
+ * also make sure all the values are of type number (int)
+ *
+ * @param {Array} arr
+ * @return {Array} list of valid opening times
+ */
+ function filterOpeningTimesDay(arr) {
+ if (!arr || arr.constructor !== Array) return [];
+ return arr.map(function (el) {
+ if (!el || typeof el !== 'object') return null;
+ for (var i = 0; i < OT_KEYS.length; ++i) {
+ el[OT_KEYS[i]] = toInt(el[OT_KEYS[i]]);
+ if (isNaN(el[OT_KEYS[i]])) return null;
+ }
+ return el;
+ }).filter(function (el) {
+ if (!el) return false;
+ if (el.HourOpen < 0 || el.HourOpen > 23) return false;
+ if (el.HourClose < 0 || el.HourClose > 23) return false;
+ if (el.HourClose < el.HourOpen) return false;
+ if (el.MinutesOpen < 0 || el.MinutesOpen > 59) return false;
+ if (el.MinutesClose < 0 || el.MinutesClose > 59) return false;
+ if (el.HourOpen === el.HourClose && el.MinutesClose < el.MinutesOpen) return false;
+ return true;
+ });
}
/**
* querys the Calendar data
* @param ids ID'S of rooms to query as string, for e.g.: "5,17,8" or "5"
*/
- function queryCalendars(ids) {
- var url = "../../../api.php?do=locationinfo&action=calendar&id=" + ids;
-
- // Todo reimplement Frontend methode if needed
- /*
- if(!(room.config.calendarqueryurl === undefined)) {
- url = room.config.calendarqueryurl;
- }
- */
+ function queryCalendars() {
+ if (!panelUuid) return;
+ var url = "../../../api.php?do=locationinfo&get=calendar&uuid=" + panelUuid;
$.ajax({
url: url,
dataType: 'json',
cache: false,
timeout: 30000,
success: function (result) {
- var l = result.length;
- for (var i = 0; i < l; i++) {
- updateCalendar(result[i].calendar, rooms[result[i].id]);
+ if (result && result.constructor === Array) {
+ var l = result.length;
+ for (var i = 0; i < l; i++) {
+ updateCalendar(result[i].calendar, rooms[result[i].id]);
+ }
}
-
-
}, error: function () {
-
+ // Retry in 5 minutes (300 seconds)
+ lastCalendarUpdate = MyDate().getTime() + globalConfig.calupdate + 300000;
}
});
}
+ const SEVEN_DAYS = 7 * 86400 * 1000;
+
/**
* applays new calendar data to the calendar plugin and also saves it to the room object
- * @param json Calendar data JSON
+ * @param {Array} json Calendar data
* @param room Room Object
*/
function updateCalendar(json, room) {
-
- if (!json) {
- console.log("Error: Calendar data was an empty string.");
+ if (!room) {
+ console.log("Error: No room for calendar data");
+ return;
+ }
+ if (!json || json.constructor !== Array) {
+ console.log("Error: Calendar data was empty or malformed.");
return;
}
+ var now = MyDate().getTime();
+ json = json.filter(function (el) {
+ if (!el.title || !el.start || !el.end) return false;
+ var s = new Date(el.start).getTime();
+ var e = new Date(el.end).getTime();
+ if (isNaN(s) || isNaN(e) || Math.abs(s - now) > SEVEN_DAYS || Math.abs(e - now) > SEVEN_DAYS) return false;
+ return true;
+ });
+ if (json.length === 0) {
+ console.log('Notice: Calendar has no current events for ' + room.name);
+ }
try {
room.timetable = json;
- if (room.config.mode != 3) {
+ if (room.config.mode !== 3) {
+ // TODO: Check if they're the same
var cal = $('#calendar_' + room.id);
- cal.weekCalendar("option", "data", json);
+ cal.weekCalendar('option', 'data', {events: json});
cal.weekCalendar("refresh");
cal.weekCalendar("option", "defaultFreeBusy", {free: false});
cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
}
- ComputeCurrentState(room);
+ room.state = null;
+ UpdateRoomHeader(room);
} catch (e) {
console.log("Error: Couldnt add calendar data");
console.log(e);
@@ -963,37 +935,33 @@ optional:
* @param room Room Object
*/
function scaleCalendar(room) {
- if (room.config.mode == 3) {
+ if (room.config.mode === 3) {
return;
}
- if (room.openTimes == null) {
- room.openTimes = 24;
- }
var cal = $('#calendar_' + room.id);
var columnWidth = document.getElementById("calendar_" + room.id).getElementsByClassName("wc-day-1")[0].clientWidth;
if (room.config.scaledaysauto) {
var result = (cal.weekCalendar("option", "daysToShow") * columnWidth) / 100;
result = parseInt(Math.min(Math.max(Math.abs(result), 1), 7));
- if (result != parseInt(cal.weekCalendar("option", "daysToShow"))) {
-
- cal.weekCalendar("option", "daysToShow", Math.abs(result));
+ if (result !== cal.weekCalendar("option", "daysToShow")) {
+ cal.weekCalendar("option", "daysToShow", result);
}
}
- if (((!room.config.scaledaysauto) || cal.weekCalendar("option", "daysToShow") == 1) && columnWidth < 85) {
+ if (((!room.config.scaledaysauto) || cal.weekCalendar("option", "daysToShow") === 1) && columnWidth < 85) {
cal.weekCalendar("option", "useShortDayNames", true);
} else {
cal.weekCalendar("option", "useShortDayNames", false);
}
var clientHeight = $(window).height();
- if (roomsToshow == 4) {
+ if (roomIds.length === 4) {
clientHeight = clientHeight / 2;
}
clientHeight = clientHeight - document.getElementById('header_' + room.id).clientHeight
- document.getElementsByClassName("wc-time-column-header")[0].clientHeight - 2;
- if (room.config.mode == 1 && room.config.vertical) {
+ if (room.config.mode === 1 && room.config.vertical) {
clientHeight = clientHeight * (room.config.scale / 100);
clientHeight -= 22;
@@ -1021,7 +989,11 @@ optional:
cal.weekCalendar("option", "textSize", 13);
}
cal.weekCalendar("option", "timeslotHeight", height);
- if (room.openingTimesCalendar != null) {
+ if (room.timetable) {
+ cal.weekCalendar("option", "data", {events: room.timetable});
+ cal.weekCalendar('refresh');
+ }
+ if (room.openingTimesCalendar) {
cal.weekCalendar("updateFreeBusy", room.openingTimesCalendar);
}
cal.weekCalendar("resizeCalendar");
@@ -1032,13 +1004,13 @@ optional:
/**
* used for countdown
* computes the time difference between 2 Date objects
- * @param a Date Object
- * @param b Date Object
+ * @param {Date} a
+ * @param {Date} b
* @param room Room Object
* @returns time string
*/
function GetTimeDiferenceAsString(a, b, room) {
- if (a == null || b == null) {
+ if (!a || !b) {
return "";
}
var milliseconds = a.getTime() - b.getTime();
@@ -1055,7 +1027,7 @@ optional:
if (minutes < 10) {
minutes = "0" + minutes;
}
- if (days != 0) {
+ if (days !== 0) {
// dont show?
return "";
}
@@ -1071,35 +1043,28 @@ optional:
* @returns Date Object of next closing
*/
function GetNextClosing(room) {
- var now = new MyDate();
+ var now = MyDate();
var day = now.getDay();
- var offset = 0;
- var bestdate;
+ var bestdate = false;
for (var a = 0; a < 7; a++) {
- var tmp = room.openingTimes[day];
- if (tmp != null) {
- for (var i = 0; i < tmp.length; i++) {
- var closeDate = new MyDate();
- closeDate.setDate(now.getDate() + offset);
- closeDate.setHours(tmp[i].HourClose);
- closeDate.setMinutes(tmp[i].MinutesClose);
- closeDate.setSeconds(0);
- if (closeDate > now) {
- if (!IsOpen(new Date(closeDate.getTime() + 60000), room)) {
- if (bestdate == null || bestdate > closeDate) {
- bestdate = closeDate;
- }
+ var tmp = room.openingTimes[(day + a) % 7];
+ if (!tmp) continue;
+ for (var i = 0; i < tmp.length; i++) {
+ var closeDate = getNextDayOfWeek(now, (day + a) % 7);
+ closeDate.setHours(tmp[i].HourClose);
+ closeDate.setMinutes(tmp[i].MinutesClose);
+ closeDate.setSeconds(0);
+ if (closeDate > now) {
+ if (!IsOpen(new Date(closeDate.getTime() + 1800000), room)) {
+ if (!bestdate || bestdate > closeDate) {
+ bestdate = closeDate;
}
}
}
}
- offset++;
- day++;
- if (day > 6) {
- day = 0;
- }
+ if (bestdate) return bestdate;
}
- return bestdate;
+ return null;
}
@@ -1110,18 +1075,14 @@ optional:
* @returns bool for open or not
*/
function IsOpen(date, room) {
- if (room.openingTimes == null) {
- return false;
- }
+ if (!room.openingTimes) return false;
var tmp = room.openingTimes[date.getDay()];
- if (tmp == null) {
- return false;
- }
+ if (!tmp) return false;
+ var openDate = new Date(date.getTime());
+ var closeDate = new Date(date.getTime());
for (var i = 0; i < tmp.length; i++) {
- var openDate = new MyDate();
openDate.setHours(tmp[i].HourOpen);
openDate.setMinutes(tmp[i].MinutesOpen);
- var closeDate = new MyDate();
closeDate.setHours(tmp[i].HourClose);
closeDate.setMinutes(tmp[i].MinutesClose);
if (openDate < date && closeDate > date) {
@@ -1138,37 +1099,28 @@ optional:
* @returns bestdate Date Object of next opening
*/
function GetNextOpening(room) {
- var now = new MyDate();
+ if (!room.openingTimes) return null;
+ var now = MyDate();
var day = now.getDay();
- var offset = 0;
- var bestdate;
- for (var a = 0; a < 7; a++) {
- if (room.openingTimes == null) {
- return null;
- }
- var tmp = room.openingTimes[day];
- if (tmp != null) {
- for (var i = 0; i < tmp.length; i++) {
- var openDate = new MyDate();
- openDate.setDate(now.getDate() + offset);
- openDate.setHours(tmp[i].HourOpen);
- openDate.setMinutes(tmp[i].MinutesOpen);
- if (openDate > now) {
- if (!IsOpen(new Date(openDate.getTime() - 60000), room)) {
- if (bestdate == null || bestdate > openDate) {
- bestdate = openDate;
- }
+ var bestdate = false;
+ for (var dow = 0; dow < 7; dow++) {
+ var tmp = room.openingTimes[(day + dow) % 7];
+ if (!tmp) continue;
+ for (var i = 0; i < tmp.length; i++) {
+ var openDate = getNextDayOfWeek(now, (day + dow) % 7);
+ openDate.setHours(tmp[i].HourOpen);
+ openDate.setMinutes(tmp[i].MinutesOpen);
+ if (openDate > now) {
+ if (!IsOpen(new Date(openDate.getTime() - 1800000), room)) {
+ if (!bestdate || bestdate > openDate) {
+ bestdate = openDate;
}
}
}
}
- offset++;
- day++;
- if (day > 6) {
- day = 0;
- }
+ if (bestdate) return bestdate;
}
- return bestdate;
+ return null;
}
@@ -1181,7 +1133,7 @@ optional:
if (seats > 0) {
$("#freeSeatsHeader_" + id).text(seats);
$("#square_" + id).css('background-color', '#00dd10');
- } else if (seats == -1) {
+ } else if (seats === -1) {
$("#freeSeatsHeader_" + id).text("");
$("#square_" + id).css('background-color', 'red');
} else {
@@ -1196,16 +1148,16 @@ optional:
*/
function UpdateRoomHeader(room) {
var tmp = room.getState();
- if (tmp.state == "closed") {
- $("#courseHeading_" + room.id).text(t("closed", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, new MyDate(), room));
+ if (tmp.state === "closed") {
+ $("#courseHeading_" + room.id).text(t("closed", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, MyDate(), room));
SetFreeSeats(room.id, room.freePcs);
- } else if (tmp.state == "ClaendarEvent") {
+ } else if (tmp.state === "CalendarEvent") {
$("#courseHeading_" + room.id).text(tmp.title);
SetFreeSeats(room.id, -1);
- } else if (tmp.state == "Free") {
- $("#courseHeading_" + room.id).text(t("free", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, new MyDate(), room));
+ } else if (tmp.state === "Free") {
+ $("#courseHeading_" + room.id).text(t("free", room.config.language) + " " + GetTimeDiferenceAsString(tmp.end, MyDate(), room));
SetFreeSeats(room.id, room.freePcs);
- } else if (tmp.state == "FreeNoEnd") {
+ } else if (tmp.state === "FreeNoEnd") {
$("#courseHeading_" + room.id).text(t("free", room.config.language));
SetFreeSeats(room.id, room.freePcs);
}
@@ -1213,11 +1165,11 @@ optional:
/**
* computes state of a room, states are:
- * closed, FreeNoEnd, Free, ClaendarEvent.
- * @param Room Object
+ * closed, FreeNoEnd, Free, CalendarEvent.
+ * @param room Object
*/
function ComputeCurrentState(room) {
- if (!IsOpen(new MyDate(), room)) {
+ if (!IsOpen(MyDate(), room)) {
room.state = {state: "closed", end: GetNextOpening(room), title: "", next: ""};
return;
@@ -1227,25 +1179,25 @@ optional:
var event = getNextEvent(room.timetable);
// no event and no closing
- if (closing == null && event == null) {
+ if (!closing && !event) {
room.state = {state: "FreeNoEnd", end: "", title: "", next: ""};
return;
}
// no event so closing is next
- if (event == null) {
+ if (!event) {
room.state = {state: "Free", end: closing, title: "", next: "closing"};
return;
}
// event is at the moment
- if ((closing == null || event.start.getTime() < closing.getTime()) && event.start.getTime() < new MyDate()) {
- room.state = {state: "ClaendarEvent", end: event.end, title: event.title, next: ""};
+ if ((!closing || event.start.getTime() < closing.getTime()) && event.start.getTime() < MyDate()) {
+ room.state = {state: "CalendarEvent", end: event.end, title: event.title, next: ""};
return;
}
// no closing so event is next
- if (closing == null) {
+ if (!closing) {
room.state = {state: "Free", end: event.start, title: "", next: "event"};
return;
}
@@ -1253,7 +1205,7 @@ optional:
// event sooner then closing
if (event.start.getTime() < closing) {
room.state = {state: "Free", end: event.start, title: "", next: "event"};
- } else if (event.start.getTime() > closing) {
+ } else {
room.state = {state: "Free", end: closing, title: "", next: "closing"};
}
@@ -1262,40 +1214,40 @@ optional:
/**
* returns next event from a given json of events
- * @param json Json which contains the calendar data.
+ * @param calEvents Json which contains the calendar data.
* @returns event next Carlendar Event
*/
- function getNextEvent(json) {
- var event;
- var now = new MyDate();
- if (json == null) {
- return;
+ function getNextEvent(calEvents) {
+ if (!calEvents) return null;
+ if (calEvents.constructor !== Array) {
+ console.log('getNextEvent called with something not array: ' + typeof(calEvents));
+ return null;
}
- for (var i = 0; i < json.length; i++) {
+ var event;
+ var now = MyDate();
+ for (var i = 0; i < calEvents.length; i++) {
//event is now active
- if (json[i].start.getTime() < now.getTime() && json[i].end.getTime() > now.getTime()) {
- return json[i];
+ if (calEvents[i].start.getTime() < now.getTime() && calEvents[i].end.getTime() > now.getTime()) {
+ return calEvents[i];
}
//first element to consider
- if (event == null) {
- if (json[i].start.getTime() > now.getTime()) {
- event = json[i];
+ if (!event) {
+ if (calEvents[i].start.getTime() > now.getTime()) {
+ event = calEvents[i];
}
- }
- if (json[i].start.getTime() > now.getTime() && event.start.getTime() > json[i].start.getTime()) {
- event = json[i];
+ } else if (calEvents[i].start.getTime() > now.getTime() && event.start.getTime() > calEvents[i].start.getTime()) {
+ event = calEvents[i];
}
}
return event;
}
+ /**
+ * Skip to next upcoming day matching the given day of week.
+ */
function getNextDayOfWeek(date, dayOfWeek) {
- // Code to check that date and dayOfWeek are valid left as an exercise ;)
-
var resultDate = new Date(date.getTime());
-
resultDate.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);
-
return resultDate;
}
/*
@@ -1315,13 +1267,12 @@ optional:
var div = document.createElement("div");
div.id = "roomLayout_" + room.id;
div.className = "roomLayoutDesign";
- if ((room.config.vertical && room.config.mode == 1) || (room.config.mode == 3) || (room.config.mode == 4)) {
+ if ((room.config.vertical && room.config.mode === 1) || (room.config.mode === 3) || (room.config.mode === 4)) {
width = 100 + "%";
- $(div).css('float', "none");
}
div.style.width = width;
- if (room.config.mode == 4) {
+ if (room.config.mode === 4) {
div.style.display = "none";
}
//document.body.appendChild(div);
@@ -1329,76 +1280,41 @@ optional:
}
- /**
- * Donwloads Room Layout Json (which contains the pc information for a given room)
- * @param room Room Object
- */
- function preInitRoom(room) {
-
- $.getJSON("../../../api.php?do=locationinfo&action=locationinfo&id=" + room.id + "&coords=1", function (result) {
-
- generateRoomLayoutDiv((100 - room.config.scale) + "%", room);
- if (result && result[0] && result[0].computer) {
- initRoom(result[0].computer, room);
- } else {
- initRoom([], room);
- }
-
- }).error(function () {
-
- generateRoomLayoutDiv((100 - room.config.scale) + "%", room);
-
- })
- }
-
/**
- * Main funciton for generating the Room Layout
+ * Main function for generating the Room Layout
* @param layout Layout Json
* @param room Room Object
*/
- function initRoom(layout, room) {
- var maxX;
- var maxY;
- var minY;
- var minX;
- var xDifference;
- var yDifference;
- room.layout = layout;
- if (layout == null || layout.length == 0) {
+ function initRoomLayout(room) {
+ var maxX = false, maxY = false;
+ var minX = false, minY = false;
+ var xDifference, yDifference;
+ var x, y;
+
+ generateRoomLayoutDiv((100 - globalConfig.scale) + "%", room);
+ var layout = room.layout;
+ if (layout === null || !layout.length) {
return;
}
- if (room.config.rotation != 0) {
- rotateRoom(room.config.rotation, layout);
- }
+ rotateRoom(globalConfig.rotation, layout);
for (var i = 0; i < layout.length; i++) {
- if (!isNaN(parseInt(layout[i].x)) && !isNaN(parseInt(layout[i].y)) && layout[i].y != null && layout[i].y != null) {
- if (minX === undefined) {
- minX = parseInt(layout[i].x);
- }
- if (minY === undefined) {
- minY = parseInt(layout[i].y);
- }
- if (maxX === undefined) {
- maxX = parseInt(layout[i].x);
- }
- if (maxY === undefined) {
- maxY = parseInt(layout[i].y);
- }
- if (parseInt(layout[i].x) < parseInt(minX)) {
- minX = parseInt(layout[i].x);
- }
- if (parseInt(layout[i].y) < parseInt(minY)) {
- minY = parseInt(layout[i].y);
- }
- if (parseInt(layout[i].x) > parseInt(maxX)) {
- maxX = parseInt(layout[i].x);
- }
- if (parseInt(layout[i].y) > parseInt(maxY)) {
- maxY = parseInt(layout[i].y);
- }
+ x = layout[i].x = parseInt(layout[i].x);
+ y = layout[i].y = parseInt(layout[i].y);
+ if (isNaN(x) || isNaN(y)) continue;
+ if (minX === false || x < minX) {
+ minX = x;
+ }
+ if (minY === false || y < minY) {
+ minY = y;
+ }
+ if (maxX === false || x > maxX) {
+ maxX = x;
+ }
+ if (maxY === false || y > maxY) {
+ maxY = y;
}
}
@@ -1426,17 +1342,17 @@ optional:
function generateOffsetAndScale(room) {
var clientHeight = $(window).height();
- if (roomsToshow == 4) {
+ if (roomIds.length === 4) {
clientHeight = clientHeight / 2;
}
clientHeight = clientHeight - document.getElementById('header_' + room.id).clientHeight - 5;
- if (roomsToshow > 1) {
+ if (roomIds.length > 1) {
clientHeight -= 5;
}
- if (room.config.vertical && room.config.mode == 1) {
- clientHeight = clientHeight * (1 - (room.config.scale / 100));
+ if (globalConfig.vertical && globalConfig.mode === 1) {
+ clientHeight = clientHeight * (1 - (globalConfig.scale / 100));
}
var roomLayout = document.getElementById('roomLayout_' + room.id);
@@ -1444,13 +1360,13 @@ optional:
//roomLayout.style.height = clientHeight + "px";
var scaleX;
- if (room.xDifference != 0) {
+ if (room.xDifference !== 0) {
scaleX = clientWidth / room.xDifference;
} else {
scaleX = clientWidth;
}
var scaleY;
- if (room.yDifference != 0) {
+ if (room.yDifference !== 0) {
scaleY = clientHeight / room.yDifference;
} else {
scaleY = clientHeight;
@@ -1464,9 +1380,7 @@ optional:
scaleXs = 9999;
}
-
- var tmp = [scaleYs, scaleY, scaleXs, scaleX, (clientHeight * 0.9) / picSizeY, (clientWidth * 0.9) / picSizeX];
- room.scale = Math.min.apply(Math, tmp);
+ room.scale = Math.min(scaleYs, scaleY, scaleXs, scaleX, (clientHeight * 0.9) / picSizeY, (clientWidth * 0.9) / picSizeX);
room.xOffset = 0 - room.minX;
room.yOffset = 0 - room.minY;
room.xOffset += ((1 / 2 * (clientWidth - (((room.maxX + room.xOffset) * room.scale) + picSizeX * room.scale))) / room.scale);
@@ -1481,8 +1395,7 @@ optional:
*/
function setUpRoom(room, layout) {
for (var i = 0; i < layout.length; i++) {
-
- if (layout[i].y != null && layout[i].x != null && !isNaN(layout[i].y) && !isNaN(layout[i].x)) {
+ if (!isNaN(layout[i].y) && !isNaN(layout[i].x)) {
var text = "<div class= 'PCImgDiv' id ='layout_PC_div_" + room.id + "_" + layout[i].id + "'>" +
"<div class= 'OverlayDiv' id ='layout_PC_overlay_" + room.id + "_" + layout[i].id + "'>" +
@@ -1491,7 +1404,7 @@ optional:
"</div>";
$('#roomLayout_' + room.id).append(text);
- if (layout[i].hasOwnProperty('overlay')) {
+ if (layout[i].overlay && layout[i].overlay.constructor === Array) {
for (var a = 0; a < layout[i].overlay.length; a++) {
addOverlay($('#layout_PC_overlay_' + room.id + "_" + layout[i].id), layout[i].overlay[a]);
}
@@ -1515,15 +1428,10 @@ optional:
}
}
- if (imgname == null) {
- return;
- }
- var text = $("<img class='overlay' src='" + imgname + "'></img>");
- text.addClass("overlay-" + overlayName);
-
- object.append(text);
-
-
+ if (!imgname) return; // No image found on server, do nothing
+ var $text = $("<img>");
+ $text.addClass('overlay').attr('src', imgname).addClass("overlay-" + overlayName);
+ object.append($text);
}
@@ -1538,7 +1446,7 @@ optional:
var http = new XMLHttpRequest();
http.open('HEAD', image_url, false);
http.send();
- imgExists[image_url] = http.status != 404;
+ imgExists[image_url] = http.status === 200;
}
return imgExists[image_url];
@@ -1546,22 +1454,79 @@ optional:
/**
* Querys Pc states
- * @param ids Room ID's which should be queried. Format for e.g.: "20,5,6"
*/
- function queryRooms(ids) {
+ function queryRooms() {
$.ajax({
- url: "../../../api.php?do=locationinfo&action=locationinfo&id=" + ids + "&coords=0",
+ url: "../../../api.php?do=locationinfo&get=machines&uuid=" + panelUuid,
dataType: 'json',
cache: false,
timeout: 30000,
success: function (result) {
+ if (!result || result.constructor !== Array) {
+ console.log('Warning: get=machines didnt return array');
+ return;
+ }
for (var i = 0; i < result.length; i++) {
- UpdatePc(result[i].computer, rooms[result[i].id]);
+ UpdatePc(result[i].machines, rooms[result[i].id]);
}
}
})
}
+ /**
+ * Updates the PC's (images) in the room layout. Also Updates how many pc's are free.
+ * @param update Update Json from query for one(!) room
+ * @param room Room object
+ */
+ function UpdatePc(update, room) {
+ if (!room) {
+ console.log('Got room update for unknown room, ignored.');
+ return;
+ }
+ if (!update || update.constructor !== Array) {
+ console.log('Update data is not array for room ' + room.name);
+ console.log(update);
+ return;
+ }
+ var freePcs = 0;
+ for (var i = 0; i < update.length; i++) {
+ var $imgobj = $("#layout_PC_" + room.id + "_" + update[i].id);
+
+ var img;
+ var color;
+ // Pc free
+ if (update[i].pcState === "IDLE") {
+ img = "img/pc_free";
+ color = 'green';
+ freePcs++;
+ // Pc in use
+ } else if (update[i].pcState === "OCCUPIED") {
+ img = "img/pc_used";
+ color = 'red';
+ // PC off
+ } else if (update[i].pcState === "OFF") {
+ img = "img/pc_off";
+ color = 'black';
+ freePcs++;
+ // Must be defect
+ } else {
+ img = "img/pc_defect";
+ color = 'black';
+ }
+
+ if (supportSvg) {
+ if (room.config.eco) {
+ img = img + "_eink";
+ }
+ $imgobj.attr('src', img + ".svg");
+ } else {
+ $imgobj.css('background-color', color);
+ }
+
+ }
+ room.freePcs = freePcs;
+ UpdateRoomHeader(room);
+ }
/**
* Adjust pc coordinate depending on room rotation
@@ -1584,112 +1549,46 @@ optional:
* @param room Room object
*/
function scaleRoom(room) {
- if (room.layout == null) {
- return;
- }
for (var i = 0; i < room.layout.length; i++) {
- if (room.layout[i].y != null && room.layout[i].x != null && !isNaN(room.layout[i].y) && !isNaN(room.layout[i].x)) {
+ if (!isNaN(room.layout[i].y) && !isNaN(room.layout[i].x)) {
var tmp = document.getElementById("layout_PC_div_" + room.id + "_" + room.layout[i].id);
- var img = document.getElementById("layout_PC_" + room.id + "_" + room.layout[i].id);
- if (tmp != null) {
+ if (tmp) {
tmp.style.width = (picSizeX * room.scale);
tmp.setAttribute("style", "width:" + (picSizeX * room.scale) + "px");
tmp.style.height = (picSizeY * room.scale) + "px";
- tmp.style.left = ((parseInt(room.layout[i].x) + room.xOffset) * room.scale) + "px";
- tmp.style.top = ((parseInt(room.layout[i].y) + room.yOffset) * room.scale ) + "px";
- }
- }
- }
- }
-
-
- /**
- * Updates the PC's (images) in the room layout. Also Updates how many pc's are free.
- * @param update Update Json from query for one(!) room
- * @param room Room object
- */
- function UpdatePc(update, room) {
- if (update === undefined || update == null) {
- return;
- }
- var freePcs = 0;
- for (var i = 0; i < update.length; i++) {
- var imgobj = document.getElementById("layout_PC_" + room.id + "_" + update[i].id);
-
-
- var img;
- // Pc free
- if (update[i].pcState == "IDLE") {
- if (supportSvg) {
- img = "img/pc_free";
- } else {
- imgobj.style.backgroundColor = "green";
- }
- freePcs++;
- // Pc in use
- } else if (update[i].pcState == "OCCUPIED") {
- if (supportSvg) {
- img = "img/pc_used";
- } else {
- imgobj.style.backgroundColor = "red";
- }
- // PC off
- } else if (update[i].pcState == "OFF") {
- if (supportSvg) {
- img = "img/pc_off";
- } else {
- imgobj.style.backgroundColor = "black";
- }
- freePcs++;
- } else {
- if (supportSvg) {
- img = "img/pc_defect";
- } else {
- imgobj.style.backgroundColor = "black";
- }
- }
-
- if (imgobj != null && supportSvg) {
- if (room.config.eco) {
- img = img + "_eink";
+ tmp.style.left = ((room.layout[i].x + room.xOffset) * room.scale) + "px";
+ tmp.style.top = ((room.layout[i].y + room.yOffset) * room.scale) + "px";
}
- imgobj.src = img + ".svg";
}
-
}
-
- room.freePcs = freePcs;
-
-
}
/*
/========================================== Misc =============================================
*/
- var resizeTimeout;
+ var resizeTimeout = false;
// called when browser window changes size
// scales calendar and room layout acordingly
$(window).resize(function () {
- clearTimeout(resizeTimeout);
+ if (resizeTimeout) clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function () {
-
+ resizeTimeout = false;
for (var property in rooms) {
-
rooms[property].resized = true;
- if (rooms[property].config.mode != null) {
- if (rooms[property].config.mode != 3) {
+ if (rooms[property].config.mode !== null) {
+ if (rooms[property].config.mode !== 3) {
scaleCalendar(rooms[property]);
-
}
- if (rooms[property].config.mode != 2) {
+ if (rooms[property].config.mode !== 2) {
generateOffsetAndScale(rooms[property]);
scaleRoom(rooms[property]);
}
}
}
- }, 50);
+ SetProgressBarSpeed();
+ }, 200);
});
@@ -1724,8 +1623,8 @@ optional:
function t(toTranslate, lang) {
var r;
- if (lang === undefined) {
- r = translation['en'][toTranslate];
+ if (!lang || !translation[lang] || !translation[lang][toTranslate]) {
+ r = translation['en'][toTranslate] || 'missing';
} else {
r = translation[lang][toTranslate];
}
@@ -1737,63 +1636,69 @@ optional:
* Used in Mode 4, switches given room from Timetable to Roomlayout and vice versa
* @param room
*/
- function switchLayout(room) {
- var car = document.getElementById("calendar_" + room.id);
- var roomLayout = document.getElementById("roomLayout_" + room.id);
-
- if (car.style.display == "none") {
- roomLayout.style.display = "none";
- car.style.display = "block";
- if (room.resized) {
- scaleCalendar(room);
- room.resized = false;
- }
- } else {
- car.style.display = "none";
- roomLayout.style.display = "block";
- if (room.resized) {
- generateOffsetAndScale(room);
- scaleRoom(room);
- room.resized = false;
+ function switchLayouts() {
+ for (var roomKey in rooms) {
+ var room = rooms[roomKey];
+ if (room.config.mode !== 4) continue;
+ var car = document.getElementById("calendar_" + room.id);
+ var roomLayout = document.getElementById("roomLayout_" + room.id);
+
+ if (car.style.display === "none") {
+ roomLayout.style.display = "none";
+ car.style.display = "block";
+ if (room.resized) {
+ scaleCalendar(room);
+ room.resized = false;
+ }
+ } else {
+ car.style.display = "none";
+ roomLayout.style.display = "block";
+ if (room.resized) {
+ generateOffsetAndScale(room);
+ scaleRoom(room);
+ room.resized = false;
+ }
}
}
+ lastSwitchTime = MyDate().getTime();
}
+ var $pbar = false;
+ var pbarTimer = false;
+ const PX_PER_SEC_TARGET = 10;
/**
- * adds a progressbar to a given room (id) used in mode 4
- * @param id room id
- */
- function generateProgressBar(id) {
-
- var div = document.createElement("div");
- div.id = "progressBar_" + id;
- div.classList.add("progressbar");
- //document.body.appendChild(div);
- $("#room_" + id).append(div);
-
- }
- /**
- * Animates the progressbar used in mode 4
- * @param roomId
- * @param time
- * @constructor
+ * adds a progressbar (id) used in mode 4
*/
- function MoveProgressBar(roomId, time) {
- var elem = document.getElementById("progressBar_" + roomId);
- var width = 1;
- var id = setInterval(frame, time / 100);
-
- function frame() {
+ function generateProgressBar() {
+ if ($pbar) return;
+ $pbar = $('<div id="progressBar" class="progressbar">');
+ $('body').append($pbar);
+ SetProgressBarSpeed()
+ }
+
+ function SetProgressBarSpeed() {
+ if (!$pbar || !globalConfig.switchtime) return;
+ if (pbarTimer) clearInterval(pbarTimer);
+ var pxPerMSec = $('body').width() / globalConfig.switchtime;
+ var interval = Math.max(1 / (pxPerMSec / PX_PER_SEC_TARGET), 100);
+ pbarTimer = setInterval(function () {
+ var width = ((MyDate().getTime() - lastSwitchTime) / globalConfig.switchtime) * 100;
+ if (width < 0) width = 0;
if (width >= 100) {
- clearInterval(id);
- } else {
- width++;
- elem.style.width = width + '%';
+ width = 100;
+ switchLayouts();
}
- }
+ $pbar.width(width + '%');
+ }, interval);
}
+ function toInt(str) {
+ var t = typeof str;
+ if (t === 'number') return str | 0;
+ if (t === 'string') return parseInt(str.replace(/^0+([^0])/, '$1'));
+ return NaN;
+ }
</script>
</head>
diff --git a/modules-available/locationinfo/frontend/jquery-week-calendar/jquery.weekcalendar.js b/modules-available/locationinfo/frontend/jquery-week-calendar/jquery.weekcalendar.js
index 9d83afca..1d80118f 100755
--- a/modules-available/locationinfo/frontend/jquery-week-calendar/jquery.weekcalendar.js
+++ b/modules-available/locationinfo/frontend/jquery-week-calendar/jquery.weekcalendar.js
@@ -19,14 +19,18 @@
* If you're after a monthly calendar plugin, check out this one :
* http://arshaw.com/fullcalendar/
*/
-var startdate;
+var startdate = 0;
function SetUpDate(d) {
- startdate = d.getTime()-new Date().getTime();
+ startdate = d.getTime() - new Date().getTime();
}
+/**
+ *
+ * @return {Date}
+ */
function MyDate() {
- return new Date(startdate +new Date().getTime());
+ return new Date(startdate + new Date().getTime());
}
(function($) {
@@ -39,7 +43,7 @@ function MyDate() {
return {
options: {
- date: new MyDate(),
+ date: MyDate(),
timeFormat: null,
dateFormat: 'M d, Y',
alwaysDisplayTimeMinutes: true,
@@ -341,7 +345,7 @@ function MyDate() {
*/
today: function() {
this._clearCalendar();
- this._loadCalEvents(new MyDate());
+ this._loadCalEvents(MyDate());
},
/*
@@ -525,7 +529,7 @@ function MyDate() {
this._loadCalEvents(newDate);
},
getCurrentFirstDay: function() {
- return this._dateFirstDayOfWeek(this.options.date || new MyDate());
+ return this._dateFirstDayOfWeek(this.options.date || MyDate());
},
getCurrentLastDay: function() {
return this._addDays(this.getCurrentFirstDay(), this.options.daysToShow - 1);
@@ -1273,7 +1277,7 @@ function MyDate() {
*/
_drawCurrentHourLine: function() {
var self = this;
- var d = new MyDate(),
+ var d = MyDate(),
options = this.options,
businessHours = options.businessHours;
@@ -1958,6 +1962,7 @@ function MyDate() {
}
var $target = this.element.find('.wc-grid-timeslot-header .wc-hour-header:eq(' + slot + ')');
+ if ($target.length === 0) return;
$scrollable.animate({scrollTop: 0}, 0, function() {
var targetOffset = $target.offset().top;
@@ -2001,7 +2006,7 @@ function MyDate() {
_isToday: function(date) {
var clonedDate = this._cloneDate(date);
this._clearTime(clonedDate);
- var today = new MyDate();
+ var today = MyDate();
this._clearTime(today);
return today.getTime() === clonedDate.getTime();
},
diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php
index fa97a0c6..473804cc 100644
--- a/modules-available/locationinfo/inc/locationinfo.inc.php
+++ b/modules-available/locationinfo/inc/locationinfo.inc.php
@@ -11,14 +11,6 @@ class LocationInfo
*/
public static function getPcState($pc)
{
- /* pcState:
- * [0] = IDLE (NOT IN USE)
- * [1] = OCCUPIED (IN USE)
- * [2] = OFF
- * [3] = 10 days offline (BROKEN?)
- */
- // TODO USE STATE NAME instead of numbers
-
$logintime = (int)$pc['logintime'];
$lastseen = (int)$pc['lastseen'];
$lastboot = (int)$pc['lastboot'];
@@ -65,7 +57,7 @@ class LocationInfo
*
* @return array Return a default config.
*/
- public static function defaultPanelConfig()
+ public static function defaultPanelConfig($type)
{
return array(
'language' => 'en',
diff --git a/modules-available/locationinfo/page.inc.php b/modules-available/locationinfo/page.inc.php
index 996a5fa6..c3232b80 100644
--- a/modules-available/locationinfo/page.inc.php
+++ b/modules-available/locationinfo/page.inc.php
@@ -173,16 +173,17 @@ class Page_LocationInfo extends Page
}
}
- Database::exec("INSERT INTO `locationinfo_locationconfig` (locationid, serverid, serverlocationid, openingtime, lastcalendarupdate)
- VALUES (:id, :insertserverid, :serverlocationid, :openingtimes, 0)
+ Database::exec("INSERT INTO `locationinfo_locationconfig` (locationid, serverid, serverlocationid, openingtime, lastcalendarupdate, lastchange)
+ VALUES (:id, :insertserverid, :serverlocationid, :openingtimes, 0, :now)
ON DUPLICATE KEY UPDATE serverid = IF(:ignore_server AND serverid IS NULL, NULL, :serverid), serverlocationid = VALUES(serverlocationid),
- openingtime = VALUES(openingtime), lastcalendarupdate = 0", array(
+ openingtime = VALUES(openingtime), lastcalendarupdate = 0, lastchange = VALUES(lastchange)", array(
'id' => $locationid,
'insertserverid' => $insertServerId,
'serverid' => $serverid,
'openingtimes' => $openingtimes,
'serverlocationid' => $serverlocationid,
'ignore_server' => $ignoreServer,
+ 'now' => time(),
));
if (!$recursive)
@@ -196,10 +197,11 @@ class Page_LocationInfo extends Page
}
if (!empty($array)) {
Database::exec("UPDATE locationinfo_locationconfig
- SET serverid = :serverid, lastcalendarupdate = IF(serverid <> :serverid, 0, lastcalendarupdate)
+ SET serverid = :serverid, lastcalendarupdate = IF(serverid <> :serverid, 0, lastcalendarupdate), lastchange = :now
WHERE locationid IN (:locations)", array(
'serverid' => $serverid,
'locations' => $array,
+ 'now' => time(),
));
}
return true;
@@ -234,7 +236,6 @@ class Page_LocationInfo extends Page
}
// Build json struct
$conf = array(
- 'ts' => time(),
'language' => Request::post('language', 'en', 'string'),
'mode' => Request::post('mode', 1, 'int'),
'vertical' => Request::post('vertical', false, 'bool'),
@@ -260,11 +261,11 @@ class Page_LocationInfo extends Page
if ($paneluuid === 'new') {
$paneluuid = Util::randomUuid();
- $query = "INSERT INTO `locationinfo_panel` (paneluuid, panelname, locationids, paneltype, panelconfig)
- VALUES (:id, :name, :locationids, :type, :config)";
+ $query = "INSERT INTO `locationinfo_panel` (paneluuid, panelname, locationids, paneltype, panelconfig, lastchange)
+ VALUES (:id, :name, :locationids, :type, :config, :now)";
} else {
$query = "UPDATE `locationinfo_panel`
- SET panelname = :name, locationids = :locationids, paneltype = :type, panelconfig = :config
+ SET panelname = :name, locationids = :locationids, paneltype = :type, panelconfig = :config, lastchange = :now
WHERE paneluuid = :id";
}
Database::exec($query, array(
@@ -273,6 +274,7 @@ class Page_LocationInfo extends Page
'locationids' => implode(',', $locationids),
'type' => 'DEFAULT', // TODO
'config' => json_encode($conf),
+ 'now' => time(),
));
Message::addSuccess('config-saved');