Skip to content

Commit 05296ee

Browse files
authored
Issue#30 no way to read evaluations (#41)
1 parent a0d0c3d commit 05296ee

File tree

9 files changed

+212
-106
lines changed

9 files changed

+212
-106
lines changed

app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from config import config_bp
99
from course_preference import course_preference_bp
1010
from assignment import assignment_bp
11-
from db import db, Year, Organization, User, Course, Teacher, Researcher
11+
from db import db, Year, Organization, User, Course, Teacher, Researcher, Evaluation
1212
from decorators import *
1313
from flask import Flask, render_template, session, request
1414
from enums import *
@@ -57,7 +57,7 @@ def index(): # put application's code here
5757
current_year = get_current_year()
5858
user = db.session.query(User).filter_by(email=session['email']).first()
5959
courses_teacher = db.session.query(Course).filter_by(year=current_year).join(Teacher).filter(Teacher.user_id == user.id).all()
60-
return render_template("home.html", user=user, courses=courses_teacher)
60+
return render_template("home.html", user=user, courses=courses_teacher, evaluations=user.evaluations)
6161

6262

6363
if __name__ == '__main__':

course.py

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,10 @@ def course_info(course_id, year):
147147
all_years = db.session.query(Course).filter_by(id=course.id).distinct(Course.year).order_by(
148148
Course.year.desc()).all()
149149

150-
return render_template('course_info.html', course=course, all_years=all_years, current_year=year)
150+
evaluations = db.session.query(Evaluation).filter_by(course_id=course_id).all() or []
151+
152+
return render_template('course_info.html', course=course, all_years=all_years, current_year=year,
153+
evaluations=evaluations)
151154

152155

153156
@course_bp.route('/update_course_info', methods=['POST'])
@@ -265,21 +268,45 @@ def add_duplicate_course():
265268
return redirect(url_for('course.course_info', course_id=course_id, year=year))
266269

267270

268-
@course_bp.route('/evaluations/<int:user_id>/<int:current_year>')
271+
@course_bp.route('/evaluation/<int:evaluation_id>')
272+
@login_required
273+
def course_evaluation(evaluation_id):
274+
evaluation = db.session.query(Evaluation).get(evaluation_id)
275+
courses = db.session.query(Course).filter_by(year=evaluation.course_year).all()
276+
277+
course = evaluation.course
278+
user = db.session.query(User).filter_by(id=session['user_id']).first()
279+
teachers = course.course_teacher
280+
281+
# Accessible only to the admin, the evaluation creator and the course teachers
282+
if (not user.is_admin) and (user.id != evaluation.user_id) and (user.id not in [teacher.user_id for teacher in teachers]):
283+
flash("You are not allowed to access this page", "danger")
284+
return redirect(url_for('course.courses', course_id=course.id, year=course.year))
285+
286+
return render_template('evaluations.html', evaluation=evaluation, current_year=evaluation.course_year,
287+
courses=courses)
288+
289+
290+
@course_bp.route('/evaluations/<int:current_year>')
269291
@login_required
270-
def evaluations(user_id, current_year):
292+
@check_access_level(Role.RESEARCHER)
293+
def user_evaluation(current_year):
271294
courses = db.session.query(Course).filter_by(year=current_year).all()
295+
user_id = session.get('user_id')
272296

273-
return render_template('evaluations.html', courses=courses, current_year=current_year, user_id=user_id)
297+
return render_template('evaluations.html', courses=courses, current_year=current_year, user_id=user_id,
298+
evaluation=None)
274299

275300

276-
@course_bp.route('/create_evaluations/<int:user_id>/<int:current_year>', methods=['POST'])
301+
@course_bp.route('/create_evaluations/<int:current_year>', methods=['POST'])
277302
@login_required
278-
def create_evaluation(user_id, current_year):
303+
@check_access_level(Role.RESEARCHER)
304+
def create_evaluation(current_year):
279305
form = request.form
280306
if not form:
281307
return make_response("Problem with form request", 500)
282308

309+
user_id = session.get('user_id')
283310
course_id = request.form.get('course_id')
284311
tasks = request.form.getlist('tasks[]')
285312
other_task = request.form.get('other_task')
@@ -290,9 +317,6 @@ def create_evaluation(user_id, current_year):
290317
if not all([course_id, evaluation_hour, workload, comment is not None]):
291318
return make_response("Missing required fields", 400)
292319

293-
if other_task:
294-
tasks.append(other_task)
295-
296320
try:
297321
existing_evaluation = db.session.query(Evaluation).filter_by(course_id=course_id, course_year=current_year,
298322
user_id=user_id).first()
@@ -304,11 +328,12 @@ def create_evaluation(user_id, current_year):
304328
flash('Evaluation created successfully!', 'success')
305329

306330
new_evaluation = Evaluation(course_id=course_id, course_year=current_year, user_id=user_id, task=tasks,
307-
nbr_hours=evaluation_hour, workload=workload, comment=comment)
331+
other_task=other_task, nbr_hours=evaluation_hour, workload=workload,
332+
comment=comment)
308333
db.session.add(new_evaluation)
309334
db.session.commit()
310335
except Exception as e:
311336
db.session.rollback()
312337
flash(f'An error occurred: {str(e)}', 'danger')
313338

314-
return redirect(url_for('course.evaluations', user_id=user_id, current_year=current_year))
339+
return redirect(url_for('course.user_evaluation', user_id=user_id, current_year=current_year))

db.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,17 +214,24 @@ class AssignmentPublished(db.Model):
214214
class Evaluation(db.Model):
215215
__tablename__ = 'evaluation'
216216

217-
course_id = db.Column(db.Integer, primary_key=True)
218-
course_year = db.Column(db.Integer, primary_key=True)
219-
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
217+
id = db.Column(db.Integer, primary_key=True)
218+
course_id = db.Column(db.Integer, nullable=False)
219+
course_year = db.Column(db.Integer, nullable=False)
220+
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
220221
task = db.Column(db.JSON, nullable=False)
222+
other_task = db.Column(db.String(200))
221223
nbr_hours = db.Column(db.String(10), nullable=False)
222224
workload = db.Column(db.String(10), nullable=False)
223225
comment = db.Column(db.String(500))
224226

225227
__table_args__ = (
228+
db.UniqueConstraint('course_id', 'course_year', 'user_id', name='unique_course_year_user'),
226229
db.ForeignKeyConstraint(
227230
['course_id', 'course_year'],
228231
['course.id', 'course.year']
229232
),
230233
)
234+
235+
course = db.relationship('Course', backref=db.backref('evaluations', lazy=True))
236+
user = db.relationship('User',
237+
backref=db.backref('evaluations', lazy=True, order_by='desc(Evaluation.course_year)'))

templates/course_info.html

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -43,42 +43,68 @@ <h2 class="sub-header">Assistant(s) for this year ({{ course.year }} - {{ course
4343
</tbody>
4444
</table>
4545
<div class="container-fluid">
46-
<h2 class="sub-header">History</h2>
47-
<hr>
46+
<div class="card">
47+
<div class="card-body">
48+
<h2 class="sub-header">History</h2>
49+
<hr>
4850

49-
<!-- Nav tabs -->
50-
<ul class="nav nav-tabs" id="historyTabs" role="tablist">
51-
<li class="nav-item">
52-
<a class="nav-link active" id="assistants-tab" data-bs-toggle="tab" href="#assistants" role="tab"
53-
aria-controls="assistants" aria-selected="true">Assistants</a>
54-
</li>
55-
<li class="nav-item">
56-
<a class="nav-link" id="evaluations-tab" data-bs-toggle="tab" href="#evaluations" role="tab"
57-
aria-controls="evaluations" aria-selected="false">Evaluations</a>
58-
</li>
59-
</ul>
51+
<!-- Nav tabs -->
52+
<ul class="nav nav-tabs" id="historyTabs{{ course.year }}" role="tablist">
53+
<li class="nav-item">
54+
<a class="nav-link active" id="assistants-tab-{{ course.year }}" data-bs-toggle="tab" href="#assistants-{{ course.year }}"
55+
role="tab"
56+
aria-controls="assistants" aria-selected="true">Assistants</a>
57+
</li>
58+
<li class="nav-item">
59+
<a class="nav-link" id="evaluations-tab-{{ course.year }}" data-bs-toggle="tab" href="#evaluations-{{ course.year }}"
60+
role="tab"
61+
aria-controls="evaluations" aria-selected="false">Evaluations</a>
62+
</li>
63+
</ul>
6064

61-
<!-- Tab panes -->
62-
<div class="tab-content">
63-
<!-- Assistants Pane -->
64-
<div class="tab-pane fade show active" id="assistants" role="tabpanel"
65-
aria-labelledby="assistants-tab">
66-
<table class="table table-hover mt-3">
67-
<thead>
68-
<tr>
69-
<th>Last name</th>
70-
<th>First name</th>
71-
</tr>
72-
</thead>
73-
<tbody>
74-
</tbody>
75-
</table>
76-
</div>
77-
<!-- Evaluations Pane -->
78-
<div class="tab-pane fade show" id="evaluations" role="tabpanel" aria-labelledby="evaluations-tab">
79-
<!-- Content for Evaluations -->
80-
<br>
81-
<p>Content for evaluations will go here.</p>
65+
<!-- Tab panes -->
66+
<div class="tab-content">
67+
<!-- Assistants Pane -->
68+
<div class="tab-pane fade show active" id="assistants-{{ course.year }}" role="tabpanel"
69+
aria-labelledby="assistants-tab-{{ course.year }}">
70+
<table class="table table-hover mt-3">
71+
<thead>
72+
<tr>
73+
<th>Last name</th>
74+
<th>First name</th>
75+
</tr>
76+
</thead>
77+
<tbody>
78+
</tbody>
79+
</table>
80+
</div>
81+
<!-- Evaluations Pane -->
82+
<div class="tab-pane fade show" id="evaluations-{{ course.year }}" role="tabpanel"
83+
aria-labelledby="evaluations-tab-{{ course.year }}">
84+
<!-- Content for Evaluations -->
85+
<table class="table table-hover" id="evaluationTable">
86+
<thead>
87+
<tr>
88+
<th>Evaluation id</th>
89+
</tr>
90+
</thead>
91+
<tbody>
92+
{% if not evaluations %}
93+
<tr>
94+
<td>No evaluations for this year.</td>
95+
</tr>
96+
{% endif %}
97+
{% for evaluation in evaluations %}
98+
<tr>
99+
<td><a href="{{ url_for('course.course_evaluation', evaluation_id=evaluation.id) }}">
100+
{{ evaluation.id }}</a>
101+
</td>
102+
</tr>
103+
{% endfor %}
104+
</tbody>
105+
</table>
106+
</div>
107+
</div>
82108
</div>
83109
</div>
84110
</div>

templates/course_info_template.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
{% block additionalpageheader %}
2+
<style>
3+
a {
4+
text-decoration: none;
5+
color: black;
6+
}
7+
</style>
8+
{% endblock %}
19
<input type="hidden" name="course_id" value="{{ course.id }}">
210
<div class="row">
311
<div class="col-lg-4 col-md-6">

templates/course_template.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
{% block pagetitle %}Course informations{% endblock %}
33
{% block additionalpageheader %}
44
<style>
5-
.badge a {
6-
color: black;
7-
text-decoration: none;
8-
}
9-
105
.badge a:hover {
116
color: red;
127
}

templates/evaluations.html

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,20 @@ <h2>Evaluation form</h2>
88
<p>Please note that your answers are confidential and that if there are any problems or changes we have to
99
report, we'll do so anonymously.</p>
1010
<hr>
11-
<form action="{{ url_for("course.create_evaluation", current_year=current_year, user_id=user_id) }}"
11+
<form action="{{ url_for("course.create_evaluation", current_year=current_year) }}"
1212
method="POST">
1313
<strong>If you gave two courses during this semester, choose one of them and create a new evaluation for the
1414
second one </strong>
1515
<div class="form-group">
1616
<br>
17-
<label for="course1">1. What is the course you gave this semester?</label>
18-
<select class="form-control" id="course" name="course_id" required>
17+
<label for="course">1. What is the course you gave this semester?</label>
18+
<select class="form-control" id="course" name="course_id" required
19+
{% if evaluation %} disabled {% endif %}>
1920
{% for course in courses %}
20-
<option value="{{ course.id }}">{{ course.code }} - {{ course.title }}</option>
21+
<option value="{{ course.id }}"
22+
{% if evaluation and evaluation.course_id == course.id %} selected {% endif %}>
23+
{{ course.code }} - {{ course.title }}
24+
</option>
2125
{% endfor %}
2226
</select>
2327
</div>
@@ -28,32 +32,37 @@ <h2>Evaluation form</h2>
2832
{% for task in tasks %}
2933
<div class="form-check">
3034
<input class="form-check-input" type="checkbox" name="tasks[]" id="{{ task }}"
31-
value="{{ task }}">
35+
value="{{ task }}"
36+
{% if evaluation and task in evaluation.task %} checked disabled {% endif %}>
3237
<label class="form-check-label" for="{{ task }}">{{ task }}</label>
3338
</div>
3439
{% endfor %}
3540
<div class="form-check">
36-
<input class="form-check-input" type="checkbox" name="tasks[]" id="other" value="Other">
41+
<input class="form-check-input" type="checkbox" name="tasks[]" id="other" value="Other"
42+
{% if evaluation and "Other" in evaluation.task %} checked disabled{% endif %}>
3743
<input class="form-control" type="text" name="other_task" id="other_task" placeholder="Other"
38-
value="">
44+
value="{{ evaluation.other_task if evaluation else '' }}" {% if evaluation %} disabled {% endif %}>
3945
</div>
4046
</div>
4147
<br>
4248
<div class="form-group">
4349
<label>3. On average, how many hours a week were devoted to this course (preparation, time in exercise
4450
sessions, projects, etc., all included)?</label><br>
45-
<select class="form-control" name="evaluation_hour" required>
51+
<select class="form-control" name="evaluation_hour" required {% if evaluation %} disabled {% endif %}>
4652
{% for hour in evaluation_hour %}
47-
<option value="{{ hour }}">{{ hour }}</option>
53+
<option value="{{ hour }}" {% if evaluation and evaluation.nbr_hours == hour %}
54+
selected {% endif %}>{{ hour }}</option>
4855
{% endfor %}
4956
</select>
5057
</div>
5158
<br>
5259
<div class="form-group">
5360
<label>4. How would you rate your workload for this course?</label><br>
54-
<select class="form-control" name="workload" required>
61+
<select class="form-control" name="workload" required {% if evaluation %} disabled {% endif %}>
5562
{% for workload in workloads %}
56-
<option value="{{ workload }}">{{ workload }}</option>
63+
<option value="{{ workload }}"
64+
{% if evaluation and evaluation.workload == workload %} selected {% endif %}>
65+
{{ workload }}</option>
5766
{% endfor %}
5867
</select>
5968
</div>
@@ -62,10 +71,14 @@ <h2>Evaluation form</h2>
6271
<label for="comments">5. Do you have any comments to make about the course load? (For example: if you
6372
know that the course will change a lot less next year, or will be strongly
6473
reorganized,...)</label><br>
65-
<textarea class="form-control" id="comment" name="comment" rows="3"></textarea>
74+
<textarea class="form-control" id="comment" name="comment"
75+
rows="3" {% if evaluation %} disabled {% endif %}>{{ evaluation.comment if evaluation else '' }}</textarea>
6676
</div>
77+
78+
{% if not evaluation %}
6779
<br>
6880
<button type="submit" class="btn btn-primary">Submit</button>
81+
{% endif %}
6982
</form>
7083
</div>
7184
{% endblock %}

0 commit comments

Comments
 (0)