From 16bec2f5e1b5b69789435988c578d5c1f3651186 Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Sat, 27 Jul 2024 21:43:28 +0200 Subject: [PATCH 01/10] Resolving issues filtering with no organizations --- course.py | 14 ++++++++++++++ static/scripts/util.js | 14 +++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/course.py b/course.py index 36da38c..3da9bc3 100644 --- a/course.py +++ b/course.py @@ -65,6 +65,11 @@ def assign_teachers_to_course(course_id, course_year, assigned_teachers): raise e +def count_org(orgs): + if len(orgs) == 0: + return "Please select at least one organization", 400 + + @course_bp.route('/add_course', methods=['POST', 'GET']) @login_required @check_access_level(Role.ADMIN) @@ -87,6 +92,9 @@ def add_course(): language = request.form['language'] organization_ids = request.form.getlist('organization_code[]') + check_orgs = count_org(organization_ids) + if check_orgs: + return make_response(*check_orgs) try: is_course = db.session.query(Course).filter(Course.code == code, @@ -167,6 +175,9 @@ def update_course_info(): nbr_monitor_students = request.form['nbr_monitor_students'] assigned_teachers = request.form.getlist('assigned_teachers[]') organisation_code = request.form.getlist('organization_code[]') + check_orgs = count_org(organisation_code) + if check_orgs: + return make_response(*check_orgs) course = db.session.query(Course).filter(Course.id == course_id, Course.year == year).first() if not course: @@ -239,6 +250,9 @@ def add_duplicate_course(): course_id = request.form['course_id'] assigned_teachers = request.form.getlist('assigned_teachers[]') organisation_code = request.form.getlist('organization_code[]') + check_orgs = count_org(organisation_code) + if check_orgs: + return make_response(*check_orgs) try: duplicate_course = Course(id=course_id, code=code, title=title, quadri=quadri, year=year, diff --git a/static/scripts/util.js b/static/scripts/util.js index 6856b2e..e0b7cec 100644 --- a/static/scripts/util.js +++ b/static/scripts/util.js @@ -75,18 +75,10 @@ function filter(page) { if (activeOrganizations.length > 0) { items.each(function () { - let organizations; - let showItem; - - if (page === "course") { - organizations = $(this).data('organizations').toString().split(','); - showItem = activeOrganizations.some(org => organizations.includes(org.toString())); - } - else if (page === "user") { - organizations = $(this).data('organizations'); - showItem = activeOrganizations.includes(organizations); - } + let organizations = $(this).data('organizations').toString().split(','); + let showItem = activeOrganizations.some(org => organizations.includes(org.toString())); + // Show or hide the item based on whether it belongs to any active organization if (showItem) { $(this).show(); } else { From 585ace3daa0cfc7793086573913faff95df46685 Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Mon, 29 Jul 2024 20:22:54 +0200 Subject: [PATCH 02/10] use toast to display errors --- course.py | 21 ++++++++++----------- templates/add_course.html | 1 + templates/course_template.html | 1 + templates/toast_check_orgs.html | 29 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 templates/toast_check_orgs.html diff --git a/course.py b/course.py index 3da9bc3..fe0a969 100644 --- a/course.py +++ b/course.py @@ -66,8 +66,7 @@ def assign_teachers_to_course(course_id, course_year, assigned_teachers): def count_org(orgs): - if len(orgs) == 0: - return "Please select at least one organization", 400 + return len(orgs) == 0 @course_bp.route('/add_course', methods=['POST', 'GET']) @@ -92,9 +91,9 @@ def add_course(): language = request.form['language'] organization_ids = request.form.getlist('organization_code[]') - check_orgs = count_org(organization_ids) - if check_orgs: - return make_response(*check_orgs) + if count_org(organization_ids): + flash("Please select at least one organization", "danger") + return redirect(url_for('course.add_course')) try: is_course = db.session.query(Course).filter(Course.code == code, @@ -175,9 +174,9 @@ def update_course_info(): nbr_monitor_students = request.form['nbr_monitor_students'] assigned_teachers = request.form.getlist('assigned_teachers[]') organisation_code = request.form.getlist('organization_code[]') - check_orgs = count_org(organisation_code) - if check_orgs: - return make_response(*check_orgs) + if count_org(organisation_code): + flash("Please select at least one organization", "danger") + return redirect(url_for('course.course_info', course_id=course_id)) course = db.session.query(Course).filter(Course.id == course_id, Course.year == year).first() if not course: @@ -250,9 +249,9 @@ def add_duplicate_course(): course_id = request.form['course_id'] assigned_teachers = request.form.getlist('assigned_teachers[]') organisation_code = request.form.getlist('organization_code[]') - check_orgs = count_org(organisation_code) - if check_orgs: - return make_response(*check_orgs) + if count_org(organisation_code): + flash("Please select at least one organization", "danger") + return redirect(url_for('course.duplicate_course', course_id=course_id, year=year)) try: duplicate_course = Course(id=course_id, code=code, title=title, quadri=quadri, year=year, diff --git a/templates/add_course.html b/templates/add_course.html index 4b45b11..5e3cf8f 100644 --- a/templates/add_course.html +++ b/templates/add_course.html @@ -13,6 +13,7 @@ {% endblock %} {% block pagecontent %} + {% include "toast_check_orgs.html" %}

New Course

diff --git a/templates/course_template.html b/templates/course_template.html index e8fa3ac..dedc6ca 100644 --- a/templates/course_template.html +++ b/templates/course_template.html @@ -14,6 +14,7 @@ {% endblock %} {% block pagecontent %} + {% include "toast_check_orgs.html" %}

diff --git a/templates/toast_check_orgs.html b/templates/toast_check_orgs.html new file mode 100644 index 0000000..c0949cf --- /dev/null +++ b/templates/toast_check_orgs.html @@ -0,0 +1,29 @@ +
+ {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + + {% endif %} + {% endwith %} +
+{% block additionalfooter %} + +{% endblock %} \ No newline at end of file From eada3ca914b062e131dc6f40349d43bc0d8aed0d Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Tue, 30 Jul 2024 13:07:59 +0200 Subject: [PATCH 03/10] Fix small issues --- course.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/course.py b/course.py index fe0a969..ead2686 100644 --- a/course.py +++ b/course.py @@ -65,10 +65,6 @@ def assign_teachers_to_course(course_id, course_year, assigned_teachers): raise e -def count_org(orgs): - return len(orgs) == 0 - - @course_bp.route('/add_course', methods=['POST', 'GET']) @login_required @check_access_level(Role.ADMIN) @@ -91,7 +87,7 @@ def add_course(): language = request.form['language'] organization_ids = request.form.getlist('organization_code[]') - if count_org(organization_ids): + if not len(organization_ids): flash("Please select at least one organization", "danger") return redirect(url_for('course.add_course')) @@ -174,7 +170,7 @@ def update_course_info(): nbr_monitor_students = request.form['nbr_monitor_students'] assigned_teachers = request.form.getlist('assigned_teachers[]') organisation_code = request.form.getlist('organization_code[]') - if count_org(organisation_code): + if not len(organisation_code): flash("Please select at least one organization", "danger") return redirect(url_for('course.course_info', course_id=course_id)) @@ -249,7 +245,7 @@ def add_duplicate_course(): course_id = request.form['course_id'] assigned_teachers = request.form.getlist('assigned_teachers[]') organisation_code = request.form.getlist('organization_code[]') - if count_org(organisation_code): + if not len(organisation_code): flash("Please select at least one organization", "danger") return redirect(url_for('course.duplicate_course', course_id=course_id, year=year)) From 7cae21838595e6a277b0edc179ca2230cab9f456 Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Tue, 30 Jul 2024 15:22:27 +0200 Subject: [PATCH 04/10] create unique file for toast and use it --- templates/add_course.html | 2 +- templates/course_template.html | 2 +- templates/evaluations.html | 28 +--------------------------- templates/home.html | 24 +----------------------- templates/toast.html | 27 +++++++++++++++++++++++++++ templates/toast_check_orgs.html | 29 ----------------------------- 6 files changed, 31 insertions(+), 81 deletions(-) create mode 100644 templates/toast.html delete mode 100644 templates/toast_check_orgs.html diff --git a/templates/add_course.html b/templates/add_course.html index 5e3cf8f..481f3db 100644 --- a/templates/add_course.html +++ b/templates/add_course.html @@ -13,7 +13,7 @@ {% endblock %} {% block pagecontent %} - {% include "toast_check_orgs.html" %} + {% include "toast.html" %}

New Course

diff --git a/templates/course_template.html b/templates/course_template.html index dedc6ca..1438b82 100644 --- a/templates/course_template.html +++ b/templates/course_template.html @@ -14,7 +14,7 @@ {% endblock %} {% block pagecontent %} - {% include "toast_check_orgs.html" %} + {% include "toast.html" %}

diff --git a/templates/evaluations.html b/templates/evaluations.html index 5bd3202..099a115 100644 --- a/templates/evaluations.html +++ b/templates/evaluations.html @@ -1,26 +1,7 @@ {% extends "layout.html" %} {% block pagetitle %}Evaluation form{% endblock %} {% block pagecontent %} -
-
- {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - {% for category, message in messages %} - - {% endfor %} - {% endif %} - {% endwith %} -
-
+ {% include "toast.html" %}

Evaluation form

@@ -103,11 +84,4 @@

Focus on your (first) course of the semester

{% endblock %} -{% block additionalfooter %} - -{% endblock %} diff --git a/templates/home.html b/templates/home.html index 1997232..5229658 100644 --- a/templates/home.html +++ b/templates/home.html @@ -2,22 +2,7 @@ {% block pagetitle %}Home Page{% endblock %} {% block pagecontent %}
-
- {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - {% for category, message in messages %} -
-
- Notification -
-
- {{ message }} -
-
- {% endfor %} - {% endif %} - {% endwith %} -
+ {% include "toast.html" %}

{{ session.first_name }} {{ session.name }}


{% if user.is_researcher %} @@ -113,11 +98,4 @@

Course assignments for my researchers

{% endif %} -{% endblock %} -{% block additionalfooter %} - {% endblock %} \ No newline at end of file diff --git a/templates/toast.html b/templates/toast.html new file mode 100644 index 0000000..d745e2b --- /dev/null +++ b/templates/toast.html @@ -0,0 +1,27 @@ +
+
+ {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} + + {% endfor %} + {% endif %} + {% endwith %} +
+
+{% block additionalfooter %} + +{% endblock %} diff --git a/templates/toast_check_orgs.html b/templates/toast_check_orgs.html deleted file mode 100644 index c0949cf..0000000 --- a/templates/toast_check_orgs.html +++ /dev/null @@ -1,29 +0,0 @@ -
- {% with messages = get_flashed_messages(with_categories=true) %} - {% if messages %} - - {% endif %} - {% endwith %} -
-{% block additionalfooter %} - -{% endblock %} \ No newline at end of file From 1177b1192418adf37c7b666da3963e710343a9b8 Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Wed, 9 Oct 2024 13:01:20 +0200 Subject: [PATCH 05/10] indicate the type of user to be displayed --- templates/users.html | 2 +- user.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/users.html b/templates/users.html index 03878d1..6580e3f 100644 --- a/templates/users.html +++ b/templates/users.html @@ -10,7 +10,7 @@ {% endblock %} {% block pagecontent %}
-

List of Users

+

List of {{ list_name }}


{% include 'filter.html' %}
diff --git a/user.py b/user.py index 8c63d4b..7c6e1c5 100644 --- a/user.py +++ b/user.py @@ -80,18 +80,23 @@ def add_user(): @check_access_level(Role.ADMIN) def users(user_type): base_query = db.session.query(User).filter() + list_name = '' if user_type == 'teacher': base_query = base_query.filter(User.is_teacher == True, User.active == True) + list_name = 'Teachers' elif user_type == 'researcher': base_query = base_query.filter(User.is_researcher == True, User.active == True) + list_name = 'Researchers' elif user_type == 'archived': base_query = base_query.filter(User.active == False) + list_name = 'Archived Users' elif user_type == 'other': base_query = base_query.filter(User.active == True, User.is_teacher == False, User.is_researcher == False) + list_name = 'Other Users' all_users = base_query.all() - return render_template('users.html', users=all_users, user_type=user_type) + return render_template('users.html', users=all_users, user_type=user_type, list_name=list_name) def is_allowed_user(user_id): From 9f8b4cc244c992f0f61803c34a912609408febee Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Wed, 9 Oct 2024 13:06:15 +0200 Subject: [PATCH 06/10] Fix the bug that prevents you from changing organisation if none was selected --- templates/user_profile.html | 11 +++++------ user.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/templates/user_profile.html b/templates/user_profile.html index 366882b..b065e94 100644 --- a/templates/user_profile.html +++ b/templates/user_profile.html @@ -70,13 +70,12 @@

Your informations

disabled {% endif %}> {% if requested_user.organization == None and current_user %} - {% else %} - {% for code in organizations_code %} - - {% endfor %} {% endif %} + {% for code in organizations_code %} + + {% endfor %} diff --git a/user.py b/user.py index 7c6e1c5..a525c7f 100644 --- a/user.py +++ b/user.py @@ -79,7 +79,7 @@ def add_user(): @login_required @check_access_level(Role.ADMIN) def users(user_type): - base_query = db.session.query(User).filter() + base_query = db.session.query(User) list_name = '' if user_type == 'teacher': From 14ff12086f1a310b884f1ecfab375a447baf6fea Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Wed, 25 Sep 2024 19:25:04 +0200 Subject: [PATCH 07/10] Define the current year statically # Conflicts: # config.py # course.py # templates/layout.html # util.py --- templates/layout.html | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/templates/layout.html b/templates/layout.html index 0e4afbf..27b42fa 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -120,21 +120,6 @@
{% block pagecontent %}{% endblock %}
-{% block additionalfooter %} - -{% endblock %} +{% block additionalfooter %}{% endblock %} From ae962fc5a0b3c83d7c2fff6589107ebb07362dac Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Wed, 9 Oct 2024 16:54:15 +0200 Subject: [PATCH 08/10] Fixed the bug that wasn't updating assigned teachers correctly # Conflicts: # course.py --- course.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/course.py b/course.py index 3072d1f..a1d231f 100644 --- a/course.py +++ b/course.py @@ -125,10 +125,8 @@ def search_teachers(): if not validate_string_pattern(search_term): return make_response("Invalid search term", 400) - teachers = db.session.query(User).join(Teacher).filter( - User.active == True, - User.name.ilike(f'%{search_term}%') - ).all() + teachers = db.session.query(User).filter(User.active == True, User.is_teacher == True, + User.name.ilike(f'%{search_term}%')).all() results = [{'id': teacher.id, 'text': f'{teacher.name} {teacher.first_name}'} for teacher in teachers] return jsonify(results) From 24d59615f1b8b9a49c3b54d86b711f969d07391d Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Wed, 16 Oct 2024 19:19:27 +0200 Subject: [PATCH 09/10] small fix + rebase # Conflicts: # user.py --- user.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/user.py b/user.py index 961d32c..a76f810 100644 --- a/user.py +++ b/user.py @@ -138,7 +138,6 @@ def user_profile(user_id, current_year): if researcher: preferences = db.session.query(PreferenceAssignment).filter_by(researcher_id=researcher.id, course_year=current_year).all() - courses = [] if current_user and requested_user.organization: courses = db.session.query(Course).filter(Course.year == current_year, @@ -201,7 +200,6 @@ def update_user_profile(user_id): user.organization_id = organization_code user.is_admin = is_admin user.is_teacher = is_teacher - user.is_researcher = is_researcher if is_researcher: if researcher is None: create_researcher(user.id, researcher_type, max_loads) From 0bc3240102c9720a48f9345306f96fce8d02d655 Mon Sep 17 00:00:00 2001 From: Samuel Van Campenhout Date: Tue, 22 Oct 2024 15:35:50 +0200 Subject: [PATCH 10/10] fix requested changes --- course.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/course.py b/course.py index a1d231f..2f64c6c 100644 --- a/course.py +++ b/course.py @@ -1,3 +1,5 @@ +from sqlalchemy import func + from decorators import login_required, check_access_level from db import db, User, Course, Teacher, Organization, Evaluation, Configuration, Role from flask import Blueprint, render_template, flash, url_for, request, make_response, redirect, \ @@ -123,10 +125,13 @@ def search_teachers(): search_term = request.args.get('q', '') if not validate_string_pattern(search_term): - return make_response("Invalid search term", 400) + flash("Invalid search term", "danger") - teachers = db.session.query(User).filter(User.active == True, User.is_teacher == True, - User.name.ilike(f'%{search_term}%')).all() + teachers = db.session.query(User).filter( + User.active == True, + User.is_teacher == True, + func.concat(User.name, ' ', User.first_name).ilike(f'%{search_term}%') + ).all() results = [{'id': teacher.id, 'text': f'{teacher.name} {teacher.first_name}'} for teacher in teachers] return jsonify(results)