-
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ | |
from cms.djangoapps.contentstore.utils import reverse_usage_url | ||
from common.djangoapps.util.db import MYSQL_MAX_INT, generate_int_id | ||
from lms.lib.utils import get_parent_unit | ||
from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_user_partition | ||
from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_user_partition, get_teamed_user_partition # lint-amnesty, pylint: disable=wrong-import-order | ||
from xmodule.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, ReadOnlyUserPartitionError, UserPartition # lint-amnesty, pylint: disable=wrong-import-order | ||
from xmodule.partitions.partitions_service import get_all_partitions_for_course # lint-amnesty, pylint: disable=wrong-import-order | ||
from xmodule.split_test_block import get_split_user_partitions # lint-amnesty, pylint: disable=wrong-import-order | ||
|
@@ -22,6 +22,7 @@ | |
RANDOM_SCHEME = "random" | ||
COHORT_SCHEME = "cohort" | ||
ENROLLMENT_SCHEME = "enrollment_track" | ||
TEAM_SCHEME = "team" | ||
|
||
CONTENT_GROUP_CONFIGURATION_DESCRIPTION = _( | ||
'The groups in this configuration can be mapped to cohorts in the Instructor Dashboard.' | ||
|
@@ -114,7 +115,7 @@ def get_user_partition(self): | |
raise GroupConfigurationsValidationError(_("unable to load this type of group configuration")) # lint-amnesty, pylint: disable=raise-missing-from | ||
|
||
@staticmethod | ||
def _get_usage_dict(course, unit, block, scheme_name=None): | ||
def _get_usage_dict(course, unit, block, scheme_name=COHORT_SCHEME): | ||
""" | ||
Get usage info for unit/block. | ||
""" | ||
|
@@ -347,22 +348,25 @@ def update_partition_usage_info(store, course, configuration): | |
return partition_configuration | ||
|
||
@staticmethod | ||
def get_or_create_content_group(store, course): | ||
def get_or_create_content_group(store, course, scheme_name=COHORT_SCHEME): | ||
""" | ||
Returns the first user partition from the course which uses the | ||
CohortPartitionScheme, or generates one if no such partition is | ||
found. The created partition is not saved to the course until | ||
the client explicitly creates a group within the partition and | ||
POSTs back. | ||
""" | ||
content_group_configuration = get_cohorted_user_partition(course) | ||
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) | ||
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 commentThe reason will be displayed to describe this comment to others. Learn more. use the same name but parametrized |
||
description=CONTENT_GROUP_CONFIGURATION_DESCRIPTION, | ||
groups=[], | ||
scheme_id=COHORT_SCHEME | ||
scheme_id=scheme_name, | ||
) | ||
return content_group_configuration.to_json() | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -763,6 +763,7 @@ def get_visibility_partition_info(xblock, course=None): | |
selectable_partitions = [] | ||
# We wish to display enrollment partitions before cohort partitions. | ||
enrollment_user_partitions = get_user_partition_info(xblock, schemes=["enrollment_track"], course=course) | ||
team_partitions = get_user_partition_info(xblock, schemes=["team"], course=course) | ||
|
||
# For enrollment partitions, we only show them if there is a selected group or | ||
# or if the number of groups > 1. | ||
|
@@ -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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. like in enrollment tracks |
||
|
||
# Find the first partition with a selected group. That will be the one initially enabled in the dialog | ||
# (if the course has only been added in Studio, only one partition should have a selected group). | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,8 @@ | |
from .toggles import are_team_submissions_enabled | ||
from .utils import emit_team_event | ||
|
||
from openedx.core.djangoapps.course_groups.api import * | ||
|
||
TEAM_MEMBERSHIPS_PER_PAGE = 5 | ||
TOPICS_PER_PAGE = 12 | ||
MAXIMUM_SEARCH_SIZE = 10000 | ||
|
@@ -637,6 +639,13 @@ def post(self, request): | |
) | ||
|
||
data = CourseTeamSerializer(team, context={"request": request}).data | ||
group = add_team_to_course( | ||
team.name, | ||
course_key, | ||
) | ||
if request.data.get("user_partition_id") and request.data.get("content_group"): | ||
link_team_to_partition_group(group, request.data["user_partition_id"], request.data["content_group"]) | ||
|
||
return Response(data) | ||
|
||
def get_page(self): | ||
|
@@ -838,6 +847,27 @@ def delete(self, request, team_id): | |
}) | ||
return Response(status=status.HTTP_204_NO_CONTENT) | ||
|
||
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) | ||
Comment on lines
+850
to
+869
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add docstring and explain why are we doing this |
||
|
||
|
||
class TeamsAssignmentsView(GenericAPIView): | ||
""" | ||
|
@@ -1479,6 +1509,8 @@ def post(self, request): | |
|
||
try: | ||
membership = team.add_user(user) | ||
group = get_course_team_qs(team.course_id).get(name=team.name) | ||
add_user_to_team(group, user.username) | ||
Comment on lines
+1512
to
+1513
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we make this toggable? |
||
emit_team_event( | ||
'edx.team.learner_added', | ||
team.course_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.
Could this be more generic? In the meantime, let's not refactor