summaryrefslogtreecommitdiffstats
path: root/modules-available
diff options
context:
space:
mode:
authorChristian Hofmaier2020-09-08 20:56:19 +0200
committerChristian Hofmaier2020-09-08 20:56:19 +0200
commitc535ce5e2f78f5223662c97543f718334abf2a35 (patch)
tree728fe2fcfe16e33757daeb086ba905c2f834118e /modules-available
parent[locationinfo] Fix overriding "show hostnames" not being saved (diff)
downloadslx-admin-c535ce5e2f78f5223662c97543f718334abf2a35.tar.gz
slx-admin-c535ce5e2f78f5223662c97543f718334abf2a35.tar.xz
slx-admin-c535ce5e2f78f5223662c97543f718334abf2a35.zip
[locations] Migrate openingtimes from infoscreen to locations module
- move openingtimes from infoscreen db to locations db - read-only openingtimes in infoscreen
Diffstat (limited to 'modules-available')
-rw-r--r--modules-available/locationinfo/inc/infopanel.inc.php2
-rw-r--r--modules-available/locationinfo/install.inc.php3
-rw-r--r--modules-available/locationinfo/lang/de/template-tags.json2
-rw-r--r--modules-available/locationinfo/lang/en/template-tags.json2
-rw-r--r--modules-available/locationinfo/page.inc.php97
-rw-r--r--modules-available/locationinfo/templates/ajax-config-location.html93
-rw-r--r--modules-available/locationinfo/templates/page-locations.html27
-rw-r--r--modules-available/locations/clientscript.js153
-rw-r--r--modules-available/locations/config.json8
-rw-r--r--modules-available/locations/install.inc.php22
-rw-r--r--modules-available/locations/lang/de/template-tags.json14
-rw-r--r--modules-available/locations/lang/en/template-tags.json14
-rw-r--r--modules-available/locations/pages/details.inc.php177
-rw-r--r--modules-available/locations/templates/ajax-opening-location.html173
-rw-r--r--modules-available/locations/templates/location-subnets.html44
-rw-r--r--modules-available/locations/templates/locations.html5
16 files changed, 674 insertions, 162 deletions
diff --git a/modules-available/locationinfo/inc/infopanel.inc.php b/modules-available/locationinfo/inc/infopanel.inc.php
index 001f31ea..af32c1ed 100644
--- a/modules-available/locationinfo/inc/infopanel.inc.php
+++ b/modules-available/locationinfo/inc/infopanel.inc.php
@@ -169,7 +169,7 @@ class InfoPanel
$allIds = self::getLocationsWithParents($idList);
if (empty($allIds))
return;
- $res = Database::simpleQuery("SELECT locationid, openingtime FROM locationinfo_locationconfig
+ $res = Database::simpleQuery("SELECT locationid, openingtime FROM location
WHERE locationid IN (:lids)", array('lids' => $allIds));
$openingTimes = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
diff --git a/modules-available/locationinfo/install.inc.php b/modules-available/locationinfo/install.inc.php
index 7e58315b..42bc8234 100644
--- a/modules-available/locationinfo/install.inc.php
+++ b/modules-available/locationinfo/install.inc.php
@@ -6,7 +6,6 @@ $t1 = $res[] = tableCreate('locationinfo_locationconfig', '
`locationid` INT(11) NOT NULL,
`serverid` INT(10) UNSIGNED,
`serverlocationid` VARCHAR(150),
- `openingtime` BLOB,
`calendar` BLOB,
`lastcalendarupdate` INT(10) UNSIGNED NOT NULL DEFAULT 0,
`lastuse` INT(10) UNSIGNED NOT NULL DEFAULT 0,
@@ -53,7 +52,7 @@ if ($t1 === UPDATE_NOOP) {
Database::exec('INSERT INTO locationinfo_panel (paneluuid, panelname, locationids, paneltype, panelconfig, lastchange)'
. " SELECT UUID(), Concat('Import: ', l.locationname), o.locationid, 'DEFAULT', o.config, 0 "
. " FROM locationinfo_locationconfig o INNER JOIN location l USING (locationid)"
- . ' WHERE Length(o.config) > 10 OR Length(o.openingtime) > 10');
+ . ' WHERE Length(o.config) > 10');
}
Database::exec("ALTER TABLE locationinfo_locationconfig CHANGE `serverid` `serverid` INT(10) UNSIGNED NULL");
tableDropColumn('locationinfo_locationconfig', 'hidden');
diff --git a/modules-available/locationinfo/lang/de/template-tags.json b/modules-available/locationinfo/lang/de/template-tags.json
index 2879184e..90a38885 100644
--- a/modules-available/locationinfo/lang/de/template-tags.json
+++ b/modules-available/locationinfo/lang/de/template-tags.json
@@ -55,7 +55,7 @@
"lang_locationSettings": "Raum-\/Ortsbezogene Einstellungen",
"lang_locations": "Orte",
"lang_locationsTable": "R\u00e4ume \/ Orte",
- "lang_locationsTableHints": "Hier k\u00f6nnen Sie f\u00fcr die R\u00e4ume und Orte Ihrer Einrichtung \u00d6ffnungszeiten hinterlegen, sowie die Verkn\u00fcpfung mit Raum-IDs aus konfigurierten Backends (z.B. HISinOne) vornehmen, damit Belegungspl\u00e4ne abgerufen werden k\u00f6nnen.",
+ "lang_locationsTableHints": "Hier k\u00f6nnen Sie f\u00fcr die R\u00e4ume und Orte Ihrer Einrichtung die Verkn\u00fcpfung mit Raum-IDs aus konfigurierten Backends (z.B. HISinOne) vornehmen, damit Belegungspl\u00e4ne abgerufen werden k\u00f6nnen.",
"lang_locsHint": "Hier k\u00f6nnen Sie die Orte ausw\u00e4hlen, die in diesem Panel angezeigt werden.",
"lang_longFri": "Freitag",
"lang_longMon": "Montag",
diff --git a/modules-available/locationinfo/lang/en/template-tags.json b/modules-available/locationinfo/lang/en/template-tags.json
index ba743dfb..64846ab6 100644
--- a/modules-available/locationinfo/lang/en/template-tags.json
+++ b/modules-available/locationinfo/lang/en/template-tags.json
@@ -55,7 +55,7 @@
"lang_locationSettings": "Location specific settings",
"lang_locations": "Locations",
"lang_locationsTable": "Rooms \/ Locations",
- "lang_locationsTableHints": "Here you can define opening times for your locations and link the location ID to a configured backend (e.g. HISinOne) to show calendar events.",
+ "lang_locationsTableHints": "Here you can link the location ID to a configured backend (e.g. HISinOne) to show calendar events.",
"lang_locsHint": "You can pick up the locations that will be shown in this panel.",
"lang_longFri": "Friday",
"lang_longMon": "Monday",
diff --git a/modules-available/locationinfo/page.inc.php b/modules-available/locationinfo/page.inc.php
index ee50bc9c..8032642d 100644
--- a/modules-available/locationinfo/page.inc.php
+++ b/modules-available/locationinfo/page.inc.php
@@ -167,101 +167,20 @@ class Page_LocationInfo extends Page
$ignoreServer = 0;
}
- // Opening times
- $openingtimes = Request::post('openingtimes', '', 'string');
- if ($openingtimes !== '') {
- $openingtimes = json_decode($openingtimes, true);
- if (!is_array($openingtimes)) {
- $openingtimes = '';
- } else {
- $mangled = array();
- foreach (array_keys($openingtimes) as $key) {
- $entry = $openingtimes[$key];
- if (!isset($entry['days']) || !is_array($entry['days']) || empty($entry['days'])) {
- Message::addError('ignored-line-no-days');
- continue;
- }
- $s = $this->getTime($entry['openingtime']);
- $e = $this->getTime($entry['closingtime']);
- if ($s === false) {
- Message::addError('ignored-invalid-start', $entry['openingtime']);
- continue;
- }
- if ($e === false) {
- Message::addError('ignored-invalid-end', $entry['closingtime']);
- continue;
- }
- if ($e <= $s) {
- Message::addError('ignored-invalid-range', $entry['openingtime'], $entry['closingtime']);
- continue;
- }
- unset($entry['tag']);
- $mangled[] = $entry;
- }
- if (empty($mangled)) {
- $openingtimes = null;
- } else {
- $openingtimes = json_encode($mangled);
- }
- }
- }
$NOW = time();
- // Check if openingtimes changed
- $res = Database::queryFirst('SELECT openingtime FROM locationinfo_locationconfig WHERE locationid = :locationid', compact('locationid'));
- $otChanged = $res === false || $res['openingtime'] !== $openingtimes;
- Database::exec("INSERT INTO `locationinfo_locationconfig` (locationid, serverid, serverlocationid, openingtime, lastcalendarupdate, lastchange)
- VALUES (:id, :insertserverid, :serverlocationid, :openingtimes, 0, :now)
+ Database::exec("INSERT INTO `locationinfo_locationconfig` (locationid, serverid, serverlocationid, lastcalendarupdate, lastchange)
+ VALUES (:id, :insertserverid, :serverlocationid, 0, :now)
ON DUPLICATE KEY UPDATE serverid = IF(:ignore_server AND serverid IS NULL, NULL, :serverid), serverlocationid = VALUES(serverlocationid),
- openingtime = VALUES(openingtime), lastcalendarupdate = 0, lastchange = VALUES(lastchange)", array(
+ lastcalendarupdate = 0, lastchange = VALUES(lastchange)", array(
'id' => $locationid,
'insertserverid' => $insertServerId,
'serverid' => $serverid,
- 'openingtimes' => $openingtimes,
'serverlocationid' => $serverlocationid,
'ignore_server' => $ignoreServer,
'now' => $NOW,
));
- if ($otChanged) {
- $tree = Location::getLocationsAssoc();
- $todo = array();
- $done = array();
- foreach ($tree as $l) {
- if ($l['parentlocationid'] == $locationid) {
- $todo[] = $l['locationid'];
- }
- }
- while (!empty($todo)) {
- $loc = array_pop($todo);
- if (in_array($loc, $done))
- continue;
- $done[] = $loc;
- // See if this one inherits
- $res = Database::queryFirst('SELECT openingtime FROM locationinfo_locationconfig WHERE locationid = :loc', compact('loc'));
- if ($res === false) {
- $res = Database::exec('INSERT INTO locationinfo_locationconfig (locationid, lastchange)
- VALUES (:locationid, :now) ON DUPLICATE KEY UPDATE lastchange = :now',
- array('locationid' => $loc, 'now' => $NOW));
- } elseif (strlen($res['openingtime']) < 5) {
- $res = Database::exec('UPDATE locationinfo_locationconfig SET lastchange = :now, openingtime = NULL
- WHERE locationid = :locationid',
- array('locationid' => $loc, 'now' => $NOW));
- } else {
- $res = 0;
- }
- if ($res > 0) {
- // Row was updated, which means the openingtime column was empty, which means the openingtime is inherited, descend further
- $todo = array_merge($todo, $tree[$loc]['children']);
- foreach ($tree as $l) {
- if ($l['parentlocationid'] == $loc) {
- $todo[] = $l['locationid'];
- }
- }
- }
- }
- }
-
if ($changeServerRecursive) {
// Recursive overwriting of serverid
$children = Location::getRecursiveFlat($locationid);
@@ -612,9 +531,10 @@ class Page_LocationInfo extends Page
$locations = Location::getLocations(0, 0, false, true);
// Get hidden state of all locations
- $dbquery = Database::simpleQuery("SELECT li.locationid, li.serverid, li.serverlocationid, li.openingtime, li.lastcalendarupdate, cb.servertype, cb.servername
+ $dbquery = Database::simpleQuery("SELECT li.locationid, li.serverid, li.serverlocationid, loc.openingtime, li.lastcalendarupdate, cb.servertype, cb.servername
FROM `locationinfo_locationconfig` AS li
- LEFT JOIN `locationinfo_coursebackend` AS cb USING (serverid)");
+ LEFT JOIN `locationinfo_coursebackend` AS cb USING (serverid)
+ LEFT JOIN `location` AS loc USING (locationid)");
while ($row = $dbquery->fetch(PDO::FETCH_ASSOC)) {
$locid = (int)$row['locationid'];
@@ -780,7 +700,10 @@ class Page_LocationInfo extends Page
private function ajaxConfigLocation($id)
{
User::assertPermission('location.edit', $id);
- $locConfig = Database::queryFirst("SELECT serverid, serverlocationid, openingtime FROM `locationinfo_locationconfig` WHERE locationid = :id", array('id' => $id));
+ $locConfig = Database::queryFirst("SELECT info.serverid, info.serverlocationid, loc.openingtime
+ FROM `locationinfo_locationconfig` AS info
+ LEFT JOIN `location` AS loc USING (locationid)
+ WHERE locationid = :id", array('id' => $id));
if ($locConfig !== false) {
$openingtimes = json_decode($locConfig['openingtime'], true);
} else {
diff --git a/modules-available/locationinfo/templates/ajax-config-location.html b/modules-available/locationinfo/templates/ajax-config-location.html
index 47d4ba8a..f7e96b9d 100644
--- a/modules-available/locationinfo/templates/ajax-config-location.html
+++ b/modules-available/locationinfo/templates/ajax-config-location.html
@@ -4,11 +4,7 @@
{{^expertMode}}
<div id="simple-mode">
- <div align="right">
- <a href="#" class="btn btn-default btn-sm" id="btn-show-expert">{{lang_expertMode}}</a>
- </div>
<div class="clearfix"></div>
-
<table class="table table-condensed" style="margin-bottom:0">
<tr>
<th>{{lang_day}}</th>
@@ -19,57 +15,57 @@
<tr class="tablerow">
<td>{{lang_monTilFr}}</td>
<td>
- <div class="input-group bootstrap-timepicker">
+ <div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
- <input type="text" class="form-control timepicker2" id="week-open" pattern="[0-9]{1,2}:[0-9]{2}">
+ <input disabled type="text" class="form-control timepicker2" id="week-open">
</div>
</td>
<td>
- <div class="input-group bootstrap-timepicker">
+ <div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
- <input type="text" class="form-control timepicker2" id="week-close" pattern="[0-9]{1,2}:[0-9]{2}">
+ <input disabled type="text" class="form-control timepicker2" id="week-close">
</div>
</td>
</tr>
<tr class="tablerow">
<td>{{lang_saturday}}</td>
<td>
- <div class="input-group bootstrap-timepicker">
+ <div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
- <input type="text" class="form-control timepicker2" id="saturday-open" pattern="[0-9]{1,2}:[0-9]{2}">
+ <input disabled type="text" class="form-control timepicker2" id="saturday-open">
</div>
</td>
<td>
- <div class="input-group bootstrap-timepicker">
+ <div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
- <input type="text" class="form-control timepicker2" id="saturday-close" pattern="[0-9]{1,2}:[0-9]{2}">
+ <input disabled type="text" class="form-control timepicker2" id="saturday-close">
</div>
</td>
</tr>
<tr class="tablerow">
<td>{{lang_sunday}}</td>
<td>
- <div class="input-group bootstrap-timepicker">
+ <div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
- <input type="text" class="form-control timepicker2" id="sunday-open" pattern="[0-9]{1,2}:[0-9]{2}">
+ <input disabled type="text" class="form-control timepicker2" id="sunday-open">
</div>
</td>
<td>
- <div class="input-group bootstrap-timepicker">
+ <div class="input-group">
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
- <input type="text" class="form-control timepicker2" id="sunday-close" pattern="[0-9]{1,2}:[0-9]{2}">
+ <input disabled type="text" class="form-control timepicker2" id="sunday-close">
</div>
</td>
</tr>
@@ -78,21 +74,15 @@
{{/expertMode}}
<div id="expert-mode" style="{{^expertMode}}display:none{{/expertMode}}">
- <div class="pull-right">
- <a class="btn btn-success btn-sm" id="new-openingtime">
- <span class="glyphicon glyphicon-plus-sign"></span>
- {{lang_openingTime}}
- </a>
- </div>
<div class="clearfix"></div>
<div id="expert-table">
<div class="row">
- <div class="col-xs-9">{{lang_day}}</div>
- <div class="col-xs-3 text-right">{{lang_delete}}</div>
<div class="col-sm-6">{{lang_openingTime}}</div>
- <div class="col-sm-6">{{lang_closingTime}}</div>
+ <div class="col-sm-4">{{lang_closingTime}}</div>
+ <div class="col-sm-2 text-right">{{lang_delete}}</div>
</div>
</div>
+ <hr>
</div>
</div>
@@ -105,7 +95,7 @@
<select id="backend-select" class="form-control" name="serverid">
<option value="0">{{lang_noServer}}</option>
{{#serverlist}}
- <option value="{{serverid}}" {{selected}}>{{servername}}</option>
+ <option value="{{serverid}}" {{selected}}>{{servername}}</option>
{{/serverlist}}
</select>
</div>
@@ -143,6 +133,33 @@
</div>
</div>
+<div class="hidden" id="expert-template">
+ <div class="row expert-row">
+ <hr>
+ <div class="col-xs-12 days-box">
+ <div class="checkbox checkbox-inline" style="margin-top: 0px;"><input disabled type="checkbox" class="i-Monday"><label>{{lang_shortMonday}}</label></div>
+ <div class="checkbox checkbox-inline"><input disabled type="checkbox" class="i-Tuesday"><label>{{lang_shortTuesday}}</label></div>
+ <div class="checkbox checkbox-inline"><input disabled type="checkbox" class="i-Wednesday"><label>{{lang_shortWednesday}}</label></div>
+ <div class="checkbox checkbox-inline"><input disabled type="checkbox" class="i-Thursday"><label>{{lang_shortThursday}}</label></div>
+ <div class="checkbox checkbox-inline"><input disabled type="checkbox" class="i-Friday"><label>{{lang_shortFriday}}</label></div>
+ <div class="checkbox checkbox-inline"><input disabled type="checkbox" class="i-Saturday"><label>{{lang_shortSaturday}}</label></div>
+ <div class="checkbox checkbox-inline"><input disabled type="checkbox" class="i-Sunday"><label>{{lang_shortSunday}}</label></div>
+ </div>
+ <div class="col-sm-6">
+ <div class="input-group">
+ <span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
+ <input disabled type="text" class="form-control i-openingtime">
+ </div>
+ </div>
+ <div class="col-sm-6">
+ <div class="input-group">
+ <span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
+ <input disabled type="text" class="form-control i-closingtime">
+ </div>
+ </div>
+ </div>
+</div>
+
<script type="application/javascript"><!--
(function() {
@@ -154,18 +171,18 @@
}
{{/expertMode}}
{{^expertMode}}
- for (var i = 0; i < scheduleData.length; ++i) {
- if (scheduleData[i].days.length === 5) {
- $('#week-open').val(scheduleData[i]['openingtime']);
- $('#week-close').val(scheduleData[i]['closingtime']);
- } else if (scheduleData[i].days.length === 1 && scheduleData[i].days[0] === 'Saturday') {
- $('#saturday-open').val(scheduleData[i]['openingtime']);
- $('#saturday-close').val(scheduleData[i]['closingtime']);
- } else if (scheduleData[i].days.length === 1 && scheduleData[i].days[0] === 'Sunday') {
- $('#sunday-open').val(scheduleData[i]['openingtime']);
- $('#sunday-close').val(scheduleData[i]['closingtime']);
- }
+ for (var i = 0; i < scheduleData.length; ++i) {
+ if (scheduleData[i].days.length === 5) {
+ $('#week-open').val(scheduleData[i]['openingtime']);
+ $('#week-close').val(scheduleData[i]['closingtime']);
+ } else if (scheduleData[i].days.length === 1 && scheduleData[i].days[0] === 'Saturday') {
+ $('#saturday-open').val(scheduleData[i]['openingtime']);
+ $('#saturday-close').val(scheduleData[i]['closingtime']);
+ } else if (scheduleData[i].days.length === 1 && scheduleData[i].days[0] === 'Sunday') {
+ $('#sunday-open').val(scheduleData[i]['openingtime']);
+ $('#sunday-close').val(scheduleData[i]['closingtime']);
}
+ }
{{/expertMode}}
setTimepicker($('#settings-outer').find('.timepicker2'));
@@ -175,7 +192,7 @@
$('#new-openingtime').click(function (e) {
e.preventDefault();
setTimepicker(newOpeningTime({}).find('.timepicker2'));
- })
+ });
$('#btn-show-expert').click(function (e) {
e.preventDefault();
diff --git a/modules-available/locationinfo/templates/page-locations.html b/modules-available/locationinfo/templates/page-locations.html
index f90a0f35..9635268c 100644
--- a/modules-available/locationinfo/templates/page-locations.html
+++ b/modules-available/locationinfo/templates/page-locations.html
@@ -65,33 +65,6 @@
</div>
</div>
-<div class="hidden" id="expert-template">
- <div class="row expert-row" style="margin-top:1em;border-top:1px solid #ddd">
- <div class="col-xs-12 days-box">
- <div class="pull-right checkbox checkbox-inline"><input type="checkbox" class="i-delete"><label><span class="glyphicon glyphicon-trash"></span></label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Monday"><label>{{lang_shortMonday}}</label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Tuesday"><label>{{lang_shortTuesday}}</label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Wednesday"><label>{{lang_shortWednesday}}</label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Thursday"><label>{{lang_shortThursday}}</label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Friday"><label>{{lang_shortFriday}}</label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Saturday"><label>{{lang_shortSaturday}}</label></div>
- <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Sunday"><label>{{lang_shortSunday}}</label></div>
- </div>
- <div class="col-sm-6">
- <div class="input-group bootstrap-timepicker">
- <span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
- <input type="text" class="form-control timepicker2 i-openingtime" pattern="[0-9]{1,2}:[0-9]{2}">
- </div>
- </div>
- <div class="col-sm-6">
- <div class="input-group bootstrap-timepicker">
- <span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
- <input type="text" class="form-control timepicker2 i-closingtime" pattern="[0-9]{1,2}:[0-9]{2}">
- </div>
- </div>
- </div>
-</div>
-
<script type="text/javascript"><!--
document.addEventListener("DOMContentLoaded", function () {
diff --git a/modules-available/locations/clientscript.js b/modules-available/locations/clientscript.js
new file mode 100644
index 00000000..25c255fb
--- /dev/null
+++ b/modules-available/locations/clientscript.js
@@ -0,0 +1,153 @@
+/*
+ * Generic helpers.
+ */
+
+/**
+ * Initialize timepicker on given element.
+ */
+function setTimepicker($e) {
+ $e.timepicker({
+ minuteStep: 15,
+ appendWidgetTo: 'body',
+ showSeconds: false,
+ showMeridian: false,
+ defaultTime: false
+ });
+}
+
+function getTime(str) {
+ if (!str) return false;
+ str = str.split(':');
+ if (str.length !== 2) return false;
+ var h = parseInt(str[0].replace(/^0/, ''));
+ var m = parseInt(str[1].replace(/^0/, ''));
+ if (h < 0 || h > 23) return false;
+ if (m < 0 || m > 59) return false;
+ return h * 60 + m;
+}
+
+const allDays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
+
+/*
+ * Opening times related...
+ */
+
+var slxIdCounter = 0;
+
+/**
+ * Adds a new opening time to the table in expert mode.
+ */
+function newOpeningTime(vals) {
+ var $row = $('#expert-template').find('div.row').clone();
+ if (vals['days'] && Array.isArray(vals['days'])) {
+ for (var i = 0; i < allDays.length; ++i) {
+ $row.find('.i-' + allDays[i]).prop('checked', vals['days'].indexOf(allDays[i]) !== -1);
+ }
+ }
+ $row.find('input').each(function() {
+ var $inp = $(this);
+ if ($inp.length === 0) return;
+ slxIdCounter++;
+ $inp.prop('id', 'id-inp-' + slxIdCounter);
+ $inp.siblings('label').prop('for', 'id-inp-' + slxIdCounter);
+ });
+ $row.find('.i-openingtime').val(vals['openingtime']);
+ $row.find('.i-closingtime').val(vals['closingtime']);
+ $('#expert-table').append($row);
+ return $row;
+}
+
+/**
+ * Convert fields from simple mode view to entries in expert mode.
+ * @returns {Array}
+ */
+function simpleToExpert() {
+ var retval = [];
+ if ($('#week-open').val() || $('#week-close').val()) {
+ retval.push({
+ 'days': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
+ 'openingtime': $('#week-open').val(),
+ 'closingtime': $('#week-close').val(),
+ 'tag': '#week'
+ });
+ }
+ if ($('#saturday-open').val() || $('#saturday-close').val()) {
+ retval.push({
+ 'days': ['Saturday'],
+ 'openingtime': $('#saturday-open').val(),
+ 'closingtime': $('#saturday-close').val(),
+ 'tag': '#saturday'
+ });
+ }
+ if ($('#sunday-open').val() || $('#sunday-close').val()) {
+ retval.push({
+ 'days': ['Sunday'],
+ 'openingtime': $('#sunday-open').val(),
+ 'closingtime': $('#sunday-close').val(),
+ 'tag': '#sunday'
+ });
+ }
+ return retval;
+}
+
+/**
+ * Triggered when the form is submitted
+ */
+function submitLocationSettings(event) {
+ var schedule, s, e;
+ var badFormat = false;
+ $('#settings-outer').find('.red-bg').removeClass('red-bg');
+ if ($('#week-open').length > 0) {
+ schedule = simpleToExpert();
+ for (var i = 0; i < schedule.length; ++i) {
+ s = getTime(schedule[i].openingtime);
+ e = getTime(schedule[i].closingtime);
+ if (s === false) {
+ $(schedule[i].tag + '-open').addClass('red-bg');
+ badFormat = true;
+ }
+ if (e === false || e <= s) {
+ $(schedule[i].tag + '-close').addClass('red-bg');
+ badFormat = true;
+ }
+ }
+ } else {
+ // Serialize
+ schedule = [];
+ $('#expert-table').find('.expert-row').each(function () {
+ var $t = $(this);
+ if ($t.find('.i-delete').is(':checked')) return; // Skip marked as delete
+ var entry = {
+ 'days': [],
+ 'openingtime': $t.find('.i-openingtime').val(),
+ 'closingtime': $t.find('.i-closingtime').val()
+ };
+ for (var i = 0; i < allDays.length; ++i) {
+ if ($t.find('.i-' + allDays[i]).is(':checked')) {
+ entry['days'].push(allDays[i]);
+ }
+ }
+ if (entry.openingtime.length === 0 && entry.closingtime.length === 0 && entry.days.length === 0) return; // Also ignore empty lines
+ s = getTime(entry.openingtime);
+ e = getTime(entry.closingtime);
+ if (s === false) {
+ $t.find('.i-openingtime').addClass('red-bg');
+ badFormat = true;
+ }
+ if (e === false || e <= s) {
+ $t.find('.i-closingtime').addClass('red-bg');
+ badFormat = true;
+ }
+ if (entry.days.length === 0) {
+ $t.find('.days-box').addClass('red-bg');
+ badFormat = true;
+ }
+ if (badFormat) return;
+ schedule.push(entry);
+ });
+ }
+ if (badFormat) {
+ event.preventDefault();
+ }
+ $('#json-openingtimes').val(JSON.stringify(schedule));
+} \ No newline at end of file
diff --git a/modules-available/locations/config.json b/modules-available/locations/config.json
index 110f8b67..ee2600f2 100644
--- a/modules-available/locations/config.json
+++ b/modules-available/locations/config.json
@@ -1,3 +1,9 @@
{
- "category": "main.content"
+ "category": "main.content",
+ "dependencies": [
+ "bootstrap_timepicker"
+ ],
+ "scripts": [
+ "clientscript.js"
+ ]
} \ No newline at end of file
diff --git a/modules-available/locations/install.inc.php b/modules-available/locations/install.inc.php
index d4e1b67b..31d53560 100644
--- a/modules-available/locations/install.inc.php
+++ b/modules-available/locations/install.inc.php
@@ -35,5 +35,27 @@ $res[] = tableAddConstraint('subnet', 'locationid', 'location', 'locationid',
$res[] = tableAddConstraint('setting_location', 'locationid', 'location', 'locationid',
'ON UPDATE CASCADE ON DELETE CASCADE');
+// Update
+
+// 2020-07-14 Add openingtime column to location table, then migrate data and delete the column from locationinfo
+
+if (!tableHasColumn('location', 'openingtime')) {
+ if (Database::exec("ALTER TABLE location ADD openingtime BLOB") === false) {
+ finalResponse(UPDATE_FAILED, 'Could not create openingtime column');
+ } else {
+ if (Module::get('locationinfo') !== false) {
+ if (Database::exec(
+ "UPDATE location, locationinfo_locationconfig
+ SET location.openingtime = locationinfo_locationconfig.openingtime
+ WHERE location.locationid = locationinfo_locationconfig.locationid") === false) {
+ finalResponse(UPDATE_FAILED, 'Could not migrate openingtime data from table to table');
+ }
+ if (Database::exec("ALTER TABLE locationinfo_locationconfig DROP COLUMN openingtime") === false) {
+ finalResponse(UPDATE_FAILED, 'Could not delete openingtime column');
+ }
+ }
+ }
+}
+
// Create response for browser
responseFromArray($res);
diff --git a/modules-available/locations/lang/de/template-tags.json b/modules-available/locations/lang/de/template-tags.json
index 2a03aa85..18176278 100644
--- a/modules-available/locations/lang/de/template-tags.json
+++ b/modules-available/locations/lang/de/template-tags.json
@@ -4,6 +4,8 @@
"lang_assignSubnetExplanation": "Rechner, die in einen der hier aufgef\u00fchrten Adressbereiche fallen, werden diesem Ort zugeschrieben und erhalten damit z.B. f\u00fcr diesen Raum angepasste Veranstaltungslisten.",
"lang_assignedSubnets": "Zugeordnete Subnetze bzw. IP-Bereiche",
"lang_bootMenu": "Bootmen\u00fc",
+ "lang_closingTime": "Schlie\u00dfungszeit",
+ "lang_day": "Tag",
"lang_deleteChildLocations": "Untergeordnete Orte ebenfalls l\u00f6schen",
"lang_deleteLocation": "Ort l\u00f6schen",
"lang_deleteSubnet": "Bereich l\u00f6schen",
@@ -11,6 +13,7 @@
"lang_editConfigVariables": "Konfig.-Variablen",
"lang_editRoomplan": "Raumplan bearbeiten",
"lang_endAddress": "Endadresse",
+ "lang_expertMode": "Experten Modus",
"lang_fixMachineAssign": "Zuweisungen anzeigen\/aufheben",
"lang_ip": "IP-Adresse",
"lang_listOfSubnets": "Liste der Subnetze",
@@ -29,17 +32,28 @@
"lang_matchingMachines": "Enthaltene Rechner",
"lang_mismatchHeading": "Rechner mit widerspr\u00fcchlicher Raumzuweisung",
"lang_mismatchIntroText": "Die hier aufgelisteten Rechner wurden mittels des Raumplaners im oben genannten Raum platziert. Ihrer IP-Adresse nach fallen diese jedoch in einen anderen Raum (durch die f\u00fcr diesen definierten IP-Ranges). Wenn Sie die entsprechenden Rechner hier markieren und auf \"Zur\u00fccksetzen\" klicken, werden die Rechner aus dem oben genannten Raumplan entfernt. Wenn Sie stattdessen auf \"Verschieben\" klicken, werden die Rechner mit ihrer aktuellen Position aus dem jetzigen Raum in den eigentlichen Raum (siehe letzte Spalte der Tabelle) verschoben.",
+ "lang_monTilFr": "Montag - Freitag",
"lang_moveMachines": "In durch Subnet zugeordneten Raum verschieben",
"lang_moveable": "Verschiebbar",
"lang_name": "Name",
"lang_numMachinesWithOverrides": "Anzahl Rechner, bei denen mindestens eine Konfigurationsvariable \u00fcberschrieben wird",
+ "lang_openingTime": "\u00d6ffnungszeit",
"lang_overridenVarsForLocation": "Anzahl Variablen, die an diesem Ort \u00fcberschrieben werden",
"lang_parentLocation": "\u00dcbergeordneter Ort",
"lang_referencingLectures": "Veranstaltungen",
"lang_resetMachines": "Raumzuweisung zur\u00fccksetzen",
+ "lang_saturday": "Samstag",
+ "lang_shortFriday": "Fr",
+ "lang_shortMonday": "Mo",
+ "lang_shortSaturday": "Sa",
+ "lang_shortSunday": "Su",
+ "lang_shortThursday": "Do",
+ "lang_shortTuesday": "Di",
+ "lang_shortWednesday": "Mi",
"lang_showRoomplan": "Raumplan anzeigen",
"lang_startAddress": "Startadresse",
"lang_subnet": "IP-Bereich",
+ "lang_sunday": "Sonntag",
"lang_sysConfig": "Lokalisierung",
"lang_thisListByLocation": "Orte",
"lang_thisListBySubnet": "Subnetze",
diff --git a/modules-available/locations/lang/en/template-tags.json b/modules-available/locations/lang/en/template-tags.json
index 3a79494c..c4fabdb0 100644
--- a/modules-available/locations/lang/en/template-tags.json
+++ b/modules-available/locations/lang/en/template-tags.json
@@ -4,6 +4,8 @@
"lang_assignSubnetExplanation": "Client machines which fall into an IP range listed below will be assigned to this location and will see an according lecture list (e.g. they will see lectures that are exclusively assigned to this location).",
"lang_assignedSubnets": "Assigned subnets \/ IP ranges",
"lang_bootMenu": "Boot menu",
+ "lang_closingTime": "Closing time",
+ "lang_day": "Day",
"lang_deleteChildLocations": "Delete child locations as well",
"lang_deleteLocation": "Delete location",
"lang_deleteSubnet": "Delete range",
@@ -11,6 +13,7 @@
"lang_editConfigVariables": "Config vars",
"lang_editRoomplan": "Edit roomplan",
"lang_endAddress": "End address",
+ "lang_expertMode": "Expert mode",
"lang_fixMachineAssign": "Fix or remove assignment",
"lang_ip": "IP address",
"lang_listOfSubnets": "List of subnets",
@@ -29,17 +32,28 @@
"lang_matchingMachines": "Matching clients",
"lang_mismatchHeading": "Machines with mismatching room plan assignment",
"lang_mismatchIntroText": "Machines listed here are assigned to the room above, but judging from their IP address, should actually be in another room (because of the IP range(s) assigned to that room). By selecting machines below and clicking \"reset\", they will be removed from their current room plan. If you choose \"move\", they will be transferred to the plan of the room they should actually belong to (see last column of table).",
+ "lang_monTilFr": "Monday - Friday",
"lang_moveMachines": "Move to room designated by IP address",
"lang_moveable": "Moveable",
"lang_name": "Name",
"lang_numMachinesWithOverrides": "Number of clients where at least one variable is overridden",
+ "lang_openingTime": "Opening Time",
"lang_overridenVarsForLocation": "Number of variables that get overridden for this location",
"lang_parentLocation": "Parent location",
"lang_referencingLectures": "Assigned Lectures",
"lang_resetMachines": "Reset room assignment",
+ "lang_saturday": "Saturday",
+ "lang_shortFriday": "Fri",
+ "lang_shortMonday": "Mon",
+ "lang_shortSaturday": "Sat",
+ "lang_shortSunday": "Sun",
+ "lang_shortThursday": "Thu",
+ "lang_shortTuesday": "Tue",
+ "lang_shortWednesday": "Wed",
"lang_showRoomplan": "Show room plan",
"lang_startAddress": "Start address",
"lang_subnet": "IP range",
+ "lang_sunday": "Sunday",
"lang_sysConfig": "Localization\/Integration",
"lang_thisListByLocation": "Locations",
"lang_thisListBySubnet": "Subnets",
diff --git a/modules-available/locations/pages/details.inc.php b/modules-available/locations/pages/details.inc.php
index 81b58456..a55460cf 100644
--- a/modules-available/locations/pages/details.inc.php
+++ b/modules-available/locations/pages/details.inc.php
@@ -8,6 +8,9 @@ class SubPage
if ($action === 'updatelocation') {
self::updateLocation();
return true;
+ } else if ($action === 'updateOpeningtimes') {
+ self::updateOpeningTimes();
+ return true;
}
return false;
}
@@ -22,10 +25,75 @@ class SubPage
if ($action === 'showlocation') {
self::ajaxShowLocation();
return true;
+ } elseif ($action === 'getOpeningtimes') {
+ $id = Request::any('locid', 0, 'int');
+ self::ajaxOpeningTimes($id);
+ return true;
}
return false;
}
+ private static function updateOpeningTimes() {
+ $openingTimes = Request::post('openingtimes', '', 'string');
+ $locationid = Request::post('locationid', false, 'int');
+
+ User::assertPermission('location.edit', $locationid);
+
+ // Construct opening-times for database
+ if ($openingTimes !== '') {
+ $openingTimes = json_decode($openingTimes, true);
+ if (!is_array($openingTimes)) {
+ $openingTimes = '';
+ } else {
+ $mangled = array();
+ foreach (array_keys($openingTimes) as $key) {
+ $entry = $openingTimes[$key];
+ if (!isset($entry['days']) || !is_array($entry['days']) || empty($entry['days'])) {
+ Message::addError('ignored-line-no-days');
+ continue;
+ }
+ $start = self::getTime($entry['openingtime']);
+ $end = self::getTime($entry['closingtime']);
+ if ($start === false) {
+ Message::addError('ignored-invalid-start', $entry['openingtime']);
+ continue;
+ }
+ if ($end === false) {
+ Message::addError('ignored-invalid-end', $entry['closingtime']);
+ continue;
+ }
+ if ($end <= $start) {
+ Message::addError('ignored-invalid-range', $entry['openingtime'], $entry['closingtime']);
+ continue;
+ }
+ unset($entry['tag']);
+ $mangled[] = $entry;
+ }
+ if (empty($mangled)) {
+ $openingTimes = null;
+ } else {
+ $openingTimes = json_encode($mangled);
+ }
+ }
+ }
+ // Check if opening-times changed
+ // $res = Database::queryFirst('SELECT openingtime FROM location WHERE locationid = :locationid', compact('locationid'));
+ // $otChanged = $res === false || $res['openingtime'] !== $openingTimes;
+
+ Database::exec('UPDATE location SET openingtime = :openingtime WHERE locationid = :locationid',
+ array('locationid' => $locationid, 'openingtime' => $openingTimes));
+
+ return true;
+ }
+
+ private static function getTime($str)
+ {
+ $str = explode(':', $str);
+ if (count($str) !== 2) return false;
+ if ($str[0] < 0 || $str[0] > 23 || $str[1] < 0 || $str[1] > 59) return false;
+ return $str[0] * 60 + $str[1];
+ }
+
private static function updateLocation()
{
$locationId = Request::post('locationid', false, 'integer');
@@ -313,4 +381,113 @@ class SubPage
echo Render::parse('location-subnets', $data);
}
+ private static function ajaxOpeningTimes($id) {
+ User::assertPermission('location.edit', $id);
+ $openTimes = Database::queryFirst("SELECT openingtime FROM `location` WHERE locationid = :id", array('id' => $id));
+ if ($openTimes !== false) {
+ $openingTimes = json_decode($openTimes['openingtime'], true);
+ }
+ if (!isset($openingTimes) || !is_array($openingTimes)) {
+ $openingTimes = array();
+ }
+ $data = array('id' => $id);
+ $data['expertMode'] = !self::isSimpleMode($openingTimes);
+ $data['schedule_data'] = json_encode($openingTimes);
+
+ echo Render::parse('ajax-opening-location', $data);
+ }
+
+ private static function isSimpleMode(&$array) {
+ if (empty($array))
+ return true;
+ // Decompose by day
+ $new = array();
+ foreach ($array as $row) {
+ $s = self::getTime($row['openingtime']);
+ $e = self::getTime($row['closingtime']);
+ if ($s === false || $e === false || $e <= $s)
+ continue;
+ foreach ($row['days'] as $day) {
+ self::addDay($new, $day, $s, $e);
+ }
+ }
+ // Merge by timespan, but always keep saturday and sunday separate
+ $merged = array();
+ foreach ($new as $day => $ranges) {
+ foreach ($ranges as $range) {
+ if ($day === 'Saturday' || $day === 'Sunday') {
+ $add = $day;
+ } else {
+ $add = '';
+ }
+ $key = '#' . $range[0] . '#' . $range[1] . '#' . $add;
+ if (!isset($merged[$key])) {
+ $merged[$key] = array();
+ }
+ $merged[$key][$day] = true;
+ }
+ }
+ // Check if it passes as simple mode
+ if (count($merged) > 3)
+ return false;
+ foreach ($merged as $days) {
+ if (count($days) === 5) {
+ $res = array_keys($days);
+ $res = array_intersect($res, array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday"));
+ if (count($res) !== 5)
+ return false;
+ } elseif (count($days) === 1) {
+ if (!isset($days['Saturday']) && !isset($days['Sunday'])) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ // Valid simple mode, finally transform back to what we know
+ $new = array();
+ foreach ($merged as $span => $days) {
+ preg_match('/^#(\d+)#(\d+)#/', $span, $out);
+ $new[] = array(
+ 'days' => array_keys($days),
+ 'openingtime' => floor($out[1] / 60) . ':' . ($out[1] % 60),
+ 'closingtime' => floor($out[2] / 60) . ':' . ($out[2] % 60),
+ );
+ }
+ $array = $new;
+ return true;
+ }
+
+ private static function addDay(&$array, $day, $s, $e)
+ {
+ if (!isset($array[$day])) {
+ $array[$day] = array(array($s, $e));
+ return;
+ }
+ foreach (array_keys($array[$day]) as $key) {
+ $current = $array[$day][$key];
+ if ($s <= $current[0] && $e >= $current[1]) {
+ // Fully dominated
+ unset($array[$day][$key]);
+ continue; // Might partially overlap with additional ranges, keep going
+ }
+ if ($current[0] <= $s && $current[1] >= $s) {
+ // $start lies within existing range
+ if ($current[0] <= $e && $current[1] >= $e)
+ return; // Fully in existing range, do nothing
+ // $end seems to extend range we're checking against but $start lies within this range, update and keep going
+ $s = $current[0];
+ unset($array[$day][$key]);
+ continue;
+ }
+ // Last possibility: $start is before range, $end within range
+ if ($current[0] <= $e && $current[1] >= $e) {
+ // $start must lie before range start, otherwise we'd have hit the case above
+ $e = $current[1];
+ unset($array[$day][$key]);
+ continue;
+ }
+ }
+ $array[$day][] = array($s, $e);
+ }
} \ No newline at end of file
diff --git a/modules-available/locations/templates/ajax-opening-location.html b/modules-available/locations/templates/ajax-opening-location.html
new file mode 100644
index 00000000..09fe7869
--- /dev/null
+++ b/modules-available/locations/templates/ajax-opening-location.html
@@ -0,0 +1,173 @@
+<input type="hidden" name="locationid" value="{{id}}">
+<div id="settings-outer">
+ <h3>{{lang_openingTime}}</h3>
+ {{^expertMode}}
+ <div id="simple-mode">
+
+ <div align="right" style="margin-bottom: 10px;">
+ <a href="#" class="btn btn-default btn-sm" id="btn-show-expert">{{lang_expertMode}}</a>
+ </div>
+ <div class="clearfix"></div>
+ <table class="table table-condensed" style="margin-bottom:0">
+ <tr>
+ <th>{{lang_day}}</th>
+ <th>{{lang_openingTime}}</th>
+ <th>{{lang_closingTime}}</th>
+ </tr>
+
+ <tr class="tablerow">
+ <td>{{lang_monTilFr}}</td>
+ <td>
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon">
+ <span class="glyphicon glyphicon-time"></span>
+ </span>
+ <input type="text" class="form-control timepicker2" id="week-open" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </td>
+ <td>
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon">
+ <span class="glyphicon glyphicon-time"></span>
+ </span>
+ <input type="text" class="form-control timepicker2" id="week-close" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </td>
+ </tr>
+ <tr class="tablerow">
+ <td>{{lang_saturday}}</td>
+ <td>
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon">
+ <span class="glyphicon glyphicon-time"></span>
+ </span>
+ <input type="text" class="form-control timepicker2" id="saturday-open" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </td>
+ <td>
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon">
+ <span class="glyphicon glyphicon-time"></span>
+ </span>
+ <input type="text" class="form-control timepicker2" id="saturday-close" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </td>
+ </tr>
+ <tr class="tablerow">
+ <td>{{lang_sunday}}</td>
+ <td>
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon">
+ <span class="glyphicon glyphicon-time"></span>
+ </span>
+ <input type="text" class="form-control timepicker2" id="sunday-open" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </td>
+ <td>
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon">
+ <span class="glyphicon glyphicon-time"></span>
+ </span>
+ <input type="text" class="form-control timepicker2" id="sunday-close" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ {{/expertMode}}
+
+ <div id="expert-mode" style="{{^expertMode}}display:none{{/expertMode}}">
+ <div class="clearfix"></div>
+ <div id="expert-table">
+ <div class="row">
+ <div class="col-sm-6">{{lang_openingTime}}</div>
+ <div class="col-sm-4">{{lang_closingTime}}</div>
+ <div class="col-sm-2 text-right">{{lang_delete}}</div>
+ </div>
+ </div>
+ <hr>
+ <div style="text-align: center;">
+ <a class="btn btn-success btn-sm" id="new-openingtime">
+ <span class="glyphicon glyphicon-plus-sign"></span>
+ {{lang_openingTime}}
+ </a>
+ </div>
+ <br>
+ </div>
+</div>
+
+<div class="hidden" id="expert-template">
+ <div class="row expert-row">
+ <hr>
+ <div class="col-xs-12 days-box">
+ <div class="pull-right checkbox checkbox-inline"><input type="checkbox" class="i-delete"><label><span class="glyphicon glyphicon-trash"></span></label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Monday"><label>{{lang_shortMonday}}</label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Tuesday"><label>{{lang_shortTuesday}}</label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Wednesday"><label>{{lang_shortWednesday}}</label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Thursday"><label>{{lang_shortThursday}}</label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Friday"><label>{{lang_shortFriday}}</label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Saturday"><label>{{lang_shortSaturday}}</label></div>
+ <div class="checkbox checkbox-inline"><input type="checkbox" class="i-Sunday"><label>{{lang_shortSunday}}</label></div>
+ </div>
+ <div class="col-sm-6">
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
+ <input type="text" class="form-control timepicker2 i-openingtime" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </div>
+ <div class="col-sm-6">
+ <div class="input-group bootstrap-timepicker">
+ <span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
+ <input type="text" class="form-control timepicker2 i-closingtime" pattern="[0-9]{1,2}:[0-9]{2}">
+ </div>
+ </div>
+ </div>
+</div>
+
+<script type="application/javascript"><!--
+ (function() {
+
+ var scheduleData = {{{schedule_data}}};
+
+ {{#expertMode}}
+ for (var i = 0; i < scheduleData.length; ++i) {
+ newOpeningTime(scheduleData[i]);
+ }
+ {{/expertMode}}
+ {{^expertMode}}
+ for (var i = 0; i < scheduleData.length; ++i) {
+ if (scheduleData[i].days.length === 5) {
+ $('#week-open').val(scheduleData[i]['openingtime']);
+ $('#week-close').val(scheduleData[i]['closingtime']);
+ } else if (scheduleData[i].days.length === 1 && scheduleData[i].days[0] === 'Saturday') {
+ $('#saturday-open').val(scheduleData[i]['openingtime']);
+ $('#saturday-close').val(scheduleData[i]['closingtime']);
+ } else if (scheduleData[i].days.length === 1 && scheduleData[i].days[0] === 'Sunday') {
+ $('#sunday-open').val(scheduleData[i]['openingtime']);
+ $('#sunday-close').val(scheduleData[i]['closingtime']);
+ }
+ }
+ {{/expertMode}}
+
+ setTimepicker($('#settings-outer').find('.timepicker2'));
+
+ $('p.helptext').tooltip();
+
+ $('#new-openingtime').click(function (e) {
+ e.preventDefault();
+ setTimepicker(newOpeningTime({}).find('.timepicker2'));
+ });
+
+ $('#btn-show-expert').click(function (e) {
+ e.preventDefault();
+ scheduleData = simpleToExpert();
+ for (var i = 0; i < scheduleData.length; ++i) {
+ setTimepicker(newOpeningTime(scheduleData[i]).find('.timepicker2'));
+ }
+ $('#simple-mode').remove();
+ $('#expert-mode').show();
+ });
+
+ })();
+
+//--></script>
diff --git a/modules-available/locations/templates/location-subnets.html b/modules-available/locations/templates/location-subnets.html
index 6062b559..b85ddbec 100644
--- a/modules-available/locations/templates/location-subnets.html
+++ b/modules-available/locations/templates/location-subnets.html
@@ -62,7 +62,7 @@
<div class="slx-bold">{{lang_locationInfo}}</div>
<div class="row">
- <div class="col-md-4">
+ <div class="col-md-3">
{{#haveDozmod}}
<div>
<span class="slx-ga2">{{lang_referencingLectures}}:</span> {{lectures}}
@@ -81,7 +81,13 @@
</div>
{{/haveStatistics}}
</div>
- <div class="col-md-4 text-center">
+ <div class="col-md-3 text-center">
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#openingTimesModal{{locationid}}" onclick="loadOpeningTimes('{{locationid}}')">
+ <span class="glyphicon glyphicon-time"></span>
+ {{lang_openingTime}}
+ </button>
+ </div>
+ <div class="col-md-3 text-center">
{{#roomplanner}}
<a class="btn btn-default" href="?do=roomplanner&amp;locationid={{locationid}}" target="_blank"
onclick="window.open(this.href, '_blank', 'toolbar=0,scrollbars,resizable');return false">
@@ -91,7 +97,7 @@
</a>
{{/roomplanner}}
</div>
- <div class="col-md-4 text-right">
+ <div class="col-md-3 text-right">
<button {{perms.location.delete.disabled}} type="button" class="btn btn-danger" data-toggle="modal" data-target="#deleteLocationModal{{locationid}}"><span class="glyphicon glyphicon-trash"></span> {{lang_deleteLocation}}</button>
<button onclick="deleteSubnetWarning('{{locationid}}')" {{perms.save_button.disabled}} type="button" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
@@ -130,4 +136,34 @@
</div>
</form>
-</div> \ No newline at end of file
+</div>
+
+<div class="modal fade" id="openingTimesModal{{locationid}}" tabindex="-1" role="dialog">
+ <div class="modal-dialog">
+
+ <div class="modal-content">
+ <form method="post" action="?do=Locations" id="settings-form">
+ <input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="action" value="updateOpeningtimes">
+ <input type="hidden" name="page" value="details">
+ <input type="hidden" name="openingtimes" id="json-openingtimes" value="">
+
+ <div class="modal-header">{{locationname}}</div>
+ <div class="modal-body"></div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_close}}</button>
+ <button type="submit" class="btn btn-primary">
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
+ </div>
+
+ </form>
+ </div>
+
+ </div>
+</div>
+
+<script type="text/javascript">
+ $('#settings-form').submit(submitLocationSettings);
+</script> \ No newline at end of file
diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html
index 7adfe2fc..12d401c1 100644
--- a/modules-available/locations/templates/locations.html
+++ b/modules-available/locations/templates/locations.html
@@ -250,5 +250,10 @@ function deleteSubnetWarning(locid) {
form.submit();
}
}
+
+function loadOpeningTimes(locid) {
+ $("#openingTimesModal" + locid).find('.modal-body').load("?do=Locations&page=details&action=getOpeningtimes&locid=" + locid)
+}
+
// -->
</script>