diff --git a/app/scodoc/sco_report.py b/app/scodoc/sco_report.py
index aba7d6d11505010a82284d9a6d54080447d67557..05371480e6b884725a26e188dcc6553760bab993 100644
--- a/app/scodoc/sco_report.py
+++ b/app/scodoc/sco_report.py
@@ -1227,9 +1227,13 @@ def tsp_grouped_list(codes_etuds):
     return L
 
 
-def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True):
-    """Tableau recapitulant tous les parcours"""
-    sem = sco_formsemestre.get_formsemestre(formsemestre_id)
+def table_suivi_cursus(
+    formsemestre: FormSemestre,
+    groups_infos: sco_groups_view.DisplayedGroupsInfos,
+    only_primo=False,
+    grouped_parcours=True,
+):
+    """Tableau récapitulant tous les cursus suivis par les étudiants"""
     (
         etuds,
         bacs,
@@ -1238,7 +1242,7 @@ def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True)
         annee_admissions,
         civilites,
         statuts,
-    ) = tsp_etud_list(formsemestre_id, only_primo=only_primo)
+    ) = tsp_etud_list(formsemestre.id, groups_infos=groups_infos, only_primo=only_primo)
     codes_etuds = collections.defaultdict(list)
     for etud in etuds:
         etud["code_cursus"], etud["decisions_jury"] = get_code_cursus_etud(
@@ -1283,12 +1287,12 @@ def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True)
         S = set()
         sems_ids = list(S.union(*[list(e["decisions_jury"].keys()) for e in etuds]))
         sems_ids.sort()
-        sem_tits = ["S%s" % s for s in sems_ids]
+        sem_tits = [f"S{s}" for s in sems_ids]
         titles.update([(s, s) for s in sem_tits])
         columns_ids += tuple(sem_tits)
         for etud in etuds:
             for s in etud["decisions_jury"]:
-                etud["S%s" % s] = etud["decisions_jury"][s]
+                etud[f"S{s}"] = etud["decisions_jury"][s]
 
     if only_primo:
         primostr = "primo-entrants du"
@@ -1298,12 +1302,9 @@ def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True)
         columns_ids=columns_ids,
         rows=L,
         titles=titles,
-        origin="Généré par %s le " % sco_version.SCONAME
-        + scu.timedate_human_repr()
-        + "",
-        caption="Parcours suivis, étudiants %s semestre " % primostr
-        + sem["titreannee"],
-        page_title="Parcours " + sem["titreannee"],
+        origin=f"Généré par {sco_version.SCONAME} le {scu.timedate_human_repr()}",
+        caption=f"Parcours suivis, étudiants {primostr} semestre {formsemestre.titre_annee()}",
+        page_title=f"Parcours {formsemestre.titre_annee()}",
         html_sortable=True,
         html_class="table_leftalign table_listegroupe",
         html_next_section="""<table class="help">
@@ -1318,7 +1319,7 @@ def table_suivi_cursus(formsemestre_id, only_primo=False, grouped_parcours=True)
             "nb": len(etuds),
             "code_cursus": len(etuds),
         },
-        preferences=sco_preferences.SemPreferences(formsemestre_id),
+        preferences=sco_preferences.SemPreferences(formsemestre.id),
         table_id="table_suivi_cursus",
     )
     return tab
@@ -1357,8 +1358,24 @@ def formsemestre_suivi_cursus(
     no_grouping=False,
 ):
     """Effectifs dans les differents cursus possibles."""
+    formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
+    if request.method == "POST":
+        group_ids = request.form.getlist("group_ids")
+    else:
+        group_ids = request.args.getlist("group_ids")
+    try:
+        group_ids = [int(gid) for gid in group_ids]
+    except ValueError as exc:
+        raise ScoValueError("group_ids invalide") from exc
+    groups_infos = sco_groups_view.DisplayedGroupsInfos(
+        group_ids,
+        formsemestre_id=formsemestre.id,
+        select_all_when_unspecified=True,
+    )
+
     tab = table_suivi_cursus(
-        formsemestre_id,
+        formsemestre,
+        groups_infos,
         only_primo=only_primo,
         grouped_parcours=not no_grouping,
     )
@@ -1367,12 +1384,13 @@ def formsemestre_suivi_cursus(
         tab.base_url += "&only_primo=1"
     if no_grouping:
         tab.base_url += "&no_grouping=1"
+
     t = tab.make_page(fmt=fmt, with_html_headers=False)
     if fmt != "html":
         return t
     F = [
         tsp_form_primo_group(
-            only_primo, no_grouping, formsemestre_id, fmt, groups_infos=None
+            only_primo, no_grouping, formsemestre_id, fmt, groups_infos=groups_infos
         )
     ]
 
@@ -1381,7 +1399,12 @@ def formsemestre_suivi_cursus(
         "\n".join(F),
         t,
     ]
-    return render_template("sco_page.j2", title=tab.page_title, content="\n".join(H))
+    return render_template(
+        "sco_page.j2",
+        javascripts=["js/groups_view.js"],
+        title=tab.page_title,
+        content="\n".join(H),
+    )
 
 
 # -------------