Commit 3eaf9cfc authored by Julian Rother's avatar Julian Rother
Browse files

Replaced "responsible" text field with multiselect widget

parent 6d58ed62
......@@ -297,7 +297,8 @@ CREATE TABLE IF NOT EXISTS `jobs` (
CREATE TABLE IF NOT EXISTS `responsible` (
`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`course_id` INTEGER NOT NULL,
`user_id` INTEGER NOT NULL
`user_id` INTEGER NOT NULL,
UNIQUE (course_id, user_id)
);
CREATE VIEW IF NOT EXISTS `courses` AS select * from `courses_data` where (not(`courses_data`.`deleted`));
......
......@@ -196,3 +196,15 @@ def changelog():
for entry in changelog:
entry['path'] = '.'.join([entry['table'], entry['id_value'], entry['field']])
return render_template('changelog.html', changelog=changelog, page=page, pagesize=pagesize, pagecount=pagecount)
@app.route('/internal/set/responsible/<int:course_id>/<int:user_id>', defaults={'value': True}, methods=['GET', 'POST'])
@app.route('/internal/unset/responsible/<int:course_id>/<int:user_id>', defaults={'value': False}, methods=['GET', 'POST'])
@mod_required
@csrf_protect
def set_responsible(course_id, user_id, value):
if value:
modify('REPLACE INTO responsible (course_id, user_id) values (?, ?)', course_id, user_id);
else:
modify('DELETE FROM responsible WHERE course_id = ? AND user_id = ?', course_id, user_id);
return "OK", 200
......@@ -261,7 +261,12 @@ def course(id=None, handle=None):
if course['coursechapters']:
chapters = query('SELECT chapters.* FROM chapters JOIN lectures ON lectures.id = chapters.lecture_id WHERE lectures.course_id = ? AND NOT chapters.deleted AND chapters.visible ORDER BY time ASC', course['id'])
videos += genlive(livestreams)
return render_template('course.html', course=course, lectures=lectures, videos=videos, chapters=chapters)
responsible = query('''SELECT users.*, responsible.course_id AS responsible
FROM users
LEFT JOIN responsible ON (responsible.user_id = users.id AND responsible.course_id = ?)
WHERE users.fsacc != "" AND users.level > 0
ORDER BY responsible DESC, users.realname ASC''', course['id'])
return render_template('course.html', course=course, lectures=lectures, videos=videos, chapters=chapters, responsible=responsible)
@app.route('/faq')
@register_navbar('FAQ', icon='question-sign')
......
span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0}
This diff is collapsed.
......@@ -12,6 +12,24 @@ var moderator = {
req[path] = value;
moderator.api.set_multi(req,reload)
},
set_map: function(table, key1, key2, value) {
var dict = {};
var url;
if (value) {
url = "/internal/set/"+table+"/"+key1+"/"+key2;
} else {
url = "/internal/unset/"+table+"/"+key1+"/"+key2;
}
dict['_csrf_token'] = moderator.api.csrf_token;
$.ajax({
method: "POST",
url: url,
dataType: "text",
contentType: "application/json",
data: JSON.stringify(dict),
error: moderator.api.handleapierror
});
},
set_multi: function(dict,reload) {
dict['_csrf_token'] = moderator.api.csrf_token;
$.ajax({
......
......@@ -20,12 +20,16 @@
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='videojs/video-js.css')}}">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='videojs/videojs.markers.css')}}">
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='videojs/videojs-resolution-switcher.css')}}">
{% if ismod() %}
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='bootstrap-multiselect.css')}}">
{% endif %}
<script src="{{url_for('static', filename='jquery.js')}}"></script>
<script src="{{url_for('static', filename='bootstrap/bootstrap.js')}}"></script>
<script src="{{url_for('static', filename='js.cookie.js')}}"></script>
{%if ismod() %}
<script src="{{url_for('static', filename='moderator.js')}}"></script>
<script src="{{url_for('static', filename='bootstrap-multiselect.js')}}"></script>
<script src="{{url_for('static', filename='plotly.min.js')}}"></script>
{% endif %}
<script src="{{url_for('static', filename='videojs/video.js')}}"></script>
......
......@@ -49,7 +49,13 @@
<tr><td>Short:</td><td>{{ moderator_editor(['courses',course.id,'short'], course.short) }}</td></tr>
<tr><td>Handle:</td><td>{{ moderator_editor(['courses',course.id,'handle'], course.handle) }}</td></tr>
<tr><td>Thema:</td><td>{{ moderator_editor(['courses',course.id,'subject'], course.subject) }}</td></tr>
<tr><td>Zuständig:</td><td>{{ moderator_editor(['courses',course.id,'responsible'], course.responsible) }}</td></tr>
<tr><td>Zuständig:</td><td>
<select id="responsible-select" multiple="multiple">
{% for user in responsible %}
<option value="{{ user.id }}"{% if user.responsible %} selected="selected"{% endif %}>{{ user.realname }}</option>
{% endfor %}
</select>
</td></tr>
<tr><td>Interne Bemerkungen:</td><td>{{ moderator_editor(['courses',course.id,'internal'], course.internal) }}</td></tr>
</tbody>
</table>
......@@ -138,6 +144,14 @@
</div>
</div>
<script>
{% if ismod() %}
$('#responsible-select').multiselect({enableCaseInsensitiveFiltering: true,
maxHeight: 200, numberDisplayed: 5, nonSelectedText: 'Niemand',
nSelectedText: 'ausgewählt', allSelectedText: false,
onChange: function(option, checked, select) {
moderator.api.set_map('responsible', {{ course.id }}, option.val(), checked);
}})
{% endif %}
$.ajax({
method: "GET",
url: "{{url_for('stats_generic', req="lecture_views", param=course.id)}}",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment