summaryrefslogtreecommitdiffstats
path: root/modules-available/exams
diff options
context:
space:
mode:
authorChristian Klinger2016-06-17 15:26:20 +0200
committerChristian Klinger2016-06-17 15:26:20 +0200
commit1433be46299be45b1dbb1d393c867c382368df97 (patch)
treed1ce45f0324f15af6414d38c1239732c814e2072 /modules-available/exams
parentAdded translation for messages. (diff)
downloadslx-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.json2
-rw-r--r--modules-available/exams/lang/de/template-tags.json32
-rw-r--r--modules-available/exams/page.inc.php115
-rw-r--r--modules-available/exams/style.css13
-rw-r--r--modules-available/exams/templates/page-edit-exam.html61
-rw-r--r--modules-available/exams/templates/page-exams.html33
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);