-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add content groups support to teams #33105
Conversation
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:
All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here. This is currently a draft pull request. When it is ready for our review and all tests are green, click "Ready for Review", or remove "WIP" from the title, as appropriate. |
93780a9
to
3f72406
Compare
63ca4b0
to
fc0cd80
Compare
3f72406
to
4825fcd
Compare
db4a744
to
3a9b457
Compare
@@ -776,7 +777,7 @@ def get_visibility_partition_info(xblock, course=None): | |||
selectable_partitions += get_user_partition_info(xblock, schemes=[CONTENT_TYPE_GATING_SCHEME], course=course) | |||
|
|||
# Now add the cohort user partitions. | |||
selectable_partitions = selectable_partitions + get_user_partition_info(xblock, schemes=["cohort"], course=course) | |||
selectable_partitions = selectable_partitions + get_user_partition_info(xblock, schemes=["cohort"], course=course) + team_partitions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to author: this can be generalized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
like in enrollment tracks
if scheme_name == COHORT_SCHEME: | ||
content_group_configuration = get_cohorted_user_partition(course) | ||
elif scheme_name == TEAM_SCHEME: | ||
content_group_configuration = get_teamed_user_partition(course) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be more generic? In the meantime, let's not refactor
if content_group_configuration is None: | ||
content_group_configuration = UserPartition( | ||
id=generate_int_id(MINIMUM_GROUP_ID, MYSQL_MAX_INT, GroupConfiguration.get_used_ids(course)), | ||
name=CONTENT_GROUP_CONFIGURATION_NAME, | ||
name=f"Content Groups for {scheme_name}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the same name but parametrized
elif partition['scheme'] == "team": | ||
has_content_groups = True | ||
displayable_partitions.append(partition) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this mean we can only have one type of grouping at a time?
def patch(self, request, team_id): | ||
course_team = get_object_or_404(CourseTeam, team_id=team_id) | ||
data = request.data | ||
|
||
content_group_id = data["content_group"] | ||
if not content_group_id: | ||
return super().patch(request, team_id) | ||
|
||
group = get_course_team_qs(course_team.course_id).filter(name=course_team.name).first() | ||
partitioned_group_info = get_group_info_for_team(group) | ||
if not partitioned_group_info: | ||
link_team_to_partition_group(group, data["user_partition_id"], data["content_group"]) | ||
return super().patch(request, team_id) | ||
|
||
existing_content_group_id, existing_partition_id = get_group_info_for_team(group) | ||
if content_group_id != existing_content_group_id or data["user_partition_id"] != existing_partition_id: | ||
unlink_team_partition_group(group) | ||
link_team_to_partition_group(group, data["user_partition_id"], data["content_group"]) | ||
|
||
return super().patch(request, team_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add docstring and explain why are we doing this
group = get_course_team_qs(team.course_id).get(name=team.name) | ||
add_user_to_team(group, user.username) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we make this toggable?
|
||
from openedx.core.djangoapps.course_groups.models import CohortMembership | ||
from .models import CourseUserGroupPartitionGroup, CourseTeamGroup |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's not do this
def get_assignment_type(user_group): | ||
""" | ||
Get assignment type for cohort. | ||
""" | ||
course_cohort = user_group.cohort | ||
return course_cohort.assignment_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this?
def get_team(user, course_key, assign=True, use_cached=False): | ||
if user is None or user.is_anonymous: | ||
return None | ||
|
||
try: | ||
membership = TeamMembership.objects.get( | ||
course_id=course_key, | ||
user_id=user.id, | ||
) | ||
return membership.course_user_group | ||
except TeamMembership.DoesNotExist: | ||
if not assign: | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add docstring
def get_course_teams(course_id=None): | ||
query_set = CourseUserGroup.objects.filter( | ||
course_id=course_id, | ||
group_type=CourseUserGroup.TEAM, | ||
) | ||
return list(query_set) | ||
|
||
def get_course_team_qs(course_id=None): | ||
query_set = CourseUserGroup.objects.filter( | ||
course_id=course_id, | ||
group_type=CourseUserGroup.TEAM, | ||
) | ||
return query_set |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add docstring
).course_user_group | ||
|
||
|
||
def add_user_to_team(group, username_or_email_or_user): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add docstring
super().clean_fields(*args, **kwargs) | ||
|
||
@classmethod | ||
def assign(cls, group, user): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should we do here besides removing the unicity condition?
@@ -63,7 +63,8 @@ class Meta: | |||
# For now, only have group type 'cohort', but adding a type field to support | |||
# things like 'question_discussion', 'friends', 'off-line-class', etc | |||
COHORT = 'cohort' # If changing this string, update it in migration 0006.forwards() as well | |||
GROUP_TYPE_CHOICES = ((COHORT, 'Cohort'),) | |||
TEAM = 'team' | |||
GROUP_TYPE_CHOICES = ((COHORT, 'Cohort'), (TEAM, 'Team'),) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[question] if we already have a way of grouping users (teams) why do we need this mapping?
9fa5f51
to
545b0a2
Compare
Current limitations:
|
@mariajgrimaldi Even though your pull request wasn’t merged, please take a moment to answer a two question survey so we can improve your experience in the future. |
Closed in favor of #33788 |
Description
This PR creates a bridge between teams and content groups, based on the exploration of new flexible grouping definition published previously on this PR: #32806
We're calling
flexible group
to a course user group similar to cohorts but without unicity restrictions, so it's more generic.Here are the use cases we've implementing so far:
Supporting information
This implementation is part of the effort for: openedx/platform-roadmap#250, and it's a continuation of #32806 connecting flexible groups capabilities with teams.
More on teams: https://openedx.atlassian.net/wiki/spaces/LEARNER/pages/19006021/Teams
Testing instructions
MJG/extended-teams
Studio > Select your course > Pages & Resources > Teams
Studio> Select your course > Group Configurations > Content Group for group
Select your course > Teams tab > Select the topic you created > Create a new team in this topic