You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Build a modern frontend for the course Teams experience
Context
The in-course Teams tab is one of the last big learner-facing pages still served by a legacy Django/Backbone frontend. It's a full Backbone/RequireJS SPA at /courses/{course_id}/teams/, and there's no MFE for it. Everywhere else the learner experience has moved to React MFEs; Teams hasn't, and the legacy app has to be rebuilt before it can be removed.
This is a real migration, not a small tab. The legacy frontend is roughly 2,500 lines of Backbone JS across ~18 views, plus 15 Underscore templates and a dedicated 773-line SCSS file, covering topic browse, team browse/create/edit, membership join/leave, team profiles, embedded team discussions, and instructor tools. Because of that size it doesn't have to live inside frontend-app-learning as a tab; it may be better as its own MFE. You'll have to figure out if that makes sense.
There is already a complete, versioned REST API (api/team/v0/) and the legacy app already runs entirely on top of it, so little to no backend work is expected.
What exists today
Legacy learner UI.TeamsDashboardView (lms/djangoapps/teams/views.py:114) renders the Mako teams/teams.html, which bootstraps the Backbone app teams/js/teams_tab_factory.js. The frontend lives under lms/djangoapps/teams/static/teams/ (views, models, collections, .underscore templates); styling is lms/static/sass/views/_teams.scss.
Tab + gating. Registered as a TeamsTab(EnrolledTab) CourseTab plugin (lms/djangoapps/teams/plugins.py:22), gated by settings.ENABLE_TEAMS (default on) and the per-course teams_configuration advanced setting. The tab is live wherever a course enables teams.
The MFE links out. The learning MFE renders course tabs from the Course Home metadata API; CourseTabSerializer.get_url resolves the Teams tab to the legacy /courses/{course_id}/teams/ URL, so the tab leaves the MFE.
The REST API is ready. A versioned DRF API under api/team/v0/ already backs the whole feature:
v0/teams/{team_id}/assignments, v0/bulk_team_membership/{course_id} — assignments and instructor bulk management.
Proposed approach
Build a modern React frontend for Teams against the existing api/team/v0/ endpoints, then retire the legacy app. Rough surface, in rough dependency order:
Topics + team browse — topics list, teams within a topic, team cards, search/filter.
Team detail + membership — team profile, join/leave, membership list, capacity/roster rules.
Create / edit team — forms honoring teamset type rules.
Team discussions — the embedded per-team discussion; compose with frontend-app-discussions rather than porting the legacy inline view.
Instructor tools — manage / bulk membership and instructor-only actions.
Its own MFE, or a learning-MFE tab. Given the size, a dedicated Teams MFE might make sense alongside a frontend-app-learning route/tab. Weigh reuse of learning-MFE course chrome/routing against a cleaner standalone boundary and independent ownership.
Team discussions. Reuse frontend-app-discussions for the per-team discussion instead of reimplementing the legacy inline view; needs a look at how team discussions map onto the discussions MFE's topic model.
Instructor tools split. Which teams-management surfaces belong in the learner experience vs. frontend-app-instructor-dashboard.
API gaps. The API is complete for the legacy app, but confirm nothing the rebuild wants (pagination shapes, search, teamset metadata) is missing before assuming zero backend work.
REST API: lms/djangoapps/teams/api_urls.py and lms/djangoapps/teams/views.py (TeamsListView, TeamsDetailView, TopicListView, TopicDetailView, MembershipListView, MembershipDetailView, TeamsAssignmentsView, MembershipBulkManagementView); serializers in lms/djangoapps/teams/serializers.py.
MFE today: tab URL comes from lms/djangoapps/course_home_api/course_metadata/serializers.py (CourseTabSerializer.get_url); no teams code in frontend-app-learning/src.
Build a modern frontend for the course Teams experience
Context
The in-course Teams tab is one of the last big learner-facing pages still served by a legacy Django/Backbone frontend. It's a full Backbone/RequireJS SPA at
/courses/{course_id}/teams/, and there's no MFE for it. Everywhere else the learner experience has moved to React MFEs; Teams hasn't, and the legacy app has to be rebuilt before it can be removed.This is a real migration, not a small tab. The legacy frontend is roughly 2,500 lines of Backbone JS across ~18 views, plus 15 Underscore templates and a dedicated 773-line SCSS file, covering topic browse, team browse/create/edit, membership join/leave, team profiles, embedded team discussions, and instructor tools. Because of that size it doesn't have to live inside
frontend-app-learningas a tab; it may be better as its own MFE. You'll have to figure out if that makes sense.There is already a complete, versioned REST API (
api/team/v0/) and the legacy app already runs entirely on top of it, so little to no backend work is expected.What exists today
TeamsDashboardView(lms/djangoapps/teams/views.py:114) renders the Makoteams/teams.html, which bootstraps the Backbone appteams/js/teams_tab_factory.js. The frontend lives underlms/djangoapps/teams/static/teams/(views, models, collections,.underscoretemplates); styling islms/static/sass/views/_teams.scss.TeamsTab(EnrolledTab)CourseTab plugin (lms/djangoapps/teams/plugins.py:22), gated bysettings.ENABLE_TEAMS(default on) and the per-courseteams_configurationadvanced setting. The tab is live wherever a course enables teams.CourseTabSerializer.get_urlresolves the Teams tab to the legacy/courses/{course_id}/teams/URL, so the tab leaves the MFE.api/team/v0/already backs the whole feature:v0/topics/,v0/topics/{topic_id},{course_id}— topics / teamsets.v0/teams/,v0/teams/{team_id}— list/create, detail/update/delete.v0/team_membership/,v0/team_membership/{team_id},{username}— list/join, detail/leave.v0/teams/{team_id}/assignments,v0/bulk_team_membership/{course_id}— assignments and instructor bulk management.Proposed approach
Build a modern React frontend for Teams against the existing
api/team/v0/endpoints, then retire the legacy app. Rough surface, in rough dependency order:frontend-app-discussionsrather than porting the legacy inline view.lms/djangoapps/teams/static/Backbone bundle, the Mako templates, and_teams.scss. Tracked back in Inventory the current state of the MFEs and Legacy Pages openedx-platform#38936.Open questions
frontend-app-learningroute/tab. Weigh reuse of learning-MFE course chrome/routing against a cleaner standalone boundary and independent ownership.frontend-app-discussionsfor the per-team discussion instead of reimplementing the legacy inline view; needs a look at how team discussions map onto the discussions MFE's topic model.frontend-app-instructor-dashboard.References
lms/djangoapps/teams/views.py(TeamsDashboardView), templatelms/djangoapps/teams/templates/teams/teams.html, Backbone bundlelms/djangoapps/teams/static/teams/, stylinglms/static/sass/views/_teams.scss, tab pluginlms/djangoapps/teams/plugins.py.lms/djangoapps/teams/api_urls.pyandlms/djangoapps/teams/views.py(TeamsListView,TeamsDetailView,TopicListView,TopicDetailView,MembershipListView,MembershipDetailView,TeamsAssignmentsView,MembershipBulkManagementView); serializers inlms/djangoapps/teams/serializers.py.lms/djangoapps/course_home_api/course_metadata/serializers.py(CourseTabSerializer.get_url); no teams code infrontend-app-learning/src.