diff --git a/pedagogy/api.py b/pedagogy/api.py
index 24f5919b..91acb817 100644
--- a/pedagogy/api.py
+++ b/pedagogy/api.py
@@ -29,14 +29,11 @@ class UeController(ControllerBase):
response=UeSchema,
)
def fetch_from_utbm_api(
- self,
- code: str,
- lang: Query[str] = "fr",
- year: Query[Annotated[int, Ge(2010)] | None] = None,
+ self, code: str, year: Query[Annotated[int, Ge(2010)] | None] = None
):
"""Fetch UE data from the UTBM API and returns it after some parsing."""
with UtbmApiClient() as client:
- res = client.find_ue(lang, code, year)
+ res = client.find_ue(code, year)
if res is None:
raise NotFound
return res
diff --git a/pedagogy/schemas.py b/pedagogy/schemas.py
index c25df71f..592c134a 100644
--- a/pedagogy/schemas.py
+++ b/pedagogy/schemas.py
@@ -153,6 +153,7 @@ class UeFilterSchema(FilterSchema):
set[Literal["CS", "TM", "EC", "OM", "QC"]] | None,
FilterLookup("credit_type__in"),
] = None
+ is_open: bool | None = None
language: str = "FR"
department: Annotated[set[str] | None, FilterLookup("department__in")] = None
@@ -187,3 +188,11 @@ class UeFilterSchema(FilterSchema):
return Q()
value.add("AUTUMN_AND_SPRING")
return Q(semester__in=value)
+
+ def filter_is_open(self, value: bool | None) -> Q: # noqa: FBT001
+ """Filter by open/closed status."""
+ if value is None:
+ return Q()
+ if not value:
+ return Q(semester="CLOSED")
+ return ~Q(semester="CLOSED")
diff --git a/pedagogy/static/bundled/pedagogy/guide-index.ts b/pedagogy/static/bundled/pedagogy/guide-index.ts
index 9a3165a4..22987c4b 100644
--- a/pedagogy/static/bundled/pedagogy/guide-index.ts
+++ b/pedagogy/static/bundled/pedagogy/guide-index.ts
@@ -20,6 +20,7 @@ document.addEventListener("alpine:init", () => {
// biome-ignore lint/style/useNamingConvention: api is in snake_case
page_size: pageSizeDefault,
search: "",
+ hideClosedUes: true,
department: [] as string[],
// biome-ignore lint/style/useNamingConvention: api is in snake_case
credit_type: [] as CreditType[],
@@ -41,6 +42,7 @@ document.addEventListener("alpine:init", () => {
10,
);
this.search = url.get("search") || "";
+ this.hideClosedUes = [null, "true"].includes(url.get("hideClosed"));
this.department = url.getAll("department");
this.credit_type = url.getAll("credit_type") as CreditType[];
/* The semester is easier to use on the backend as an enum (spring/autumn/both/none)
@@ -61,7 +63,13 @@ document.addEventListener("alpine:init", () => {
this.to_change = [];
}, 50);
- const searchParams = ["search", "department", "credit_type", "semester"];
+ const searchParams = [
+ "search",
+ "hideClosedUes",
+ "department",
+ "credit_type",
+ "semester",
+ ];
const paginationParams = ["page", "page_size"];
for (const param of searchParams) {
this.$watch(param, () => {
@@ -93,6 +101,8 @@ document.addEventListener("alpine:init", () => {
// biome-ignore lint/style/useNamingConvention: api is in snake_case
credit_type: this.credit_type.length > 0 ? this.credit_type : undefined,
semester: this.semester.length > 0 ? this.semester : undefined,
+ // biome-ignore lint/style/useNamingConvention: api is snake_case
+ is_open: this.hideClosedUes ? true : undefined,
department: this.department.length > 0 ? this.department : undefined,
search: this.search || undefined,
},
diff --git a/pedagogy/templates/pedagogy/guide.jinja b/pedagogy/templates/pedagogy/guide.jinja
index 66e0f3b4..8cbfe58d 100644
--- a/pedagogy/templates/pedagogy/guide.jinja
+++ b/pedagogy/templates/pedagogy/guide.jinja
@@ -44,6 +44,10 @@
x-model.debounce.500ms="search"
/>
+