feat: connect teams with content groups using dynamic partition generator
Description
This PR implements the connection from the teams feature to the content groups feature discussed and approved by product. This implementation uses the dynamic partition generator extension point to associate content groups with the users that belong to a Team.
This implementation was heavily inspired by the enrollment tracks dynamic partitions.
Rejected alternatives:
- Using a fixed bridge as it is done for cohorts (pull/33105)
Supporting information
Product roadmap issue for this feature: Enhancements to teams to make learner grouping more flexible Connecting teams to content groups
As of today, course authors can create topics or team-sets within a course. Then, associate teams to each team-set so students can join later. When connecting teams to content groups, learners can work on group assignments and access content designed by the course author specifically for that course team, as with cohorts or enrollment tracks.
This is how this feature works behind the scenes (roughly):
- We plugged in a new
dynamic_partition_generatorfunction calledcreate_team_set_partitionthat creates aTeamUserPartitionobject in memory for each course's team-set created via Pages & Resources > Teams UI in Studio. - Each (content) group associated with each partition is dynamically generated based on the teams within the team-set when loading course content in the LMS.
- So, each time a Student loads the course blocks, the course
UserPartitionTransformertransformer collects the blocks the current user can access. When doing so, the registered course outline processors are called. Among them is theTeamPartitionGroupsOutlineProcessor, which gets the information in the blocksgroup_accessfield and then matches it with the student's group filtering the course tree for the current user.
Testing instructions
Warning: You must create a new course to avoid data inconsistencies after the test.
Since we're adding a new entrypoint to the setup.py file, you should connect to your LMS/CMS containers and run: pip install -e .
Then, restart them.
-
After creating your course, you'll need to turn on a course-level flag that enables content groups for teams: Go to /admin/waffle_utils/waffleflagcourseoverridemodel Add new flag using your new course ID: course_teams.content_groups_for_teams
-
Enable teams for the course: Studio > Select course > Content > Pages & resources > Teams > Teams toggle
-
Create a few team sets (or groups) from the Course Authoring MFE for your course:
-
Then, go to the LMS and create a few teams within those team-set (or topics, or groups):
-
As a student, try loading the sections of the course, you'll be able to load each course section. You'll be able to see them as usual.
-
Now, restrict topics for each team as you would with cohorts or enrollment tracks:
-
As a student, try loading the course sections again. You won't be able to see any content.
-
As a student, join one of the teams and try again: you'll be able to see the content within your team
-
As a student, join the other team: you'll be able to see the content within both teams
Deadline
This effort is part of the Spanish consortium project, so it'd be ideal to merge this before the end of the project.
Other information
More technical info on teams: https://openedx.atlassian.net/wiki/spaces/AC/pages/160611195 Course author docs on teams: https://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/course_features/teams/teams_setup.html#teams-overview
Thanks for the pull request, @mariajgrimaldi! Please note that it may take us up to several weeks or months to complete a review and merge your PR.
Feel free to add as much of the following information to the ticket as you can:
- supporting documentation
- Open edX discussion forum threads
- timeline information ("this must be merged by XX date", and why that is)
- partner information ("this is a course on edx.org")
- any other information that can help Product understand the context for the PR
All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.
Please let us know once your PR is ready for our review and all tests are green.
Hi folks. I'm tagging you in our official technical proposal for connecting teams to content groups since you were tagged in the 1st rough implementation of the feature: https://github.com/openedx/edx-platform/pull/32806#issuecomment-1648264648 FYI @ormsbee, @feanil, @bmtcril, @kdmccormick, @jmakowski1123
Just so you know, the tests are failing because of the query count, so I'll leave them be until we have a review and I hear what you think about the extra queries caused by the course waffle flag check.
Hi @kdmccormick! Thank you for the feedback and the patience; I'll address your comments ASAP. :)
We understand how difficult it can be to set up a testing environment to review specific pull requests, so we'll add access information to the installation where we've been testing these particular changes.
You can follow the testing instructions in the PR cover letter with these credentials:
| Username | Password | User role |
|---|---|---|
| instructor-openedx | instructor-openedx | Instructor |
| student-openedx | student-openedx | Student |
Test cases
With this setup:
- A course with two team-sets A and B, each team-set with two teams: Team A.1 and team A.2 for team-set A, and team B.1 and team B.2 for team-set B.
- There are two subsections, each with two units.
- Unit 1 in the 1st subsection is restricted to team A.1, and unit 2 is restricted to team A.2.
- Unit 1 in the 2nd subsection is restricted to team B.1, and unit 2 is restricted to team B.2.
Here's the list of test cases we've considered:
- If the flag is off, then there's no way of configuring the teams + content groups integration.
- When the flag is on, an instructor can configure content groups for the course using the unit content restrictions view.
- When an instructor configures a unit as restricted for a team, a message is shown under the unit in the course outline.
- When a non-staff user with no team loads subsections in the LMS with restricted children units, the user cannot see the restricted blocks in the course outline.
- When a staff user with no team loads subsections in the LMS with restricted children units, the user can see the restricted blocks in the course outline.
- A non-staff user of team A.1 can load and see the unit's content restricted to the A.1 team, this should happen with each team.
- A non-staff user of team A.1 and B.1, can load and see the unit's content restricted to the A.1 and B.1 team. The blocks should be listed in the course outline for the user.
- A user cannot be part of two teams in the same team-set, so they can't load content restricted to more than one team within a team-set.
Hi @mariajgrimaldi, doing some tests with the masquerade I see that when I set the view from a specific team, it does not show me the units to which that team has access. e.g.
I have this structure in the course. Team A1 has access to the Unit 1.1.1:
When I use the masquerade with Team A1, I can't see the unit.
@BryanttV: thank you for the report! I'll be looking into it.
@BryanttV: I believe I fixed the masquerading issue, could you test again? Thanks!
There is a scenario I'd like to discuss with the reviewer; consider this:
- A new team is created in a course with the flag for this feature off
- The flag is then turned on
- The instructor tries to restrict content to teams
- The instructor won't see any teams listed in the unit's content restrictions configurations
Why? The metadata used to link team sets to dynamic partitions is generated (if it isn't already) each time the course metadata is save; this can be triggered by saving any setting for the course in Studio. No, I wonder if this feature should handle this use case. Or should we recommend to turn the flag on and then create teams in the docs?
I believe I fixed the masquerading issue, could you test again? Thanks!
@mariajgrimaldi, I checked it again and it works perfectly!
@BryanttV given that you also tested this, are you ok leaving a formal review with comments or an approval?
Thanks for the review, @kdmccormick! March 28-29 are public holidays in my home, so I'll be back on April 1st to address all your comments.
I'll be working on fixing the tests. Thanks!
Let me know if you have any more comments, @kdmccormick! Thanks
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
@kdmccormick: thanks again. I'll be addressing your comments now.
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
@mariajgrimaldi The code looks solid now â Before approving I'm just making sure I can manually test it.
I've created a sandbox with your PR. There are two teamsets configured, and the waffle flag is enabled, but I don't see the option to restrict unit access to teams.
As we discussed above, I made sure the edit Advanced Settings after enabling the waffle flag, but that didn't seem to work. Am I missing something? Could it be the fact that the teams config uses the old term ("topics") instead of the new one ("teamsets")?
Users:
- admin user: username=openedx, password=openedx
- regular user: username=learner, password=p@ssw0rd
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
By the way, I could not find the Teams card on Pages and Resources, so I have been editing Advanced Settings directly. I didn't that that would affect this new feature, but I mention it just in case it does.
I was looking at the sandbox and I was surprised to not find the teams configuration in the "pages and resourses" view.
@kdmccormick how did you turned teams on?
Thanks to Majo, this teams.enable_teams_app feature flag also needs to be turned on.
However I did that. Did the old turnoff/save/turnon and it did not start working. So I must defer to @mariajgrimaldi to investigate a bit.
Jinx @felipemontoya , I don't know why it's missing either.
I just imported the demo course, which already had teams enabled. The teams config in Advanced Settings which I screenshotted comes directly from the import.
Is there a waffle flag or django setting I'm missing in order to enable that new Teams configuration card? The sandbox is running basically the default Tutor configuration.
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
Cool, the teams.teams_app waffle flag makes the card show up. I added a teamset, and now the content groups connection is working as expected:
I am not sure exactly what step in that process fixed the content groups. I have some guesses, which I haven't tested:
- maybe the
teams.teams_appflag is required in order for the content groups to link up with the team-sets? - maybe the API used by Pages and Resources triggers the content groups connection, but simply saving the Advanced Settings page doesn't?
- maybe the "topics" key doesn't work, but the "team_sets" key does?
I'm going to lunch now and I can poke around more later today. Let me know if you find anything in the meantime.
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
@kdmccormick: I'll try reproducing what you did in my environment. I'll let you know!
Sandbox deployment successful đ đ LMS đ Studio âšī¸ Grove Config, Tutor Config, Tutor Requirements
@kdmccormick:
- Importing a new course doesn't trigger the update course metadata tasks that create the partition IDs, so that needs to be done manually by triggering a course metadata update.
- The key
topicsis not recognized when generating partition IDs by the helper function here: https://github.com/openedx/edx-platform/pull/33788/files#diff-0d4d54dfeec3342d390b4442574473f71abc0ed062629c2cbdae0878252778e8R334-R336. So it only recognizes team-sets, as the name shows. I'll address this now. - After importing the course, I tried updating the course metadata by manually changing
topicstoteam_sets, but it didn't work. It worked only when using the Course Authoring app. I first tried turning on/off teams, but it didn't update thetopicsjson dict, it only worked after changing the team size. - After changing
topicstoteam_sets, I removed the partition ids, then saved, and they re-appeared. So that metadata it's updated as well when saving it from the advanced settings view.