diff options
author | Christian Klinger | 2016-06-17 15:26:20 +0200 |
---|---|---|
committer | Christian Klinger | 2016-06-17 15:26:20 +0200 |
commit | 1433be46299be45b1dbb1d393c867c382368df97 (patch) | |
tree | d1ce45f0324f15af6414d38c1239732c814e2072 /modules-available/exams | |
parent | Added translation for messages. (diff) | |
download | slx-admin-1433be46299be45b1dbb1d393c867c382368df97.tar.gz slx-admin-1433be46299be45b1dbb1d393c867c382368df97.tar.xz slx-admin-1433be46299be45b1dbb1d393c867c382368df97.zip |
"Edit" for exam periods, UTC timestamps.
Diffstat (limited to 'modules-available/exams')
-rw-r--r-- | modules-available/exams/lang/de/messages.json | 2 | ||||
-rw-r--r-- | modules-available/exams/lang/de/template-tags.json | 32 | ||||
-rw-r--r-- | modules-available/exams/page.inc.php | 115 | ||||
-rw-r--r-- | modules-available/exams/style.css | 13 | ||||
-rw-r--r-- | modules-available/exams/templates/page-edit-exam.html | 61 | ||||
-rw-r--r-- | modules-available/exams/templates/page-exams.html | 33 |
6 files changed, 208 insertions, 48 deletions
diff --git a/modules-available/exams/lang/de/messages.json b/modules-available/exams/lang/de/messages.json index 2eb9dbc3..b2c1e451 100644 --- a/modules-available/exams/lang/de/messages.json +++ b/modules-available/exams/lang/de/messages.json @@ -1,4 +1,6 @@ { + "changes-successfully-saved": "\u00c4nderungen erfolgreich gespeichert", + "error-while-saving-changes": "Fehler beim Speichern der \u00c4nderungen", "exam-added-success": "Klausurzeitraum erfolgreich hinzugef\u00fcgt", "exam-deleted-success": "Klausurzeitraum erfolgreich gel\u00f6scht", "exam-not-added": "Klausurzeitraum konnte nicht hinzugef\u00fcgt werden", diff --git a/modules-available/exams/lang/de/template-tags.json b/modules-available/exams/lang/de/template-tags.json index 19b919bb..430599f9 100644 --- a/modules-available/exams/lang/de/template-tags.json +++ b/modules-available/exams/lang/de/template-tags.json @@ -1,16 +1,18 @@ { - "lang_addExam": "Klausurzeitraum hinzufügen", - "lang_allExamPeriods": "Alle Klausurzeiträume", - "lang_deleteConfirmation": "Wirklich löschen?", - "lang_id" : "ID", - "lang_locations" : "Räume/Orte", - "lang_begin" : "Beginn", - "lang_end" : "Ende", - "lang_actions" : "Aktionen", - "lang_location" : "Raum/Ort", - "lang_begin_date" : "Beginn Datum", - "lang_begin_time" : "Uhrzeit", - "lang_end_date" : "Ende Datum", - "lang_end_time" : "Uhrzeit", - "lang_description" : "Beschreibung" -} + "lang_actions": "Aktionen", + "lang_addExam": "Klausurzeitraum hinzuf\u00fcgen", + "lang_allExamPeriods": "Alle Klausurzeitr\u00e4ume", + "lang_begin": "Beginn", + "lang_begin_date": "Beginn Datum", + "lang_begin_time": "Uhrzeit", + "lang_deleteConfirmation": "Wirklich l\u00f6schen?", + "lang_description": "Beschreibung", + "lang_editExam": "Klausurzeitraum bearbeiten", + "lang_end": "Ende", + "lang_end_date": "Ende Datum", + "lang_end_time": "Uhrzeit", + "lang_id": "ID", + "lang_location": "Raum\/Ort", + "lang_locations": "R\u00e4ume\/Orte", + "lang_saveExam": "Klausurzeitraum speichern" +}
\ No newline at end of file diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php index 8c82f50e..20101229 100644 --- a/modules-available/exams/page.inc.php +++ b/modules-available/exams/page.inc.php @@ -8,9 +8,15 @@ class Page_Exams extends Page var $lectures; - protected function readLocations() + /** if examid is set, also add a column 'selected' **/ + protected function readLocations($examid = NULL) { - $tmp = Database::simpleQuery("select * from location;", []); + if ($examid == NULL) { + $tmp = Database::simpleQuery("SELECT locationid, locationname FROM location;", []); + } else { + $tmp = Database::simpleQuery("SELECT locationid, locationname, " . + "EXISTS(SELECT * FROM exams NATURAL JOIN exams_x_locations WHERE locationid = x.locationid AND examid= :examid) AS selected FROM location x", compact('examid')); + } while ($loc = $tmp->fetch(PDO::FETCH_ASSOC)) { $this->locations[] = $loc; } @@ -18,9 +24,9 @@ class Page_Exams extends Page protected function readExams() { - $tmp = Database::simpleQuery("select examid, starttime, endtime, GROUP_CONCAT(locationid) AS locationids," - . " GROUP_CONCAT(locationname) AS locationnames from " - . "exams NATURAL JOIN exams_x_locations NATURAL 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_locations NATURAL LEFT JOIN location GROUP BY examid", []); while ($exam = $tmp->fetch(PDO::FETCH_ASSOC)) { $this->exams[] = $exam; } @@ -28,7 +34,10 @@ class Page_Exams extends Page protected function readLectures() { - $tmp = Database::simpleQuery("select * from sat.lecture NATURAL JOIN sat.lecture_x_location"); + $tmp = Database::simpleQuery( + "SELECT lectureid, locationid, displayname, starttime, endtime, isenabled ". + "FROM sat.lecture NATURAL JOIN sat.lecture_x_location " . + "WHERE isexam <> 0"); while ($lecture = $tmp->fetch(PDO::FETCH_ASSOC)) { $this->lectures[] = $lecture; } @@ -50,12 +59,13 @@ class Page_Exams extends Page } $unique_ids = 1; + /* add the red shadows */ foreach ($this->exams as $e) { foreach(explode(',', $e['locationids']) as $locationid) { $out[] = [ 'id' => 'shadow_' . $unique_ids++, 'content' => '', - 'start' => $e['starttime'], - 'end' => $e['endtime'], + 'start' => intval($e['starttime']) * 1000, + 'end' => intval($e['endtime']) * 1000, 'type' => 'background', 'group' => $locationid, ]; @@ -64,12 +74,16 @@ class Page_Exams extends Page /* add the lectures */ $i = 2; foreach ($this->lectures as $l) { + $mark = '<span class="' . ($l['isenabled'] ? '' : 'glyphicon glyphicon-exclamation-sign') . '"></span>'; $out[] = [ 'id' => $l['lectureid'], - 'content' => $l['displayname'], - 'start' => date(DATE_ISO8601, $l['starttime']), - 'end' => date(DATE_ISO8601, $l['endtime']), + 'content' => htmlspecialchars($l['displayname']) . $mark , + 'title' => $l['isenabled'] ? '' : Dictionary::translate('warning_lecture_is_not_enabled'), + 'start' => intval($l['starttime']) * 1000, + 'end' => intval($l['endtime']) * 1000, 'group' => $l['locationid'], + 'className' => $l['isenabled'] ? '' : 'disabled', + 'editable' => false, 'subgroup' => $i++ ]; @@ -90,12 +104,22 @@ class Page_Exams extends Page return json_encode($out); } + protected function makeExamsForTemplate() { + $out = []; + foreach ($this->exams as $exam) { + $tmp = $exam; + $tmp['starttime'] = date('Y-m-d H:i', $tmp['starttime']); + $tmp['endtime'] = date('Y-m-d H:i', $tmp['endtime']); + $out[] = $tmp; + } + return $out; + } protected function doPreprocess() { User::load(); $req_action = Request::get('action', 'show'); - if (in_array($req_action, ['show', 'add', 'delete'])) { + if (in_array($req_action, ['show', 'add', 'delete', 'edit'])) { $this->action = $req_action; } @@ -109,8 +133,13 @@ class Page_Exams extends Page /* process form-data */ $locationids = Request::post('locations', [], "ARRAY"); - $starttime = Request::post('starttime_date') . " " . Request::post('starttime_time'); - $endtime = Request::post('endtime_date') . " " . Request::post('endtime_time'); + /* global room has id 0 */ + if(empty($locationids)) { + $locationids[] = 0; + } + + $starttime = strtotime(Request::post('starttime_date') . " " . Request::post('starttime_time')); + $endtime = strtotime(Request::post('endtime_date') . " " . Request::post('endtime_time')); $description = Request::post('description'); $res = Database::exec("INSERT INTO exams(starttime, endtime, description) VALUES(:starttime, :endtime, :description);", @@ -141,8 +170,41 @@ class Page_Exams extends Page Message::addInfo('exam-deleted-success'); } Util::redirect('?do=exams'); + } elseif ($this->action === 'edit') { + $examid = Request::get('examid', -1, 'int'); + $this->readLocations($examid); + $this->currentExam = Database::queryFirst("SELECT * FROM exams WHERE examid = :examid", array('examid' => $examid)); + + if (Request::isPost()) { + $locationids = Request::post('locations', [], "ARRAY"); + + /* global room has id 0 */ + if(empty($locationids)) { + $locationids[] = 0; + } + + $starttime = strtotime(Request::post('starttime_date') . " " . Request::post('starttime_time')); + $endtime = strtotime(Request::post('endtime_date') . " " . Request::post('endtime_time')); + $description = Request::post('description'); + /* update fields */ + $res = Database::exec("UPDATE exams SET starttime = :starttime, endtime = :endtime, description = :description WHERE examid = :examid", + compact('starttime', 'endtime', 'description', 'examid')); + /* drop all connections and reconnect to rooms */ + $res = $res !== FALSE && Database::exec("DELETE FROM exams_x_locations WHERE examid = :examid", compact('examid')); + /* reconnect */ + foreach ($locationids as $lid) { + $res = $res !== FALSE && Database::exec("INSERT INTO exams_x_locations(examid, locationid) VALUES(:examid, :lid)", compact('examid', 'lid')); + } + if ($res !== FALSE) { + Message::addInfo("changes-successfully-saved"); + } else { + Message::addError("error-while-saving-changes"); + } + Util::redirect('?do=exams'); + } + } else { - Util::traceError("unknown action"); + Util::traceError("action not implemented"); } } @@ -154,15 +216,28 @@ class Page_Exams extends Page if ($this->action === "show") { Render::setTitle("All Exams"); Render::addTemplate('page-exams', - [ 'exams' => $this->exams, - 'exams_json' => $this->makeItemsForVis(), - 'rooms_json' => $this->makeGroupsForVis(), - 'vis_begin' => date('Y-m-d'), - 'vis_end' => date('Y-m-d', strtotime("+2 day")) + [ 'exams' => $this->makeExamsForTemplate(), + 'exams_json' => $this->makeItemsForVis(), + 'rooms_json' => $this->makeGroupsForVis(), + 'vis_begin' => time() * 1000, + 'vis_end' => strtotime('+2 day') * 1000, + 'vis_min_date' => strtotime('-1 day') * 1000, + 'vis_max_date' => strtotime('+3 month') * 1000 ]); } elseif ($this->action === "add") { Render::setTitle("Add Exam"); Render::addTemplate('page-add-exam', ['locations' => $this->locations]); + } elseif ($this->action === 'edit') { + Render::setTitle("Edit Exam"); + $exam = [ + 'examid' => $this->currentExam['examid'], + 'starttime_date' => date('Y-m-d', $this->currentExam['starttime']), + 'starttime_time' => date('H:i', $this->currentExam['starttime']), + 'endtime_date' => date('Y-m-d', $this->currentExam['endtime']), + 'endtime_time' => date('H:i', $this->currentExam['endtime']), + 'description' => $this->currentExam['description'] + ]; + Render::addTemplate('page-edit-exam', ['exam' => $exam, 'locations' => $this->locations]); } // Render::output('hi'); } diff --git a/modules-available/exams/style.css b/modules-available/exams/style.css index bc5ae53e..89f312fa 100644 --- a/modules-available/exams/style.css +++ b/modules-available/exams/style.css @@ -1,7 +1,16 @@ .vis-item.vis-background { - background-color: #E8A7A7 !important; + background-color: rgba(192, 57, 43, .5) !important; } .vis-item.spacer { visibility: hidden; - background-color: green !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; } diff --git a/modules-available/exams/templates/page-edit-exam.html b/modules-available/exams/templates/page-edit-exam.html new file mode 100644 index 00000000..61848ec2 --- /dev/null +++ b/modules-available/exams/templates/page-edit-exam.html @@ -0,0 +1,61 @@ +<h1>{{lang_editExam}}: </h1> + +<form class="form" method="POST" action="?do=exams&action=edit&examid={{exam.examid}}"> + <div class="form-group"> + <label for="locations">{{lang_location}}</label> + <select id="locations" multiple="multiple" name="locations[]" class=""> + {{#locations}} + <option value="{{locationid}}" {{#selected}}selected{{/selected}} > {{locationname}} </option> + {{/locations}} + </select> + </div> + + <div class="row"> + <div class="form-group col-xs-6"> + <label for="starttime_date">{{lang_begin_date}}</label> + <input required class="form-control datepicker" name="starttime_date" value="{{exam.starttime_date}}"/> + </div> + <div class="form-group col-xs-6"> + <label for="starttime_time">{{lang_begin_time}}</label> + <input required type="text" class="form-control timepicker" name="starttime_time" value="{{exam.starttime_time}}" /> + </div> + </div> + + <div class="row"> + <div class="form-group col-xs-6"> + <label for="endtime_date">{{lang_end_date}}</label> + <input required class="form-control datepicker" name="endtime_date" value="{{exam.endtime_date}}"/> + </div> + <div class="form-group col-xs-6"> + <label for="endtime_time">{{lang_end_time}}</label> + <input required type="texxt" class="form-control timepicker" name="endtime_time" value="{{exam.endtime_time}}"/> + </div> + </div> + <div class="row"> + <div class="form-group col-xs-12"> + <label for="description">{{lang_description}}</label> + <textarea class="form-control" type="textarea" name="description">{{exam.description}}</textarea> + </div> + </div> + + <input type="hidden" name="token" value="{{token}}" /> + <input type="submit" class="btn btn-success" value="{{lang_saveExam}}"></input> +</form> + +<script type="application/javascript"><!-- +document.addEventListener("DOMContentLoaded", function () { + var dateSettings = { + format: 'yyyy-mm-dd', + weekStart: 1, + startDate: 'today', + }; + var timeSettings = { + showSeconds: false, + showMeridian: false + }; + $('.datepicker').datepicker(dateSettings); + $('.timepicker').timepicker(timeSettings); + + $('#locations').multiselect({numberDisplayed: 1}); +}, false); +// --></script> diff --git a/modules-available/exams/templates/page-exams.html b/modules-available/exams/templates/page-exams.html index 0cc4cb8a..0dcedb84 100644 --- a/modules-available/exams/templates/page-exams.html +++ b/modules-available/exams/templates/page-exams.html @@ -17,11 +17,18 @@ <td>{{starttime}}</td> <td>{{endtime}}</td> <td> - <form method="POST" action="?do=exams&action=delete" onsubmit="return confirm('{{lang_deleteConfirmation}}');"> - <input type="hidden" name="token" value="{{token}}"/> - <input type="hidden" name="examid" value="{{examid}}"/> - <input type="submit" value="{{lang_delete}}" class="btn btn-default btn-sm" /> - </form> + <div class="btn-toolbar" role="toolbar"> + <div class="btn-group"> + <a href="?do=exams&action=edit&examid={{examid}}" class="btn btn-default btn-sm" >{{lang_edit}}</a> + </div> + <div class="btn-group"> + <form method="POST" action="?do=exams&action=delete" onsubmit="return confirm('{{lang_deleteConfirmation}}');"> + <input type="hidden" name="token" value="{{token}}"/> + <input type="hidden" name="examid" value="{{examid}}"/> + <input type="submit" value="{{lang_delete}}" class="btn btn-default btn-sm" /> + </form> + </div> + </div> </td> </tr> {{/exams}} @@ -48,18 +55,22 @@ function customOrder(a, b) { document.addEventListener("DOMContentLoaded", function () { var container = document.getElementById('timeline'); - var groups_plain = JSON.parse('{{{rooms_json}}}'); - var items_plain = JSON.parse('{{{exams_json}}}'); + 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); var options = { - 'start' : '{{{vis_begin}}}', - 'end' : '{{{vis_end}}}', - 'stack' : false, - 'order' : customOrder + 'start' : {{vis_begin}}, + 'end' : {{vis_end}}, + 'stack' : false, + 'editable' : false, + 'min' : {{vis_begin}}, + 'max' : {{vis_max_date}}, + 'order' : customOrder, + 'moment' : function(date) { return vis.moment(date).utc(); } }; var timeline = new vis.Timeline(container, items, groups, options); |