Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature colour preferences #48

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
16bec2f
Resolving issues filtering with no organizations
SamuelVch98 Jul 27, 2024
585ace3
use toast to display errors
SamuelVch98 Jul 29, 2024
0da87f0
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Jul 29, 2024
eada3ca
Fix small issues
SamuelVch98 Jul 30, 2024
7cae218
create unique file for toast and use it
SamuelVch98 Jul 30, 2024
4a633f6
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Jul 30, 2024
99f16d6
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Aug 20, 2024
cf3938d
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Sep 12, 2024
ad8658c
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Oct 1, 2024
1177b11
indicate the type of user to be displayed
SamuelVch98 Oct 9, 2024
9f8b4cc
Fix the bug that prevents you from changing organisation if none was …
SamuelVch98 Oct 9, 2024
ec2bdc1
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Oct 13, 2024
97023c8
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Oct 15, 2024
af8da85
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Oct 15, 2024
4db087a
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Oct 16, 2024
d40c27b
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Oct 17, 2024
7d55991
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Nov 28, 2024
cce7b20
Merge branch 'UCL-INGI:main' into main
SamuelVch98 Dec 3, 2024
df910c4
Add handsontable to the app
SamuelVch98 Jul 16, 2024
9cdc7e5
Finish integrating the handsontable panel
SamuelVch98 Jul 16, 2024
690e8b3
update README
SamuelVch98 Jul 16, 2024
841ef04
Fix PR request
SamuelVch98 Jul 26, 2024
d38814d
rabse + modifying the code to display several promoters
SamuelVch98 Oct 21, 2024
81dff63
remove useless code
SamuelVch98 Oct 7, 2024
f6ed468
Add a way of displaying the number of times an assistant has given a …
SamuelVch98 Oct 7, 2024
fdfc2cc
small fix
SamuelVch98 Oct 15, 2024
6287ba5
update legend in the table
SamuelVch98 Dec 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions assignment.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from sqlalchemy import func
from decorators import login_required, check_access_level
from db import db, User, Course, PreferenceAssignment, Teacher, Researcher, Organization, \
ResearcherSupervisor, Role, AssignmentDraft, AssignmentPublished
Expand All @@ -11,6 +12,7 @@

@assignment_bp.route('/assignments', methods=['GET'])
@login_required
@check_access_level(Role.ADMIN)
def assignments():
return render_template('assignment.html')

Expand Down Expand Up @@ -72,6 +74,7 @@ def load_data():

@assignment_bp.route('/publish_assignments', methods=['POST'])
@login_required
@check_access_level(Role.ADMIN)
def publish_assignments():
data = request.get_json()
if not data:
Expand Down Expand Up @@ -130,3 +133,27 @@ def publish_assignments():
except Exception as e:
db.session.rollback()
return jsonify({"error": f"Failed to publish assignments: {str(e)}"}), 500


def count_course_assignments():
# Counts the number of times each user has taught each course
current_year = get_current_year()
assignment_counts = (db.session.query(
AssignmentDraft.researcher_id,
AssignmentDraft.course_id,
func.count(AssignmentDraft.course_id).label('count')
).filter(AssignmentDraft.course_year < current_year).group_by(
AssignmentDraft.researcher_id,
AssignmentDraft.course_id
).distinct().all())

return assignment_counts


@assignment_bp.route('/course_assignments_count', methods=['GET'])
@login_required
@check_access_level(Role.ADMIN)
def get_course_assignments_count():
results = count_course_assignments()
return jsonify(
results=[{'user_id': user_id, 'course_id': course_id, 'count': count} for user_id, course_id, count in results])
2 changes: 1 addition & 1 deletion course.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def add_course():
@check_access_level(Role.ADMIN)
def courses(year):
courses = db.session.query(Course).filter_by(year=year).all()
return render_template('courses.html', courses=courses, current_year=year)
return render_template('courses.html', courses=courses, year=year)


@course_bp.route('/search_teachers')
Expand Down
1 change: 1 addition & 0 deletions db.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class Teacher(db.Model):

class PreferenceAssignment(db.Model):
__tablename__ = 'preference_assignment'
rank = db.Column(db.Integer, nullable=False)
id = db.Column(db.Integer, primary_key=True)
rank = db.Column(db.Integer, nullable=False)
course_id = db.Column(db.Integer, nullable=False)
Expand Down
37 changes: 32 additions & 5 deletions static/scripts/assignment_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ fetch('/assignment/load_data')
}
}

function getCountCourseAssignment() {
return fetch('/assignment/course_assignments_count')
.then(response => response.json())
.then(data => {
return data.results;
})
.catch(error => console.log(error))
}

const table = new Handsontable(document.getElementById("handsontable"), {
data: data,
fixedColumnsLeft: lenFixedHeaders,
Expand Down Expand Up @@ -277,16 +286,34 @@ fetch('/assignment/load_data')
});
}
},
afterRenderer: function (TD, row, col, prop, value, cellProperties) {
afterRenderer: async function (TD, row, col, prop, value, cellProperties) {
if ((col >= lenFixedHeaders && row >= lenFixedRowsText) && (row % 2 === 1) && (value !== '')) {
TD.style.fontWeight = 'bold'; // Bold text
TD.style.textAlign = 'left'; // Left alignment
}
//Style first col if needed
if (col === 0 && row < lenFixedRowsText) {
TD.style.fontWeight = 'bold';
TD.style.textAlign = 'left';

if (row >= lenFixedRowsText && col >= lenFixedHeaders && (row % 2 === 0)) {
const assignmentCount = await getCountCourseAssignment();

const user_id = this.getDataAtRowProp(row, 'researchers.id'); // Retrieves user ID
const course_id = this.getDataAtCol(col)[0]; // Retrieves the course ID

const assignment = assignmentCount.find(item => item.user_id === user_id && item.course_id === course_id);

if (assignment && value !== '' && value !== null) {
// Colouring based on the number of assignments
const count = assignment.count;
TD.style.color = 'black'; // to better see the preferences when the cell is coloured
if (count === 1) {
TD.style.backgroundColor = '#A0A7D5';
} else if (count === 2) {
TD.style.backgroundColor = '#555DB0';
} else if (count >= 3) {
TD.style.backgroundColor = '#1C2793';
}
}
}

//(row%2) === 1 to avoid empty lines
if (row >= lenFixedRowsText && (row % 2) === 0 && col < lenFixedHeaders) {
const rowValue = this.getDataAtRow(row);
Expand Down
27 changes: 23 additions & 4 deletions templates/assignment.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,38 @@ <h5>Course Header Colors :</h5>
<ul class="list-unstyled">
<li><span class="d-inline-block bg-success"
style="width: 16px; height: 16px; margin-right: 8px;"></span> Desired
number of assistants reached
number of assistants/loads reached
</li>
<li><span class="d-inline-block bg-danger"
style="width: 16px; height: 16px; margin-right: 8px;"></span>
Too many researchers assigned
Too many researchers/loads assigned
</li>
<li><span class="d-inline-block"
style="width: 16px; height: 16px; margin-right: 8px; background-color: #D8BFD8;"></span>
No number of assistants defined
</li>
</ul>
</div>
<div class="mt-4">
<h5>Cell Colors:</h5>
<ul class="list-unstyled">
<li>
<span class="d-inline-block"
style="width: 16px; height: 16px; margin-right: 8px; background-color: #A0A7D5;"></span>
The researcher has already given this course 1 time
</li>
<li>
<span class="d-inline-block"
style="width: 16px; height: 16px; margin-right: 8px; background-color: #555DB0;"></span>
The researcher has already given this course 2 times
</li>
<li>
<span class="d-inline-block"
style="width: 16px; height: 16px; margin-right: 8px; background-color: #1C2793;"></span>
The researcher has already given this course 3 times or more
</li>
</ul>
</div>
</div>
</div>
</div>
Expand All @@ -85,8 +105,7 @@ <h2 class="accordion-header" id="controlsHeading">
<div class="accordion-body">
<div class="d-grid gap-3">
<button type="button" class="btn btn-outline-dark btn-sm" id="button-export">Export
to
CSV
to CSV
</button>
<div class="row g-2">
<div class="col-6">
Expand Down
2 changes: 1 addition & 1 deletion templates/courses.html
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ <h4>Courses</h4>
<tr class="course-item"
data-organizations="{{ course.organizations | map(attribute='id') | join(',') }}">
<td>
<a href="{{ url_for("course.course_info", course_id=course.id, year=current_year) }}">
<a href="{{ url_for("course.course_info", course_id=course.id, year=year) }}">
{{ course.code }} - {{ course.title }}
</a>
</td>
Expand Down
13 changes: 13 additions & 0 deletions templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,19 @@
</li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="assignmentDropdown" role="button"
data-bs-toggle="dropdown" aria-expanded="false">
Assignments
</a>
<ul class="dropdown-menu" aria-labelledby="assignmentDropdown">
<li>
<a class="dropdown-item" id="assignmentList"
href="{{ url_for('assignment.assignments') }}"> Load Assignment
</a>
</li>
</ul>
</li>
{% endif %}
{% block additionalnav %}{% endblock %}
</ul>
Expand Down