From d2700067d135a13383f2e1a4d8ed693f14dc844f Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 6 Jul 2016 17:34:57 +0200 Subject: [exams] Add button to zoom to selected exam period; autofill end day; show description of exam periods --- modules-available/exams/install.inc.php | 4 +- modules-available/exams/page.inc.php | 69 ++++++++++++++-------- modules-available/exams/style.css | 23 ++++---- .../exams/templates/page-add-edit-exam.html | 15 +++++ modules-available/exams/templates/page-exams.html | 24 +++++--- 5 files changed, 91 insertions(+), 44 deletions(-) (limited to 'modules-available/exams') diff --git a/modules-available/exams/install.inc.php b/modules-available/exams/install.inc.php index aa8c9a0d..0cb1af8e 100644 --- a/modules-available/exams/install.inc.php +++ b/modules-available/exams/install.inc.php @@ -6,7 +6,7 @@ $res[] = tableCreate('exams', ' `examid` int(11) NOT NULL AUTO_INCREMENT, `starttime` int(11) NOT NULL, `endtime` int(11) NOT NULL, - `description` varchar(100) DEFAULT NULL, + `description` varchar(500) DEFAULT NULL, PRIMARY KEY (`examid`) '); @@ -24,6 +24,8 @@ if (Database::exec("ALTER TABLE exams ADD INDEX `idx_daterange` ( `starttime` , $res[] = UPDATE_DONE; } +Database::exec("ALTER TABLE `exams` CHANGE `description` `description` varchar(500) DEFAULT NULL"); + if (in_array(UPDATE_DONE, $res)) { finalResponse(UPDATE_DONE, 'Tables created successfully'); } diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php index 54fad5cf..33117c2e 100644 --- a/modules-available/exams/page.inc.php +++ b/modules-available/exams/page.inc.php @@ -7,6 +7,8 @@ class Page_Exams extends Page var $locations; var $lectures; private $currentExam; + private $rangeMin; + private $rangeMax; /** if examid is set, also add a column 'selected' **/ @@ -26,9 +28,9 @@ class Page_Exams extends Page protected function readExams() { - $tmp = Database::simpleQuery("select examid, starttime, endtime, description, GROUP_CONCAT(locationid) AS locationids, " - . "GROUP_CONCAT(locationname) AS locationnames FROM " - . "exams NATURAL LEFT JOIN exams_x_location NATURAL LEFT JOIN location GROUP BY examid", []); + $tmp = Database::simpleQuery("SELECT examid, starttime, endtime, description, GROUP_CONCAT(locationid) AS locationids, " + . "GROUP_CONCAT(locationname) AS locationnames FROM exams " + . "NATURAL LEFT JOIN exams_x_location NATURAL LEFT JOIN location GROUP BY examid"); while ($exam = $tmp->fetch(PDO::FETCH_ASSOC)) { $this->exams[] = $exam; } @@ -38,17 +40,28 @@ class Page_Exams extends Page { $tmp = Database::simpleQuery( "SELECT lectureid, locationid, displayname, starttime, endtime, isenabled " . - "FROM sat.lecture NATURAL JOIN sat.lecture_x_location " . - "WHERE isexam <> 0"); + "FROM sat.lecture " . + "NATURAL LEFT JOIN sat.lecture_x_location " . + "WHERE isexam <> 0 AND starttime < :rangeMax AND endtime > :rangeMin", + ['rangeMax' => $this->rangeMax, 'rangeMin' => $this->rangeMin]); while ($lecture = $tmp->fetch(PDO::FETCH_ASSOC)) { - $this->lectures[] = $lecture; + if (is_null($lecture['locationid'])) { + foreach ($this->locations as $location) { + $lecture['locationid'] = $location['locationid']; + $this->lectures[] = $lecture; + } + } else { + $this->lectures[] = $lecture; + } } } protected function makeItemsForVis() { $out = []; - /* foreach group also add an invisible item on top */ + // foreach group also add an invisible item on top + // disabled for now - more of an annoyance if you have more than a few rooms + /* foreach ($this->locations as $l) { $out[] = ['id' => 'spacer_' . $l['locationid'], 'group' => $l['locationid'], @@ -58,11 +71,13 @@ class Page_Exams extends Page 'end' => 99999999999999, 'subgroup' => 0 ]; - } + */ $unique_ids = 1; /* add the red shadows */ foreach ($this->exams as $e) { + if ($e['starttime'] > $this->rangeMax || $e['endtime'] < $this->rangeMin) + continue; $locationids = explode(',', $e['locationids']); if ($locationids[0] == 0) { $locationids = []; @@ -71,8 +86,10 @@ class Page_Exams extends Page } } foreach ($locationids as $locationid) { - $out[] = ['id' => 'shadow_' . $unique_ids++, - 'content' => '', + $out[] = [ + 'id' => 'shadow_' . $unique_ids++, + 'content' => $e['description'], + 'title' => $e['description'], 'start' => intval($e['starttime']) * 1000, 'end' => intval($e['endtime']) * 1000, 'type' => 'background', @@ -93,9 +110,8 @@ class Page_Exams extends Page 'group' => $l['locationid'], 'className' => $l['isenabled'] ? '' : 'disabled', 'editable' => false, - 'subgroup' => $i++ + 'subgroup' => $i++, ]; - } return json_encode($out); @@ -124,21 +140,18 @@ class Page_Exams extends Page $exam['btnClass'] = 'btn-success'; } else { $exam['btnClass'] = 'btn-default'; + $exam['confirmDelete'] = true; } - $exam['starttime'] = date('Y-m-d H:i', $exam['starttime']); - $exam['endtime'] = date('Y-m-d H:i', $exam['endtime']); + $exam['starttime_s'] = date('Y-m-d H:i', $exam['starttime']); + $exam['endtime_s'] = date('Y-m-d H:i', $exam['endtime']); $out[] = $exam; } return $out; } - private function dateSane($time) + private function isDateSane($time) { - if ($time < strtotime('-1 day')) - return false; - if ($time > strtotime('+90 day')) - return false; - return true; + return ($time >= $this->rangeMin && $time <= $this->rangeMax); } private function saveExam() @@ -158,11 +171,11 @@ class Page_Exams extends Page $starttime = strtotime(Request::post('starttime_date') . " " . Request::post('starttime_time')); $endtime = strtotime(Request::post('endtime_date') . " " . Request::post('endtime_time')); $description = Request::post('description'); - if (!$this->dateSane($starttime)) { + if (!$this->isDateSane($starttime)) { Message::addError('starttime-invalid', Request::post('starttime_date') . " " . Request::post('starttime_time')); Util::redirect('?do=exams'); } - if (!$this->dateSane($endtime)) { + if (!$this->isDateSane($endtime)) { Message::addError('endtime-invalid', Request::post('endtime_date') . " " . Request::post('endtime_time')); Util::redirect('?do=exams'); } @@ -217,6 +230,14 @@ class Page_Exams extends Page { User::load(); + if (!User::hasPermission('superadmin')) { + Message::addError('main.no-permission'); + Util::redirect('?do=Main'); + } + + $this->rangeMin = strtotime('-1 day'); + $this->rangeMax = strtotime('+3 month'); + $req_action = Request::any('action', 'show'); if (in_array($req_action, ['show', 'add', 'delete', 'edit', 'save'])) { $this->action = $req_action; @@ -274,8 +295,8 @@ class Page_Exams extends Page 'rooms_json' => $this->makeGroupsForVis(), 'vis_begin' => strtotime('-5 minute') * 1000, 'vis_end' => strtotime('+2 day') * 1000, - 'vis_min_date' => strtotime('-1 day') * 1000, - 'vis_max_date' => strtotime('+3 month') * 1000 + 'vis_min_date' => $this->rangeMin * 1000, + 'vis_max_date' => $this->rangeMax * 1000 ]); } elseif ($this->action === "add") { Render::setTitle(Dictionary::translate('title_add-exam')); diff --git a/modules-available/exams/style.css b/modules-available/exams/style.css index 89f312fa..4a6cd7da 100644 --- a/modules-available/exams/style.css +++ b/modules-available/exams/style.css @@ -1,16 +1,17 @@ - .vis-item.vis-background { +.vis-item.vis-background { background-color: rgba(192, 57, 43, .5) !important; } - .vis-item.spacer { + +.vis-item.spacer { visibility: hidden; - } +} - .vis-selected, - .vis-readonly { - background-color: #80D6F2 !important; - border: 1px solid grey !important; - } +.vis-selected, +.vis-readonly { + background-color: #80D6F2 !important; + border: 1px solid grey !important; +} - .vis-item.disabled { - background-color: rgba(189, 195, 199,1.0) !important; - } +.vis-item.disabled { + background-color: rgba(189, 195, 199, 1.0) !important; +} diff --git a/modules-available/exams/templates/page-add-edit-exam.html b/modules-available/exams/templates/page-add-edit-exam.html index 7d74972d..830b631d 100644 --- a/modules-available/exams/templates/page-add-edit-exam.html +++ b/modules-available/exams/templates/page-add-edit-exam.html @@ -86,6 +86,7 @@ document.addEventListener("DOMContentLoaded", function () { format: 'yyyy-mm-dd', weekStart: 1, startDate: 'today', + todayHighlight: true, language: LANG }; var timeSettings = { @@ -103,5 +104,19 @@ document.addEventListener("DOMContentLoaded", function () { }); + $('#starttime_date').focusout(function () { + var start = $('#starttime_date').val(); + var end = $('#endtime_date').val(); + var ok = end.length === 0; + if (!ok) { + var ms = moment(start, 'YYYY-MM-DD'); + var me = moment(end, 'YYYY-MM-DD'); + ok = !me.isValid() || me.isBefore(ms); + } + if (ok) { + $('#endtime_date').val(start); + } + }); + }, false); // --> diff --git a/modules-available/exams/templates/page-exams.html b/modules-available/exams/templates/page-exams.html index 45ec0b50..c30289d6 100644 --- a/modules-available/exams/templates/page-exams.html +++ b/modules-available/exams/templates/page-exams.html @@ -13,12 +13,16 @@ {{#exams}} {{examid}} - {{locationnames}} - {{starttime}} - {{endtime}} -
- {{lang_edit}} + {{locationnames}} +
{{description}}
+ + {{starttime_s}} + {{endtime_s}} + + + + {{lang_edit}} @@ -53,12 +57,12 @@ function groupOrderFun(a, b) { return itemOrderFun(a, b); } +var slxTimeline; + document.addEventListener("DOMContentLoaded", function () { var container = document.getElementById('timeline'); var groups_plain = {{{rooms_json}}}; var items_plain = {{{exams_json}}}; - console.log(groups_plain); - console.log(items_plain); var groups = new vis.DataSet(groups_plain); var items = new vis.DataSet(items_plain); @@ -79,7 +83,11 @@ document.addEventListener("DOMContentLoaded", function () { 'moment' : function(date) { return vis.moment(date).utc(); } }; - var timeline = new vis.Timeline(container, items, groups, options); + slxTimeline = new vis.Timeline(container, items, groups, options); }, false); +function slxShow(st, et) { + slxTimeline.setWindow(st * 1000, et * 1000); +} + // --> -- cgit v1.2.3-55-g7522