Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 37 additions & 0 deletions course/static/course/course_filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
$(document).ready(function() {
const tagCheckboxes = $('#tag-filter-menu input[type="checkbox"]');
const courseCards = $('.card');

tagCheckboxes.prop('checked', false);

const audienceMap = {
'1': ['1'],
'2': ['2'],
'3': ['1', '2']
};

function applyFilters() {
const selectedAudiences = $('input[name="audience"]:checked')
.map(function () {
return this.value;
})
.get();

courseCards.each(function () {
const $card = $(this);
const cardAudience = String($card.data('audience'));

const cardAudiences = audienceMap[cardAudience] || [];

const audienceMatch =
selectedAudiences.length === 0 ||
selectedAudiences.some(a => cardAudiences.includes(a));

$card.toggle(audienceMatch);
});
}

tagCheckboxes.on('change', function() {
applyFilters();
});
});
2 changes: 1 addition & 1 deletion course/templates/course/_course_cards.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

{% for instance in instances %}
{% with instance_url=instance|url %}
<div class="frontpage card">
<div class="frontpage card" data-audience="{{ instance.enrollment_audience }}">
<div class="card-clickable">
<a href="{{ instance_url }}">
{% if not condensed %}
Expand Down
36 changes: 36 additions & 0 deletions course/templates/course/_filter_courses_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% load i18n %}
{% load course %}

{% load static %}
{% block scripts %}
<script src="{% static 'course/course_filter.js' %}"></script>
{% endblock %}

<form class="form-inline" id="course-filter-form">
<div class="d-flex gap-2">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton"
data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
{% translate "FILTER_COURSES" %}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton" id="tag-filter-menu">
<li class="p-2">
{% for tag in course_tag_choices %}
{% comment %} Don't show the "Aalto and MOOC" tag {% endcomment %}
{% if tag and tag.value != "3" %}
<div class="form-check">
<input class="form-check-input" type="checkbox" name="audience" value="{{ tag.value }}"
id="tag-{{ tag.value }}">
{% if tag.value == "1" %}
<label class="form-check-label" for="tag-{{ tag.value }}">{{ internal_user_label|safe }}</label>
{% elif tag.value == "2" %}
<label class="form-check-label" for="tag-{{ tag.value }}">{{ external_user_label|safe }}</label>
{% endif %}
</div>
{% endif %}
{% endfor %}
</li>
</ul>
</div>
</div>
</form>
5 changes: 4 additions & 1 deletion course/templates/course/archive.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
<div class="frontpage-panel">
<div class="page-header d-flex justify-content-between align-items-center flex-column flex-md-row">
<h1 class="align-self-start">{% translate "COURSE_ARCHIVE" %}</h1>
<div class="align-self-stretch mt-md-4">{% include "course/_search_courses_form.html" %}</div>
<div class="d-flex gap-2 align-self-stretch mt-md-4">
{% include "course/_filter_courses_form.html" %}
{% include "course/_search_courses_form.html" %}
</div>
</div>
{% regroup instances by starting_time|date:"Y" as instances_by_year %}

Expand Down
1 change: 1 addition & 0 deletions course/templates/course/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ <h2>{% translate "ALL_ONGOING_COURSES" %}</h2>
<a href="{{ url }}">{% translate "SEE_ALL_COURSES" %}</a>
</div>
</div>
<div class="mb-2 mt-md-4">{% include "course/_filter_courses_form.html" %}</div>
<div class="mb-2 mt-md-4">{% include "course/_search_courses_form.html" %}</div>
</div>
<div class="cards">
Expand Down
14 changes: 13 additions & 1 deletion course/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def get_common_objects(self):
self.welcome_text = settings_text('WELCOME_TEXT')
self.internal_user_label = settings_text('INTERNAL_USER_LABEL')
self.external_user_label = settings_text('EXTERNAL_USER_LABEL')
self.course_tag_choices = [{'value': str(value), 'label': label}
for value, label in CourseInstance.ENROLLMENT_AUDIENCE.choices]
self.show_language_toggle = True
my_instances = []
all_instances = []
Expand Down Expand Up @@ -92,6 +94,7 @@ def get_common_objects(self):
"all_instances",
"is_logged_in",
"show_language_toggle",
"course_tag_choices",
)


Expand All @@ -101,12 +104,21 @@ class ArchiveView(UserProfileView):

def get_common_objects(self):
super().get_common_objects()
self.internal_user_label = settings_text('INTERNAL_USER_LABEL')
self.external_user_label = settings_text('EXTERNAL_USER_LABEL')
self.course_tag_choices = [{'value': str(value), 'label': label}
for value, label in CourseInstance.ENROLLMENT_AUDIENCE.choices]
query = self.request.GET.get("search", "").strip()
self.instances = CourseInstance.objects.get_visible(self.request.user)
if query:
self.instances = self.instances.filter(Q(course__name__icontains=query) | Q(course__code__icontains=query))
self.show_language_toggle = True
self.note("instances", "show_language_toggle")
self.note("instances",
"show_language_toggle",
"course_tag_choices",
"internal_user_label",
"external_user_label",
)

class CourseInstancesView(UserProfileView):
access_mode = ACCESS.ANONYMOUS
Expand Down
52 changes: 28 additions & 24 deletions locale/en/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-12 10:31+0300\n"
"POT-Creation-Date: 2026-07-22 12:18+0300\n"
"PO-Revision-Date: 2021-05-27 14:47+0300\n"
"Last-Translator: Jimmy Lumiaho <jimmy.lumiaho@aalto.fi>\n"
"Language-Team: English<>\n"
Expand Down Expand Up @@ -1118,6 +1118,10 @@ msgstr ""
"Login is required to submit assignments, but you may anonymously explore the "
"course material."

#: course/templates/course/_filter_courses_form.html
msgid "FILTER_COURSES"
msgstr "Filter courses"

#: course/templates/course/_group_info.html
#, python-format
msgid "GROUP_SUBMITTING_WITH -- %(collaborators)s"
Expand Down Expand Up @@ -2187,8 +2191,8 @@ msgstr "point limits"
#: diploma/models.py
msgid "DIPLOMA_POINT_LIMITS_HELPTEXT"
msgstr ""
"A list of length 5 where each element is the required points for n:th "
"grade.The element can be a list of 2-tuples \n"
"A list of length 5 where each element is the required points for n:th grade."
"The element can be a list of 2-tuples \n"
"[[difficulty_level_a, points], [difficulty_level_b, points]]."

#: diploma/models.py
Expand Down Expand Up @@ -2505,8 +2509,8 @@ msgid "LABEL_GIT_ORIGIN_HELPTEXT"
msgstr ""
"The git address of the repository for the course materials. This address is "
"used in the 'git clone' command. Note: do not copy the address of the web "
"page in GitLab. Copy the 'Clone with SSH' address, for example, "
"git@version.aalto.fi:course/aplus-manual.git"
"page in GitLab. Copy the 'Clone with SSH' address, for example, git@version."
"aalto.fi:course/aplus-manual.git"

#: edit_course/course_forms.py
msgid "LABEL_GIT_BRANCH"
Expand Down Expand Up @@ -4246,6 +4250,7 @@ msgstr "Points required to pass"

#: exercise/templates/exercise/_exercise_info.html
#: exercise/templates/exercise/_user_results.html
#: exercise/templates/exercise/_user_toc.html
#: exercise/templates/exercise/exercise_plain.html
msgid "PERSONAL_EXTENDED_DEADLINE"
msgstr "Personal extended deadline"
Expand Down Expand Up @@ -5036,8 +5041,8 @@ msgstr "Show only students with submissions"
#: exercise/templates/exercise/staff/results.html
msgid "RESULTS_IGNORE_GRADING_MODE_LAST_TOOLTIP"
msgstr ""
"If this is checked, the points shown ignore the grading mode "
"&quot;last&quot; even if it has been enabled for some assignment."
"If this is checked, the points shown ignore the grading mode &quot;"
"last&quot; even if it has been enabled for some assignment."

#: exercise/templates/exercise/staff/results.html
msgid "RESULTS_IGNORE_GRADING_MODE_LAST"
Expand Down Expand Up @@ -5169,8 +5174,8 @@ msgstr ""
#, python-brace-format
msgid "PERSONAL_EXTENDED_DEADLINE_PLURAL -- {count}"
msgstr ""
"<span data-bs-toggle=\"tooltip\" title=\"Personal extended deadlines: {count}"
"\"><span class=\"bi-clock\" aria-hidden=\"true\"></span><span "
"<span data-bs-toggle=\"tooltip\" title=\"Personal extended deadlines: "
"{count}\"><span class=\"bi-clock\" aria-hidden=\"true\"></span><span "
"class=\"visually-hidden\">Personal extended deadlines: {count}</span></span>"

#: exercise/templatetags/exercise.py
Expand Down Expand Up @@ -5473,8 +5478,8 @@ msgstr "badge for the menu link (else service default)."
#: external_services/models.py
msgid "MENU_ITEM_MENU_ICON_CLASS_HELPTEXT"
msgstr ""
"Menu icon style name (else service default), e.g. star see https://"
"icons.getbootstrap.com/"
"Menu icon style name (else service default), e.g. star see https://icons."
"getbootstrap.com/"

#: external_services/models.py
msgid "LABEL_MENU_WEIGHT"
Expand Down Expand Up @@ -5605,24 +5610,23 @@ msgstr ""
#, python-format
msgid "EXTERNAL_SERVICE_SENT_ACCESS_TOKEN_COURSE_STAFF -- %(brand)s"
msgstr ""
"Moreover, we send this service a so-called <a href=\"https://"
"en.wikipedia.org/wiki/Access_token\" rel=\"noopener nofollow\" "
"target=\"_blank\" class=\"alert-link\">access token</a>, which gives the "
"service access to the %(brand)s API at your privilege level. If you don't "
"want that to happen, please contact %(brand)s administration."
"Moreover, we send this service a so-called <a href=\"https://en.wikipedia."
"org/wiki/Access_token\" rel=\"noopener nofollow\" target=\"_blank\" "
"class=\"alert-link\">access token</a>, which gives the service access to the "
"%(brand)s API at your privilege level. If you don't want that to happen, "
"please contact %(brand)s administration."

#: external_services/templates/external_services/_privacy.html
#, python-format
msgid "EXTERNAL_SERVICE_SENT_ACCESS_TOKEN_STUDENT -- %(brand)s"
msgstr ""
"Moreover, we send this service a so-called <a href=\"https://"
"en.wikipedia.org/wiki/Access_token\" rel=\"noopener nofollow\" "
"target=\"_blank\" class=\"alert-link\">access token</a>, which gives the "
"service access to the %(brand)s API at your privilege level. This means that "
"the service can, for example, access your student ID number and your "
"progress in the course, and submit solutions to assignments. The course "
"staff has enabled this feature and trust the service to operate with your "
"best interests in mind."
"Moreover, we send this service a so-called <a href=\"https://en.wikipedia."
"org/wiki/Access_token\" rel=\"noopener nofollow\" target=\"_blank\" "
"class=\"alert-link\">access token</a>, which gives the service access to the "
"%(brand)s API at your privilege level. This means that the service can, for "
"example, access your student ID number and your progress in the course, and "
"submit solutions to assignments. The course staff has enabled this feature "
"and trust the service to operate with your best interests in mind."

#: external_services/templates/external_services/_privacy.html
#, python-format
Expand Down
20 changes: 12 additions & 8 deletions locale/fi/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-06-12 10:31+0300\n"
"POT-Creation-Date: 2026-07-22 12:18+0300\n"
"PO-Revision-Date: 2019-08-14 12:16+0200\n"
"Last-Translator: Jimmy Lumiaho <jimmy.lumiaho@aalto.fi>\n"
"Language-Team: Finnish <>\n"
Expand Down Expand Up @@ -1125,6 +1125,10 @@ msgstr ""
"Tehtävien palauttaminen vaatii kirjautumisen järjestelmään, mutta voit "
"selailla kurssimateriaalia tunnistautumatta."

#: course/templates/course/_filter_courses_form.html
msgid "FILTER_COURSES"
msgstr "Suodata kursseja"

#: course/templates/course/_group_info.html
#, python-format
msgid "GROUP_SUBMITTING_WITH -- %(collaborators)s"
Expand Down Expand Up @@ -4256,6 +4260,7 @@ msgstr "Pistevaatimus"

#: exercise/templates/exercise/_exercise_info.html
#: exercise/templates/exercise/_user_results.html
#: exercise/templates/exercise/_user_toc.html
#: exercise/templates/exercise/exercise_plain.html
msgid "PERSONAL_EXTENDED_DEADLINE"
msgstr "Henkilökohtainen pidennetty määräaika"
Expand Down Expand Up @@ -5050,9 +5055,8 @@ msgstr "Näytä vain palauttaneet opiskelijat"
#: exercise/templates/exercise/staff/results.html
msgid "RESULTS_IGNORE_GRADING_MODE_LAST_TOOLTIP"
msgstr ""
"Jos tämä on valittuna, näytetyt pisteet eivät huomioi arvostelutapaa "
"&quot;vain viimeinen palautus&quot;, vaikka se olisi jossain tehtävässä "
"asetettuna."
"Jos tämä on valittuna, näytetyt pisteet eivät huomioi arvostelutapaa &quot;"
"vain viimeinen palautus&quot;, vaikka se olisi jossain tehtävässä asetettuna."

#: exercise/templates/exercise/staff/results.html
msgid "RESULTS_IGNORE_GRADING_MODE_LAST"
Expand Down Expand Up @@ -5494,8 +5498,8 @@ msgstr "Nimi (muuten palvelun oletus)."
#: external_services/models.py
msgid "MENU_ITEM_MENU_ICON_CLASS_HELPTEXT"
msgstr ""
"Ikonin tyyli (muuten palvelun oletus), esim. star katso https://"
"icons.getbootstrap.com/"
"Ikonin tyyli (muuten palvelun oletus), esim. star katso https://icons."
"getbootstrap.com/"

#: external_services/models.py
msgid "LABEL_MENU_WEIGHT"
Expand Down Expand Up @@ -5684,8 +5688,8 @@ msgstr ""
#: external_services/templates/external_services/_privacy.html
msgid "EXTERNAL_SERVICE_PRIVACY_GDPR_COMPLIANT"
msgstr ""
"Palvelu sijaitsee Euroopan talousalueen ulkopuolella, mutta noudattaa "
"GDPR:ää tietosuojailmoituksensa perusteella."
"Palvelu sijaitsee Euroopan talousalueen ulkopuolella, mutta noudattaa GDPR:"
"ää tietosuojailmoituksensa perusteella."

#: external_services/templates/external_services/_privacy.html
msgid "EXTERNAL_SERVICE_PRIVACY_GLOBAL"
Expand Down
Loading