From ab7a557d4eca565871aedde12f18f5052c6f25a1 Mon Sep 17 00:00:00 2001
From: flange <38500-flange@users.noreply.git.rwth-aachen.de>
Date: Mon, 31 Mar 2025 13:53:47 +0200
Subject: [PATCH] add proficiency level facet

---
 .../basic_search_filters.py                   |  2 ++
 .../dalia/query/items/facets/facet_objects.py | 22 ++++++++++++++++---
 .../items/metadata/proficiency_levels.py      |  6 +++--
 .../dalia/query/items/search/text_search.py   |  2 ++
 project/dalia/query/labels/label_service.py   |  2 +-
 .../test_basic_search_filters.py              | 11 ++++++++++
 6 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/project/dalia/query/items/basic_search_filters/basic_search_filters.py b/project/dalia/query/items/basic_search_filters/basic_search_filters.py
index 8368ccb..15d15a8 100644
--- a/project/dalia/query/items/basic_search_filters/basic_search_filters.py
+++ b/project/dalia/query/items/basic_search_filters/basic_search_filters.py
@@ -8,6 +8,7 @@ from project.dalia.query.items.facets.facet_objects import (
     LANGUAGE_FACET,
     LEARNING_RESOURCE_TYPE_FACET,
     MEDIA_TYPE_FACET,
+    PROFICIENCY_LEVEL_FACET,
     TARGET_AUDIENCE_FACET,
 )
 from project.dalia.query.labels.label_service import get_labels_for_item_uris_for_facet
@@ -17,6 +18,7 @@ from project.dalia.rdf.namespace import educor
 
 _BASIC_SEARCH_FILTER_FACETS = [
     TARGET_AUDIENCE_FACET,
+    PROFICIENCY_LEVEL_FACET,
     MEDIA_TYPE_FACET,
     LEARNING_RESOURCE_TYPE_FACET,
     LANGUAGE_FACET,
diff --git a/project/dalia/query/items/facets/facet_objects.py b/project/dalia/query/items/facets/facet_objects.py
index 5747dbe..b2b1d5f 100644
--- a/project/dalia/query/items/facets/facet_objects.py
+++ b/project/dalia/query/items/facets/facet_objects.py
@@ -1,6 +1,7 @@
-from dataclasses import dataclass
+from dataclasses import dataclass, field
+from typing import Any
 
-from rdflib import DCTERMS, SKOS, URIRef, XSD
+from rdflib import DCTERMS, RDFS, SKOS, URIRef, Variable, XSD
 
 from project.dalia.query.labels.label_service import VAR_ITEM, VAR_LABEL
 from project.dalia.query.utils import Dataset, filter_by_lang
@@ -17,7 +18,7 @@ class FacetObject:
     predicate: URIRef
     label_dataset: Dataset
     label_graph_pattern: tuple
-    label_order = VAR_LABEL
+    label_order: Any = field(default=VAR_LABEL)
 
 
 TARGET_AUDIENCE_FACET = FacetObject(
@@ -63,3 +64,18 @@ LANGUAGE_FACET = FacetObject(
         filter_by_lang(VAR_LABEL),
     ),
 )
+
+_VAR_LEVEL_ORDER = Variable("levelOrder")
+
+PROFICIENCY_LEVEL_FACET = FacetObject(
+    label="Proficiency Level",
+    key=MoDalia.Proficiency,
+    predicate=MoDalia.requiresProficiencyLevel,
+    label_dataset=Dataset.ONTOLOGIES,
+    label_graph_pattern=(
+        (VAR_ITEM, RDFS.label, VAR_LABEL),
+        (VAR_ITEM, MoDalia.hasOrder, _VAR_LEVEL_ORDER),
+        filter_by_lang(VAR_LABEL),
+    ),
+    label_order=_VAR_LEVEL_ORDER,
+)
diff --git a/project/dalia/query/items/metadata/proficiency_levels.py b/project/dalia/query/items/metadata/proficiency_levels.py
index 244320d..004f424 100644
--- a/project/dalia/query/items/metadata/proficiency_levels.py
+++ b/project/dalia/query/items/metadata/proficiency_levels.py
@@ -4,8 +4,10 @@ from rdflib import RDFS, URIRef
 from rdflib.term import Node, Variable
 
 from project.dalia.api_models.api_models import LabelValueItem
+from project.dalia.query.items.facets.facet_objects import PROFICIENCY_LEVEL_FACET
 from project.dalia.query.items.metadata.one_to_many_metadata import get_one_to_many_metadata_for_resources
-from project.dalia.query.labels.label_service import VAR_ITEM, VAR_LABEL, get_labels_for_item_uris
+from project.dalia.query.labels.label_service import VAR_ITEM, VAR_LABEL, get_labels_for_item_uris, \
+    get_labels_for_item_uris_for_facet
 from project.dalia.query.labels.utils import remap_to_label_value_item
 from project.dalia.query.utils import Dataset, filter_by_lang
 from project.dalia.rdf.namespace import MoDalia
@@ -20,7 +22,7 @@ _LABEL_GRAPH_PATTERN = (
 
 
 def _map_proficiency_level_uris_to_label_value_items(items: Collection[Node]) -> Dict[Node, LabelValueItem]:
-    mapping = get_labels_for_item_uris(items, Dataset.ONTOLOGIES, _LABEL_GRAPH_PATTERN, order_by=_VAR_LEVEL_ORDER)
+    mapping = get_labels_for_item_uris_for_facet(items, PROFICIENCY_LEVEL_FACET)
 
     return remap_to_label_value_item(mapping)
 
diff --git a/project/dalia/query/items/search/text_search.py b/project/dalia/query/items/search/text_search.py
index 531f70d..d8a5bc9 100644
--- a/project/dalia/query/items/search/text_search.py
+++ b/project/dalia/query/items/search/text_search.py
@@ -10,6 +10,7 @@ from project.dalia.query.items.facets.facet_objects import (
     LANGUAGE_FACET,
     LEARNING_RESOURCE_TYPE_FACET,
     MEDIA_TYPE_FACET,
+    PROFICIENCY_LEVEL_FACET,
     TARGET_AUDIENCE_FACET,
 )
 from project.dalia.query.items.metadata.items import get_metadata_for_learning_resources
@@ -22,6 +23,7 @@ from project.dalia.rdf.namespace.xpath_functions import day_from_date, month_fro
 
 _ITEM_SEARCH_FACETS = [
     TARGET_AUDIENCE_FACET,
+    PROFICIENCY_LEVEL_FACET,
     MEDIA_TYPE_FACET,
     LEARNING_RESOURCE_TYPE_FACET,
     LANGUAGE_FACET,
diff --git a/project/dalia/query/labels/label_service.py b/project/dalia/query/labels/label_service.py
index 47336c0..f394827 100644
--- a/project/dalia/query/labels/label_service.py
+++ b/project/dalia/query/labels/label_service.py
@@ -66,4 +66,4 @@ def get_labels_for_item_uris_for_facet(items: Collection[URIRef], facet) -> Dict
     :return: Associations between the item URIRefs and their respective label. The insertion order of this dictionary
              reflects the specified order.
     """
-    return get_labels_for_item_uris(items, facet.label_dataset, facet.label_graph_pattern)
+    return get_labels_for_item_uris(items, facet.label_dataset, facet.label_graph_pattern, facet.label_order)
diff --git a/tests/project/dalia/query/items/basic_search_filters/test_basic_search_filters.py b/tests/project/dalia/query/items/basic_search_filters/test_basic_search_filters.py
index 606c69f..ff8908a 100644
--- a/tests/project/dalia/query/items/basic_search_filters/test_basic_search_filters.py
+++ b/tests/project/dalia/query/items/basic_search_filters/test_basic_search_filters.py
@@ -11,6 +11,7 @@ from project.dalia.query.items.facets.facet_objects import (
     LANGUAGE_FACET,
     LEARNING_RESOURCE_TYPE_FACET,
     MEDIA_TYPE_FACET,
+    PROFICIENCY_LEVEL_FACET,
     TARGET_AUDIENCE_FACET,
 )
 from project.dalia.query.utils import Dataset
@@ -62,6 +63,16 @@ def test_get_on_BasicSearchFiltersView_returns_200_and_all_available_filters(tri
                 BasicSearchFilterValue(label='Teacher (School)', value=str(MoDalia.TeacherSchool)),
             ]
         ),
+        BasicSearchFilter(
+            key=BasicSearchFilterKey(name=str(PROFICIENCY_LEVEL_FACET.key), label=PROFICIENCY_LEVEL_FACET.label),
+            values=[
+                BasicSearchFilterValue(label='Novice', value='https://purl.org/ontology/modalia#Novice'),
+                BasicSearchFilterValue(label='Advanced Beginner', value='https://purl.org/ontology/modalia#Beginner'),
+                BasicSearchFilterValue(label='Competent', value='https://purl.org/ontology/modalia#Competent'),
+                BasicSearchFilterValue(label='Proficient', value='https://purl.org/ontology/modalia#Proficient'),
+                BasicSearchFilterValue(label='Expert', value='https://purl.org/ontology/modalia#Expert'),
+            ]
+        ),
         BasicSearchFilter(
             key=BasicSearchFilterKey(name=str(MEDIA_TYPE_FACET.key), label=MEDIA_TYPE_FACET.label),
             values=[
-- 
GitLab